TypePrinter.cpp revision 13dcd00615de5c4279d97bdf63cd5f0a14fd9dcc
1de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===// 2de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// 3de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// The LLVM Compiler Infrastructure 4de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// 5de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// This file is distributed under the University of Illinois Open Source 6de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// License. See LICENSE.TXT for details. 7de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// 8de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák//===----------------------------------------------------------------------===// 9de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// 10de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// This contains code to print types from Clang's type system. 11de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák// 12de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák//===----------------------------------------------------------------------===// 13de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák 14de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "clang/AST/Decl.h" 15de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "clang/AST/DeclObjC.h" 16de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "clang/AST/DeclTemplate.h" 17de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "clang/AST/Expr.h" 18de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "clang/AST/Type.h" 19de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "clang/AST/PrettyPrinter.h" 20de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "clang/Basic/LangOptions.h" 21de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "llvm/ADT/StringExtras.h" 22de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák#include "llvm/Support/raw_ostream.h" 23de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšákusing namespace clang; 24de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák 25de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšáknamespace { 26de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák class TypePrinter { 276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák PrintingPolicy Policy; 286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák public: 306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { } 316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák void Print(QualType T, std::string &S); 33bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse void PrintTag(const TagType *T, std::string &S); 346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#define ABSTRACT_TYPE(CLASS, PARENT) 3570b1837dfb1b282ad9efcaeec4f9c8da5f9a74d8Chia-I Wu#define TYPE(CLASS, PARENT) \ 366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák void Print##CLASS(const CLASS##Type *T, std::string &S); 376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "clang/AST/TypeNodes.def" 386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák }; 396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void AppendTypeQualList(std::string &S, unsigned TypeQuals) { 426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (TypeQuals & Qualifiers::Const) { 43bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (!S.empty()) S += ' '; 44bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += "const"; 45bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 46bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (TypeQuals & Qualifiers::Volatile) { 47bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (!S.empty()) S += ' '; 486ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S += "volatile"; 496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (TypeQuals & Qualifiers::Restrict) { 516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (!S.empty()) S += ' '; 521e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S += "restrict"; 53bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse } 541e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák} 55bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse 56bbc320a94def6178028a4c46012c737839e1cf61Jerome Glissevoid TypePrinter::Print(QualType T, std::string &S) { 57bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse if (T.isNull()) { 581e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S += "NULL TYPE"; 591e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák return; 60bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse } 61bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse 621e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák if (Policy.SuppressSpecifiers && T->isSpecifierType()) 631e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák return; 641e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák 651e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák // Print qualifiers as appropriate. 66bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Qualifiers Quals = T.getLocalQualifiers(); 67bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (!Quals.empty()) { 68bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string TQS; 69bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Quals.getAsStringInternal(TQS, Policy); 70bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 71bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (!S.empty()) { 72bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse TQS += ' '; 73bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse TQS += S; 74bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 75bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::swap(S, TQS); 76bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 77bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 78bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse switch (T->getTypeClass()) { 79bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse#define ABSTRACT_TYPE(CLASS, PARENT) 80bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse#define TYPE(CLASS, PARENT) case Type::CLASS: \ 81bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S); \ 82bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse break; 83bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse#include "clang/AST/TypeNodes.def" 84bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 85bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse} 86bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 87bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glissevoid TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) { 88bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (S.empty()) { 89bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = T->getName(Policy.LangOpts); 90bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } else { 91bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // Prefix the basic type, e.g. 'int X'. 92bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = ' ' + S; 931e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S = T->getName(Policy.LangOpts) + S; 946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintFixedWidthInt(const FixedWidthIntType *T, 986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // FIXME: Once we get bitwidth attribute, write as 1006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // "int __attribute__((bitwidth(x)))". 1016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string prefix = "__clang_fixedwidth"; 1026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák prefix += llvm::utostr_32(T->getWidth()); 103bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse prefix += (char)(T->isSigned() ? 'S' : 'U'); 104bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (S.empty()) { 105bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = prefix; 106bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } else { 107bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // Prefix the basic type, e.g. 'int X'. 108bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = prefix + S; 1096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 1106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 1116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 1126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintComplex(const ComplexType *T, std::string &S) { 1136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Print(T->getElementType(), S); 1146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = "_Complex " + S; 1156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 1166ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 1176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintPointer(const PointerType *T, std::string &S) { 1186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = '*' + S; 119bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 120bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // Handle things like 'int (*A)[4];' correctly. 121bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // FIXME: this should include vectors, but vectors use attributes I guess. 122bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (isa<ArrayType>(T->getPointeeType())) 123bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = '(' + S + ')'; 124bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 1256ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Print(T->getPointeeType(), S); 1266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 1276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 1286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) { 1296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = '^' + S; 1306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Print(T->getPointeeType(), S); 1316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 1326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 1336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintLValueReference(const LValueReferenceType *T, 1346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 1356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = '&' + S; 1366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 1376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // Handle things like 'int (&A)[4];' correctly. 1386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // FIXME: this should include vectors, but vectors use attributes I guess. 139bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 140bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse S = '(' + S + ')'; 141bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse 1426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Print(T->getPointeeTypeAsWritten(), S); 1436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 1446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 1456ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintRValueReference(const RValueReferenceType *T, 1466ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 1476ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = "&&" + S; 1486ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 1496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // Handle things like 'int (&&A)[4];' correctly. 1501e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák // FIXME: this should include vectors, but vectors use attributes I guess. 1516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 1522664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák S = '(' + S + ')'; 1536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 154b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák Print(T->getPointeeTypeAsWritten(), S); 155b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák} 156b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák 157b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšákvoid TypePrinter::PrintMemberPointer(const MemberPointerType *T, 158ef64da8f013691c66744064769db379e57ef95deMarek Olšák std::string &S) { 159ef64da8f013691c66744064769db379e57ef95deMarek Olšák std::string C; 1601e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák Print(QualType(T->getClass(), 0), C); 1611e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák C += "::*"; 1621e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S = C + S; 1631e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák 1641e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák // Handle things like 'int (Cls::*A)[4];' correctly. 165ef64da8f013691c66744064769db379e57ef95deMarek Olšák // FIXME: this should include vectors, but vectors use attributes I guess. 1663da5196263fb2ae60483044cbd34c94270e2accdBrian Paul if (isa<ArrayType>(T->getPointeeType())) 1673da5196263fb2ae60483044cbd34c94270e2accdBrian Paul S = '(' + S + ')'; 1681e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák 1691e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák Print(T->getPointeeType(), S); 1701e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák} 1711e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák 1726ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintConstantArray(const ConstantArrayType *T, 1736ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 1741e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S += '['; 1751e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S += llvm::utostr(T->getSize().getZExtValue()); 1766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S += ']'; 1772664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák 1786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Print(T->getElementType(), S); 179b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák} 180b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák 181b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšákvoid TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 182b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák std::string &S) { 183ef64da8f013691c66744064769db379e57ef95deMarek Olšák S += "[]"; 184ef64da8f013691c66744064769db379e57ef95deMarek Olšák Print(T->getElementType(), S); 1851e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák} 1861e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák 1871e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšákvoid TypePrinter::PrintVariableArray(const VariableArrayType *T, 1881e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák std::string &S) { 1891e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S += '['; 190ef64da8f013691c66744064769db379e57ef95deMarek Olšák 1913da5196263fb2ae60483044cbd34c94270e2accdBrian Paul if (T->getIndexTypeQualifiers().hasQualifiers()) { 1923da5196263fb2ae60483044cbd34c94270e2accdBrian Paul AppendTypeQualList(S, T->getIndexTypeCVRQualifiers()); 1931e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák S += ' '; 1941e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák } 1951e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák 1961e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák if (T->getSizeModifier() == VariableArrayType::Static) 1976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S += "static"; 1986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák else if (T->getSizeModifier() == VariableArrayType::Star) 199356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse S += '*'; 200bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 201bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (T->getSizeExpr()) { 202356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse std::string SStr; 203bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse llvm::raw_string_ostream s(SStr); 204bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse T->getSizeExpr()->printPretty(s, 0, Policy); 205bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += s.str(); 206bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 207356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse S += ']'; 208356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse 209356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse Print(T->getElementType(), S); 210356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse} 211356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse 212356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glissevoid TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 213356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse std::string &S) { 214e372e53ee0ed57072322003e508b3ca4c58076beJerome Glisse S += '['; 215e372e53ee0ed57072322003e508b3ca4c58076beJerome Glisse 216e372e53ee0ed57072322003e508b3ca4c58076beJerome Glisse if (T->getSizeExpr()) { 217356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse std::string SStr; 218bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse llvm::raw_string_ostream s(SStr); 219bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse T->getSizeExpr()->printPretty(s, 0, Policy); 220bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += s.str(); 221bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 222bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += ']'; 223bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 224356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse Print(T->getElementType(), S); 225356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse} 226356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse 227356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glissevoid TypePrinter::PrintDependentSizedExtVector( 228356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse const DependentSizedExtVectorType *T, 229356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse std::string &S) { 230356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse Print(T->getElementType(), S); 231356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse 232356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse S += " __attribute__((ext_vector_type("; 233bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (T->getSizeExpr()) { 234bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string SStr; 235bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse llvm::raw_string_ostream s(SStr); 236bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse T->getSizeExpr()->printPretty(s, 0, Policy); 237bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += s.str(); 238bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 239356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse S += ")))"; 240356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse} 241356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse 242356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glissevoid TypePrinter::PrintVector(const VectorType *T, std::string &S) { 243356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse // FIXME: We prefer to print the size directly here, but have no way 244356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse // to get the size of the type. 245356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse S += " __attribute__((__vector_size__("; 246bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += llvm::utostr_32(T->getNumElements()); // convert back to bytes. 247bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string ET; 248bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print(T->getElementType(), ET); 249bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += " * sizeof(" + ET + "))))"; 250bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print(T->getElementType(), S); 251bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse} 252bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 253bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glissevoid TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 254bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += " __attribute__((ext_vector_type("; 255bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += llvm::utostr_32(T->getNumElements()); 256bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += ")))"; 257bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print(T->getElementType(), S); 258bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse} 259bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 260bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glissevoid TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 261bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string &S) { 262bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // If needed for precedence reasons, wrap the inner part in grouping parens. 263bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (!S.empty()) 264bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = "(" + S + ")"; 265bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 266bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += "("; 267bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string Tmp; 268bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse PrintingPolicy ParamPolicy(Policy); 269bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ParamPolicy.SuppressSpecifiers = false; 270bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { 271bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (i) S += ", "; 272bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print(T->getArgType(i), Tmp); 273bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += Tmp; 274bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Tmp.clear(); 275bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 276bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 277bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (T->isVariadic()) { 278bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (T->getNumArgs()) 279bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += ", "; 280bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += "..."; 281bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { 282bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // Do not emit int() if we have a proto, emit 'int(void)'. 283bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += "void"; 284bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 285bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 286bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += ")"; 287bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (T->getNoReturnAttr()) 288bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += " __attribute__((noreturn))"; 289bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print(T->getResultType(), S); 290bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 291bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse} 292bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 293bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glissevoid TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 294bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string &S) { 295bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // If needed for precedence reasons, wrap the inner part in grouping parens. 296bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (!S.empty()) 297bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = "(" + S + ")"; 298bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 299bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += "()"; 300bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (T->getNoReturnAttr()) 301bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S += " __attribute__((noreturn))"; 302bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print(T->getResultType(), S); 303bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse} 3046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 3056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 3066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 307bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = ' ' + S; 3083da5196263fb2ae60483044cbd34c94270e2accdBrian Paul S = T->getDecl()->getIdentifier()->getName().str() + S; 3093da5196263fb2ae60483044cbd34c94270e2accdBrian Paul} 3103da5196263fb2ae60483044cbd34c94270e2accdBrian Paul 311c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšákvoid TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) { 312c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák if (!S.empty()) // Prefix the basic type, e.g. 'typeof(e) X'. 313c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák S = ' ' + S; 314c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák std::string Str; 315bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse llvm::raw_string_ostream s(Str); 316c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák T->getUnderlyingExpr()->printPretty(s, 0, Policy); 317c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák S = "typeof " + s.str() + S; 3186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 319c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák 320a3cd2c6c9b3724dbc3aa565dab98968c46bde963Marek Olšákvoid TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) { 321c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák if (!S.empty()) // Prefix the basic type, e.g. 'typeof(t) X'. 322bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = ' ' + S; 323bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string Tmp; 324bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Print(T->getUnderlyingType(), Tmp); 325bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = "typeof(" + Tmp + ")" + S; 326c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák} 327c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák 328c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšákvoid TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { 329c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák if (!S.empty()) // Prefix the basic type, e.g. 'decltype(t) X'. 330c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák S = ' ' + S; 3316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string Str; 3326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák llvm::raw_string_ostream s(Str); 3330a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák T->getUnderlyingExpr()->printPretty(s, 0, Policy); 3340a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák S = "decltype(" + s.str() + ")" + S; 3350a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák} 3366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 3370a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšákvoid TypePrinter::PrintTag(const TagType *T, std::string &InnerString) { 3380a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák if (Policy.SuppressTag) 3390a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák return; 3408decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák 3416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. 3426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák InnerString = ' ' + InnerString; 3430a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák 34445e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName(); 3450a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák const char *ID; 3460a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák if (const IdentifierInfo *II = T->getDecl()->getIdentifier()) 347ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák ID = II->getNameStart(); 348ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) { 349ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák Kind = 0; 350ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák assert(Typedef->getIdentifier() && "Typedef without identifier?"); 351ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák ID = Typedef->getIdentifier()->getNameStart(); 352ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák } else 353ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák ID = "<anonymous>"; 354ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák 355ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák // If this is a class template specialization, print the template 356ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák // arguments. 357ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák if (ClassTemplateSpecializationDecl *Spec 35845e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) { 359ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 360ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák std::string TemplateArgsStr 361ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák = TemplateSpecializationType::PrintTemplateArgumentList( 362ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák TemplateArgs.getFlatArgumentList(), 363ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák TemplateArgs.flat_size(), 364ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák Policy); 365ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák InnerString = TemplateArgsStr + InnerString; 366ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák } 367ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák 368ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák if (!Policy.SuppressScope) { 369ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák // Compute the full nested-name-specifier for this type. In C, 370ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák // this will always be empty. 371ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák std::string ContextStr; 372ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák for (DeclContext *DC = T->getDecl()->getDeclContext(); 37345e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák !DC->isTranslationUnit(); DC = DC->getParent()) { 37445e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák std::string MyPart; 3750a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 3766caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák if (NS->getIdentifier()) 3776caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák MyPart = NS->getNameAsString(); 3786caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák } else if (ClassTemplateSpecializationDecl *Spec 3796caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { 3806caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 3816caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák std::string TemplateArgsStr 3826caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák = TemplateSpecializationType::PrintTemplateArgumentList( 3836caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák TemplateArgs.getFlatArgumentList(), 3846caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák TemplateArgs.flat_size(), 3851554e69e00566bc7255b82f5ea93b1f02f1a5bb3Marek Olšák Policy); 386ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr; 387ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { 3885650a719f0c69c00954e47bd7a7b3e9433cb551dMarek Olšák if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) 3896caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák MyPart = Typedef->getIdentifier()->getName(); 3906caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák else if (Tag->getIdentifier()) 3916caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák MyPart = Tag->getIdentifier()->getName(); 3926caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák } 3936caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák 3946caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák if (!MyPart.empty()) 3956caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák ContextStr = MyPart + "::" + ContextStr; 3966caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák } 3976caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák 3981e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák if (Kind) 39945e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString; 4006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák else 4016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák InnerString = ContextStr + ID + InnerString; 4026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } else 4038decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák InnerString = ID + InnerString; 4048decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák} 4058decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák 4068decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšákvoid TypePrinter::PrintRecord(const RecordType *T, std::string &S) { 4078decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák PrintTag(T, S); 4088decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák} 409652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák 410652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšákvoid TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 411652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák PrintTag(T, S); 412652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák} 413652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák 4148decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšákvoid TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 4158decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák std::string TypeStr; 416a3cd2c6c9b3724dbc3aa565dab98968c46bde963Marek Olšák PrintingPolicy InnerPolicy(Policy); 4178decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák InnerPolicy.SuppressTagKind = true; 4188decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S); 4198decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák 4208decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S; 4218decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák} 4228decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák 4238decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšákvoid TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 4248decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák std::string &S) { 4258decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'. 4268decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák S = ' ' + S; 42770b1837dfb1b282ad9efcaeec4f9c8da5f9a74d8Chia-I Wu 4288decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák if (!T->getName()) 4298decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' + 4308decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák llvm::utostr_32(T->getIndex()) + S; 4318decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák else 4328decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák S = T->getName()->getName().str() + S; 4336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 4348decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák 4358decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšákvoid TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 4366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 4376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Print(T->getReplacementType(), S); 4386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 4396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 4400a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšákvoid TypePrinter::PrintTemplateSpecialization( 4416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák const TemplateSpecializationType *T, 4426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 4436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string SpecString; 4446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 4456ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák { 446bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse llvm::raw_string_ostream OS(SpecString); 447bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse T->getTemplateName().print(OS, Policy); 4486ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 4496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 4506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák SpecString += TemplateSpecializationType::PrintTemplateArgumentList( 4516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák T->getArgs(), 4526ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák T->getNumArgs(), 4536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Policy); 454bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse if (S.empty()) 455bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse S.swap(SpecString); 4566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák else 4576ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = SpecString + ' ' + S; 4586ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 4596ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 4606ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 4616ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 4626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string MyString; 4636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 4646ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák { 4656ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák llvm::raw_string_ostream OS(MyString); 4666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák T->getQualifier()->print(OS, Policy); 4676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 4680a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák 4690a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák std::string TypeStr; 4706ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák PrintingPolicy InnerPolicy(Policy); 4716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák InnerPolicy.SuppressTagKind = true; 4726ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák InnerPolicy.SuppressScope = true; 4736ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr); 4746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 4756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák MyString += TypeStr; 476bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse if (S.empty()) 477bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse S.swap(MyString); 4786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák else 4796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = MyString + ' ' + S; 4806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 4816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 4823da5196263fb2ae60483044cbd34c94270e2accdBrian Paulvoid TypePrinter::PrintTypename(const TypenameType *T, std::string &S) { 483bfa51dfeac67a7e3383614374c86bdfb5751997aMarek Olšák std::string MyString; 484bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 4856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák { 4863da5196263fb2ae60483044cbd34c94270e2accdBrian Paul llvm::raw_string_ostream OS(MyString); 4873da5196263fb2ae60483044cbd34c94270e2accdBrian Paul OS << "typename "; 48893f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633Marek Olšák T->getQualifier()->print(OS, Policy); 489363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák 490363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák if (const IdentifierInfo *Ident = T->getIdentifier()) 491363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák OS << Ident->getName(); 4926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák else if (const TemplateSpecializationType *Spec = T->getTemplateId()) { 4936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Spec->getTemplateName().print(OS, Policy, true); 494bfa51dfeac67a7e3383614374c86bdfb5751997aMarek Olšák OS << TemplateSpecializationType::PrintTemplateArgumentList( 4956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Spec->getArgs(), 4966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Spec->getNumArgs(), 4976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Policy); 4989d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák } 4999d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák } 5009d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák 5019d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák if (S.empty()) 5026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S.swap(MyString); 5036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák else 5046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S = MyString + ' ' + S; 5056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 5066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 507bbc320a94def6178028a4c46012c737839e1cf61Jerome Glissevoid TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 5086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string &S) { 5094682e706012fe26627a2f827db01b5068cc62814Marek Olšák if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 5104682e706012fe26627a2f827db01b5068cc62814Marek Olšák S = ' ' + S; 5114682e706012fe26627a2f827db01b5068cc62814Marek Olšák 5124682e706012fe26627a2f827db01b5068cc62814Marek Olšák std::string ObjCQIString = T->getDecl()->getNameAsString(); 5136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (T->getNumProtocols()) { 5146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák ObjCQIString += '<'; 515df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák bool isFirst = true; 5166ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák for (ObjCInterfaceType::qual_iterator I = T->qual_begin(), 517bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse E = T->qual_end(); 5188decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák I != E; ++I) { 5196ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (isFirst) 520bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse isFirst = false; 521bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse else 522bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString += ','; 523bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString += (*I)->getNameAsString(); 524356eb0aadbb977b0732da077ad31cd66d1b53e23Jerome Glisse } 525bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString += '>'; 526bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse } 527bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse S = ObjCQIString + S; 528bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse} 529bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 530bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glissevoid TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 531bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string &S) { 532bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string ObjCQIString; 533bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 534bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (T->isObjCIdType() || T->isObjCQualifiedIdType()) 535bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString = "id"; 536bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) 537bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString = "Class"; 538bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse else if (T->isObjCSelType()) 539bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString = "SEL"; 540bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse else 541bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString = T->getInterfaceDecl()->getNameAsString(); 542bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 543bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (!T->qual_empty()) { 544bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString += '<'; 545bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 546bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse E = T->qual_end(); 547bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse I != E; ++I) { 548bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse ObjCQIString += (*I)->getNameAsString(); 5496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (I+1 != E) 5506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák ObjCQIString += ','; 5516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 5526ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák ObjCQIString += '>'; 5536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 5546ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 5556ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString, 5566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Policy); 557a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák 558a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) 559a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák ObjCQIString += " *"; // Don't forget the implicit pointer. 560a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 561a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák S = ' ' + S; 562a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák 563a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák S = ObjCQIString + S; 564333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák} 565a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák 566a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšákstatic void PrintTemplateArgument(std::string &Buffer, 5671e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák const TemplateArgument &Arg, 568333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák const PrintingPolicy &Policy) { 569a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák switch (Arg.getKind()) { 570a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák case TemplateArgument::Null: 571333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák assert(false && "Null template argument"); 572a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák break; 573a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák 5746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák case TemplateArgument::Type: 5756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Arg.getAsType().getAsStringInternal(Buffer, Policy); 5766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák break; 5776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 5786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák case TemplateArgument::Declaration: 579bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString(); 5806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák break; 5816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 5826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák case TemplateArgument::Template: { 5838ab1fcc66a58ca87fb19fea2b0e14e62562decccMarek Olšák llvm::raw_string_ostream s(Buffer); 584685c3262b945a7f0e9f1f3a9409a12fdda08c828Marek Olšák Arg.getAsTemplate().print(s, Policy); 5856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák break; 5866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 587685c3262b945a7f0e9f1f3a9409a12fdda08c828Marek Olšák 5886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák case TemplateArgument::Integral: 5896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Buffer = Arg.getAsIntegral()->toString(10, true); 5906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák break; 5916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 5928ab1fcc66a58ca87fb19fea2b0e14e62562decccMarek Olšák case TemplateArgument::Expression: { 5936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák llvm::raw_string_ostream s(Buffer); 5946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák Arg.getAsExpr()->printPretty(s, 0, Policy); 5956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák break; 5966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák } 5976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 5986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák case TemplateArgument::Pack: 5996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák assert(0 && "FIXME: Implement!"); 6006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák break; 601bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse } 6026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 6036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 6046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstd::string 6056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek OlšákTemplateSpecializationType::PrintTemplateArgumentList( 606a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák const TemplateArgument *Args, 6076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák unsigned NumArgs, 6086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák const PrintingPolicy &Policy) { 6096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string SpecString; 6106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák SpecString += '<'; 611bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 612bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse if (Arg) 613bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse SpecString += ", "; 614bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse 615bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse // Print the argument into a string. 616bb1f0cf3508630a9a93512c79badf8c493c46743Jerome Glisse std::string ArgString; 6176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák PrintTemplateArgument(ArgString, Args[Arg], Policy); 6186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 6196ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // If this is the first argument and its string representation 620c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // begins with the global scope specifier ('::foo'), add a space 621c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // to avoid printing the diagraph '<:'. 622c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse if (!Arg && !ArgString.empty() && ArgString[0] == ':') 623c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse SpecString += ' '; 624c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse 625c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse SpecString += ArgString; 626c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse } 627c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse 628c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // If the last character of our string is '>', add another space to 629c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // keep the two '>''s separate tokens. We don't *have* to do this in 630c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // C++0x, but it's still good hygiene. 631c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse if (SpecString[SpecString.size() - 1] == '>') 632c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse SpecString += ' '; 633c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse 634c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse SpecString += '>'; 63511f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer 63611f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer return SpecString; 63711f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer} 63811f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer 63911f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer// Sadly, repeat all that with TemplateArgLoc. 64011f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzerstd::string TemplateSpecializationType:: 64111f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel DänzerPrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs, 64211f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer const PrintingPolicy &Policy) { 64311f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer std::string SpecString; 64411f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer SpecString += '<'; 64511f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 64611f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer if (Arg) 64711f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer SpecString += ", "; 64811f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer 649d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák // Print the argument into a string. 650d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák std::string ArgString; 651c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy); 652c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse 653c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // If this is the first argument and its string representation 654c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // begins with the global scope specifier ('::foo'), add a space 655c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse // to avoid printing the diagraph '<:'. 6566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (!Arg && !ArgString.empty() && ArgString[0] == ':') 6572664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák SpecString += ' '; 6583da5196263fb2ae60483044cbd34c94270e2accdBrian Paul 6593da5196263fb2ae60483044cbd34c94270e2accdBrian Paul SpecString += ArgString; 6603da5196263fb2ae60483044cbd34c94270e2accdBrian Paul } 6616ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 6626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // If the last character of our string is '>', add another space to 6636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák // keep the two '>''s separate tokens. We don't *have* to do this in 664df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák // C++0x, but it's still good hygiene. 6656ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (SpecString[SpecString.size() - 1] == '>') 6666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák SpecString += ' '; 6676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 6686ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák SpecString += '>'; 669d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák 670d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák return SpecString; 6716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 672bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse 6736ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid QualType::dump(const char *msg) const { 6746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák std::string R = "identifier"; 675bbc320a94def6178028a4c46012c737839e1cf61Jerome Glisse LangOptions LO; 676c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse getAsStringInternal(R, PrintingPolicy(LO)); 677c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse if (msg) 678c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse fprintf(stderr, "%s: %s\n", msg, R.c_str()); 679c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse else 680c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse fprintf(stderr, "%s\n", R.c_str()); 681c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse} 682c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glissevoid QualType::dump() const { 683c0c979eebc076b95cc8d18a013ce2968fe6311adJerome Glisse dump(""); 6846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 6856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 686d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákvoid Type::dump() const { 687d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák QualType(this, 0).dump(); 688d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák} 68911f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer 69011f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzerstd::string Qualifiers::getAsString() const { 69111f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer LangOptions LO; 69211f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer return getAsString(PrintingPolicy(LO)); 6936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 6946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 6952664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák// Appends qualifiers to the given string, separated by spaces. Will 6963da5196263fb2ae60483044cbd34c94270e2accdBrian Paul// prefix a space if the string is non-empty. Will not append a final 6973da5196263fb2ae60483044cbd34c94270e2accdBrian Paul// space. 6983da5196263fb2ae60483044cbd34c94270e2accdBrian Paulvoid Qualifiers::getAsStringInternal(std::string &S, 6996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák const PrintingPolicy&) const { 700fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák AppendTypeQualList(S, getCVRQualifiers()); 701fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák if (unsigned AddressSpace = getAddressSpace()) { 702fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák if (!S.empty()) S += ' '; 703fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák S += "__attribute__((address_space("; 704d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák S += llvm::utostr_32(AddressSpace); 7056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S += ")))"; 706d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák } 7076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (Qualifiers::GC GCAttrType = getObjCGCAttr()) { 7086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (!S.empty()) S += ' '; 709d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák S += "__attribute__((objc_gc("; 7106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák if (GCAttrType == Qualifiers::Weak) 7116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák S += "weak"; 71211f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer else 71311f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer S += "strong"; 71411f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer S += ")))"; 71511f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer } 71611f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer} 71711f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer 71811f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzerstd::string QualType::getAsString() const { 71911f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer std::string S; 72011f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer LangOptions LO; 72111f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer getAsStringInternal(S, PrintingPolicy(LO)); 72211f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer return S; 72311f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer} 72411f056a3f0b87e86267efa8b5ac9d36a343c9dc1Michel Dänzer 7256ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid QualType::getAsStringInternal(std::string &S, 7266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák const PrintingPolicy &Policy) const { 7276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák TypePrinter Printer(Policy); 728df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák Printer.Print(*this, S); 7296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák} 7306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák 7316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák