[cfe-commits] r86629 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/CMakeLists.txt lib/AST/NestedNameSpecifier.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp

Douglas Gregor dgregor at apple.com
Mon Nov 9 18:39:09 CST 2009


Author: dgregor
Date: Mon Nov  9 18:39:07 2009
New Revision: 86629

URL: http://llvm.org/viewvc/llvm-project?rev=86629&view=rev
Log:
Move all of the type-printing logic to its own C++ source file

Added:
    cfe/trunk/lib/AST/TypePrinter.cpp
Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/CMakeLists.txt
    cfe/trunk/lib/AST/NestedNameSpecifier.cpp
    cfe/trunk/lib/AST/Type.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=86629&r1=86628&r2=86629&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Nov  9 18:39:07 2009
@@ -892,8 +892,6 @@
 
   QualType getCanonicalTypeInternal() const { return CanonicalType; }
   void dump() const;
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const = 0;
   static bool classof(const Type *) { return true; }
 };
 
@@ -979,9 +977,6 @@
     return TypeKind >= Float && TypeKind <= LongDouble;
   }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
   static bool classof(const BuiltinType *) { return true; }
 };
@@ -1004,9 +999,6 @@
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   static bool classof(const Type *T) { return T->getTypeClass() == FixedWidthInt; }
   static bool classof(const FixedWidthIntType *) { return true; }
 };
@@ -1024,9 +1016,6 @@
 public:
   QualType getElementType() const { return ElementType; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1052,9 +1041,6 @@
   friend class ASTContext;  // ASTContext creates these.
 public:
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   QualType getPointeeType() const { return PointeeType; }
 
   bool isSugared() const { return false; }
@@ -1087,9 +1073,6 @@
   // Get the pointee type. Pointee is required to always be a function type.
   QualType getPointeeType() const { return PointeeType; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1173,9 +1156,6 @@
   {}
   friend class ASTContext; // ASTContext creates these
 public:
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1193,9 +1173,6 @@
   }
   friend class ASTContext; // ASTContext creates these
 public:
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1225,9 +1202,6 @@
 
   const Type *getClass() const { return Class; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1318,9 +1292,6 @@
   friend class ASTContext;  // ASTContext creates these.
 public:
   const llvm::APInt &getSize() const { return Size; }
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1352,9 +1323,6 @@
     : ArrayType(IncompleteArray, et, can, sm, tq) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1418,9 +1386,6 @@
   SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
   SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1474,9 +1439,6 @@
   SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
   SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1526,9 +1488,6 @@
   QualType getElementType() const { return ElementType; }
   SourceLocation getAttributeLoc() const { return loc; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1571,9 +1530,6 @@
   QualType getElementType() const { return ElementType; }
   unsigned getNumElements() const { return NumElements; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1649,9 +1605,6 @@
       return unsigned(idx-1) < NumElements;
     return false;
   }
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1715,9 +1668,6 @@
 public:
   // No additional state past what FunctionType provides.
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1828,9 +1778,6 @@
     return exception_begin() + NumExceptions;
   }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -1872,9 +1819,6 @@
   bool isSugared() const { return true; }
   QualType desugar() const;
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
   static bool classof(const TypedefType *) { return true; }
 };
@@ -1895,9 +1839,6 @@
   /// \brief Returns whether this type directly provides sugar.
   bool isSugared() const { return true; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
   static bool classof(const TypeOfExprType *) { return true; }
 };
@@ -1940,9 +1881,6 @@
   /// \brief Returns whether this type directly provides sugar.
   bool isSugared() const { return true; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
   static bool classof(const TypeOfType *) { return true; }
 };
@@ -1969,9 +1907,6 @@
   /// \brief Returns whether this type directly provides sugar.
   bool isSugared() const { return !isDependentType(); }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
   static bool classof(const DecltypeType *) { return true; }
 };
@@ -2016,9 +1951,6 @@
   bool isBeingDefined() const { return decl.getInt(); }
   void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   static bool classof(const Type *T) {
     return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
   }
@@ -2133,9 +2065,6 @@
     }
   }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, getUnderlyingType(), getTagKind());
   }
@@ -2171,9 +2100,6 @@
   bool isParameterPack() const { return ParameterPack; }
   IdentifierInfo *getName() const { return Name; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -2227,9 +2153,6 @@
     return getCanonicalTypeInternal();
   }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return true; }
   QualType desugar() const { return getReplacementType(); }
 
@@ -2325,9 +2248,6 @@
   /// \precondition @c isArgType(Arg)
   const TemplateArgument &getArg(unsigned Idx) const;
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return !isDependentType(); }
   QualType desugar() const { return getCanonicalTypeInternal(); }
 
@@ -2379,9 +2299,6 @@
   /// \brief Returns whether this type directly provides sugar.
   bool isSugared() const { return true; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, NNS, NamedType);
   }
@@ -2456,9 +2373,6 @@
     return Name.dyn_cast<const TemplateSpecializationType *>();
   }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -2509,9 +2423,6 @@
   qual_iterator qual_end() const   { return Protocols.end(); }
   bool qual_empty() const { return Protocols.size() == 0; }
 
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
@@ -2597,8 +2508,6 @@
   void Profile(llvm::FoldingSetNodeID &ID);
   static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
                       ObjCProtocolDecl **protocols, unsigned NumProtocols);
-  virtual void getAsStringInternal(std::string &InnerString,
-                                   const PrintingPolicy &Policy) const;
   static bool classof(const Type *T) {
     return T->getTypeClass() == ObjCObjectPointer;
   }

Modified: cfe/trunk/lib/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=86629&r1=86628&r2=86629&view=diff

==============================================================================
--- cfe/trunk/lib/AST/CMakeLists.txt (original)
+++ cfe/trunk/lib/AST/CMakeLists.txt Mon Nov  9 18:39:07 2009
@@ -30,6 +30,7 @@
   TemplateName.cpp
   Type.cpp
   TypeLoc.cpp
