TypePrinter.cpp revision 48026d26fb58e413544874eead5491b1452e2ebf
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" 21fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "llvm/ADT/StringExtras.h" 22fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "llvm/Support/raw_ostream.h" 23fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorusing namespace clang; 24fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 25fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregornamespace { 26fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor class TypePrinter { 27fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintingPolicy Policy; 28fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 29fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor public: 30fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { } 31fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 32fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor void Print(QualType T, std::string &S); 33fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor void PrintTag(const TagType *T, std::string &S); 34fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT) 35fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define TYPE(CLASS, PARENT) \ 36fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor void Print##CLASS(const CLASS##Type *T, std::string &S); 37fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/TypeNodes.def" 38fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor }; 39fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 40fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 41fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstatic void AppendTypeQualList(std::string &S, unsigned TypeQuals) { 42fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (TypeQuals & Qualifiers::Const) { 43fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 44fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "const"; 45fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 46fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (TypeQuals & Qualifiers::Volatile) { 47fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 48fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "volatile"; 49fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 50fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (TypeQuals & Qualifiers::Restrict) { 51fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 52fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "restrict"; 53fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 54fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 55fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 56fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::Print(QualType T, std::string &S) { 57fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T.isNull()) { 58fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "NULL TYPE"; 59fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return; 60fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 61fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 62fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Policy.SuppressSpecifiers && T->isSpecifierType()) 63fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return; 64fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 65fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Print qualifiers as appropriate. 66a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor Qualifiers Quals = T.getLocalQualifiers(); 67fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!Quals.empty()) { 68fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string TQS; 69fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Quals.getAsStringInternal(TQS, Policy); 70fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 71fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) { 72fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TQS += ' '; 73fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TQS += S; 74fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 75fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::swap(S, TQS); 76fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 77fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 78fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor switch (T->getTypeClass()) { 79fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT) 80fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define TYPE(CLASS, PARENT) case Type::CLASS: \ 81fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S); \ 82fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 83fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/TypeNodes.def" 84fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 85fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 86fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 87fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) { 88fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) { 89fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = T->getName(Policy.LangOpts); 90fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else { 91fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Prefix the basic type, e.g. 'int X'. 92fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 93fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = T->getName(Policy.LangOpts) + S; 94fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 95fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 96fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 97fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintComplex(const ComplexType *T, std::string &S) { 98fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 99fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "_Complex " + S; 100fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 101fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 102fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintPointer(const PointerType *T, std::string &S) { 103fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '*' + S; 104fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 105fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (*A)[4];' correctly. 106fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 107fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeType())) 108fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 109fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 110fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeType(), S); 111fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 112fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 113fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) { 114fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '^' + S; 115fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeType(), S); 116fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 117fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 118fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintLValueReference(const LValueReferenceType *T, 119fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 120fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '&' + S; 121fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 122fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (&A)[4];' correctly. 123fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 124fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 125fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 126fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 127fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeTypeAsWritten(), S); 128fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 129fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 130fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintRValueReference(const RValueReferenceType *T, 131fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 132fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "&&" + S; 133fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 134fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (&&A)[4];' correctly. 135fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 136fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 137fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 138fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 139fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeTypeAsWritten(), S); 140fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 141fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 142fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintMemberPointer(const MemberPointerType *T, 143fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 144fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string C; 145fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(QualType(T->getClass(), 0), C); 146fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor C += "::*"; 147fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = C + S; 148fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 149fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Handle things like 'int (Cls::*A)[4];' correctly. 150fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: this should include vectors, but vectors use attributes I guess. 151fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isa<ArrayType>(T->getPointeeType())) 152fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = '(' + S + ')'; 153fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 154fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getPointeeType(), S); 155fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 156fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 157fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintConstantArray(const ConstantArrayType *T, 158fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 159fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '['; 160fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += llvm::utostr(T->getSize().getZExtValue()); 161fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ']'; 162fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 163fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 164fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 165fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 166fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 167fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 168fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "[]"; 169fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 170fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 171fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 172fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintVariableArray(const VariableArrayType *T, 173fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 174fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '['; 175fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 176fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getIndexTypeQualifiers().hasQualifiers()) { 177fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor AppendTypeQualList(S, T->getIndexTypeCVRQualifiers()); 178fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ' '; 179fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 180fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 181fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeModifier() == VariableArrayType::Static) 182fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "static"; 183fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (T->getSizeModifier() == VariableArrayType::Star) 184fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '*'; 185fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 186fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeExpr()) { 187fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SStr; 188fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(SStr); 189fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getSizeExpr()->printPretty(s, 0, Policy); 190fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += s.str(); 191fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 192fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ']'; 193fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 194fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 195fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 196fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 197fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 198fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 199fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += '['; 200fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 201fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeExpr()) { 202fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SStr; 203fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(SStr); 204fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getSizeExpr()->printPretty(s, 0, Policy); 205fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += s.str(); 206fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 207fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ']'; 208fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 209fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 210fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 211fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 212fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDependentSizedExtVector( 213fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const DependentSizedExtVectorType *T, 214fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 215fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 216fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 217fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += " __attribute__((ext_vector_type("; 218fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getSizeExpr()) { 219fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SStr; 220fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(SStr); 221fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getSizeExpr()->printPretty(s, 0, Policy); 222fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += s.str(); 223fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 224fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 225fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 226fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 227fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintVector(const VectorType *T, std::string &S) { 228fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // FIXME: We prefer to print the size directly here, but have no way 229fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // to get the size of the type. 2306e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson Print(T->getElementType(), S); 2316e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson std::string V = "__attribute__((__vector_size__("; 2326e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson V += llvm::utostr_32(T->getNumElements()); // convert back to bytes. 233fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ET; 234fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), ET); 2356e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson V += " * sizeof(" + ET + ")))) "; 2366e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson S = V + S; 237fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 238fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 239fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 240fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += " __attribute__((ext_vector_type("; 241fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += llvm::utostr_32(T->getNumElements()); 242fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 243fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getElementType(), S); 244fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 245fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 246fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 247fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 248fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If needed for precedence reasons, wrap the inner part in grouping parens. 249fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) 250fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "(" + S + ")"; 251fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 252fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "("; 253fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Tmp; 254fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintingPolicy ParamPolicy(Policy); 255fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ParamPolicy.SuppressSpecifiers = false; 256fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { 257fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (i) S += ", "; 258fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getArgType(i), Tmp); 259fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += Tmp; 260fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Tmp.clear(); 261fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 262fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 263fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->isVariadic()) { 264fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getNumArgs()) 265fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ", "; 266fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "..."; 267fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { 268fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Do not emit int() if we have a proto, emit 'int(void)'. 269fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "void"; 270fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 271fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 272fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")"; 2730ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor 27448026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor if (T->getNoReturnAttr()) 27548026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor S += " __attribute__((noreturn))"; 27648026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor 27748026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor 2780ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor if (T->hasExceptionSpec()) { 2790ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += " throw("; 2800ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor if (T->hasAnyExceptionSpec()) 2810ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += "..."; 2820ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor else 2830ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) { 2840ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor if (I) 2850ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += ", "; 2860ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor 2870ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor std::string ExceptionType; 2880ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor Print(T->getExceptionType(I), ExceptionType); 2890ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += ExceptionType; 2900ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor } 2910ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor S += ")"; 2920ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor } 2930ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor 29448026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor AppendTypeQualList(S, T->getTypeQuals()); 295fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 29648026d26fb58e413544874eead5491b1452e2ebfDouglas Gregor Print(T->getResultType(), S); 297fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 298fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 299fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 300fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 301fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If needed for precedence reasons, wrap the inner part in grouping parens. 302fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) 303fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "(" + S + ")"; 304fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 305fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "()"; 306fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getNoReturnAttr()) 307fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += " __attribute__((noreturn))"; 308fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getResultType(), S); 309fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 310fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 311ed97649e9574b9d854fa4d6109c9333ae0993554John McCallvoid TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T, 312ed97649e9574b9d854fa4d6109c9333ae0993554John McCall std::string &S) { 313ed97649e9574b9d854fa4d6109c9333ae0993554John McCall IdentifierInfo *II = T->getDecl()->getIdentifier(); 314ed97649e9574b9d854fa4d6109c9333ae0993554John McCall if (S.empty()) 315ed97649e9574b9d854fa4d6109c9333ae0993554John McCall S = II->getName().str(); 316ed97649e9574b9d854fa4d6109c9333ae0993554John McCall else 317ed97649e9574b9d854fa4d6109c9333ae0993554John McCall S = II->getName().str() + ' ' + S; 318ed97649e9574b9d854fa4d6109c9333ae0993554John McCall} 319ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 320fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 321fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 322fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 323fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = T->getDecl()->getIdentifier()->getName().str() + S; 324fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 325fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 326fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) { 327fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'typeof(e) X'. 328fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 329fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Str; 330fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(Str); 331fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getUnderlyingExpr()->printPretty(s, 0, Policy); 332fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "typeof " + s.str() + S; 333fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 334fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 335fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) { 336fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'typeof(t) X'. 337fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 338fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Tmp; 339fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getUnderlyingType(), Tmp); 340fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "typeof(" + Tmp + ")" + S; 341fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 342fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 343fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { 344fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'decltype(t) X'. 345fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 346fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string Str; 347fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(Str); 348fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getUnderlyingExpr()->printPretty(s, 0, Policy); 349fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "decltype(" + s.str() + ")" + S; 350fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 351fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 352fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTag(const TagType *T, std::string &InnerString) { 353fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Policy.SuppressTag) 354fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return; 355fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 356fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. 357fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerString = ' ' + InnerString; 358fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 359fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName(); 360fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const char *ID; 361fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (const IdentifierInfo *II = T->getDecl()->getIdentifier()) 362fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ID = II->getNameStart(); 363fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) { 364fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Kind = 0; 365fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor assert(Typedef->getIdentifier() && "Typedef without identifier?"); 366fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ID = Typedef->getIdentifier()->getNameStart(); 367fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else 368fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ID = "<anonymous>"; 369fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 370fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If this is a class template specialization, print the template 371fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // arguments. 372fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (ClassTemplateSpecializationDecl *Spec 373fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) { 374fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 375fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string TemplateArgsStr 376fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor = TemplateSpecializationType::PrintTemplateArgumentList( 377fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TemplateArgs.getFlatArgumentList(), 378fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TemplateArgs.flat_size(), 379fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Policy); 380fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerString = TemplateArgsStr + InnerString; 381fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 382fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 383fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!Policy.SuppressScope) { 384fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Compute the full nested-name-specifier for this type. In C, 385fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // this will always be empty. 386fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ContextStr; 387fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (DeclContext *DC = T->getDecl()->getDeclContext(); 388fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor !DC->isTranslationUnit(); DC = DC->getParent()) { 389fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string MyPart; 390fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 391fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (NS->getIdentifier()) 392fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor MyPart = NS->getNameAsString(); 393fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else if (ClassTemplateSpecializationDecl *Spec 394fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { 395fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 396fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string TemplateArgsStr 397fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor = TemplateSpecializationType::PrintTemplateArgumentList( 398fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TemplateArgs.getFlatArgumentList(), 399fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TemplateArgs.flat_size(), 400fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Policy); 401fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr; 402fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { 403fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) 404fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor MyPart = Typedef->getIdentifier()->getName(); 405fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (Tag->getIdentifier()) 406fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor MyPart = Tag->getIdentifier()->getName(); 407fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 408fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 409fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!MyPart.empty()) 410fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ContextStr = MyPart + "::" + ContextStr; 411fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 412fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 413fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Kind) 414fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString; 415fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 416fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerString = ContextStr + ID + InnerString; 417fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } else 418fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerString = ID + InnerString; 419fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 420fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 421fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintRecord(const RecordType *T, std::string &S) { 422fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintTag(T, S); 423fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 424fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 425fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 426fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintTag(T, S); 427fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 428fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 429fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 430fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string TypeStr; 431fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintingPolicy InnerPolicy(Policy); 432fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerPolicy.SuppressTagKind = true; 433fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S); 434fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 435fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S; 436fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 437fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 438fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 439fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 440fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'. 441fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 442fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 443fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!T->getName()) 444fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' + 445fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::utostr_32(T->getIndex()) + S; 446fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 447fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = T->getName()->getName().str() + S; 448fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 449fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 450fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 451fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 452fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Print(T->getReplacementType(), S); 453fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 454fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 455fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTemplateSpecialization( 456fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateSpecializationType *T, 457fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 458fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SpecString; 459fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 460fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor { 461fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream OS(SpecString); 462fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getTemplateName().print(OS, Policy); 463fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 464fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 465fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += TemplateSpecializationType::PrintTemplateArgumentList( 466fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getArgs(), 467fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getNumArgs(), 468fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Policy); 469fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) 470fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S.swap(SpecString); 471fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 472fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = SpecString + ' ' + S; 473fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 474fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 475fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 476fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 477fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string MyString; 478fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 479fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor { 480fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream OS(MyString); 481fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getQualifier()->print(OS, Policy); 482fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 483fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 484fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string TypeStr; 485fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintingPolicy InnerPolicy(Policy); 486fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerPolicy.SuppressTagKind = true; 487fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor InnerPolicy.SuppressScope = true; 488fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr); 489fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 490fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor MyString += TypeStr; 491fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) 492fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S.swap(MyString); 493fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 494fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = MyString + ' ' + S; 495fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 496fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 497fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypename(const TypenameType *T, std::string &S) { 498fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string MyString; 499fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 500fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor { 501fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream OS(MyString); 502fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor OS << "typename "; 503fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor T->getQualifier()->print(OS, Policy); 504fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 505fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (const IdentifierInfo *Ident = T->getIdentifier()) 506fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor OS << Ident->getName(); 507fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (const TemplateSpecializationType *Spec = T->getTemplateId()) { 508fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Spec->getTemplateName().print(OS, Policy, true); 509fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor OS << TemplateSpecializationType::PrintTemplateArgumentList( 510fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Spec->getArgs(), 511fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Spec->getNumArgs(), 512fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Policy); 513fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 514fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 515fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 516fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (S.empty()) 517fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S.swap(MyString); 518fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 519fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = MyString + ' ' + S; 520fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 521fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 522fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 523fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 524fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 525fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 526fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 527fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ObjCQIString = T->getDecl()->getNameAsString(); 528fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->getNumProtocols()) { 529fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += '<'; 530fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor bool isFirst = true; 531fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (ObjCInterfaceType::qual_iterator I = T->qual_begin(), 532fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor E = T->qual_end(); 533fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor I != E; ++I) { 534fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (isFirst) 535fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor isFirst = false; 536fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 537fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += ','; 538fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += (*I)->getNameAsString(); 539fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 540fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += '>'; 541fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 542fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ObjCQIString + S; 543fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 544fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 545fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 546fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string &S) { 547fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ObjCQIString; 548fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 549fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (T->isObjCIdType() || T->isObjCQualifiedIdType()) 550fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString = "id"; 551fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) 552fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString = "Class"; 55313dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian else if (T->isObjCSelType()) 55413dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian ObjCQIString = "SEL"; 555fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 556fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString = T->getInterfaceDecl()->getNameAsString(); 557fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 558fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!T->qual_empty()) { 559fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += '<'; 560fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 561fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor E = T->qual_end(); 562fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor I != E; ++I) { 563fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += (*I)->getNameAsString(); 564fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (I+1 != E) 565fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += ','; 566fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 567fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += '>'; 568fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 569fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 570a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString, 571a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor Policy); 572fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 573fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) 574fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor ObjCQIString += " *"; // Don't forget the implicit pointer. 575fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 576fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ' ' + S; 577fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 578fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S = ObjCQIString + S; 579fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 580fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 581fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstatic void PrintTemplateArgument(std::string &Buffer, 582fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateArgument &Arg, 583fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) { 584fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor switch (Arg.getKind()) { 585fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Null: 586fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor assert(false && "Null template argument"); 587fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 588fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 589fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Type: 590fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Arg.getAsType().getAsStringInternal(Buffer, Policy); 591fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 592fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 593fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Declaration: 594fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString(); 595fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 596fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 597788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor case TemplateArgument::Template: { 598788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor llvm::raw_string_ostream s(Buffer); 599788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Arg.getAsTemplate().print(s, Policy); 600fb898e17cff919bd28b88e9d93301d6e2cc5cbd1Douglas Gregor break; 601788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 602788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor 603fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Integral: 604fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Buffer = Arg.getAsIntegral()->toString(10, true); 605fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 606fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 607fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Expression: { 608fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor llvm::raw_string_ostream s(Buffer); 609fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Arg.getAsExpr()->printPretty(s, 0, Policy); 610fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 611fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 612fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 613fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor case TemplateArgument::Pack: 614fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor assert(0 && "FIXME: Implement!"); 615fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor break; 616fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 617fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 618fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 619d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallstd::string TemplateSpecializationType:: 620d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall PrintTemplateArgumentList(const TemplateArgumentListInfo &Args, 621d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall const PrintingPolicy &Policy) { 622d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall return PrintTemplateArgumentList(Args.getArgumentArray(), 623d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall Args.size(), 624d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall Policy); 625d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall} 626d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 627fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string 628fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorTemplateSpecializationType::PrintTemplateArgumentList( 629fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const TemplateArgument *Args, 630fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor unsigned NumArgs, 631fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) { 632fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SpecString; 633fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '<'; 634fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 635fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Arg) 636fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ", "; 637fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 638fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Print the argument into a string. 639fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ArgString; 640fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintTemplateArgument(ArgString, Args[Arg], Policy); 641fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 642fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If this is the first argument and its string representation 643fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // begins with the global scope specifier ('::foo'), add a space 644fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // to avoid printing the diagraph '<:'. 645fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!Arg && !ArgString.empty() && ArgString[0] == ':') 646fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 647fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 648fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ArgString; 649fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 650fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 651fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If the last character of our string is '>', add another space to 652fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // keep the two '>''s separate tokens. We don't *have* to do this in 653fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // C++0x, but it's still good hygiene. 654fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (SpecString[SpecString.size() - 1] == '>') 655fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 656fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 657fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '>'; 658fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 659fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return SpecString; 660fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 661fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 662fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Sadly, repeat all that with TemplateArgLoc. 663fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string TemplateSpecializationType:: 664fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorPrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs, 665fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) { 666fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string SpecString; 667fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '<'; 668fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 669fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Arg) 670fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ", "; 671fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 672fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // Print the argument into a string. 673fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string ArgString; 674fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy); 675fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 676fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If this is the first argument and its string representation 677fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // begins with the global scope specifier ('::foo'), add a space 678fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // to avoid printing the diagraph '<:'. 679fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!Arg && !ArgString.empty() && ArgString[0] == ':') 680fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 681fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 682fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ArgString; 683fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 684fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 685fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // If the last character of our string is '>', add another space to 686fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // keep the two '>''s separate tokens. We don't *have* to do this in 687fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor // C++0x, but it's still good hygiene. 688fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (SpecString[SpecString.size() - 1] == '>') 689fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += ' '; 690fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 691fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor SpecString += '>'; 692fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 693fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return SpecString; 694fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 695fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 696fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump(const char *msg) const { 697fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string R = "identifier"; 698fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor LangOptions LO; 699fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor getAsStringInternal(R, PrintingPolicy(LO)); 700fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (msg) 701e7cb7e4570842297f698bd7fd8d85520fc008acdDaniel Dunbar llvm::errs() << msg << ": "; 702e7cb7e4570842297f698bd7fd8d85520fc008acdDaniel Dunbar llvm::errs() << R << "\n"; 703fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 704fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump() const { 705fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor dump(""); 706fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 707fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 708fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid Type::dump() const { 709fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor QualType(this, 0).dump(); 710fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 711fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 712fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string Qualifiers::getAsString() const { 713fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor LangOptions LO; 714fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return getAsString(PrintingPolicy(LO)); 715fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 716fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 717fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Appends qualifiers to the given string, separated by spaces. Will 718fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// prefix a space if the string is non-empty. Will not append a final 719fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// space. 720fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid Qualifiers::getAsStringInternal(std::string &S, 721fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy&) const { 722fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor AppendTypeQualList(S, getCVRQualifiers()); 723fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (unsigned AddressSpace = getAddressSpace()) { 724fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 725fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "__attribute__((address_space("; 726fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += llvm::utostr_32(AddressSpace); 727fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 728fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 729fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (Qualifiers::GC GCAttrType = getObjCGCAttr()) { 730fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (!S.empty()) S += ' '; 731fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "__attribute__((objc_gc("; 732fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor if (GCAttrType == Qualifiers::Weak) 733fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "weak"; 734fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor else 735fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += "strong"; 736fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor S += ")))"; 737fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor } 738fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 739fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 740fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string QualType::getAsString() const { 741fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor std::string S; 742fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor LangOptions LO; 743fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor getAsStringInternal(S, PrintingPolicy(LO)); 744fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor return S; 745fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 746fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 747fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::getAsStringInternal(std::string &S, 748fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor const PrintingPolicy &Policy) const { 749fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor TypePrinter Printer(Policy); 750fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor Printer.Print(*this, S); 751fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor} 752fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor 753