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