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