• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ASTContext.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/Type.h"
20 #include "clang/AST/PrettyPrinter.h"
21 #include "clang/Basic/LangOptions.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/Support/SaveAndRestore.h"
27 using namespace clang;
28 
29 namespace {
30   /// \brief RAII object that enables printing of the ARC __strong lifetime
31   /// qualifier.
32   class IncludeStrongLifetimeRAII {
33     PrintingPolicy &Policy;
34     bool Old;
35 
36   public:
IncludeStrongLifetimeRAII(PrintingPolicy & Policy)37     explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
38       : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
39       Policy.SuppressStrongLifetime = false;
40     }
41 
~IncludeStrongLifetimeRAII()42     ~IncludeStrongLifetimeRAII() {
43       Policy.SuppressStrongLifetime = Old;
44     }
45   };
46 
47   class ParamPolicyRAII {
48     PrintingPolicy &Policy;
49     bool Old;
50 
51   public:
ParamPolicyRAII(PrintingPolicy & Policy)52     explicit ParamPolicyRAII(PrintingPolicy &Policy)
53       : Policy(Policy), Old(Policy.SuppressSpecifiers) {
54       Policy.SuppressSpecifiers = false;
55     }
56 
~ParamPolicyRAII()57     ~ParamPolicyRAII() {
58       Policy.SuppressSpecifiers = Old;
59     }
60   };
61 
62   class ElaboratedTypePolicyRAII {
63     PrintingPolicy &Policy;
64     bool SuppressTagKeyword;
65     bool SuppressScope;
66 
67   public:
ElaboratedTypePolicyRAII(PrintingPolicy & Policy)68     explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
69       SuppressTagKeyword = Policy.SuppressTagKeyword;
70       SuppressScope = Policy.SuppressScope;
71       Policy.SuppressTagKeyword = true;
72       Policy.SuppressScope = true;
73     }
74 
~ElaboratedTypePolicyRAII()75     ~ElaboratedTypePolicyRAII() {
76       Policy.SuppressTagKeyword = SuppressTagKeyword;
77       Policy.SuppressScope = SuppressScope;
78     }
79   };
80 
81   class TypePrinter {
82     PrintingPolicy Policy;
83     bool HasEmptyPlaceHolder;
84 
85   public:
TypePrinter(const PrintingPolicy & Policy)86     explicit TypePrinter(const PrintingPolicy &Policy)
87       : Policy(Policy), HasEmptyPlaceHolder(false) { }
88 
89     void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
90                StringRef PlaceHolder);
91     void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
92 
93     static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
94     void spaceBeforePlaceHolder(raw_ostream &OS);
95     void printTypeSpec(const NamedDecl *D, raw_ostream &OS);
96 
97     void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
98     void printBefore(QualType T, raw_ostream &OS);
99     void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
100     void printAfter(QualType T, raw_ostream &OS);
101     void AppendScope(DeclContext *DC, raw_ostream &OS);
102     void printTag(TagDecl *T, raw_ostream &OS);
103 #define ABSTRACT_TYPE(CLASS, PARENT)
104 #define TYPE(CLASS, PARENT) \
105     void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
106     void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
107 #include "clang/AST/TypeNodes.def"
108   };
109 }
110 
AppendTypeQualList(raw_ostream & OS,unsigned TypeQuals)111 static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals) {
112   bool appendSpace = false;
113   if (TypeQuals & Qualifiers::Const) {
114     OS << "const";
115     appendSpace = true;
116   }
117   if (TypeQuals & Qualifiers::Volatile) {
118     if (appendSpace) OS << ' ';
119     OS << "volatile";
120     appendSpace = true;
121   }
122   if (TypeQuals & Qualifiers::Restrict) {
123     if (appendSpace) OS << ' ';
124     OS << "restrict";
125   }
126 }
127 
spaceBeforePlaceHolder(raw_ostream & OS)128 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
129   if (!HasEmptyPlaceHolder)
130     OS << ' ';
131 }
132 
print(QualType t,raw_ostream & OS,StringRef PlaceHolder)133 void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
134   SplitQualType split = t.split();
135   print(split.Ty, split.Quals, OS, PlaceHolder);
136 }
137 
print(const Type * T,Qualifiers Quals,raw_ostream & OS,StringRef PlaceHolder)138 void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
139                         StringRef PlaceHolder) {
140   if (!T) {
141     OS << "NULL TYPE";
142     return;
143   }
144 
145   if (Policy.SuppressSpecifiers && T->isSpecifierType())
146     return;
147 
148   SaveAndRestore<bool> PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
149 
150   printBefore(T, Quals, OS);
151   OS << PlaceHolder;
152   printAfter(T, Quals, OS);
153 }
154 
canPrefixQualifiers(const Type * T,bool & NeedARCStrongQualifier)155 bool TypePrinter::canPrefixQualifiers(const Type *T,
156                                       bool &NeedARCStrongQualifier) {
157   // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
158   // so that we get "const int" instead of "int const", but we can't do this if
159   // the type is complex.  For example if the type is "int*", we *must* print
160   // "int * const", printing "const int *" is different.  Only do this when the
161   // type expands to a simple string.
162   bool CanPrefixQualifiers = false;
163   NeedARCStrongQualifier = false;
164   Type::TypeClass TC = T->getTypeClass();
165   if (const AutoType *AT = dyn_cast<AutoType>(T))
166     TC = AT->desugar()->getTypeClass();
167   if (const SubstTemplateTypeParmType *Subst
168                                       = dyn_cast<SubstTemplateTypeParmType>(T))
169     TC = Subst->getReplacementType()->getTypeClass();
170 
171   switch (TC) {
172     case Type::Builtin:
173     case Type::Complex:
174     case Type::UnresolvedUsing:
175     case Type::Typedef:
176     case Type::TypeOfExpr:
177     case Type::TypeOf:
178     case Type::Decltype:
179     case Type::UnaryTransform:
180     case Type::Record:
181     case Type::Enum:
182     case Type::Elaborated:
183     case Type::TemplateTypeParm:
184     case Type::SubstTemplateTypeParmPack:
185     case Type::TemplateSpecialization:
186     case Type::InjectedClassName:
187     case Type::DependentName:
188     case Type::DependentTemplateSpecialization:
189     case Type::ObjCObject:
190     case Type::ObjCInterface:
191     case Type::Atomic:
192       CanPrefixQualifiers = true;
193       break;
194 
195     case Type::ObjCObjectPointer:
196       CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
197         T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
198       break;
199 
200     case Type::ConstantArray:
201     case Type::IncompleteArray:
202     case Type::VariableArray:
203     case Type::DependentSizedArray:
204       NeedARCStrongQualifier = true;
205       // Fall through
206 
207     case Type::Pointer:
208     case Type::BlockPointer:
209     case Type::LValueReference:
210     case Type::RValueReference:
211     case Type::MemberPointer:
212     case Type::DependentSizedExtVector:
213     case Type::Vector:
214     case Type::ExtVector:
215     case Type::FunctionProto:
216     case Type::FunctionNoProto:
217     case Type::Paren:
218     case Type::Attributed:
219     case Type::PackExpansion:
220     case Type::SubstTemplateTypeParm:
221     case Type::Auto:
222       CanPrefixQualifiers = false;
223       break;
224   }
225 
226   return CanPrefixQualifiers;
227 }
228 
printBefore(QualType T,raw_ostream & OS)229 void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
230   SplitQualType Split = T.split();
231 
232   // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
233   // at this level.
234   Qualifiers Quals = Split.Quals;
235   if (const SubstTemplateTypeParmType *Subst =
236         dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
237     Quals -= QualType(Subst, 0).getQualifiers();
238 
239   printBefore(Split.Ty, Quals, OS);
240 }
241 
242 /// \brief Prints the part of the type string before an identifier, e.g. for
243 /// "int foo[10]" it prints "int ".
printBefore(const Type * T,Qualifiers Quals,raw_ostream & OS)244 void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
245   if (Policy.SuppressSpecifiers && T->isSpecifierType())
246     return;
247 
248   SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder);
249 
250   // Print qualifiers as appropriate.
251 
252   bool CanPrefixQualifiers = false;
253   bool NeedARCStrongQualifier = false;
254   CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
255 
256   if (CanPrefixQualifiers && !Quals.empty()) {
257     if (NeedARCStrongQualifier) {
258       IncludeStrongLifetimeRAII Strong(Policy);
259       Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
260     } else {
261       Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
262     }
263   }
264 
265   bool hasAfterQuals = false;
266   if (!CanPrefixQualifiers && !Quals.empty()) {
267     hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
268     if (hasAfterQuals)
269       HasEmptyPlaceHolder = false;
270   }
271 
272   switch (T->getTypeClass()) {
273 #define ABSTRACT_TYPE(CLASS, PARENT)
274 #define TYPE(CLASS, PARENT) case Type::CLASS: \
275     print##CLASS##Before(cast<CLASS##Type>(T), OS); \
276     break;
277 #include "clang/AST/TypeNodes.def"
278   }
279 
280   if (hasAfterQuals) {
281     if (NeedARCStrongQualifier) {
282       IncludeStrongLifetimeRAII Strong(Policy);
283       Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
284     } else {
285       Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
286     }
287   }
288 }
289 
printAfter(QualType t,raw_ostream & OS)290 void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
291   SplitQualType split = t.split();
292   printAfter(split.Ty, split.Quals, OS);
293 }
294 
295 /// \brief Prints the part of the type string after an identifier, e.g. for
296 /// "int foo[10]" it prints "[10]".
printAfter(const Type * T,Qualifiers Quals,raw_ostream & OS)297 void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
298   switch (T->getTypeClass()) {
299 #define ABSTRACT_TYPE(CLASS, PARENT)
300 #define TYPE(CLASS, PARENT) case Type::CLASS: \
301     print##CLASS##After(cast<CLASS##Type>(T), OS); \
302     break;
303 #include "clang/AST/TypeNodes.def"
304   }
305 }
306 
printBuiltinBefore(const BuiltinType * T,raw_ostream & OS)307 void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
308   OS << T->getName(Policy);
309   spaceBeforePlaceHolder(OS);
310 }
printBuiltinAfter(const BuiltinType * T,raw_ostream & OS)311 void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) { }
312 
printComplexBefore(const ComplexType * T,raw_ostream & OS)313 void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
314   OS << "_Complex ";
315   printBefore(T->getElementType(), OS);
316 }
printComplexAfter(const ComplexType * T,raw_ostream & OS)317 void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
318   printAfter(T->getElementType(), OS);
319 }
320 
printPointerBefore(const PointerType * T,raw_ostream & OS)321 void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
322   IncludeStrongLifetimeRAII Strong(Policy);
323   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
324   printBefore(T->getPointeeType(), OS);
325   // Handle things like 'int (*A)[4];' correctly.
326   // FIXME: this should include vectors, but vectors use attributes I guess.
327   if (isa<ArrayType>(T->getPointeeType()))
328     OS << '(';
329   OS << '*';
330 }
printPointerAfter(const PointerType * T,raw_ostream & OS)331 void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
332   IncludeStrongLifetimeRAII Strong(Policy);
333   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
334   // Handle things like 'int (*A)[4];' correctly.
335   // FIXME: this should include vectors, but vectors use attributes I guess.
336   if (isa<ArrayType>(T->getPointeeType()))
337     OS << ')';
338   printAfter(T->getPointeeType(), OS);
339 }
340 
printBlockPointerBefore(const BlockPointerType * T,raw_ostream & OS)341 void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
342                                           raw_ostream &OS) {
343   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
344   printBefore(T->getPointeeType(), OS);
345   OS << '^';
346 }
printBlockPointerAfter(const BlockPointerType * T,raw_ostream & OS)347 void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
348                                           raw_ostream &OS) {
349   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
350   printAfter(T->getPointeeType(), OS);
351 }
352 
printLValueReferenceBefore(const LValueReferenceType * T,raw_ostream & OS)353 void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
354                                              raw_ostream &OS) {
355   IncludeStrongLifetimeRAII Strong(Policy);
356   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
357   printBefore(T->getPointeeTypeAsWritten(), OS);
358   // Handle things like 'int (&A)[4];' correctly.
359   // FIXME: this should include vectors, but vectors use attributes I guess.
360   if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
361     OS << '(';
362   OS << '&';
363 }
printLValueReferenceAfter(const LValueReferenceType * T,raw_ostream & OS)364 void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
365                                             raw_ostream &OS) {
366   IncludeStrongLifetimeRAII Strong(Policy);
367   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
368   // Handle things like 'int (&A)[4];' correctly.
369   // FIXME: this should include vectors, but vectors use attributes I guess.
370   if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
371     OS << ')';
372   printAfter(T->getPointeeTypeAsWritten(), OS);
373 }
374 
printRValueReferenceBefore(const RValueReferenceType * T,raw_ostream & OS)375 void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
376                                              raw_ostream &OS) {
377   IncludeStrongLifetimeRAII Strong(Policy);
378   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
379   printBefore(T->getPointeeTypeAsWritten(), OS);
380   // Handle things like 'int (&&A)[4];' correctly.
381   // FIXME: this should include vectors, but vectors use attributes I guess.
382   if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
383     OS << '(';
384   OS << "&&";
385 }
printRValueReferenceAfter(const RValueReferenceType * T,raw_ostream & OS)386 void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
387                                             raw_ostream &OS) {
388   IncludeStrongLifetimeRAII Strong(Policy);
389   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
390   // Handle things like 'int (&&A)[4];' correctly.
391   // FIXME: this should include vectors, but vectors use attributes I guess.
392   if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
393     OS << ')';
394   printAfter(T->getPointeeTypeAsWritten(), OS);
395 }
396 
printMemberPointerBefore(const MemberPointerType * T,raw_ostream & OS)397 void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
398                                            raw_ostream &OS) {
399   IncludeStrongLifetimeRAII Strong(Policy);
400   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
401   printBefore(T->getPointeeType(), OS);
402   // Handle things like 'int (Cls::*A)[4];' correctly.
403   // FIXME: this should include vectors, but vectors use attributes I guess.
404   if (isa<ArrayType>(T->getPointeeType()))
405     OS << '(';
406 
407   PrintingPolicy InnerPolicy(Policy);
408   InnerPolicy.SuppressTag = false;
409   TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
410 
411   OS << "::*";
412 }
printMemberPointerAfter(const MemberPointerType * T,raw_ostream & OS)413 void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
414                                           raw_ostream &OS) {
415   IncludeStrongLifetimeRAII Strong(Policy);
416   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
417   // Handle things like 'int (Cls::*A)[4];' correctly.
418   // FIXME: this should include vectors, but vectors use attributes I guess.
419   if (isa<ArrayType>(T->getPointeeType()))
420     OS << ')';
421   printAfter(T->getPointeeType(), OS);
422 }
423 
printConstantArrayBefore(const ConstantArrayType * T,raw_ostream & OS)424 void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
425                                            raw_ostream &OS) {
426   IncludeStrongLifetimeRAII Strong(Policy);
427   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
428   printBefore(T->getElementType(), OS);
429 }
printConstantArrayAfter(const ConstantArrayType * T,raw_ostream & OS)430 void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
431                                           raw_ostream &OS) {
432   OS << '[' << T->getSize().getZExtValue() << ']';
433   printAfter(T->getElementType(), OS);
434 }
435 
printIncompleteArrayBefore(const IncompleteArrayType * T,raw_ostream & OS)436 void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
437                                              raw_ostream &OS) {
438   IncludeStrongLifetimeRAII Strong(Policy);
439   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
440   printBefore(T->getElementType(), OS);
441 }
printIncompleteArrayAfter(const IncompleteArrayType * T,raw_ostream & OS)442 void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
443                                             raw_ostream &OS) {
444   OS << "[]";
445   printAfter(T->getElementType(), OS);
446 }
447 
printVariableArrayBefore(const VariableArrayType * T,raw_ostream & OS)448 void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
449                                            raw_ostream &OS) {
450   IncludeStrongLifetimeRAII Strong(Policy);
451   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
452   printBefore(T->getElementType(), OS);
453 }
printVariableArrayAfter(const VariableArrayType * T,raw_ostream & OS)454 void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
455                                           raw_ostream &OS) {
456   OS << '[';
457   if (T->getIndexTypeQualifiers().hasQualifiers()) {
458     AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers());
459     OS << ' ';
460   }
461 
462   if (T->getSizeModifier() == VariableArrayType::Static)
463     OS << "static";
464   else if (T->getSizeModifier() == VariableArrayType::Star)
465     OS << '*';
466 
467   if (T->getSizeExpr())
468     T->getSizeExpr()->printPretty(OS, 0, Policy);
469   OS << ']';
470 
471   printAfter(T->getElementType(), OS);
472 }
473 
printDependentSizedArrayBefore(const DependentSizedArrayType * T,raw_ostream & OS)474 void TypePrinter::printDependentSizedArrayBefore(
475                                                const DependentSizedArrayType *T,
476                                                raw_ostream &OS) {
477   IncludeStrongLifetimeRAII Strong(Policy);
478   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
479   printBefore(T->getElementType(), OS);
480 }
printDependentSizedArrayAfter(const DependentSizedArrayType * T,raw_ostream & OS)481 void TypePrinter::printDependentSizedArrayAfter(
482                                                const DependentSizedArrayType *T,
483                                                raw_ostream &OS) {
484   OS << '[';
485   if (T->getSizeExpr())
486     T->getSizeExpr()->printPretty(OS, 0, Policy);
487   OS << ']';
488   printAfter(T->getElementType(), OS);
489 }
490 
printDependentSizedExtVectorBefore(const DependentSizedExtVectorType * T,raw_ostream & OS)491 void TypePrinter::printDependentSizedExtVectorBefore(
492                                           const DependentSizedExtVectorType *T,
493                                           raw_ostream &OS) {
494   printBefore(T->getElementType(), OS);
495 }
printDependentSizedExtVectorAfter(const DependentSizedExtVectorType * T,raw_ostream & OS)496 void TypePrinter::printDependentSizedExtVectorAfter(
497                                           const DependentSizedExtVectorType *T,
498                                           raw_ostream &OS) {
499   OS << " __attribute__((ext_vector_type(";
500   if (T->getSizeExpr())
501     T->getSizeExpr()->printPretty(OS, 0, Policy);
502   OS << ")))";
503   printAfter(T->getElementType(), OS);
504 }
505 
printVectorBefore(const VectorType * T,raw_ostream & OS)506 void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
507   switch (T->getVectorKind()) {
508   case VectorType::AltiVecPixel:
509     OS << "__vector __pixel ";
510     break;
511   case VectorType::AltiVecBool:
512     OS << "__vector __bool ";
513     printBefore(T->getElementType(), OS);
514     break;
515   case VectorType::AltiVecVector:
516     OS << "__vector ";
517     printBefore(T->getElementType(), OS);
518     break;
519   case VectorType::NeonVector:
520     OS << "__attribute__((neon_vector_type("
521        << T->getNumElements() << "))) ";
522     printBefore(T->getElementType(), OS);
523     break;
524   case VectorType::NeonPolyVector:
525     OS << "__attribute__((neon_polyvector_type(" <<
526           T->getNumElements() << "))) ";
527     printBefore(T->getElementType(), OS);
528     break;
529   case VectorType::GenericVector: {
530     // FIXME: We prefer to print the size directly here, but have no way
531     // to get the size of the type.
532     OS << "__attribute__((__vector_size__("
533        << T->getNumElements()
534        << " * sizeof(";
535     print(T->getElementType(), OS, StringRef());
536     OS << ")))) ";
537     printBefore(T->getElementType(), OS);
538     break;
539   }
540   }
541 }
printVectorAfter(const VectorType * T,raw_ostream & OS)542 void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
543   printAfter(T->getElementType(), OS);
544 }
545 
printExtVectorBefore(const ExtVectorType * T,raw_ostream & OS)546 void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
547                                        raw_ostream &OS) {
548   printBefore(T->getElementType(), OS);
549 }
printExtVectorAfter(const ExtVectorType * T,raw_ostream & OS)550 void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
551   printAfter(T->getElementType(), OS);
552   OS << " __attribute__((ext_vector_type(";
553   OS << T->getNumElements();
554   OS << ")))";
555 }
556 
557 void
printExceptionSpecification(raw_ostream & OS,PrintingPolicy Policy) const558 FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
559                                                PrintingPolicy Policy) const {
560 
561   if (hasDynamicExceptionSpec()) {
562     OS << " throw(";
563     if (getExceptionSpecType() == EST_MSAny)
564       OS << "...";
565     else
566       for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
567         if (I)
568           OS << ", ";
569 
570         OS << getExceptionType(I).stream(Policy);
571       }
572     OS << ')';
573   } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
574     OS << " noexcept";
575     if (getExceptionSpecType() == EST_ComputedNoexcept) {
576       OS << '(';
577       getNoexceptExpr()->printPretty(OS, 0, Policy);
578       OS << ')';
579     }
580   }
581 }
582 
printFunctionProtoBefore(const FunctionProtoType * T,raw_ostream & OS)583 void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
584                                            raw_ostream &OS) {
585   if (T->hasTrailingReturn()) {
586     OS << "auto ";
587     if (!HasEmptyPlaceHolder)
588       OS << '(';
589   } else {
590     // If needed for precedence reasons, wrap the inner part in grouping parens.
591     SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
592     printBefore(T->getResultType(), OS);
593     if (!PrevPHIsEmpty.get())
594       OS << '(';
595   }
596 }
597 
printFunctionProtoAfter(const FunctionProtoType * T,raw_ostream & OS)598 void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
599                                           raw_ostream &OS) {
600   // If needed for precedence reasons, wrap the inner part in grouping parens.
601   if (!HasEmptyPlaceHolder)
602     OS << ')';
603   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
604 
605   OS << '(';
606   {
607     ParamPolicyRAII ParamPolicy(Policy);
608     for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
609       if (i) OS << ", ";
610       print(T->getArgType(i), OS, StringRef());
611     }
612   }
613 
614   if (T->isVariadic()) {
615     if (T->getNumArgs())
616       OS << ", ";
617     OS << "...";
618   } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
619     // Do not emit int() if we have a proto, emit 'int(void)'.
620     OS << "void";
621   }
622 
623   OS << ')';
624 
625   FunctionType::ExtInfo Info = T->getExtInfo();
626   switch(Info.getCC()) {
627   case CC_Default: break;
628   case CC_C:
629     OS << " __attribute__((cdecl))";
630     break;
631   case CC_X86StdCall:
632     OS << " __attribute__((stdcall))";
633     break;
634   case CC_X86FastCall:
635     OS << " __attribute__((fastcall))";
636     break;
637   case CC_X86ThisCall:
638     OS << " __attribute__((thiscall))";
639     break;
640   case CC_X86Pascal:
641     OS << " __attribute__((pascal))";
642     break;
643   case CC_AAPCS:
644     OS << " __attribute__((pcs(\"aapcs\")))";
645     break;
646   case CC_AAPCS_VFP:
647     OS << " __attribute__((pcs(\"aapcs-vfp\")))";
648     break;
649   }
650   if (Info.getNoReturn())
651     OS << " __attribute__((noreturn))";
652   if (Info.getRegParm())
653     OS << " __attribute__((regparm ("
654        << Info.getRegParm() << ")))";
655 
656   if (unsigned quals = T->getTypeQuals()) {
657     OS << ' ';
658     AppendTypeQualList(OS, quals);
659   }
660 
661   switch (T->getRefQualifier()) {
662   case RQ_None:
663     break;
664 
665   case RQ_LValue:
666     OS << " &";
667     break;
668 
669   case RQ_RValue:
670     OS << " &&";
671     break;
672   }
673   T->printExceptionSpecification(OS, Policy);
674 
675   if (T->hasTrailingReturn()) {
676     OS << " -> ";
677     print(T->getResultType(), OS, StringRef());
678   } else
679     printAfter(T->getResultType(), OS);
680 }
681 
printFunctionNoProtoBefore(const FunctionNoProtoType * T,raw_ostream & OS)682 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
683                                              raw_ostream &OS) {
684   // If needed for precedence reasons, wrap the inner part in grouping parens.
685   SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
686   printBefore(T->getResultType(), OS);
687   if (!PrevPHIsEmpty.get())
688     OS << '(';
689 }
printFunctionNoProtoAfter(const FunctionNoProtoType * T,raw_ostream & OS)690 void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
691                                             raw_ostream &OS) {
692   // If needed for precedence reasons, wrap the inner part in grouping parens.
693   if (!HasEmptyPlaceHolder)
694     OS << ')';
695   SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
696 
697   OS << "()";
698   if (T->getNoReturnAttr())
699     OS << " __attribute__((noreturn))";
700   printAfter(T->getResultType(), OS);
701 }
702 
printTypeSpec(const NamedDecl * D,raw_ostream & OS)703 void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
704   IdentifierInfo *II = D->getIdentifier();
705   OS << II->getName();
706   spaceBeforePlaceHolder(OS);
707 }
708 
printUnresolvedUsingBefore(const UnresolvedUsingType * T,raw_ostream & OS)709 void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
710                                              raw_ostream &OS) {
711   printTypeSpec(T->getDecl(), OS);
712 }
printUnresolvedUsingAfter(const UnresolvedUsingType * T,raw_ostream & OS)713 void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
714                                              raw_ostream &OS) { }
715 
printTypedefBefore(const TypedefType * T,raw_ostream & OS)716 void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
717   printTypeSpec(T->getDecl(), OS);
718 }
printTypedefAfter(const TypedefType * T,raw_ostream & OS)719 void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { }
720 
printTypeOfExprBefore(const TypeOfExprType * T,raw_ostream & OS)721 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
722                                         raw_ostream &OS) {
723   OS << "typeof ";
724   T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
725   spaceBeforePlaceHolder(OS);
726 }
printTypeOfExprAfter(const TypeOfExprType * T,raw_ostream & OS)727 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
728                                        raw_ostream &OS) { }
729 
printTypeOfBefore(const TypeOfType * T,raw_ostream & OS)730 void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
731   OS << "typeof(";
732   print(T->getUnderlyingType(), OS, StringRef());
733   OS << ')';
734   spaceBeforePlaceHolder(OS);
735 }
printTypeOfAfter(const TypeOfType * T,raw_ostream & OS)736 void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { }
737 
printDecltypeBefore(const DecltypeType * T,raw_ostream & OS)738 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
739   OS << "decltype(";
740   T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
741   OS << ')';
742   spaceBeforePlaceHolder(OS);
743 }
printDecltypeAfter(const DecltypeType * T,raw_ostream & OS)744 void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { }
745 
printUnaryTransformBefore(const UnaryTransformType * T,raw_ostream & OS)746 void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
747                                             raw_ostream &OS) {
748   IncludeStrongLifetimeRAII Strong(Policy);
749 
750   switch (T->getUTTKind()) {
751     case UnaryTransformType::EnumUnderlyingType:
752       OS << "__underlying_type(";
753       print(T->getBaseType(), OS, StringRef());
754       OS << ')';
755       spaceBeforePlaceHolder(OS);
756       return;
757   }
758 
759   printBefore(T->getBaseType(), OS);
760 }
printUnaryTransformAfter(const UnaryTransformType * T,raw_ostream & OS)761 void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
762                                            raw_ostream &OS) {
763   IncludeStrongLifetimeRAII Strong(Policy);
764 
765   switch (T->getUTTKind()) {
766     case UnaryTransformType::EnumUnderlyingType:
767       return;
768   }
769 
770   printAfter(T->getBaseType(), OS);
771 }
772 
printAutoBefore(const AutoType * T,raw_ostream & OS)773 void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
774   // If the type has been deduced, do not print 'auto'.
775   if (T->isDeduced()) {
776     printBefore(T->getDeducedType(), OS);
777   } else {
778     OS << "auto";
779     spaceBeforePlaceHolder(OS);
780   }
781 }
printAutoAfter(const AutoType * T,raw_ostream & OS)782 void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
783   // If the type has been deduced, do not print 'auto'.
784   if (T->isDeduced())
785     printAfter(T->getDeducedType(), OS);
786 }
787 
printAtomicBefore(const AtomicType * T,raw_ostream & OS)788 void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
789   IncludeStrongLifetimeRAII Strong(Policy);
790 
791   OS << "_Atomic(";
792   print(T->getValueType(), OS, StringRef());
793   OS << ')';
794   spaceBeforePlaceHolder(OS);
795 }
printAtomicAfter(const AtomicType * T,raw_ostream & OS)796 void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { }
797 
798 /// Appends the given scope to the end of a string.
AppendScope(DeclContext * DC,raw_ostream & OS)799 void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
800   if (DC->isTranslationUnit()) return;
801   AppendScope(DC->getParent(), OS);
802 
803   if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
804     if (Policy.SuppressUnwrittenScope &&
805         (NS->isAnonymousNamespace() || NS->isInline()))
806       return;
807     if (NS->getIdentifier())
808       OS << NS->getName() << "::";
809     else
810       OS << "<anonymous>::";
811   } else if (ClassTemplateSpecializationDecl *Spec
812                = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
813     IncludeStrongLifetimeRAII Strong(Policy);
814     OS << Spec->getIdentifier()->getName();
815     const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
816     TemplateSpecializationType::PrintTemplateArgumentList(OS,
817                                             TemplateArgs.data(),
818                                             TemplateArgs.size(),
819                                             Policy);
820     OS << "::";
821   } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
822     if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
823       OS << Typedef->getIdentifier()->getName() << "::";
824     else if (Tag->getIdentifier())
825       OS << Tag->getIdentifier()->getName() << "::";
826     else
827       return;
828   }
829 }
830 
printTag(TagDecl * D,raw_ostream & OS)831 void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
832   if (Policy.SuppressTag)
833     return;
834 
835   bool HasKindDecoration = false;
836 
837   // bool SuppressTagKeyword
838   //   = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword;
839 
840   // We don't print tags unless this is an elaborated type.
841   // In C, we just assume every RecordType is an elaborated type.
842   if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword ||
843         D->getTypedefNameForAnonDecl())) {
844     HasKindDecoration = true;
845     OS << D->getKindName();
846     OS << ' ';
847   }
848 
849   // Compute the full nested-name-specifier for this type.
850   // In C, this will always be empty except when the type
851   // being printed is anonymous within other Record.
852   if (!Policy.SuppressScope)
853     AppendScope(D->getDeclContext(), OS);
854 
855   if (const IdentifierInfo *II = D->getIdentifier())
856     OS << II->getName();
857   else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
858     assert(Typedef->getIdentifier() && "Typedef without identifier?");
859     OS << Typedef->getIdentifier()->getName();
860   } else {
861     // Make an unambiguous representation for anonymous types, e.g.
862     //   <anonymous enum at /usr/include/string.h:120:9>
863 
864     if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
865       OS << "<lambda";
866       HasKindDecoration = true;
867     } else {
868       OS << "<anonymous";
869     }
870 
871     if (Policy.AnonymousTagLocations) {
872       // Suppress the redundant tag keyword if we just printed one.
873       // We don't have to worry about ElaboratedTypes here because you can't
874       // refer to an anonymous type with one.
875       if (!HasKindDecoration)
876         OS << " " << D->getKindName();
877 
878       PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
879           D->getLocation());
880       if (PLoc.isValid()) {
881         OS << " at " << PLoc.getFilename()
882            << ':' << PLoc.getLine()
883            << ':' << PLoc.getColumn();
884       }
885     }
886 
887     OS << '>';
888   }
889 
890   // If this is a class template specialization, print the template
891   // arguments.
892   if (ClassTemplateSpecializationDecl *Spec
893         = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
894     const TemplateArgument *Args;
895     unsigned NumArgs;
896     if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
897       const TemplateSpecializationType *TST =
898         cast<TemplateSpecializationType>(TAW->getType());
899       Args = TST->getArgs();
900       NumArgs = TST->getNumArgs();
901     } else {
902       const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
903       Args = TemplateArgs.data();
904       NumArgs = TemplateArgs.size();
905     }
906     IncludeStrongLifetimeRAII Strong(Policy);
907     TemplateSpecializationType::PrintTemplateArgumentList(OS,
908                                                           Args, NumArgs,
909                                                           Policy);
910   }
911 
912   spaceBeforePlaceHolder(OS);
913 }
914 
printRecordBefore(const RecordType * T,raw_ostream & OS)915 void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
916   printTag(T->getDecl(), OS);
917 }
printRecordAfter(const RecordType * T,raw_ostream & OS)918 void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { }
919 
printEnumBefore(const EnumType * T,raw_ostream & OS)920 void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
921   printTag(T->getDecl(), OS);
922 }
printEnumAfter(const EnumType * T,raw_ostream & OS)923 void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { }
924 
printTemplateTypeParmBefore(const TemplateTypeParmType * T,raw_ostream & OS)925 void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
926                                               raw_ostream &OS) {
927   if (IdentifierInfo *Id = T->getIdentifier())
928     OS << Id->getName();
929   else
930     OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
931   spaceBeforePlaceHolder(OS);
932 }
printTemplateTypeParmAfter(const TemplateTypeParmType * T,raw_ostream & OS)933 void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
934                                              raw_ostream &OS) { }
935 
printSubstTemplateTypeParmBefore(const SubstTemplateTypeParmType * T,raw_ostream & OS)936 void TypePrinter::printSubstTemplateTypeParmBefore(
937                                              const SubstTemplateTypeParmType *T,
938                                              raw_ostream &OS) {
939   IncludeStrongLifetimeRAII Strong(Policy);
940   printBefore(T->getReplacementType(), OS);
941 }
printSubstTemplateTypeParmAfter(const SubstTemplateTypeParmType * T,raw_ostream & OS)942 void TypePrinter::printSubstTemplateTypeParmAfter(
943                                              const SubstTemplateTypeParmType *T,
944                                              raw_ostream &OS) {
945   IncludeStrongLifetimeRAII Strong(Policy);
946   printAfter(T->getReplacementType(), OS);
947 }
948 
printSubstTemplateTypeParmPackBefore(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)949 void TypePrinter::printSubstTemplateTypeParmPackBefore(
950                                         const SubstTemplateTypeParmPackType *T,
951                                         raw_ostream &OS) {
952   IncludeStrongLifetimeRAII Strong(Policy);
953   printTemplateTypeParmBefore(T->getReplacedParameter(), OS);
954 }
printSubstTemplateTypeParmPackAfter(const SubstTemplateTypeParmPackType * T,raw_ostream & OS)955 void TypePrinter::printSubstTemplateTypeParmPackAfter(
956                                         const SubstTemplateTypeParmPackType *T,
957                                         raw_ostream &OS) {
958   IncludeStrongLifetimeRAII Strong(Policy);
959   printTemplateTypeParmAfter(T->getReplacedParameter(), OS);
960 }
961 
printTemplateSpecializationBefore(const TemplateSpecializationType * T,raw_ostream & OS)962 void TypePrinter::printTemplateSpecializationBefore(
963                                             const TemplateSpecializationType *T,
964                                             raw_ostream &OS) {
965   IncludeStrongLifetimeRAII Strong(Policy);
966   T->getTemplateName().print(OS, Policy);
967 
968   TemplateSpecializationType::PrintTemplateArgumentList(OS,
969                                                         T->getArgs(),
970                                                         T->getNumArgs(),
971                                                         Policy);
972   spaceBeforePlaceHolder(OS);
973 }
printTemplateSpecializationAfter(const TemplateSpecializationType * T,raw_ostream & OS)974 void TypePrinter::printTemplateSpecializationAfter(
975                                             const TemplateSpecializationType *T,
976                                             raw_ostream &OS) { }
977 
printInjectedClassNameBefore(const InjectedClassNameType * T,raw_ostream & OS)978 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
979                                                raw_ostream &OS) {
980   printTemplateSpecializationBefore(T->getInjectedTST(), OS);
981 }
printInjectedClassNameAfter(const InjectedClassNameType * T,raw_ostream & OS)982 void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
983                                                raw_ostream &OS) { }
984 
printElaboratedBefore(const ElaboratedType * T,raw_ostream & OS)985 void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
986                                         raw_ostream &OS) {
987   OS << TypeWithKeyword::getKeywordName(T->getKeyword());
988   if (T->getKeyword() != ETK_None)
989     OS << " ";
990   NestedNameSpecifier* Qualifier = T->getQualifier();
991   if (Qualifier)
992     Qualifier->print(OS, Policy);
993 
994   ElaboratedTypePolicyRAII PolicyRAII(Policy);
995   printBefore(T->getNamedType(), OS);
996 }
printElaboratedAfter(const ElaboratedType * T,raw_ostream & OS)997 void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
998                                         raw_ostream &OS) {
999   ElaboratedTypePolicyRAII PolicyRAII(Policy);
1000   printAfter(T->getNamedType(), OS);
1001 }
1002 
printParenBefore(const ParenType * T,raw_ostream & OS)1003 void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1004   if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1005     printBefore(T->getInnerType(), OS);
1006     OS << '(';
1007   } else
1008     printBefore(T->getInnerType(), OS);
1009 }
printParenAfter(const ParenType * T,raw_ostream & OS)1010 void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1011   if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1012     OS << ')';
1013     printAfter(T->getInnerType(), OS);
1014   } else
1015     printAfter(T->getInnerType(), OS);
1016 }
1017 
printDependentNameBefore(const DependentNameType * T,raw_ostream & OS)1018 void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1019                                            raw_ostream &OS) {
1020   OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1021   if (T->getKeyword() != ETK_None)
1022     OS << " ";
1023 
1024   T->getQualifier()->print(OS, Policy);
1025 
1026   OS << T->getIdentifier()->getName();
1027   spaceBeforePlaceHolder(OS);
1028 }
printDependentNameAfter(const DependentNameType * T,raw_ostream & OS)1029 void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1030                                           raw_ostream &OS) { }
1031 
printDependentTemplateSpecializationBefore(const DependentTemplateSpecializationType * T,raw_ostream & OS)1032 void TypePrinter::printDependentTemplateSpecializationBefore(
1033         const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1034   IncludeStrongLifetimeRAII Strong(Policy);
1035 
1036   OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1037   if (T->getKeyword() != ETK_None)
1038     OS << " ";
1039 
1040   if (T->getQualifier())
1041     T->getQualifier()->print(OS, Policy);
1042   OS << T->getIdentifier()->getName();
1043   TemplateSpecializationType::PrintTemplateArgumentList(OS,
1044                                                         T->getArgs(),
1045                                                         T->getNumArgs(),
1046                                                         Policy);
1047   spaceBeforePlaceHolder(OS);
1048 }
printDependentTemplateSpecializationAfter(const DependentTemplateSpecializationType * T,raw_ostream & OS)1049 void TypePrinter::printDependentTemplateSpecializationAfter(
1050         const DependentTemplateSpecializationType *T, raw_ostream &OS) { }
1051 
printPackExpansionBefore(const PackExpansionType * T,raw_ostream & OS)1052 void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1053                                            raw_ostream &OS) {
1054   printBefore(T->getPattern(), OS);
1055 }
printPackExpansionAfter(const PackExpansionType * T,raw_ostream & OS)1056 void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1057                                           raw_ostream &OS) {
1058   printAfter(T->getPattern(), OS);
1059   OS << "...";
1060 }
1061 
printAttributedBefore(const AttributedType * T,raw_ostream & OS)1062 void TypePrinter::printAttributedBefore(const AttributedType *T,
1063                                         raw_ostream &OS) {
1064   // Prefer the macro forms of the GC and ownership qualifiers.
1065   if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1066       T->getAttrKind() == AttributedType::attr_objc_ownership)
1067     return printBefore(T->getEquivalentType(), OS);
1068 
1069   printBefore(T->getModifiedType(), OS);
1070 }
1071 
printAttributedAfter(const AttributedType * T,raw_ostream & OS)1072 void TypePrinter::printAttributedAfter(const AttributedType *T,
1073                                        raw_ostream &OS) {
1074   // Prefer the macro forms of the GC and ownership qualifiers.
1075   if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1076       T->getAttrKind() == AttributedType::attr_objc_ownership)
1077     return printAfter(T->getEquivalentType(), OS);
1078 
1079   // TODO: not all attributes are GCC-style attributes.
1080   OS << " __attribute__((";
1081   switch (T->getAttrKind()) {
1082   case AttributedType::attr_address_space:
1083     OS << "address_space(";
1084     OS << T->getEquivalentType().getAddressSpace();
1085     OS << ')';
1086     break;
1087 
1088   case AttributedType::attr_vector_size: {
1089     OS << "__vector_size__(";
1090     if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) {
1091       OS << vector->getNumElements();
1092       OS << " * sizeof(";
1093       print(vector->getElementType(), OS, StringRef());
1094       OS << ')';
1095     }
1096     OS << ')';
1097     break;
1098   }
1099 
1100   case AttributedType::attr_neon_vector_type:
1101   case AttributedType::attr_neon_polyvector_type: {
1102     if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
1103       OS << "neon_vector_type(";
1104     else
1105       OS << "neon_polyvector_type(";
1106     const VectorType *vector = T->getEquivalentType()->getAs<VectorType>();
1107     OS << vector->getNumElements();
1108     OS << ')';
1109     break;
1110   }
1111 
1112   case AttributedType::attr_regparm: {
1113     OS << "regparm(";
1114     QualType t = T->getEquivalentType();
1115     while (!t->isFunctionType())
1116       t = t->getPointeeType();
1117     OS << t->getAs<FunctionType>()->getRegParmType();
1118     OS << ')';
1119     break;
1120   }
1121 
1122   case AttributedType::attr_objc_gc: {
1123     OS << "objc_gc(";
1124 
1125     QualType tmp = T->getEquivalentType();
1126     while (tmp.getObjCGCAttr() == Qualifiers::GCNone) {
1127       QualType next = tmp->getPointeeType();
1128       if (next == tmp) break;
1129       tmp = next;
1130     }
1131 
1132     if (tmp.isObjCGCWeak())
1133       OS << "weak";
1134     else
1135       OS << "strong";
1136     OS << ')';
1137     break;
1138   }
1139 
1140   case AttributedType::attr_objc_ownership:
1141     OS << "objc_ownership(";
1142     switch (T->getEquivalentType().getObjCLifetime()) {
1143     case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
1144     case Qualifiers::OCL_ExplicitNone: OS << "none"; break;
1145     case Qualifiers::OCL_Strong: OS << "strong"; break;
1146     case Qualifiers::OCL_Weak: OS << "weak"; break;
1147     case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break;
1148     }
1149     OS << ')';
1150     break;
1151 
1152   case AttributedType::attr_noreturn: OS << "noreturn"; break;
1153   case AttributedType::attr_cdecl: OS << "cdecl"; break;
1154   case AttributedType::attr_fastcall: OS << "fastcall"; break;
1155   case AttributedType::attr_stdcall: OS << "stdcall"; break;
1156   case AttributedType::attr_thiscall: OS << "thiscall"; break;
1157   case AttributedType::attr_pascal: OS << "pascal"; break;
1158   case AttributedType::attr_pcs: {
1159     OS << "pcs(";
1160    QualType t = T->getEquivalentType();
1161    while (!t->isFunctionType())
1162      t = t->getPointeeType();
1163    OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1164          "\"aapcs\"" : "\"aapcs-vfp\"");
1165    OS << ')';
1166    break;
1167   }
1168   }
1169   OS << "))";
1170 }
1171 
printObjCInterfaceBefore(const ObjCInterfaceType * T,raw_ostream & OS)1172 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
1173                                            raw_ostream &OS) {
1174   OS << T->getDecl()->getName();
1175   spaceBeforePlaceHolder(OS);
1176 }
printObjCInterfaceAfter(const ObjCInterfaceType * T,raw_ostream & OS)1177 void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
1178                                           raw_ostream &OS) { }
1179 
printObjCObjectBefore(const ObjCObjectType * T,raw_ostream & OS)1180 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1181                                         raw_ostream &OS) {
1182   if (T->qual_empty())
1183     return printBefore(T->getBaseType(), OS);
1184 
1185   print(T->getBaseType(), OS, StringRef());
1186   OS << '<';
1187   bool isFirst = true;
1188   for (ObjCObjectType::qual_iterator
1189          I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
1190     if (isFirst)
1191       isFirst = false;
1192     else
1193       OS << ',';
1194     OS << (*I)->getName();
1195   }
1196   OS << '>';
1197   spaceBeforePlaceHolder(OS);
1198 }
printObjCObjectAfter(const ObjCObjectType * T,raw_ostream & OS)1199 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1200                                         raw_ostream &OS) {
1201   if (T->qual_empty())
1202     return printAfter(T->getBaseType(), OS);
1203 }
1204 
printObjCObjectPointerBefore(const ObjCObjectPointerType * T,raw_ostream & OS)1205 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1206                                                raw_ostream &OS) {
1207   T->getPointeeType().getLocalQualifiers().print(OS, Policy,
1208                                                 /*appendSpaceIfNonEmpty=*/true);
1209 
1210   if (T->isObjCIdType() || T->isObjCQualifiedIdType())
1211     OS << "id";
1212   else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
1213     OS << "Class";
1214   else if (T->isObjCSelType())
1215     OS << "SEL";
1216   else
1217     OS << T->getInterfaceDecl()->getName();
1218 
1219   if (!T->qual_empty()) {
1220     OS << '<';
1221     for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
1222                                               E = T->qual_end();
1223          I != E; ++I) {
1224       OS << (*I)->getName();
1225       if (I+1 != E)
1226         OS << ',';
1227     }
1228     OS << '>';
1229   }
1230 
1231   if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) {
1232     OS << " *"; // Don't forget the implicit pointer.
1233   } else {
1234     spaceBeforePlaceHolder(OS);
1235   }
1236 }
printObjCObjectPointerAfter(const ObjCObjectPointerType * T,raw_ostream & OS)1237 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1238                                               raw_ostream &OS) { }
1239 
1240 void TemplateSpecializationType::
PrintTemplateArgumentList(raw_ostream & OS,const TemplateArgumentListInfo & Args,const PrintingPolicy & Policy)1241   PrintTemplateArgumentList(raw_ostream &OS,
1242                             const TemplateArgumentListInfo &Args,
1243                             const PrintingPolicy &Policy) {
1244   return PrintTemplateArgumentList(OS,
1245                                    Args.getArgumentArray(),
1246                                    Args.size(),
1247                                    Policy);
1248 }
1249 
1250 void
PrintTemplateArgumentList(raw_ostream & OS,const TemplateArgument * Args,unsigned NumArgs,const PrintingPolicy & Policy,bool SkipBrackets)1251 TemplateSpecializationType::PrintTemplateArgumentList(
1252                                                 raw_ostream &OS,
1253                                                 const TemplateArgument *Args,
1254                                                 unsigned NumArgs,
1255                                                   const PrintingPolicy &Policy,
1256                                                       bool SkipBrackets) {
1257   if (!SkipBrackets)
1258     OS << '<';
1259 
1260   bool needSpace = false;
1261   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1262     if (Arg > 0)
1263       OS << ", ";
1264 
1265     // Print the argument into a string.
1266     SmallString<128> Buf;
1267     llvm::raw_svector_ostream ArgOS(Buf);
1268     if (Args[Arg].getKind() == TemplateArgument::Pack) {
1269       PrintTemplateArgumentList(ArgOS,
1270                                 Args[Arg].pack_begin(),
1271                                 Args[Arg].pack_size(),
1272                                 Policy, true);
1273     } else {
1274       Args[Arg].print(Policy, ArgOS);
1275     }
1276     StringRef ArgString = ArgOS.str();
1277 
1278     // If this is the first argument and its string representation
1279     // begins with the global scope specifier ('::foo'), add a space
1280     // to avoid printing the diagraph '<:'.
1281     if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1282       OS << ' ';
1283 
1284     OS << ArgString;
1285 
1286     needSpace = (!ArgString.empty() && ArgString.back() == '>');
1287   }
1288 
1289   // If the last character of our string is '>', add another space to
1290   // keep the two '>''s separate tokens. We don't *have* to do this in
1291   // C++0x, but it's still good hygiene.
1292   if (needSpace)
1293     OS << ' ';
1294 
1295   if (!SkipBrackets)
1296     OS << '>';
1297 }
1298 
1299 // Sadly, repeat all that with TemplateArgLoc.
1300 void TemplateSpecializationType::
PrintTemplateArgumentList(raw_ostream & OS,const TemplateArgumentLoc * Args,unsigned NumArgs,const PrintingPolicy & Policy)1301 PrintTemplateArgumentList(raw_ostream &OS,
1302                           const TemplateArgumentLoc *Args, unsigned NumArgs,
1303                           const PrintingPolicy &Policy) {
1304   OS << '<';
1305 
1306   bool needSpace = false;
1307   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1308     if (Arg > 0)
1309       OS << ", ";
1310 
1311     // Print the argument into a string.
1312     SmallString<128> Buf;
1313     llvm::raw_svector_ostream ArgOS(Buf);
1314     if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) {
1315       PrintTemplateArgumentList(ArgOS,
1316                                 Args[Arg].getArgument().pack_begin(),
1317                                 Args[Arg].getArgument().pack_size(),
1318                                 Policy, true);
1319     } else {
1320       Args[Arg].getArgument().print(Policy, ArgOS);
1321     }
1322     StringRef ArgString = ArgOS.str();
1323 
1324     // If this is the first argument and its string representation
1325     // begins with the global scope specifier ('::foo'), add a space
1326     // to avoid printing the diagraph '<:'.
1327     if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1328       OS << ' ';
1329 
1330     OS << ArgString;
1331 
1332     needSpace = (!ArgString.empty() && ArgString.back() == '>');
1333   }
1334 
1335   // If the last character of our string is '>', add another space to
1336   // keep the two '>''s separate tokens. We don't *have* to do this in
1337   // C++0x, but it's still good hygiene.
1338   if (needSpace)
1339     OS << ' ';
1340 
1341   OS << '>';
1342 }
1343 
1344 void
printExceptionSpecification(std::string & S,PrintingPolicy Policy) const1345 FunctionProtoType::printExceptionSpecification(std::string &S,
1346                                                PrintingPolicy Policy) const {
1347 
1348   if (hasDynamicExceptionSpec()) {
1349     S += " throw(";
1350     if (getExceptionSpecType() == EST_MSAny)
1351       S += "...";
1352     else
1353       for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
1354         if (I)
1355           S += ", ";
1356 
1357         S += getExceptionType(I).getAsString(Policy);
1358       }
1359     S += ")";
1360   } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
1361     S += " noexcept";
1362     if (getExceptionSpecType() == EST_ComputedNoexcept) {
1363       S += "(";
1364       llvm::raw_string_ostream EOut(S);
1365       getNoexceptExpr()->printPretty(EOut, 0, Policy);
1366       EOut.flush();
1367       S += EOut.str();
1368       S += ")";
1369     }
1370   }
1371 }
1372 
1373 std::string TemplateSpecializationType::
PrintTemplateArgumentList(const TemplateArgumentListInfo & Args,const PrintingPolicy & Policy)1374   PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
1375                             const PrintingPolicy &Policy) {
1376   return PrintTemplateArgumentList(Args.getArgumentArray(),
1377                                    Args.size(),
1378                                    Policy);
1379 }
1380 
1381 std::string
PrintTemplateArgumentList(const TemplateArgument * Args,unsigned NumArgs,const PrintingPolicy & Policy,bool SkipBrackets)1382 TemplateSpecializationType::PrintTemplateArgumentList(
1383                                                 const TemplateArgument *Args,
1384                                                 unsigned NumArgs,
1385                                                   const PrintingPolicy &Policy,
1386                                                       bool SkipBrackets) {
1387   std::string SpecString;
1388   if (!SkipBrackets)
1389     SpecString += '<';
1390 
1391   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1392     if (SpecString.size() > unsigned(!SkipBrackets))
1393       SpecString += ", ";
1394 
1395     // Print the argument into a string.
1396     std::string ArgString;
1397     if (Args[Arg].getKind() == TemplateArgument::Pack) {
1398       ArgString = PrintTemplateArgumentList(Args[Arg].pack_begin(),
1399                                             Args[Arg].pack_size(),
1400                                             Policy, true);
1401     } else {
1402       llvm::raw_string_ostream ArgOut(ArgString);
1403       Args[Arg].print(Policy, ArgOut);
1404     }
1405 
1406     // If this is the first argument and its string representation
1407     // begins with the global scope specifier ('::foo'), add a space
1408     // to avoid printing the diagraph '<:'.
1409     if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1410       SpecString += ' ';
1411 
1412     SpecString += ArgString;
1413   }
1414 
1415   // If the last character of our string is '>', add another space to
1416   // keep the two '>''s separate tokens. We don't *have* to do this in
1417   // C++0x, but it's still good hygiene.
1418   if (!SpecString.empty() && SpecString[SpecString.size() - 1] == '>')
1419     SpecString += ' ';
1420 
1421   if (!SkipBrackets)
1422     SpecString += '>';
1423 
1424   return SpecString;
1425 }
1426 
1427 // Sadly, repeat all that with TemplateArgLoc.
1428 std::string TemplateSpecializationType::
PrintTemplateArgumentList(const TemplateArgumentLoc * Args,unsigned NumArgs,const PrintingPolicy & Policy)1429 PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
1430                           const PrintingPolicy &Policy) {
1431   std::string SpecString;
1432   SpecString += '<';
1433   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1434     if (SpecString.size() > 1)
1435       SpecString += ", ";
1436 
1437     // Print the argument into a string.
1438     std::string ArgString;
1439     if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) {
1440       ArgString = PrintTemplateArgumentList(
1441                                            Args[Arg].getArgument().pack_begin(),
1442                                             Args[Arg].getArgument().pack_size(),
1443                                             Policy, true);
1444     } else {
1445       llvm::raw_string_ostream ArgOut(ArgString);
1446       Args[Arg].getArgument().print(Policy, ArgOut);
1447     }
1448 
1449     // If this is the first argument and its string representation
1450     // begins with the global scope specifier ('::foo'), add a space
1451     // to avoid printing the diagraph '<:'.
1452     if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1453       SpecString += ' ';
1454 
1455     SpecString += ArgString;
1456   }
1457 
1458   // If the last character of our string is '>', add another space to
1459   // keep the two '>''s separate tokens. We don't *have* to do this in
1460   // C++0x, but it's still good hygiene.
1461   if (SpecString[SpecString.size() - 1] == '>')
1462     SpecString += ' ';
1463 
1464   SpecString += '>';
1465 
1466   return SpecString;
1467 }
1468 
dump(const char * msg) const1469 void QualType::dump(const char *msg) const {
1470   if (msg)
1471     llvm::errs() << msg << ": ";
1472   LangOptions LO;
1473   print(llvm::errs(), PrintingPolicy(LO), "identifier");
1474   llvm::errs() << '\n';
1475 }
dump() const1476 void QualType::dump() const {
1477   dump(0);
1478 }
1479 
dump() const1480 void Type::dump() const {
1481   QualType(this, 0).dump();
1482 }
1483 
getAsString() const1484 std::string Qualifiers::getAsString() const {
1485   LangOptions LO;
1486   return getAsString(PrintingPolicy(LO));
1487 }
1488 
1489 // Appends qualifiers to the given string, separated by spaces.  Will
1490 // prefix a space if the string is non-empty.  Will not append a final
1491 // space.
getAsString(const PrintingPolicy & Policy) const1492 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
1493   SmallString<64> Buf;
1494   llvm::raw_svector_ostream StrOS(Buf);
1495   print(StrOS, Policy);
1496   return StrOS.str();
1497 }
1498 
isEmptyWhenPrinted(const PrintingPolicy & Policy) const1499 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
1500   if (getCVRQualifiers())
1501     return false;
1502 
1503   if (getAddressSpace())
1504     return false;
1505 
1506   if (getObjCGCAttr())
1507     return false;
1508 
1509   if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
1510     if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
1511       return false;
1512 
1513   return true;
1514 }
1515 
1516 // Appends qualifiers to the given string, separated by spaces.  Will
1517 // prefix a space if the string is non-empty.  Will not append a final
1518 // space.
print(raw_ostream & OS,const PrintingPolicy & Policy,bool appendSpaceIfNonEmpty) const1519 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
1520                        bool appendSpaceIfNonEmpty) const {
1521   bool addSpace = false;
1522 
1523   unsigned quals = getCVRQualifiers();
1524   if (quals) {
1525     AppendTypeQualList(OS, quals);
1526     addSpace = true;
1527   }
1528   if (unsigned addrspace = getAddressSpace()) {
1529     if (addSpace)
1530       OS << ' ';
1531     addSpace = true;
1532     switch (addrspace) {
1533       case LangAS::opencl_global:
1534         OS << "__global";
1535         break;
1536       case LangAS::opencl_local:
1537         OS << "__local";
1538         break;
1539       case LangAS::opencl_constant:
1540         OS << "__constant";
1541         break;
1542       default:
1543         OS << "__attribute__((address_space(";
1544         OS << addrspace;
1545         OS << ")))";
1546     }
1547   }
1548   if (Qualifiers::GC gc = getObjCGCAttr()) {
1549     if (addSpace)
1550       OS << ' ';
1551     addSpace = true;
1552     if (gc == Qualifiers::Weak)
1553       OS << "__weak";
1554     else
1555       OS << "__strong";
1556   }
1557   if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
1558     if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
1559       if (addSpace)
1560         OS << ' ';
1561       addSpace = true;
1562     }
1563 
1564     switch (lifetime) {
1565     case Qualifiers::OCL_None: llvm_unreachable("none but true");
1566     case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
1567     case Qualifiers::OCL_Strong:
1568       if (!Policy.SuppressStrongLifetime)
1569         OS << "__strong";
1570       break;
1571 
1572     case Qualifiers::OCL_Weak: OS << "__weak"; break;
1573     case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
1574     }
1575   }
1576 
1577   if (appendSpaceIfNonEmpty && addSpace)
1578     OS << ' ';
1579 }
1580 
getAsString(const PrintingPolicy & Policy) const1581 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
1582   std::string S;
1583   getAsStringInternal(S, Policy);
1584   return S;
1585 }
1586 
getAsString(const Type * ty,Qualifiers qs)1587 std::string QualType::getAsString(const Type *ty, Qualifiers qs) {
1588   std::string buffer;
1589   LangOptions options;
1590   getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
1591   return buffer;
1592 }
1593 
print(const Type * ty,Qualifiers qs,raw_ostream & OS,const PrintingPolicy & policy,const Twine & PlaceHolder)1594 void QualType::print(const Type *ty, Qualifiers qs,
1595                      raw_ostream &OS, const PrintingPolicy &policy,
1596                      const Twine &PlaceHolder) {
1597   SmallString<128> PHBuf;
1598   StringRef PH;
1599   if (PlaceHolder.isSingleStringRef())
1600     PH = PlaceHolder.getSingleStringRef();
1601   else
1602     PH = PlaceHolder.toStringRef(PHBuf);
1603 
1604   TypePrinter(policy).print(ty, qs, OS, PH);
1605 }
1606 
getAsStringInternal(const Type * ty,Qualifiers qs,std::string & buffer,const PrintingPolicy & policy)1607 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
1608                                    std::string &buffer,
1609                                    const PrintingPolicy &policy) {
1610   SmallString<256> Buf;
1611   llvm::raw_svector_ostream StrOS(Buf);
1612   TypePrinter(policy).print(ty, qs, StrOS, buffer);
1613   std::string str = StrOS.str();
1614   buffer.swap(str);
1615 }
1616