TypePrinter.cpp revision 16834e88b9102b7c6562a6bb8a8931a58ebda900
1fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===// 2fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// 3fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// The LLVM Compiler Infrastructure 4fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// 5fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// This file is distributed under the University of Illinois Open Source 6fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// License. See LICENSE.TXT for details. 7fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// 8fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//===----------------------------------------------------------------------===// 9fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// 10fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// This contains code to print types from Clang's type system. 11fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// 12fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//===----------------------------------------------------------------------===// 13fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 14fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/Decl.h" 15fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/DeclObjC.h" 16fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/DeclTemplate.h" 17fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/Expr.h" 18fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/Type.h" 19fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/PrettyPrinter.h" 20fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/Basic/LangOptions.h" 2173061d054128e486e70e0f2874b23d6eca067e5bJohn McCall#include "clang/Basic/SourceManager.h" 22fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "llvm/ADT/StringExtras.h" 23fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "llvm/Support/raw_ostream.h" 24fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorusing namespace clang; 25fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 26fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregornamespace { 27fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor class TypePrinter { 28fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintingPolicy Policy; 29fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 30fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor public: 31fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { } 32493ec51db3a0cfa6f32e612c92c8eb0580dc9ebcAbramo Bagnara 33fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor void Print(QualType T, std::string &S); 347c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall void AppendScope(DeclContext *DC, std::string &S); 353cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall void PrintTag(TagDecl *T, std::string &S); 36fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT) 37fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define TYPE(CLASS, PARENT) \ 38fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor void Print##CLASS(const CLASS##Type *T, std::string &S); 39fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/TypeNodes.def" 40fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor }; 41fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 42fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 43fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstatic void AppendTypeQualList(std::string &S, unsigned TypeQuals) { 44fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (TypeQuals & Qualifiers::Const) { 45fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 46fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "const"; 47fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 48fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (TypeQuals & Qualifiers::Volatile) { 49fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 50fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "volatile"; 51fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 52fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (TypeQuals & Qualifiers::Restrict) { 53fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 54fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "restrict"; 55fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 56fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 57fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 58fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::Print(QualType T, std::string &S) { 59fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T.isNull()) { 60fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "NULL TYPE"; 61fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return; 62fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 63fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 64fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Policy.SuppressSpecifiers && T->isSpecifierType()) 65fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return; 66fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 67fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Print qualifiers as appropriate. 68a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor Qualifiers Quals = T.getLocalQualifiers(); 69fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!Quals.empty()) { 70fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string TQS; 71fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Quals.getAsStringInternal(TQS, Policy); 72fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 73fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) { 74fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TQS += ' '; 75fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TQS += S; 76fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 77fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::swap(S, TQS); 78fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 79fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 80fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor switch (T->getTypeClass()) { 81fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT) 82fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define TYPE(CLASS, PARENT) case Type::CLASS: \ 83fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S); \ 84fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 85fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/TypeNodes.def" 86fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 87fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 88fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 89fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) { 90fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) { 91fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = T->getName(Policy.LangOpts); 92fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else { 93fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Prefix the basic type, e.g. 'int X'. 94fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 95fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = T->getName(Policy.LangOpts) + S; 96fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 97fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 98fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 99fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintComplex(const ComplexType *T, std::string &S) { 100fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 101fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "_Complex " + S; 102fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 103fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 104fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintPointer(const PointerType *T, std::string &S) { 105fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '*' + S; 106fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 107fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (*A)[4];' correctly. 108fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 109fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeType())) 110fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 111fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 112fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeType(), S); 113fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 114fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 115fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) { 116fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '^' + S; 117fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeType(), S); 118fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 119fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 120fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintLValueReference(const LValueReferenceType *T, 121fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 122fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '&' + S; 123fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 124fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (&A)[4];' correctly. 125fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 126fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 127fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 128fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 129fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeTypeAsWritten(), S); 130fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 131fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 132fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintRValueReference(const RValueReferenceType *T, 133fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 134fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "&&" + S; 135fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 136fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (&&A)[4];' correctly. 137fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 138fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 139fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 140fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 141fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeTypeAsWritten(), S); 142fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 143fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 144fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintMemberPointer(const MemberPointerType *T, 145fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 146fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string C; 147fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(QualType(T->getClass(), 0), C); 148fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor C += "::*"; 149fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = C + S; 150fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 151fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (Cls::*A)[4];' correctly. 152fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 153fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeType())) 154fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 155fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 156fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeType(), S); 157fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 158fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 159fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintConstantArray(const ConstantArrayType *T, 160fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 161fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '['; 162fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += llvm::utostr(T->getSize().getZExtValue()); 163fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ']'; 164fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 165fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 166fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 167fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 168fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 169fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 170fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "[]"; 171fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 172fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 173fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 174fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintVariableArray(const VariableArrayType *T, 175fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 176fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '['; 177fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 178fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getIndexTypeQualifiers().hasQualifiers()) { 179fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor AppendTypeQualList(S, T->getIndexTypeCVRQualifiers()); 180fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ' '; 181fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 182fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 183fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeModifier() == VariableArrayType::Static) 184fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "static"; 185fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (T->getSizeModifier() == VariableArrayType::Star) 186fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '*'; 187fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 188fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeExpr()) { 189fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SStr; 190fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(SStr); 191fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getSizeExpr()->printPretty(s, 0, Policy); 192fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += s.str(); 193fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 194fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ']'; 195fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 196fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 197fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 198fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 199fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 200fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 201fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '['; 202fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 203fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeExpr()) { 204fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SStr; 205fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(SStr); 206fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getSizeExpr()->printPretty(s, 0, Policy); 207fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += s.str(); 208fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 209fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ']'; 210fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 211fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 212fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 213fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 214fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDependentSizedExtVector( 215fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const DependentSizedExtVectorType *T, 216fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 217fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 218fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 219fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += " __attribute__((ext_vector_type("; 220fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeExpr()) { 221fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SStr; 222fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(SStr); 223fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getSizeExpr()->printPretty(s, 0, Policy); 224fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += s.str(); 225fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 226fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 227fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 228fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 229fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintVector(const VectorType *T, std::string &S) { 23082287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson if (T->isAltiVec()) { 23182287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson if (T->isPixel()) 23282287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson S = "__vector __pixel " + S; 23382287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson else { 23482287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson Print(T->getElementType(), S); 23582287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson S = "__vector " + S; 23682287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson } 23782287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson } else { 23882287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // FIXME: We prefer to print the size directly here, but have no way 23982287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson // to get the size of the type. 24082287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson Print(T->getElementType(), S); 24182287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson std::string V = "__attribute__((__vector_size__("; 24282287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson V += llvm::utostr_32(T->getNumElements()); // convert back to bytes. 24382287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson std::string ET; 24482287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson Print(T->getElementType(), ET); 24582287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson V += " * sizeof(" + ET + ")))) "; 24682287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson S = V + S; 24782287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson } 248fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 249fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 250fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 251fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += " __attribute__((ext_vector_type("; 252fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += llvm::utostr_32(T->getNumElements()); 253fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 254fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 255fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 256fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 257fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 258fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 259fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If needed for precedence reasons, wrap the inner part in grouping parens. 260fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) 261fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "(" + S + ")"; 262fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 263fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "("; 264fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Tmp; 265fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintingPolicy ParamPolicy(Policy); 266fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ParamPolicy.SuppressSpecifiers = false; 267fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { 268fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (i) S += ", "; 269fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getArgType(i), Tmp); 270fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += Tmp; 271fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Tmp.clear(); 272fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 273fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 274fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->isVariadic()) { 275fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getNumArgs()) 276fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ", "; 277fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "..."; 278fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { 279fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Do not emit int() if we have a proto, emit 'int(void)'. 280fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "void"; 281fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 282fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 283fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")"; 2840ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor 285264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola FunctionType::ExtInfo Info = T->getExtInfo(); 286264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola switch(Info.getCC()) { 287f82b4e85b1219295cad4b5851b035575bc293010John McCall case CC_Default: 288f82b4e85b1219295cad4b5851b035575bc293010John McCall default: break; 289f82b4e85b1219295cad4b5851b035575bc293010John McCall case CC_C: 290f82b4e85b1219295cad4b5851b035575bc293010John McCall S += " __attribute__((cdecl))"; 291f82b4e85b1219295cad4b5851b035575bc293010John McCall break; 292f82b4e85b1219295cad4b5851b035575bc293010John McCall case CC_X86StdCall: 293f82b4e85b1219295cad4b5851b035575bc293010John McCall S += " __attribute__((stdcall))"; 294f82b4e85b1219295cad4b5851b035575bc293010John McCall break; 295f82b4e85b1219295cad4b5851b035575bc293010John McCall case CC_X86FastCall: 296f82b4e85b1219295cad4b5851b035575bc293010John McCall S += " __attribute__((fastcall))"; 297f82b4e85b1219295cad4b5851b035575bc293010John McCall break; 298f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case CC_X86ThisCall: 299f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor S += " __attribute__((thiscall))"; 300f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor break; 301f82b4e85b1219295cad4b5851b035575bc293010John McCall } 302264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola if (Info.getNoReturn()) 30348026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor S += " __attribute__((noreturn))"; 304425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola if (Info.getRegParm()) 305425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola S += " __attribute__((regparm (" + 306425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola llvm::utostr_32(Info.getRegParm()) + ")))"; 30748026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor 3080ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor if (T->hasExceptionSpec()) { 3090ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += " throw("; 3100ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor if (T->hasAnyExceptionSpec()) 3110ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += "..."; 3120ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor else 3130ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) { 3140ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor if (I) 3150ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += ", "; 3160ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor 3170ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor std::string ExceptionType; 3180ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor Print(T->getExceptionType(I), ExceptionType); 3190ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += ExceptionType; 3200ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor } 3210ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += ")"; 3220ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor } 3230ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor 32448026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor AppendTypeQualList(S, T->getTypeQuals()); 325fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 32648026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor Print(T->getResultType(), S); 327fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 328fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 329fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 330fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 331fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If needed for precedence reasons, wrap the inner part in grouping parens. 332fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) 333fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "(" + S + ")"; 334fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 335fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "()"; 336fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getNoReturnAttr()) 337fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += " __attribute__((noreturn))"; 338fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getResultType(), S); 339fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 340fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 3413cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCallstatic void PrintTypeSpec(const NamedDecl *D, std::string &S) { 3423cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall IdentifierInfo *II = D->getIdentifier(); 343ed97649e9574b9d854fa4d6109c9333ae0993554John McCall if (S.empty()) 344ed97649e9574b9d854fa4d6109c9333ae0993554John McCall S = II->getName().str(); 345ed97649e9574b9d854fa4d6109c9333ae0993554John McCall else 346ed97649e9574b9d854fa4d6109c9333ae0993554John McCall S = II->getName().str() + ' ' + S; 347ed97649e9574b9d854fa4d6109c9333ae0993554John McCall} 348ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 3493cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCallvoid TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T, 3503cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall std::string &S) { 3513cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall PrintTypeSpec(T->getDecl(), S); 3523cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall} 3533cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall 354fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 3553cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall PrintTypeSpec(T->getDecl(), S); 356fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 357fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 358fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) { 359fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'typeof(e) X'. 360fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 361fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Str; 362fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(Str); 363fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getUnderlyingExpr()->printPretty(s, 0, Policy); 364fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "typeof " + s.str() + S; 365fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 366fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 367fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) { 368fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'typeof(t) X'. 369fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 370fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Tmp; 371fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getUnderlyingType(), Tmp); 372fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "typeof(" + Tmp + ")" + S; 373fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 374fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 375fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { 376fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'decltype(t) X'. 377fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 378fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Str; 379fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(Str); 380fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getUnderlyingExpr()->printPretty(s, 0, Policy); 381fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "decltype(" + s.str() + ")" + S; 382fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 383fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 3847c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall/// Appends the given scope to the end of a string. 3857c2342dd4c9947806842e5aca3d2bb2e542853c9John McCallvoid TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) { 3867c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (DC->isTranslationUnit()) return; 3877c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall AppendScope(DC->getParent(), Buffer); 3887c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 3897c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall unsigned OldSize = Buffer.size(); 3907c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 3917c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 3927c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (NS->getIdentifier()) 3937c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += NS->getNameAsString(); 3947c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall else 3957c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += "<anonymous>"; 3967c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall } else if (ClassTemplateSpecializationDecl *Spec 3977c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { 3987c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 3997c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall std::string TemplateArgsStr 4007c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall = TemplateSpecializationType::PrintTemplateArgumentList( 4017c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall TemplateArgs.getFlatArgumentList(), 4027c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall TemplateArgs.flat_size(), 4037c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Policy); 4047c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += Spec->getIdentifier()->getName(); 4057c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += TemplateArgsStr; 4067c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { 4077c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) 4087c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += Typedef->getIdentifier()->getName(); 4097c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall else if (Tag->getIdentifier()) 4107c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += Tag->getIdentifier()->getName(); 4117c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall } 4127c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4137c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (Buffer.size() != OldSize) 4147c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += "::"; 4157c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall} 4167c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4173cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCallvoid TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) { 418fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Policy.SuppressTag) 419fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return; 4207c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4217c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall std::string Buffer; 42273061d054128e486e70e0f2874b23d6eca067e5bJohn McCall bool HasKindDecoration = false; 4237c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4247c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall // We don't print tags unless this is an elaborated type. 4257c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall // In C, we just assume every RecordType is an elaborated type. 4267c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) { 42773061d054128e486e70e0f2874b23d6eca067e5bJohn McCall HasKindDecoration = true; 4287c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += D->getKindName(); 4297c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += ' '; 4307c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall } 4317c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4327c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (!Policy.SuppressScope) 4337c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall // Compute the full nested-name-specifier for this type. In C, 4347c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall // this will always be empty. 4357c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall AppendScope(D->getDeclContext(), Buffer); 4367c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4373cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall if (const IdentifierInfo *II = D->getIdentifier()) 43873061d054128e486e70e0f2874b23d6eca067e5bJohn McCall Buffer += II->getNameStart(); 4393cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) { 440fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor assert(Typedef->getIdentifier() && "Typedef without identifier?"); 44173061d054128e486e70e0f2874b23d6eca067e5bJohn McCall Buffer += Typedef->getIdentifier()->getNameStart(); 44273061d054128e486e70e0f2874b23d6eca067e5bJohn McCall } else { 44373061d054128e486e70e0f2874b23d6eca067e5bJohn McCall // Make an unambiguous representation for anonymous types, e.g. 44473061d054128e486e70e0f2874b23d6eca067e5bJohn McCall // <anonymous enum at /usr/include/string.h:120:9> 44573061d054128e486e70e0f2874b23d6eca067e5bJohn McCall llvm::raw_string_ostream OS(Buffer); 44673061d054128e486e70e0f2874b23d6eca067e5bJohn McCall OS << "<anonymous"; 44773061d054128e486e70e0f2874b23d6eca067e5bJohn McCall 44884139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor if (Policy.AnonymousTagLocations) { 44984139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor // Suppress the redundant tag keyword if we just printed one. 45084139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor // We don't have to worry about ElaboratedTypes here because you can't 45184139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor // refer to an anonymous type with one. 45284139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor if (!HasKindDecoration) 45384139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor OS << " " << D->getKindName(); 45484139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor 45516834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor if (D->getLocation().isValid()) { 45616834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc( 45716834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor D->getLocation()); 45816834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor OS << " at " << PLoc.getFilename() 45916834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor << ':' << PLoc.getLine() 46016834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor << ':' << PLoc.getColumn(); 46116834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor } 46284139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor } 46384139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor 46484139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor OS << '>'; 46573061d054128e486e70e0f2874b23d6eca067e5bJohn McCall OS.flush(); 46673061d054128e486e70e0f2874b23d6eca067e5bJohn McCall } 4677c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 468fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If this is a class template specialization, print the template 469fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // arguments. 470fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (ClassTemplateSpecializationDecl *Spec 4717c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 4723cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall const TemplateArgument *Args; 4733cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall unsigned NumArgs; 4743cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { 4753cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall const TemplateSpecializationType *TST = 4763cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall cast<TemplateSpecializationType>(TAW->getType()); 4773cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall Args = TST->getArgs(); 4783cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall NumArgs = TST->getNumArgs(); 4793cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall } else { 4803cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 4813cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall Args = TemplateArgs.getFlatArgumentList(); 4823cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall NumArgs = TemplateArgs.flat_size(); 4833cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall } 4847c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args, 4857c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall NumArgs, 4867c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Policy); 487fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 4887c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4897c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall if (!InnerString.empty()) { 4907c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += ' '; 4917c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall Buffer += InnerString; 4927c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall } 4937c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall 4947c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall std::swap(Buffer, InnerString); 495fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 496fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 497fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintRecord(const RecordType *T, std::string &S) { 4983cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall PrintTag(T->getDecl(), S); 499fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 500fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 501fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 5023cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall PrintTag(T->getDecl(), S); 503fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 504fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 505fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 506fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 507fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'. 508fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 509fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 510fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!T->getName()) 511fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' + 512fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::utostr_32(T->getIndex()) + S; 513fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 514fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = T->getName()->getName().str() + S; 515fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 516fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 517fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 518fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 519fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getReplacementType(), S); 520fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 521fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 522fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTemplateSpecialization( 523fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateSpecializationType *T, 524fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 525fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SpecString; 526fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 527fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor { 528fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream OS(SpecString); 529fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getTemplateName().print(OS, Policy); 530fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 531fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 532fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += TemplateSpecializationType::PrintTemplateArgumentList( 533fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getArgs(), 534fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getNumArgs(), 535fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Policy); 536fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) 537fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S.swap(SpecString); 538fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 539fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = SpecString + ' ' + S; 540fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 541fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 5423cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCallvoid TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T, 5433cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall std::string &S) { 54431f17ecbef57b5679c017c375db330546b7b5145John McCall PrintTemplateSpecialization(T->getInjectedTST(), S); 5453cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall} 5463cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall 547465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnaravoid TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 548fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string MyString; 549fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 550fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor { 551fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream OS(MyString); 552465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 553465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (T->getKeyword() != ETK_None) 554465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara OS << " "; 555465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara NestedNameSpecifier* Qualifier = T->getQualifier(); 556465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (Qualifier) 557465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara Qualifier->print(OS, Policy); 558fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 559fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 560fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string TypeStr; 561fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintingPolicy InnerPolicy(Policy); 562fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerPolicy.SuppressScope = true; 563fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr); 564fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 565fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor MyString += TypeStr; 566fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) 567fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S.swap(MyString); 568fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 569fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = MyString + ' ' + S; 570fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 571fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 5724714c12a1ab759156b78be8f109ea4c12213af57Douglas Gregorvoid TypePrinter::PrintDependentName(const DependentNameType *T, std::string &S) { 573fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string MyString; 574fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 575fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor { 576fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream OS(MyString); 577465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 578465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (T->getKeyword() != ETK_None) 579465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara OS << " "; 5804a2023f5014e82389d5980d307b89c545dbbac81Douglas Gregor 581fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getQualifier()->print(OS, Policy); 582fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 583fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (const IdentifierInfo *Ident = T->getIdentifier()) 584fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor OS << Ident->getName(); 585fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (const TemplateSpecializationType *Spec = T->getTemplateId()) { 586fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Spec->getTemplateName().print(OS, Policy, true); 587fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor OS << TemplateSpecializationType::PrintTemplateArgumentList( 588fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Spec->getArgs(), 589fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Spec->getNumArgs(), 590fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Policy); 591fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 592fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 593fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 594fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) 595fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S.swap(MyString); 596fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 597fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = MyString + ' ' + S; 598fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 599fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 600fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 601fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 602fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 603fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 604c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 605fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ObjCQIString = T->getDecl()->getNameAsString(); 606fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ObjCQIString + S; 607fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 608fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 609c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallvoid TypePrinter::PrintObjCObject(const ObjCObjectType *T, 610c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall std::string &S) { 611c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (T->qual_empty()) 612c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return Print(T->getBaseType(), S); 613c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 614c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall std::string tmp; 615c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall Print(T->getBaseType(), tmp); 616c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall tmp += '<'; 617c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall bool isFirst = true; 618c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall for (ObjCObjectType::qual_iterator 619c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall I = T->qual_begin(), E = T->qual_end(); I != E; ++I) { 620c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (isFirst) 621c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall isFirst = false; 622c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall else 623c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall tmp += ','; 624c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall tmp += (*I)->getNameAsString(); 625c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall } 626c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall tmp += '>'; 627c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 628c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (!S.empty()) { 629c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall tmp += ' '; 630c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall tmp += S; 631c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall } 632c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall std::swap(tmp, S); 633c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall} 634c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 635fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 636fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 637fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ObjCQIString; 638fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 639fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->isObjCIdType() || T->isObjCQualifiedIdType()) 640fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString = "id"; 641fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) 642fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString = "Class"; 64313dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian else if (T->isObjCSelType()) 64413dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian ObjCQIString = "SEL"; 645fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 646fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString = T->getInterfaceDecl()->getNameAsString(); 647fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 648fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!T->qual_empty()) { 649fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += '<'; 650fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 651fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor E = T->qual_end(); 652fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor I != E; ++I) { 653fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += (*I)->getNameAsString(); 654fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (I+1 != E) 655fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += ','; 656fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 657fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += '>'; 658fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 659fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 660a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString, 661a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor Policy); 662fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 663fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) 664fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += " *"; // Don't forget the implicit pointer. 665fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 666fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 667fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 668fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ObjCQIString + S; 669fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 670fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 671fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstatic void PrintTemplateArgument(std::string &Buffer, 672fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateArgument &Arg, 673fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) { 674fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor switch (Arg.getKind()) { 675fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Null: 676fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor assert(false && "Null template argument"); 677fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 678fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 679fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Type: 680fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Arg.getAsType().getAsStringInternal(Buffer, Policy); 681fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 682fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 683fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Declaration: 684fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString(); 685fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 686fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 687788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor case TemplateArgument::Template: { 688788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor llvm::raw_string_ostream s(Buffer); 689788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Arg.getAsTemplate().print(s, Policy); 690fb898e17cff919bd28b88e9d93301d6e2cc5cbd1Douglas Gregor break; 691788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 692788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor 693fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Integral: 694fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Buffer = Arg.getAsIntegral()->toString(10, true); 695fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 696fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 697fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Expression: { 698fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(Buffer); 699fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Arg.getAsExpr()->printPretty(s, 0, Policy); 700fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 701fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 702fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 703fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Pack: 704fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor assert(0 && "FIXME: Implement!"); 705fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 706fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 707fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 708fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 709d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallstd::string TemplateSpecializationType:: 710d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall PrintTemplateArgumentList(const TemplateArgumentListInfo &Args, 711d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall const PrintingPolicy &Policy) { 712d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall return PrintTemplateArgumentList(Args.getArgumentArray(), 713d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall Args.size(), 714d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall Policy); 715d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall} 716d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 717fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string 718fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorTemplateSpecializationType::PrintTemplateArgumentList( 719fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateArgument *Args, 720fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor unsigned NumArgs, 721fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) { 722fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SpecString; 723fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '<'; 724fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 725fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Arg) 726fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ", "; 727fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 728fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Print the argument into a string. 729fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ArgString; 730fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintTemplateArgument(ArgString, Args[Arg], Policy); 731fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 732fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If this is the first argument and its string representation 733fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // begins with the global scope specifier ('::foo'), add a space 734fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // to avoid printing the diagraph '<:'. 735fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!Arg && !ArgString.empty() && ArgString[0] == ':') 736fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 737fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 738fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ArgString; 739fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 740fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 741fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If the last character of our string is '>', add another space to 742fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // keep the two '>''s separate tokens. We don't *have* to do this in 743fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // C++0x, but it's still good hygiene. 744fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (SpecString[SpecString.size() - 1] == '>') 745fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 746fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 747fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '>'; 748fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 749fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return SpecString; 750fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 751fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 752fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Sadly, repeat all that with TemplateArgLoc. 753fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string TemplateSpecializationType:: 754fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorPrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs, 755fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) { 756fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SpecString; 757fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '<'; 758fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 759fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Arg) 760fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ", "; 761fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 762fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Print the argument into a string. 763fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ArgString; 764fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy); 765fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 766fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If this is the first argument and its string representation 767fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // begins with the global scope specifier ('::foo'), add a space 768fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // to avoid printing the diagraph '<:'. 769fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!Arg && !ArgString.empty() && ArgString[0] == ':') 770fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 771fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 772fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ArgString; 773fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 774fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 775fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If the last character of our string is '>', add another space to 776fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // keep the two '>''s separate tokens. We don't *have* to do this in 777fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // C++0x, but it's still good hygiene. 778fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (SpecString[SpecString.size() - 1] == '>') 779fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 780fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 781fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '>'; 782fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 783fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return SpecString; 784fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 785fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 786fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump(const char *msg) const { 787fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string R = "identifier"; 788fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor LangOptions LO; 789fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor getAsStringInternal(R, PrintingPolicy(LO)); 790fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (msg) 791e7cb7e4570842297f698bd7fd8d85520fc008acdDaniel Dunbar llvm::errs() << msg << ": "; 792e7cb7e4570842297f698bd7fd8d85520fc008acdDaniel Dunbar llvm::errs() << R << "\n"; 793fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 794fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump() const { 795fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor dump(""); 796fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 797fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 798fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid Type::dump() const { 799fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor QualType(this, 0).dump(); 800fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 801fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 802fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string Qualifiers::getAsString() const { 803fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor LangOptions LO; 804fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return getAsString(PrintingPolicy(LO)); 805fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 806fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 807fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Appends qualifiers to the given string, separated by spaces. Will 808fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// prefix a space if the string is non-empty. Will not append a final 809fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// space. 810fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid Qualifiers::getAsStringInternal(std::string &S, 811fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy&) const { 812fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor AppendTypeQualList(S, getCVRQualifiers()); 813fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (unsigned AddressSpace = getAddressSpace()) { 814fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 815fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "__attribute__((address_space("; 816fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += llvm::utostr_32(AddressSpace); 817fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 818fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 819fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Qualifiers::GC GCAttrType = getObjCGCAttr()) { 820fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 821fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "__attribute__((objc_gc("; 822fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (GCAttrType == Qualifiers::Weak) 823fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "weak"; 824fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 825fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "strong"; 826fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 827fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 828fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 829fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 830fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string QualType::getAsString() const { 831fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string S; 832fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor LangOptions LO; 833fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor getAsStringInternal(S, PrintingPolicy(LO)); 834fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return S; 835fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 836fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 837fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::getAsStringInternal(std::string &S, 838fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) const { 839fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TypePrinter Printer(Policy); 840fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Printer.Print(*this, S); 841fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 842