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