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