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