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