TypePrinter.cpp revision fb898e17cff919bd28b88e9d93301d6e2cc5cbd1
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.
66fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Qualifiers Quals = T.getQualifiers();
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::PrintFixedWidthInt(const FixedWidthIntType *T,
98fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     std::string &S) {
99fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: Once we get bitwidth attribute, write as
100fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // "int __attribute__((bitwidth(x)))".
101fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string prefix = "__clang_fixedwidth";
102fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  prefix += llvm::utostr_32(T->getWidth());
103fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  prefix += (char)(T->isSigned() ? 'S' : 'U');
104fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (S.empty()) {
105fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = prefix;
106fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  } else {
107fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Prefix the basic type, e.g. 'int X'.
108fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = prefix + S;
109fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
110fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
111fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
112fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
113fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), S);
114fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = "_Complex " + S;
115fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
116fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
117fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintPointer(const PointerType *T, std::string &S) {
118fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = '*' + S;
119fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
120fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (*A)[4];' correctly.
121fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
122fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeType()))
123fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = '(' + S + ')';
124fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
125fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getPointeeType(), S);
126fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
127fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
128fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
129fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = '^' + S;
130fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getPointeeType(), S);
131fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
132fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
133fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintLValueReference(const LValueReferenceType *T,
134fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                       std::string &S) {
135fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = '&' + S;
136fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
137fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (&A)[4];' correctly.
138fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
139fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
140fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = '(' + S + ')';
141fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
142fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getPointeeTypeAsWritten(), S);
143fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
144fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
145fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintRValueReference(const RValueReferenceType *T,
146fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                       std::string &S) {
147fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = "&&" + S;
148fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
149fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (&&A)[4];' correctly.
150fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
151fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
152fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = '(' + S + ')';
153fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
154fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getPointeeTypeAsWritten(), S);
155fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
156fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
157fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintMemberPointer(const MemberPointerType *T,
158fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     std::string &S) {
159fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string C;
160fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(QualType(T->getClass(), 0), C);
161fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  C += "::*";
162fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = C + S;
163fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
164fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (Cls::*A)[4];' correctly.
165fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
166fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeType()))
167fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = '(' + S + ')';
168fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
169fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getPointeeType(), S);
170fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
171fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
172fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintConstantArray(const ConstantArrayType *T,
173fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     std::string &S) {
174fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += '[';
175fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += llvm::utostr(T->getSize().getZExtValue());
176fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += ']';
177fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
178fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), S);
179fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
180fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
181fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T,
182fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                       std::string &S) {
183fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += "[]";
184fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), S);
185fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
186fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
187fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintVariableArray(const VariableArrayType *T,
188fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     std::string &S) {
189fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += '[';
190fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
191fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getIndexTypeQualifiers().hasQualifiers()) {
192fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    AppendTypeQualList(S, T->getIndexTypeCVRQualifiers());
193fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += ' ';
194fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
195fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
196fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getSizeModifier() == VariableArrayType::Static)
197fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += "static";
198fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else if (T->getSizeModifier() == VariableArrayType::Star)
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::PrintDependentSizedArray(const DependentSizedArrayType *T,
213fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                           std::string &S) {
214fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += '[';
215fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
216fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getSizeExpr()) {
217fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string SStr;
218fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    llvm::raw_string_ostream s(SStr);
219fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    T->getSizeExpr()->printPretty(s, 0, Policy);
220fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += s.str();
221fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
222fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += ']';
223fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
224fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), S);
225fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
226fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
227fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDependentSizedExtVector(
228fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                          const DependentSizedExtVectorType *T,
229fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                               std::string &S) {
230fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), S);
231fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
232fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += " __attribute__((ext_vector_type(";
233fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getSizeExpr()) {
234fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string SStr;
235fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    llvm::raw_string_ostream s(SStr);
236fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    T->getSizeExpr()->printPretty(s, 0, Policy);
237fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += s.str();
238fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
239fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += ")))";
240fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
241fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
242fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintVector(const VectorType *T, std::string &S) {
243fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: We prefer to print the size directly here, but have no way
244fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // to get the size of the type.
245fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += " __attribute__((__vector_size__(";
246fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
247fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string ET;
248fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), ET);
249fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += " * sizeof(" + ET + "))))";
250fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), S);
251fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
252fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
253fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) {
254fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += " __attribute__((ext_vector_type(";
255fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += llvm::utostr_32(T->getNumElements());
256fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += ")))";
257fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getElementType(), S);
258fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
259fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
260fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintFunctionProto(const FunctionProtoType *T,
261fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     std::string &S) {
262fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If needed for precedence reasons, wrap the inner part in grouping parens.
263fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())
264fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = "(" + S + ")";
265fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
266fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += "(";
267fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string Tmp;
268fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  PrintingPolicy ParamPolicy(Policy);
269fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  ParamPolicy.SuppressSpecifiers = false;
270fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
271fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (i) S += ", ";
272fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    Print(T->getArgType(i), Tmp);
273fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += Tmp;
274fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    Tmp.clear();
275fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
276fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
277fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->isVariadic()) {
278fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (T->getNumArgs())
279fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      S += ", ";
280fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += "...";
281fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
282fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Do not emit int() if we have a proto, emit 'int(void)'.
283fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += "void";
284fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
285fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
286fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += ")";
287fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getNoReturnAttr())
288fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += " __attribute__((noreturn))";
289fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getResultType(), S);
290fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
291fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
292fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
293fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
294fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                       std::string &S) {
295fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If needed for precedence reasons, wrap the inner part in grouping parens.
296fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())
297fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = "(" + S + ")";
298fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
299fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S += "()";
300fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getNoReturnAttr())
301fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += " __attribute__((noreturn))";
302fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getResultType(), S);
303fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
304fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
305fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
306fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
307fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = ' ' + S;
308fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = T->getDecl()->getIdentifier()->getName().str() + S;
309fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
310fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
311fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
312fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
313fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = ' ' + S;
314fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string Str;
315fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  llvm::raw_string_ostream s(Str);
316fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
317fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = "typeof " + s.str() + S;
318fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
319fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
320fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) {
321fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
322fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = ' ' + S;
323fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string Tmp;
324fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getUnderlyingType(), Tmp);
325fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = "typeof(" + Tmp + ")" + S;
326fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
327fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
328fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) {
329fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
330fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = ' ' + S;
331fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string Str;
332fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  llvm::raw_string_ostream s(Str);
333fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
334fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = "decltype(" + s.str() + ")" + S;
335fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
336fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
337fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTag(const TagType *T, std::string &InnerString) {
338fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (Policy.SuppressTag)
339fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    return;
340fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
341fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
342fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    InnerString = ' ' + InnerString;
343fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
344fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName();
345fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  const char *ID;
346fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (const IdentifierInfo *II = T->getDecl()->getIdentifier())
347fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ID = II->getNameStart();
348fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) {
349fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    Kind = 0;
350fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    assert(Typedef->getIdentifier() && "Typedef without identifier?");
351fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ID = Typedef->getIdentifier()->getNameStart();
352fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  } else
353fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ID = "<anonymous>";
354fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
355fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If this is a class template specialization, print the template
356fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // arguments.
357fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (ClassTemplateSpecializationDecl *Spec
358fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
359fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
360fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string TemplateArgsStr
361fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      = TemplateSpecializationType::PrintTemplateArgumentList(
362fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            TemplateArgs.getFlatArgumentList(),
363fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            TemplateArgs.flat_size(),
364fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            Policy);
365fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    InnerString = TemplateArgsStr + InnerString;
366fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
367fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
368fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!Policy.SuppressScope) {
369fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Compute the full nested-name-specifier for this type. In C,
370fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // this will always be empty.
371fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string ContextStr;
372fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    for (DeclContext *DC = T->getDecl()->getDeclContext();
373fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor         !DC->isTranslationUnit(); DC = DC->getParent()) {
374fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      std::string MyPart;
375fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
376fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        if (NS->getIdentifier())
377fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor          MyPart = NS->getNameAsString();
378fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      } else if (ClassTemplateSpecializationDecl *Spec
379fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                  = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
380fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
381fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        std::string TemplateArgsStr
382fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor          = TemplateSpecializationType::PrintTemplateArgumentList(
383fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            TemplateArgs.getFlatArgumentList(),
384fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            TemplateArgs.flat_size(),
385fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            Policy);
386fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
387fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
388fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
389fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor          MyPart = Typedef->getIdentifier()->getName();
390fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        else if (Tag->getIdentifier())
391fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor          MyPart = Tag->getIdentifier()->getName();
392fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      }
393fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
394fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      if (!MyPart.empty())
395fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        ContextStr = MyPart + "::" + ContextStr;
396fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    }
397fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
398fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (Kind)
399fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
400fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    else
401fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      InnerString = ContextStr + ID + InnerString;
402fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  } else
403fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    InnerString = ID + InnerString;
404fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
405fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
406fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
407fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  PrintTag(T, S);
408fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
409fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
410fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintEnum(const EnumType *T, std::string &S) {
411fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  PrintTag(T, S);
412fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
413fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
414fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
415fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string TypeStr;
416fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  PrintingPolicy InnerPolicy(Policy);
417fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  InnerPolicy.SuppressTagKind = true;
418fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S);
419fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
420fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;
421fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
422fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
423fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T,
424fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                        std::string &S) {
425fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
426fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = ' ' + S;
427fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
428fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!T->getName())
429fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
430fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        llvm::utostr_32(T->getIndex()) + S;
431fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else
432fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = T->getName()->getName().str() + S;
433fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
434fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
435fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T,
436fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                             std::string &S) {
437fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Print(T->getReplacementType(), S);
438fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
439fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
440fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTemplateSpecialization(
441fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            const TemplateSpecializationType *T,
442fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                              std::string &S) {
443fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string SpecString;
444fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
445fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  {
446fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    llvm::raw_string_ostream OS(SpecString);
447fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    T->getTemplateName().print(OS, Policy);
448fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
449fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
450fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
451fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                                  T->getArgs(),
452fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                                T->getNumArgs(),
453fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                                      Policy);
454fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (S.empty())
455fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S.swap(SpecString);
456fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else
457fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = SpecString + ' ' + S;
458fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
459fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
460fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintQualifiedName(const QualifiedNameType *T,
461fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     std::string &S) {
462fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string MyString;
463fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
464fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  {
465fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    llvm::raw_string_ostream OS(MyString);
466fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    T->getQualifier()->print(OS, Policy);
467fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
468fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
469fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string TypeStr;
470fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  PrintingPolicy InnerPolicy(Policy);
471fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  InnerPolicy.SuppressTagKind = true;
472fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  InnerPolicy.SuppressScope = true;
473fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
474fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
475fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  MyString += TypeStr;
476fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (S.empty())
477fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S.swap(MyString);
478fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else
479fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = MyString + ' ' + S;
480fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
481fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
482fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintTypename(const TypenameType *T, std::string &S) {
483fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string MyString;
484fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
485fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  {
486fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    llvm::raw_string_ostream OS(MyString);
487fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    OS << "typename ";
488fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    T->getQualifier()->print(OS, Policy);
489fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
490fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (const IdentifierInfo *Ident = T->getIdentifier())
491fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      OS << Ident->getName();
492fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
493fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      Spec->getTemplateName().print(OS, Policy, true);
494fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      OS << TemplateSpecializationType::PrintTemplateArgumentList(
495fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                            Spec->getArgs(),
496fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                            Spec->getNumArgs(),
497fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                            Policy);
498fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    }
499fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
500fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
501fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (S.empty())
502fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S.swap(MyString);
503fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else
504fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = MyString + ' ' + S;
505fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
506fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
507fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T,
508fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     std::string &S) {
509fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
510fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = ' ' + S;
511fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
512fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string ObjCQIString = T->getDecl()->getNameAsString();
513fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getNumProtocols()) {
514fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString += '<';
515fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    bool isFirst = true;
516fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    for (ObjCInterfaceType::qual_iterator I = T->qual_begin(),
517fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                          E = T->qual_end();
518fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor         I != E; ++I) {
519fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      if (isFirst)
520fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        isFirst = false;
521fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      else
522fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        ObjCQIString += ',';
523fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      ObjCQIString += (*I)->getNameAsString();
524fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    }
525fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString += '>';
526fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
527fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = ObjCQIString + S;
528fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
529fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
530fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T,
531fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                         std::string &S) {
532fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string ObjCQIString;
533fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
534fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->isObjCIdType() || T->isObjCQualifiedIdType())
535fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString = "id";
536fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
537fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString = "Class";
538fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else
539fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString = T->getInterfaceDecl()->getNameAsString();
540fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
541fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!T->qual_empty()) {
542fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString += '<';
543fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
544fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                              E = T->qual_end();
545fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor         I != E; ++I) {
546fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      ObjCQIString += (*I)->getNameAsString();
547fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      if (I+1 != E)
548fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor        ObjCQIString += ',';
549fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    }
550fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString += '>';
551fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
552fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
553fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  T->getPointeeType().getQualifiers().getAsStringInternal(ObjCQIString, Policy);
554fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
555fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
556fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    ObjCQIString += " *"; // Don't forget the implicit pointer.
557fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
558fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S = ' ' + S;
559fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
560fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  S = ObjCQIString + S;
561fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
562fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
563fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstatic void PrintTemplateArgument(std::string &Buffer,
564fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                  const TemplateArgument &Arg,
565fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                  const PrintingPolicy &Policy) {
566fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  switch (Arg.getKind()) {
567fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    case TemplateArgument::Null:
568fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      assert(false && "Null template argument");
569fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      break;
570fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
571fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    case TemplateArgument::Type:
572fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      Arg.getAsType().getAsStringInternal(Buffer, Policy);
573fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      break;
574fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
575fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    case TemplateArgument::Declaration:
576fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
577fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      break;
578fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
579788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    case TemplateArgument::Template: {
580788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor      llvm::raw_string_ostream s(Buffer);
581788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor      Arg.getAsTemplate().print(s, Policy);
582fb898e17cff919bd28b88e9d93301d6e2cc5cbd1Douglas Gregor      break;
583788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    }
584788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor
585fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    case TemplateArgument::Integral:
586fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      Buffer = Arg.getAsIntegral()->toString(10, true);
587fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      break;
588fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
589fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    case TemplateArgument::Expression: {
590fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      llvm::raw_string_ostream s(Buffer);
591fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      Arg.getAsExpr()->printPretty(s, 0, Policy);
592fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      break;
593fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    }
594fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
595fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    case TemplateArgument::Pack:
596fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      assert(0 && "FIXME: Implement!");
597fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      break;
598fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
599fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
600fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
601fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string
602fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorTemplateSpecializationType::PrintTemplateArgumentList(
603fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                const TemplateArgument *Args,
604fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                unsigned NumArgs,
605fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                const PrintingPolicy &Policy) {
606fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string SpecString;
607fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  SpecString += '<';
608fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
609fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (Arg)
610fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ", ";
611fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
612fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Print the argument into a string.
613fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string ArgString;
614fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    PrintTemplateArgument(ArgString, Args[Arg], Policy);
615fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
616fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // If this is the first argument and its string representation
617fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // begins with the global scope specifier ('::foo'), add a space
618fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // to avoid printing the diagraph '<:'.
619fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
620fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ' ';
621fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
622fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ArgString;
623fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
624fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
625fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If the last character of our string is '>', add another space to
626fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // keep the two '>''s separate tokens. We don't *have* to do this in
627fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // C++0x, but it's still good hygiene.
628fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (SpecString[SpecString.size() - 1] == '>')
629fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ' ';
630fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
631fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  SpecString += '>';
632fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
633fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  return SpecString;
634fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
635fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
636fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Sadly, repeat all that with TemplateArgLoc.
637fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string TemplateSpecializationType::
638fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorPrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
639fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                          const PrintingPolicy &Policy) {
640fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string SpecString;
641fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  SpecString += '<';
642fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
643fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (Arg)
644fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ", ";
645fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
646fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Print the argument into a string.
647fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string ArgString;
648fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
649fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
650fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // If this is the first argument and its string representation
651fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // begins with the global scope specifier ('::foo'), add a space
652fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // to avoid printing the diagraph '<:'.
653fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
654fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ' ';
655fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
656fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ArgString;
657fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
658fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
659fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If the last character of our string is '>', add another space to
660fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // keep the two '>''s separate tokens. We don't *have* to do this in
661fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // C++0x, but it's still good hygiene.
662fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (SpecString[SpecString.size() - 1] == '>')
663fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ' ';
664fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
665fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  SpecString += '>';
666fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
667fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  return SpecString;
668fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
669fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
670fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump(const char *msg) const {
671fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string R = "identifier";
672fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  LangOptions LO;
673fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  getAsStringInternal(R, PrintingPolicy(LO));
674fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (msg)
675fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    fprintf(stderr, "%s: %s\n", msg, R.c_str());
676fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else
677fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    fprintf(stderr, "%s\n", R.c_str());
678fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
679fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump() const {
680fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  dump("");
681fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
682fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
683fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid Type::dump() const {
684fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  QualType(this, 0).dump();
685fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
686fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
687fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string Qualifiers::getAsString() const {
688fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  LangOptions LO;
689fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  return getAsString(PrintingPolicy(LO));
690fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
691fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
692fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Appends qualifiers to the given string, separated by spaces.  Will
693fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// prefix a space if the string is non-empty.  Will not append a final
694fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// space.
695fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid Qualifiers::getAsStringInternal(std::string &S,
696fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                     const PrintingPolicy&) const {
697fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  AppendTypeQualList(S, getCVRQualifiers());
698fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (unsigned AddressSpace = getAddressSpace()) {
699fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (!S.empty()) S += ' ';
700fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += "__attribute__((address_space(";
701fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += llvm::utostr_32(AddressSpace);
702fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += ")))";
703fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
704fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
705fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (!S.empty()) S += ' ';
706fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += "__attribute__((objc_gc(";
707fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (GCAttrType == Qualifiers::Weak)
708fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      S += "weak";
709fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    else
710fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      S += "strong";
711fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    S += ")))";
712fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
713fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
714fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
715fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string QualType::getAsString() const {
716fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string S;
717fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  LangOptions LO;
718fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  getAsStringInternal(S, PrintingPolicy(LO));
719fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  return S;
720fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
721fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
722fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::getAsStringInternal(std::string &S,
723fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                   const PrintingPolicy &Policy) const {
724fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  TypePrinter Printer(Policy);
725fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  Printer.Print(*this, S);
726fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
727fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
728