+  TypePrinter.cpp
   )
 
 add_dependencies(clangAST ClangDiagnosticAST)

Modified: cfe/trunk/lib/AST/NestedNameSpecifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NestedNameSpecifier.cpp?rev=86629&r1=86628&r2=86629&view=diff

==============================================================================
--- cfe/trunk/lib/AST/NestedNameSpecifier.cpp (original)
+++ cfe/trunk/lib/AST/NestedNameSpecifier.cpp Mon Nov  9 18:39:07 2009
@@ -167,7 +167,7 @@
                                                                  InnerPolicy);
     } else {
       // Print the type normally
-      T->getAsStringInternal(TypeStr, InnerPolicy);
+      TypeStr = QualType(T, 0).getAsString(InnerPolicy);
     }
     OS << TypeStr;
     break;

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=86629&r1=86628&r2=86629&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Nov  9 18:39:07 2009
@@ -906,539 +906,6 @@
   return Context->getQualifiedType(T, *this);
 }
 
-
-//===----------------------------------------------------------------------===//
-// Type Printing
-//===----------------------------------------------------------------------===//
-
-void QualType::dump(const char *msg) const {
-  std::string R = "identifier";
-  LangOptions LO;
-  getAsStringInternal(R, PrintingPolicy(LO));
-  if (msg)
-    fprintf(stderr, "%s: %s\n", msg, R.c_str());
-  else
-    fprintf(stderr, "%s\n", R.c_str());
-}
-void QualType::dump() const {
-  dump("");
-}
-
-void Type::dump() const {
-  std::string S = "identifier";
-  LangOptions LO;
-  getAsStringInternal(S, PrintingPolicy(LO));
-  fprintf(stderr, "%s\n", S.c_str());
-}
-
-
-
-static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
-  if (TypeQuals & Qualifiers::Const) {
-    if (!S.empty()) S += ' ';
-    S += "const";
-  }
-  if (TypeQuals & Qualifiers::Volatile) {
-    if (!S.empty()) S += ' ';
-    S += "volatile";
-  }
-  if (TypeQuals & Qualifiers::Restrict) {
-    if (!S.empty()) S += ' ';
-    S += "restrict";
-  }
-}
-
-std::string Qualifiers::getAsString() const {
-  LangOptions LO;
-  return getAsString(PrintingPolicy(LO));
-}
-
-// Appends qualifiers to the given string, separated by spaces.  Will
-// prefix a space if the string is non-empty.  Will not append a final
-// space.
-void Qualifiers::getAsStringInternal(std::string &S,
-                                     const PrintingPolicy&) const {
-  AppendTypeQualList(S, getCVRQualifiers());
-  if (unsigned AddressSpace = getAddressSpace()) {
-    if (!S.empty()) S += ' ';
-    S += "__attribute__((address_space(";
-    S += llvm::utostr_32(AddressSpace);
-    S += ")))";
-  }
-  if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
-    if (!S.empty()) S += ' ';
-    S += "__attribute__((objc_gc(";
-    if (GCAttrType == Qualifiers::Weak)
-      S += "weak";
-    else
-      S += "strong";
-    S += ")))";
-  }
-}
-
-std::string QualType::getAsString() const {
-  std::string S;
-  LangOptions LO;
-  getAsStringInternal(S, PrintingPolicy(LO));
-  return S;
-}
-
-void
-QualType::getAsStringInternal(std::string &S,
-                              const PrintingPolicy &Policy) const {
-  if (isNull()) {
-    S += "NULL TYPE";
-    return;
-  }
-
-  if (Policy.SuppressSpecifiers && getTypePtr()->isSpecifierType())
-    return;
-
-  // Print qualifiers as appropriate.
-  Qualifiers Quals = getQualifiers();
-  if (!Quals.empty()) {
-    std::string TQS;
-    Quals.getAsStringInternal(TQS, Policy);
-
-    if (!S.empty()) {
-      TQS += ' ';
-      TQS += S;
-    }
-    std::swap(S, TQS);
-  }
-
-  getTypePtr()->getAsStringInternal(S, Policy);
-}
-
-void BuiltinType::getAsStringInternal(std::string &S,
-                                      const PrintingPolicy &Policy) const {
-  if (S.empty()) {
-    S = getName(Policy.LangOpts);
-  } else {
-    // Prefix the basic type, e.g. 'int X'.
-    S = ' ' + S;
-    S = getName(Policy.LangOpts) + S;
-  }
-}
-
-void FixedWidthIntType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  // FIXME: Once we get bitwidth attribute, write as
-  // "int __attribute__((bitwidth(x)))".
-  std::string prefix = "__clang_fixedwidth";
-  prefix += llvm::utostr_32(Width);
-  prefix += (char)(Signed ? 'S' : 'U');
-  if (S.empty()) {
-    S = prefix;
-  } else {
-    // Prefix the basic type, e.g. 'int X'.
-    S = prefix + S;
-  }
-}
-
-
-void ComplexType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  ElementType->getAsStringInternal(S, Policy);
-  S = "_Complex " + S;
-}
-
-void PointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S = '*' + S;
-
-  // Handle things like 'int (*A)[4];' correctly.
-  // FIXME: this should include vectors, but vectors use attributes I guess.
-  if (isa<ArrayType>(getPointeeType()))
-    S = '(' + S + ')';
-
-  getPointeeType().getAsStringInternal(S, Policy);
-}
-
-void BlockPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S = '^' + S;
-  PointeeType.getAsStringInternal(S, Policy);
-}
-
-void LValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S = '&' + S;
-
-  // Handle things like 'int (&A)[4];' correctly.
-  // FIXME: this should include vectors, but vectors use attributes I guess.
-  if (isa<ArrayType>(getPointeeTypeAsWritten()))
-    S = '(' + S + ')';
-
-  getPointeeTypeAsWritten().getAsStringInternal(S, Policy);
-}
-
-void RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S = "&&" + S;
-
-  // Handle things like 'int (&&A)[4];' correctly.
-  // FIXME: this should include vectors, but vectors use attributes I guess.
-  if (isa<ArrayType>(getPointeeTypeAsWritten()))
-    S = '(' + S + ')';
-
-  getPointeeTypeAsWritten().getAsStringInternal(S, Policy);
-}
-
-void MemberPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  std::string C;
-  Class->getAsStringInternal(C, Policy);
-  C += "::*";
-  S = C + S;
-
-  // Handle things like 'int (Cls::*A)[4];' correctly.
-  // FIXME: this should include vectors, but vectors use attributes I guess.
-  if (isa<ArrayType>(getPointeeType()))
-    S = '(' + S + ')';
-
-  getPointeeType().getAsStringInternal(S, Policy);
-}
-
-void ConstantArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S += '[';
-  S += llvm::utostr(getSize().getZExtValue());
-  S += ']';
-
-  getElementType().getAsStringInternal(S, Policy);
-}
-
-void IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S += "[]";
-
-  getElementType().getAsStringInternal(S, Policy);
-}
-
-void VariableArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S += '[';
-
-  if (getIndexTypeQualifiers().hasQualifiers()) {
-    AppendTypeQualList(S, getIndexTypeCVRQualifiers());
-    S += ' ';
-  }
-
-  if (getSizeModifier() == Static)
-    S += "static";
-  else if (getSizeModifier() == Star)
-    S += '*';
-
-  if (getSizeExpr()) {
-    std::string SStr;
-    llvm::raw_string_ostream s(SStr);
-    getSizeExpr()->printPretty(s, 0, Policy);
-    S += s.str();
-  }
-  S += ']';
-
-  getElementType().getAsStringInternal(S, Policy);
-}
-
-void DependentSizedArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S += '[';
-
-  if (getIndexTypeQualifiers().hasQualifiers()) {
-    AppendTypeQualList(S, getIndexTypeCVRQualifiers());
-    S += ' ';
-  }
-
-  if (getSizeModifier() == Static)
-    S += "static";
-  else if (getSizeModifier() == Star)
-    S += '*';
-
-  if (getSizeExpr()) {
-    std::string SStr;
-    llvm::raw_string_ostream s(SStr);
-    getSizeExpr()->printPretty(s, 0, Policy);
-    S += s.str();
-  }
-  S += ']';
-
-  getElementType().getAsStringInternal(S, Policy);
-}
-
-void DependentSizedExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  getElementType().getAsStringInternal(S, Policy);
-
-  S += " __attribute__((ext_vector_type(";
-  if (getSizeExpr()) {
-    std::string SStr;
-    llvm::raw_string_ostream s(SStr);
-    getSizeExpr()->printPretty(s, 0, Policy);
-    S += s.str();
-  }
-  S += ")))";
-}
-
-void VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  // FIXME: We prefer to print the size directly here, but have no way
-  // to get the size of the type.
-  S += " __attribute__((__vector_size__(";
-  S += llvm::utostr_32(NumElements); // convert back to bytes.
-  S += " * sizeof(" + ElementType.getAsString() + "))))";
-  ElementType.getAsStringInternal(S, Policy);
-}
-
-void ExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  S += " __attribute__((ext_vector_type(";
-  S += llvm::utostr_32(NumElements);
-  S += ")))";
-  ElementType.getAsStringInternal(S, Policy);
-}
-
-void TypeOfExprType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
-    InnerString = ' ' + InnerString;
-  std::string Str;
-  llvm::raw_string_ostream s(Str);
-  getUnderlyingExpr()->printPretty(s, 0, Policy);
-  InnerString = "typeof " + s.str() + InnerString;
-}
-
-void TypeOfType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
-    InnerString = ' ' + InnerString;
-  std::string Tmp;
-  getUnderlyingType().getAsStringInternal(Tmp, Policy);
-  InnerString = "typeof(" + Tmp + ")" + InnerString;
-}
-
-void DecltypeType::getAsStringInternal(std::string &InnerString,
-                                       const PrintingPolicy &Policy) const {
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
-    InnerString = ' ' + InnerString;
-  std::string Str;
-  llvm::raw_string_ostream s(Str);
-  getUnderlyingExpr()->printPretty(s, 0, Policy);
-  InnerString = "decltype(" + s.str() + ")" + InnerString;
-}
-
-void FunctionNoProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  // If needed for precedence reasons, wrap the inner part in grouping parens.
-  if (!S.empty())
-    S = "(" + S + ")";
-
-  S += "()";
-  if (getNoReturnAttr())
-    S += " __attribute__((noreturn))";
-  getResultType().getAsStringInternal(S, Policy);
-}
-
-void FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
-  // If needed for precedence reasons, wrap the inner part in grouping parens.
-  if (!S.empty())
-    S = "(" + S + ")";
-
-  S += "(";
-  std::string Tmp;
-  PrintingPolicy ParamPolicy(Policy);
-  ParamPolicy.SuppressSpecifiers = false;
-  for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
-    if (i) S += ", ";
-    getArgType(i).getAsStringInternal(Tmp, ParamPolicy);
-    S += Tmp;
-    Tmp.clear();
-  }
-
-  if (isVariadic()) {
-    if (getNumArgs())
-      S += ", ";
-    S += "...";
-  } else if (getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
-    // Do not emit int() if we have a proto, emit 'int(void)'.
-    S += "void";
-  }
-
-  S += ")";
-  if (getNoReturnAttr())
-    S += " __attribute__((noreturn))";
-  getResultType().getAsStringInternal(S, Policy);
-}
-
-
-void TypedefType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
-    InnerString = ' ' + InnerString;
-  InnerString = getDecl()->getIdentifier()->getName().str() + InnerString;
-}
-
-void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'parmname X'.
-    InnerString = ' ' + InnerString;
-
-  if (!Name)
-    InnerString = "type-parameter-" + llvm::utostr_32(Depth) + '-' +
-      llvm::utostr_32(Index) + InnerString;
-  else
-    InnerString = Name->getName().str() + InnerString;
-}
-
-void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  getReplacementType().getAsStringInternal(InnerString, Policy);
-}
-
-static void PrintTemplateArgument(std::string &Buffer,
-                                  const TemplateArgument &Arg,
-                                  const PrintingPolicy &Policy) {
-  switch (Arg.getKind()) {
-  case TemplateArgument::Null:
-    assert(false && "Null template argument");
-    break;
-    
-  case TemplateArgument::Type:
-    Arg.getAsType().getAsStringInternal(Buffer, Policy);
-    break;
-
-  case TemplateArgument::Declaration:
-    Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
-    break;
-
-  case TemplateArgument::Integral:
-    Buffer = Arg.getAsIntegral()->toString(10, true);
-    break;
-
-  case TemplateArgument::Expression: {
-    llvm::raw_string_ostream s(Buffer);
-    Arg.getAsExpr()->printPretty(s, 0, Policy);
-    break;
-  }
-
-  case TemplateArgument::Pack:
-    assert(0 && "FIXME: Implement!");
-    break;
-  }
-}
-
-std::string
-TemplateSpecializationType::PrintTemplateArgumentList(
-                                                  const TemplateArgument *Args,
-                                                  unsigned NumArgs,
-                                                  const PrintingPolicy &Policy) {
-  std::string SpecString;
-  SpecString += '<';
-  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
-    if (Arg)
-      SpecString += ", ";
-
-    // Print the argument into a string.
-    std::string ArgString;
-    PrintTemplateArgument(ArgString, Args[Arg], Policy);
-
-    // If this is the first argument and its string representation
-    // begins with the global scope specifier ('::foo'), add a space
-    // to avoid printing the diagraph '<:'.
-    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
-      SpecString += ' ';
-
-    SpecString += ArgString;
-  }
-
-  // If the last character of our string is '>', add another space to
-  // keep the two '>''s separate tokens. We don't *have* to do this in
-  // C++0x, but it's still good hygiene.
-  if (SpecString[SpecString.size() - 1] == '>')
-    SpecString += ' ';
-
-  SpecString += '>';
-
-  return SpecString;
-}
-
-// Sadly, repeat all that with TemplateArgLoc.
-std::string TemplateSpecializationType::
-PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
-                          const PrintingPolicy &Policy) {
-  std::string SpecString;
-  SpecString += '<';
-  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
-    if (Arg)
-      SpecString += ", ";
-
-    // Print the argument into a string.
-    std::string ArgString;
-    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
-
-    // If this is the first argument and its string representation
-    // begins with the global scope specifier ('::foo'), add a space
-    // to avoid printing the diagraph '<:'.
-    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
-      SpecString += ' ';
-
-    SpecString += ArgString;
-  }
-
-  // If the last character of our string is '>', add another space to
-  // keep the two '>''s separate tokens. We don't *have* to do this in
-  // C++0x, but it's still good hygiene.
-  if (SpecString[SpecString.size() - 1] == '>')
-    SpecString += ' ';
-
-  SpecString += '>';
-
-  return SpecString;
-}
-
-void
-TemplateSpecializationType::
-getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  std::string SpecString;
-
-  {
-    llvm::raw_string_ostream OS(SpecString);
-    Template.print(OS, Policy);
-  }
-
-  SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs(), Policy);
-  if (InnerString.empty())
-    InnerString.swap(SpecString);
-  else
-    InnerString = SpecString + ' ' + InnerString;
-}
-
-void QualifiedNameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  std::string MyString;
-
-  {
-    llvm::raw_string_ostream OS(MyString);
-    NNS->print(OS, Policy);
-  }
-
-  std::string TypeStr;
-  PrintingPolicy InnerPolicy(Policy);
-  InnerPolicy.SuppressTagKind = true;
-  InnerPolicy.SuppressScope = true;
-  NamedType.getAsStringInternal(TypeStr, InnerPolicy);
-
-  MyString += TypeStr;
-  if (InnerString.empty())
-    InnerString.swap(MyString);
-  else
-    InnerString = MyString + ' ' + InnerString;
-}
-
-void TypenameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  std::string MyString;
-
-  {
-    llvm::raw_string_ostream OS(MyString);
-    OS << "typename ";
-    NNS->print(OS, Policy);
-
-    if (const IdentifierInfo *Ident = getIdentifier())
-      OS << Ident->getName();
-    else if (const TemplateSpecializationType *Spec = getTemplateId()) {
-      Spec->getTemplateName().print(OS, Policy, true);
-      OS << TemplateSpecializationType::PrintTemplateArgumentList(
-                                                               Spec->getArgs(),
-                                                            Spec->getNumArgs(),
-                                                               Policy);
-    }
-  }
-
-  if (InnerString.empty())
-    InnerString.swap(MyString);
-  else
-    InnerString = MyString + ' ' + InnerString;
-}
-
 void ObjCInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
                                          const ObjCInterfaceDecl *Decl,
                                          ObjCProtocolDecl **protocols,
@@ -1454,134 +921,3 @@
   else
     Profile(ID, getDecl(), 0, 0);
 }
-
-void ObjCInterfaceType::getAsStringInternal(std::string &InnerString,
-                                           const PrintingPolicy &Policy) const {
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
-    InnerString = ' ' + InnerString;
-
-  std::string ObjCQIString = getDecl()->getNameAsString();
-  if (getNumProtocols()) {
-    ObjCQIString += '<';
-    bool isFirst = true;
-    for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
-      if (isFirst)
-        isFirst = false;
-      else
-        ObjCQIString += ',';
-      ObjCQIString += (*I)->getNameAsString();
-    }
-    ObjCQIString += '>';
-  }
-  InnerString = ObjCQIString + InnerString;
-}
-
-void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
-                                                const PrintingPolicy &Policy) const {
-  std::string ObjCQIString;
-
-  if (isObjCIdType() || isObjCQualifiedIdType())
-    ObjCQIString = "id";
-  else if (isObjCClassType() || isObjCQualifiedClassType())
-    ObjCQIString = "Class";
-  else
-    ObjCQIString = getInterfaceDecl()->getNameAsString();
-
-  if (!qual_empty()) {
-    ObjCQIString += '<';
-    for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
-      ObjCQIString += (*I)->getNameAsString();
-      if (I+1 != E)
-        ObjCQIString += ',';
-    }
-    ObjCQIString += '>';
-  }
-
-  PointeeType.getQualifiers().getAsStringInternal(ObjCQIString, Policy);
-
-  if (!isObjCIdType() && !isObjCQualifiedIdType())
-    ObjCQIString += " *"; // Don't forget the implicit pointer.
-  else if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
-    InnerString = ' ' + InnerString;
-
-  InnerString = ObjCQIString + InnerString;
-}
-
-void ElaboratedType::getAsStringInternal(std::string &InnerString,
-                                         const PrintingPolicy &Policy) const {
-  std::string TypeStr;
-  PrintingPolicy InnerPolicy(Policy);
-  InnerPolicy.SuppressTagKind = true;
-  UnderlyingType.getAsStringInternal(InnerString, InnerPolicy);
-
-  InnerString = std::string(getNameForTagKind(getTagKind())) + ' ' + InnerString;
-}
-
-void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  if (Policy.SuppressTag)
-    return;
-
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
-    InnerString = ' ' + InnerString;
-
-  const char *Kind = Policy.SuppressTagKind? 0 : getDecl()->getKindName();
-  const char *ID;
-  if (const IdentifierInfo *II = getDecl()->getIdentifier())
-    ID = II->getNameStart();
-  else if (TypedefDecl *Typedef = getDecl()->getTypedefForAnonDecl()) {
-    Kind = 0;
-    assert(Typedef->getIdentifier() && "Typedef without identifier?");
-    ID = Typedef->getIdentifier()->getNameStart();
-  } else
-    ID = "<anonymous>";
-
-  // If this is a class template specialization, print the template
-  // arguments.
-  if (ClassTemplateSpecializationDecl *Spec
-        = dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
-    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-    std::string TemplateArgsStr
-      = TemplateSpecializationType::PrintTemplateArgumentList(
-                                            TemplateArgs.getFlatArgumentList(),
-                                            TemplateArgs.flat_size(),
-                                                              Policy);
-    InnerString = TemplateArgsStr + InnerString;
-  }
-
-  if (!Policy.SuppressScope) {
-    // Compute the full nested-name-specifier for this type. In C,
-    // this will always be empty.
-    std::string ContextStr;
-    for (DeclContext *DC = getDecl()->getDeclContext();
-         !DC->isTranslationUnit(); DC = DC->getParent()) {
-      std::string MyPart;
-      if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
-        if (NS->getIdentifier())
-          MyPart = NS->getNameAsString();
-      } else if (ClassTemplateSpecializationDecl *Spec
-                   = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
-        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-        std::string TemplateArgsStr
-          = TemplateSpecializationType::PrintTemplateArgumentList(
-                                           TemplateArgs.getFlatArgumentList(),
-                                           TemplateArgs.flat_size(),
-                                           Policy);
-        MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
-      } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
-        if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
-          MyPart = Typedef->getIdentifier()->getName();
-        else if (Tag->getIdentifier())
-          MyPart = Tag->getIdentifier()->getName();
-      }
-
-      if (!MyPart.empty())
-        ContextStr = MyPart + "::" + ContextStr;
-    }
-
-    if (Kind)
-      InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
-    else
-      InnerString = ContextStr + ID + InnerString;
-  } else
-    InnerString = ID + InnerString;
-}

