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