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