Added: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=86629&view=auto

==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (added)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Nov  9 18:39:07 2009
@@ -0,0 +1,721 @@
+//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to print types from Clang's type system.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+  class TypePrinter {
+    PrintingPolicy Policy;
+
+  public:
+    explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
+    
+    void Print(QualType T, std::string &S);
+    void PrintTag(const TagType *T, std::string &S);
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) \
+  void Print##CLASS(const CLASS##Type *T, std::string &S);
+#include "clang/AST/TypeNodes.def"
+  };
+}
+
+static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
+  if (TypeQuals & Qualifiers::Const) {
+    if (!S.empty()) S += ' ';
+    S += "const";
+  }
+  if (TypeQuals & Qualifiers::Volatile) {
+    if (!S.empty()) S += ' ';
+    S += "volatile";
+  }
+  if (TypeQuals & Qualifiers::Restrict) {
+    if (!S.empty()) S += ' ';
+    S += "restrict";
+  }
+}
+
+void TypePrinter::Print(QualType T, std::string &S) {
+  if (T.isNull()) {
+    S += "NULL TYPE";
+    return;
+  }
+  
+  if (Policy.SuppressSpecifiers && T->isSpecifierType())
+    return;
+  
+  // Print qualifiers as appropriate.
+  Qualifiers Quals = T.getQualifiers();
+  if (!Quals.empty()) {
+    std::string TQS;
+    Quals.getAsStringInternal(TQS, Policy);
+    
+    if (!S.empty()) {
+      TQS += ' ';
+      TQS += S;
+    }
+    std::swap(S, TQS);
+  }
+  
+  switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) case Type::CLASS:                \
+    Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S);      \
+    break;
+#include "clang/AST/TypeNodes.def"
+  }
+}
+
+void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
+  if (S.empty()) {
+    S = T->getName(Policy.LangOpts);
+  } else {
+    // Prefix the basic type, e.g. 'int X'.
+    S = ' ' + S;
+    S = T->getName(Policy.LangOpts) + S;
+  }
+}
+
+void TypePrinter::PrintFixedWidthInt(const FixedWidthIntType *T, 
+                                     std::string &S) {
+  // FIXME: Once we get bitwidth attribute, write as
+  // "int __attribute__((bitwidth(x)))".
+  std::string prefix = "__clang_fixedwidth";
+  prefix += llvm::utostr_32(T->getWidth());
+  prefix += (char)(T->isSigned() ? 'S' : 'U');
+  if (S.empty()) {
+    S = prefix;
+  } else {
+    // Prefix the basic type, e.g. 'int X'.
+    S = prefix + S;
+  }  
+}
+
+void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
+  Print(T->getElementType(), S);
+  S = "_Complex " + S;
+}
+
+void TypePrinter::PrintPointer(const PointerType *T, std::string &S) { 
+  S = '*' + S;
+  
+  // Handle things like 'int (*A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeType()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
+  S = '^' + S;
+  Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintLValueReference(const LValueReferenceType *T, 
+                                       std::string &S) { 
+  S = '&' + S;
+  
+  // Handle things like 'int (&A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeTypeAsWritten(), S);
+}
+
+void TypePrinter::PrintRValueReference(const RValueReferenceType *T, 
+                                       std::string &S) { 
+  S = "&&" + S;
+  
+  // Handle things like 'int (&&A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeTypeAsWritten(), S);
+}
+
+void TypePrinter::PrintMemberPointer(const MemberPointerType *T, 
+                                     std::string &S) { 
+  std::string C;
+  Print(QualType(T->getClass(), 0), C);
+  C += "::*";
+  S = C + S;
+  
+  // Handle things like 'int (Cls::*A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(T->getPointeeType()))
+    S = '(' + S + ')';
+  
+  Print(T->getPointeeType(), S);
+}
+
+void TypePrinter::PrintConstantArray(const ConstantArrayType *T, 
+                                     std::string &S) {
+  S += '[';
+  S += llvm::utostr(T->getSize().getZExtValue());
+  S += ']';
+  
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 
+                                       std::string &S) {
+  S += "[]";
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintVariableArray(const VariableArrayType *T, 
+                                     std::string &S) { 
+  S += '[';
+  
+  if (T->getIndexTypeQualifiers().hasQualifiers()) {
+    AppendTypeQualList(S, T->getIndexTypeCVRQualifiers());
+    S += ' ';
+  }
+  
+  if (T->getSizeModifier() == VariableArrayType::Static)
+    S += "static";
+  else if (T->getSizeModifier() == VariableArrayType::Star)
+    S += '*';
+  
+  if (T->getSizeExpr()) {
+    std::string SStr;
+    llvm::raw_string_ostream s(SStr);
+    T->getSizeExpr()->printPretty(s, 0, Policy);
+    S += s.str();
+  }
+  S += ']';
+  
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 
+                                           std::string &S) {  
+  S += '[';
+  
+  if (T->getSizeExpr()) {
+    std::string SStr;
+    llvm::raw_string_ostream s(SStr);
+    T->getSizeExpr()->printPretty(s, 0, Policy);
+    S += s.str();
+  }
+  S += ']';
+  
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintDependentSizedExtVector(
+                                          const DependentSizedExtVectorType *T, 
+                                               std::string &S) { 
+  Print(T->getElementType(), S);
+  
+  S += " __attribute__((ext_vector_type(";
+  if (T->getSizeExpr()) {
+    std::string SStr;
+    llvm::raw_string_ostream s(SStr);
+    T->getSizeExpr()->printPretty(s, 0, Policy);
+    S += s.str();
+  }
+  S += ")))";  
+}
+
+void TypePrinter::PrintVector(const VectorType *T, std::string &S) { 
+  // FIXME: We prefer to print the size directly here, but have no way
+  // to get the size of the type.
+  S += " __attribute__((__vector_size__(";
+  S += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
+  std::string ET;
+  Print(T->getElementType(), ET);
+  S += " * sizeof(" + ET + "))))";
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 
+  S += " __attribute__((ext_vector_type(";
+  S += llvm::utostr_32(T->getNumElements());
+  S += ")))";
+  Print(T->getElementType(), S);
+}
+
+void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 
+                                     std::string &S) { 
+  // If needed for precedence reasons, wrap the inner part in grouping parens.
+  if (!S.empty())
+    S = "(" + S + ")";
+  
+  S += "(";
+  std::string Tmp;
+  PrintingPolicy ParamPolicy(Policy);
+  ParamPolicy.SuppressSpecifiers = false;
+  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+    if (i) S += ", ";
+    Print(T->getArgType(i), Tmp);
+    S += Tmp;
+    Tmp.clear();
+  }
+  
+  if (T->isVariadic()) {
+    if (T->getNumArgs())
+      S += ", ";
+    S += "...";
+  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
+    // Do not emit int() if we have a proto, emit 'int(void)'.
+    S += "void";
+  }
+  
+  S += ")";
+  if (T->getNoReturnAttr())
+    S += " __attribute__((noreturn))";
+  Print(T->getResultType(), S);
+  
+}
+
+void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 
+                                       std::string &S) { 
+  // If needed for precedence reasons, wrap the inner part in grouping parens.
+  if (!S.empty())
+    S = "(" + S + ")";
+  
+  S += "()";
+  if (T->getNoReturnAttr())
+    S += " __attribute__((noreturn))";
+  Print(T->getResultType(), S);
+}
+
+void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
+    S = ' ' + S;
+  S = T->getDecl()->getIdentifier()->getName().str() + S;  
+}
+
+void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
+  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
+    S = ' ' + S;
+  std::string Str;
+  llvm::raw_string_ostream s(Str);
+  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
+  S = "typeof " + s.str() + S;
+}
+
+void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
+    S = ' ' + S;
+  std::string Tmp;
+  Print(T->getUnderlyingType(), Tmp);
+  S = "typeof(" + Tmp + ")" + S;
+}
+
+void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
+    S = ' ' + S;
+  std::string Str;
+  llvm::raw_string_ostream s(Str);
+  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
+  S = "decltype(" + s.str() + ")" + S;
+}
+
+void TypePrinter::PrintTag(const TagType *T, std::string &InnerString) {
+  if (Policy.SuppressTag)
+    return;
+  
+  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
+    InnerString = ' ' + InnerString;
+  
+  const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName();
+  const char *ID;
+  if (const IdentifierInfo *II = T->getDecl()->getIdentifier())
+    ID = II->getNameStart();
+  else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) {
+    Kind = 0;
+    assert(Typedef->getIdentifier() && "Typedef without identifier?");
+    ID = Typedef->getIdentifier()->getNameStart();
+  } else
+    ID = "<anonymous>";
+  
+  // If this is a class template specialization, print the template
+  // arguments.
+  if (ClassTemplateSpecializationDecl *Spec
+      = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
+    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+    std::string TemplateArgsStr
+      = TemplateSpecializationType::PrintTemplateArgumentList(
+                                            TemplateArgs.getFlatArgumentList(),
+                                            TemplateArgs.flat_size(),
+                                            Policy);
+    InnerString = TemplateArgsStr + InnerString;
+  }
+  
+  if (!Policy.SuppressScope) {
+    // Compute the full nested-name-specifier for this type. In C,
+    // this will always be empty.
+    std::string ContextStr;
+    for (DeclContext *DC = T->getDecl()->getDeclContext();
+         !DC->isTranslationUnit(); DC = DC->getParent()) {
+      std::string MyPart;
+      if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
+        if (NS->getIdentifier())
+          MyPart = NS->getNameAsString();
+      } else if (ClassTemplateSpecializationDecl *Spec
+                  = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
+        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+        std::string TemplateArgsStr
+          = TemplateSpecializationType::PrintTemplateArgumentList(
+                                            TemplateArgs.getFlatArgumentList(),
+                                            TemplateArgs.flat_size(),
+                                            Policy);
+        MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
+      } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
+        if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
+          MyPart = Typedef->getIdentifier()->getName();
+        else if (Tag->getIdentifier())
+          MyPart = Tag->getIdentifier()->getName();
+      }
+      
+      if (!MyPart.empty())
+        ContextStr = MyPart + "::" + ContextStr;
+    }
+    
+    if (Kind)
+      InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
+    else
+      InnerString = ContextStr + ID + InnerString;
+  } else
+    InnerString = ID + InnerString;  
+}
+
+void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
+  PrintTag(T, S);
+}
+
+void TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 
+  PrintTag(T, S);
+}
+
+void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 
+  std::string TypeStr;
+  PrintingPolicy InnerPolicy(Policy);
+  InnerPolicy.SuppressTagKind = true;
+  TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S);
+  
+  S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;  
+}
+
+void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 
+                                        std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
+    S = ' ' + S;
+  
+  if (!T->getName())
+    S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
+        llvm::utostr_32(T->getIndex()) + S;
+  else
+    S = T->getName()->getName().str() + S;  
+}
+
+void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 
+                                             std::string &S) { 
+  Print(T->getReplacementType(), S);
+}
+
+void TypePrinter::PrintTemplateSpecialization(
+                                            const TemplateSpecializationType *T, 
+                                              std::string &S) { 
+  std::string SpecString;
+  
+  {
+    llvm::raw_string_ostream OS(SpecString);
+    T->getTemplateName().print(OS, Policy);
+  }
+  
+  SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
+                                                                  T->getArgs(), 
+                                                                T->getNumArgs(), 
+                                                                      Policy);
+  if (S.empty())
+    S.swap(SpecString);
+  else
+    S = SpecString + ' ' + S;
+}
+
+void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 
+                                     std::string &S) { 
+  std::string MyString;
+  
+  {
+    llvm::raw_string_ostream OS(MyString);
+    T->getQualifier()->print(OS, Policy);
+  }
+  
+  std::string TypeStr;
+  PrintingPolicy InnerPolicy(Policy);
+  InnerPolicy.SuppressTagKind = true;
+  InnerPolicy.SuppressScope = true;
+  TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
+  
+  MyString += TypeStr;
+  if (S.empty())
+    S.swap(MyString);
+  else
+    S = MyString + ' ' + S;  
+}
+
+void TypePrinter::PrintTypename(const TypenameType *T, std::string &S) { 
+  std::string MyString;
+  
+  {
+    llvm::raw_string_ostream OS(MyString);
+    OS << "typename ";
+    T->getQualifier()->print(OS, Policy);
+    
+    if (const IdentifierInfo *Ident = T->getIdentifier())
+      OS << Ident->getName();
+    else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
+      Spec->getTemplateName().print(OS, Policy, true);
+      OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                            Spec->getArgs(),
+                                                            Spec->getNumArgs(),
+                                                            Policy);
+    }
+  }
+  
+  if (S.empty())
+    S.swap(MyString);
+  else
+    S = MyString + ' ' + S;
+}
+
+void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 
+                                     std::string &S) { 
+  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
+    S = ' ' + S;
+  
+  std::string ObjCQIString = T->getDecl()->getNameAsString();
+  if (T->getNumProtocols()) {
+    ObjCQIString += '<';
+    bool isFirst = true;
+    for (ObjCInterfaceType::qual_iterator I = T->qual_begin(), 
+                                          E = T->qual_end(); 
+         I != E; ++I) {
+      if (isFirst)
+        isFirst = false;
+      else
+        ObjCQIString += ',';
+      ObjCQIString += (*I)->getNameAsString();
+    }
+    ObjCQIString += '>';
+  }
+  S = ObjCQIString + S;
+}
+
+void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 
+                                         std::string &S) { 
+  std::string ObjCQIString;
+  
+  if (T->isObjCIdType() || T->isObjCQualifiedIdType())
+    ObjCQIString = "id";
+  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
+    ObjCQIString = "Class";
+  else
+    ObjCQIString = T->getInterfaceDecl()->getNameAsString();
+  
+  if (!T->qual_empty()) {
+    ObjCQIString += '<';
+    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 
+                                              E = T->qual_end();
+         I != E; ++I) {
+      ObjCQIString += (*I)->getNameAsString();
+      if (I+1 != E)
+        ObjCQIString += ',';
+    }
+    ObjCQIString += '>';
+  }
+  
+  T->getPointeeType().getQualifiers().getAsStringInternal(ObjCQIString, Policy);
+  
+  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
+    ObjCQIString += " *"; // Don't forget the implicit pointer.
+  else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
+    S = ' ' + S;
+  
+  S = ObjCQIString + S;  
+}
+
+static void PrintTemplateArgument(std::string &Buffer,
+                                  const TemplateArgument &Arg,
+                                  const PrintingPolicy &Policy) {
+  switch (Arg.getKind()) {
+    case TemplateArgument::Null:
+      assert(false && "Null template argument");
+      break;
+      
+    case TemplateArgument::Type:
+      Arg.getAsType().getAsStringInternal(Buffer, Policy);
+      break;
+      
+    case TemplateArgument::Declaration:
+      Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
+      break;
+      
+    case TemplateArgument::Integral:
+      Buffer = Arg.getAsIntegral()->toString(10, true);
+      break;
+      
+    case TemplateArgument::Expression: {
+      llvm::raw_string_ostream s(Buffer);
+      Arg.getAsExpr()->printPretty(s, 0, Policy);
+      break;
+    }
+      
+    case TemplateArgument::Pack:
+      assert(0 && "FIXME: Implement!");
+      break;
+  }
+}
+
+std::string
+TemplateSpecializationType::PrintTemplateArgumentList(
+                                                const TemplateArgument *Args,
+                                                unsigned NumArgs,
+                                                const PrintingPolicy &Policy) {
+  std::string SpecString;
+  SpecString += '<';
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    if (Arg)
+      SpecString += ", ";
+    
+    // Print the argument into a string.
+    std::string ArgString;
+    PrintTemplateArgument(ArgString, Args[Arg], Policy);
+    
+    // If this is the first argument and its string representation
+    // begins with the global scope specifier ('::foo'), add a space
+    // to avoid printing the diagraph '<:'.
+    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+      SpecString += ' ';
+    
+    SpecString += ArgString;
+  }
+  
+  // If the last character of our string is '>', add another space to
+  // keep the two '>''s separate tokens. We don't *have* to do this in
+  // C++0x, but it's still good hygiene.
+  if (SpecString[SpecString.size() - 1] == '>')
+    SpecString += ' ';
+  
+  SpecString += '>';
+  
+  return SpecString;
+}
+
+// Sadly, repeat all that with TemplateArgLoc.
+std::string TemplateSpecializationType::
+PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
+                          const PrintingPolicy &Policy) {
+  std::string SpecString;
+  SpecString += '<';
+  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+    if (Arg)
+      SpecString += ", ";
+    
+    // Print the argument into a string.
+    std::string ArgString;
+    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
+    
+    // If this is the first argument and its string representation
+    // begins with the global scope specifier ('::foo'), add a space
+    // to avoid printing the diagraph '<:'.
+    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+      SpecString += ' ';
+    
+    SpecString += ArgString;
+  }
+  
+  // If the last character of our string is '>', add another space to
+  // keep the two '>''s separate tokens. We don't *have* to do this in
+  // C++0x, but it's still good hygiene.
+  if (SpecString[SpecString.size() - 1] == '>')
+    SpecString += ' ';
+  
+  SpecString += '>';
+  
+  return SpecString;
+}
+
+void QualType::dump(const char *msg) const {
+  std::string R = "identifier";
+  LangOptions LO;
+  getAsStringInternal(R, PrintingPolicy(LO));
+  if (msg)
+    fprintf(stderr, "%s: %s\n", msg, R.c_str());
+  else
+    fprintf(stderr, "%s\n", R.c_str());
+}
+void QualType::dump() const {
+  dump("");
+}
+
+void Type::dump() const {
+  QualType(this, 0).dump();
+}
+
+std::string Qualifiers::getAsString() const {
+  LangOptions LO;
+  return getAsString(PrintingPolicy(LO));
+}
+
+// Appends qualifiers to the given string, separated by spaces.  Will
+// prefix a space if the string is non-empty.  Will not append a final
+// space.
+void Qualifiers::getAsStringInternal(std::string &S,
+                                     const PrintingPolicy&) const {
+  AppendTypeQualList(S, getCVRQualifiers());
+  if (unsigned AddressSpace = getAddressSpace()) {
+    if (!S.empty()) S += ' ';
+    S += "__attribute__((address_space(";
+    S += llvm::utostr_32(AddressSpace);
+    S += ")))";
+  }
+  if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
+    if (!S.empty()) S += ' ';
+    S += "__attribute__((objc_gc(";
+    if (GCAttrType == Qualifiers::Weak)
+      S += "weak";
+    else
+      S += "strong";
+    S += ")))";
+  }
+}
+
+std::string QualType::getAsString() const {
+  std::string S;
+  LangOptions LO;
+  getAsStringInternal(S, PrintingPolicy(LO));
+  return S;
+}
+
+void QualType::getAsStringInternal(std::string &S,
+                                   const PrintingPolicy &Policy) const {
+  TypePrinter Printer(Policy);
+  Printer.Print(*this, S);
+}
+




More information about the cfe-commits mailing list