[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 16:39:09 PST 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