TypePrinter.cpp revision f813a2c03fcb05381b3252010435f557eb6b3cde
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->isAltiVec()) {
231    if (T->isPixel())
232      S = "__vector __pixel " + S;
233    else {
234      Print(T->getElementType(), S);
235      S = "__vector " + S;
236    }
237  } else {
238    // FIXME: We prefer to print the size directly here, but have no way
239    // to get the size of the type.
240    Print(T->getElementType(), S);
241    std::string V = "__attribute__((__vector_size__(";
242    V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
243    std::string ET;
244    Print(T->getElementType(), ET);
245    V += " * sizeof(" + ET + ")))) ";
246    S = V + S;
247  }
248}
249
250void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) {
251  S += " __attribute__((ext_vector_type(";
252  S += llvm::utostr_32(T->getNumElements());
253  S += ")))";
254  Print(T->getElementType(), S);
255}
256
257void TypePrinter::PrintFunctionProto(const FunctionProtoType *T,
258                                     std::string &S) {
259  // If needed for precedence reasons, wrap the inner part in grouping parens.
260  if (!S.empty())
261    S = "(" + S + ")";
262
263  S += "(";
264  std::string Tmp;
265  PrintingPolicy ParamPolicy(Policy);
266  ParamPolicy.SuppressSpecifiers = false;
267  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
268    if (i) S += ", ";
269    Print(T->getArgType(i), Tmp);
270    S += Tmp;
271    Tmp.clear();
272  }
273
274  if (T->isVariadic()) {
275    if (T->getNumArgs())
276      S += ", ";
277    S += "...";
278  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
279    // Do not emit int() if we have a proto, emit 'int(void)'.
280    S += "void";
281  }
282
283  S += ")";
284
285  FunctionType::ExtInfo Info = T->getExtInfo();
286  switch(Info.getCC()) {
287  case CC_Default:
288  default: break;
289  case CC_C:
290    S += " __attribute__((cdecl))";
291    break;
292  case CC_X86StdCall:
293    S += " __attribute__((stdcall))";
294    break;
295  case CC_X86FastCall:
296    S += " __attribute__((fastcall))";
297    break;
298  case CC_X86ThisCall:
299    S += " __attribute__((thiscall))";
300    break;
301  }
302  if (Info.getNoReturn())
303    S += " __attribute__((noreturn))";
304  if (Info.getRegParm())
305    S += " __attribute__((regparm (" +
306        llvm::utostr_32(Info.getRegParm()) + ")))";
307
308  if (T->hasExceptionSpec()) {
309    S += " throw(";
310    if (T->hasAnyExceptionSpec())
311      S += "...";
312    else
313      for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) {
314        if (I)
315          S += ", ";
316
317        std::string ExceptionType;
318        Print(T->getExceptionType(I), ExceptionType);
319        S += ExceptionType;
320      }
321    S += ")";
322  }
323
324  AppendTypeQualList(S, T->getTypeQuals());
325
326  Print(T->getResultType(), S);
327}
328
329void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
330                                       std::string &S) {
331  // If needed for precedence reasons, wrap the inner part in grouping parens.
332  if (!S.empty())
333    S = "(" + S + ")";
334
335  S += "()";
336  if (T->getNoReturnAttr())
337    S += " __attribute__((noreturn))";
338  Print(T->getResultType(), S);
339}
340
341static void PrintTypeSpec(const NamedDecl *D, std::string &S) {
342  IdentifierInfo *II = D->getIdentifier();
343  if (S.empty())
344    S = II->getName().str();
345  else
346    S = II->getName().str() + ' ' + S;
347}
348
349void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
350                                       std::string &S) {
351  PrintTypeSpec(T->getDecl(), S);
352}
353
354void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
355  PrintTypeSpec(T->getDecl(), S);
356}
357
358void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
359  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
360    S = ' ' + S;
361  std::string Str;
362  llvm::raw_string_ostream s(Str);
363  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
364  S = "typeof " + s.str() + S;
365}
366
367void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) {
368  if (!S.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
369    S = ' ' + S;
370  std::string Tmp;
371  Print(T->getUnderlyingType(), Tmp);
372  S = "typeof(" + Tmp + ")" + S;
373}
374
375void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) {
376  if (!S.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
377    S = ' ' + S;
378  std::string Str;
379  llvm::raw_string_ostream s(Str);
380  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
381  S = "decltype(" + s.str() + ")" + S;
382}
383
384/// Appends the given scope to the end of a string.
385void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) {
386  if (DC->isTranslationUnit()) return;
387  AppendScope(DC->getParent(), Buffer);
388
389  unsigned OldSize = Buffer.size();
390
391  if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
392    if (NS->getIdentifier())
393      Buffer += NS->getNameAsString();
394    else
395      Buffer += "<anonymous>";
396  } else if (ClassTemplateSpecializationDecl *Spec
397               = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
398    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
399    std::string TemplateArgsStr
400      = TemplateSpecializationType::PrintTemplateArgumentList(
401                                            TemplateArgs.getFlatArgumentList(),
402                                            TemplateArgs.flat_size(),
403                                            Policy);
404    Buffer += Spec->getIdentifier()->getName();
405    Buffer += TemplateArgsStr;
406  } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
407    if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
408      Buffer += Typedef->getIdentifier()->getName();
409    else if (Tag->getIdentifier())
410      Buffer += Tag->getIdentifier()->getName();
411  }
412
413  if (Buffer.size() != OldSize)
414    Buffer += "::";
415}
416
417void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
418  if (Policy.SuppressTag)
419    return;
420
421  std::string Buffer;
422  bool HasKindDecoration = false;
423
424  // We don't print tags unless this is an elaborated type.
425  // In C, we just assume every RecordType is an elaborated type.
426  if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
427    HasKindDecoration = true;
428    Buffer += D->getKindName();
429    Buffer += ' ';
430  }
431
432  if (!Policy.SuppressScope)
433    // Compute the full nested-name-specifier for this type. In C,
434    // this will always be empty.
435    AppendScope(D->getDeclContext(), Buffer);
436
437  if (const IdentifierInfo *II = D->getIdentifier())
438    Buffer += II->getNameStart();
439  else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
440    assert(Typedef->getIdentifier() && "Typedef without identifier?");
441    Buffer += Typedef->getIdentifier()->getNameStart();
442  } else {
443    // Make an unambiguous representation for anonymous types, e.g.
444    //   <anonymous enum at /usr/include/string.h:120:9>
445    llvm::raw_string_ostream OS(Buffer);
446    OS << "<anonymous";
447
448    if (Policy.AnonymousTagLocations) {
449      // Suppress the redundant tag keyword if we just printed one.
450      // We don't have to worry about ElaboratedTypes here because you can't
451      // refer to an anonymous type with one.
452      if (!HasKindDecoration)
453        OS << " " << D->getKindName();
454
455      PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
456        D->getLocation());
457      OS << " at " << PLoc.getFilename()
458         << ':' << PLoc.getLine()
459         << ':' << PLoc.getColumn();
460    }
461
462    OS << '>';
463    OS.flush();
464  }
465
466  // If this is a class template specialization, print the template
467  // arguments.
468  if (ClassTemplateSpecializationDecl *Spec
469        = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
470    const TemplateArgument *Args;
471    unsigned NumArgs;
472    if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
473      const TemplateSpecializationType *TST =
474        cast<TemplateSpecializationType>(TAW->getType());
475      Args = TST->getArgs();
476      NumArgs = TST->getNumArgs();
477    } else {
478      const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
479      Args = TemplateArgs.getFlatArgumentList();
480      NumArgs = TemplateArgs.flat_size();
481    }
482    Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
483                                                                    NumArgs,
484                                                                    Policy);
485  }
486
487  if (!InnerString.empty()) {
488    Buffer += ' ';
489    Buffer += InnerString;
490  }
491
492  std::swap(Buffer, InnerString);
493}
494
495void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
496  PrintTag(T->getDecl(), S);
497}
498
499void TypePrinter::PrintEnum(const EnumType *T, std::string &S) {
500  PrintTag(T->getDecl(), S);
501}
502
503void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T,
504                                        std::string &S) {
505  if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
506    S = ' ' + S;
507
508  if (!T->getName())
509    S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
510        llvm::utostr_32(T->getIndex()) + S;
511  else
512    S = T->getName()->getName().str() + S;
513}
514
515void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T,
516                                             std::string &S) {
517  Print(T->getReplacementType(), S);
518}
519
520void TypePrinter::PrintTemplateSpecialization(
521                                            const TemplateSpecializationType *T,
522                                              std::string &S) {
523  std::string SpecString;
524
525  {
526    llvm::raw_string_ostream OS(SpecString);
527    T->getTemplateName().print(OS, Policy);
528  }
529
530  SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
531                                                                  T->getArgs(),
532                                                                T->getNumArgs(),
533                                                                      Policy);
534  if (S.empty())
535    S.swap(SpecString);
536  else
537    S = SpecString + ' ' + S;
538}
539
540void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T,
541                                         std::string &S) {
542  PrintTemplateSpecialization(T->getInjectedTST(), S);
543}
544
545void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
546  std::string MyString;
547
548  {
549    llvm::raw_string_ostream OS(MyString);
550    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
551    if (T->getKeyword() != ETK_None)
552      OS << " ";
553    NestedNameSpecifier* Qualifier = T->getQualifier();
554    if (Qualifier)
555      Qualifier->print(OS, Policy);
556  }
557
558  std::string TypeStr;
559  PrintingPolicy InnerPolicy(Policy);
560  InnerPolicy.SuppressScope = true;
561  TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
562
563  MyString += TypeStr;
564  if (S.empty())
565    S.swap(MyString);
566  else
567    S = MyString + ' ' + S;
568}
569
570void TypePrinter::PrintDependentName(const DependentNameType *T, std::string &S) {
571  std::string MyString;
572
573  {
574    llvm::raw_string_ostream OS(MyString);
575    OS << TypeWithKeyword::getKeywordName(T->getKeyword());
576    if (T->getKeyword() != ETK_None)
577      OS << " ";
578
579    T->getQualifier()->print(OS, Policy);
580
581    if (const IdentifierInfo *Ident = T->getIdentifier())
582      OS << Ident->getName();
583    else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
584      Spec->getTemplateName().print(OS, Policy, true);
585      OS << TemplateSpecializationType::PrintTemplateArgumentList(
586                                                            Spec->getArgs(),
587                                                            Spec->getNumArgs(),
588                                                            Policy);
589    }
590  }
591
592  if (S.empty())
593    S.swap(MyString);
594  else
595    S = MyString + ' ' + S;
596}
597
598void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T,
599                                     std::string &S) {
600  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
601    S = ' ' + S;
602
603  std::string ObjCQIString = T->getDecl()->getNameAsString();
604  S = ObjCQIString + S;
605}
606
607void TypePrinter::PrintObjCObject(const ObjCObjectType *T,
608                                  std::string &S) {
609  if (T->qual_empty())
610    return Print(T->getBaseType(), S);
611
612  std::string tmp;
613  Print(T->getBaseType(), tmp);
614  tmp += '<';
615  bool isFirst = true;
616  for (ObjCObjectType::qual_iterator
617         I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
618    if (isFirst)
619      isFirst = false;
620    else
621      tmp += ',';
622    tmp += (*I)->getNameAsString();
623  }
624  tmp += '>';
625
626  if (!S.empty()) {
627    tmp += ' ';
628    tmp += S;
629  }
630  std::swap(tmp, S);
631}
632
633void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T,
634                                         std::string &S) {
635  std::string ObjCQIString;
636
637  if (T->isObjCIdType() || T->isObjCQualifiedIdType())
638    ObjCQIString = "id";
639  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
640    ObjCQIString = "Class";
641  else if (T->isObjCSelType())
642    ObjCQIString = "SEL";
643  else
644    ObjCQIString = T->getInterfaceDecl()->getNameAsString();
645
646  if (!T->qual_empty()) {
647    ObjCQIString += '<';
648    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
649                                              E = T->qual_end();
650         I != E; ++I) {
651      ObjCQIString += (*I)->getNameAsString();
652      if (I+1 != E)
653        ObjCQIString += ',';
654    }
655    ObjCQIString += '>';
656  }
657
658  T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString,
659                                                               Policy);
660
661  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
662    ObjCQIString += " *"; // Don't forget the implicit pointer.
663  else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
664    S = ' ' + S;
665
666  S = ObjCQIString + S;
667}
668
669static void PrintTemplateArgument(std::string &Buffer,
670                                  const TemplateArgument &Arg,
671                                  const PrintingPolicy &Policy) {
672  switch (Arg.getKind()) {
673    case TemplateArgument::Null:
674      assert(false && "Null template argument");
675      break;
676
677    case TemplateArgument::Type:
678      Arg.getAsType().getAsStringInternal(Buffer, Policy);
679      break;
680
681    case TemplateArgument::Declaration:
682      Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
683      break;
684
685    case TemplateArgument::Template: {
686      llvm::raw_string_ostream s(Buffer);
687      Arg.getAsTemplate().print(s, Policy);
688      break;
689    }
690
691    case TemplateArgument::Integral:
692      Buffer = Arg.getAsIntegral()->toString(10, true);
693      break;
694
695    case TemplateArgument::Expression: {
696      llvm::raw_string_ostream s(Buffer);
697      Arg.getAsExpr()->printPretty(s, 0, Policy);
698      break;
699    }
700
701    case TemplateArgument::Pack:
702      assert(0 && "FIXME: Implement!");
703      break;
704  }
705}
706
707std::string TemplateSpecializationType::
708  PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
709                            const PrintingPolicy &Policy) {
710  return PrintTemplateArgumentList(Args.getArgumentArray(),
711                                   Args.size(),
712                                   Policy);
713}
714
715std::string
716TemplateSpecializationType::PrintTemplateArgumentList(
717                                                const TemplateArgument *Args,
718                                                unsigned NumArgs,
719                                                const PrintingPolicy &Policy) {
720  std::string SpecString;
721  SpecString += '<';
722  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
723    if (Arg)
724      SpecString += ", ";
725
726    // Print the argument into a string.
727    std::string ArgString;
728    PrintTemplateArgument(ArgString, Args[Arg], Policy);
729
730    // If this is the first argument and its string representation
731    // begins with the global scope specifier ('::foo'), add a space
732    // to avoid printing the diagraph '<:'.
733    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
734      SpecString += ' ';
735
736    SpecString += ArgString;
737  }
738
739  // If the last character of our string is '>', add another space to
740  // keep the two '>''s separate tokens. We don't *have* to do this in
741  // C++0x, but it's still good hygiene.
742  if (SpecString[SpecString.size() - 1] == '>')
743    SpecString += ' ';
744
745  SpecString += '>';
746
747  return SpecString;
748}
749
750// Sadly, repeat all that with TemplateArgLoc.
751std::string TemplateSpecializationType::
752PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
753                          const PrintingPolicy &Policy) {
754  std::string SpecString;
755  SpecString += '<';
756  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
757    if (Arg)
758      SpecString += ", ";
759
760    // Print the argument into a string.
761    std::string ArgString;
762    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
763
764    // If this is the first argument and its string representation
765    // begins with the global scope specifier ('::foo'), add a space
766    // to avoid printing the diagraph '<:'.
767    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
768      SpecString += ' ';
769
770    SpecString += ArgString;
771  }
772
773  // If the last character of our string is '>', add another space to
774  // keep the two '>''s separate tokens. We don't *have* to do this in
775  // C++0x, but it's still good hygiene.
776  if (SpecString[SpecString.size() - 1] == '>')
777    SpecString += ' ';
778
779  SpecString += '>';
780
781  return SpecString;
782}
783
784void QualType::dump(const char *msg) const {
785  std::string R = "identifier";
786  LangOptions LO;
787  getAsStringInternal(R, PrintingPolicy(LO));
788  if (msg)
789    llvm::errs() << msg << ": ";
790  llvm::errs() << R << "\n";
791}
792void QualType::dump() const {
793  dump("");
794}
795
796void Type::dump() const {
797  QualType(this, 0).dump();
798}
799
800std::string Qualifiers::getAsString() const {
801  LangOptions LO;
802  return getAsString(PrintingPolicy(LO));
803}
804
805// Appends qualifiers to the given string, separated by spaces.  Will
806// prefix a space if the string is non-empty.  Will not append a final
807// space.
808void Qualifiers::getAsStringInternal(std::string &S,
809                                     const PrintingPolicy&) const {
810  AppendTypeQualList(S, getCVRQualifiers());
811  if (unsigned AddressSpace = getAddressSpace()) {
812    if (!S.empty()) S += ' ';
813    S += "__attribute__((address_space(";
814    S += llvm::utostr_32(AddressSpace);
815    S += ")))";
816  }
817  if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
818    if (!S.empty()) S += ' ';
819    S += "__attribute__((objc_gc(";
820    if (GCAttrType == Qualifiers::Weak)
821      S += "weak";
822    else
823      S += "strong";
824    S += ")))";
825  }
826}
827
828std::string QualType::getAsString() const {
829  std::string S;
830  LangOptions LO;
831  getAsStringInternal(S, PrintingPolicy(LO));
832  return S;
833}
834
835void QualType::getAsStringInternal(std::string &S,
836                                   const PrintingPolicy &Policy) const {
837  TypePrinter Printer(Policy);
838  Printer.Print(*this, S);
839}
840