TypePrinter.cpp revision 788b0fd67e1992f23555454efcdb16a19dfefac3
1//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to print types from Clang's type system.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/Decl.h"
15#include "clang/AST/DeclObjC.h"
16#include "clang/AST/DeclTemplate.h"
17#include "clang/AST/Expr.h"
18#include "clang/AST/Type.h"
19#include "clang/AST/PrettyPrinter.h"
20#include "clang/Basic/LangOptions.h"
21#include "clang/Basic/SourceManager.h"
22#include "llvm/ADT/StringExtras.h"
23#include "llvm/Support/raw_ostream.h"
24using namespace clang;
25
26namespace {
27  class TypePrinter {
28    PrintingPolicy Policy;
29
30  public:
31    explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
32
33    void Print(QualType T, std::string &S);
34    void AppendScope(DeclContext *DC, std::string &S);
35    void PrintTag(TagDecl *T, std::string &S);
36#define ABSTRACT_TYPE(CLASS, PARENT)
37#define TYPE(CLASS, PARENT) \
38  void Print##CLASS(const CLASS##Type *T, std::string &S);
39#include "clang/AST/TypeNodes.def"
40  };
41}
42
43static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
44  if (TypeQuals & Qualifiers::Const) {
45    if (!S.empty()) S += ' ';
46    S += "const";
47  }
48  if (TypeQuals & Qualifiers::Volatile) {
49    if (!S.empty()) S += ' ';
50    S += "volatile";
51  }
52  if (TypeQuals & Qualifiers::Restrict) {
53    if (!S.empty()) S += ' ';
54    S += "restrict";
55  }
56}
57
58void TypePrinter::Print(QualType T, std::string &S) {
59  if (T.isNull()) {
60    S += "NULL TYPE";
61    return;
62  }
63
64  if (Policy.SuppressSpecifiers && T->isSpecifierType())
65    return;
66
67  // Print qualifiers as appropriate.
68  Qualifiers Quals = T.getLocalQualifiers();
69  if (!Quals.empty()) {
70    std::string TQS;
71    Quals.getAsStringInternal(TQS, Policy);
72
73    if (!S.empty()) {
74      TQS += ' ';
75      TQS += S;
76    }
77    std::swap(S, TQS);
78  }
79
80  switch (T->getTypeClass()) {
81#define ABSTRACT_TYPE(CLASS, PARENT)
82#define TYPE(CLASS, PARENT) case Type::CLASS:                \
83    Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S);      \
84    break;
85#include "clang/AST/TypeNodes.def"
86  }
87}
88
89void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
90  if (S.empty()) {
91    S = T->getName(Policy.LangOpts);
92  } else {
93    // Prefix the basic type, e.g. 'int X'.
94    S = ' ' + S;
95    S = T->getName(Policy.LangOpts) + S;
96  }
97}
98
99void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
100  Print(T->getElementType(), S);
101  S = "_Complex " + S;
102}
103
104void TypePrinter::PrintPointer(const PointerType *T, std::string &S) {
105  S = '*' + S;
106
107  // Handle things like 'int (*A)[4];' correctly.
108  // FIXME: this should include vectors, but vectors use attributes I guess.
109  if (isa<ArrayType>(T->getPointeeType()))
110    S = '(' + S + ')';
111
112  Print(T->getPointeeType(), S);
113}
114
115void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
116  S = '^' + S;
117  Print(T->getPointeeType(), S);
118}
119
120void TypePrinter::PrintLValueReference(const LValueReferenceType *T,
121                                       std::string &S) {
122  S = '&' + S;
123
124  // Handle things like 'int (&A)[4];' correctly.
125  // FIXME: this should include vectors, but vectors use attributes I guess.
126  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
127    S = '(' + S + ')';
128
129  Print(T->getPointeeTypeAsWritten(), S);
130}
131
132void TypePrinter::PrintRValueReference(const RValueReferenceType *T,
133                                       std::string &S) {
134  S = "&&" + S;
135
136  // Handle things like 'int (&&A)[4];' correctly.
137  // FIXME: this should include vectors, but vectors use attributes I guess.
138  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
139    S = '(' + S + ')';
140
141  Print(T->getPointeeTypeAsWritten(), S);
142}
143
144void TypePrinter::PrintMemberPointer(const MemberPointerType *T,
145                                     std::string &S) {
146  std::string C;
147  Print(QualType(T->getClass(), 0), C);
148  C += "::*";
149  S = C + S;
150
151  // Handle things like 'int (Cls::*A)[4];' correctly.
152  // FIXME: this should include vectors, but vectors use attributes I guess.
153  if (isa<ArrayType>(T->getPointeeType()))
154    S = '(' + S + ')';
155
156  Print(T->getPointeeType(), S);
157}
158
159void TypePrinter::PrintConstantArray(const ConstantArrayType *T,
160                                     std::string &S) {
161  S += '[';
162  S += llvm::utostr(T->getSize().getZExtValue());
163  S += ']';
164
165  Print(T->getElementType(), S);
166}
167
168void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T,
169                                       std::string &S) {
170  S += "[]";
171  Print(T->getElementType(), S);
172}
173
174void TypePrinter::PrintVariableArray(const VariableArrayType *T,
175                                     std::string &S) {
176  S += '[';
177
178  if (T->getIndexTypeQualifiers().hasQualifiers()) {
179    AppendTypeQualList(S, T->getIndexTypeCVRQualifiers());
180    S += ' ';
181  }
182
183  if (T->getSizeModifier() == VariableArrayType::Static)
184    S += "static";
185  else if (T->getSizeModifier() == VariableArrayType::Star)
186    S += '*';
187
188  if (T->getSizeExpr()) {
189    std::string SStr;
190    llvm::raw_string_ostream s(SStr);
191    T->getSizeExpr()->printPretty(s, 0, Policy);
192    S += s.str();
193  }
194  S += ']';
195
196  Print(T->getElementType(), S);
197}
198
199void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T,
200                                           std::string &S) {
201  S += '[';
202
203  if (T->getSizeExpr()) {
204    std::string SStr;
205    llvm::raw_string_ostream s(SStr);
206    T->getSizeExpr()->printPretty(s, 0, Policy);
207    S += s.str();
208  }
209  S += ']';
210
211  Print(T->getElementType(), S);
212}
213
214void TypePrinter::PrintDependentSizedExtVector(
215                                          const DependentSizedExtVectorType *T,
216                                               std::string &S) {
217  Print(T->getElementType(), S);
218
219  S += " __attribute__((ext_vector_type(";
220  if (T->getSizeExpr()) {
221    std::string SStr;
222    llvm::raw_string_ostream s(SStr);
223    T->getSizeExpr()->printPretty(s, 0, Policy);
224    S += s.str();
225  }
226  S += ")))";
227}
228
229void TypePrinter::PrintVector(const VectorType *T, std::string &S) {
230  if (T->getAltiVecSpecific() != VectorType::NotAltiVec) {
231    if (T->getAltiVecSpecific() == VectorType::Pixel)
232      S = "__vector __pixel " + S;
233    else {
234      Print(T->getElementType(), S);
235      S = ((T->getAltiVecSpecific() == VectorType::Bool)
236           ? "__vector __bool " : "__vector ") + S;
237    }
238  } else {
239    // FIXME: We prefer to print the size directly here, but have no way
240    // to get the size of the type.
241    Print(T->getElementType(), S);
242    std::string V = "__attribute__((__vector_size__(";
243    V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
244    std::string ET;
245    Print(T->getElementType(), ET);
246    V += " * sizeof(" + ET + ")))) ";
247    S = V + S;
248  }
249}
250
251void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) {
252  S += " __attribute__((ext_vector_type(";
253  S += llvm::utostr_32(T->getNumElements());
254  S += ")))";
255  Print(T->getElementType(), S);
256}
257
258void TypePrinter::PrintFunctionProto(const FunctionProtoType *T,
259                                     std::string &S) {
260  // If needed for precedence reasons, wrap the inner part in grouping parens.
261  if (!S.empty())
262    S = "(" + S + ")";
263
264  S += "(";
265  std::string Tmp;
266  PrintingPolicy ParamPolicy(Policy);
267  ParamPolicy.SuppressSpecifiers = false;
268  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
269    if (i) S += ", ";
270    Print(T->getArgType(i), Tmp);
271    S += Tmp;
272    Tmp.clear();
273  }
274
275  if (T->isVariadic()) {
276    if (T->getNumArgs())
277      S += ", ";
278    S += "...";
279  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
280    // Do not emit int() if we have a proto, emit 'int(void)'.
281    S += "void";
282  }
283
284  S += ")";
285
286  FunctionType::ExtInfo Info = T->getExtInfo();
287  switch(Info.getCC()) {
288  case CC_Default:
289  default: break;
290  case CC_C:
291    S += " __attribute__((cdecl))";
292    break;
293  case CC_X86StdCall:
294    S += " __attribute__((stdcall))";
295    break;
296  case CC_X86FastCall:
297    S += " __attribute__((fastcall))";
298    break;
299  case CC_X86ThisCall:
300    S += " __attribute__((thiscall))";
301    break;
302  }
303  if (Info.getNoReturn())
304    S += " __attribute__((noreturn))";
305  if (Info.getRegParm())
306    S += " __attribute__((regparm (" +
307        llvm::utostr_32(Info.getRegParm()) + ")))";
308
309  if (T->hasExceptionSpec()) {
310    S += " throw(";
311    if (T->hasAnyExceptionSpec())
312      S += "...";
313    else
314      for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) {
315        if (I)
316          S += ", ";
317
318        std::string ExceptionType;
319        Print(T->getExceptionType(I), ExceptionType);
320        S += ExceptionType;
321      }
322    S += ")";
323  }
324
325  AppendTypeQualList(S, T->getTypeQuals());
326
327  Print(T->getResultType(), S);
328}
329
330void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
331                                       std::string &S) {
332  // If needed for precedence reasons, wrap the inner part in grouping parens.
333  if (!S.empty())
334    S = "(" + S + ")";
335
336  S += "()";
337  if (T->getNoReturnAttr())
338    S += " __attribute__((noreturn))";
339  Print(T->getResultType(), S);
340}
341
342static void PrintTypeSpec(const NamedDecl *D, std::string &S) {
343  IdentifierInfo *II = D->getIdentifier();
344  if (S.empty())
345    S = II->getName().str();
346  else
347    S = II->getName().str() + ' ' + S;
348}
349
350void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
351                                       std::string &S) {
352  PrintTypeSpec(T->getDecl(), S);
353}
354
355void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
356  PrintTypeSpec(T->getDecl(), S);
357}
358
359void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
360  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
361    S = ' ' + S;
362  std::string Str;
363  llvm::raw_string_ostream s(Str);
364  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
365  S = "typeof " + s.str() + S;
366}
367
368void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) {
369  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
370    S = ' ' + S;
371  std::string Tmp;
372  Print(T->getUnderlyingType(), Tmp);
373  S = "typeof(" + Tmp + ")" + S;
374}
375
376void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) {
377  if (!S.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
378    S = ' ' + S;
379  std::string Str;
380  llvm::raw_string_ostream s(Str);
381  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
382  S = "decltype(" + s.str() + ")" + S;
383}
384
385/// Appends the given scope to the end of a string.
386void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) {
387  if (DC->isTranslationUnit()) return;
388  AppendScope(DC->getParent(), Buffer);
389
390  unsigned OldSize = Buffer.size();
391
392  if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
393    if (NS->getIdentifier())
394      Buffer += NS->getNameAsString();
395    else
396      Buffer += "<anonymous>";
397  } else if (ClassTemplateSpecializationDecl *Spec
398               = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
399    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
400    std::string TemplateArgsStr
401      = TemplateSpecializationType::PrintTemplateArgumentList(
402                                            TemplateArgs.getFlatArgumentList(),
403                                            TemplateArgs.flat_size(),
404                                            Policy);
405    Buffer += Spec->getIdentifier()->getName();
406    Buffer += TemplateArgsStr;
407  } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
408    if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
409      Buffer += Typedef->getIdentifier()->getName();
410    else if (Tag->getIdentifier())
411      Buffer += Tag->getIdentifier()->getName();
412  }
413
414  if (Buffer.size() != OldSize)
415    Buffer += "::";
416}
417
418void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
419  if (Policy.SuppressTag)
420    return;
421
422  std::string Buffer;
423  bool HasKindDecoration = false;
424
425  // We don't print tags unless this is an elaborated type.
426  // In C, we just assume every RecordType is an elaborated type.
427  if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
428    HasKindDecoration = true;
429    Buffer += D->getKindName();
430    Buffer += ' ';
431  }
432
433  if (!Policy.SuppressScope)
434    // Compute the full nested-name-specifier for this type. In C,
435    // this will always be empty.
436    AppendScope(D->getDeclContext(), Buffer);
437
438  if (const IdentifierInfo *II = D->getIdentifier())
439    Buffer += II->getNameStart();
440  else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
441    assert(Typedef->getIdentifier() && "Typedef without identifier?");
442    Buffer += Typedef->getIdentifier()->getNameStart();
443  } else {
444    // Make an unambiguous representation for anonymous types, e.g.
445    //   <anonymous enum at /usr/include/string.h:120:9>
446    llvm::raw_string_ostream OS(Buffer);
447    OS << "<anonymous";
448
449    if (Policy.AnonymousTagLocations) {
450      // Suppress the redundant tag keyword if we just printed one.
451      // We don't have to worry about ElaboratedTypes here because you can't
452      // refer to an anonymous type with one.
453      if (!HasKindDecoration)
454        OS << " " << D->getKindName();
455
456      if (D->getLocation().isValid()) {
457        PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
458          D->getLocation());
459        OS << " at " << PLoc.getFilename()
460           << ':' << PLoc.getLine()
461           << ':' << PLoc.getColumn();
462      }
463    }
464
465    OS << '>';
466    OS.flush();
467  }
468
469  // If this is a class template specialization, print the template
470  // arguments.
471  if (ClassTemplateSpecializationDecl *Spec
472        = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
473    const TemplateArgument *Args;
474    unsigned NumArgs;
475    if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
476      const TemplateSpecializationType *TST =
477        cast<TemplateSpecializationType>(TAW->getType());
478      Args = TST->getArgs();
479      NumArgs = TST->getNumArgs();
480    } else {
481      const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
482      Args = TemplateArgs.getFlatArgumentList();
483      NumArgs = TemplateArgs.flat_size();
484    }
485    Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
486                                                                    NumArgs,
487                                                                    Policy);
488  }
489
490  if (!InnerString.empty()) {
491    Buffer += ' ';
492    Buffer += InnerString;
493  }
494
495  std::swap(Buffer, InnerString);
496}
497
498void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
499  PrintTag(T->getDecl(), S);
500}
501
502void TypePrinter::PrintEnum(const EnumType *T, std::string &S) {
503  PrintTag(T->getDecl(), S);
504}
505
506void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T,
507                                        std::string &S) {
508  if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
509    S = ' ' + S;
510
511  if (!T->getName())
512    S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
513        llvm::utostr_32(T->getIndex()) + S;
514  else
515    S = T->getName()->getName().str() + S;
516}
517
518void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T,
519                                             std::string &S) {
520  Print(T->getReplacementType(), S);
521}
522
523void TypePrinter::PrintTemplateSpecialization(
524                                            const TemplateSpecializationType *T,
525                                              std::string &S) {
526  std::string SpecString;
527
528  {
529    llvm::raw_string_ostream OS(SpecString);
530    T->getTemplateName().print(OS, Policy);
531  }
532
533  SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
534                                                                  T->getArgs(),
535                                                                T->getNumArgs(),
536                                                                      Policy);
537  if (S.empty())
538    S.swap(SpecString);
539  else
540    S = SpecString + ' ' + S;
541}
542
543void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T,
544                                         std::string &S) {
545  PrintTemplateSpecialization(T->getInjectedTST(), S);
546}
547
548void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
549  std::string MyString;
550
551  {
552    llvm::raw_string_ostream OS(MyString);
553    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
554    if (T->getKeyword() != ETK_None)
555      OS << " ";
556    NestedNameSpecifier* Qualifier = T->getQualifier();
557    if (Qualifier)
558      Qualifier->print(OS, Policy);
559  }
560
561  std::string TypeStr;
562  PrintingPolicy InnerPolicy(Policy);
563  InnerPolicy.SuppressScope = true;
564  TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
565
566  MyString += TypeStr;
567  if (S.empty())
568    S.swap(MyString);
569  else
570    S = MyString + ' ' + S;
571}
572
573void TypePrinter::PrintDependentName(const DependentNameType *T, std::string &S) {
574  std::string MyString;
575
576  {
577    llvm::raw_string_ostream OS(MyString);
578    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
579    if (T->getKeyword() != ETK_None)
580      OS << " ";
581
582    T->getQualifier()->print(OS, Policy);
583
584    OS << T->getIdentifier()->getName();
585  }
586
587  if (S.empty())
588    S.swap(MyString);
589  else
590    S = MyString + ' ' + S;
591}
592
593void TypePrinter::PrintDependentTemplateSpecialization(
594        const DependentTemplateSpecializationType *T, std::string &S) {
595  std::string MyString;
596  {
597    llvm::raw_string_ostream OS(MyString);
598
599    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
600    if (T->getKeyword() != ETK_None)
601      OS << " ";
602
603    T->getQualifier()->print(OS, Policy);
604    OS << T->getIdentifier()->getName();
605    OS << TemplateSpecializationType::PrintTemplateArgumentList(
606                                                            T->getArgs(),
607                                                            T->getNumArgs(),
608                                                            Policy);
609  }
610
611  if (S.empty())
612    S.swap(MyString);
613  else
614    S = MyString + ' ' + S;
615}
616
617void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T,
618                                     std::string &S) {
619  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
620    S = ' ' + S;
621
622  std::string ObjCQIString = T->getDecl()->getNameAsString();
623  S = ObjCQIString + S;
624}
625
626void TypePrinter::PrintObjCObject(const ObjCObjectType *T,
627                                  std::string &S) {
628  if (T->qual_empty())
629    return Print(T->getBaseType(), S);
630
631  std::string tmp;
632  Print(T->getBaseType(), tmp);
633  tmp += '<';
634  bool isFirst = true;
635  for (ObjCObjectType::qual_iterator
636         I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
637    if (isFirst)
638      isFirst = false;
639    else
640      tmp += ',';
641    tmp += (*I)->getNameAsString();
642  }
643  tmp += '>';
644
645  if (!S.empty()) {
646    tmp += ' ';
647    tmp += S;
648  }
649  std::swap(tmp, S);
650}
651
652void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T,
653                                         std::string &S) {
654  std::string ObjCQIString;
655
656  if (T->isObjCIdType() || T->isObjCQualifiedIdType())
657    ObjCQIString = "id";
658  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
659    ObjCQIString = "Class";
660  else if (T->isObjCSelType())
661    ObjCQIString = "SEL";
662  else
663    ObjCQIString = T->getInterfaceDecl()->getNameAsString();
664
665  if (!T->qual_empty()) {
666    ObjCQIString += '<';
667    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
668                                              E = T->qual_end();
669         I != E; ++I) {
670      ObjCQIString += (*I)->getNameAsString();
671      if (I+1 != E)
672        ObjCQIString += ',';
673    }
674    ObjCQIString += '>';
675  }
676
677  T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString,
678                                                               Policy);
679
680  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
681    ObjCQIString += " *"; // Don't forget the implicit pointer.
682  else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
683    S = ' ' + S;
684
685  S = ObjCQIString + S;
686}
687
688static void PrintTemplateArgument(std::string &Buffer,
689                                  const TemplateArgument &Arg,
690                                  const PrintingPolicy &Policy) {
691  switch (Arg.getKind()) {
692    case TemplateArgument::Null:
693      assert(false && "Null template argument");
694      break;
695
696    case TemplateArgument::Type:
697      Arg.getAsType().getAsStringInternal(Buffer, Policy);
698      break;
699
700    case TemplateArgument::Declaration:
701      Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
702      break;
703
704    case TemplateArgument::Template: {
705      llvm::raw_string_ostream s(Buffer);
706      Arg.getAsTemplate().print(s, Policy);
707      break;
708    }
709
710    case TemplateArgument::Integral:
711      Buffer = Arg.getAsIntegral()->toString(10, true);
712      break;
713
714    case TemplateArgument::Expression: {
715      llvm::raw_string_ostream s(Buffer);
716      Arg.getAsExpr()->printPretty(s, 0, Policy);
717      break;
718    }
719
720    case TemplateArgument::Pack:
721      assert(0 && "FIXME: Implement!");
722      break;
723  }
724}
725
726std::string TemplateSpecializationType::
727  PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
728                            const PrintingPolicy &Policy) {
729  return PrintTemplateArgumentList(Args.getArgumentArray(),
730                                   Args.size(),
731                                   Policy);
732}
733
734std::string
735TemplateSpecializationType::PrintTemplateArgumentList(
736                                                const TemplateArgument *Args,
737                                                unsigned NumArgs,
738                                                const PrintingPolicy &Policy) {
739  std::string SpecString;
740  SpecString += '<';
741  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
742    if (Arg)
743      SpecString += ", ";
744
745    // Print the argument into a string.
746    std::string ArgString;
747    PrintTemplateArgument(ArgString, Args[Arg], Policy);
748
749    // If this is the first argument and its string representation
750    // begins with the global scope specifier ('::foo'), add a space
751    // to avoid printing the diagraph '<:'.
752    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
753      SpecString += ' ';
754
755    SpecString += ArgString;
756  }
757
758  // If the last character of our string is '>', add another space to
759  // keep the two '>''s separate tokens. We don't *have* to do this in
760  // C++0x, but it's still good hygiene.
761  if (SpecString[SpecString.size() - 1] == '>')
762    SpecString += ' ';
763
764  SpecString += '>';
765
766  return SpecString;
767}
768
769// Sadly, repeat all that with TemplateArgLoc.
770std::string TemplateSpecializationType::
771PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
772                          const PrintingPolicy &Policy) {
773  std::string SpecString;
774  SpecString += '<';
775  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
776    if (Arg)
777      SpecString += ", ";
778
779    // Print the argument into a string.
780    std::string ArgString;
781    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
782
783    // If this is the first argument and its string representation
784    // begins with the global scope specifier ('::foo'), add a space
785    // to avoid printing the diagraph '<:'.
786    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
787      SpecString += ' ';
788
789    SpecString += ArgString;
790  }
791
792  // If the last character of our string is '>', add another space to
793  // keep the two '>''s separate tokens. We don't *have* to do this in
794  // C++0x, but it's still good hygiene.
795  if (SpecString[SpecString.size() - 1] == '>')
796    SpecString += ' ';
797
798  SpecString += '>';
799
800  return SpecString;
801}
802
803void QualType::dump(const char *msg) const {
804  std::string R = "identifier";
805  LangOptions LO;
806  getAsStringInternal(R, PrintingPolicy(LO));
807  if (msg)
808    llvm::errs() << msg << ": ";
809  llvm::errs() << R << "\n";
810}
811void QualType::dump() const {
812  dump("");
813}
814
815void Type::dump() const {
816  QualType(this, 0).dump();
817}
818
819std::string Qualifiers::getAsString() const {
820  LangOptions LO;
821  return getAsString(PrintingPolicy(LO));
822}
823
824// Appends qualifiers to the given string, separated by spaces.  Will
825// prefix a space if the string is non-empty.  Will not append a final
826// space.
827void Qualifiers::getAsStringInternal(std::string &S,
828                                     const PrintingPolicy&) const {
829  AppendTypeQualList(S, getCVRQualifiers());
830  if (unsigned AddressSpace = getAddressSpace()) {
831    if (!S.empty()) S += ' ';
832    S += "__attribute__((address_space(";
833    S += llvm::utostr_32(AddressSpace);
834    S += ")))";
835  }
836  if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
837    if (!S.empty()) S += ' ';
838    S += "__attribute__((objc_gc(";
839    if (GCAttrType == Qualifiers::Weak)
840      S += "weak";
841    else
842      S += "strong";
843    S += ")))";
844  }
845}
846
847std::string QualType::getAsString() const {
848  std::string S;
849  LangOptions LO;
850  getAsStringInternal(S, PrintingPolicy(LO));
851  return S;
852}
853
854void QualType::getAsStringInternal(std::string &S,
855                                   const PrintingPolicy &Policy) const {
856  TypePrinter Printer(Policy);
857  Printer.Print(*this, S);
858}
859