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.
10//
11//===----------------------------------------------------------------------===//
12
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>
46
47using namespace clang;
48
49namespace {
50
51/// RAII object that enables printing of the ARC __strong lifetime
52/// qualifier.
53class IncludeStrongLifetimeRAII {
54 PrintingPolicy &Policy;
55 bool Old;
56
57public:
58 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
59 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
60 if (!Policy.SuppressLifetimeQualifiers)
61 Policy.SuppressStrongLifetime = false;
62 }
63
64 ~IncludeStrongLifetimeRAII() { Policy.SuppressStrongLifetime = Old; }
65};
66
67class ParamPolicyRAII {
68 PrintingPolicy &Policy;
69 bool Old;
70
71public:
72 explicit ParamPolicyRAII(PrintingPolicy &Policy)
73 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
74 Policy.SuppressSpecifiers = false;
75 }
76
77 ~ParamPolicyRAII() { Policy.SuppressSpecifiers = Old; }
78};
79
80class DefaultTemplateArgsPolicyRAII {
81 PrintingPolicy &Policy;
82 bool Old;
83
84public:
85 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)
86 : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {
87 Policy.SuppressDefaultTemplateArgs = false;
88 }
89
90 ~DefaultTemplateArgsPolicyRAII() { Policy.SuppressDefaultTemplateArgs = Old; }
91};
92
93class ElaboratedTypePolicyRAII {
94 PrintingPolicy &Policy;
95 bool SuppressTagKeyword;
96 bool SuppressScope;
97
98public:
99 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
100 SuppressTagKeyword = Policy.SuppressTagKeyword;
101 SuppressScope = Policy.SuppressScope;
102 Policy.SuppressTagKeyword = true;
103 Policy.SuppressScope = true;
104 }
105
106 ~ElaboratedTypePolicyRAII() {
107 Policy.SuppressTagKeyword = SuppressTagKeyword;
108 Policy.SuppressScope = SuppressScope;
109 }
110};
111
112class TypePrinter {
113 PrintingPolicy Policy;
114 unsigned Indentation;
115 bool HasEmptyPlaceHolder = false;
116 bool InsideCCAttribute = false;
117
118public:
119 explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
120 : Policy(Policy), Indentation(Indentation) {}
121
122 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
123 StringRef PlaceHolder);
124 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
125
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);
131
132 void printBefore(QualType T, raw_ostream &OS);
133 void printAfter(QualType T, raw_ostream &OS);
134 void printTagType(const TagType *T, raw_ostream &OS);
135 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
136#define ABSTRACT_TYPE(CLASS, PARENT)
137#define TYPE(CLASS, PARENT) \
138 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
139 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
140#include "clang/AST/TypeNodes.inc"
141
142private:
143 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
144 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
145};
146
147} // namespace
148
149static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
150 bool HasRestrictKeyword) {
151 bool appendSpace = false;
152 if (TypeQuals & Qualifiers::Const) {
153 OS << "const";
154 appendSpace = true;
155 }
156 if (TypeQuals & Qualifiers::Volatile) {
157 if (appendSpace) OS << ' ';
158 OS << "volatile";
159 appendSpace = true;
160 }
161 if (TypeQuals & Qualifiers::Restrict) {
162 if (appendSpace) OS << ' ';
163 if (HasRestrictKeyword) {
164 OS << "restrict";
165 } else {
166 OS << "__restrict";
167 }
168 }
169}
170
171void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
172 if (!HasEmptyPlaceHolder)
173 OS << ' ';
174}
175
176static SplitQualType splitAccordingToPolicy(QualType QT,
177 const PrintingPolicy &Policy) {
178 if (Policy.PrintAsCanonical)
179 QT = QT.getCanonicalType();
180 return QT.split();
181}
182
183void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
184 SplitQualType split = splitAccordingToPolicy(QT: t, Policy);
185 print(ty: split.Ty, qs: split.Quals, OS, PlaceHolder);
186}
187
188void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
189 StringRef PlaceHolder) {
190 if (!T) {
191 OS << "NULL TYPE";
192 return;
193 }
194
195 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
196
197 printBefore(ty: T, qs: Quals, OS);
198 OS << PlaceHolder;
199 printAfter(ty: T, qs: Quals, OS);
200}
201
202bool TypePrinter::canPrefixQualifiers(const Type *T,
203 bool &NeedARCStrongQualifier) {
204 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
205 // so that we get "const int" instead of "int const", but we can't do this if
206 // the type is complex. For example if the type is "int*", we *must* print
207 // "int * const", printing "const int *" is different. Only do this when the
208 // type expands to a simple string.
209 bool CanPrefixQualifiers = false;
210 NeedARCStrongQualifier = false;
211 const Type *UnderlyingType = T;
212 if (const auto *AT = dyn_cast<AutoType>(Val: T))
213 UnderlyingType = AT->desugar().getTypePtr();
214 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Val: T))
215 UnderlyingType = Subst->getReplacementType().getTypePtr();
216 Type::TypeClass TC = UnderlyingType->getTypeClass();
217
218 switch (TC) {
219 case Type::Auto:
220 case Type::Builtin:
221 case Type::Complex:
222 case Type::UnresolvedUsing:
223 case Type::Using:
224 case Type::Typedef:
225 case Type::TypeOfExpr:
226 case Type::TypeOf:
227 case Type::Decltype:
228 case Type::UnaryTransform:
229 case Type::Record:
230 case Type::Enum:
231 case Type::TemplateTypeParm:
232 case Type::SubstTemplateTypeParmPack:
233 case Type::SubstBuiltinTemplatePack:
234 case Type::DeducedTemplateSpecialization:
235 case Type::TemplateSpecialization:
236 case Type::InjectedClassName:
237 case Type::DependentName:
238 case Type::ObjCObject:
239 case Type::ObjCTypeParam:
240 case Type::ObjCInterface:
241 case Type::Atomic:
242 case Type::Pipe:
243 case Type::BitInt:
244 case Type::DependentBitInt:
245 case Type::BTFTagAttributed:
246 case Type::HLSLAttributedResource:
247 case Type::HLSLInlineSpirv:
248 case Type::PredefinedSugar:
249 CanPrefixQualifiers = true;
250 break;
251
252 case Type::ObjCObjectPointer:
253 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
254 T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
255 break;
256
257 case Type::VariableArray:
258 case Type::DependentSizedArray:
259 NeedARCStrongQualifier = true;
260 [[fallthrough]];
261
262 case Type::ConstantArray:
263 case Type::IncompleteArray:
264 return canPrefixQualifiers(
265 T: cast<ArrayType>(Val: UnderlyingType)->getElementType().getTypePtr(),
266 NeedARCStrongQualifier);
267
268 case Type::Adjusted:
269 case Type::Decayed:
270 case Type::ArrayParameter:
271 case Type::Pointer:
272 case Type::BlockPointer:
273 case Type::LValueReference:
274 case Type::RValueReference:
275 case Type::MemberPointer:
276 case Type::DependentAddressSpace:
277 case Type::DependentVector:
278 case Type::DependentSizedExtVector:
279 case Type::Vector:
280 case Type::ExtVector:
281 case Type::ConstantMatrix:
282 case Type::DependentSizedMatrix:
283 case Type::FunctionProto:
284 case Type::FunctionNoProto:
285 case Type::Paren:
286 case Type::PackExpansion:
287 case Type::SubstTemplateTypeParm:
288 case Type::MacroQualified:
289 case Type::OverflowBehavior:
290 case Type::CountAttributed:
291 CanPrefixQualifiers = false;
292 break;
293
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>(Val: UnderlyingType);
298 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
299 break;
300 }
301 case Type::PackIndexing: {
302 return canPrefixQualifiers(
303 T: cast<PackIndexingType>(Val: UnderlyingType)->getPattern().getTypePtr(),
304 NeedARCStrongQualifier);
305 }
306 }
307
308 return CanPrefixQualifiers;
309}
310
311void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
312 SplitQualType Split = splitAccordingToPolicy(QT: T, Policy);
313
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>(Val: Split.Ty))
318 Quals -= QualType(Subst, 0).getQualifiers();
319
320 printBefore(ty: Split.Ty, qs: Quals, OS);
321}
322
323/// Prints the part of the type string before an identifier, e.g. for
324/// "int foo[10]" it prints "int ".
325void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
326 if (Policy.SuppressSpecifiers && T->isSpecifierType())
327 return;
328
329 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
330
331 // Print qualifiers as appropriate.
332
333 bool CanPrefixQualifiers = false;
334 bool NeedARCStrongQualifier = false;
335 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
336
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);
343 }
344 }
345
346 bool hasAfterQuals = false;
347 if (!CanPrefixQualifiers && !Quals.empty()) {
348 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
349 if (hasAfterQuals)
350 HasEmptyPlaceHolder = false;
351 }
352
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"
359 }
360
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());
367 }
368 }
369}
370
371void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
372 SplitQualType split = splitAccordingToPolicy(QT: t, Policy);
373 printAfter(ty: split.Ty, qs: split.Quals, OS);
374}
375
376/// Prints the part of the type string after an identifier, e.g. for
377/// "int foo[10]" it prints "[10]".
378void 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"
385 }
386}
387
388void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
389 OS << T->getName(Policy);
390 spaceBeforePlaceHolder(OS);
391}
392
393void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
394
395void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
396 OS << "_Complex ";
397 printBefore(T: T->getElementType(), OS);
398}
399
400void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
401 printAfter(t: T->getElementType(), OS);
402}
403
404void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
405 IncludeStrongLifetimeRAII Strong(Policy);
406 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
407 printBefore(T: 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>(Val: T->getPointeeType()))
411 OS << '(';
412 OS << '*';
413}
414
415void 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>(Val: T->getPointeeType()))
421 OS << ')';
422 printAfter(t: T->getPointeeType(), OS);
423}
424
425void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
426 raw_ostream &OS) {
427 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
428 printBefore(T: T->getPointeeType(), OS);
429 OS << '^';
430}
431
432void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
433 raw_ostream &OS) {
434 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
435 printAfter(t: T->getPointeeType(), OS);
436}
437
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.
440static QualType skipTopLevelReferences(QualType T) {
441 if (auto *Ref = T->getAs<ReferenceType>())
442 return skipTopLevelReferences(T: Ref->getPointeeTypeAsWritten());
443 return T;
444}
445
446void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
447 raw_ostream &OS) {
448 IncludeStrongLifetimeRAII Strong(Policy);
449 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
450 QualType Inner = skipTopLevelReferences(T: T->getPointeeTypeAsWritten());
451 printBefore(T: 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>(Val: Inner))
455 OS << '(';
456 OS << '&';
457}
458
459void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
460 raw_ostream &OS) {
461 IncludeStrongLifetimeRAII Strong(Policy);
462 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
463 QualType Inner = skipTopLevelReferences(T: 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>(Val: Inner))
467 OS << ')';
468 printAfter(t: Inner, OS);
469}
470
471void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
472 raw_ostream &OS) {
473 IncludeStrongLifetimeRAII Strong(Policy);
474 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
475 QualType Inner = skipTopLevelReferences(T: T->getPointeeTypeAsWritten());
476 printBefore(T: 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>(Val: Inner))
480 OS << '(';
481 OS << "&&";
482}
483
484void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
485 raw_ostream &OS) {
486 IncludeStrongLifetimeRAII Strong(Policy);
487 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
488 QualType Inner = skipTopLevelReferences(T: 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>(Val: Inner))
492 OS << ')';
493 printAfter(t: Inner, OS);
494}
495
496void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
497 raw_ostream &OS) {
498 IncludeStrongLifetimeRAII Strong(Policy);
499 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
500 printBefore(T: 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>(Val: T->getPointeeType()))
504 OS << '(';
505 T->getQualifier().print(OS, Policy);
506 OS << "*";
507}
508
509void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
510 raw_ostream &OS) {
511 IncludeStrongLifetimeRAII Strong(Policy);
512 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
513 // Handle things like 'int (Cls::*A)[4];' correctly.
514 // FIXME: this should include vectors, but vectors use attributes I guess.
515 if (isa<ArrayType>(Val: T->getPointeeType()))
516 OS << ')';
517 printAfter(t: T->getPointeeType(), OS);
518}
519
520void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
521 raw_ostream &OS) {
522 IncludeStrongLifetimeRAII Strong(Policy);
523 printBefore(T: T->getElementType(), OS);
524}
525
526void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
527 raw_ostream &OS) {
528 OS << '[';
529 if (T->getIndexTypeQualifiers().hasQualifiers()) {
530 AppendTypeQualList(OS, TypeQuals: T->getIndexTypeCVRQualifiers(),
531 HasRestrictKeyword: Policy.Restrict);
532 OS << ' ';
533 }
534
535 if (T->getSizeModifier() == ArraySizeModifier::Static)
536 OS << "static ";
537
538 OS << T->getZExtSize() << ']';
539 printAfter(t: T->getElementType(), OS);
540}
541
542void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
543 raw_ostream &OS) {
544 IncludeStrongLifetimeRAII Strong(Policy);
545 printBefore(T: T->getElementType(), OS);
546}
547
548void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
549 raw_ostream &OS) {
550 OS << "[]";
551 printAfter(t: T->getElementType(), OS);
552}
553
554void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
555 raw_ostream &OS) {
556 IncludeStrongLifetimeRAII Strong(Policy);
557 printBefore(T: T->getElementType(), OS);
558}
559
560void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
561 raw_ostream &OS) {
562 OS << '[';
563 if (T->getIndexTypeQualifiers().hasQualifiers()) {
564 AppendTypeQualList(OS, TypeQuals: T->getIndexTypeCVRQualifiers(), HasRestrictKeyword: Policy.Restrict);
565 OS << ' ';
566 }
567
568 if (T->getSizeModifier() == ArraySizeModifier::Static)
569 OS << "static ";
570 else if (T->getSizeModifier() == ArraySizeModifier::Star)
571 OS << '*';
572
573 if (T->getSizeExpr())
574 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
575 OS << ']';
576
577 printAfter(t: T->getElementType(), OS);
578}
579
580void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
581 // Print the adjusted representation, otherwise the adjustment will be
582 // invisible.
583 printBefore(T: T->getAdjustedType(), OS);
584}
585
586void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
587 printAfter(t: T->getAdjustedType(), OS);
588}
589
590void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
591 // Print as though it's a pointer.
592 printAdjustedBefore(T, OS);
593}
594
595void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
596 raw_ostream &OS) {
597 printConstantArrayAfter(T, OS);
598}
599
600void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
601 raw_ostream &OS) {
602 printConstantArrayBefore(T, OS);
603}
604
605void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
606 printAdjustedAfter(T, OS);
607}
608
609void TypePrinter::printDependentSizedArrayBefore(
610 const DependentSizedArrayType *T,
611 raw_ostream &OS) {
612 IncludeStrongLifetimeRAII Strong(Policy);
613 printBefore(T: T->getElementType(), OS);
614}
615
616void TypePrinter::printDependentSizedArrayAfter(
617 const DependentSizedArrayType *T,
618 raw_ostream &OS) {
619 OS << '[';
620 if (T->getSizeExpr())
621 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
622 OS << ']';
623 printAfter(t: T->getElementType(), OS);
624}
625
626void TypePrinter::printDependentAddressSpaceBefore(
627 const DependentAddressSpaceType *T, raw_ostream &OS) {
628 printBefore(T: T->getPointeeType(), OS);
629}
630
631void TypePrinter::printDependentAddressSpaceAfter(
632 const DependentAddressSpaceType *T, raw_ostream &OS) {
633 OS << " __attribute__((address_space(";
634 if (T->getAddrSpaceExpr())
635 T->getAddrSpaceExpr()->printPretty(OS, Helper: nullptr, Policy);
636 OS << ")))";
637 printAfter(t: T->getPointeeType(), OS);
638}
639
640void TypePrinter::printDependentSizedExtVectorBefore(
641 const DependentSizedExtVectorType *T, raw_ostream &OS) {
642 if (Policy.UseHLSLTypes) {
643 OS << "vector<";
644 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
645 OS << ", ";
646 if (T->getSizeExpr())
647 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
648 OS << ">";
649 spaceBeforePlaceHolder(OS);
650 } else {
651 printBefore(T: T->getElementType(), OS);
652 }
653}
654
655void TypePrinter::printDependentSizedExtVectorAfter(
656 const DependentSizedExtVectorType *T, raw_ostream &OS) {
657 if (Policy.UseHLSLTypes)
658 return;
659
660 OS << " __attribute__((ext_vector_type(";
661 if (T->getSizeExpr())
662 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
663 OS << ")))";
664 printAfter(t: T->getElementType(), OS);
665}
666
667void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
668 switch (T->getVectorKind()) {
669 case VectorKind::AltiVecPixel:
670 OS << "__vector __pixel ";
671 break;
672 case VectorKind::AltiVecBool:
673 OS << "__vector __bool ";
674 printBefore(T: T->getElementType(), OS);
675 break;
676 case VectorKind::AltiVecVector:
677 OS << "__vector ";
678 printBefore(T: T->getElementType(), OS);
679 break;
680 case VectorKind::Neon:
681 OS << "__attribute__((neon_vector_type("
682 << T->getNumElements() << "))) ";
683 printBefore(T: T->getElementType(), OS);
684 break;
685 case VectorKind::NeonPoly:
686 OS << "__attribute__((neon_polyvector_type(" <<
687 T->getNumElements() << "))) ";
688 printBefore(T: T->getElementType(), OS);
689 break;
690 case VectorKind::Generic: {
691 // FIXME: We prefer to print the size directly here, but have no way
692 // to get the size of the type.
693 OS << "__attribute__((__vector_size__("
694 << T->getNumElements()
695 << " * sizeof(";
696 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
697 OS << ")))) ";
698 printBefore(T: T->getElementType(), OS);
699 break;
700 }
701 case VectorKind::SveFixedLengthData:
702 case VectorKind::SveFixedLengthPredicate:
703 // FIXME: We prefer to print the size directly here, but have no way
704 // to get the size of the type.
705 OS << "__attribute__((__arm_sve_vector_bits__(";
706
707 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
708 // Predicates take a bit per byte of the vector size, multiply by 8 to
709 // get the number of bits passed to the attribute.
710 OS << T->getNumElements() * 8;
711 else
712 OS << T->getNumElements();
713
714 OS << " * sizeof(";
715 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
716 // Multiply by 8 for the number of bits.
717 OS << ") * 8))) ";
718 printBefore(T: T->getElementType(), OS);
719 break;
720 case VectorKind::RVVFixedLengthData:
721 case VectorKind::RVVFixedLengthMask:
722 case VectorKind::RVVFixedLengthMask_1:
723 case VectorKind::RVVFixedLengthMask_2:
724 case VectorKind::RVVFixedLengthMask_4:
725 // FIXME: We prefer to print the size directly here, but have no way
726 // to get the size of the type.
727 OS << "__attribute__((__riscv_rvv_vector_bits__(";
728 switch (T->getVectorKind()) {
729 case VectorKind::RVVFixedLengthMask_1:
730 OS << '1';
731 break;
732 case VectorKind::RVVFixedLengthMask_2:
733 OS << '2';
734 break;
735 case VectorKind::RVVFixedLengthMask_4:
736 OS << '4';
737 break;
738 default:
739 OS << T->getNumElements();
740 OS << " * sizeof(";
741 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
742 // Multiply by 8 for the number of bits.
743 OS << ") * 8";
744 break;
745 }
746 OS << "))) ";
747 printBefore(T: T->getElementType(), OS);
748 break;
749 }
750}
751
752void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
753 printAfter(t: T->getElementType(), OS);
754}
755
756void TypePrinter::printDependentVectorBefore(
757 const DependentVectorType *T, raw_ostream &OS) {
758 switch (T->getVectorKind()) {
759 case VectorKind::AltiVecPixel:
760 OS << "__vector __pixel ";
761 break;
762 case VectorKind::AltiVecBool:
763 OS << "__vector __bool ";
764 printBefore(T: T->getElementType(), OS);
765 break;
766 case VectorKind::AltiVecVector:
767 OS << "__vector ";
768 printBefore(T: T->getElementType(), OS);
769 break;
770 case VectorKind::Neon:
771 OS << "__attribute__((neon_vector_type(";
772 if (T->getSizeExpr())
773 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
774 OS << "))) ";
775 printBefore(T: T->getElementType(), OS);
776 break;
777 case VectorKind::NeonPoly:
778 OS << "__attribute__((neon_polyvector_type(";
779 if (T->getSizeExpr())
780 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
781 OS << "))) ";
782 printBefore(T: T->getElementType(), OS);
783 break;
784 case VectorKind::Generic: {
785 // FIXME: We prefer to print the size directly here, but have no way
786 // to get the size of the type.
787 OS << "__attribute__((__vector_size__(";
788 if (T->getSizeExpr())
789 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
790 OS << " * sizeof(";
791 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
792 OS << ")))) ";
793 printBefore(T: T->getElementType(), OS);
794 break;
795 }
796 case VectorKind::SveFixedLengthData:
797 case VectorKind::SveFixedLengthPredicate:
798 // FIXME: We prefer to print the size directly here, but have no way
799 // to get the size of the type.
800 OS << "__attribute__((__arm_sve_vector_bits__(";
801 if (T->getSizeExpr()) {
802 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
803 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
804 // Predicates take a bit per byte of the vector size, multiply by 8 to
805 // get the number of bits passed to the attribute.
806 OS << " * 8";
807 OS << " * sizeof(";
808 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
809 // Multiply by 8 for the number of bits.
810 OS << ") * 8";
811 }
812 OS << "))) ";
813 printBefore(T: T->getElementType(), OS);
814 break;
815 case VectorKind::RVVFixedLengthData:
816 case VectorKind::RVVFixedLengthMask:
817 case VectorKind::RVVFixedLengthMask_1:
818 case VectorKind::RVVFixedLengthMask_2:
819 case VectorKind::RVVFixedLengthMask_4:
820 // FIXME: We prefer to print the size directly here, but have no way
821 // to get the size of the type.
822 OS << "__attribute__((__riscv_rvv_vector_bits__(";
823 switch (T->getVectorKind()) {
824 case VectorKind::RVVFixedLengthMask_1:
825 OS << '1';
826 break;
827 case VectorKind::RVVFixedLengthMask_2:
828 OS << '2';
829 break;
830 case VectorKind::RVVFixedLengthMask_4:
831 OS << '4';
832 break;
833 default:
834 if (T->getSizeExpr()) {
835 T->getSizeExpr()->printPretty(OS, Helper: nullptr, Policy);
836 OS << " * sizeof(";
837 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
838 // Multiply by 8 for the number of bits.
839 OS << ") * 8";
840 }
841 break;
842 }
843 OS << "))) ";
844 printBefore(T: T->getElementType(), OS);
845 break;
846 }
847}
848
849void TypePrinter::printDependentVectorAfter(
850 const DependentVectorType *T, raw_ostream &OS) {
851 printAfter(t: T->getElementType(), OS);
852}
853
854void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
855 raw_ostream &OS) {
856 if (Policy.UseHLSLTypes) {
857 OS << "vector<";
858 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
859 OS << ", " << T->getNumElements() << ">";
860 spaceBeforePlaceHolder(OS);
861 } else {
862 printBefore(T: T->getElementType(), OS);
863 }
864}
865
866void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
867 if (Policy.UseHLSLTypes)
868 return;
869
870 printAfter(t: T->getElementType(), OS);
871 OS << " __attribute__((ext_vector_type(";
872 OS << T->getNumElements();
873 OS << ")))";
874}
875
876static void printDims(const ConstantMatrixType *T, raw_ostream &OS) {
877 OS << T->getNumRows() << ", " << T->getNumColumns();
878}
879
880static void printHLSLMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,
881 raw_ostream &OS) {
882 OS << "matrix<";
883 TP.print(t: T->getElementType(), OS, PlaceHolder: StringRef());
884 OS << ", ";
885 printDims(T, OS);
886 OS << ">";
887 TP.spaceBeforePlaceHolder(OS);
888}
889
890static void printHLSLMatrixAfter(const ConstantMatrixType *T, raw_ostream &OS) {
891}
892
893static void printClangMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,
894 raw_ostream &OS) {
895 TP.printBefore(T: T->getElementType(), OS);
896 OS << " __attribute__((matrix_type(";
897 printDims(T, OS);
898 OS << ")))";
899}
900
901void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
902 raw_ostream &OS) {
903 if (Policy.UseHLSLTypes) {
904 printHLSLMatrixBefore(TP&: *this, T, OS);
905 return;
906 }
907 printClangMatrixBefore(TP&: *this, T, OS);
908}
909
910void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
911 raw_ostream &OS) {
912 if (Policy.UseHLSLTypes) {
913 printHLSLMatrixAfter(T, OS);
914 return;
915 }
916 printAfter(t: T->getElementType(), OS);
917}
918
919void TypePrinter::printDependentSizedMatrixBefore(
920 const DependentSizedMatrixType *T, raw_ostream &OS) {
921 if (Policy.UseHLSLTypes) {
922 OS << "matrix<";
923 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
924 OS << ", ";
925 if (T->getRowExpr())
926 T->getRowExpr()->printPretty(OS, Helper: nullptr, Policy);
927 OS << ", ";
928 if (T->getColumnExpr())
929 T->getColumnExpr()->printPretty(OS, Helper: nullptr, Policy);
930 OS << ">";
931 spaceBeforePlaceHolder(OS);
932 } else {
933 printBefore(T: T->getElementType(), OS);
934 OS << " __attribute__((matrix_type(";
935 if (T->getRowExpr())
936 T->getRowExpr()->printPretty(OS, Helper: nullptr, Policy);
937 OS << ", ";
938 if (T->getColumnExpr())
939 T->getColumnExpr()->printPretty(OS, Helper: nullptr, Policy);
940 OS << ")))";
941 }
942}
943
944void TypePrinter::printDependentSizedMatrixAfter(
945 const DependentSizedMatrixType *T, raw_ostream &OS) {
946 if (!Policy.UseHLSLTypes)
947 printAfter(t: T->getElementType(), OS);
948}
949
950void
951FunctionProtoType::printExceptionSpecification(raw_ostream &OS,
952 const PrintingPolicy &Policy)
953 const {
954 if (hasDynamicExceptionSpec()) {
955 OS << " throw(";
956 if (getExceptionSpecType() == EST_MSAny)
957 OS << "...";
958 else
959 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
960 if (I)
961 OS << ", ";
962
963 OS << getExceptionType(i: I).stream(Policy);
964 }
965 OS << ')';
966 } else if (EST_NoThrow == getExceptionSpecType()) {
967 OS << " __attribute__((nothrow))";
968 } else if (isNoexceptExceptionSpec(ESpecType: getExceptionSpecType())) {
969 OS << " noexcept";
970 // FIXME:Is it useful to print out the expression for a non-dependent
971 // noexcept specification?
972 if (isComputedNoexcept(ESpecType: getExceptionSpecType())) {
973 OS << '(';
974 if (getNoexceptExpr())
975 getNoexceptExpr()->printPretty(OS, Helper: nullptr, Policy);
976 OS << ')';
977 }
978 }
979}
980
981void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
982 raw_ostream &OS) {
983 if (T->hasTrailingReturn()) {
984 OS << "auto ";
985 if (!HasEmptyPlaceHolder)
986 OS << '(';
987 } else {
988 // If needed for precedence reasons, wrap the inner part in grouping parens.
989 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
990 printBefore(T: T->getReturnType(), OS);
991 if (!PrevPHIsEmpty.get())
992 OS << '(';
993 }
994}
995
996StringRef clang::getParameterABISpelling(ParameterABI ABI) {
997 switch (ABI) {
998 case ParameterABI::Ordinary:
999 llvm_unreachable("asking for spelling of ordinary parameter ABI");
1000 case ParameterABI::SwiftContext:
1001 return "swift_context";
1002 case ParameterABI::SwiftAsyncContext:
1003 return "swift_async_context";
1004 case ParameterABI::SwiftErrorResult:
1005 return "swift_error_result";
1006 case ParameterABI::SwiftIndirectResult:
1007 return "swift_indirect_result";
1008 case ParameterABI::HLSLOut:
1009 return "out";
1010 case ParameterABI::HLSLInOut:
1011 return "inout";
1012 }
1013 llvm_unreachable("bad parameter ABI kind");
1014}
1015
1016void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
1017 raw_ostream &OS) {
1018 // If needed for precedence reasons, wrap the inner part in grouping parens.
1019 if (!HasEmptyPlaceHolder)
1020 OS << ')';
1021 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1022
1023 OS << '(';
1024 {
1025 ParamPolicyRAII ParamPolicy(Policy);
1026 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
1027 if (i) OS << ", ";
1028
1029 auto EPI = T->getExtParameterInfo(I: i);
1030 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
1031 if (EPI.isNoEscape())
1032 OS << "__attribute__((noescape)) ";
1033 auto ABI = EPI.getABI();
1034 if (ABI == ParameterABI::HLSLInOut || ABI == ParameterABI::HLSLOut) {
1035 OS << getParameterABISpelling(ABI) << " ";
1036 if (Policy.UseHLSLTypes) {
1037 // This is a bit of a hack because we _do_ use reference types in the
1038 // AST for representing inout and out parameters so that code
1039 // generation is sane, but when re-printing these for HLSL we need to
1040 // skip the reference.
1041 print(t: T->getParamType(i).getNonReferenceType(), OS, PlaceHolder: StringRef());
1042 continue;
1043 }
1044 } else if (ABI != ParameterABI::Ordinary)
1045 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
1046
1047 print(t: T->getParamType(i), OS, PlaceHolder: StringRef());
1048 }
1049 }
1050
1051 if (T->isVariadic()) {
1052 if (T->getNumParams())
1053 OS << ", ";
1054 OS << "...";
1055 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
1056 // Do not emit int() if we have a proto, emit 'int(void)'.
1057 OS << "void";
1058 }
1059
1060 OS << ')';
1061
1062 FunctionType::ExtInfo Info = T->getExtInfo();
1063 unsigned SMEBits = T->getAArch64SMEAttributes();
1064
1065 if (SMEBits & FunctionType::SME_PStateSMCompatibleMask)
1066 OS << " __arm_streaming_compatible";
1067 if (SMEBits & FunctionType::SME_PStateSMEnabledMask)
1068 OS << " __arm_streaming";
1069 if (SMEBits & FunctionType::SME_AgnosticZAStateMask)
1070 OS << "__arm_agnostic(\"sme_za_state\")";
1071 if (FunctionType::getArmZAState(AttrBits: SMEBits) == FunctionType::ARM_Preserves)
1072 OS << " __arm_preserves(\"za\")";
1073 if (FunctionType::getArmZAState(AttrBits: SMEBits) == FunctionType::ARM_In)
1074 OS << " __arm_in(\"za\")";
1075 if (FunctionType::getArmZAState(AttrBits: SMEBits) == FunctionType::ARM_Out)
1076 OS << " __arm_out(\"za\")";
1077 if (FunctionType::getArmZAState(AttrBits: SMEBits) == FunctionType::ARM_InOut)
1078 OS << " __arm_inout(\"za\")";
1079 if (FunctionType::getArmZT0State(AttrBits: SMEBits) == FunctionType::ARM_Preserves)
1080 OS << " __arm_preserves(\"zt0\")";
1081 if (FunctionType::getArmZT0State(AttrBits: SMEBits) == FunctionType::ARM_In)
1082 OS << " __arm_in(\"zt0\")";
1083 if (FunctionType::getArmZT0State(AttrBits: SMEBits) == FunctionType::ARM_Out)
1084 OS << " __arm_out(\"zt0\")";
1085 if (FunctionType::getArmZT0State(AttrBits: SMEBits) == FunctionType::ARM_InOut)
1086 OS << " __arm_inout(\"zt0\")";
1087
1088 printFunctionAfter(Info, OS);
1089
1090 if (!T->getMethodQuals().empty())
1091 OS << " " << T->getMethodQuals().getAsString();
1092
1093 switch (T->getRefQualifier()) {
1094 case RQ_None:
1095 break;
1096
1097 case RQ_LValue:
1098 OS << " &";
1099 break;
1100
1101 case RQ_RValue:
1102 OS << " &&";
1103 break;
1104 }
1105 T->printExceptionSpecification(OS, Policy);
1106
1107 const FunctionEffectsRef FX = T->getFunctionEffects();
1108 for (const auto &CFE : FX) {
1109 OS << " __attribute__((" << CFE.Effect.name();
1110 if (const Expr *E = CFE.Cond.getCondition()) {
1111 OS << '(';
1112 E->printPretty(OS, Helper: nullptr, Policy);
1113 OS << ')';
1114 }
1115 OS << "))";
1116 }
1117
1118 if (T->hasCFIUncheckedCallee())
1119 OS << " __attribute__((cfi_unchecked_callee))";
1120
1121 if (T->hasTrailingReturn()) {
1122 OS << " -> ";
1123 print(t: T->getReturnType(), OS, PlaceHolder: StringRef());
1124 } else
1125 printAfter(t: T->getReturnType(), OS);
1126}
1127
1128void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1129 raw_ostream &OS) {
1130 if (!InsideCCAttribute) {
1131 switch (Info.getCC()) {
1132 case CC_C:
1133 // The C calling convention is the default on the vast majority of platforms
1134 // we support. If the user wrote it explicitly, it will usually be printed
1135 // while traversing the AttributedType. If the type has been desugared, let
1136 // the canonical spelling be the implicit calling convention.
1137 // FIXME: It would be better to be explicit in certain contexts, such as a
1138 // cdecl function typedef used to declare a member function with the
1139 // Microsoft C++ ABI.
1140 break;
1141 case CC_X86StdCall:
1142 OS << " __attribute__((stdcall))";
1143 break;
1144 case CC_X86FastCall:
1145 OS << " __attribute__((fastcall))";
1146 break;
1147 case CC_X86ThisCall:
1148 OS << " __attribute__((thiscall))";
1149 break;
1150 case CC_X86VectorCall:
1151 OS << " __attribute__((vectorcall))";
1152 break;
1153 case CC_X86Pascal:
1154 OS << " __attribute__((pascal))";
1155 break;
1156 case CC_AAPCS:
1157 OS << " __attribute__((pcs(\"aapcs\")))";
1158 break;
1159 case CC_AAPCS_VFP:
1160 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1161 break;
1162 case CC_AArch64VectorCall:
1163 OS << " __attribute__((aarch64_vector_pcs))";
1164 break;
1165 case CC_AArch64SVEPCS:
1166 OS << " __attribute__((aarch64_sve_pcs))";
1167 break;
1168 case CC_DeviceKernel:
1169 OS << " __attribute__((device_kernel))";
1170 break;
1171 case CC_IntelOclBicc:
1172 OS << " __attribute__((intel_ocl_bicc))";
1173 break;
1174 case CC_Win64:
1175 OS << " __attribute__((ms_abi))";
1176 break;
1177 case CC_X86_64SysV:
1178 OS << " __attribute__((sysv_abi))";
1179 break;
1180 case CC_X86RegCall:
1181 OS << " __attribute__((regcall))";
1182 break;
1183 case CC_SpirFunction:
1184 // Do nothing. These CCs are not available as attributes.
1185 break;
1186 case CC_Swift:
1187 OS << " __attribute__((swiftcall))";
1188 break;
1189 case CC_SwiftAsync:
1190 OS << "__attribute__((swiftasynccall))";
1191 break;
1192 case CC_PreserveMost:
1193 OS << " __attribute__((preserve_most))";
1194 break;
1195 case CC_PreserveAll:
1196 OS << " __attribute__((preserve_all))";
1197 break;
1198 case CC_M68kRTD:
1199 OS << " __attribute__((m68k_rtd))";
1200 break;
1201 case CC_PreserveNone:
1202 OS << " __attribute__((preserve_none))";
1203 break;
1204 case CC_RISCVVectorCall:
1205 OS << "__attribute__((riscv_vector_cc))";
1206 break;
1207#define CC_VLS_CASE(ABI_VLEN) \
1208 case CC_RISCVVLSCall_##ABI_VLEN: \
1209 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \
1210 break;
1211 CC_VLS_CASE(32)
1212 CC_VLS_CASE(64)
1213 CC_VLS_CASE(128)
1214 CC_VLS_CASE(256)
1215 CC_VLS_CASE(512)
1216 CC_VLS_CASE(1024)
1217 CC_VLS_CASE(2048)
1218 CC_VLS_CASE(4096)
1219 CC_VLS_CASE(8192)
1220 CC_VLS_CASE(16384)
1221 CC_VLS_CASE(32768)
1222 CC_VLS_CASE(65536)
1223#undef CC_VLS_CASE
1224 }
1225 }
1226
1227 if (Info.getNoReturn())
1228 OS << " __attribute__((noreturn))";
1229 if (Info.getCmseNSCall())
1230 OS << " __attribute__((cmse_nonsecure_call))";
1231 if (Info.getProducesResult())
1232 OS << " __attribute__((ns_returns_retained))";
1233 if (Info.getRegParm())
1234 OS << " __attribute__((regparm ("
1235 << Info.getRegParm() << ")))";
1236 if (Info.getNoCallerSavedRegs())
1237 OS << " __attribute__((no_caller_saved_registers))";
1238 if (Info.getNoCfCheck())
1239 OS << " __attribute__((nocf_check))";
1240}
1241
1242void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1243 raw_ostream &OS) {
1244 // If needed for precedence reasons, wrap the inner part in grouping parens.
1245 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1246 printBefore(T: T->getReturnType(), OS);
1247 if (!PrevPHIsEmpty.get())
1248 OS << '(';
1249}
1250
1251void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1252 raw_ostream &OS) {
1253 // If needed for precedence reasons, wrap the inner part in grouping parens.
1254 if (!HasEmptyPlaceHolder)
1255 OS << ')';
1256 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1257
1258 OS << "()";
1259 printFunctionAfter(Info: T->getExtInfo(), OS);
1260 printAfter(t: T->getReturnType(), OS);
1261}
1262
1263void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1264
1265 // Compute the full nested-name-specifier for this type.
1266 // In C, this will always be empty except when the type
1267 // being printed is anonymous within other Record.
1268 if (!Policy.SuppressScope)
1269 D->printNestedNameSpecifier(OS, Policy);
1270
1271 IdentifierInfo *II = D->getIdentifier();
1272 OS << II->getName();
1273 spaceBeforePlaceHolder(OS);
1274}
1275
1276void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1277 raw_ostream &OS) {
1278 OS << TypeWithKeyword::getKeywordName(Keyword: T->getKeyword());
1279 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1280 OS << ' ';
1281 auto *D = T->getDecl();
1282 if (Policy.FullyQualifiedName || T->isCanonicalUnqualified()) {
1283 D->printNestedNameSpecifier(OS, Policy);
1284 } else {
1285 T->getQualifier().print(OS, Policy);
1286 }
1287 OS << D->getIdentifier()->getName();
1288 spaceBeforePlaceHolder(OS);
1289}
1290
1291void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1292 raw_ostream &OS) {}
1293
1294void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1295 OS << TypeWithKeyword::getKeywordName(Keyword: T->getKeyword());
1296 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1297 OS << ' ';
1298 auto *D = T->getDecl();
1299 if (Policy.FullyQualifiedName) {
1300 D->printNestedNameSpecifier(OS, Policy);
1301 } else {
1302 T->getQualifier().print(OS, Policy);
1303 }
1304 OS << D->getIdentifier()->getName();
1305 spaceBeforePlaceHolder(OS);
1306}
1307
1308void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1309
1310void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1311 OS << TypeWithKeyword::getKeywordName(Keyword: T->getKeyword());
1312 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1313 OS << ' ';
1314 auto *D = T->getDecl();
1315 if (Policy.FullyQualifiedName) {
1316 D->printNestedNameSpecifier(OS, Policy);
1317 } else {
1318 T->getQualifier().print(OS, Policy);
1319 }
1320 OS << D->getIdentifier()->getName();
1321 spaceBeforePlaceHolder(OS);
1322}
1323
1324void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1325 raw_ostream &OS) {
1326 StringRef MacroName = T->getMacroIdentifier()->getName();
1327 OS << MacroName << " ";
1328
1329 // Since this type is meant to print the macro instead of the whole attribute,
1330 // we trim any attributes and go directly to the original modified type.
1331 printBefore(T: T->getModifiedType(), OS);
1332}
1333
1334void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1335 raw_ostream &OS) {
1336 printAfter(t: T->getModifiedType(), OS);
1337}
1338
1339void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1340
1341void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1342 raw_ostream &OS) {
1343 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1344 : "typeof ");
1345 if (T->getUnderlyingExpr())
1346 T->getUnderlyingExpr()->printPretty(OS, Helper: nullptr, Policy);
1347 spaceBeforePlaceHolder(OS);
1348}
1349
1350void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1351 raw_ostream &OS) {}
1352
1353void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1354 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1355 : "typeof(");
1356 print(t: T->getUnmodifiedType(), OS, PlaceHolder: StringRef());
1357 OS << ')';
1358 spaceBeforePlaceHolder(OS);
1359}
1360
1361void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1362
1363void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1364 OS << "decltype(";
1365 if (const Expr *E = T->getUnderlyingExpr()) {
1366 PrintingPolicy ExprPolicy = Policy;
1367 ExprPolicy.PrintAsCanonical = T->isCanonicalUnqualified();
1368 E->printPretty(OS, Helper: nullptr, Policy: ExprPolicy);
1369 }
1370 OS << ')';
1371 spaceBeforePlaceHolder(OS);
1372}
1373
1374void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1375 raw_ostream &OS) {
1376 if (T->hasSelectedType()) {
1377 OS << T->getSelectedType();
1378 } else {
1379 OS << T->getPattern() << "...[";
1380 T->getIndexExpr()->printPretty(OS, Helper: nullptr, Policy);
1381 OS << "]";
1382 }
1383 spaceBeforePlaceHolder(OS);
1384}
1385
1386void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1387 raw_ostream &OS) {}
1388
1389void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1390
1391void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1392 raw_ostream &OS) {
1393 IncludeStrongLifetimeRAII Strong(Policy);
1394
1395 static const llvm::DenseMap<int, const char *> Transformation = {{
1396#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1397 {UnaryTransformType::Enum, "__" #Trait},
1398#include "clang/Basic/TransformTypeTraits.def"
1399 }};
1400 OS << Transformation.lookup(Val: T->getUTTKind()) << '(';
1401 print(t: T->getBaseType(), OS, PlaceHolder: StringRef());
1402 OS << ')';
1403 spaceBeforePlaceHolder(OS);
1404}
1405
1406void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1407 raw_ostream &OS) {}
1408
1409void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1410 // If the type has been deduced, do not print 'auto'.
1411 if (!T->getDeducedType().isNull()) {
1412 printBefore(T: T->getDeducedType(), OS);
1413 } else {
1414 if (T->isConstrained()) {
1415 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1416 // type as it was written.
1417 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1418 auto Args = T->getTypeConstraintArguments();
1419 if (!Args.empty())
1420 printTemplateArgumentList(
1421 OS, Args, Policy,
1422 TPL: T->getTypeConstraintConcept()->getTemplateParameters());
1423 OS << ' ';
1424 }
1425 switch (T->getKeyword()) {
1426 case AutoTypeKeyword::Auto: OS << "auto"; break;
1427 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1428 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1429 }
1430 spaceBeforePlaceHolder(OS);
1431 }
1432}
1433
1434void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1435 // If the type has been deduced, do not print 'auto'.
1436 if (!T->getDeducedType().isNull())
1437 printAfter(t: T->getDeducedType(), OS);
1438}
1439
1440void TypePrinter::printDeducedTemplateSpecializationBefore(
1441 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1442 if (ElaboratedTypeKeyword Keyword = T->getKeyword();
1443 T->getKeyword() != ElaboratedTypeKeyword::None)
1444 OS << KeywordHelpers::getKeywordName(Keyword) << ' ';
1445
1446 TemplateName Name = T->getTemplateName();
1447
1448 // If the type has been deduced, print the template arguments, as if this was
1449 // printing the deduced type, but including elaboration and template name
1450 // qualification.
1451 // FIXME: There should probably be a policy which controls this.
1452 // We would probably want to do this on diagnostics, but not on -ast-print.
1453 ArrayRef<TemplateArgument> Args;
1454 TemplateDecl *DeducedTD = nullptr;
1455 if (!T->getDeducedType().isNull()) {
1456 if (const auto *TST =
1457 dyn_cast<TemplateSpecializationType>(Val: T->getDeducedType())) {
1458 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1459 /*IgnoreDeduced=*/true);
1460 Args = TST->template_arguments();
1461 } else {
1462 // Should only get here for canonical types.
1463 const auto *CD = cast<ClassTemplateSpecializationDecl>(
1464 Val: cast<RecordType>(Val: T->getDeducedType())->getDecl());
1465 DeducedTD = CD->getSpecializedTemplate();
1466 Args = CD->getTemplateArgs().asArray();
1467 }
1468
1469 // FIXME: Workaround for alias template CTAD not producing guides which
1470 // include the alias template specialization type.
1471 // Purposefully disregard qualification when building this TemplateName;
1472 // any qualification we might have, might not make sense in the
1473 // context this was deduced.
1474 if (!declaresSameEntity(D1: DeducedTD, D2: Name.getAsTemplateDecl(
1475 /*IgnoreDeduced=*/true)))
1476 Name = TemplateName(DeducedTD);
1477 }
1478
1479 {
1480 IncludeStrongLifetimeRAII Strong(Policy);
1481 Name.print(OS, Policy);
1482 }
1483 if (DeducedTD) {
1484 printTemplateArgumentList(OS, Args, Policy,
1485 TPL: DeducedTD->getTemplateParameters());
1486 }
1487
1488 spaceBeforePlaceHolder(OS);
1489}
1490
1491void TypePrinter::printDeducedTemplateSpecializationAfter(
1492 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1493 // If the type has been deduced, print the deduced type.
1494 if (!T->getDeducedType().isNull())
1495 printAfter(t: T->getDeducedType(), OS);
1496}
1497
1498void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1499 IncludeStrongLifetimeRAII Strong(Policy);
1500
1501 OS << "_Atomic(";
1502 print(t: T->getValueType(), OS, PlaceHolder: StringRef());
1503 OS << ')';
1504 spaceBeforePlaceHolder(OS);
1505}
1506
1507void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1508
1509void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1510 IncludeStrongLifetimeRAII Strong(Policy);
1511
1512 if (T->isReadOnly())
1513 OS << "read_only ";
1514 else
1515 OS << "write_only ";
1516 OS << "pipe ";
1517 print(t: T->getElementType(), OS, PlaceHolder: StringRef());
1518 spaceBeforePlaceHolder(OS);
1519}
1520
1521void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1522
1523void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1524 if (T->isUnsigned())
1525 OS << "unsigned ";
1526 OS << "_BitInt(" << T->getNumBits() << ")";
1527 spaceBeforePlaceHolder(OS);
1528}
1529
1530void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1531
1532void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1533 raw_ostream &OS) {
1534 if (T->isUnsigned())
1535 OS << "unsigned ";
1536 OS << "_BitInt(";
1537 T->getNumBitsExpr()->printPretty(OS, Helper: nullptr, Policy);
1538 OS << ")";
1539 spaceBeforePlaceHolder(OS);
1540}
1541
1542void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1543 raw_ostream &OS) {}
1544
1545void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,
1546 raw_ostream &OS) {
1547 OS << T->getIdentifier()->getName();
1548 spaceBeforePlaceHolder(OS);
1549}
1550
1551void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,
1552 raw_ostream &OS) {}
1553
1554void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
1555 TagDecl *D = T->getDecl();
1556
1557 if (Policy.IncludeTagDefinition && T->isTagOwned()) {
1558 D->print(Out&: OS, Policy, Indentation);
1559 spaceBeforePlaceHolder(OS);
1560 return;
1561 }
1562
1563 bool PrintedKindDecoration = false;
1564 if (T->isCanonicalUnqualified()) {
1565 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1566 PrintedKindDecoration = true;
1567 OS << D->getKindName();
1568 OS << ' ';
1569 }
1570 } else {
1571 OS << TypeWithKeyword::getKeywordName(Keyword: T->getKeyword());
1572 if (T->getKeyword() != ElaboratedTypeKeyword::None) {
1573 PrintedKindDecoration = true;
1574 OS << ' ';
1575 }
1576 }
1577
1578 if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
1579 T->getQualifier().print(OS, Policy);
1580 } else if (!Policy.SuppressScope) {
1581 // Compute the full nested-name-specifier for this type.
1582 // In C, this will always be empty except when the type
1583 // being printed is anonymous within other Record.
1584 D->printNestedNameSpecifier(OS, Policy);
1585 }
1586
1587 if (const IdentifierInfo *II = D->getIdentifier())
1588 OS << II->getName();
1589 else {
1590 clang::PrintingPolicy Copy(Policy);
1591
1592 // Suppress the redundant tag keyword if we just printed one.
1593 if (PrintedKindDecoration) {
1594 Copy.SuppressTagKeywordInAnonNames = true;
1595 Copy.SuppressTagKeyword = true;
1596 }
1597
1598 D->printName(OS, Policy: Copy);
1599 }
1600
1601 // If this is a class template specialization, print the template
1602 // arguments.
1603 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(Val: D)) {
1604 const TemplateParameterList *TParams =
1605 S->getSpecializedTemplate()->getTemplateParameters();
1606 const ASTTemplateArgumentListInfo *TArgAsWritten =
1607 S->getTemplateArgsAsWritten();
1608 IncludeStrongLifetimeRAII Strong(Policy);
1609 if (TArgAsWritten && !Policy.PrintAsCanonical)
1610 printTemplateArgumentList(OS, Args: TArgAsWritten->arguments(), Policy,
1611 TPL: TParams);
1612 else
1613 printTemplateArgumentList(OS, Args: S->getTemplateArgs().asArray(), Policy,
1614 TPL: TParams);
1615 }
1616
1617 spaceBeforePlaceHolder(OS);
1618}
1619
1620void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1621 // Print the preferred name if we have one for this type.
1622 if (Policy.UsePreferredNames) {
1623 for (const auto *PNA : T->getDecl()
1624 ->getMostRecentDecl()
1625 ->specific_attrs<PreferredNameAttr>()) {
1626 if (!declaresSameEntity(D1: PNA->getTypedefType()->getAsCXXRecordDecl(),
1627 D2: T->getDecl()))
1628 continue;
1629 // Find the outermost typedef or alias template.
1630 QualType T = PNA->getTypedefType();
1631 while (true) {
1632 if (auto *TT = dyn_cast<TypedefType>(Val&: T))
1633 return printTypeSpec(D: TT->getDecl(), OS);
1634 if (auto *TST = dyn_cast<TemplateSpecializationType>(Val&: T))
1635 return printTemplateId(T: TST, OS, /*FullyQualify=*/true);
1636 T = T->getLocallyUnqualifiedSingleStepDesugaredType();
1637 }
1638 }
1639 }
1640
1641 printTagType(T, OS);
1642}
1643
1644void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1645
1646void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1647 printTagType(T, OS);
1648}
1649
1650void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1651
1652void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1653 raw_ostream &OS) {
1654 const ASTContext &Ctx = T->getDecl()->getASTContext();
1655 IncludeStrongLifetimeRAII Strong(Policy);
1656 T->getTemplateName(Ctx).print(OS, Policy);
1657 if (Policy.PrintInjectedClassNameWithArguments) {
1658 auto *Decl = T->getDecl();
1659 // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
1660 // arguments.
1661 if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Val: Decl)) {
1662 printTemplateArgumentList(OS, Args: RD->getTemplateArgsAsWritten()->arguments(),
1663 Policy,
1664 TPL: T->getTemplateDecl()->getTemplateParameters());
1665 } else {
1666 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
1667 assert(TD);
1668 printTemplateArgumentList(
1669 OS, Args: TD->getTemplateParameters()->getInjectedTemplateArgs(Context: Ctx), Policy,
1670 TPL: T->getTemplateDecl()->getTemplateParameters());
1671 }
1672 }
1673 spaceBeforePlaceHolder(OS);
1674}
1675
1676void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1677 raw_ostream &OS) {}
1678
1679void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1680 raw_ostream &OS) {
1681 TemplateTypeParmDecl *D = T->getDecl();
1682 if (D && D->isImplicit()) {
1683 if (auto *TC = D->getTypeConstraint()) {
1684 TC->print(OS, Policy);
1685 OS << ' ';
1686 }
1687 OS << "auto";
1688 } else if (IdentifierInfo *Id = T->getIdentifier())
1689 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1690 : Id->getName());
1691 else
1692 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1693
1694 spaceBeforePlaceHolder(OS);
1695}
1696
1697void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1698 raw_ostream &OS) {}
1699
1700void TypePrinter::printSubstTemplateTypeParmBefore(
1701 const SubstTemplateTypeParmType *T,
1702 raw_ostream &OS) {
1703 IncludeStrongLifetimeRAII Strong(Policy);
1704 printBefore(T: T->getReplacementType(), OS);
1705}
1706
1707void TypePrinter::printSubstTemplateTypeParmAfter(
1708 const SubstTemplateTypeParmType *T,
1709 raw_ostream &OS) {
1710 IncludeStrongLifetimeRAII Strong(Policy);
1711 printAfter(t: T->getReplacementType(), OS);
1712}
1713
1714void TypePrinter::printSubstBuiltinTemplatePackBefore(
1715 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
1716 IncludeStrongLifetimeRAII Strong(Policy);
1717 OS << "type-pack";
1718}
1719
1720void TypePrinter::printSubstBuiltinTemplatePackAfter(
1721 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
1722
1723void TypePrinter::printSubstTemplateTypeParmPackBefore(
1724 const SubstTemplateTypeParmPackType *T,
1725 raw_ostream &OS) {
1726 IncludeStrongLifetimeRAII Strong(Policy);
1727 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1728 if (D && D->isImplicit()) {
1729 if (auto *TC = D->getTypeConstraint()) {
1730 TC->print(OS, Policy);
1731 OS << ' ';
1732 }
1733 OS << "auto";
1734 } else if (IdentifierInfo *Id = D->getIdentifier())
1735 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1736 : Id->getName());
1737 else
1738 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1739
1740 spaceBeforePlaceHolder(OS);
1741 }
1742}
1743
1744void TypePrinter::printSubstTemplateTypeParmPackAfter(
1745 const SubstTemplateTypeParmPackType *T,
1746 raw_ostream &OS) {
1747 IncludeStrongLifetimeRAII Strong(Policy);
1748}
1749
1750void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1751 raw_ostream &OS, bool FullyQualify) {
1752 IncludeStrongLifetimeRAII Strong(Policy);
1753
1754 if (ElaboratedTypeKeyword K = T->getKeyword();
1755 K != ElaboratedTypeKeyword::None)
1756 OS << TypeWithKeyword::getKeywordName(Keyword: K) << ' ';
1757
1758 TemplateDecl *TD =
1759 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1760 // FIXME: Null TD never exercised in test suite.
1761 if (FullyQualify && TD) {
1762 if (!Policy.SuppressScope)
1763 TD->printNestedNameSpecifier(OS, Policy);
1764
1765 OS << TD->getName();
1766 } else {
1767 T->getTemplateName().print(OS, Policy,
1768 Qual: !Policy.SuppressScope
1769 ? TemplateName::Qualified::AsWritten
1770 : TemplateName::Qualified::None);
1771 }
1772
1773 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1774 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1775 printTemplateArgumentList(OS, Args: T->template_arguments(), Policy, TPL);
1776 spaceBeforePlaceHolder(OS);
1777}
1778
1779void TypePrinter::printTemplateSpecializationBefore(
1780 const TemplateSpecializationType *T,
1781 raw_ostream &OS) {
1782 printTemplateId(T, OS, FullyQualify: Policy.FullyQualifiedName);
1783}
1784
1785void TypePrinter::printTemplateSpecializationAfter(
1786 const TemplateSpecializationType *T,
1787 raw_ostream &OS) {}
1788
1789void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1790 if (!HasEmptyPlaceHolder && !isa<FunctionType>(Val: T->getInnerType())) {
1791 printBefore(T: T->getInnerType(), OS);
1792 OS << '(';
1793 } else
1794 printBefore(T: T->getInnerType(), OS);
1795}
1796
1797void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1798 if (!HasEmptyPlaceHolder && !isa<FunctionType>(Val: T->getInnerType())) {
1799 OS << ')';
1800 printAfter(t: T->getInnerType(), OS);
1801 } else
1802 printAfter(t: T->getInnerType(), OS);
1803}
1804
1805void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1806 raw_ostream &OS) {
1807 OS << TypeWithKeyword::getKeywordName(Keyword: T->getKeyword());
1808 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1809 OS << " ";
1810 T->getQualifier().print(OS, Policy);
1811 OS << T->getIdentifier()->getName();
1812 spaceBeforePlaceHolder(OS);
1813}
1814
1815void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1816 raw_ostream &OS) {}
1817
1818void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1819 raw_ostream &OS) {
1820 printBefore(T: T->getPattern(), OS);
1821}
1822
1823void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1824 raw_ostream &OS) {
1825 printAfter(t: T->getPattern(), OS);
1826 OS << "...";
1827}
1828
1829static void printCountAttributedImpl(const CountAttributedType *T,
1830 raw_ostream &OS,
1831 const PrintingPolicy &Policy) {
1832 OS << ' ';
1833 if (T->isCountInBytes() && T->isOrNull())
1834 OS << "__sized_by_or_null(";
1835 else if (T->isCountInBytes())
1836 OS << "__sized_by(";
1837 else if (T->isOrNull())
1838 OS << "__counted_by_or_null(";
1839 else
1840 OS << "__counted_by(";
1841 if (T->getCountExpr())
1842 T->getCountExpr()->printPretty(OS, Helper: nullptr, Policy);
1843 OS << ')';
1844}
1845
1846void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1847 raw_ostream &OS) {
1848 printBefore(T: T->desugar(), OS);
1849 if (!T->isArrayType())
1850 printCountAttributedImpl(T, OS, Policy);
1851}
1852
1853void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1854 raw_ostream &OS) {
1855 printAfter(t: T->desugar(), OS);
1856 if (T->isArrayType())
1857 printCountAttributedImpl(T, OS, Policy);
1858}
1859
1860void TypePrinter::printAttributedBefore(const AttributedType *T,
1861 raw_ostream &OS) {
1862 // FIXME: Generate this with TableGen.
1863
1864 // Prefer the macro forms of the GC and ownership qualifiers.
1865 if (T->getAttrKind() == attr::ObjCGC ||
1866 T->getAttrKind() == attr::ObjCOwnership)
1867 return printBefore(T: T->getEquivalentType(), OS);
1868
1869 if (T->getAttrKind() == attr::ObjCKindOf)
1870 OS << "__kindof ";
1871
1872 if (T->getAttrKind() == attr::PreserveNone) {
1873 OS << "__attribute__((preserve_none)) ";
1874 spaceBeforePlaceHolder(OS);
1875 } else if (T->getAttrKind() == attr::PreserveMost) {
1876 OS << "__attribute__((preserve_most)) ";
1877 spaceBeforePlaceHolder(OS);
1878 } else if (T->getAttrKind() == attr::PreserveAll) {
1879 OS << "__attribute__((preserve_all)) ";
1880 spaceBeforePlaceHolder(OS);
1881 }
1882
1883 if (T->getAttrKind() == attr::AddressSpace)
1884 printBefore(T: T->getEquivalentType(), OS);
1885 else
1886 printBefore(T: T->getModifiedType(), OS);
1887
1888 if (T->isMSTypeSpec()) {
1889 switch (T->getAttrKind()) {
1890 default: return;
1891 case attr::Ptr32: OS << " __ptr32"; break;
1892 case attr::Ptr64: OS << " __ptr64"; break;
1893 case attr::SPtr: OS << " __sptr"; break;
1894 case attr::UPtr: OS << " __uptr"; break;
1895 }
1896 spaceBeforePlaceHolder(OS);
1897 }
1898
1899 if (T->isWebAssemblyFuncrefSpec())
1900 OS << "__funcref";
1901
1902 // Print nullability type specifiers.
1903 if (T->getImmediateNullability()) {
1904 if (T->getAttrKind() == attr::TypeNonNull)
1905 OS << " _Nonnull";
1906 else if (T->getAttrKind() == attr::TypeNullable)
1907 OS << " _Nullable";
1908 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1909 OS << " _Null_unspecified";
1910 else if (T->getAttrKind() == attr::TypeNullableResult)
1911 OS << " _Nullable_result";
1912 else
1913 llvm_unreachable("unhandled nullability");
1914 spaceBeforePlaceHolder(OS);
1915 }
1916}
1917
1918void TypePrinter::printAttributedAfter(const AttributedType *T,
1919 raw_ostream &OS) {
1920 // FIXME: Generate this with TableGen.
1921
1922 // Prefer the macro forms of the GC and ownership qualifiers.
1923 if (T->getAttrKind() == attr::ObjCGC ||
1924 T->getAttrKind() == attr::ObjCOwnership)
1925 return printAfter(t: T->getEquivalentType(), OS);
1926
1927 // If this is a calling convention attribute, don't print the implicit CC from
1928 // the modified type.
1929 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1930
1931 printAfter(t: T->getModifiedType(), OS);
1932
1933 // Some attributes are printed as qualifiers before the type, so we have
1934 // nothing left to do.
1935 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1936 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1937 return;
1938
1939 // Don't print the inert __unsafe_unretained attribute at all.
1940 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1941 return;
1942
1943 // Don't print ns_returns_retained unless it had an effect.
1944 if (T->getAttrKind() == attr::NSReturnsRetained &&
1945 !T->getEquivalentType()->castAs<FunctionType>()
1946 ->getExtInfo().getProducesResult())
1947 return;
1948
1949 if (T->getAttrKind() == attr::LifetimeBound) {
1950 OS << " [[clang::lifetimebound]]";
1951 return;
1952 }
1953 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1954 OS << " [[clang::lifetime_capture_by(";
1955 if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(Val: T->getAttr()))
1956 llvm::interleaveComma(c: attr->getArgIdents(), os&: OS,
1957 each_fn: [&](auto it) { OS << it->getName(); });
1958 OS << ")]]";
1959 return;
1960 }
1961
1962 // The printing of the address_space attribute is handled by the qualifier
1963 // since it is still stored in the qualifier. Return early to prevent printing
1964 // this twice.
1965 if (T->getAttrKind() == attr::AddressSpace)
1966 return;
1967
1968 if (T->getAttrKind() == attr::AnnotateType) {
1969 // FIXME: Print the attribute arguments once we have a way to retrieve these
1970 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1971 // without the arguments so that we know at least that we had _some_
1972 // annotation on the type.
1973 OS << " [[clang::annotate_type(...)]]";
1974 return;
1975 }
1976
1977 if (T->getAttrKind() == attr::ArmStreaming) {
1978 OS << "__arm_streaming";
1979 return;
1980 }
1981 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1982 OS << "__arm_streaming_compatible";
1983 return;
1984 }
1985
1986 if (T->getAttrKind() == attr::SwiftAttr) {
1987 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(Val: T->getAttr())) {
1988 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1989 << "\")))";
1990 }
1991 return;
1992 }
1993
1994 if (T->getAttrKind() == attr::PreserveAll ||
1995 T->getAttrKind() == attr::PreserveMost ||
1996 T->getAttrKind() == attr::PreserveNone) {
1997 // This has to be printed before the type.
1998 return;
1999 }
2000
2001 OS << " __attribute__((";
2002 switch (T->getAttrKind()) {
2003#define TYPE_ATTR(NAME)
2004#define DECL_OR_TYPE_ATTR(NAME)
2005#define ATTR(NAME) case attr::NAME:
2006#include "clang/Basic/AttrList.inc"
2007 llvm_unreachable("non-type attribute attached to type");
2008
2009 case attr::BTFTypeTag:
2010 llvm_unreachable("BTFTypeTag attribute handled separately");
2011
2012 case attr::HLSLResourceClass:
2013 case attr::HLSLROV:
2014 case attr::HLSLRawBuffer:
2015 case attr::HLSLContainedType:
2016 case attr::HLSLIsCounter:
2017 case attr::HLSLResourceDimension:
2018 case attr::HLSLIsArray:
2019 llvm_unreachable("HLSL resource type attributes handled separately");
2020
2021 case attr::OpenCLPrivateAddressSpace:
2022 case attr::OpenCLGlobalAddressSpace:
2023 case attr::OpenCLGlobalDeviceAddressSpace:
2024 case attr::OpenCLGlobalHostAddressSpace:
2025 case attr::OpenCLLocalAddressSpace:
2026 case attr::OpenCLConstantAddressSpace:
2027 case attr::OpenCLGenericAddressSpace:
2028 case attr::HLSLGroupSharedAddressSpace:
2029 // FIXME: Update printAttributedBefore to print these once we generate
2030 // AttributedType nodes for them.
2031 break;
2032
2033 case attr::CountedBy:
2034 case attr::CountedByOrNull:
2035 case attr::SizedBy:
2036 case attr::SizedByOrNull:
2037 case attr::LifetimeBound:
2038 case attr::LifetimeCaptureBy:
2039 case attr::TypeNonNull:
2040 case attr::TypeNullable:
2041 case attr::TypeNullableResult:
2042 case attr::TypeNullUnspecified:
2043 case attr::ObjCGC:
2044 case attr::ObjCInertUnsafeUnretained:
2045 case attr::ObjCKindOf:
2046 case attr::ObjCOwnership:
2047 case attr::Ptr32:
2048 case attr::Ptr64:
2049 case attr::SPtr:
2050 case attr::UPtr:
2051 case attr::PointerAuth:
2052 case attr::AddressSpace:
2053 case attr::CmseNSCall:
2054 case attr::AnnotateType:
2055 case attr::WebAssemblyFuncref:
2056 case attr::ArmAgnostic:
2057 case attr::ArmStreaming:
2058 case attr::ArmStreamingCompatible:
2059 case attr::ArmIn:
2060 case attr::ArmOut:
2061 case attr::ArmInOut:
2062 case attr::ArmPreserves:
2063 case attr::NonBlocking:
2064 case attr::NonAllocating:
2065 case attr::Blocking:
2066 case attr::Allocating:
2067 case attr::SwiftAttr:
2068 case attr::PreserveAll:
2069 case attr::PreserveMost:
2070 case attr::PreserveNone:
2071 case attr::OverflowBehavior:
2072 llvm_unreachable("This attribute should have been handled already");
2073
2074 case attr::NSReturnsRetained:
2075 OS << "ns_returns_retained";
2076 break;
2077
2078 case attr::HLSLRowMajor:
2079 OS << "row_major";
2080 break;
2081 case attr::HLSLColumnMajor:
2082 OS << "column_major";
2083 break;
2084
2085 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2086 // attribute again in printFunctionProtoAfter.
2087 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2088 case attr::CDecl: OS << "cdecl"; break;
2089 case attr::FastCall: OS << "fastcall"; break;
2090 case attr::StdCall: OS << "stdcall"; break;
2091 case attr::ThisCall: OS << "thiscall"; break;
2092 case attr::SwiftCall: OS << "swiftcall"; break;
2093 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2094 case attr::VectorCall: OS << "vectorcall"; break;
2095 case attr::Pascal: OS << "pascal"; break;
2096 case attr::MSABI: OS << "ms_abi"; break;
2097 case attr::SysVABI: OS << "sysv_abi"; break;
2098 case attr::RegCall: OS << "regcall"; break;
2099 case attr::Pcs: {
2100 OS << "pcs(";
2101 QualType t = T->getEquivalentType();
2102 while (!t->isFunctionType())
2103 t = t->getPointeeType();
2104 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2105 "\"aapcs\"" : "\"aapcs-vfp\"");
2106 OS << ')';
2107 break;
2108 }
2109 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2110 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2111 case attr::IntelOclBicc:
2112 OS << "inteloclbicc";
2113 break;
2114 case attr::M68kRTD:
2115 OS << "m68k_rtd";
2116 break;
2117 case attr::RISCVVectorCC:
2118 OS << "riscv_vector_cc";
2119 break;
2120 case attr::RISCVVLSCC:
2121 OS << "riscv_vls_cc";
2122 break;
2123 case attr::NoDeref:
2124 OS << "noderef";
2125 break;
2126 case attr::CFIUncheckedCallee:
2127 OS << "cfi_unchecked_callee";
2128 break;
2129 case attr::AcquireHandle:
2130 OS << "acquire_handle";
2131 break;
2132 case attr::ArmMveStrictPolymorphism:
2133 OS << "__clang_arm_mve_strict_polymorphism";
2134 break;
2135 case attr::ExtVectorType:
2136 OS << "ext_vector_type";
2137 break;
2138 case attr::CFISalt:
2139 OS << "cfi_salt(\"" << cast<CFISaltAttr>(Val: T->getAttr())->getSalt() << "\")";
2140 break;
2141 case attr::NoFieldProtection:
2142 OS << "no_field_protection";
2143 break;
2144 case attr::PointerFieldProtection:
2145 OS << "pointer_field_protection";
2146 break;
2147 }
2148 OS << "))";
2149}
2150
2151void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2152 raw_ostream &OS) {
2153 printBefore(T: T->getWrappedType(), OS);
2154 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2155}
2156
2157void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2158 raw_ostream &OS) {
2159 printAfter(t: T->getWrappedType(), OS);
2160}
2161
2162void TypePrinter::printOverflowBehaviorBefore(const OverflowBehaviorType *T,
2163 raw_ostream &OS) {
2164 switch (T->getBehaviorKind()) {
2165 case clang::OverflowBehaviorType::OverflowBehaviorKind::Wrap:
2166 OS << "__ob_wrap ";
2167 break;
2168 case clang::OverflowBehaviorType::OverflowBehaviorKind::Trap:
2169 OS << "__ob_trap ";
2170 break;
2171 }
2172 printBefore(T: T->getUnderlyingType(), OS);
2173}
2174
2175void TypePrinter::printOverflowBehaviorAfter(const OverflowBehaviorType *T,
2176 raw_ostream &OS) {
2177 printAfter(t: T->getUnderlyingType(), OS);
2178}
2179
2180void TypePrinter::printHLSLAttributedResourceBefore(
2181 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2182 printBefore(T: T->getWrappedType(), OS);
2183}
2184
2185void TypePrinter::printHLSLAttributedResourceAfter(
2186 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2187 printAfter(t: T->getWrappedType(), OS);
2188 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2189 OS << " [[hlsl::resource_class("
2190 << HLSLResourceClassAttr::ConvertResourceClassToStr(Val: Attrs.ResourceClass)
2191 << ")]]";
2192 if (Attrs.IsROV)
2193 OS << " [[hlsl::is_rov]]";
2194 if (Attrs.RawBuffer)
2195 OS << " [[hlsl::raw_buffer]]";
2196 if (Attrs.IsCounter)
2197 OS << " [[hlsl::is_counter]]";
2198 if (Attrs.IsArray)
2199 OS << " [[hlsl::is_array]]";
2200
2201 QualType ContainedTy = T->getContainedType();
2202 if (!ContainedTy.isNull()) {
2203 OS << " [[hlsl::contained_type(";
2204 printBefore(T: ContainedTy, OS);
2205 printAfter(t: ContainedTy, OS);
2206 OS << ")]]";
2207 }
2208
2209 if (Attrs.ResourceDimension != llvm::dxil::ResourceDimension::Unknown)
2210 OS << " [[hlsl::resource_dimension("
2211 << HLSLResourceDimensionAttr::ConvertResourceDimensionToStr(
2212 Val: Attrs.ResourceDimension)
2213 << ")]]";
2214}
2215
2216void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2217 raw_ostream &OS) {
2218 OS << "__hlsl_spirv_type<" << T->getOpcode();
2219
2220 OS << ", " << T->getSize();
2221 OS << ", " << T->getAlignment();
2222
2223 for (auto &Operand : T->getOperands()) {
2224 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2225
2226 OS << ", ";
2227 switch (Operand.getKind()) {
2228 case SpirvOperandKind::ConstantId: {
2229 QualType ConstantType = Operand.getResultType();
2230 OS << "vk::integral_constant<";
2231 printBefore(T: ConstantType, OS);
2232 printAfter(t: ConstantType, OS);
2233 OS << ", ";
2234 OS << Operand.getValue();
2235 OS << ">";
2236 break;
2237 }
2238 case SpirvOperandKind::Literal:
2239 OS << "vk::Literal<vk::integral_constant<uint, ";
2240 OS << Operand.getValue();
2241 OS << ">>";
2242 break;
2243 case SpirvOperandKind::TypeId: {
2244 QualType Type = Operand.getResultType();
2245 printBefore(T: Type, OS);
2246 printAfter(t: Type, OS);
2247 break;
2248 }
2249 default:
2250 llvm_unreachable("Invalid SpirvOperand kind!");
2251 break;
2252 }
2253 }
2254
2255 OS << ">";
2256}
2257
2258void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2259 raw_ostream &OS) {
2260 // nothing to do
2261}
2262
2263void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2264 raw_ostream &OS) {
2265 OS << T->getDecl()->getName();
2266 spaceBeforePlaceHolder(OS);
2267}
2268
2269void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2270 raw_ostream &OS) {}
2271
2272void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2273 raw_ostream &OS) {
2274 OS << T->getDecl()->getName();
2275 if (!T->qual_empty()) {
2276 bool isFirst = true;
2277 OS << '<';
2278 for (const auto *I : T->quals()) {
2279 if (isFirst)
2280 isFirst = false;
2281 else
2282 OS << ',';
2283 OS << I->getName();
2284 }
2285 OS << '>';
2286 }
2287
2288 spaceBeforePlaceHolder(OS);
2289}
2290
2291void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2292 raw_ostream &OS) {}
2293
2294void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2295 raw_ostream &OS) {
2296 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2297 !T->isKindOfTypeAsWritten())
2298 return printBefore(T: T->getBaseType(), OS);
2299
2300 if (T->isKindOfTypeAsWritten())
2301 OS << "__kindof ";
2302
2303 print(t: T->getBaseType(), OS, PlaceHolder: StringRef());
2304
2305 if (T->isSpecializedAsWritten()) {
2306 bool isFirst = true;
2307 OS << '<';
2308 for (auto typeArg : T->getTypeArgsAsWritten()) {
2309 if (isFirst)
2310 isFirst = false;
2311 else
2312 OS << ",";
2313
2314 print(t: typeArg, OS, PlaceHolder: StringRef());
2315 }
2316 OS << '>';
2317 }
2318
2319 if (!T->qual_empty()) {
2320 bool isFirst = true;
2321 OS << '<';
2322 for (const auto *I : T->quals()) {
2323 if (isFirst)
2324 isFirst = false;
2325 else
2326 OS << ',';
2327 OS << I->getName();
2328 }
2329 OS << '>';
2330 }
2331
2332 spaceBeforePlaceHolder(OS);
2333}
2334
2335void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2336 raw_ostream &OS) {
2337 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2338 !T->isKindOfTypeAsWritten())
2339 return printAfter(t: T->getBaseType(), OS);
2340}
2341
2342void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2343 raw_ostream &OS) {
2344 printBefore(T: T->getPointeeType(), OS);
2345
2346 // If we need to print the pointer, print it now.
2347 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2348 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
2349 if (HasEmptyPlaceHolder)
2350 OS << ' ';
2351 OS << '*';
2352 }
2353}
2354
2355void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2356 raw_ostream &OS) {}
2357
2358static
2359const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2360
2361static const TemplateArgument &getArgument(const TemplateArgumentLoc &A) {
2362 return A.getArgument();
2363}
2364
2365static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2366 llvm::raw_ostream &OS, bool IncludeType) {
2367 A.print(Policy: PP, Out&: OS, IncludeType);
2368}
2369
2370static void printArgument(const TemplateArgumentLoc &A,
2371 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2372 bool IncludeType) {
2373 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2374 if (Kind == TemplateArgument::ArgKind::Type)
2375 return A.getTypeSourceInfo()->getType().print(OS, Policy: PP);
2376 return A.getArgument().print(Policy: PP, Out&: OS, IncludeType);
2377}
2378
2379static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2380 TemplateArgument Pattern,
2381 ArrayRef<TemplateArgument> Args,
2382 unsigned Depth);
2383
2384static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern,
2385 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2386 if (Ctx.hasSameType(T1: T, T2: Pattern))
2387 return true;
2388
2389 // A type parameter matches its argument.
2390 if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {
2391 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2392 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2393 QualType SubstArg = Ctx.getQualifiedType(
2394 T: Args[TTPT->getIndex()].getAsType(), Qs: Pattern.getQualifiers());
2395 return Ctx.hasSameType(T1: SubstArg, T2: T);
2396 }
2397 return false;
2398 }
2399
2400 // FIXME: Recurse into array types.
2401
2402 // All other cases will need the types to be identically qualified.
2403 Qualifiers TQual, PatQual;
2404 T = Ctx.getUnqualifiedArrayType(T, Quals&: TQual);
2405 Pattern = Ctx.getUnqualifiedArrayType(T: Pattern, Quals&: PatQual);
2406 if (TQual != PatQual)
2407 return false;
2408
2409 // Recurse into pointer-like types.
2410 {
2411 QualType TPointee = T->getPointeeType();
2412 QualType PPointee = Pattern->getPointeeType();
2413 if (!TPointee.isNull() && !PPointee.isNull())
2414 return T->getTypeClass() == Pattern->getTypeClass() &&
2415 isSubstitutedType(Ctx, T: TPointee, Pattern: PPointee, Args, Depth);
2416 }
2417
2418 // Recurse into template specialization types.
2419 if (auto *PTST =
2420 Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {
2421 TemplateName Template;
2422 ArrayRef<TemplateArgument> TemplateArgs;
2423 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2424 Template = TTST->getTemplateName();
2425 TemplateArgs = TTST->template_arguments();
2426 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2427 Val: T->getAsCXXRecordDecl())) {
2428 Template = TemplateName(CTSD->getSpecializedTemplate());
2429 TemplateArgs = CTSD->getTemplateArgs().asArray();
2430 } else {
2431 return false;
2432 }
2433
2434 if (!isSubstitutedTemplateArgument(Ctx, Arg: Template, Pattern: PTST->getTemplateName(),
2435 Args, Depth))
2436 return false;
2437 if (TemplateArgs.size() != PTST->template_arguments().size())
2438 return false;
2439 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2440 if (!isSubstitutedTemplateArgument(
2441 Ctx, Arg: TemplateArgs[I], Pattern: PTST->template_arguments()[I], Args, Depth))
2442 return false;
2443 return true;
2444 }
2445
2446 // FIXME: Handle more cases.
2447 return false;
2448}
2449
2450/// Evaluates the expression template argument 'Pattern' and returns true
2451/// if 'Arg' evaluates to the same result.
2452static bool templateArgumentExpressionsEqual(ASTContext const &Ctx,
2453 TemplateArgument const &Pattern,
2454 TemplateArgument const &Arg) {
2455 if (Pattern.getKind() != TemplateArgument::Expression)
2456 return false;
2457
2458 // Can't evaluate value-dependent expressions so bail early
2459 Expr const *pattern_expr = Pattern.getAsExpr();
2460 if (pattern_expr->isValueDependent() ||
2461 !pattern_expr->isIntegerConstantExpr(Ctx))
2462 return false;
2463
2464 if (Arg.getKind() == TemplateArgument::Integral)
2465 return llvm::APSInt::isSameValue(I1: pattern_expr->EvaluateKnownConstInt(Ctx),
2466 I2: Arg.getAsIntegral());
2467
2468 if (Arg.getKind() == TemplateArgument::Expression) {
2469 Expr const *args_expr = Arg.getAsExpr();
2470 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2471 return false;
2472
2473 return llvm::APSInt::isSameValue(I1: args_expr->EvaluateKnownConstInt(Ctx),
2474 I2: pattern_expr->EvaluateKnownConstInt(Ctx));
2475 }
2476
2477 return false;
2478}
2479
2480static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2481 TemplateArgument Pattern,
2482 ArrayRef<TemplateArgument> Args,
2483 unsigned Depth) {
2484 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2485 Pattern = Ctx.getCanonicalTemplateArgument(Arg: Pattern);
2486 if (Arg.structurallyEquals(Other: Pattern))
2487 return true;
2488
2489 if (Pattern.getKind() == TemplateArgument::Expression) {
2490 if (auto *DRE =
2491 dyn_cast<DeclRefExpr>(Val: Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2492 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Val: DRE->getDecl()))
2493 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2494 Args[NTTP->getIndex()].structurallyEquals(Other: Arg);
2495 }
2496 }
2497
2498 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2499 return true;
2500
2501 if (Arg.getKind() != Pattern.getKind())
2502 return false;
2503
2504 if (Arg.getKind() == TemplateArgument::Type)
2505 return isSubstitutedType(Ctx, T: Arg.getAsType(), Pattern: Pattern.getAsType(), Args,
2506 Depth);
2507
2508 if (Arg.getKind() == TemplateArgument::Template) {
2509 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2510 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(Val: PatTD))
2511 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2512 Ctx.getCanonicalTemplateArgument(Arg: Args[TTPD->getIndex()])
2513 .structurallyEquals(Other: Arg);
2514 }
2515
2516 // FIXME: Handle more cases.
2517 return false;
2518}
2519
2520bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2521 const NamedDecl *Param,
2522 ArrayRef<TemplateArgument> Args,
2523 unsigned Depth) {
2524 // An empty pack is equivalent to not providing a pack argument.
2525 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2526 return true;
2527
2528 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Param)) {
2529 return TTPD->hasDefaultArgument() &&
2530 isSubstitutedTemplateArgument(
2531 Ctx, Arg, Pattern: TTPD->getDefaultArgument().getArgument(), Args, Depth);
2532 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Param)) {
2533 return TTPD->hasDefaultArgument() &&
2534 isSubstitutedTemplateArgument(
2535 Ctx, Arg, Pattern: TTPD->getDefaultArgument().getArgument(), Args, Depth);
2536 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Val: Param)) {
2537 return NTTPD->hasDefaultArgument() &&
2538 isSubstitutedTemplateArgument(
2539 Ctx, Arg, Pattern: NTTPD->getDefaultArgument().getArgument(), Args,
2540 Depth);
2541 }
2542 return false;
2543}
2544
2545template <typename TA>
2546static void
2547printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2548 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2549 // Drop trailing template arguments that match default arguments.
2550 if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&
2551 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2552 llvm::SmallVector<TemplateArgument, 8> OrigArgs;
2553 for (const TA &A : Args)
2554 OrigArgs.push_back(Elt: getArgument(A));
2555 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2556 Args = Args.drop_back();
2557 }
2558
2559 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2560 if (!IsPack)
2561 OS << '<';
2562
2563 bool NeedSpace = false;
2564 bool FirstArg = true;
2565 for (const auto &Arg : Args) {
2566 // Print the argument into a string.
2567 SmallString<128> Buf;
2568 llvm::raw_svector_ostream ArgOS(Buf);
2569 const TemplateArgument &Argument = getArgument(Arg);
2570 if (Argument.getKind() == TemplateArgument::Pack) {
2571 if (Argument.pack_size() && !FirstArg)
2572 OS << Comma;
2573 printTo(OS&: ArgOS, Args: Argument.getPackAsArray(), Policy, TPL,
2574 /*IsPack*/ true, ParmIndex);
2575 } else {
2576 if (!FirstArg)
2577 OS << Comma;
2578 // Tries to print the argument with location info if exists.
2579 printArgument(Arg, Policy, ArgOS,
2580 TemplateParameterList::shouldIncludeTypeForArgument(
2581 Policy, TPL, Idx: ParmIndex));
2582 }
2583 StringRef ArgString = ArgOS.str();
2584
2585 // If this is the first argument and its string representation
2586 // begins with the global scope specifier ('::foo'), add a space
2587 // to avoid printing the diagraph '<:'.
2588 if (FirstArg && ArgString.starts_with(Prefix: ":"))
2589 OS << ' ';
2590
2591 OS << ArgString;
2592
2593 // If the last character of our string is '>', add another space to
2594 // keep the two '>''s separate tokens.
2595 if (!ArgString.empty()) {
2596 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2597 FirstArg = false;
2598 }
2599
2600 // Use same template parameter for all elements of Pack
2601 if (!IsPack)
2602 ParmIndex++;
2603 }
2604
2605 if (!IsPack) {
2606 if (NeedSpace)
2607 OS << ' ';
2608 OS << '>';
2609 }
2610}
2611
2612void clang::printTemplateArgumentList(raw_ostream &OS,
2613 const TemplateArgumentListInfo &Args,
2614 const PrintingPolicy &Policy,
2615 const TemplateParameterList *TPL) {
2616 printTemplateArgumentList(OS, Args: Args.arguments(), Policy, TPL);
2617}
2618
2619void clang::printTemplateArgumentList(raw_ostream &OS,
2620 ArrayRef<TemplateArgument> Args,
2621 const PrintingPolicy &Policy,
2622 const TemplateParameterList *TPL) {
2623 PrintingPolicy InnerPolicy = Policy;
2624 InnerPolicy.SuppressScope = false;
2625 printTo(OS, Args, Policy: InnerPolicy, TPL, /*isPack*/ IsPack: false, /*parmIndex*/ ParmIndex: 0);
2626}
2627
2628void clang::printTemplateArgumentList(raw_ostream &OS,
2629 ArrayRef<TemplateArgumentLoc> Args,
2630 const PrintingPolicy &Policy,
2631 const TemplateParameterList *TPL) {
2632 PrintingPolicy InnerPolicy = Policy;
2633 InnerPolicy.SuppressScope = false;
2634 printTo(OS, Args, Policy: InnerPolicy, TPL, /*isPack*/ IsPack: false, /*parmIndex*/ ParmIndex: 0);
2635}
2636
2637std::string PointerAuthQualifier::getAsString() const {
2638 LangOptions LO;
2639 return getAsString(Policy: PrintingPolicy(LO));
2640}
2641
2642std::string PointerAuthQualifier::getAsString(const PrintingPolicy &P) const {
2643 SmallString<64> Buf;
2644 llvm::raw_svector_ostream StrOS(Buf);
2645 print(OS&: StrOS, Policy: P);
2646 return StrOS.str().str();
2647}
2648
2649bool PointerAuthQualifier::isEmptyWhenPrinted(const PrintingPolicy &P) const {
2650 return !isPresent();
2651}
2652
2653void PointerAuthQualifier::print(raw_ostream &OS,
2654 const PrintingPolicy &P) const {
2655 if (!isPresent())
2656 return;
2657
2658 OS << "__ptrauth(";
2659 OS << getKey();
2660 OS << "," << unsigned(isAddressDiscriminated()) << ","
2661 << getExtraDiscriminator() << ")";
2662}
2663
2664std::string Qualifiers::getAsString() const {
2665 LangOptions LO;
2666 return getAsString(Policy: PrintingPolicy(LO));
2667}
2668
2669// Appends qualifiers to the given string, separated by spaces. Will
2670// prefix a space if the string is non-empty. Will not append a final
2671// space.
2672std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2673 SmallString<64> Buf;
2674 llvm::raw_svector_ostream StrOS(Buf);
2675 print(OS&: StrOS, Policy);
2676 return std::string(StrOS.str());
2677}
2678
2679bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
2680 if (getCVRQualifiers())
2681 return false;
2682
2683 if (getAddressSpace() != LangAS::Default)
2684 return false;
2685
2686 if (getObjCGCAttr())
2687 return false;
2688
2689 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
2690 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2691 return false;
2692
2693 if (PointerAuthQualifier PointerAuth = getPointerAuth();
2694 PointerAuth && !PointerAuth.isEmptyWhenPrinted(P: Policy))
2695 return false;
2696
2697 return true;
2698}
2699
2700std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
2701 switch (AS) {
2702 case LangAS::Default:
2703 return "";
2704 case LangAS::opencl_global:
2705 case LangAS::sycl_global:
2706 return "__global";
2707 case LangAS::opencl_local:
2708 case LangAS::sycl_local:
2709 return "__local";
2710 case LangAS::opencl_private:
2711 case LangAS::sycl_private:
2712 return "__private";
2713 case LangAS::opencl_constant:
2714 return "__constant";
2715 case LangAS::opencl_generic:
2716 return "__generic";
2717 case LangAS::opencl_global_device:
2718 case LangAS::sycl_global_device:
2719 return "__global_device";
2720 case LangAS::opencl_global_host:
2721 case LangAS::sycl_global_host:
2722 return "__global_host";
2723 case LangAS::cuda_device:
2724 return "__device__";
2725 case LangAS::cuda_constant:
2726 return "__constant__";
2727 case LangAS::cuda_shared:
2728 return "__shared__";
2729 case LangAS::ptr32_sptr:
2730 return "__sptr __ptr32";
2731 case LangAS::ptr32_uptr:
2732 return "__uptr __ptr32";
2733 case LangAS::ptr64:
2734 return "__ptr64";
2735 case LangAS::hlsl_groupshared:
2736 return "groupshared";
2737 case LangAS::hlsl_constant:
2738 return "hlsl_constant";
2739 case LangAS::hlsl_private:
2740 return "hlsl_private";
2741 case LangAS::hlsl_device:
2742 return "hlsl_device";
2743 case LangAS::hlsl_input:
2744 return "hlsl_input";
2745 case LangAS::hlsl_output:
2746 return "hlsl_output";
2747 case LangAS::hlsl_push_constant:
2748 return "hlsl_push_constant";
2749 case LangAS::wasm_funcref:
2750 return "__funcref";
2751 default:
2752 return std::to_string(val: toTargetAddressSpace(AS));
2753 }
2754}
2755
2756// Appends qualifiers to the given string, separated by spaces. Will
2757// prefix a space if the string is non-empty. Will not append a final
2758// space.
2759void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2760 bool appendSpaceIfNonEmpty) const {
2761 bool addSpace = false;
2762
2763 unsigned quals = getCVRQualifiers();
2764 if (quals) {
2765 AppendTypeQualList(OS, TypeQuals: quals, HasRestrictKeyword: Policy.Restrict);
2766 addSpace = true;
2767 }
2768 if (hasUnaligned()) {
2769 if (addSpace)
2770 OS << ' ';
2771 OS << "__unaligned";
2772 addSpace = true;
2773 }
2774 auto ASStr = getAddrSpaceAsString(AS: getAddressSpace());
2775 if (!ASStr.empty()) {
2776 if (addSpace)
2777 OS << ' ';
2778 addSpace = true;
2779 // Wrap target address space into an attribute syntax
2780 if (isTargetAddressSpace(AS: getAddressSpace()))
2781 OS << "__attribute__((address_space(" << ASStr << ")))";
2782 else
2783 OS << ASStr;
2784 }
2785
2786 if (Qualifiers::GC gc = getObjCGCAttr()) {
2787 if (addSpace)
2788 OS << ' ';
2789 addSpace = true;
2790 if (gc == Qualifiers::Weak)
2791 OS << "__weak";
2792 else
2793 OS << "__strong";
2794 }
2795 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2796 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2797 if (addSpace)
2798 OS << ' ';
2799 addSpace = true;
2800 }
2801
2802 switch (lifetime) {
2803 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2804 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2805 case Qualifiers::OCL_Strong:
2806 if (!Policy.SuppressStrongLifetime)
2807 OS << "__strong";
2808 break;
2809
2810 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2811 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2812 }
2813 }
2814
2815 if (PointerAuthQualifier PointerAuth = getPointerAuth()) {
2816 if (addSpace)
2817 OS << ' ';
2818 addSpace = true;
2819
2820 PointerAuth.print(OS, P: Policy);
2821 }
2822
2823 if (appendSpaceIfNonEmpty && addSpace)
2824 OS << ' ';
2825}
2826
2827std::string QualType::getAsString() const {
2828 return getAsString(split: split(), Policy: LangOptions());
2829}
2830
2831std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2832 std::string S;
2833 getAsStringInternal(Str&: S, Policy);
2834 return S;
2835}
2836
2837std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2838 const PrintingPolicy &Policy) {
2839 std::string buffer;
2840 getAsStringInternal(ty, qs, out&: buffer, policy: Policy);
2841 return buffer;
2842}
2843
2844void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2845 const Twine &PlaceHolder, unsigned Indentation) const {
2846 print(split: splitAccordingToPolicy(QT: *this, Policy), OS, policy: Policy, PlaceHolder,
2847 Indentation);
2848}
2849
2850void QualType::print(const Type *ty, Qualifiers qs,
2851 raw_ostream &OS, const PrintingPolicy &policy,
2852 const Twine &PlaceHolder, unsigned Indentation) {
2853 SmallString<128> PHBuf;
2854 StringRef PH = PlaceHolder.toStringRef(Out&: PHBuf);
2855
2856 TypePrinter(policy, Indentation).print(T: ty, Quals: qs, OS, PlaceHolder: PH);
2857}
2858
2859void QualType::getAsStringInternal(std::string &Str,
2860 const PrintingPolicy &Policy) const {
2861 return getAsStringInternal(split: splitAccordingToPolicy(QT: *this, Policy), out&: Str,
2862 policy: Policy);
2863}
2864
2865void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
2866 std::string &buffer,
2867 const PrintingPolicy &policy) {
2868 SmallString<256> Buf;
2869 llvm::raw_svector_ostream StrOS(Buf);
2870 TypePrinter(policy).print(T: ty, Quals: qs, OS&: StrOS, PlaceHolder: buffer);
2871 std::string str = std::string(StrOS.str());
2872 buffer.swap(s&: str);
2873}
2874
2875raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2876 SplitQualType S = QT.split();
2877 TypePrinter(LangOptions()).print(T: S.Ty, Quals: S.Quals, OS, /*PlaceHolder=*/"");
2878 return OS;
2879}
2880