1 //===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This contains code to print types from Clang's type system.
12 //===----------------------------------------------------------------------===//
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;
30 /// \brief RAII object that enables printing of the ARC __strong lifetime
32 class IncludeStrongLifetimeRAII {
33 PrintingPolicy &Policy;
37 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
38 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
39 if (!Policy.SuppressLifetimeQualifiers)
40 Policy.SuppressStrongLifetime = false;
43 ~IncludeStrongLifetimeRAII() {
44 Policy.SuppressStrongLifetime = Old;
48 class ParamPolicyRAII {
49 PrintingPolicy &Policy;
53 explicit ParamPolicyRAII(PrintingPolicy &Policy)
54 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
55 Policy.SuppressSpecifiers = false;
59 Policy.SuppressSpecifiers = Old;
63 class ElaboratedTypePolicyRAII {
64 PrintingPolicy &Policy;
65 bool SuppressTagKeyword;
69 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
70 SuppressTagKeyword = Policy.SuppressTagKeyword;
71 SuppressScope = Policy.SuppressScope;
72 Policy.SuppressTagKeyword = true;
73 Policy.SuppressScope = true;
76 ~ElaboratedTypePolicyRAII() {
77 Policy.SuppressTagKeyword = SuppressTagKeyword;
78 Policy.SuppressScope = SuppressScope;
83 PrintingPolicy Policy;
84 bool HasEmptyPlaceHolder;
85 bool InsideCCAttribute;
88 explicit TypePrinter(const PrintingPolicy &Policy)
89 : Policy(Policy), HasEmptyPlaceHolder(false), InsideCCAttribute(false) { }
91 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
92 StringRef PlaceHolder);
93 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
95 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
96 void spaceBeforePlaceHolder(raw_ostream &OS);
97 void printTypeSpec(const NamedDecl *D, raw_ostream &OS);
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"
113 static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals) {
114 bool appendSpace = false;
115 if (TypeQuals & Qualifiers::Const) {
119 if (TypeQuals & Qualifiers::Volatile) {
120 if (appendSpace) OS << ' ';
124 if (TypeQuals & Qualifiers::Restrict) {
125 if (appendSpace) OS << ' ';
130 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
131 if (!HasEmptyPlaceHolder)
135 void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
136 SplitQualType split = t.split();
137 print(split.Ty, split.Quals, OS, PlaceHolder);
140 void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
141 StringRef PlaceHolder) {
147 SaveAndRestore<bool> PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
149 printBefore(T, Quals, OS);
151 printAfter(T, Quals, OS);
154 bool TypePrinter::canPrefixQualifiers(const Type *T,
155 bool &NeedARCStrongQualifier) {
156 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
157 // so that we get "const int" instead of "int const", but we can't do this if
158 // the type is complex. For example if the type is "int*", we *must* print
159 // "int * const", printing "const int *" is different. Only do this when the
160 // type expands to a simple string.
161 bool CanPrefixQualifiers = false;
162 NeedARCStrongQualifier = false;
163 Type::TypeClass TC = T->getTypeClass();
164 if (const AutoType *AT = dyn_cast<AutoType>(T))
165 TC = AT->desugar()->getTypeClass();
166 if (const SubstTemplateTypeParmType *Subst
167 = dyn_cast<SubstTemplateTypeParmType>(T))
168 TC = Subst->getReplacementType()->getTypeClass();
174 case Type::UnresolvedUsing:
176 case Type::TypeOfExpr:
179 case Type::UnaryTransform:
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:
192 CanPrefixQualifiers = true;
195 case Type::ObjCObjectPointer:
196 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
197 T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
200 case Type::ConstantArray:
201 case Type::IncompleteArray:
202 case Type::VariableArray:
203 case Type::DependentSizedArray:
204 NeedARCStrongQualifier = true;
210 case Type::BlockPointer:
211 case Type::LValueReference:
212 case Type::RValueReference:
213 case Type::MemberPointer:
214 case Type::DependentSizedExtVector:
216 case Type::ExtVector:
217 case Type::FunctionProto:
218 case Type::FunctionNoProto:
220 case Type::Attributed:
221 case Type::PackExpansion:
222 case Type::SubstTemplateTypeParm:
223 CanPrefixQualifiers = false;
227 return CanPrefixQualifiers;
230 void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
231 SplitQualType Split = T.split();
233 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
235 Qualifiers Quals = Split.Quals;
236 if (const SubstTemplateTypeParmType *Subst =
237 dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
238 Quals -= QualType(Subst, 0).getQualifiers();
240 printBefore(Split.Ty, Quals, OS);
243 /// \brief Prints the part of the type string before an identifier, e.g. for
244 /// "int foo[10]" it prints "int ".
245 void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
246 if (Policy.SuppressSpecifiers && T->isSpecifierType())
249 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder);
251 // Print qualifiers as appropriate.
253 bool CanPrefixQualifiers = false;
254 bool NeedARCStrongQualifier = false;
255 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
257 if (CanPrefixQualifiers && !Quals.empty()) {
258 if (NeedARCStrongQualifier) {
259 IncludeStrongLifetimeRAII Strong(Policy);
260 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
262 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
266 bool hasAfterQuals = false;
267 if (!CanPrefixQualifiers && !Quals.empty()) {
268 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
270 HasEmptyPlaceHolder = false;
273 switch (T->getTypeClass()) {
274 #define ABSTRACT_TYPE(CLASS, PARENT)
275 #define TYPE(CLASS, PARENT) case Type::CLASS: \
276 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
278 #include "clang/AST/TypeNodes.def"
282 if (NeedARCStrongQualifier) {
283 IncludeStrongLifetimeRAII Strong(Policy);
284 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
286 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
291 void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
292 SplitQualType split = t.split();
293 printAfter(split.Ty, split.Quals, OS);
296 /// \brief Prints the part of the type string after an identifier, e.g. for
297 /// "int foo[10]" it prints "[10]".
298 void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
299 switch (T->getTypeClass()) {
300 #define ABSTRACT_TYPE(CLASS, PARENT)
301 #define TYPE(CLASS, PARENT) case Type::CLASS: \
302 print##CLASS##After(cast<CLASS##Type>(T), OS); \
304 #include "clang/AST/TypeNodes.def"
308 void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
309 OS << T->getName(Policy);
310 spaceBeforePlaceHolder(OS);
312 void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) { }
314 void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
316 printBefore(T->getElementType(), OS);
318 void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
319 printAfter(T->getElementType(), OS);
322 void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
323 IncludeStrongLifetimeRAII Strong(Policy);
324 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
325 printBefore(T->getPointeeType(), OS);
326 // Handle things like 'int (*A)[4];' correctly.
327 // FIXME: this should include vectors, but vectors use attributes I guess.
328 if (isa<ArrayType>(T->getPointeeType()))
332 void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
333 IncludeStrongLifetimeRAII Strong(Policy);
334 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
335 // Handle things like 'int (*A)[4];' correctly.
336 // FIXME: this should include vectors, but vectors use attributes I guess.
337 if (isa<ArrayType>(T->getPointeeType()))
339 printAfter(T->getPointeeType(), OS);
342 void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
344 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
345 printBefore(T->getPointeeType(), OS);
348 void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
350 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
351 printAfter(T->getPointeeType(), OS);
354 void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
356 IncludeStrongLifetimeRAII Strong(Policy);
357 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
358 printBefore(T->getPointeeTypeAsWritten(), OS);
359 // Handle things like 'int (&A)[4];' correctly.
360 // FIXME: this should include vectors, but vectors use attributes I guess.
361 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
365 void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
367 IncludeStrongLifetimeRAII Strong(Policy);
368 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
369 // Handle things like 'int (&A)[4];' correctly.
370 // FIXME: this should include vectors, but vectors use attributes I guess.
371 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
373 printAfter(T->getPointeeTypeAsWritten(), OS);
376 void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
378 IncludeStrongLifetimeRAII Strong(Policy);
379 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
380 printBefore(T->getPointeeTypeAsWritten(), OS);
381 // Handle things like 'int (&&A)[4];' correctly.
382 // FIXME: this should include vectors, but vectors use attributes I guess.
383 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
387 void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
389 IncludeStrongLifetimeRAII Strong(Policy);
390 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
391 // Handle things like 'int (&&A)[4];' correctly.
392 // FIXME: this should include vectors, but vectors use attributes I guess.
393 if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
395 printAfter(T->getPointeeTypeAsWritten(), OS);
398 void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
400 IncludeStrongLifetimeRAII Strong(Policy);
401 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
402 printBefore(T->getPointeeType(), OS);
403 // Handle things like 'int (Cls::*A)[4];' correctly.
404 // FIXME: this should include vectors, but vectors use attributes I guess.
405 if (isa<ArrayType>(T->getPointeeType()))
408 PrintingPolicy InnerPolicy(Policy);
409 InnerPolicy.SuppressTag = false;
410 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
414 void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
416 IncludeStrongLifetimeRAII Strong(Policy);
417 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
418 // Handle things like 'int (Cls::*A)[4];' correctly.
419 // FIXME: this should include vectors, but vectors use attributes I guess.
420 if (isa<ArrayType>(T->getPointeeType()))
422 printAfter(T->getPointeeType(), OS);
425 void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
427 IncludeStrongLifetimeRAII Strong(Policy);
428 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
429 printBefore(T->getElementType(), OS);
431 void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
434 if (T->getIndexTypeQualifiers().hasQualifiers()) {
435 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers());
439 if (T->getSizeModifier() == ArrayType::Static)
442 OS << T->getSize().getZExtValue() << ']';
443 printAfter(T->getElementType(), OS);
446 void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
448 IncludeStrongLifetimeRAII Strong(Policy);
449 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
450 printBefore(T->getElementType(), OS);
452 void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
455 printAfter(T->getElementType(), OS);
458 void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
460 IncludeStrongLifetimeRAII Strong(Policy);
461 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
462 printBefore(T->getElementType(), OS);
464 void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
467 if (T->getIndexTypeQualifiers().hasQualifiers()) {
468 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers());
472 if (T->getSizeModifier() == VariableArrayType::Static)
474 else if (T->getSizeModifier() == VariableArrayType::Star)
477 if (T->getSizeExpr())
478 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
481 printAfter(T->getElementType(), OS);
484 void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
485 // Print the adjusted representation, otherwise the adjustment will be
487 printBefore(T->getAdjustedType(), OS);
489 void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
490 printAfter(T->getAdjustedType(), OS);
493 void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
494 // Print as though it's a pointer.
495 printAdjustedBefore(T, OS);
497 void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
498 printAdjustedAfter(T, OS);
501 void TypePrinter::printDependentSizedArrayBefore(
502 const DependentSizedArrayType *T,
504 IncludeStrongLifetimeRAII Strong(Policy);
505 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
506 printBefore(T->getElementType(), OS);
508 void TypePrinter::printDependentSizedArrayAfter(
509 const DependentSizedArrayType *T,
512 if (T->getSizeExpr())
513 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
515 printAfter(T->getElementType(), OS);
518 void TypePrinter::printDependentSizedExtVectorBefore(
519 const DependentSizedExtVectorType *T,
521 printBefore(T->getElementType(), OS);
523 void TypePrinter::printDependentSizedExtVectorAfter(
524 const DependentSizedExtVectorType *T,
526 OS << " __attribute__((ext_vector_type(";
527 if (T->getSizeExpr())
528 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
530 printAfter(T->getElementType(), OS);
533 void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
534 switch (T->getVectorKind()) {
535 case VectorType::AltiVecPixel:
536 OS << "__vector __pixel ";
538 case VectorType::AltiVecBool:
539 OS << "__vector __bool ";
540 printBefore(T->getElementType(), OS);
542 case VectorType::AltiVecVector:
544 printBefore(T->getElementType(), OS);
546 case VectorType::NeonVector:
547 OS << "__attribute__((neon_vector_type("
548 << T->getNumElements() << "))) ";
549 printBefore(T->getElementType(), OS);
551 case VectorType::NeonPolyVector:
552 OS << "__attribute__((neon_polyvector_type(" <<
553 T->getNumElements() << "))) ";
554 printBefore(T->getElementType(), OS);
556 case VectorType::GenericVector: {
557 // FIXME: We prefer to print the size directly here, but have no way
558 // to get the size of the type.
559 OS << "__attribute__((__vector_size__("
560 << T->getNumElements()
562 print(T->getElementType(), OS, StringRef());
564 printBefore(T->getElementType(), OS);
569 void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
570 printAfter(T->getElementType(), OS);
573 void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
575 printBefore(T->getElementType(), OS);
577 void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
578 printAfter(T->getElementType(), OS);
579 OS << " __attribute__((ext_vector_type(";
580 OS << T->getNumElements();
585 FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
586 const PrintingPolicy &Policy)
589 if (hasDynamicExceptionSpec()) {
591 if (getExceptionSpecType() == EST_MSAny)
594 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
598 OS << getExceptionType(I).stream(Policy);
601 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
603 if (getExceptionSpecType() == EST_ComputedNoexcept) {
605 if (getNoexceptExpr())
606 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
612 void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
614 if (T->hasTrailingReturn()) {
616 if (!HasEmptyPlaceHolder)
619 // If needed for precedence reasons, wrap the inner part in grouping parens.
620 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
621 printBefore(T->getReturnType(), OS);
622 if (!PrevPHIsEmpty.get())
627 void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
629 // If needed for precedence reasons, wrap the inner part in grouping parens.
630 if (!HasEmptyPlaceHolder)
632 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
636 ParamPolicyRAII ParamPolicy(Policy);
637 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
639 print(T->getParamType(i), OS, StringRef());
643 if (T->isVariadic()) {
644 if (T->getNumParams())
647 } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) {
648 // Do not emit int() if we have a proto, emit 'int(void)'.
654 FunctionType::ExtInfo Info = T->getExtInfo();
656 if (!InsideCCAttribute) {
657 switch (Info.getCC()) {
659 // The C calling convention is the default on the vast majority of platforms
660 // we support. If the user wrote it explicitly, it will usually be printed
661 // while traversing the AttributedType. If the type has been desugared, let
662 // the canonical spelling be the implicit calling convention.
663 // FIXME: It would be better to be explicit in certain contexts, such as a
664 // cdecl function typedef used to declare a member function with the
665 // Microsoft C++ ABI.
668 OS << " __attribute__((stdcall))";
671 OS << " __attribute__((fastcall))";
674 OS << " __attribute__((thiscall))";
677 OS << " __attribute__((pascal))";
680 OS << " __attribute__((pcs(\"aapcs\")))";
683 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
686 OS << " __attribute__((pnaclcall))";
688 case CC_IntelOclBicc:
689 OS << " __attribute__((intel_ocl_bicc))";
692 OS << " __attribute__((ms_abi))";
695 OS << " __attribute__((sysv_abi))";
700 if (Info.getNoReturn())
701 OS << " __attribute__((noreturn))";
702 if (Info.getRegParm())
703 OS << " __attribute__((regparm ("
704 << Info.getRegParm() << ")))";
706 if (unsigned quals = T->getTypeQuals()) {
708 AppendTypeQualList(OS, quals);
711 switch (T->getRefQualifier()) {
723 T->printExceptionSpecification(OS, Policy);
725 if (T->hasTrailingReturn()) {
727 print(T->getReturnType(), OS, StringRef());
729 printAfter(T->getReturnType(), OS);
732 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
734 // If needed for precedence reasons, wrap the inner part in grouping parens.
735 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
736 printBefore(T->getReturnType(), OS);
737 if (!PrevPHIsEmpty.get())
740 void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
742 // If needed for precedence reasons, wrap the inner part in grouping parens.
743 if (!HasEmptyPlaceHolder)
745 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
748 if (T->getNoReturnAttr())
749 OS << " __attribute__((noreturn))";
750 printAfter(T->getReturnType(), OS);
753 void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
754 IdentifierInfo *II = D->getIdentifier();
756 spaceBeforePlaceHolder(OS);
759 void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
761 printTypeSpec(T->getDecl(), OS);
763 void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
766 void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
767 printTypeSpec(T->getDecl(), OS);
769 void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { }
771 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
774 if (T->getUnderlyingExpr())
775 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
776 spaceBeforePlaceHolder(OS);
778 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
781 void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
783 print(T->getUnderlyingType(), OS, StringRef());
785 spaceBeforePlaceHolder(OS);
787 void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { }
789 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
791 if (T->getUnderlyingExpr())
792 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
794 spaceBeforePlaceHolder(OS);
796 void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { }
798 void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
800 IncludeStrongLifetimeRAII Strong(Policy);
802 switch (T->getUTTKind()) {
803 case UnaryTransformType::EnumUnderlyingType:
804 OS << "__underlying_type(";
805 print(T->getBaseType(), OS, StringRef());
807 spaceBeforePlaceHolder(OS);
811 printBefore(T->getBaseType(), OS);
813 void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
815 IncludeStrongLifetimeRAII Strong(Policy);
817 switch (T->getUTTKind()) {
818 case UnaryTransformType::EnumUnderlyingType:
822 printAfter(T->getBaseType(), OS);
825 void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
826 // If the type has been deduced, do not print 'auto'.
827 if (!T->getDeducedType().isNull()) {
828 printBefore(T->getDeducedType(), OS);
830 OS << (T->isDecltypeAuto() ? "decltype(auto)" : "auto");
831 spaceBeforePlaceHolder(OS);
834 void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
835 // If the type has been deduced, do not print 'auto'.
836 if (!T->getDeducedType().isNull())
837 printAfter(T->getDeducedType(), OS);
840 void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
841 IncludeStrongLifetimeRAII Strong(Policy);
844 print(T->getValueType(), OS, StringRef());
846 spaceBeforePlaceHolder(OS);
848 void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { }
850 /// Appends the given scope to the end of a string.
851 void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
852 if (DC->isTranslationUnit()) return;
853 if (DC->isFunctionOrMethod()) return;
854 AppendScope(DC->getParent(), OS);
856 if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
857 if (Policy.SuppressUnwrittenScope &&
858 (NS->isAnonymousNamespace() || NS->isInline()))
860 if (NS->getIdentifier())
861 OS << NS->getName() << "::";
863 OS << "(anonymous namespace)::";
864 } else if (ClassTemplateSpecializationDecl *Spec
865 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
866 IncludeStrongLifetimeRAII Strong(Policy);
867 OS << Spec->getIdentifier()->getName();
868 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
869 TemplateSpecializationType::PrintTemplateArgumentList(OS,
874 } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
875 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
876 OS << Typedef->getIdentifier()->getName() << "::";
877 else if (Tag->getIdentifier())
878 OS << Tag->getIdentifier()->getName() << "::";
884 void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
885 if (Policy.SuppressTag)
888 bool HasKindDecoration = false;
890 // bool SuppressTagKeyword
891 // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword;
893 // We don't print tags unless this is an elaborated type.
894 // In C, we just assume every RecordType is an elaborated type.
895 if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword ||
896 D->getTypedefNameForAnonDecl())) {
897 HasKindDecoration = true;
898 OS << D->getKindName();
902 // Compute the full nested-name-specifier for this type.
903 // In C, this will always be empty except when the type
904 // being printed is anonymous within other Record.
905 if (!Policy.SuppressScope)
906 AppendScope(D->getDeclContext(), OS);
908 if (const IdentifierInfo *II = D->getIdentifier())
910 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
911 assert(Typedef->getIdentifier() && "Typedef without identifier?");
912 OS << Typedef->getIdentifier()->getName();
914 // Make an unambiguous representation for anonymous types, e.g.
915 // (anonymous enum at /usr/include/string.h:120:9)
917 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
919 HasKindDecoration = true;
924 if (Policy.AnonymousTagLocations) {
925 // Suppress the redundant tag keyword if we just printed one.
926 // We don't have to worry about ElaboratedTypes here because you can't
927 // refer to an anonymous type with one.
928 if (!HasKindDecoration)
929 OS << " " << D->getKindName();
931 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
933 if (PLoc.isValid()) {
934 OS << " at " << PLoc.getFilename()
935 << ':' << PLoc.getLine()
936 << ':' << PLoc.getColumn();
943 // If this is a class template specialization, print the template
945 if (ClassTemplateSpecializationDecl *Spec
946 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
947 const TemplateArgument *Args;
949 if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
950 const TemplateSpecializationType *TST =
951 cast<TemplateSpecializationType>(TAW->getType());
952 Args = TST->getArgs();
953 NumArgs = TST->getNumArgs();
955 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
956 Args = TemplateArgs.data();
957 NumArgs = TemplateArgs.size();
959 IncludeStrongLifetimeRAII Strong(Policy);
960 TemplateSpecializationType::PrintTemplateArgumentList(OS,
965 spaceBeforePlaceHolder(OS);
968 void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
969 printTag(T->getDecl(), OS);
971 void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { }
973 void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
974 printTag(T->getDecl(), OS);
976 void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { }
978 void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
980 if (IdentifierInfo *Id = T->getIdentifier())
983 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
984 spaceBeforePlaceHolder(OS);
986 void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
989 void TypePrinter::printSubstTemplateTypeParmBefore(
990 const SubstTemplateTypeParmType *T,
992 IncludeStrongLifetimeRAII Strong(Policy);
993 printBefore(T->getReplacementType(), OS);
995 void TypePrinter::printSubstTemplateTypeParmAfter(
996 const SubstTemplateTypeParmType *T,
998 IncludeStrongLifetimeRAII Strong(Policy);
999 printAfter(T->getReplacementType(), OS);
1002 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1003 const SubstTemplateTypeParmPackType *T,
1005 IncludeStrongLifetimeRAII Strong(Policy);
1006 printTemplateTypeParmBefore(T->getReplacedParameter(), OS);
1008 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1009 const SubstTemplateTypeParmPackType *T,
1011 IncludeStrongLifetimeRAII Strong(Policy);
1012 printTemplateTypeParmAfter(T->getReplacedParameter(), OS);
1015 void TypePrinter::printTemplateSpecializationBefore(
1016 const TemplateSpecializationType *T,
1018 IncludeStrongLifetimeRAII Strong(Policy);
1019 T->getTemplateName().print(OS, Policy);
1021 TemplateSpecializationType::PrintTemplateArgumentList(OS,
1025 spaceBeforePlaceHolder(OS);
1027 void TypePrinter::printTemplateSpecializationAfter(
1028 const TemplateSpecializationType *T,
1029 raw_ostream &OS) { }
1031 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1033 printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1035 void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1036 raw_ostream &OS) { }
1038 void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1040 if (Policy.SuppressTag && isa<TagType>(T->getNamedType()))
1042 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1043 if (T->getKeyword() != ETK_None)
1045 NestedNameSpecifier* Qualifier = T->getQualifier();
1047 Qualifier->print(OS, Policy);
1049 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1050 printBefore(T->getNamedType(), OS);
1052 void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1054 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1055 printAfter(T->getNamedType(), OS);
1058 void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1059 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1060 printBefore(T->getInnerType(), OS);
1063 printBefore(T->getInnerType(), OS);
1065 void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1066 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1068 printAfter(T->getInnerType(), OS);
1070 printAfter(T->getInnerType(), OS);
1073 void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1075 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1076 if (T->getKeyword() != ETK_None)
1079 T->getQualifier()->print(OS, Policy);
1081 OS << T->getIdentifier()->getName();
1082 spaceBeforePlaceHolder(OS);
1084 void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1085 raw_ostream &OS) { }
1087 void TypePrinter::printDependentTemplateSpecializationBefore(
1088 const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1089 IncludeStrongLifetimeRAII Strong(Policy);
1091 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1092 if (T->getKeyword() != ETK_None)
1095 if (T->getQualifier())
1096 T->getQualifier()->print(OS, Policy);
1097 OS << T->getIdentifier()->getName();
1098 TemplateSpecializationType::PrintTemplateArgumentList(OS,
1102 spaceBeforePlaceHolder(OS);
1104 void TypePrinter::printDependentTemplateSpecializationAfter(
1105 const DependentTemplateSpecializationType *T, raw_ostream &OS) { }
1107 void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1109 printBefore(T->getPattern(), OS);
1111 void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1113 printAfter(T->getPattern(), OS);
1117 void TypePrinter::printAttributedBefore(const AttributedType *T,
1119 // Prefer the macro forms of the GC and ownership qualifiers.
1120 if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1121 T->getAttrKind() == AttributedType::attr_objc_ownership)
1122 return printBefore(T->getEquivalentType(), OS);
1124 printBefore(T->getModifiedType(), OS);
1126 if (T->isMSTypeSpec()) {
1127 switch (T->getAttrKind()) {
1129 case AttributedType::attr_ptr32: OS << " __ptr32"; break;
1130 case AttributedType::attr_ptr64: OS << " __ptr64"; break;
1131 case AttributedType::attr_sptr: OS << " __sptr"; break;
1132 case AttributedType::attr_uptr: OS << " __uptr"; break;
1134 spaceBeforePlaceHolder(OS);
1138 void TypePrinter::printAttributedAfter(const AttributedType *T,
1140 // Prefer the macro forms of the GC and ownership qualifiers.
1141 if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1142 T->getAttrKind() == AttributedType::attr_objc_ownership)
1143 return printAfter(T->getEquivalentType(), OS);
1145 // TODO: not all attributes are GCC-style attributes.
1146 if (T->isMSTypeSpec())
1149 // If this is a calling convention attribute, don't print the implicit CC from
1150 // the modified type.
1151 SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1153 printAfter(T->getModifiedType(), OS);
1155 OS << " __attribute__((";
1156 switch (T->getAttrKind()) {
1157 default: llvm_unreachable("This attribute should have been handled already");
1158 case AttributedType::attr_address_space:
1159 OS << "address_space(";
1160 OS << T->getEquivalentType().getAddressSpace();
1164 case AttributedType::attr_vector_size: {
1165 OS << "__vector_size__(";
1166 if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) {
1167 OS << vector->getNumElements();
1169 print(vector->getElementType(), OS, StringRef());
1176 case AttributedType::attr_neon_vector_type:
1177 case AttributedType::attr_neon_polyvector_type: {
1178 if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
1179 OS << "neon_vector_type(";
1181 OS << "neon_polyvector_type(";
1182 const VectorType *vector = T->getEquivalentType()->getAs<VectorType>();
1183 OS << vector->getNumElements();
1188 case AttributedType::attr_regparm: {
1189 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1190 // attribute again in printFunctionProtoAfter.
1192 QualType t = T->getEquivalentType();
1193 while (!t->isFunctionType())
1194 t = t->getPointeeType();
1195 OS << t->getAs<FunctionType>()->getRegParmType();
1200 case AttributedType::attr_objc_gc: {
1203 QualType tmp = T->getEquivalentType();
1204 while (tmp.getObjCGCAttr() == Qualifiers::GCNone) {
1205 QualType next = tmp->getPointeeType();
1206 if (next == tmp) break;
1210 if (tmp.isObjCGCWeak())
1218 case AttributedType::attr_objc_ownership:
1219 OS << "objc_ownership(";
1220 switch (T->getEquivalentType().getObjCLifetime()) {
1221 case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
1222 case Qualifiers::OCL_ExplicitNone: OS << "none"; break;
1223 case Qualifiers::OCL_Strong: OS << "strong"; break;
1224 case Qualifiers::OCL_Weak: OS << "weak"; break;
1225 case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break;
1230 // FIXME: When Sema learns to form this AttributedType, avoid printing the
1231 // attribute again in printFunctionProtoAfter.
1232 case AttributedType::attr_noreturn: OS << "noreturn"; break;
1234 case AttributedType::attr_cdecl: OS << "cdecl"; break;
1235 case AttributedType::attr_fastcall: OS << "fastcall"; break;
1236 case AttributedType::attr_stdcall: OS << "stdcall"; break;
1237 case AttributedType::attr_thiscall: OS << "thiscall"; break;
1238 case AttributedType::attr_pascal: OS << "pascal"; break;
1239 case AttributedType::attr_ms_abi: OS << "ms_abi"; break;
1240 case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break;
1241 case AttributedType::attr_pcs:
1242 case AttributedType::attr_pcs_vfp: {
1244 QualType t = T->getEquivalentType();
1245 while (!t->isFunctionType())
1246 t = t->getPointeeType();
1247 OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1248 "\"aapcs\"" : "\"aapcs-vfp\"");
1252 case AttributedType::attr_pnaclcall: OS << "pnaclcall"; break;
1253 case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break;
1258 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
1260 OS << T->getDecl()->getName();
1261 spaceBeforePlaceHolder(OS);
1263 void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
1264 raw_ostream &OS) { }
1266 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1268 if (T->qual_empty())
1269 return printBefore(T->getBaseType(), OS);
1271 print(T->getBaseType(), OS, StringRef());
1273 bool isFirst = true;
1274 for (const auto *I : T->quals()) {
1282 spaceBeforePlaceHolder(OS);
1284 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1286 if (T->qual_empty())
1287 return printAfter(T->getBaseType(), OS);
1290 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1292 T->getPointeeType().getLocalQualifiers().print(OS, Policy,
1293 /*appendSpaceIfNonEmpty=*/true);
1295 assert(!T->isObjCSelType());
1297 if (T->isObjCIdType() || T->isObjCQualifiedIdType())
1299 else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
1302 OS << T->getInterfaceDecl()->getName();
1304 if (!T->qual_empty()) {
1306 for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
1309 OS << (*I)->getName();
1316 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
1317 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
1318 OS << " *"; // Don't forget the implicit pointer.
1320 spaceBeforePlaceHolder(OS);
1323 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1324 raw_ostream &OS) { }
1326 void TemplateSpecializationType::
1327 PrintTemplateArgumentList(raw_ostream &OS,
1328 const TemplateArgumentListInfo &Args,
1329 const PrintingPolicy &Policy) {
1330 return PrintTemplateArgumentList(OS,
1331 Args.getArgumentArray(),
1337 TemplateSpecializationType::PrintTemplateArgumentList(
1339 const TemplateArgument *Args,
1341 const PrintingPolicy &Policy,
1342 bool SkipBrackets) {
1346 bool needSpace = false;
1347 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1348 // Print the argument into a string.
1349 SmallString<128> Buf;
1350 llvm::raw_svector_ostream ArgOS(Buf);
1351 if (Args[Arg].getKind() == TemplateArgument::Pack) {
1352 if (Args[Arg].pack_size() && Arg > 0)
1354 PrintTemplateArgumentList(ArgOS,
1355 Args[Arg].pack_begin(),
1356 Args[Arg].pack_size(),
1361 Args[Arg].print(Policy, ArgOS);
1363 StringRef ArgString = ArgOS.str();
1365 // If this is the first argument and its string representation
1366 // begins with the global scope specifier ('::foo'), add a space
1367 // to avoid printing the diagraph '<:'.
1368 if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1373 needSpace = (!ArgString.empty() && ArgString.back() == '>');
1376 // If the last character of our string is '>', add another space to
1377 // keep the two '>''s separate tokens. We don't *have* to do this in
1378 // C++0x, but it's still good hygiene.
1386 // Sadly, repeat all that with TemplateArgLoc.
1387 void TemplateSpecializationType::
1388 PrintTemplateArgumentList(raw_ostream &OS,
1389 const TemplateArgumentLoc *Args, unsigned NumArgs,
1390 const PrintingPolicy &Policy) {
1393 bool needSpace = false;
1394 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1398 // Print the argument into a string.
1399 SmallString<128> Buf;
1400 llvm::raw_svector_ostream ArgOS(Buf);
1401 if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) {
1402 PrintTemplateArgumentList(ArgOS,
1403 Args[Arg].getArgument().pack_begin(),
1404 Args[Arg].getArgument().pack_size(),
1407 Args[Arg].getArgument().print(Policy, ArgOS);
1409 StringRef ArgString = ArgOS.str();
1411 // If this is the first argument and its string representation
1412 // begins with the global scope specifier ('::foo'), add a space
1413 // to avoid printing the diagraph '<:'.
1414 if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1419 needSpace = (!ArgString.empty() && ArgString.back() == '>');
1422 // If the last character of our string is '>', add another space to
1423 // keep the two '>''s separate tokens. We don't *have* to do this in
1424 // C++0x, but it's still good hygiene.
1431 void QualType::dump(const char *msg) const {
1433 llvm::errs() << msg << ": ";
1435 print(llvm::errs(), PrintingPolicy(LO), "identifier");
1436 llvm::errs() << '\n';
1439 LLVM_DUMP_METHOD void QualType::dump() const { dump(nullptr); }
1441 LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
1443 std::string Qualifiers::getAsString() const {
1445 return getAsString(PrintingPolicy(LO));
1448 // Appends qualifiers to the given string, separated by spaces. Will
1449 // prefix a space if the string is non-empty. Will not append a final
1451 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
1452 SmallString<64> Buf;
1453 llvm::raw_svector_ostream StrOS(Buf);
1454 print(StrOS, Policy);
1458 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
1459 if (getCVRQualifiers())
1462 if (getAddressSpace())
1465 if (getObjCGCAttr())
1468 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
1469 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
1475 // Appends qualifiers to the given string, separated by spaces. Will
1476 // prefix a space if the string is non-empty. Will not append a final
1478 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
1479 bool appendSpaceIfNonEmpty) const {
1480 bool addSpace = false;
1482 unsigned quals = getCVRQualifiers();
1484 AppendTypeQualList(OS, quals);
1487 if (unsigned addrspace = getAddressSpace()) {
1491 switch (addrspace) {
1492 case LangAS::opencl_global:
1495 case LangAS::opencl_local:
1498 case LangAS::opencl_constant:
1502 OS << "__attribute__((address_space(";
1507 if (Qualifiers::GC gc = getObjCGCAttr()) {
1511 if (gc == Qualifiers::Weak)
1516 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
1517 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
1524 case Qualifiers::OCL_None: llvm_unreachable("none but true");
1525 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
1526 case Qualifiers::OCL_Strong:
1527 if (!Policy.SuppressStrongLifetime)
1531 case Qualifiers::OCL_Weak: OS << "__weak"; break;
1532 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
1536 if (appendSpaceIfNonEmpty && addSpace)
1540 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
1542 getAsStringInternal(S, Policy);
1546 std::string QualType::getAsString(const Type *ty, Qualifiers qs) {
1548 LangOptions options;
1549 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
1553 void QualType::print(const Type *ty, Qualifiers qs,
1554 raw_ostream &OS, const PrintingPolicy &policy,
1555 const Twine &PlaceHolder) {
1556 SmallString<128> PHBuf;
1557 StringRef PH = PlaceHolder.toStringRef(PHBuf);
1559 TypePrinter(policy).print(ty, qs, OS, PH);
1562 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
1563 std::string &buffer,
1564 const PrintingPolicy &policy) {
1565 SmallString<256> Buf;
1566 llvm::raw_svector_ostream StrOS(Buf);
1567 TypePrinter(policy).print(ty, qs, StrOS, buffer);
1568 std::string str = StrOS.str();