1 //===- TypePrinter.cpp - Pretty-Print Clang Types -------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This contains code to print types from Clang's type system.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/Attr.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/DeclTemplate.h"
20 #include "clang/AST/Expr.h"
21 #include "clang/AST/NestedNameSpecifier.h"
22 #include "clang/AST/PrettyPrinter.h"
23 #include "clang/AST/TemplateBase.h"
24 #include "clang/AST/TemplateName.h"
25 #include "clang/AST/Type.h"
26 #include "clang/Basic/AddressSpaces.h"
27 #include "clang/Basic/AttrKinds.h"
28 #include "clang/Basic/ExceptionSpecificationType.h"
29 #include "clang/Basic/IdentifierTable.h"
30 #include "clang/Basic/LLVM.h"
31 #include "clang/Basic/LangOptions.h"
32 #include "clang/Basic/SourceLocation.h"
33 #include "clang/Basic/SourceManager.h"
34 #include "clang/Basic/Specifiers.h"
35 #include "llvm/ADT/ArrayRef.h"
36 #include "llvm/ADT/DenseMap.h"
37 #include "llvm/ADT/SmallString.h"
38 #include "llvm/ADT/StringRef.h"
39 #include "llvm/ADT/Twine.h"
40 #include "llvm/Support/Compiler.h"
41 #include "llvm/Support/ErrorHandling.h"
42 #include "llvm/Support/SaveAndRestore.h"
43 #include "llvm/Support/raw_ostream.h"
47 using namespace clang
;
51 /// RAII object that enables printing of the ARC __strong lifetime
53 class IncludeStrongLifetimeRAII
{
54 PrintingPolicy
&Policy
;
58 explicit IncludeStrongLifetimeRAII(PrintingPolicy
&Policy
)
59 : Policy(Policy
), Old(Policy
.SuppressStrongLifetime
) {
60 if (!Policy
.SuppressLifetimeQualifiers
)
61 Policy
.SuppressStrongLifetime
= false;
64 ~IncludeStrongLifetimeRAII() { Policy
.SuppressStrongLifetime
= Old
; }
67 class ParamPolicyRAII
{
68 PrintingPolicy
&Policy
;
72 explicit ParamPolicyRAII(PrintingPolicy
&Policy
)
73 : Policy(Policy
), Old(Policy
.SuppressSpecifiers
) {
74 Policy
.SuppressSpecifiers
= false;
77 ~ParamPolicyRAII() { Policy
.SuppressSpecifiers
= Old
; }
80 class DefaultTemplateArgsPolicyRAII
{
81 PrintingPolicy
&Policy
;
85 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy
&Policy
)
86 : Policy(Policy
), Old(Policy
.SuppressDefaultTemplateArgs
) {
87 Policy
.SuppressDefaultTemplateArgs
= false;
90 ~DefaultTemplateArgsPolicyRAII() { Policy
.SuppressDefaultTemplateArgs
= Old
; }
93 class ElaboratedTypePolicyRAII
{
94 PrintingPolicy
&Policy
;
95 bool SuppressTagKeyword
;
99 explicit ElaboratedTypePolicyRAII(PrintingPolicy
&Policy
) : Policy(Policy
) {
100 SuppressTagKeyword
= Policy
.SuppressTagKeyword
;
101 SuppressScope
= Policy
.SuppressScope
;
102 Policy
.SuppressTagKeyword
= true;
103 Policy
.SuppressScope
= true;
106 ~ElaboratedTypePolicyRAII() {
107 Policy
.SuppressTagKeyword
= SuppressTagKeyword
;
108 Policy
.SuppressScope
= SuppressScope
;
113 PrintingPolicy Policy
;
114 unsigned Indentation
;
115 bool HasEmptyPlaceHolder
= false;
116 bool InsideCCAttribute
= false;
119 explicit TypePrinter(const PrintingPolicy
&Policy
, unsigned Indentation
= 0)
120 : Policy(Policy
), Indentation(Indentation
) {}
122 void print(const Type
*ty
, Qualifiers qs
, raw_ostream
&OS
,
123 StringRef PlaceHolder
);
124 void print(QualType T
, raw_ostream
&OS
, StringRef PlaceHolder
);
126 static bool canPrefixQualifiers(const Type
*T
, bool &NeedARCStrongQualifier
);
127 void spaceBeforePlaceHolder(raw_ostream
&OS
);
128 void printTypeSpec(NamedDecl
*D
, raw_ostream
&OS
);
129 void printTemplateId(const TemplateSpecializationType
*T
, raw_ostream
&OS
,
132 void printBefore(QualType T
, raw_ostream
&OS
);
133 void printAfter(QualType T
, raw_ostream
&OS
);
134 void AppendScope(DeclContext
*DC
, raw_ostream
&OS
,
135 DeclarationName NameInScope
);
136 void printTag(TagDecl
*T
, raw_ostream
&OS
);
137 void printFunctionAfter(const FunctionType::ExtInfo
&Info
, raw_ostream
&OS
);
138 #define ABSTRACT_TYPE(CLASS, PARENT)
139 #define TYPE(CLASS, PARENT) \
140 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
141 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
142 #include "clang/AST/TypeNodes.inc"
145 void printBefore(const Type
*ty
, Qualifiers qs
, raw_ostream
&OS
);
146 void printAfter(const Type
*ty
, Qualifiers qs
, raw_ostream
&OS
);
151 static void AppendTypeQualList(raw_ostream
&OS
, unsigned TypeQuals
,
152 bool HasRestrictKeyword
) {
153 bool appendSpace
= false;
154 if (TypeQuals
& Qualifiers::Const
) {
158 if (TypeQuals
& Qualifiers::Volatile
) {
159 if (appendSpace
) OS
<< ' ';
163 if (TypeQuals
& Qualifiers::Restrict
) {
164 if (appendSpace
) OS
<< ' ';
165 if (HasRestrictKeyword
) {
173 void TypePrinter::spaceBeforePlaceHolder(raw_ostream
&OS
) {
174 if (!HasEmptyPlaceHolder
)
178 static SplitQualType
splitAccordingToPolicy(QualType QT
,
179 const PrintingPolicy
&Policy
) {
180 if (Policy
.PrintCanonicalTypes
)
181 QT
= QT
.getCanonicalType();
185 void TypePrinter::print(QualType t
, raw_ostream
&OS
, StringRef PlaceHolder
) {
186 SplitQualType split
= splitAccordingToPolicy(t
, Policy
);
187 print(split
.Ty
, split
.Quals
, OS
, PlaceHolder
);
190 void TypePrinter::print(const Type
*T
, Qualifiers Quals
, raw_ostream
&OS
,
191 StringRef PlaceHolder
) {
197 SaveAndRestore
PHVal(HasEmptyPlaceHolder
, PlaceHolder
.empty());
199 printBefore(T
, Quals
, OS
);
201 printAfter(T
, Quals
, OS
);
204 bool TypePrinter::canPrefixQualifiers(const Type
*T
,
205 bool &NeedARCStrongQualifier
) {
206 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
207 // so that we get "const int" instead of "int const", but we can't do this if
208 // the type is complex. For example if the type is "int*", we *must* print
209 // "int * const", printing "const int *" is different. Only do this when the
210 // type expands to a simple string.
211 bool CanPrefixQualifiers
= false;
212 NeedARCStrongQualifier
= false;
213 const Type
*UnderlyingType
= T
;
214 if (const auto *AT
= dyn_cast
<AutoType
>(T
))
215 UnderlyingType
= AT
->desugar().getTypePtr();
216 if (const auto *Subst
= dyn_cast
<SubstTemplateTypeParmType
>(T
))
217 UnderlyingType
= Subst
->getReplacementType().getTypePtr();
218 Type::TypeClass TC
= UnderlyingType
->getTypeClass();
224 case Type::UnresolvedUsing
:
227 case Type::TypeOfExpr
:
230 case Type::UnaryTransform
:
233 case Type::Elaborated
:
234 case Type::TemplateTypeParm
:
235 case Type::SubstTemplateTypeParmPack
:
236 case Type::DeducedTemplateSpecialization
:
237 case Type::TemplateSpecialization
:
238 case Type::InjectedClassName
:
239 case Type::DependentName
:
240 case Type::DependentTemplateSpecialization
:
241 case Type::ObjCObject
:
242 case Type::ObjCTypeParam
:
243 case Type::ObjCInterface
:
247 case Type::DependentBitInt
:
248 case Type::BTFTagAttributed
:
249 case Type::HLSLAttributedResource
:
250 CanPrefixQualifiers
= true;
253 case Type::ObjCObjectPointer
:
254 CanPrefixQualifiers
= T
->isObjCIdType() || T
->isObjCClassType() ||
255 T
->isObjCQualifiedIdType() || T
->isObjCQualifiedClassType();
258 case Type::VariableArray
:
259 case Type::DependentSizedArray
:
260 NeedARCStrongQualifier
= true;
263 case Type::ConstantArray
:
264 case Type::IncompleteArray
:
265 return canPrefixQualifiers(
266 cast
<ArrayType
>(UnderlyingType
)->getElementType().getTypePtr(),
267 NeedARCStrongQualifier
);
271 case Type::ArrayParameter
:
273 case Type::BlockPointer
:
274 case Type::LValueReference
:
275 case Type::RValueReference
:
276 case Type::MemberPointer
:
277 case Type::DependentAddressSpace
:
278 case Type::DependentVector
:
279 case Type::DependentSizedExtVector
:
281 case Type::ExtVector
:
282 case Type::ConstantMatrix
:
283 case Type::DependentSizedMatrix
:
284 case Type::FunctionProto
:
285 case Type::FunctionNoProto
:
287 case Type::PackExpansion
:
288 case Type::SubstTemplateTypeParm
:
289 case Type::MacroQualified
:
290 case Type::CountAttributed
:
291 CanPrefixQualifiers
= false;
294 case Type::Attributed
: {
295 // We still want to print the address_space before the type if it is an
296 // address_space attribute.
297 const auto *AttrTy
= cast
<AttributedType
>(UnderlyingType
);
298 CanPrefixQualifiers
= AttrTy
->getAttrKind() == attr::AddressSpace
;
301 case Type::PackIndexing
: {
302 return canPrefixQualifiers(
303 cast
<PackIndexingType
>(UnderlyingType
)->getPattern().getTypePtr(),
304 NeedARCStrongQualifier
);
308 return CanPrefixQualifiers
;
311 void TypePrinter::printBefore(QualType T
, raw_ostream
&OS
) {
312 SplitQualType Split
= splitAccordingToPolicy(T
, Policy
);
314 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
316 Qualifiers Quals
= Split
.Quals
;
317 if (const auto *Subst
= dyn_cast
<SubstTemplateTypeParmType
>(Split
.Ty
))
318 Quals
-= QualType(Subst
, 0).getQualifiers();
320 printBefore(Split
.Ty
, Quals
, OS
);
323 /// Prints the part of the type string before an identifier, e.g. for
324 /// "int foo[10]" it prints "int ".
325 void TypePrinter::printBefore(const Type
*T
,Qualifiers Quals
, raw_ostream
&OS
) {
326 if (Policy
.SuppressSpecifiers
&& T
->isSpecifierType())
329 SaveAndRestore
PrevPHIsEmpty(HasEmptyPlaceHolder
);
331 // Print qualifiers as appropriate.
333 bool CanPrefixQualifiers
= false;
334 bool NeedARCStrongQualifier
= false;
335 CanPrefixQualifiers
= canPrefixQualifiers(T
, NeedARCStrongQualifier
);
337 if (CanPrefixQualifiers
&& !Quals
.empty()) {
338 if (NeedARCStrongQualifier
) {
339 IncludeStrongLifetimeRAII
Strong(Policy
);
340 Quals
.print(OS
, Policy
, /*appendSpaceIfNonEmpty=*/true);
342 Quals
.print(OS
, Policy
, /*appendSpaceIfNonEmpty=*/true);
346 bool hasAfterQuals
= false;
347 if (!CanPrefixQualifiers
&& !Quals
.empty()) {
348 hasAfterQuals
= !Quals
.isEmptyWhenPrinted(Policy
);
350 HasEmptyPlaceHolder
= false;
353 switch (T
->getTypeClass()) {
354 #define ABSTRACT_TYPE(CLASS, PARENT)
355 #define TYPE(CLASS, PARENT) case Type::CLASS: \
356 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
358 #include "clang/AST/TypeNodes.inc"
362 if (NeedARCStrongQualifier
) {
363 IncludeStrongLifetimeRAII
Strong(Policy
);
364 Quals
.print(OS
, Policy
, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty
.get());
366 Quals
.print(OS
, Policy
, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty
.get());
371 void TypePrinter::printAfter(QualType t
, raw_ostream
&OS
) {
372 SplitQualType split
= splitAccordingToPolicy(t
, Policy
);
373 printAfter(split
.Ty
, split
.Quals
, OS
);
376 /// Prints the part of the type string after an identifier, e.g. for
377 /// "int foo[10]" it prints "[10]".
378 void TypePrinter::printAfter(const Type
*T
, Qualifiers Quals
, raw_ostream
&OS
) {
379 switch (T
->getTypeClass()) {
380 #define ABSTRACT_TYPE(CLASS, PARENT)
381 #define TYPE(CLASS, PARENT) case Type::CLASS: \
382 print##CLASS##After(cast<CLASS##Type>(T), OS); \
384 #include "clang/AST/TypeNodes.inc"
388 void TypePrinter::printBuiltinBefore(const BuiltinType
*T
, raw_ostream
&OS
) {
389 OS
<< T
->getName(Policy
);
390 spaceBeforePlaceHolder(OS
);
393 void TypePrinter::printBuiltinAfter(const BuiltinType
*T
, raw_ostream
&OS
) {}
395 void TypePrinter::printComplexBefore(const ComplexType
*T
, raw_ostream
&OS
) {
397 printBefore(T
->getElementType(), OS
);
400 void TypePrinter::printComplexAfter(const ComplexType
*T
, raw_ostream
&OS
) {
401 printAfter(T
->getElementType(), OS
);
404 void TypePrinter::printPointerBefore(const PointerType
*T
, raw_ostream
&OS
) {
405 IncludeStrongLifetimeRAII
Strong(Policy
);
406 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
407 printBefore(T
->getPointeeType(), OS
);
408 // Handle things like 'int (*A)[4];' correctly.
409 // FIXME: this should include vectors, but vectors use attributes I guess.
410 if (isa
<ArrayType
>(T
->getPointeeType()))
415 void TypePrinter::printPointerAfter(const PointerType
*T
, raw_ostream
&OS
) {
416 IncludeStrongLifetimeRAII
Strong(Policy
);
417 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
418 // Handle things like 'int (*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::printBlockPointerBefore(const BlockPointerType
*T
,
427 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
428 printBefore(T
->getPointeeType(), OS
);
432 void TypePrinter::printBlockPointerAfter(const BlockPointerType
*T
,
434 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
435 printAfter(T
->getPointeeType(), OS
);
438 // When printing a reference, the referenced type might also be a reference.
439 // If so, we want to skip that before printing the inner type.
440 static QualType
skipTopLevelReferences(QualType T
) {
441 if (auto *Ref
= T
->getAs
<ReferenceType
>())
442 return skipTopLevelReferences(Ref
->getPointeeTypeAsWritten());
446 void TypePrinter::printLValueReferenceBefore(const LValueReferenceType
*T
,
448 IncludeStrongLifetimeRAII
Strong(Policy
);
449 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
450 QualType Inner
= skipTopLevelReferences(T
->getPointeeTypeAsWritten());
451 printBefore(Inner
, OS
);
452 // Handle things like 'int (&A)[4];' correctly.
453 // FIXME: this should include vectors, but vectors use attributes I guess.
454 if (isa
<ArrayType
>(Inner
))
459 void TypePrinter::printLValueReferenceAfter(const LValueReferenceType
*T
,
461 IncludeStrongLifetimeRAII
Strong(Policy
);
462 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
463 QualType Inner
= skipTopLevelReferences(T
->getPointeeTypeAsWritten());
464 // Handle things like 'int (&A)[4];' correctly.
465 // FIXME: this should include vectors, but vectors use attributes I guess.
466 if (isa
<ArrayType
>(Inner
))
468 printAfter(Inner
, OS
);
471 void TypePrinter::printRValueReferenceBefore(const RValueReferenceType
*T
,
473 IncludeStrongLifetimeRAII
Strong(Policy
);
474 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
475 QualType Inner
= skipTopLevelReferences(T
->getPointeeTypeAsWritten());
476 printBefore(Inner
, OS
);
477 // Handle things like 'int (&&A)[4];' correctly.
478 // FIXME: this should include vectors, but vectors use attributes I guess.
479 if (isa
<ArrayType
>(Inner
))
484 void TypePrinter::printRValueReferenceAfter(const RValueReferenceType
*T
,
486 IncludeStrongLifetimeRAII
Strong(Policy
);
487 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
488 QualType Inner
= skipTopLevelReferences(T
->getPointeeTypeAsWritten());
489 // Handle things like 'int (&&A)[4];' correctly.
490 // FIXME: this should include vectors, but vectors use attributes I guess.
491 if (isa
<ArrayType
>(Inner
))
493 printAfter(Inner
, OS
);
496 void TypePrinter::printMemberPointerBefore(const MemberPointerType
*T
,
498 IncludeStrongLifetimeRAII
Strong(Policy
);
499 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
500 printBefore(T
->getPointeeType(), OS
);
501 // Handle things like 'int (Cls::*A)[4];' correctly.
502 // FIXME: this should include vectors, but vectors use attributes I guess.
503 if (isa
<ArrayType
>(T
->getPointeeType()))
506 PrintingPolicy
InnerPolicy(Policy
);
507 InnerPolicy
.IncludeTagDefinition
= false;
508 TypePrinter(InnerPolicy
).print(QualType(T
->getClass(), 0), OS
, StringRef());
513 void TypePrinter::printMemberPointerAfter(const MemberPointerType
*T
,
515 IncludeStrongLifetimeRAII
Strong(Policy
);
516 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
517 // Handle things like 'int (Cls::*A)[4];' correctly.
518 // FIXME: this should include vectors, but vectors use attributes I guess.
519 if (isa
<ArrayType
>(T
->getPointeeType()))
521 printAfter(T
->getPointeeType(), OS
);
524 void TypePrinter::printConstantArrayBefore(const ConstantArrayType
*T
,
526 IncludeStrongLifetimeRAII
Strong(Policy
);
527 printBefore(T
->getElementType(), OS
);
530 void TypePrinter::printConstantArrayAfter(const ConstantArrayType
*T
,
533 if (T
->getIndexTypeQualifiers().hasQualifiers()) {
534 AppendTypeQualList(OS
, T
->getIndexTypeCVRQualifiers(),
539 if (T
->getSizeModifier() == ArraySizeModifier::Static
)
542 OS
<< T
->getZExtSize() << ']';
543 printAfter(T
->getElementType(), OS
);
546 void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType
*T
,
548 IncludeStrongLifetimeRAII
Strong(Policy
);
549 printBefore(T
->getElementType(), OS
);
552 void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType
*T
,
555 printAfter(T
->getElementType(), OS
);
558 void TypePrinter::printVariableArrayBefore(const VariableArrayType
*T
,
560 IncludeStrongLifetimeRAII
Strong(Policy
);
561 printBefore(T
->getElementType(), OS
);
564 void TypePrinter::printVariableArrayAfter(const VariableArrayType
*T
,
567 if (T
->getIndexTypeQualifiers().hasQualifiers()) {
568 AppendTypeQualList(OS
, T
->getIndexTypeCVRQualifiers(), Policy
.Restrict
);
572 if (T
->getSizeModifier() == ArraySizeModifier::Static
)
574 else if (T
->getSizeModifier() == ArraySizeModifier::Star
)
577 if (T
->getSizeExpr())
578 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
581 printAfter(T
->getElementType(), OS
);
584 void TypePrinter::printAdjustedBefore(const AdjustedType
*T
, raw_ostream
&OS
) {
585 // Print the adjusted representation, otherwise the adjustment will be
587 printBefore(T
->getAdjustedType(), OS
);
590 void TypePrinter::printAdjustedAfter(const AdjustedType
*T
, raw_ostream
&OS
) {
591 printAfter(T
->getAdjustedType(), OS
);
594 void TypePrinter::printDecayedBefore(const DecayedType
*T
, raw_ostream
&OS
) {
595 // Print as though it's a pointer.
596 printAdjustedBefore(T
, OS
);
599 void TypePrinter::printArrayParameterAfter(const ArrayParameterType
*T
,
601 printConstantArrayAfter(T
, OS
);
604 void TypePrinter::printArrayParameterBefore(const ArrayParameterType
*T
,
606 printConstantArrayBefore(T
, OS
);
609 void TypePrinter::printDecayedAfter(const DecayedType
*T
, raw_ostream
&OS
) {
610 printAdjustedAfter(T
, OS
);
613 void TypePrinter::printDependentSizedArrayBefore(
614 const DependentSizedArrayType
*T
,
616 IncludeStrongLifetimeRAII
Strong(Policy
);
617 printBefore(T
->getElementType(), OS
);
620 void TypePrinter::printDependentSizedArrayAfter(
621 const DependentSizedArrayType
*T
,
624 if (T
->getSizeExpr())
625 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
627 printAfter(T
->getElementType(), OS
);
630 void TypePrinter::printDependentAddressSpaceBefore(
631 const DependentAddressSpaceType
*T
, raw_ostream
&OS
) {
632 printBefore(T
->getPointeeType(), OS
);
635 void TypePrinter::printDependentAddressSpaceAfter(
636 const DependentAddressSpaceType
*T
, raw_ostream
&OS
) {
637 OS
<< " __attribute__((address_space(";
638 if (T
->getAddrSpaceExpr())
639 T
->getAddrSpaceExpr()->printPretty(OS
, nullptr, Policy
);
641 printAfter(T
->getPointeeType(), OS
);
644 void TypePrinter::printDependentSizedExtVectorBefore(
645 const DependentSizedExtVectorType
*T
,
647 if (Policy
.UseHLSLTypes
)
649 printBefore(T
->getElementType(), OS
);
652 void TypePrinter::printDependentSizedExtVectorAfter(
653 const DependentSizedExtVectorType
*T
,
655 if (Policy
.UseHLSLTypes
) {
657 if (T
->getSizeExpr())
658 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
661 OS
<< " __attribute__((ext_vector_type(";
662 if (T
->getSizeExpr())
663 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
666 printAfter(T
->getElementType(), OS
);
669 void TypePrinter::printVectorBefore(const VectorType
*T
, raw_ostream
&OS
) {
670 switch (T
->getVectorKind()) {
671 case VectorKind::AltiVecPixel
:
672 OS
<< "__vector __pixel ";
674 case VectorKind::AltiVecBool
:
675 OS
<< "__vector __bool ";
676 printBefore(T
->getElementType(), OS
);
678 case VectorKind::AltiVecVector
:
680 printBefore(T
->getElementType(), OS
);
682 case VectorKind::Neon
:
683 OS
<< "__attribute__((neon_vector_type("
684 << T
->getNumElements() << "))) ";
685 printBefore(T
->getElementType(), OS
);
687 case VectorKind::NeonPoly
:
688 OS
<< "__attribute__((neon_polyvector_type(" <<
689 T
->getNumElements() << "))) ";
690 printBefore(T
->getElementType(), OS
);
692 case VectorKind::Generic
: {
693 // FIXME: We prefer to print the size directly here, but have no way
694 // to get the size of the type.
695 OS
<< "__attribute__((__vector_size__("
696 << T
->getNumElements()
698 print(T
->getElementType(), OS
, StringRef());
700 printBefore(T
->getElementType(), OS
);
703 case VectorKind::SveFixedLengthData
:
704 case VectorKind::SveFixedLengthPredicate
:
705 // FIXME: We prefer to print the size directly here, but have no way
706 // to get the size of the type.
707 OS
<< "__attribute__((__arm_sve_vector_bits__(";
709 if (T
->getVectorKind() == VectorKind::SveFixedLengthPredicate
)
710 // Predicates take a bit per byte of the vector size, multiply by 8 to
711 // get the number of bits passed to the attribute.
712 OS
<< T
->getNumElements() * 8;
714 OS
<< T
->getNumElements();
717 print(T
->getElementType(), OS
, StringRef());
718 // Multiply by 8 for the number of bits.
720 printBefore(T
->getElementType(), OS
);
722 case VectorKind::RVVFixedLengthData
:
723 case VectorKind::RVVFixedLengthMask
:
724 case VectorKind::RVVFixedLengthMask_1
:
725 case VectorKind::RVVFixedLengthMask_2
:
726 case VectorKind::RVVFixedLengthMask_4
:
727 // FIXME: We prefer to print the size directly here, but have no way
728 // to get the size of the type.
729 OS
<< "__attribute__((__riscv_rvv_vector_bits__(";
731 OS
<< T
->getNumElements();
734 print(T
->getElementType(), OS
, StringRef());
735 // Multiply by 8 for the number of bits.
737 printBefore(T
->getElementType(), OS
);
742 void TypePrinter::printVectorAfter(const VectorType
*T
, raw_ostream
&OS
) {
743 printAfter(T
->getElementType(), OS
);
746 void TypePrinter::printDependentVectorBefore(
747 const DependentVectorType
*T
, raw_ostream
&OS
) {
748 switch (T
->getVectorKind()) {
749 case VectorKind::AltiVecPixel
:
750 OS
<< "__vector __pixel ";
752 case VectorKind::AltiVecBool
:
753 OS
<< "__vector __bool ";
754 printBefore(T
->getElementType(), OS
);
756 case VectorKind::AltiVecVector
:
758 printBefore(T
->getElementType(), OS
);
760 case VectorKind::Neon
:
761 OS
<< "__attribute__((neon_vector_type(";
762 if (T
->getSizeExpr())
763 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
765 printBefore(T
->getElementType(), OS
);
767 case VectorKind::NeonPoly
:
768 OS
<< "__attribute__((neon_polyvector_type(";
769 if (T
->getSizeExpr())
770 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
772 printBefore(T
->getElementType(), OS
);
774 case VectorKind::Generic
: {
775 // FIXME: We prefer to print the size directly here, but have no way
776 // to get the size of the type.
777 OS
<< "__attribute__((__vector_size__(";
778 if (T
->getSizeExpr())
779 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
781 print(T
->getElementType(), OS
, StringRef());
783 printBefore(T
->getElementType(), OS
);
786 case VectorKind::SveFixedLengthData
:
787 case VectorKind::SveFixedLengthPredicate
:
788 // FIXME: We prefer to print the size directly here, but have no way
789 // to get the size of the type.
790 OS
<< "__attribute__((__arm_sve_vector_bits__(";
791 if (T
->getSizeExpr()) {
792 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
793 if (T
->getVectorKind() == VectorKind::SveFixedLengthPredicate
)
794 // Predicates take a bit per byte of the vector size, multiply by 8 to
795 // get the number of bits passed to the attribute.
798 print(T
->getElementType(), OS
, StringRef());
799 // Multiply by 8 for the number of bits.
803 printBefore(T
->getElementType(), OS
);
805 case VectorKind::RVVFixedLengthData
:
806 case VectorKind::RVVFixedLengthMask
:
807 case VectorKind::RVVFixedLengthMask_1
:
808 case VectorKind::RVVFixedLengthMask_2
:
809 case VectorKind::RVVFixedLengthMask_4
:
810 // FIXME: We prefer to print the size directly here, but have no way
811 // to get the size of the type.
812 OS
<< "__attribute__((__riscv_rvv_vector_bits__(";
813 if (T
->getSizeExpr()) {
814 T
->getSizeExpr()->printPretty(OS
, nullptr, Policy
);
816 print(T
->getElementType(), OS
, StringRef());
817 // Multiply by 8 for the number of bits.
821 printBefore(T
->getElementType(), OS
);
826 void TypePrinter::printDependentVectorAfter(
827 const DependentVectorType
*T
, raw_ostream
&OS
) {
828 printAfter(T
->getElementType(), OS
);
831 void TypePrinter::printExtVectorBefore(const ExtVectorType
*T
,
833 if (Policy
.UseHLSLTypes
)
835 printBefore(T
->getElementType(), OS
);
838 void TypePrinter::printExtVectorAfter(const ExtVectorType
*T
, raw_ostream
&OS
) {
839 printAfter(T
->getElementType(), OS
);
841 if (Policy
.UseHLSLTypes
) {
843 OS
<< T
->getNumElements();
846 OS
<< " __attribute__((ext_vector_type(";
847 OS
<< T
->getNumElements();
852 void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType
*T
,
854 printBefore(T
->getElementType(), OS
);
855 OS
<< " __attribute__((matrix_type(";
856 OS
<< T
->getNumRows() << ", " << T
->getNumColumns();
860 void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType
*T
,
862 printAfter(T
->getElementType(), OS
);
865 void TypePrinter::printDependentSizedMatrixBefore(
866 const DependentSizedMatrixType
*T
, raw_ostream
&OS
) {
867 printBefore(T
->getElementType(), OS
);
868 OS
<< " __attribute__((matrix_type(";
869 if (T
->getRowExpr()) {
870 T
->getRowExpr()->printPretty(OS
, nullptr, Policy
);
873 if (T
->getColumnExpr()) {
874 T
->getColumnExpr()->printPretty(OS
, nullptr, Policy
);
879 void TypePrinter::printDependentSizedMatrixAfter(
880 const DependentSizedMatrixType
*T
, raw_ostream
&OS
) {
881 printAfter(T
->getElementType(), OS
);
885 FunctionProtoType::printExceptionSpecification(raw_ostream
&OS
,
886 const PrintingPolicy
&Policy
)
888 if (hasDynamicExceptionSpec()) {
890 if (getExceptionSpecType() == EST_MSAny
)
893 for (unsigned I
= 0, N
= getNumExceptions(); I
!= N
; ++I
) {
897 OS
<< getExceptionType(I
).stream(Policy
);
900 } else if (EST_NoThrow
== getExceptionSpecType()) {
901 OS
<< " __attribute__((nothrow))";
902 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
904 // FIXME:Is it useful to print out the expression for a non-dependent
905 // noexcept specification?
906 if (isComputedNoexcept(getExceptionSpecType())) {
908 if (getNoexceptExpr())
909 getNoexceptExpr()->printPretty(OS
, nullptr, Policy
);
915 void TypePrinter::printFunctionProtoBefore(const FunctionProtoType
*T
,
917 if (T
->hasTrailingReturn()) {
919 if (!HasEmptyPlaceHolder
)
922 // If needed for precedence reasons, wrap the inner part in grouping parens.
923 SaveAndRestore
PrevPHIsEmpty(HasEmptyPlaceHolder
, false);
924 printBefore(T
->getReturnType(), OS
);
925 if (!PrevPHIsEmpty
.get())
930 StringRef
clang::getParameterABISpelling(ParameterABI ABI
) {
932 case ParameterABI::Ordinary
:
933 llvm_unreachable("asking for spelling of ordinary parameter ABI");
934 case ParameterABI::SwiftContext
:
935 return "swift_context";
936 case ParameterABI::SwiftAsyncContext
:
937 return "swift_async_context";
938 case ParameterABI::SwiftErrorResult
:
939 return "swift_error_result";
940 case ParameterABI::SwiftIndirectResult
:
941 return "swift_indirect_result";
942 case ParameterABI::HLSLOut
:
944 case ParameterABI::HLSLInOut
:
947 llvm_unreachable("bad parameter ABI kind");
950 void TypePrinter::printFunctionProtoAfter(const FunctionProtoType
*T
,
952 // If needed for precedence reasons, wrap the inner part in grouping parens.
953 if (!HasEmptyPlaceHolder
)
955 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
959 ParamPolicyRAII
ParamPolicy(Policy
);
960 for (unsigned i
= 0, e
= T
->getNumParams(); i
!= e
; ++i
) {
963 auto EPI
= T
->getExtParameterInfo(i
);
964 if (EPI
.isConsumed()) OS
<< "__attribute__((ns_consumed)) ";
965 if (EPI
.isNoEscape())
966 OS
<< "__attribute__((noescape)) ";
967 auto ABI
= EPI
.getABI();
968 if (ABI
== ParameterABI::HLSLInOut
|| ABI
== ParameterABI::HLSLOut
) {
969 OS
<< getParameterABISpelling(ABI
) << " ";
970 if (Policy
.UseHLSLTypes
) {
971 // This is a bit of a hack because we _do_ use reference types in the
972 // AST for representing inout and out parameters so that code
973 // generation is sane, but when re-printing these for HLSL we need to
974 // skip the reference.
975 print(T
->getParamType(i
).getNonReferenceType(), OS
, StringRef());
978 } else if (ABI
!= ParameterABI::Ordinary
)
979 OS
<< "__attribute__((" << getParameterABISpelling(ABI
) << ")) ";
981 print(T
->getParamType(i
), OS
, StringRef());
985 if (T
->isVariadic()) {
986 if (T
->getNumParams())
989 } else if (T
->getNumParams() == 0 && Policy
.UseVoidForZeroParams
) {
990 // Do not emit int() if we have a proto, emit 'int(void)'.
996 FunctionType::ExtInfo Info
= T
->getExtInfo();
997 unsigned SMEBits
= T
->getAArch64SMEAttributes();
999 if (SMEBits
& FunctionType::SME_PStateSMCompatibleMask
)
1000 OS
<< " __arm_streaming_compatible";
1001 if (SMEBits
& FunctionType::SME_PStateSMEnabledMask
)
1002 OS
<< " __arm_streaming";
1003 if (FunctionType::getArmZAState(SMEBits
) == FunctionType::ARM_Preserves
)
1004 OS
<< " __arm_preserves(\"za\")";
1005 if (FunctionType::getArmZAState(SMEBits
) == FunctionType::ARM_In
)
1006 OS
<< " __arm_in(\"za\")";
1007 if (FunctionType::getArmZAState(SMEBits
) == FunctionType::ARM_Out
)
1008 OS
<< " __arm_out(\"za\")";
1009 if (FunctionType::getArmZAState(SMEBits
) == FunctionType::ARM_InOut
)
1010 OS
<< " __arm_inout(\"za\")";
1011 if (FunctionType::getArmZT0State(SMEBits
) == FunctionType::ARM_Preserves
)
1012 OS
<< " __arm_preserves(\"zt0\")";
1013 if (FunctionType::getArmZT0State(SMEBits
) == FunctionType::ARM_In
)
1014 OS
<< " __arm_in(\"zt0\")";
1015 if (FunctionType::getArmZT0State(SMEBits
) == FunctionType::ARM_Out
)
1016 OS
<< " __arm_out(\"zt0\")";
1017 if (FunctionType::getArmZT0State(SMEBits
) == FunctionType::ARM_InOut
)
1018 OS
<< " __arm_inout(\"zt0\")";
1020 printFunctionAfter(Info
, OS
);
1022 if (!T
->getMethodQuals().empty())
1023 OS
<< " " << T
->getMethodQuals().getAsString();
1025 switch (T
->getRefQualifier()) {
1037 T
->printExceptionSpecification(OS
, Policy
);
1039 const FunctionEffectsRef FX
= T
->getFunctionEffects();
1040 for (const auto &CFE
: FX
) {
1041 OS
<< " __attribute__((" << CFE
.Effect
.name();
1042 if (const Expr
*E
= CFE
.Cond
.getCondition()) {
1044 E
->printPretty(OS
, nullptr, Policy
);
1050 if (T
->hasTrailingReturn()) {
1052 print(T
->getReturnType(), OS
, StringRef());
1054 printAfter(T
->getReturnType(), OS
);
1057 void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo
&Info
,
1059 if (!InsideCCAttribute
) {
1060 switch (Info
.getCC()) {
1062 // The C calling convention is the default on the vast majority of platforms
1063 // we support. If the user wrote it explicitly, it will usually be printed
1064 // while traversing the AttributedType. If the type has been desugared, let
1065 // the canonical spelling be the implicit calling convention.
1066 // FIXME: It would be better to be explicit in certain contexts, such as a
1067 // cdecl function typedef used to declare a member function with the
1068 // Microsoft C++ ABI.
1071 OS
<< " __attribute__((stdcall))";
1073 case CC_X86FastCall
:
1074 OS
<< " __attribute__((fastcall))";
1076 case CC_X86ThisCall
:
1077 OS
<< " __attribute__((thiscall))";
1079 case CC_X86VectorCall
:
1080 OS
<< " __attribute__((vectorcall))";
1083 OS
<< " __attribute__((pascal))";
1086 OS
<< " __attribute__((pcs(\"aapcs\")))";
1089 OS
<< " __attribute__((pcs(\"aapcs-vfp\")))";
1091 case CC_AArch64VectorCall
:
1092 OS
<< "__attribute__((aarch64_vector_pcs))";
1094 case CC_AArch64SVEPCS
:
1095 OS
<< "__attribute__((aarch64_sve_pcs))";
1097 case CC_AMDGPUKernelCall
:
1098 OS
<< "__attribute__((amdgpu_kernel))";
1100 case CC_IntelOclBicc
:
1101 OS
<< " __attribute__((intel_ocl_bicc))";
1104 OS
<< " __attribute__((ms_abi))";
1107 OS
<< " __attribute__((sysv_abi))";
1110 OS
<< " __attribute__((regcall))";
1112 case CC_SpirFunction
:
1113 case CC_OpenCLKernel
:
1114 // Do nothing. These CCs are not available as attributes.
1117 OS
<< " __attribute__((swiftcall))";
1120 OS
<< "__attribute__((swiftasynccall))";
1122 case CC_PreserveMost
:
1123 OS
<< " __attribute__((preserve_most))";
1125 case CC_PreserveAll
:
1126 OS
<< " __attribute__((preserve_all))";
1129 OS
<< " __attribute__((m68k_rtd))";
1131 case CC_PreserveNone
:
1132 OS
<< " __attribute__((preserve_none))";
1134 case CC_RISCVVectorCall
:
1135 OS
<< "__attribute__((riscv_vector_cc))";
1140 if (Info
.getNoReturn())
1141 OS
<< " __attribute__((noreturn))";
1142 if (Info
.getCmseNSCall())
1143 OS
<< " __attribute__((cmse_nonsecure_call))";
1144 if (Info
.getProducesResult())
1145 OS
<< " __attribute__((ns_returns_retained))";
1146 if (Info
.getRegParm())
1147 OS
<< " __attribute__((regparm ("
1148 << Info
.getRegParm() << ")))";
1149 if (Info
.getNoCallerSavedRegs())
1150 OS
<< " __attribute__((no_caller_saved_registers))";
1151 if (Info
.getNoCfCheck())
1152 OS
<< " __attribute__((nocf_check))";
1155 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType
*T
,
1157 // If needed for precedence reasons, wrap the inner part in grouping parens.
1158 SaveAndRestore
PrevPHIsEmpty(HasEmptyPlaceHolder
, false);
1159 printBefore(T
->getReturnType(), OS
);
1160 if (!PrevPHIsEmpty
.get())
1164 void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType
*T
,
1166 // If needed for precedence reasons, wrap the inner part in grouping parens.
1167 if (!HasEmptyPlaceHolder
)
1169 SaveAndRestore
NonEmptyPH(HasEmptyPlaceHolder
, false);
1172 printFunctionAfter(T
->getExtInfo(), OS
);
1173 printAfter(T
->getReturnType(), OS
);
1176 void TypePrinter::printTypeSpec(NamedDecl
*D
, raw_ostream
&OS
) {
1178 // Compute the full nested-name-specifier for this type.
1179 // In C, this will always be empty except when the type
1180 // being printed is anonymous within other Record.
1181 if (!Policy
.SuppressScope
)
1182 AppendScope(D
->getDeclContext(), OS
, D
->getDeclName());
1184 IdentifierInfo
*II
= D
->getIdentifier();
1185 OS
<< II
->getName();
1186 spaceBeforePlaceHolder(OS
);
1189 void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType
*T
,
1191 printTypeSpec(T
->getDecl(), OS
);
1194 void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType
*T
,
1197 void TypePrinter::printUsingBefore(const UsingType
*T
, raw_ostream
&OS
) {
1198 // After `namespace b { using a::X }`, is the type X within B a::X or b::X?
1200 // - b::X is more formally correct given the UsingType model
1201 // - b::X makes sense if "re-exporting" a symbol in a new namespace
1202 // - a::X makes sense if "importing" a symbol for convenience
1204 // The "importing" use seems much more common, so we print a::X.
1205 // This could be a policy option, but the right choice seems to rest more
1206 // with the intent of the code than the caller.
1207 printTypeSpec(T
->getFoundDecl()->getUnderlyingDecl(), OS
);
1210 void TypePrinter::printUsingAfter(const UsingType
*T
, raw_ostream
&OS
) {}
1212 void TypePrinter::printTypedefBefore(const TypedefType
*T
, raw_ostream
&OS
) {
1213 printTypeSpec(T
->getDecl(), OS
);
1216 void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType
*T
,
1218 StringRef MacroName
= T
->getMacroIdentifier()->getName();
1219 OS
<< MacroName
<< " ";
1221 // Since this type is meant to print the macro instead of the whole attribute,
1222 // we trim any attributes and go directly to the original modified type.
1223 printBefore(T
->getModifiedType(), OS
);
1226 void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType
*T
,
1228 printAfter(T
->getModifiedType(), OS
);
1231 void TypePrinter::printTypedefAfter(const TypedefType
*T
, raw_ostream
&OS
) {}
1233 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType
*T
,
1235 OS
<< (T
->getKind() == TypeOfKind::Unqualified
? "typeof_unqual "
1237 if (T
->getUnderlyingExpr())
1238 T
->getUnderlyingExpr()->printPretty(OS
, nullptr, Policy
);
1239 spaceBeforePlaceHolder(OS
);
1242 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType
*T
,
1245 void TypePrinter::printTypeOfBefore(const TypeOfType
*T
, raw_ostream
&OS
) {
1246 OS
<< (T
->getKind() == TypeOfKind::Unqualified
? "typeof_unqual("
1248 print(T
->getUnmodifiedType(), OS
, StringRef());
1250 spaceBeforePlaceHolder(OS
);
1253 void TypePrinter::printTypeOfAfter(const TypeOfType
*T
, raw_ostream
&OS
) {}
1255 void TypePrinter::printDecltypeBefore(const DecltypeType
*T
, raw_ostream
&OS
) {
1257 if (T
->getUnderlyingExpr())
1258 T
->getUnderlyingExpr()->printPretty(OS
, nullptr, Policy
);
1260 spaceBeforePlaceHolder(OS
);
1263 void TypePrinter::printPackIndexingBefore(const PackIndexingType
*T
,
1265 if (T
->hasSelectedType()) {
1266 OS
<< T
->getSelectedType();
1268 OS
<< T
->getPattern() << "...[";
1269 T
->getIndexExpr()->printPretty(OS
, nullptr, Policy
);
1272 spaceBeforePlaceHolder(OS
);
1275 void TypePrinter::printPackIndexingAfter(const PackIndexingType
*T
,
1278 void TypePrinter::printDecltypeAfter(const DecltypeType
*T
, raw_ostream
&OS
) {}
1280 void TypePrinter::printUnaryTransformBefore(const UnaryTransformType
*T
,
1282 IncludeStrongLifetimeRAII
Strong(Policy
);
1284 static llvm::DenseMap
<int, const char *> Transformation
= {{
1285 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1286 {UnaryTransformType::Enum, "__" #Trait},
1287 #include "clang/Basic/TransformTypeTraits.def"
1289 OS
<< Transformation
[T
->getUTTKind()] << '(';
1290 print(T
->getBaseType(), OS
, StringRef());
1292 spaceBeforePlaceHolder(OS
);
1295 void TypePrinter::printUnaryTransformAfter(const UnaryTransformType
*T
,
1298 void TypePrinter::printAutoBefore(const AutoType
*T
, raw_ostream
&OS
) {
1299 // If the type has been deduced, do not print 'auto'.
1300 if (!T
->getDeducedType().isNull()) {
1301 printBefore(T
->getDeducedType(), OS
);
1303 if (T
->isConstrained()) {
1304 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1305 // type as it was written.
1306 T
->getTypeConstraintConcept()->getDeclName().print(OS
, Policy
);
1307 auto Args
= T
->getTypeConstraintArguments();
1309 printTemplateArgumentList(
1311 T
->getTypeConstraintConcept()->getTemplateParameters());
1314 switch (T
->getKeyword()) {
1315 case AutoTypeKeyword::Auto
: OS
<< "auto"; break;
1316 case AutoTypeKeyword::DecltypeAuto
: OS
<< "decltype(auto)"; break;
1317 case AutoTypeKeyword::GNUAutoType
: OS
<< "__auto_type"; break;
1319 spaceBeforePlaceHolder(OS
);
1323 void TypePrinter::printAutoAfter(const AutoType
*T
, raw_ostream
&OS
) {
1324 // If the type has been deduced, do not print 'auto'.
1325 if (!T
->getDeducedType().isNull())
1326 printAfter(T
->getDeducedType(), OS
);
1329 void TypePrinter::printDeducedTemplateSpecializationBefore(
1330 const DeducedTemplateSpecializationType
*T
, raw_ostream
&OS
) {
1331 // If the type has been deduced, print the deduced type.
1332 if (!T
->getDeducedType().isNull()) {
1333 printBefore(T
->getDeducedType(), OS
);
1335 IncludeStrongLifetimeRAII
Strong(Policy
);
1336 T
->getTemplateName().print(OS
, Policy
);
1337 spaceBeforePlaceHolder(OS
);
1341 void TypePrinter::printDeducedTemplateSpecializationAfter(
1342 const DeducedTemplateSpecializationType
*T
, raw_ostream
&OS
) {
1343 // If the type has been deduced, print the deduced type.
1344 if (!T
->getDeducedType().isNull())
1345 printAfter(T
->getDeducedType(), OS
);
1348 void TypePrinter::printAtomicBefore(const AtomicType
*T
, raw_ostream
&OS
) {
1349 IncludeStrongLifetimeRAII
Strong(Policy
);
1352 print(T
->getValueType(), OS
, StringRef());
1354 spaceBeforePlaceHolder(OS
);
1357 void TypePrinter::printAtomicAfter(const AtomicType
*T
, raw_ostream
&OS
) {}
1359 void TypePrinter::printPipeBefore(const PipeType
*T
, raw_ostream
&OS
) {
1360 IncludeStrongLifetimeRAII
Strong(Policy
);
1362 if (T
->isReadOnly())
1365 OS
<< "write_only ";
1367 print(T
->getElementType(), OS
, StringRef());
1368 spaceBeforePlaceHolder(OS
);
1371 void TypePrinter::printPipeAfter(const PipeType
*T
, raw_ostream
&OS
) {}
1373 void TypePrinter::printBitIntBefore(const BitIntType
*T
, raw_ostream
&OS
) {
1374 if (T
->isUnsigned())
1376 OS
<< "_BitInt(" << T
->getNumBits() << ")";
1377 spaceBeforePlaceHolder(OS
);
1380 void TypePrinter::printBitIntAfter(const BitIntType
*T
, raw_ostream
&OS
) {}
1382 void TypePrinter::printDependentBitIntBefore(const DependentBitIntType
*T
,
1384 if (T
->isUnsigned())
1387 T
->getNumBitsExpr()->printPretty(OS
, nullptr, Policy
);
1389 spaceBeforePlaceHolder(OS
);
1392 void TypePrinter::printDependentBitIntAfter(const DependentBitIntType
*T
,
1395 /// Appends the given scope to the end of a string.
1396 void TypePrinter::AppendScope(DeclContext
*DC
, raw_ostream
&OS
,
1397 DeclarationName NameInScope
) {
1398 if (DC
->isTranslationUnit())
1401 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1402 // which can also print names for function and method scopes.
1403 if (DC
->isFunctionOrMethod())
1406 if (Policy
.Callbacks
&& Policy
.Callbacks
->isScopeVisible(DC
))
1409 if (const auto *NS
= dyn_cast
<NamespaceDecl
>(DC
)) {
1410 if (Policy
.SuppressUnwrittenScope
&& NS
->isAnonymousNamespace())
1411 return AppendScope(DC
->getParent(), OS
, NameInScope
);
1413 // Only suppress an inline namespace if the name has the same lookup
1414 // results in the enclosing namespace.
1415 if (Policy
.SuppressInlineNamespace
!=
1416 PrintingPolicy::SuppressInlineNamespaceMode::None
&&
1417 NS
->isInline() && NameInScope
&&
1418 NS
->isRedundantInlineQualifierFor(NameInScope
))
1419 return AppendScope(DC
->getParent(), OS
, NameInScope
);
1421 AppendScope(DC
->getParent(), OS
, NS
->getDeclName());
1422 if (NS
->getIdentifier())
1423 OS
<< NS
->getName() << "::";
1425 OS
<< "(anonymous namespace)::";
1426 } else if (const auto *Spec
= dyn_cast
<ClassTemplateSpecializationDecl
>(DC
)) {
1427 AppendScope(DC
->getParent(), OS
, Spec
->getDeclName());
1428 IncludeStrongLifetimeRAII
Strong(Policy
);
1429 OS
<< Spec
->getIdentifier()->getName();
1430 const TemplateArgumentList
&TemplateArgs
= Spec
->getTemplateArgs();
1431 printTemplateArgumentList(
1432 OS
, TemplateArgs
.asArray(), Policy
,
1433 Spec
->getSpecializedTemplate()->getTemplateParameters());
1435 } else if (const auto *Tag
= dyn_cast
<TagDecl
>(DC
)) {
1436 AppendScope(DC
->getParent(), OS
, Tag
->getDeclName());
1437 if (TypedefNameDecl
*Typedef
= Tag
->getTypedefNameForAnonDecl())
1438 OS
<< Typedef
->getIdentifier()->getName() << "::";
1439 else if (Tag
->getIdentifier())
1440 OS
<< Tag
->getIdentifier()->getName() << "::";
1444 AppendScope(DC
->getParent(), OS
, NameInScope
);
1448 void TypePrinter::printTag(TagDecl
*D
, raw_ostream
&OS
) {
1449 if (Policy
.IncludeTagDefinition
) {
1450 PrintingPolicy SubPolicy
= Policy
;
1451 SubPolicy
.IncludeTagDefinition
= false;
1452 D
->print(OS
, SubPolicy
, Indentation
);
1453 spaceBeforePlaceHolder(OS
);
1457 bool HasKindDecoration
= false;
1459 // We don't print tags unless this is an elaborated type.
1460 // In C, we just assume every RecordType is an elaborated type.
1461 if (!Policy
.SuppressTagKeyword
&& !D
->getTypedefNameForAnonDecl()) {
1462 HasKindDecoration
= true;
1463 OS
<< D
->getKindName();
1467 // Compute the full nested-name-specifier for this type.
1468 // In C, this will always be empty except when the type
1469 // being printed is anonymous within other Record.
1470 if (!Policy
.SuppressScope
)
1471 AppendScope(D
->getDeclContext(), OS
, D
->getDeclName());
1473 if (const IdentifierInfo
*II
= D
->getIdentifier())
1474 OS
<< II
->getName();
1475 else if (TypedefNameDecl
*Typedef
= D
->getTypedefNameForAnonDecl()) {
1476 assert(Typedef
->getIdentifier() && "Typedef without identifier?");
1477 OS
<< Typedef
->getIdentifier()->getName();
1479 // Make an unambiguous representation for anonymous types, e.g.
1480 // (anonymous enum at /usr/include/string.h:120:9)
1481 OS
<< (Policy
.MSVCFormatting
? '`' : '(');
1483 if (isa
<CXXRecordDecl
>(D
) && cast
<CXXRecordDecl
>(D
)->isLambda()) {
1485 HasKindDecoration
= true;
1486 } else if ((isa
<RecordDecl
>(D
) && cast
<RecordDecl
>(D
)->isAnonymousStructOrUnion())) {
1492 if (Policy
.AnonymousTagLocations
) {
1493 // Suppress the redundant tag keyword if we just printed one.
1494 // We don't have to worry about ElaboratedTypes here because you can't
1495 // refer to an anonymous type with one.
1496 if (!HasKindDecoration
)
1497 OS
<< " " << D
->getKindName();
1499 PresumedLoc PLoc
= D
->getASTContext().getSourceManager().getPresumedLoc(
1501 if (PLoc
.isValid()) {
1503 StringRef File
= PLoc
.getFilename();
1504 llvm::SmallString
<1024> WrittenFile(File
);
1505 if (auto *Callbacks
= Policy
.Callbacks
)
1506 WrittenFile
= Callbacks
->remapPath(File
);
1507 // Fix inconsistent path separator created by
1508 // clang::DirectoryLookup::LookupFile when the file path is relative
1510 llvm::sys::path::Style Style
=
1511 llvm::sys::path::is_absolute(WrittenFile
)
1512 ? llvm::sys::path::Style::native
1513 : (Policy
.MSVCFormatting
1514 ? llvm::sys::path::Style::windows_backslash
1515 : llvm::sys::path::Style::posix
);
1516 llvm::sys::path::native(WrittenFile
, Style
);
1517 OS
<< WrittenFile
<< ':' << PLoc
.getLine() << ':' << PLoc
.getColumn();
1521 OS
<< (Policy
.MSVCFormatting
? '\'' : ')');
1524 // If this is a class template specialization, print the template
1526 if (auto *S
= dyn_cast
<ClassTemplateSpecializationDecl
>(D
)) {
1527 const TemplateParameterList
*TParams
=
1528 S
->getSpecializedTemplate()->getTemplateParameters();
1529 const ASTTemplateArgumentListInfo
*TArgAsWritten
=
1530 S
->getTemplateArgsAsWritten();
1531 IncludeStrongLifetimeRAII
Strong(Policy
);
1532 if (TArgAsWritten
&& !Policy
.PrintCanonicalTypes
)
1533 printTemplateArgumentList(OS
, TArgAsWritten
->arguments(), Policy
,
1536 printTemplateArgumentList(OS
, S
->getTemplateArgs().asArray(), Policy
,
1540 spaceBeforePlaceHolder(OS
);
1543 void TypePrinter::printRecordBefore(const RecordType
*T
, raw_ostream
&OS
) {
1544 // Print the preferred name if we have one for this type.
1545 if (Policy
.UsePreferredNames
) {
1546 for (const auto *PNA
: T
->getDecl()->specific_attrs
<PreferredNameAttr
>()) {
1547 if (!declaresSameEntity(PNA
->getTypedefType()->getAsCXXRecordDecl(),
1550 // Find the outermost typedef or alias template.
1551 QualType T
= PNA
->getTypedefType();
1553 if (auto *TT
= dyn_cast
<TypedefType
>(T
))
1554 return printTypeSpec(TT
->getDecl(), OS
);
1555 if (auto *TST
= dyn_cast
<TemplateSpecializationType
>(T
))
1556 return printTemplateId(TST
, OS
, /*FullyQualify=*/true);
1557 T
= T
->getLocallyUnqualifiedSingleStepDesugaredType();
1562 printTag(T
->getDecl(), OS
);
1565 void TypePrinter::printRecordAfter(const RecordType
*T
, raw_ostream
&OS
) {}
1567 void TypePrinter::printEnumBefore(const EnumType
*T
, raw_ostream
&OS
) {
1568 printTag(T
->getDecl(), OS
);
1571 void TypePrinter::printEnumAfter(const EnumType
*T
, raw_ostream
&OS
) {}
1573 void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType
*T
,
1575 TemplateTypeParmDecl
*D
= T
->getDecl();
1576 if (D
&& D
->isImplicit()) {
1577 if (auto *TC
= D
->getTypeConstraint()) {
1578 TC
->print(OS
, Policy
);
1582 } else if (IdentifierInfo
*Id
= T
->getIdentifier())
1583 OS
<< (Policy
.CleanUglifiedParameters
? Id
->deuglifiedName()
1586 OS
<< "type-parameter-" << T
->getDepth() << '-' << T
->getIndex();
1588 spaceBeforePlaceHolder(OS
);
1591 void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType
*T
,
1594 void TypePrinter::printSubstTemplateTypeParmBefore(
1595 const SubstTemplateTypeParmType
*T
,
1597 IncludeStrongLifetimeRAII
Strong(Policy
);
1598 printBefore(T
->getReplacementType(), OS
);
1601 void TypePrinter::printSubstTemplateTypeParmAfter(
1602 const SubstTemplateTypeParmType
*T
,
1604 IncludeStrongLifetimeRAII
Strong(Policy
);
1605 printAfter(T
->getReplacementType(), OS
);
1608 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1609 const SubstTemplateTypeParmPackType
*T
,
1611 IncludeStrongLifetimeRAII
Strong(Policy
);
1612 if (const TemplateTypeParmDecl
*D
= T
->getReplacedParameter()) {
1613 if (D
&& D
->isImplicit()) {
1614 if (auto *TC
= D
->getTypeConstraint()) {
1615 TC
->print(OS
, Policy
);
1619 } else if (IdentifierInfo
*Id
= D
->getIdentifier())
1620 OS
<< (Policy
.CleanUglifiedParameters
? Id
->deuglifiedName()
1623 OS
<< "type-parameter-" << D
->getDepth() << '-' << D
->getIndex();
1625 spaceBeforePlaceHolder(OS
);
1629 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1630 const SubstTemplateTypeParmPackType
*T
,
1632 IncludeStrongLifetimeRAII
Strong(Policy
);
1635 void TypePrinter::printTemplateId(const TemplateSpecializationType
*T
,
1636 raw_ostream
&OS
, bool FullyQualify
) {
1637 IncludeStrongLifetimeRAII
Strong(Policy
);
1640 T
->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1641 // FIXME: Null TD never exercised in test suite.
1642 if (FullyQualify
&& TD
) {
1643 if (!Policy
.SuppressScope
)
1644 AppendScope(TD
->getDeclContext(), OS
, TD
->getDeclName());
1646 OS
<< TD
->getName();
1648 T
->getTemplateName().print(OS
, Policy
, TemplateName::Qualified::None
);
1651 DefaultTemplateArgsPolicyRAII
TemplateArgs(Policy
);
1652 const TemplateParameterList
*TPL
= TD
? TD
->getTemplateParameters() : nullptr;
1653 printTemplateArgumentList(OS
, T
->template_arguments(), Policy
, TPL
);
1654 spaceBeforePlaceHolder(OS
);
1657 void TypePrinter::printTemplateSpecializationBefore(
1658 const TemplateSpecializationType
*T
,
1660 printTemplateId(T
, OS
, Policy
.FullyQualifiedName
);
1663 void TypePrinter::printTemplateSpecializationAfter(
1664 const TemplateSpecializationType
*T
,
1667 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType
*T
,
1669 if (Policy
.PrintInjectedClassNameWithArguments
)
1670 return printTemplateSpecializationBefore(T
->getInjectedTST(), OS
);
1672 IncludeStrongLifetimeRAII
Strong(Policy
);
1673 T
->getTemplateName().print(OS
, Policy
);
1674 spaceBeforePlaceHolder(OS
);
1677 void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType
*T
,
1680 void TypePrinter::printElaboratedBefore(const ElaboratedType
*T
,
1682 if (Policy
.IncludeTagDefinition
&& T
->getOwnedTagDecl()) {
1683 TagDecl
*OwnedTagDecl
= T
->getOwnedTagDecl();
1684 assert(OwnedTagDecl
->getTypeForDecl() == T
->getNamedType().getTypePtr() &&
1685 "OwnedTagDecl expected to be a declaration for the type");
1686 PrintingPolicy SubPolicy
= Policy
;
1687 SubPolicy
.IncludeTagDefinition
= false;
1688 OwnedTagDecl
->print(OS
, SubPolicy
, Indentation
);
1689 spaceBeforePlaceHolder(OS
);
1693 if (Policy
.SuppressElaboration
) {
1694 printBefore(T
->getNamedType(), OS
);
1698 // The tag definition will take care of these.
1699 if (!Policy
.IncludeTagDefinition
)
1701 OS
<< TypeWithKeyword::getKeywordName(T
->getKeyword());
1702 if (T
->getKeyword() != ElaboratedTypeKeyword::None
)
1704 NestedNameSpecifier
*Qualifier
= T
->getQualifier();
1705 if (!Policy
.SuppressTagKeyword
&& Policy
.SuppressScope
&&
1706 !Policy
.SuppressUnwrittenScope
) {
1707 bool OldTagKeyword
= Policy
.SuppressTagKeyword
;
1708 bool OldSupressScope
= Policy
.SuppressScope
;
1709 Policy
.SuppressTagKeyword
= true;
1710 Policy
.SuppressScope
= false;
1711 printBefore(T
->getNamedType(), OS
);
1712 Policy
.SuppressTagKeyword
= OldTagKeyword
;
1713 Policy
.SuppressScope
= OldSupressScope
;
1717 Qualifier
->print(OS
, Policy
);
1720 ElaboratedTypePolicyRAII
PolicyRAII(Policy
);
1721 printBefore(T
->getNamedType(), OS
);
1724 void TypePrinter::printElaboratedAfter(const ElaboratedType
*T
,
1726 if (Policy
.IncludeTagDefinition
&& T
->getOwnedTagDecl())
1729 if (Policy
.SuppressElaboration
) {
1730 printAfter(T
->getNamedType(), OS
);
1734 ElaboratedTypePolicyRAII
PolicyRAII(Policy
);
1735 printAfter(T
->getNamedType(), OS
);
1738 void TypePrinter::printParenBefore(const ParenType
*T
, raw_ostream
&OS
) {
1739 if (!HasEmptyPlaceHolder
&& !isa
<FunctionType
>(T
->getInnerType())) {
1740 printBefore(T
->getInnerType(), OS
);
1743 printBefore(T
->getInnerType(), OS
);
1746 void TypePrinter::printParenAfter(const ParenType
*T
, raw_ostream
&OS
) {
1747 if (!HasEmptyPlaceHolder
&& !isa
<FunctionType
>(T
->getInnerType())) {
1749 printAfter(T
->getInnerType(), OS
);
1751 printAfter(T
->getInnerType(), OS
);
1754 void TypePrinter::printDependentNameBefore(const DependentNameType
*T
,
1756 OS
<< TypeWithKeyword::getKeywordName(T
->getKeyword());
1757 if (T
->getKeyword() != ElaboratedTypeKeyword::None
)
1760 T
->getQualifier()->print(OS
, Policy
);
1762 OS
<< T
->getIdentifier()->getName();
1763 spaceBeforePlaceHolder(OS
);
1766 void TypePrinter::printDependentNameAfter(const DependentNameType
*T
,
1769 void TypePrinter::printDependentTemplateSpecializationBefore(
1770 const DependentTemplateSpecializationType
*T
, raw_ostream
&OS
) {
1771 IncludeStrongLifetimeRAII
Strong(Policy
);
1773 OS
<< TypeWithKeyword::getKeywordName(T
->getKeyword());
1774 if (T
->getKeyword() != ElaboratedTypeKeyword::None
)
1777 if (T
->getQualifier())
1778 T
->getQualifier()->print(OS
, Policy
);
1779 OS
<< "template " << T
->getIdentifier()->getName();
1780 printTemplateArgumentList(OS
, T
->template_arguments(), Policy
);
1781 spaceBeforePlaceHolder(OS
);
1784 void TypePrinter::printDependentTemplateSpecializationAfter(
1785 const DependentTemplateSpecializationType
*T
, raw_ostream
&OS
) {}
1787 void TypePrinter::printPackExpansionBefore(const PackExpansionType
*T
,
1789 printBefore(T
->getPattern(), OS
);
1792 void TypePrinter::printPackExpansionAfter(const PackExpansionType
*T
,
1794 printAfter(T
->getPattern(), OS
);
1798 static void printCountAttributedImpl(const CountAttributedType
*T
,
1800 const PrintingPolicy
&Policy
) {
1802 if (T
->isCountInBytes() && T
->isOrNull())
1803 OS
<< "__sized_by_or_null(";
1804 else if (T
->isCountInBytes())
1805 OS
<< "__sized_by(";
1806 else if (T
->isOrNull())
1807 OS
<< "__counted_by_or_null(";
1809 OS
<< "__counted_by(";
1810 if (T
->getCountExpr())
1811 T
->getCountExpr()->printPretty(OS
, nullptr, Policy
);
1815 void TypePrinter::printCountAttributedBefore(const CountAttributedType
*T
,
1817 printBefore(T
->desugar(), OS
);
1818 if (!T
->isArrayType())
1819 printCountAttributedImpl(T
, OS
, Policy
);
1822 void TypePrinter::printCountAttributedAfter(const CountAttributedType
*T
,
1824 printAfter(T
->desugar(), OS
);
1825 if (T
->isArrayType())
1826 printCountAttributedImpl(T
, OS
, Policy
);
1829 void TypePrinter::printAttributedBefore(const AttributedType
*T
,
1831 // FIXME: Generate this with TableGen.
1833 // Prefer the macro forms of the GC and ownership qualifiers.
1834 if (T
->getAttrKind() == attr::ObjCGC
||
1835 T
->getAttrKind() == attr::ObjCOwnership
)
1836 return printBefore(T
->getEquivalentType(), OS
);
1838 if (T
->getAttrKind() == attr::ObjCKindOf
)
1841 if (T
->getAttrKind() == attr::AddressSpace
)
1842 printBefore(T
->getEquivalentType(), OS
);
1844 printBefore(T
->getModifiedType(), OS
);
1846 if (T
->isMSTypeSpec()) {
1847 switch (T
->getAttrKind()) {
1849 case attr::Ptr32
: OS
<< " __ptr32"; break;
1850 case attr::Ptr64
: OS
<< " __ptr64"; break;
1851 case attr::SPtr
: OS
<< " __sptr"; break;
1852 case attr::UPtr
: OS
<< " __uptr"; break;
1854 spaceBeforePlaceHolder(OS
);
1857 if (T
->isWebAssemblyFuncrefSpec())
1860 // Print nullability type specifiers.
1861 if (T
->getImmediateNullability()) {
1862 if (T
->getAttrKind() == attr::TypeNonNull
)
1864 else if (T
->getAttrKind() == attr::TypeNullable
)
1866 else if (T
->getAttrKind() == attr::TypeNullUnspecified
)
1867 OS
<< " _Null_unspecified";
1868 else if (T
->getAttrKind() == attr::TypeNullableResult
)
1869 OS
<< " _Nullable_result";
1871 llvm_unreachable("unhandled nullability");
1872 spaceBeforePlaceHolder(OS
);
1876 void TypePrinter::printAttributedAfter(const AttributedType
*T
,
1878 // FIXME: Generate this with TableGen.
1880 // Prefer the macro forms of the GC and ownership qualifiers.
1881 if (T
->getAttrKind() == attr::ObjCGC
||
1882 T
->getAttrKind() == attr::ObjCOwnership
)
1883 return printAfter(T
->getEquivalentType(), OS
);
1885 // If this is a calling convention attribute, don't print the implicit CC from
1886 // the modified type.
1887 SaveAndRestore
MaybeSuppressCC(InsideCCAttribute
, T
->isCallingConv());
1889 printAfter(T
->getModifiedType(), OS
);
1891 // Some attributes are printed as qualifiers before the type, so we have
1892 // nothing left to do.
1893 if (T
->getAttrKind() == attr::ObjCKindOf
|| T
->isMSTypeSpec() ||
1894 T
->getImmediateNullability() || T
->isWebAssemblyFuncrefSpec())
1897 // Don't print the inert __unsafe_unretained attribute at all.
1898 if (T
->getAttrKind() == attr::ObjCInertUnsafeUnretained
)
1901 // Don't print ns_returns_retained unless it had an effect.
1902 if (T
->getAttrKind() == attr::NSReturnsRetained
&&
1903 !T
->getEquivalentType()->castAs
<FunctionType
>()
1904 ->getExtInfo().getProducesResult())
1907 if (T
->getAttrKind() == attr::LifetimeBound
) {
1908 OS
<< " [[clang::lifetimebound]]";
1911 if (T
->getAttrKind() == attr::LifetimeCaptureBy
) {
1912 OS
<< " [[clang::lifetime_capture_by(";
1913 if (auto *attr
= dyn_cast_or_null
<LifetimeCaptureByAttr
>(T
->getAttr()))
1914 llvm::interleaveComma(attr
->getArgIdents(), OS
,
1915 [&](auto it
) { OS
<< it
->getName(); });
1920 // The printing of the address_space attribute is handled by the qualifier
1921 // since it is still stored in the qualifier. Return early to prevent printing
1923 if (T
->getAttrKind() == attr::AddressSpace
)
1926 if (T
->getAttrKind() == attr::AnnotateType
) {
1927 // FIXME: Print the attribute arguments once we have a way to retrieve these
1928 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1929 // without the arguments so that we know at least that we had _some_
1930 // annotation on the type.
1931 OS
<< " [[clang::annotate_type(...)]]";
1935 if (T
->getAttrKind() == attr::ArmStreaming
) {
1936 OS
<< "__arm_streaming";
1939 if (T
->getAttrKind() == attr::ArmStreamingCompatible
) {
1940 OS
<< "__arm_streaming_compatible";
1944 if (T
->getAttrKind() == attr::SwiftAttr
) {
1945 if (auto *swiftAttr
= dyn_cast_or_null
<SwiftAttrAttr
>(T
->getAttr())) {
1946 OS
<< " __attribute__((swift_attr(\"" << swiftAttr
->getAttribute()
1952 OS
<< " __attribute__((";
1953 switch (T
->getAttrKind()) {
1954 #define TYPE_ATTR(NAME)
1955 #define DECL_OR_TYPE_ATTR(NAME)
1956 #define ATTR(NAME) case attr::NAME:
1957 #include "clang/Basic/AttrList.inc"
1958 llvm_unreachable("non-type attribute attached to type");
1960 case attr::BTFTypeTag
:
1961 llvm_unreachable("BTFTypeTag attribute handled separately");
1963 case attr::HLSLResourceClass
:
1965 case attr::HLSLRawBuffer
:
1966 case attr::HLSLContainedType
:
1967 llvm_unreachable("HLSL resource type attributes handled separately");
1969 case attr::OpenCLPrivateAddressSpace
:
1970 case attr::OpenCLGlobalAddressSpace
:
1971 case attr::OpenCLGlobalDeviceAddressSpace
:
1972 case attr::OpenCLGlobalHostAddressSpace
:
1973 case attr::OpenCLLocalAddressSpace
:
1974 case attr::OpenCLConstantAddressSpace
:
1975 case attr::OpenCLGenericAddressSpace
:
1976 case attr::HLSLGroupSharedAddressSpace
:
1977 // FIXME: Update printAttributedBefore to print these once we generate
1978 // AttributedType nodes for them.
1981 case attr::CountedBy
:
1982 case attr::CountedByOrNull
:
1984 case attr::SizedByOrNull
:
1985 case attr::LifetimeBound
:
1986 case attr::LifetimeCaptureBy
:
1987 case attr::TypeNonNull
:
1988 case attr::TypeNullable
:
1989 case attr::TypeNullableResult
:
1990 case attr::TypeNullUnspecified
:
1992 case attr::ObjCInertUnsafeUnretained
:
1993 case attr::ObjCKindOf
:
1994 case attr::ObjCOwnership
:
1999 case attr::AddressSpace
:
2000 case attr::CmseNSCall
:
2001 case attr::AnnotateType
:
2002 case attr::WebAssemblyFuncref
:
2003 case attr::ArmStreaming
:
2004 case attr::ArmStreamingCompatible
:
2007 case attr::ArmInOut
:
2008 case attr::ArmPreserves
:
2009 case attr::NonBlocking
:
2010 case attr::NonAllocating
:
2011 case attr::Blocking
:
2012 case attr::Allocating
:
2013 case attr::SwiftAttr
:
2014 llvm_unreachable("This attribute should have been handled already");
2016 case attr::NSReturnsRetained
:
2017 OS
<< "ns_returns_retained";
2020 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2021 // attribute again in printFunctionProtoAfter.
2022 case attr::AnyX86NoCfCheck
: OS
<< "nocf_check"; break;
2023 case attr::CDecl
: OS
<< "cdecl"; break;
2024 case attr::FastCall
: OS
<< "fastcall"; break;
2025 case attr::StdCall
: OS
<< "stdcall"; break;
2026 case attr::ThisCall
: OS
<< "thiscall"; break;
2027 case attr::SwiftCall
: OS
<< "swiftcall"; break;
2028 case attr::SwiftAsyncCall
: OS
<< "swiftasynccall"; break;
2029 case attr::VectorCall
: OS
<< "vectorcall"; break;
2030 case attr::Pascal
: OS
<< "pascal"; break;
2031 case attr::MSABI
: OS
<< "ms_abi"; break;
2032 case attr::SysVABI
: OS
<< "sysv_abi"; break;
2033 case attr::RegCall
: OS
<< "regcall"; break;
2036 QualType t
= T
->getEquivalentType();
2037 while (!t
->isFunctionType())
2038 t
= t
->getPointeeType();
2039 OS
<< (t
->castAs
<FunctionType
>()->getCallConv() == CC_AAPCS
?
2040 "\"aapcs\"" : "\"aapcs-vfp\"");
2044 case attr::AArch64VectorPcs
: OS
<< "aarch64_vector_pcs"; break;
2045 case attr::AArch64SVEPcs
: OS
<< "aarch64_sve_pcs"; break;
2046 case attr::AMDGPUKernelCall
: OS
<< "amdgpu_kernel"; break;
2047 case attr::IntelOclBicc
: OS
<< "inteloclbicc"; break;
2048 case attr::PreserveMost
:
2049 OS
<< "preserve_most";
2052 case attr::PreserveAll
:
2053 OS
<< "preserve_all";
2058 case attr::PreserveNone
:
2059 OS
<< "preserve_none";
2061 case attr::RISCVVectorCC
:
2062 OS
<< "riscv_vector_cc";
2067 case attr::AcquireHandle
:
2068 OS
<< "acquire_handle";
2070 case attr::ArmMveStrictPolymorphism
:
2071 OS
<< "__clang_arm_mve_strict_polymorphism";
2077 void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType
*T
,
2079 printBefore(T
->getWrappedType(), OS
);
2080 OS
<< " __attribute__((btf_type_tag(\"" << T
->getAttr()->getBTFTypeTag() << "\")))";
2083 void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType
*T
,
2085 printAfter(T
->getWrappedType(), OS
);
2088 void TypePrinter::printHLSLAttributedResourceBefore(
2089 const HLSLAttributedResourceType
*T
, raw_ostream
&OS
) {
2090 printBefore(T
->getWrappedType(), OS
);
2093 void TypePrinter::printHLSLAttributedResourceAfter(
2094 const HLSLAttributedResourceType
*T
, raw_ostream
&OS
) {
2095 printAfter(T
->getWrappedType(), OS
);
2096 const HLSLAttributedResourceType::Attributes
&Attrs
= T
->getAttrs();
2097 OS
<< " [[hlsl::resource_class("
2098 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs
.ResourceClass
)
2101 OS
<< " [[hlsl::is_rov]]";
2102 if (Attrs
.RawBuffer
)
2103 OS
<< " [[hlsl::raw_buffer]]";
2105 QualType ContainedTy
= T
->getContainedType();
2106 if (!ContainedTy
.isNull()) {
2107 OS
<< " [[hlsl::contained_type(";
2108 printBefore(ContainedTy
, OS
);
2109 printAfter(ContainedTy
, OS
);
2114 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType
*T
,
2116 OS
<< T
->getDecl()->getName();
2117 spaceBeforePlaceHolder(OS
);
2120 void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType
*T
,
2123 void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType
*T
,
2125 OS
<< T
->getDecl()->getName();
2126 if (!T
->qual_empty()) {
2127 bool isFirst
= true;
2129 for (const auto *I
: T
->quals()) {
2139 spaceBeforePlaceHolder(OS
);
2142 void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType
*T
,
2145 void TypePrinter::printObjCObjectBefore(const ObjCObjectType
*T
,
2147 if (T
->qual_empty() && T
->isUnspecializedAsWritten() &&
2148 !T
->isKindOfTypeAsWritten())
2149 return printBefore(T
->getBaseType(), OS
);
2151 if (T
->isKindOfTypeAsWritten())
2154 print(T
->getBaseType(), OS
, StringRef());
2156 if (T
->isSpecializedAsWritten()) {
2157 bool isFirst
= true;
2159 for (auto typeArg
: T
->getTypeArgsAsWritten()) {
2165 print(typeArg
, OS
, StringRef());
2170 if (!T
->qual_empty()) {
2171 bool isFirst
= true;
2173 for (const auto *I
: T
->quals()) {
2183 spaceBeforePlaceHolder(OS
);
2186 void TypePrinter::printObjCObjectAfter(const ObjCObjectType
*T
,
2188 if (T
->qual_empty() && T
->isUnspecializedAsWritten() &&
2189 !T
->isKindOfTypeAsWritten())
2190 return printAfter(T
->getBaseType(), OS
);
2193 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType
*T
,
2195 printBefore(T
->getPointeeType(), OS
);
2197 // If we need to print the pointer, print it now.
2198 if (!T
->isObjCIdType() && !T
->isObjCQualifiedIdType() &&
2199 !T
->isObjCClassType() && !T
->isObjCQualifiedClassType()) {
2200 if (HasEmptyPlaceHolder
)
2206 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType
*T
,
2210 const TemplateArgument
&getArgument(const TemplateArgument
&A
) { return A
; }
2212 static const TemplateArgument
&getArgument(const TemplateArgumentLoc
&A
) {
2213 return A
.getArgument();
2216 static void printArgument(const TemplateArgument
&A
, const PrintingPolicy
&PP
,
2217 llvm::raw_ostream
&OS
, bool IncludeType
) {
2218 A
.print(PP
, OS
, IncludeType
);
2221 static void printArgument(const TemplateArgumentLoc
&A
,
2222 const PrintingPolicy
&PP
, llvm::raw_ostream
&OS
,
2224 const TemplateArgument::ArgKind
&Kind
= A
.getArgument().getKind();
2225 if (Kind
== TemplateArgument::ArgKind::Type
)
2226 return A
.getTypeSourceInfo()->getType().print(OS
, PP
);
2227 return A
.getArgument().print(PP
, OS
, IncludeType
);
2230 static bool isSubstitutedTemplateArgument(ASTContext
&Ctx
, TemplateArgument Arg
,
2231 TemplateArgument Pattern
,
2232 ArrayRef
<TemplateArgument
> Args
,
2235 static bool isSubstitutedType(ASTContext
&Ctx
, QualType T
, QualType Pattern
,
2236 ArrayRef
<TemplateArgument
> Args
, unsigned Depth
) {
2237 if (Ctx
.hasSameType(T
, Pattern
))
2240 // A type parameter matches its argument.
2241 if (auto *TTPT
= Pattern
->getAs
<TemplateTypeParmType
>()) {
2242 if (TTPT
->getDepth() == Depth
&& TTPT
->getIndex() < Args
.size() &&
2243 Args
[TTPT
->getIndex()].getKind() == TemplateArgument::Type
) {
2244 QualType SubstArg
= Ctx
.getQualifiedType(
2245 Args
[TTPT
->getIndex()].getAsType(), Pattern
.getQualifiers());
2246 return Ctx
.hasSameType(SubstArg
, T
);
2251 // FIXME: Recurse into array types.
2253 // All other cases will need the types to be identically qualified.
2254 Qualifiers TQual
, PatQual
;
2255 T
= Ctx
.getUnqualifiedArrayType(T
, TQual
);
2256 Pattern
= Ctx
.getUnqualifiedArrayType(Pattern
, PatQual
);
2257 if (TQual
!= PatQual
)
2260 // Recurse into pointer-like types.
2262 QualType TPointee
= T
->getPointeeType();
2263 QualType PPointee
= Pattern
->getPointeeType();
2264 if (!TPointee
.isNull() && !PPointee
.isNull())
2265 return T
->getTypeClass() == Pattern
->getTypeClass() &&
2266 isSubstitutedType(Ctx
, TPointee
, PPointee
, Args
, Depth
);
2269 // Recurse into template specialization types.
2271 Pattern
.getCanonicalType()->getAs
<TemplateSpecializationType
>()) {
2272 TemplateName Template
;
2273 ArrayRef
<TemplateArgument
> TemplateArgs
;
2274 if (auto *TTST
= T
->getAs
<TemplateSpecializationType
>()) {
2275 Template
= TTST
->getTemplateName();
2276 TemplateArgs
= TTST
->template_arguments();
2277 } else if (auto *CTSD
= dyn_cast_or_null
<ClassTemplateSpecializationDecl
>(
2278 T
->getAsCXXRecordDecl())) {
2279 Template
= TemplateName(CTSD
->getSpecializedTemplate());
2280 TemplateArgs
= CTSD
->getTemplateArgs().asArray();
2285 if (!isSubstitutedTemplateArgument(Ctx
, Template
, PTST
->getTemplateName(),
2288 if (TemplateArgs
.size() != PTST
->template_arguments().size())
2290 for (unsigned I
= 0, N
= TemplateArgs
.size(); I
!= N
; ++I
)
2291 if (!isSubstitutedTemplateArgument(
2292 Ctx
, TemplateArgs
[I
], PTST
->template_arguments()[I
], Args
, Depth
))
2297 // FIXME: Handle more cases.
2301 /// Evaluates the expression template argument 'Pattern' and returns true
2302 /// if 'Arg' evaluates to the same result.
2303 static bool templateArgumentExpressionsEqual(ASTContext
const &Ctx
,
2304 TemplateArgument
const &Pattern
,
2305 TemplateArgument
const &Arg
) {
2306 if (Pattern
.getKind() != TemplateArgument::Expression
)
2309 // Can't evaluate value-dependent expressions so bail early
2310 Expr
const *pattern_expr
= Pattern
.getAsExpr();
2311 if (pattern_expr
->isValueDependent() ||
2312 !pattern_expr
->isIntegerConstantExpr(Ctx
))
2315 if (Arg
.getKind() == TemplateArgument::Integral
)
2316 return llvm::APSInt::isSameValue(pattern_expr
->EvaluateKnownConstInt(Ctx
),
2317 Arg
.getAsIntegral());
2319 if (Arg
.getKind() == TemplateArgument::Expression
) {
2320 Expr
const *args_expr
= Arg
.getAsExpr();
2321 if (args_expr
->isValueDependent() || !args_expr
->isIntegerConstantExpr(Ctx
))
2324 return llvm::APSInt::isSameValue(args_expr
->EvaluateKnownConstInt(Ctx
),
2325 pattern_expr
->EvaluateKnownConstInt(Ctx
));
2331 static bool isSubstitutedTemplateArgument(ASTContext
&Ctx
, TemplateArgument Arg
,
2332 TemplateArgument Pattern
,
2333 ArrayRef
<TemplateArgument
> Args
,
2335 Arg
= Ctx
.getCanonicalTemplateArgument(Arg
);
2336 Pattern
= Ctx
.getCanonicalTemplateArgument(Pattern
);
2337 if (Arg
.structurallyEquals(Pattern
))
2340 if (Pattern
.getKind() == TemplateArgument::Expression
) {
2342 dyn_cast
<DeclRefExpr
>(Pattern
.getAsExpr()->IgnoreParenImpCasts())) {
2343 if (auto *NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(DRE
->getDecl()))
2344 return NTTP
->getDepth() == Depth
&& Args
.size() > NTTP
->getIndex() &&
2345 Args
[NTTP
->getIndex()].structurallyEquals(Arg
);
2349 if (templateArgumentExpressionsEqual(Ctx
, Pattern
, Arg
))
2352 if (Arg
.getKind() != Pattern
.getKind())
2355 if (Arg
.getKind() == TemplateArgument::Type
)
2356 return isSubstitutedType(Ctx
, Arg
.getAsType(), Pattern
.getAsType(), Args
,
2359 if (Arg
.getKind() == TemplateArgument::Template
) {
2360 TemplateDecl
*PatTD
= Pattern
.getAsTemplate().getAsTemplateDecl();
2361 if (auto *TTPD
= dyn_cast_or_null
<TemplateTemplateParmDecl
>(PatTD
))
2362 return TTPD
->getDepth() == Depth
&& Args
.size() > TTPD
->getIndex() &&
2363 Ctx
.getCanonicalTemplateArgument(Args
[TTPD
->getIndex()])
2364 .structurallyEquals(Arg
);
2367 // FIXME: Handle more cases.
2371 bool clang::isSubstitutedDefaultArgument(ASTContext
&Ctx
, TemplateArgument Arg
,
2372 const NamedDecl
*Param
,
2373 ArrayRef
<TemplateArgument
> Args
,
2375 // An empty pack is equivalent to not providing a pack argument.
2376 if (Arg
.getKind() == TemplateArgument::Pack
&& Arg
.pack_size() == 0)
2379 if (auto *TTPD
= dyn_cast
<TemplateTypeParmDecl
>(Param
)) {
2380 return TTPD
->hasDefaultArgument() &&
2381 isSubstitutedTemplateArgument(
2382 Ctx
, Arg
, TTPD
->getDefaultArgument().getArgument(), Args
, Depth
);
2383 } else if (auto *TTPD
= dyn_cast
<TemplateTemplateParmDecl
>(Param
)) {
2384 return TTPD
->hasDefaultArgument() &&
2385 isSubstitutedTemplateArgument(
2386 Ctx
, Arg
, TTPD
->getDefaultArgument().getArgument(), Args
, Depth
);
2387 } else if (auto *NTTPD
= dyn_cast
<NonTypeTemplateParmDecl
>(Param
)) {
2388 return NTTPD
->hasDefaultArgument() &&
2389 isSubstitutedTemplateArgument(
2390 Ctx
, Arg
, NTTPD
->getDefaultArgument().getArgument(), Args
,
2396 template <typename TA
>
2398 printTo(raw_ostream
&OS
, ArrayRef
<TA
> Args
, const PrintingPolicy
&Policy
,
2399 const TemplateParameterList
*TPL
, bool IsPack
, unsigned ParmIndex
) {
2400 // Drop trailing template arguments that match default arguments.
2401 if (TPL
&& Policy
.SuppressDefaultTemplateArgs
&&
2402 !Policy
.PrintCanonicalTypes
&& !Args
.empty() && !IsPack
&&
2403 Args
.size() <= TPL
->size()) {
2404 llvm::SmallVector
<TemplateArgument
, 8> OrigArgs
;
2405 for (const TA
&A
: Args
)
2406 OrigArgs
.push_back(getArgument(A
));
2407 while (!Args
.empty() && getArgument(Args
.back()).getIsDefaulted())
2408 Args
= Args
.drop_back();
2411 const char *Comma
= Policy
.MSVCFormatting
? "," : ", ";
2415 bool NeedSpace
= false;
2416 bool FirstArg
= true;
2417 for (const auto &Arg
: Args
) {
2418 // Print the argument into a string.
2419 SmallString
<128> Buf
;
2420 llvm::raw_svector_ostream
ArgOS(Buf
);
2421 const TemplateArgument
&Argument
= getArgument(Arg
);
2422 if (Argument
.getKind() == TemplateArgument::Pack
) {
2423 if (Argument
.pack_size() && !FirstArg
)
2425 printTo(ArgOS
, Argument
.getPackAsArray(), Policy
, TPL
,
2426 /*IsPack*/ true, ParmIndex
);
2430 // Tries to print the argument with location info if exists.
2431 printArgument(Arg
, Policy
, ArgOS
,
2432 TemplateParameterList::shouldIncludeTypeForArgument(
2433 Policy
, TPL
, ParmIndex
));
2435 StringRef ArgString
= ArgOS
.str();
2437 // If this is the first argument and its string representation
2438 // begins with the global scope specifier ('::foo'), add a space
2439 // to avoid printing the diagraph '<:'.
2440 if (FirstArg
&& ArgString
.starts_with(":"))
2445 // If the last character of our string is '>', add another space to
2446 // keep the two '>''s separate tokens.
2447 if (!ArgString
.empty()) {
2448 NeedSpace
= Policy
.SplitTemplateClosers
&& ArgString
.back() == '>';
2452 // Use same template parameter for all elements of Pack
2464 void clang::printTemplateArgumentList(raw_ostream
&OS
,
2465 const TemplateArgumentListInfo
&Args
,
2466 const PrintingPolicy
&Policy
,
2467 const TemplateParameterList
*TPL
) {
2468 printTemplateArgumentList(OS
, Args
.arguments(), Policy
, TPL
);
2471 void clang::printTemplateArgumentList(raw_ostream
&OS
,
2472 ArrayRef
<TemplateArgument
> Args
,
2473 const PrintingPolicy
&Policy
,
2474 const TemplateParameterList
*TPL
) {
2475 printTo(OS
, Args
, Policy
, TPL
, /*isPack*/ false, /*parmIndex*/ 0);
2478 void clang::printTemplateArgumentList(raw_ostream
&OS
,
2479 ArrayRef
<TemplateArgumentLoc
> Args
,
2480 const PrintingPolicy
&Policy
,
2481 const TemplateParameterList
*TPL
) {
2482 printTo(OS
, Args
, Policy
, TPL
, /*isPack*/ false, /*parmIndex*/ 0);
2485 std::string
Qualifiers::getAsString() const {
2487 return getAsString(PrintingPolicy(LO
));
2490 // Appends qualifiers to the given string, separated by spaces. Will
2491 // prefix a space if the string is non-empty. Will not append a final
2493 std::string
Qualifiers::getAsString(const PrintingPolicy
&Policy
) const {
2494 SmallString
<64> Buf
;
2495 llvm::raw_svector_ostream
StrOS(Buf
);
2496 print(StrOS
, Policy
);
2497 return std::string(StrOS
.str());
2500 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy
&Policy
) const {
2501 if (getCVRQualifiers())
2504 if (getAddressSpace() != LangAS::Default
)
2507 if (getObjCGCAttr())
2510 if (Qualifiers::ObjCLifetime lifetime
= getObjCLifetime())
2511 if (!(lifetime
== Qualifiers::OCL_Strong
&& Policy
.SuppressStrongLifetime
))
2517 std::string
Qualifiers::getAddrSpaceAsString(LangAS AS
) {
2519 case LangAS::Default
:
2521 case LangAS::opencl_global
:
2522 case LangAS::sycl_global
:
2524 case LangAS::opencl_local
:
2525 case LangAS::sycl_local
:
2527 case LangAS::opencl_private
:
2528 case LangAS::sycl_private
:
2530 case LangAS::opencl_constant
:
2531 return "__constant";
2532 case LangAS::opencl_generic
:
2534 case LangAS::opencl_global_device
:
2535 case LangAS::sycl_global_device
:
2536 return "__global_device";
2537 case LangAS::opencl_global_host
:
2538 case LangAS::sycl_global_host
:
2539 return "__global_host";
2540 case LangAS::cuda_device
:
2541 return "__device__";
2542 case LangAS::cuda_constant
:
2543 return "__constant__";
2544 case LangAS::cuda_shared
:
2545 return "__shared__";
2546 case LangAS::ptr32_sptr
:
2547 return "__sptr __ptr32";
2548 case LangAS::ptr32_uptr
:
2549 return "__uptr __ptr32";
2552 case LangAS::wasm_funcref
:
2554 case LangAS::hlsl_groupshared
:
2555 return "groupshared";
2557 return std::to_string(toTargetAddressSpace(AS
));
2561 // Appends qualifiers to the given string, separated by spaces. Will
2562 // prefix a space if the string is non-empty. Will not append a final
2564 void Qualifiers::print(raw_ostream
&OS
, const PrintingPolicy
& Policy
,
2565 bool appendSpaceIfNonEmpty
) const {
2566 bool addSpace
= false;
2568 unsigned quals
= getCVRQualifiers();
2570 AppendTypeQualList(OS
, quals
, Policy
.Restrict
);
2573 if (hasUnaligned()) {
2576 OS
<< "__unaligned";
2579 auto ASStr
= getAddrSpaceAsString(getAddressSpace());
2580 if (!ASStr
.empty()) {
2584 // Wrap target address space into an attribute syntax
2585 if (isTargetAddressSpace(getAddressSpace()))
2586 OS
<< "__attribute__((address_space(" << ASStr
<< ")))";
2591 if (Qualifiers::GC gc
= getObjCGCAttr()) {
2595 if (gc
== Qualifiers::Weak
)
2600 if (Qualifiers::ObjCLifetime lifetime
= getObjCLifetime()) {
2601 if (!(lifetime
== Qualifiers::OCL_Strong
&& Policy
.SuppressStrongLifetime
)){
2608 case Qualifiers::OCL_None
: llvm_unreachable("none but true");
2609 case Qualifiers::OCL_ExplicitNone
: OS
<< "__unsafe_unretained"; break;
2610 case Qualifiers::OCL_Strong
:
2611 if (!Policy
.SuppressStrongLifetime
)
2615 case Qualifiers::OCL_Weak
: OS
<< "__weak"; break;
2616 case Qualifiers::OCL_Autoreleasing
: OS
<< "__autoreleasing"; break;
2620 if (appendSpaceIfNonEmpty
&& addSpace
)
2624 std::string
QualType::getAsString() const {
2625 return getAsString(split(), LangOptions());
2628 std::string
QualType::getAsString(const PrintingPolicy
&Policy
) const {
2630 getAsStringInternal(S
, Policy
);
2634 std::string
QualType::getAsString(const Type
*ty
, Qualifiers qs
,
2635 const PrintingPolicy
&Policy
) {
2637 getAsStringInternal(ty
, qs
, buffer
, Policy
);
2641 void QualType::print(raw_ostream
&OS
, const PrintingPolicy
&Policy
,
2642 const Twine
&PlaceHolder
, unsigned Indentation
) const {
2643 print(splitAccordingToPolicy(*this, Policy
), OS
, Policy
, PlaceHolder
,
2647 void QualType::print(const Type
*ty
, Qualifiers qs
,
2648 raw_ostream
&OS
, const PrintingPolicy
&policy
,
2649 const Twine
&PlaceHolder
, unsigned Indentation
) {
2650 SmallString
<128> PHBuf
;
2651 StringRef PH
= PlaceHolder
.toStringRef(PHBuf
);
2653 TypePrinter(policy
, Indentation
).print(ty
, qs
, OS
, PH
);
2656 void QualType::getAsStringInternal(std::string
&Str
,
2657 const PrintingPolicy
&Policy
) const {
2658 return getAsStringInternal(splitAccordingToPolicy(*this, Policy
), Str
,
2662 void QualType::getAsStringInternal(const Type
*ty
, Qualifiers qs
,
2663 std::string
&buffer
,
2664 const PrintingPolicy
&policy
) {
2665 SmallString
<256> Buf
;
2666 llvm::raw_svector_ostream
StrOS(Buf
);
2667 TypePrinter(policy
).print(ty
, qs
, StrOS
, buffer
);
2668 std::string str
= std::string(StrOS
.str());
2672 raw_ostream
&clang::operator<<(raw_ostream
&OS
, QualType QT
) {
2673 SplitQualType S
= QT
.split();
2674 TypePrinter(LangOptions()).print(S
.Ty
, S
.Quals
, OS
, /*PlaceHolder=*/"");