[LangRef] Update the position of some parameters in the vp intrinsic of abs/cttz...
[llvm-project.git] / clang / lib / AST / TypePrinter.cpp
blob7caebfb061a50b5bf412b80469551bfaa79d99df
1 //===- TypePrinter.cpp - Pretty-Print Clang Types -------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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"
44 #include <cassert>
45 #include <string>
47 using namespace clang;
49 namespace {
51 /// RAII object that enables printing of the ARC __strong lifetime
52 /// qualifier.
53 class IncludeStrongLifetimeRAII {
54 PrintingPolicy &Policy;
55 bool Old;
57 public:
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;
69 bool Old;
71 public:
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;
82 bool Old;
84 public:
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;
96 bool SuppressScope;
98 public:
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;
112 class TypePrinter {
113 PrintingPolicy Policy;
114 unsigned Indentation;
115 bool HasEmptyPlaceHolder = false;
116 bool InsideCCAttribute = false;
118 public:
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,
130 bool FullyQualify);
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"
144 private:
145 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
146 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
149 } // namespace
151 static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
152 bool HasRestrictKeyword) {
153 bool appendSpace = false;
154 if (TypeQuals & Qualifiers::Const) {
155 OS << "const";
156 appendSpace = true;
158 if (TypeQuals & Qualifiers::Volatile) {
159 if (appendSpace) OS << ' ';
160 OS << "volatile";
161 appendSpace = true;
163 if (TypeQuals & Qualifiers::Restrict) {
164 if (appendSpace) OS << ' ';
165 if (HasRestrictKeyword) {
166 OS << "restrict";
167 } else {
168 OS << "__restrict";
173 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
174 if (!HasEmptyPlaceHolder)
175 OS << ' ';
178 static SplitQualType splitAccordingToPolicy(QualType QT,
179 const PrintingPolicy &Policy) {
180 if (Policy.PrintCanonicalTypes)
181 QT = QT.getCanonicalType();
182 return QT.split();
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) {
192 if (!T) {
193 OS << "NULL TYPE";
194 return;
197 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
199 printBefore(T, Quals, OS);
200 OS << PlaceHolder;
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();
220 switch (TC) {
221 case Type::Auto:
222 case Type::Builtin:
223 case Type::Complex:
224 case Type::UnresolvedUsing:
225 case Type::Using:
226 case Type::Typedef:
227 case Type::TypeOfExpr:
228 case Type::TypeOf:
229 case Type::Decltype:
230 case Type::UnaryTransform:
231 case Type::Record:
232 case Type::Enum:
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:
244 case Type::Atomic:
245 case Type::Pipe:
246 case Type::BitInt:
247 case Type::DependentBitInt:
248 case Type::BTFTagAttributed:
249 case Type::HLSLAttributedResource:
250 CanPrefixQualifiers = true;
251 break;
253 case Type::ObjCObjectPointer:
254 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
255 T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
256 break;
258 case Type::VariableArray:
259 case Type::DependentSizedArray:
260 NeedARCStrongQualifier = true;
261 [[fallthrough]];
263 case Type::ConstantArray:
264 case Type::IncompleteArray:
265 return canPrefixQualifiers(
266 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
267 NeedARCStrongQualifier);
269 case Type::Adjusted:
270 case Type::Decayed:
271 case Type::ArrayParameter:
272 case Type::Pointer:
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:
280 case Type::Vector:
281 case Type::ExtVector:
282 case Type::ConstantMatrix:
283 case Type::DependentSizedMatrix:
284 case Type::FunctionProto:
285 case Type::FunctionNoProto:
286 case Type::Paren:
287 case Type::PackExpansion:
288 case Type::SubstTemplateTypeParm:
289 case Type::MacroQualified:
290 case Type::CountAttributed:
291 CanPrefixQualifiers = false;
292 break;
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;
299 break;
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
315 // at this level.
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())
327 return;
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);
341 } else {
342 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
346 bool hasAfterQuals = false;
347 if (!CanPrefixQualifiers && !Quals.empty()) {
348 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
349 if (hasAfterQuals)
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); \
357 break;
358 #include "clang/AST/TypeNodes.inc"
361 if (hasAfterQuals) {
362 if (NeedARCStrongQualifier) {
363 IncludeStrongLifetimeRAII Strong(Policy);
364 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
365 } else {
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); \
383 break;
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) {
396 OS << "_Complex ";
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()))
411 OS << '(';
412 OS << '*';
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()))
421 OS << ')';
422 printAfter(T->getPointeeType(), OS);
425 void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
426 raw_ostream &OS) {
427 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
428 printBefore(T->getPointeeType(), OS);
429 OS << '^';
432 void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
433 raw_ostream &OS) {
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());
443 return T;
446 void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
447 raw_ostream &OS) {
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))
455 OS << '(';
456 OS << '&';
459 void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
460 raw_ostream &OS) {
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))
467 OS << ')';
468 printAfter(Inner, OS);
471 void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
472 raw_ostream &OS) {
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))
480 OS << '(';
481 OS << "&&";
484 void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
485 raw_ostream &OS) {
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))
492 OS << ')';
493 printAfter(Inner, OS);
496 void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
497 raw_ostream &OS) {
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()))
504 OS << '(';
506 PrintingPolicy InnerPolicy(Policy);
507 InnerPolicy.IncludeTagDefinition = false;
508 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
510 OS << "::*";
513 void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
514 raw_ostream &OS) {
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()))
520 OS << ')';
521 printAfter(T->getPointeeType(), OS);
524 void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
525 raw_ostream &OS) {
526 IncludeStrongLifetimeRAII Strong(Policy);
527 printBefore(T->getElementType(), OS);
530 void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
531 raw_ostream &OS) {
532 OS << '[';
533 if (T->getIndexTypeQualifiers().hasQualifiers()) {
534 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
535 Policy.Restrict);
536 OS << ' ';
539 if (T->getSizeModifier() == ArraySizeModifier::Static)
540 OS << "static ";
542 OS << T->getZExtSize() << ']';
543 printAfter(T->getElementType(), OS);
546 void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
547 raw_ostream &OS) {
548 IncludeStrongLifetimeRAII Strong(Policy);
549 printBefore(T->getElementType(), OS);
552 void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
553 raw_ostream &OS) {
554 OS << "[]";
555 printAfter(T->getElementType(), OS);
558 void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
559 raw_ostream &OS) {
560 IncludeStrongLifetimeRAII Strong(Policy);
561 printBefore(T->getElementType(), OS);
564 void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
565 raw_ostream &OS) {
566 OS << '[';
567 if (T->getIndexTypeQualifiers().hasQualifiers()) {
568 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
569 OS << ' ';
572 if (T->getSizeModifier() == ArraySizeModifier::Static)
573 OS << "static ";
574 else if (T->getSizeModifier() == ArraySizeModifier::Star)
575 OS << '*';
577 if (T->getSizeExpr())
578 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
579 OS << ']';
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
586 // invisible.
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,
600 raw_ostream &OS) {
601 printConstantArrayAfter(T, OS);
604 void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
605 raw_ostream &OS) {
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,
615 raw_ostream &OS) {
616 IncludeStrongLifetimeRAII Strong(Policy);
617 printBefore(T->getElementType(), OS);
620 void TypePrinter::printDependentSizedArrayAfter(
621 const DependentSizedArrayType *T,
622 raw_ostream &OS) {
623 OS << '[';
624 if (T->getSizeExpr())
625 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
626 OS << ']';
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);
640 OS << ")))";
641 printAfter(T->getPointeeType(), OS);
644 void TypePrinter::printDependentSizedExtVectorBefore(
645 const DependentSizedExtVectorType *T,
646 raw_ostream &OS) {
647 if (Policy.UseHLSLTypes)
648 OS << "vector<";
649 printBefore(T->getElementType(), OS);
652 void TypePrinter::printDependentSizedExtVectorAfter(
653 const DependentSizedExtVectorType *T,
654 raw_ostream &OS) {
655 if (Policy.UseHLSLTypes) {
656 OS << ", ";
657 if (T->getSizeExpr())
658 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
659 OS << ">";
660 } else {
661 OS << " __attribute__((ext_vector_type(";
662 if (T->getSizeExpr())
663 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
664 OS << ")))";
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 ";
673 break;
674 case VectorKind::AltiVecBool:
675 OS << "__vector __bool ";
676 printBefore(T->getElementType(), OS);
677 break;
678 case VectorKind::AltiVecVector:
679 OS << "__vector ";
680 printBefore(T->getElementType(), OS);
681 break;
682 case VectorKind::Neon:
683 OS << "__attribute__((neon_vector_type("
684 << T->getNumElements() << "))) ";
685 printBefore(T->getElementType(), OS);
686 break;
687 case VectorKind::NeonPoly:
688 OS << "__attribute__((neon_polyvector_type(" <<
689 T->getNumElements() << "))) ";
690 printBefore(T->getElementType(), OS);
691 break;
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()
697 << " * sizeof(";
698 print(T->getElementType(), OS, StringRef());
699 OS << ")))) ";
700 printBefore(T->getElementType(), OS);
701 break;
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;
713 else
714 OS << T->getNumElements();
716 OS << " * sizeof(";
717 print(T->getElementType(), OS, StringRef());
718 // Multiply by 8 for the number of bits.
719 OS << ") * 8))) ";
720 printBefore(T->getElementType(), OS);
721 break;
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();
733 OS << " * sizeof(";
734 print(T->getElementType(), OS, StringRef());
735 // Multiply by 8 for the number of bits.
736 OS << ") * 8))) ";
737 printBefore(T->getElementType(), OS);
738 break;
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 ";
751 break;
752 case VectorKind::AltiVecBool:
753 OS << "__vector __bool ";
754 printBefore(T->getElementType(), OS);
755 break;
756 case VectorKind::AltiVecVector:
757 OS << "__vector ";
758 printBefore(T->getElementType(), OS);
759 break;
760 case VectorKind::Neon:
761 OS << "__attribute__((neon_vector_type(";
762 if (T->getSizeExpr())
763 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
764 OS << "))) ";
765 printBefore(T->getElementType(), OS);
766 break;
767 case VectorKind::NeonPoly:
768 OS << "__attribute__((neon_polyvector_type(";
769 if (T->getSizeExpr())
770 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
771 OS << "))) ";
772 printBefore(T->getElementType(), OS);
773 break;
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);
780 OS << " * sizeof(";
781 print(T->getElementType(), OS, StringRef());
782 OS << ")))) ";
783 printBefore(T->getElementType(), OS);
784 break;
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.
796 OS << " * 8";
797 OS << " * sizeof(";
798 print(T->getElementType(), OS, StringRef());
799 // Multiply by 8 for the number of bits.
800 OS << ") * 8";
802 OS << "))) ";
803 printBefore(T->getElementType(), OS);
804 break;
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);
815 OS << " * sizeof(";
816 print(T->getElementType(), OS, StringRef());
817 // Multiply by 8 for the number of bits.
818 OS << ") * 8";
820 OS << "))) ";
821 printBefore(T->getElementType(), OS);
822 break;
826 void TypePrinter::printDependentVectorAfter(
827 const DependentVectorType *T, raw_ostream &OS) {
828 printAfter(T->getElementType(), OS);
831 void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
832 raw_ostream &OS) {
833 if (Policy.UseHLSLTypes)
834 OS << "vector<";
835 printBefore(T->getElementType(), OS);
838 void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
839 printAfter(T->getElementType(), OS);
841 if (Policy.UseHLSLTypes) {
842 OS << ", ";
843 OS << T->getNumElements();
844 OS << ">";
845 } else {
846 OS << " __attribute__((ext_vector_type(";
847 OS << T->getNumElements();
848 OS << ")))";
852 void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
853 raw_ostream &OS) {
854 printBefore(T->getElementType(), OS);
855 OS << " __attribute__((matrix_type(";
856 OS << T->getNumRows() << ", " << T->getNumColumns();
857 OS << ")))";
860 void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
861 raw_ostream &OS) {
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);
872 OS << ", ";
873 if (T->getColumnExpr()) {
874 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
876 OS << ")))";
879 void TypePrinter::printDependentSizedMatrixAfter(
880 const DependentSizedMatrixType *T, raw_ostream &OS) {
881 printAfter(T->getElementType(), OS);
884 void
885 FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
886 const PrintingPolicy &Policy)
887 const {
888 if (hasDynamicExceptionSpec()) {
889 OS << " throw(";
890 if (getExceptionSpecType() == EST_MSAny)
891 OS << "...";
892 else
893 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
894 if (I)
895 OS << ", ";
897 OS << getExceptionType(I).stream(Policy);
899 OS << ')';
900 } else if (EST_NoThrow == getExceptionSpecType()) {
901 OS << " __attribute__((nothrow))";
902 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
903 OS << " noexcept";
904 // FIXME:Is it useful to print out the expression for a non-dependent
905 // noexcept specification?
906 if (isComputedNoexcept(getExceptionSpecType())) {
907 OS << '(';
908 if (getNoexceptExpr())
909 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
910 OS << ')';
915 void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
916 raw_ostream &OS) {
917 if (T->hasTrailingReturn()) {
918 OS << "auto ";
919 if (!HasEmptyPlaceHolder)
920 OS << '(';
921 } else {
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())
926 OS << '(';
930 StringRef clang::getParameterABISpelling(ParameterABI ABI) {
931 switch (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:
943 return "out";
944 case ParameterABI::HLSLInOut:
945 return "inout";
947 llvm_unreachable("bad parameter ABI kind");
950 void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
951 raw_ostream &OS) {
952 // If needed for precedence reasons, wrap the inner part in grouping parens.
953 if (!HasEmptyPlaceHolder)
954 OS << ')';
955 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
957 OS << '(';
959 ParamPolicyRAII ParamPolicy(Policy);
960 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
961 if (i) OS << ", ";
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());
976 continue;
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())
987 OS << ", ";
988 OS << "...";
989 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
990 // Do not emit int() if we have a proto, emit 'int(void)'.
991 OS << "void";
994 OS << ')';
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()) {
1026 case RQ_None:
1027 break;
1029 case RQ_LValue:
1030 OS << " &";
1031 break;
1033 case RQ_RValue:
1034 OS << " &&";
1035 break;
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()) {
1043 OS << '(';
1044 E->printPretty(OS, nullptr, Policy);
1045 OS << ')';
1047 OS << "))";
1050 if (T->hasTrailingReturn()) {
1051 OS << " -> ";
1052 print(T->getReturnType(), OS, StringRef());
1053 } else
1054 printAfter(T->getReturnType(), OS);
1057 void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1058 raw_ostream &OS) {
1059 if (!InsideCCAttribute) {
1060 switch (Info.getCC()) {
1061 case CC_C:
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.
1069 break;
1070 case CC_X86StdCall:
1071 OS << " __attribute__((stdcall))";
1072 break;
1073 case CC_X86FastCall:
1074 OS << " __attribute__((fastcall))";
1075 break;
1076 case CC_X86ThisCall:
1077 OS << " __attribute__((thiscall))";
1078 break;
1079 case CC_X86VectorCall:
1080 OS << " __attribute__((vectorcall))";
1081 break;
1082 case CC_X86Pascal:
1083 OS << " __attribute__((pascal))";
1084 break;
1085 case CC_AAPCS:
1086 OS << " __attribute__((pcs(\"aapcs\")))";
1087 break;
1088 case CC_AAPCS_VFP:
1089 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1090 break;
1091 case CC_AArch64VectorCall:
1092 OS << "__attribute__((aarch64_vector_pcs))";
1093 break;
1094 case CC_AArch64SVEPCS:
1095 OS << "__attribute__((aarch64_sve_pcs))";
1096 break;
1097 case CC_AMDGPUKernelCall:
1098 OS << "__attribute__((amdgpu_kernel))";
1099 break;
1100 case CC_IntelOclBicc:
1101 OS << " __attribute__((intel_ocl_bicc))";
1102 break;
1103 case CC_Win64:
1104 OS << " __attribute__((ms_abi))";
1105 break;
1106 case CC_X86_64SysV:
1107 OS << " __attribute__((sysv_abi))";
1108 break;
1109 case CC_X86RegCall:
1110 OS << " __attribute__((regcall))";
1111 break;
1112 case CC_SpirFunction:
1113 case CC_OpenCLKernel:
1114 // Do nothing. These CCs are not available as attributes.
1115 break;
1116 case CC_Swift:
1117 OS << " __attribute__((swiftcall))";
1118 break;
1119 case CC_SwiftAsync:
1120 OS << "__attribute__((swiftasynccall))";
1121 break;
1122 case CC_PreserveMost:
1123 OS << " __attribute__((preserve_most))";
1124 break;
1125 case CC_PreserveAll:
1126 OS << " __attribute__((preserve_all))";
1127 break;
1128 case CC_M68kRTD:
1129 OS << " __attribute__((m68k_rtd))";
1130 break;
1131 case CC_PreserveNone:
1132 OS << " __attribute__((preserve_none))";
1133 break;
1134 case CC_RISCVVectorCall:
1135 OS << "__attribute__((riscv_vector_cc))";
1136 break;
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,
1156 raw_ostream &OS) {
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())
1161 OS << '(';
1164 void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1165 raw_ostream &OS) {
1166 // If needed for precedence reasons, wrap the inner part in grouping parens.
1167 if (!HasEmptyPlaceHolder)
1168 OS << ')';
1169 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1171 OS << "()";
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,
1190 raw_ostream &OS) {
1191 printTypeSpec(T->getDecl(), OS);
1194 void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1195 raw_ostream &OS) {}
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,
1217 raw_ostream &OS) {
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,
1227 raw_ostream &OS) {
1228 printAfter(T->getModifiedType(), OS);
1231 void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1233 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1234 raw_ostream &OS) {
1235 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1236 : "typeof ");
1237 if (T->getUnderlyingExpr())
1238 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1239 spaceBeforePlaceHolder(OS);
1242 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1243 raw_ostream &OS) {}
1245 void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1246 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1247 : "typeof(");
1248 print(T->getUnmodifiedType(), OS, StringRef());
1249 OS << ')';
1250 spaceBeforePlaceHolder(OS);
1253 void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1255 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1256 OS << "decltype(";
1257 if (T->getUnderlyingExpr())
1258 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1259 OS << ')';
1260 spaceBeforePlaceHolder(OS);
1263 void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1264 raw_ostream &OS) {
1265 if (T->hasSelectedType()) {
1266 OS << T->getSelectedType();
1267 } else {
1268 OS << T->getPattern() << "...[";
1269 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1270 OS << "]";
1272 spaceBeforePlaceHolder(OS);
1275 void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1276 raw_ostream &OS) {}
1278 void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1280 void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1281 raw_ostream &OS) {
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());
1291 OS << ')';
1292 spaceBeforePlaceHolder(OS);
1295 void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1296 raw_ostream &OS) {}
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);
1302 } else {
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();
1308 if (!Args.empty())
1309 printTemplateArgumentList(
1310 OS, Args, Policy,
1311 T->getTypeConstraintConcept()->getTemplateParameters());
1312 OS << ' ';
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);
1334 } else {
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);
1351 OS << "_Atomic(";
1352 print(T->getValueType(), OS, StringRef());
1353 OS << ')';
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())
1363 OS << "read_only ";
1364 else
1365 OS << "write_only ";
1366 OS << "pipe ";
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())
1375 OS << "unsigned ";
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,
1383 raw_ostream &OS) {
1384 if (T->isUnsigned())
1385 OS << "unsigned ";
1386 OS << "_BitInt(";
1387 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1388 OS << ")";
1389 spaceBeforePlaceHolder(OS);
1392 void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1393 raw_ostream &OS) {}
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())
1399 return;
1401 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1402 // which can also print names for function and method scopes.
1403 if (DC->isFunctionOrMethod())
1404 return;
1406 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1407 return;
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() << "::";
1424 else
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());
1434 OS << "::";
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() << "::";
1441 else
1442 return;
1443 } else {
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);
1454 return;
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();
1464 OS << ' ';
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();
1478 } else {
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()) {
1484 OS << "lambda";
1485 HasKindDecoration = true;
1486 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1487 OS << "anonymous";
1488 } else {
1489 OS << "unnamed";
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(
1500 D->getLocation());
1501 if (PLoc.isValid()) {
1502 OS << " at ";
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
1509 // path.
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
1525 // arguments.
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,
1534 TParams);
1535 else
1536 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1537 TParams);
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(),
1548 T->getDecl()))
1549 continue;
1550 // Find the outermost typedef or alias template.
1551 QualType T = PNA->getTypedefType();
1552 while (true) {
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,
1574 raw_ostream &OS) {
1575 TemplateTypeParmDecl *D = T->getDecl();
1576 if (D && D->isImplicit()) {
1577 if (auto *TC = D->getTypeConstraint()) {
1578 TC->print(OS, Policy);
1579 OS << ' ';
1581 OS << "auto";
1582 } else if (IdentifierInfo *Id = T->getIdentifier())
1583 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1584 : Id->getName());
1585 else
1586 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1588 spaceBeforePlaceHolder(OS);
1591 void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1592 raw_ostream &OS) {}
1594 void TypePrinter::printSubstTemplateTypeParmBefore(
1595 const SubstTemplateTypeParmType *T,
1596 raw_ostream &OS) {
1597 IncludeStrongLifetimeRAII Strong(Policy);
1598 printBefore(T->getReplacementType(), OS);
1601 void TypePrinter::printSubstTemplateTypeParmAfter(
1602 const SubstTemplateTypeParmType *T,
1603 raw_ostream &OS) {
1604 IncludeStrongLifetimeRAII Strong(Policy);
1605 printAfter(T->getReplacementType(), OS);
1608 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1609 const SubstTemplateTypeParmPackType *T,
1610 raw_ostream &OS) {
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);
1616 OS << ' ';
1618 OS << "auto";
1619 } else if (IdentifierInfo *Id = D->getIdentifier())
1620 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1621 : Id->getName());
1622 else
1623 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1625 spaceBeforePlaceHolder(OS);
1629 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1630 const SubstTemplateTypeParmPackType *T,
1631 raw_ostream &OS) {
1632 IncludeStrongLifetimeRAII Strong(Policy);
1635 void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1636 raw_ostream &OS, bool FullyQualify) {
1637 IncludeStrongLifetimeRAII Strong(Policy);
1639 TemplateDecl *TD =
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();
1647 } else {
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,
1659 raw_ostream &OS) {
1660 printTemplateId(T, OS, Policy.FullyQualifiedName);
1663 void TypePrinter::printTemplateSpecializationAfter(
1664 const TemplateSpecializationType *T,
1665 raw_ostream &OS) {}
1667 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1668 raw_ostream &OS) {
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,
1678 raw_ostream &OS) {}
1680 void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1681 raw_ostream &OS) {
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);
1690 return;
1693 if (Policy.SuppressElaboration) {
1694 printBefore(T->getNamedType(), OS);
1695 return;
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)
1703 OS << " ";
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;
1714 return;
1716 if (Qualifier)
1717 Qualifier->print(OS, Policy);
1720 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1721 printBefore(T->getNamedType(), OS);
1724 void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1725 raw_ostream &OS) {
1726 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1727 return;
1729 if (Policy.SuppressElaboration) {
1730 printAfter(T->getNamedType(), OS);
1731 return;
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);
1741 OS << '(';
1742 } else
1743 printBefore(T->getInnerType(), OS);
1746 void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1747 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1748 OS << ')';
1749 printAfter(T->getInnerType(), OS);
1750 } else
1751 printAfter(T->getInnerType(), OS);
1754 void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1755 raw_ostream &OS) {
1756 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1757 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1758 OS << " ";
1760 T->getQualifier()->print(OS, Policy);
1762 OS << T->getIdentifier()->getName();
1763 spaceBeforePlaceHolder(OS);
1766 void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1767 raw_ostream &OS) {}
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)
1775 OS << " ";
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,
1788 raw_ostream &OS) {
1789 printBefore(T->getPattern(), OS);
1792 void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1793 raw_ostream &OS) {
1794 printAfter(T->getPattern(), OS);
1795 OS << "...";
1798 static void printCountAttributedImpl(const CountAttributedType *T,
1799 raw_ostream &OS,
1800 const PrintingPolicy &Policy) {
1801 OS << ' ';
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(";
1808 else
1809 OS << "__counted_by(";
1810 if (T->getCountExpr())
1811 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1812 OS << ')';
1815 void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1816 raw_ostream &OS) {
1817 printBefore(T->desugar(), OS);
1818 if (!T->isArrayType())
1819 printCountAttributedImpl(T, OS, Policy);
1822 void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1823 raw_ostream &OS) {
1824 printAfter(T->desugar(), OS);
1825 if (T->isArrayType())
1826 printCountAttributedImpl(T, OS, Policy);
1829 void TypePrinter::printAttributedBefore(const AttributedType *T,
1830 raw_ostream &OS) {
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)
1839 OS << "__kindof ";
1841 if (T->getAttrKind() == attr::AddressSpace)
1842 printBefore(T->getEquivalentType(), OS);
1843 else
1844 printBefore(T->getModifiedType(), OS);
1846 if (T->isMSTypeSpec()) {
1847 switch (T->getAttrKind()) {
1848 default: return;
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())
1858 OS << "__funcref";
1860 // Print nullability type specifiers.
1861 if (T->getImmediateNullability()) {
1862 if (T->getAttrKind() == attr::TypeNonNull)
1863 OS << " _Nonnull";
1864 else if (T->getAttrKind() == attr::TypeNullable)
1865 OS << " _Nullable";
1866 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1867 OS << " _Null_unspecified";
1868 else if (T->getAttrKind() == attr::TypeNullableResult)
1869 OS << " _Nullable_result";
1870 else
1871 llvm_unreachable("unhandled nullability");
1872 spaceBeforePlaceHolder(OS);
1876 void TypePrinter::printAttributedAfter(const AttributedType *T,
1877 raw_ostream &OS) {
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())
1895 return;
1897 // Don't print the inert __unsafe_unretained attribute at all.
1898 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1899 return;
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())
1905 return;
1907 if (T->getAttrKind() == attr::LifetimeBound) {
1908 OS << " [[clang::lifetimebound]]";
1909 return;
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(); });
1916 OS << ")]]";
1917 return;
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
1922 // this twice.
1923 if (T->getAttrKind() == attr::AddressSpace)
1924 return;
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(...)]]";
1932 return;
1935 if (T->getAttrKind() == attr::ArmStreaming) {
1936 OS << "__arm_streaming";
1937 return;
1939 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1940 OS << "__arm_streaming_compatible";
1941 return;
1944 if (T->getAttrKind() == attr::SwiftAttr) {
1945 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
1946 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1947 << "\")))";
1949 return;
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:
1964 case attr::HLSLROV:
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.
1979 break;
1981 case attr::CountedBy:
1982 case attr::CountedByOrNull:
1983 case attr::SizedBy:
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:
1991 case attr::ObjCGC:
1992 case attr::ObjCInertUnsafeUnretained:
1993 case attr::ObjCKindOf:
1994 case attr::ObjCOwnership:
1995 case attr::Ptr32:
1996 case attr::Ptr64:
1997 case attr::SPtr:
1998 case attr::UPtr:
1999 case attr::AddressSpace:
2000 case attr::CmseNSCall:
2001 case attr::AnnotateType:
2002 case attr::WebAssemblyFuncref:
2003 case attr::ArmStreaming:
2004 case attr::ArmStreamingCompatible:
2005 case attr::ArmIn:
2006 case attr::ArmOut:
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";
2018 break;
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;
2034 case attr::Pcs: {
2035 OS << "pcs(";
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\"");
2041 OS << ')';
2042 break;
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";
2050 break;
2052 case attr::PreserveAll:
2053 OS << "preserve_all";
2054 break;
2055 case attr::M68kRTD:
2056 OS << "m68k_rtd";
2057 break;
2058 case attr::PreserveNone:
2059 OS << "preserve_none";
2060 break;
2061 case attr::RISCVVectorCC:
2062 OS << "riscv_vector_cc";
2063 break;
2064 case attr::NoDeref:
2065 OS << "noderef";
2066 break;
2067 case attr::AcquireHandle:
2068 OS << "acquire_handle";
2069 break;
2070 case attr::ArmMveStrictPolymorphism:
2071 OS << "__clang_arm_mve_strict_polymorphism";
2072 break;
2074 OS << "))";
2077 void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2078 raw_ostream &OS) {
2079 printBefore(T->getWrappedType(), OS);
2080 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2083 void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2084 raw_ostream &OS) {
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)
2099 << ")]]";
2100 if (Attrs.IsROV)
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);
2110 OS << ")]]";
2114 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2115 raw_ostream &OS) {
2116 OS << T->getDecl()->getName();
2117 spaceBeforePlaceHolder(OS);
2120 void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2121 raw_ostream &OS) {}
2123 void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2124 raw_ostream &OS) {
2125 OS << T->getDecl()->getName();
2126 if (!T->qual_empty()) {
2127 bool isFirst = true;
2128 OS << '<';
2129 for (const auto *I : T->quals()) {
2130 if (isFirst)
2131 isFirst = false;
2132 else
2133 OS << ',';
2134 OS << I->getName();
2136 OS << '>';
2139 spaceBeforePlaceHolder(OS);
2142 void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2143 raw_ostream &OS) {}
2145 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2146 raw_ostream &OS) {
2147 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2148 !T->isKindOfTypeAsWritten())
2149 return printBefore(T->getBaseType(), OS);
2151 if (T->isKindOfTypeAsWritten())
2152 OS << "__kindof ";
2154 print(T->getBaseType(), OS, StringRef());
2156 if (T->isSpecializedAsWritten()) {
2157 bool isFirst = true;
2158 OS << '<';
2159 for (auto typeArg : T->getTypeArgsAsWritten()) {
2160 if (isFirst)
2161 isFirst = false;
2162 else
2163 OS << ",";
2165 print(typeArg, OS, StringRef());
2167 OS << '>';
2170 if (!T->qual_empty()) {
2171 bool isFirst = true;
2172 OS << '<';
2173 for (const auto *I : T->quals()) {
2174 if (isFirst)
2175 isFirst = false;
2176 else
2177 OS << ',';
2178 OS << I->getName();
2180 OS << '>';
2183 spaceBeforePlaceHolder(OS);
2186 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2187 raw_ostream &OS) {
2188 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2189 !T->isKindOfTypeAsWritten())
2190 return printAfter(T->getBaseType(), OS);
2193 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2194 raw_ostream &OS) {
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)
2201 OS << ' ';
2202 OS << '*';
2206 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2207 raw_ostream &OS) {}
2209 static
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,
2223 bool IncludeType) {
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,
2233 unsigned Depth);
2235 static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern,
2236 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2237 if (Ctx.hasSameType(T, Pattern))
2238 return true;
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);
2248 return false;
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)
2258 return false;
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.
2270 if (auto *PTST =
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();
2281 } else {
2282 return false;
2285 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2286 Args, Depth))
2287 return false;
2288 if (TemplateArgs.size() != PTST->template_arguments().size())
2289 return false;
2290 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2291 if (!isSubstitutedTemplateArgument(
2292 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2293 return false;
2294 return true;
2297 // FIXME: Handle more cases.
2298 return false;
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)
2307 return false;
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))
2313 return false;
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))
2322 return false;
2324 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2325 pattern_expr->EvaluateKnownConstInt(Ctx));
2328 return false;
2331 static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2332 TemplateArgument Pattern,
2333 ArrayRef<TemplateArgument> Args,
2334 unsigned Depth) {
2335 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2336 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2337 if (Arg.structurallyEquals(Pattern))
2338 return true;
2340 if (Pattern.getKind() == TemplateArgument::Expression) {
2341 if (auto *DRE =
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))
2350 return true;
2352 if (Arg.getKind() != Pattern.getKind())
2353 return false;
2355 if (Arg.getKind() == TemplateArgument::Type)
2356 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2357 Depth);
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.
2368 return false;
2371 bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2372 const NamedDecl *Param,
2373 ArrayRef<TemplateArgument> Args,
2374 unsigned Depth) {
2375 // An empty pack is equivalent to not providing a pack argument.
2376 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2377 return true;
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,
2391 Depth);
2393 return false;
2396 template <typename TA>
2397 static void
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 ? "," : ", ";
2412 if (!IsPack)
2413 OS << '<';
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)
2424 OS << Comma;
2425 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2426 /*IsPack*/ true, ParmIndex);
2427 } else {
2428 if (!FirstArg)
2429 OS << Comma;
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(":"))
2441 OS << ' ';
2443 OS << ArgString;
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() == '>';
2449 FirstArg = false;
2452 // Use same template parameter for all elements of Pack
2453 if (!IsPack)
2454 ParmIndex++;
2457 if (!IsPack) {
2458 if (NeedSpace)
2459 OS << ' ';
2460 OS << '>';
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 {
2486 LangOptions LO;
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
2492 // space.
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())
2502 return false;
2504 if (getAddressSpace() != LangAS::Default)
2505 return false;
2507 if (getObjCGCAttr())
2508 return false;
2510 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
2511 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2512 return false;
2514 return true;
2517 std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
2518 switch (AS) {
2519 case LangAS::Default:
2520 return "";
2521 case LangAS::opencl_global:
2522 case LangAS::sycl_global:
2523 return "__global";
2524 case LangAS::opencl_local:
2525 case LangAS::sycl_local:
2526 return "__local";
2527 case LangAS::opencl_private:
2528 case LangAS::sycl_private:
2529 return "__private";
2530 case LangAS::opencl_constant:
2531 return "__constant";
2532 case LangAS::opencl_generic:
2533 return "__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";
2550 case LangAS::ptr64:
2551 return "__ptr64";
2552 case LangAS::wasm_funcref:
2553 return "__funcref";
2554 case LangAS::hlsl_groupshared:
2555 return "groupshared";
2556 default:
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
2563 // space.
2564 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2565 bool appendSpaceIfNonEmpty) const {
2566 bool addSpace = false;
2568 unsigned quals = getCVRQualifiers();
2569 if (quals) {
2570 AppendTypeQualList(OS, quals, Policy.Restrict);
2571 addSpace = true;
2573 if (hasUnaligned()) {
2574 if (addSpace)
2575 OS << ' ';
2576 OS << "__unaligned";
2577 addSpace = true;
2579 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2580 if (!ASStr.empty()) {
2581 if (addSpace)
2582 OS << ' ';
2583 addSpace = true;
2584 // Wrap target address space into an attribute syntax
2585 if (isTargetAddressSpace(getAddressSpace()))
2586 OS << "__attribute__((address_space(" << ASStr << ")))";
2587 else
2588 OS << ASStr;
2591 if (Qualifiers::GC gc = getObjCGCAttr()) {
2592 if (addSpace)
2593 OS << ' ';
2594 addSpace = true;
2595 if (gc == Qualifiers::Weak)
2596 OS << "__weak";
2597 else
2598 OS << "__strong";
2600 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2601 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2602 if (addSpace)
2603 OS << ' ';
2604 addSpace = true;
2607 switch (lifetime) {
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)
2612 OS << "__strong";
2613 break;
2615 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2616 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2620 if (appendSpaceIfNonEmpty && addSpace)
2621 OS << ' ';
2624 std::string QualType::getAsString() const {
2625 return getAsString(split(), LangOptions());
2628 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2629 std::string S;
2630 getAsStringInternal(S, Policy);
2631 return S;
2634 std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2635 const PrintingPolicy &Policy) {
2636 std::string buffer;
2637 getAsStringInternal(ty, qs, buffer, Policy);
2638 return buffer;
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,
2644 Indentation);
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,
2659 Policy);
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());
2669 buffer.swap(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=*/"");
2675 return OS;