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