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

source code of clang/lib/AST/TypePrinter.cpp