clang 24.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 case Type::LateParsedAttr:
292 CanPrefixQualifiers = false;
293 break;
294
295 case Type::Attributed: {
296 // We still want to print the address_space before the type if it is an
297 // address_space attribute.
298 const auto *AttrTy = cast<AttributedType>(UnderlyingType);
299 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
300 break;
301 }
302 case Type::PackIndexing: {
303 return canPrefixQualifiers(
304 cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),
305 NeedARCStrongQualifier);
306 }
307 }
308
309 return CanPrefixQualifiers;
310}
311
312void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
313 SplitQualType Split = splitAccordingToPolicy(T, Policy);
314
315 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
316 // at this level.
317 Qualifiers Quals = Split.Quals;
318 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
319 Quals -= QualType(Subst, 0).getQualifiers();
320
321 printBefore(Split.Ty, Quals, OS);
322}
323
324/// Prints the part of the type string before an identifier, e.g. for
325/// "int foo[10]" it prints "int ".
326void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
327 if (Policy.SuppressSpecifiers && T->isSpecifierType())
328 return;
329
330 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
331
332 // Print qualifiers as appropriate.
333
334 bool CanPrefixQualifiers = false;
335 bool NeedARCStrongQualifier = false;
336 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
337
338 if (CanPrefixQualifiers && !Quals.empty()) {
339 if (NeedARCStrongQualifier) {
340 IncludeStrongLifetimeRAII Strong(Policy);
341 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
342 } else {
343 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
344 }
345 }
346
347 bool hasAfterQuals = false;
348 if (!CanPrefixQualifiers && !Quals.empty()) {
349 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
350 if (hasAfterQuals)
351 HasEmptyPlaceHolder = false;
352 }
353
354 switch (T->getTypeClass()) {
355#define ABSTRACT_TYPE(CLASS, PARENT)
356#define TYPE(CLASS, PARENT) case Type::CLASS: \
357 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
358 break;
359#include "clang/AST/TypeNodes.inc"
360 }
361
362 if (hasAfterQuals) {
363 if (NeedARCStrongQualifier) {
364 IncludeStrongLifetimeRAII Strong(Policy);
365 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
366 } else {
367 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
368 }
369 }
370}
371
372void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
373 SplitQualType split = splitAccordingToPolicy(t, Policy);
374 printAfter(split.Ty, split.Quals, OS);
375}
376
377/// Prints the part of the type string after an identifier, e.g. for
378/// "int foo[10]" it prints "[10]".
379void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
380 switch (T->getTypeClass()) {
381#define ABSTRACT_TYPE(CLASS, PARENT)
382#define TYPE(CLASS, PARENT) case Type::CLASS: \
383 print##CLASS##After(cast<CLASS##Type>(T), OS); \
384 break;
385#include "clang/AST/TypeNodes.inc"
386 }
387}
388
389void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
390 OS << T->getName(Policy);
391 spaceBeforePlaceHolder(OS);
392}
393
394void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
395
396void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
397 OS << "_Complex ";
398 printBefore(T->getElementType(), OS);
399}
400
401void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
402 printAfter(T->getElementType(), OS);
403}
404
405void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
406 IncludeStrongLifetimeRAII Strong(Policy);
407 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
408 printBefore(T->getPointeeType(), OS);
409 // Handle things like 'int (*A)[4];' correctly.
410 // FIXME: this should include vectors, but vectors use attributes I guess.
412 OS << '(';
413 OS << '*';
414}
415
416void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
417 IncludeStrongLifetimeRAII Strong(Policy);
418 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
419 // Handle things like 'int (*A)[4];' correctly.
420 // FIXME: this should include vectors, but vectors use attributes I guess.
422 OS << ')';
423 printAfter(T->getPointeeType(), OS);
424}
425
426void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
427 raw_ostream &OS) {
428 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
429 printBefore(T->getPointeeType(), OS);
430 OS << '^';
431}
432
433void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
434 raw_ostream &OS) {
435 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
436 printAfter(T->getPointeeType(), OS);
437}
438
439// When printing a reference, the referenced type might also be a reference.
440// If so, we want to skip that before printing the inner type.
442 if (auto *Ref = T->getAs<ReferenceType>())
443 return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());
444 return T;
445}
446
447void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
448 raw_ostream &OS) {
449 IncludeStrongLifetimeRAII Strong(Policy);
450 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
451 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
452 printBefore(Inner, OS);
453 // Handle things like 'int (&A)[4];' correctly.
454 // FIXME: this should include vectors, but vectors use attributes I guess.
455 if (isa<ArrayType>(Inner))
456 OS << '(';
457 OS << '&';
458}
459
460void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
461 raw_ostream &OS) {
462 IncludeStrongLifetimeRAII Strong(Policy);
463 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
464 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
465 // Handle things like 'int (&A)[4];' correctly.
466 // FIXME: this should include vectors, but vectors use attributes I guess.
467 if (isa<ArrayType>(Inner))
468 OS << ')';
469 printAfter(Inner, OS);
470}
471
472void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
473 raw_ostream &OS) {
474 IncludeStrongLifetimeRAII Strong(Policy);
475 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
476 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
477 printBefore(Inner, OS);
478 // Handle things like 'int (&&A)[4];' correctly.
479 // FIXME: this should include vectors, but vectors use attributes I guess.
480 if (isa<ArrayType>(Inner))
481 OS << '(';
482 OS << "&&";
483}
484
485void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
486 raw_ostream &OS) {
487 IncludeStrongLifetimeRAII Strong(Policy);
488 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
489 QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());
490 // Handle things like 'int (&&A)[4];' correctly.
491 // FIXME: this should include vectors, but vectors use attributes I guess.
492 if (isa<ArrayType>(Inner))
493 OS << ')';
494 printAfter(Inner, OS);
495}
496
497void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
498 raw_ostream &OS) {
499 IncludeStrongLifetimeRAII Strong(Policy);
500 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
501 printBefore(T->getPointeeType(), OS);
502 // Handle things like 'int (Cls::*A)[4];' correctly.
503 // FIXME: this should include vectors, but vectors use attributes I guess.
505 OS << '(';
506 T->getQualifier().print(OS, Policy);
507 OS << "*";
508}
509
510void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
511 raw_ostream &OS) {
512 IncludeStrongLifetimeRAII Strong(Policy);
513 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
514 // Handle things like 'int (Cls::*A)[4];' correctly.
515 // FIXME: this should include vectors, but vectors use attributes I guess.
517 OS << ')';
518 printAfter(T->getPointeeType(), OS);
519}
520
521void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
522 raw_ostream &OS) {
523 IncludeStrongLifetimeRAII Strong(Policy);
524 printBefore(T->getElementType(), OS);
525}
526
527void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
528 raw_ostream &OS) {
529 OS << '[';
530 if (T->getIndexTypeQualifiers().hasQualifiers()) {
531 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),
532 Policy.Restrict);
533 OS << ' ';
534 }
535
536 if (T->getSizeModifier() == ArraySizeModifier::Static)
537 OS << "static ";
538
539 OS << T->getZExtSize() << ']';
540 printAfter(T->getElementType(), OS);
541}
542
543void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
544 raw_ostream &OS) {
545 IncludeStrongLifetimeRAII Strong(Policy);
546 printBefore(T->getElementType(), OS);
547}
548
549void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
550 raw_ostream &OS) {
551 OS << "[]";
552 printAfter(T->getElementType(), OS);
553}
554
555void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
556 raw_ostream &OS) {
557 IncludeStrongLifetimeRAII Strong(Policy);
558 printBefore(T->getElementType(), OS);
559}
560
561void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
562 raw_ostream &OS) {
563 OS << '[';
564 if (T->getIndexTypeQualifiers().hasQualifiers()) {
565 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);
566 OS << ' ';
567 }
568
569 if (T->getSizeModifier() == ArraySizeModifier::Static)
570 OS << "static ";
571 else if (T->getSizeModifier() == ArraySizeModifier::Star)
572 OS << '*';
573
574 if (T->getSizeExpr())
575 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
576 OS << ']';
577
578 printAfter(T->getElementType(), OS);
579}
580
581void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
582 // Print the adjusted representation, otherwise the adjustment will be
583 // invisible.
584 printBefore(T->getAdjustedType(), OS);
585}
586
587void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
588 printAfter(T->getAdjustedType(), OS);
589}
590
591void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
592 // Print as though it's a pointer.
593 printAdjustedBefore(T, OS);
594}
595
596void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
597 raw_ostream &OS) {
598 printConstantArrayAfter(T, OS);
599}
600
601void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
602 raw_ostream &OS) {
603 printConstantArrayBefore(T, OS);
604}
605
606void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
607 printAdjustedAfter(T, OS);
608}
609
610void TypePrinter::printDependentSizedArrayBefore(
611 const DependentSizedArrayType *T,
612 raw_ostream &OS) {
613 IncludeStrongLifetimeRAII Strong(Policy);
614 printBefore(T->getElementType(), OS);
615}
616
617void TypePrinter::printDependentSizedArrayAfter(
618 const DependentSizedArrayType *T,
619 raw_ostream &OS) {
620 OS << '[';
621 if (T->getSizeExpr())
622 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
623 OS << ']';
624 printAfter(T->getElementType(), OS);
625}
626
627void TypePrinter::printDependentAddressSpaceBefore(
628 const DependentAddressSpaceType *T, raw_ostream &OS) {
629 printBefore(T->getPointeeType(), OS);
630}
631
632void TypePrinter::printDependentAddressSpaceAfter(
633 const DependentAddressSpaceType *T, raw_ostream &OS) {
634 OS << " __attribute__((address_space(";
635 if (T->getAddrSpaceExpr())
636 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
637 OS << ")))";
638 printAfter(T->getPointeeType(), OS);
639}
640
641void TypePrinter::printDependentSizedExtVectorBefore(
642 const DependentSizedExtVectorType *T, raw_ostream &OS) {
643 if (Policy.UseHLSLTypes) {
644 OS << "vector<";
645 print(T->getElementType(), OS, StringRef());
646 OS << ", ";
647 if (T->getSizeExpr())
648 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
649 OS << ">";
650 spaceBeforePlaceHolder(OS);
651 } else {
652 printBefore(T->getElementType(), OS);
653 }
654}
655
656void TypePrinter::printDependentSizedExtVectorAfter(
657 const DependentSizedExtVectorType *T, raw_ostream &OS) {
658 if (Policy.UseHLSLTypes)
659 return;
660
661 OS << " __attribute__((ext_vector_type(";
662 if (T->getSizeExpr())
663 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
664 OS << ")))";
665 printAfter(T->getElementType(), OS);
666}
667
668void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
669 switch (T->getVectorKind()) {
670 case VectorKind::AltiVecPixel:
671 OS << "__vector __pixel ";
672 break;
673 case VectorKind::AltiVecBool:
674 OS << "__vector __bool ";
675 printBefore(T->getElementType(), OS);
676 break;
677 case VectorKind::AltiVecVector:
678 OS << "__vector ";
679 printBefore(T->getElementType(), OS);
680 break;
681 case VectorKind::Neon:
682 OS << "__attribute__((neon_vector_type("
683 << T->getNumElements() << "))) ";
684 printBefore(T->getElementType(), OS);
685 break;
686 case VectorKind::NeonPoly:
687 OS << "__attribute__((neon_polyvector_type(" <<
688 T->getNumElements() << "))) ";
689 printBefore(T->getElementType(), OS);
690 break;
691 case VectorKind::Generic: {
692 // FIXME: We prefer to print the size directly here, but have no way
693 // to get the size of the type.
694 OS << "__attribute__((__vector_size__("
695 << T->getNumElements()
696 << " * sizeof(";
697 print(T->getElementType(), OS, StringRef());
698 OS << ")))) ";
699 printBefore(T->getElementType(), OS);
700 break;
701 }
702 case VectorKind::SveFixedLengthData:
703 case VectorKind::SveFixedLengthPredicate:
704 // FIXME: We prefer to print the size directly here, but have no way
705 // to get the size of the type.
706 OS << "__attribute__((__arm_sve_vector_bits__(";
707
708 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
709 // Predicates take a bit per byte of the vector size, multiply by 8 to
710 // get the number of bits passed to the attribute.
711 OS << T->getNumElements() * 8;
712 else
713 OS << T->getNumElements();
714
715 OS << " * sizeof(";
716 print(T->getElementType(), OS, StringRef());
717 // Multiply by 8 for the number of bits.
718 OS << ") * 8))) ";
719 printBefore(T->getElementType(), OS);
720 break;
721 case VectorKind::RVVFixedLengthData:
722 case VectorKind::RVVFixedLengthMask:
723 case VectorKind::RVVFixedLengthMask_1:
724 case VectorKind::RVVFixedLengthMask_2:
725 case VectorKind::RVVFixedLengthMask_4:
726 // FIXME: We prefer to print the size directly here, but have no way
727 // to get the size of the type.
728 OS << "__attribute__((__riscv_rvv_vector_bits__(";
729 switch (T->getVectorKind()) {
730 case VectorKind::RVVFixedLengthMask_1:
731 OS << '1';
732 break;
733 case VectorKind::RVVFixedLengthMask_2:
734 OS << '2';
735 break;
736 case VectorKind::RVVFixedLengthMask_4:
737 OS << '4';
738 break;
739 default:
740 OS << T->getNumElements();
741 OS << " * sizeof(";
742 print(T->getElementType(), OS, StringRef());
743 // Multiply by 8 for the number of bits.
744 OS << ") * 8";
745 break;
746 }
747 OS << "))) ";
748 printBefore(T->getElementType(), OS);
749 break;
750 }
751}
752
753void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
754 printAfter(T->getElementType(), OS);
755}
756
757void TypePrinter::printDependentVectorBefore(
758 const DependentVectorType *T, raw_ostream &OS) {
759 switch (T->getVectorKind()) {
760 case VectorKind::AltiVecPixel:
761 OS << "__vector __pixel ";
762 break;
763 case VectorKind::AltiVecBool:
764 OS << "__vector __bool ";
765 printBefore(T->getElementType(), OS);
766 break;
767 case VectorKind::AltiVecVector:
768 OS << "__vector ";
769 printBefore(T->getElementType(), OS);
770 break;
771 case VectorKind::Neon:
772 OS << "__attribute__((neon_vector_type(";
773 if (T->getSizeExpr())
774 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
775 OS << "))) ";
776 printBefore(T->getElementType(), OS);
777 break;
778 case VectorKind::NeonPoly:
779 OS << "__attribute__((neon_polyvector_type(";
780 if (T->getSizeExpr())
781 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
782 OS << "))) ";
783 printBefore(T->getElementType(), OS);
784 break;
785 case VectorKind::Generic: {
786 // FIXME: We prefer to print the size directly here, but have no way
787 // to get the size of the type.
788 OS << "__attribute__((__vector_size__(";
789 if (T->getSizeExpr())
790 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
791 OS << " * sizeof(";
792 print(T->getElementType(), OS, StringRef());
793 OS << ")))) ";
794 printBefore(T->getElementType(), OS);
795 break;
796 }
797 case VectorKind::SveFixedLengthData:
798 case VectorKind::SveFixedLengthPredicate:
799 // FIXME: We prefer to print the size directly here, but have no way
800 // to get the size of the type.
801 OS << "__attribute__((__arm_sve_vector_bits__(";
802 if (T->getSizeExpr()) {
803 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
804 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
805 // Predicates take a bit per byte of the vector size, multiply by 8 to
806 // get the number of bits passed to the attribute.
807 OS << " * 8";
808 OS << " * sizeof(";
809 print(T->getElementType(), OS, StringRef());
810 // Multiply by 8 for the number of bits.
811 OS << ") * 8";
812 }
813 OS << "))) ";
814 printBefore(T->getElementType(), OS);
815 break;
816 case VectorKind::RVVFixedLengthData:
817 case VectorKind::RVVFixedLengthMask:
818 case VectorKind::RVVFixedLengthMask_1:
819 case VectorKind::RVVFixedLengthMask_2:
820 case VectorKind::RVVFixedLengthMask_4:
821 // FIXME: We prefer to print the size directly here, but have no way
822 // to get the size of the type.
823 OS << "__attribute__((__riscv_rvv_vector_bits__(";
824 switch (T->getVectorKind()) {
825 case VectorKind::RVVFixedLengthMask_1:
826 OS << '1';
827 break;
828 case VectorKind::RVVFixedLengthMask_2:
829 OS << '2';
830 break;
831 case VectorKind::RVVFixedLengthMask_4:
832 OS << '4';
833 break;
834 default:
835 if (T->getSizeExpr()) {
836 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
837 OS << " * sizeof(";
838 print(T->getElementType(), OS, StringRef());
839 // Multiply by 8 for the number of bits.
840 OS << ") * 8";
841 }
842 break;
843 }
844 OS << "))) ";
845 printBefore(T->getElementType(), OS);
846 break;
847 }
848}
849
850void TypePrinter::printDependentVectorAfter(
851 const DependentVectorType *T, raw_ostream &OS) {
852 printAfter(T->getElementType(), OS);
853}
854
855void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
856 raw_ostream &OS) {
857 if (Policy.UseHLSLTypes) {
858 OS << "vector<";
859 print(T->getElementType(), OS, StringRef());
860 OS << ", " << T->getNumElements() << ">";
861 spaceBeforePlaceHolder(OS);
862 } else {
863 printBefore(T->getElementType(), OS);
864 }
865}
866
867void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
868 if (Policy.UseHLSLTypes)
869 return;
870
871 printAfter(T->getElementType(), OS);
872 OS << " __attribute__((ext_vector_type(";
873 OS << T->getNumElements();
874 OS << ")))";
875}
876
877static void printDims(const ConstantMatrixType *T, raw_ostream &OS) {
878 OS << T->getNumRows() << ", " << T->getNumColumns();
879}
880
881static void printHLSLMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,
882 raw_ostream &OS) {
883 OS << "matrix<";
884 TP.print(T->getElementType(), OS, StringRef());
885 OS << ", ";
886 printDims(T, OS);
887 OS << ">";
888 TP.spaceBeforePlaceHolder(OS);
889}
890
891static void printHLSLMatrixAfter(const ConstantMatrixType *T, raw_ostream &OS) {
892}
893
894static void printClangMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,
895 raw_ostream &OS) {
896 TP.printBefore(T->getElementType(), OS);
897 OS << " __attribute__((matrix_type(";
898 printDims(T, OS);
899 OS << ")))";
900}
901
902void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
903 raw_ostream &OS) {
904 if (Policy.UseHLSLTypes) {
905 printHLSLMatrixBefore(*this, T, OS);
906 return;
907 }
908 printClangMatrixBefore(*this, T, OS);
909}
910
911void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
912 raw_ostream &OS) {
913 if (Policy.UseHLSLTypes) {
915 return;
916 }
917 printAfter(T->getElementType(), OS);
918}
919
920void TypePrinter::printDependentSizedMatrixBefore(
921 const DependentSizedMatrixType *T, raw_ostream &OS) {
922 if (Policy.UseHLSLTypes) {
923 OS << "matrix<";
924 print(T->getElementType(), OS, StringRef());
925 OS << ", ";
926 if (T->getRowExpr())
927 T->getRowExpr()->printPretty(OS, nullptr, Policy);
928 OS << ", ";
929 if (T->getColumnExpr())
930 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
931 OS << ">";
932 spaceBeforePlaceHolder(OS);
933 } else {
934 printBefore(T->getElementType(), OS);
935 OS << " __attribute__((matrix_type(";
936 if (T->getRowExpr())
937 T->getRowExpr()->printPretty(OS, nullptr, Policy);
938 OS << ", ";
939 if (T->getColumnExpr())
940 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
941 OS << ")))";
942 }
943}
944
945void TypePrinter::printDependentSizedMatrixAfter(
946 const DependentSizedMatrixType *T, raw_ostream &OS) {
947 if (!Policy.UseHLSLTypes)
948 printAfter(T->getElementType(), OS);
949}
950
951void
953 const PrintingPolicy &Policy)
954 const {
956 OS << " throw(";
958 OS << "...";
959 else
960 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
961 if (I)
962 OS << ", ";
963
964 OS << getExceptionType(I).stream(Policy);
965 }
966 OS << ')';
967 } else if (EST_NoThrow == getExceptionSpecType()) {
968 OS << " __attribute__((nothrow))";
970 OS << " noexcept";
971 // FIXME:Is it useful to print out the expression for a non-dependent
972 // noexcept specification?
974 OS << '(';
975 if (getNoexceptExpr())
976 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
977 OS << ')';
978 }
979 }
980}
981
982void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
983 raw_ostream &OS) {
984 if (T->hasTrailingReturn()) {
985 OS << "auto ";
986 if (!HasEmptyPlaceHolder)
987 OS << '(';
988 } else {
989 // If needed for precedence reasons, wrap the inner part in grouping parens.
990 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
991 printBefore(T->getReturnType(), OS);
992 if (!PrevPHIsEmpty.get())
993 OS << '(';
994 }
995}
996
998 switch (ABI) {
1000 llvm_unreachable("asking for spelling of ordinary parameter ABI");
1002 return "swift_context";
1004 return "swift_async_context";
1006 return "swift_error_result";
1008 return "swift_indirect_result";
1010 return "out";
1012 return "inout";
1013 }
1014 llvm_unreachable("bad parameter ABI kind");
1015}
1016
1017void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
1018 raw_ostream &OS) {
1019 // If needed for precedence reasons, wrap the inner part in grouping parens.
1020 if (!HasEmptyPlaceHolder)
1021 OS << ')';
1022 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1023
1024 OS << '(';
1025 {
1026 ParamPolicyRAII ParamPolicy(Policy);
1027 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
1028 if (i) OS << ", ";
1029
1030 auto EPI = T->getExtParameterInfo(i);
1031 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
1032 if (EPI.isNoEscape())
1033 OS << "__attribute__((noescape)) ";
1034 auto ABI = EPI.getABI();
1035 if (ABI == ParameterABI::HLSLInOut || ABI == ParameterABI::HLSLOut) {
1036 OS << getParameterABISpelling(ABI) << " ";
1037 if (Policy.UseHLSLTypes) {
1038 // This is a bit of a hack because we _do_ use reference types in the
1039 // AST for representing inout and out parameters so that code
1040 // generation is sane, but when re-printing these for HLSL we need to
1041 // skip the reference.
1042 print(T->getParamType(i).getNonReferenceType(), OS, StringRef());
1043 continue;
1044 }
1045 } else if (ABI != ParameterABI::Ordinary)
1046 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
1047
1048 print(T->getParamType(i), OS, StringRef());
1049 }
1050 }
1051
1052 if (T->isVariadic()) {
1053 if (T->getNumParams())
1054 OS << ", ";
1055 OS << "...";
1056 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
1057 // Do not emit int() if we have a proto, emit 'int(void)'.
1058 OS << "void";
1059 }
1060
1061 OS << ')';
1062
1063 FunctionType::ExtInfo Info = T->getExtInfo();
1064 unsigned SMEBits = T->getAArch64SMEAttributes();
1065
1067 OS << " __arm_streaming_compatible";
1069 OS << " __arm_streaming";
1071 OS << "__arm_agnostic(\"sme_za_state\")";
1073 OS << " __arm_preserves(\"za\")";
1075 OS << " __arm_in(\"za\")";
1077 OS << " __arm_out(\"za\")";
1079 OS << " __arm_inout(\"za\")";
1081 OS << " __arm_preserves(\"zt0\")";
1083 OS << " __arm_in(\"zt0\")";
1085 OS << " __arm_out(\"zt0\")";
1087 OS << " __arm_inout(\"zt0\")";
1088
1089 printFunctionAfter(Info, OS);
1090
1091 if (!T->getMethodQuals().empty())
1092 OS << " " << T->getMethodQuals().getAsString();
1093
1094 switch (T->getRefQualifier()) {
1095 case RQ_None:
1096 break;
1097
1098 case RQ_LValue:
1099 OS << " &";
1100 break;
1101
1102 case RQ_RValue:
1103 OS << " &&";
1104 break;
1105 }
1106 T->printExceptionSpecification(OS, Policy);
1107
1108 const FunctionEffectsRef FX = T->getFunctionEffects();
1109 for (const auto &CFE : FX) {
1110 OS << " __attribute__((" << CFE.Effect.name();
1111 if (const Expr *E = CFE.Cond.getCondition()) {
1112 OS << '(';
1113 E->printPretty(OS, nullptr, Policy);
1114 OS << ')';
1115 }
1116 OS << "))";
1117 }
1118
1119 if (T->hasCFIUncheckedCallee())
1120 OS << " __attribute__((cfi_unchecked_callee))";
1121
1122 if (T->hasTrailingReturn()) {
1123 OS << " -> ";
1124 print(T->getReturnType(), OS, StringRef());
1125 } else
1126 printAfter(T->getReturnType(), OS);
1127}
1128
1129void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1130 raw_ostream &OS) {
1131 if (!InsideCCAttribute) {
1132 switch (Info.getCC()) {
1133 case CC_C:
1134 // The C calling convention is the default on the vast majority of platforms
1135 // we support. If the user wrote it explicitly, it will usually be printed
1136 // while traversing the AttributedType. If the type has been desugared, let
1137 // the canonical spelling be the implicit calling convention.
1138 // FIXME: It would be better to be explicit in certain contexts, such as a
1139 // cdecl function typedef used to declare a member function with the
1140 // Microsoft C++ ABI.
1141 break;
1142 case CC_X86StdCall:
1143 OS << " __attribute__((stdcall))";
1144 break;
1145 case CC_X86FastCall:
1146 OS << " __attribute__((fastcall))";
1147 break;
1148 case CC_X86ThisCall:
1149 OS << " __attribute__((thiscall))";
1150 break;
1151 case CC_X86VectorCall:
1152 OS << " __attribute__((vectorcall))";
1153 break;
1154 case CC_X86Pascal:
1155 OS << " __attribute__((pascal))";
1156 break;
1157 case CC_AAPCS:
1158 OS << " __attribute__((pcs(\"aapcs\")))";
1159 break;
1160 case CC_AAPCS_VFP:
1161 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1162 break;
1164 OS << " __attribute__((aarch64_vector_pcs))";
1165 break;
1166 case CC_AArch64SVEPCS:
1167 OS << " __attribute__((aarch64_sve_pcs))";
1168 break;
1169 case CC_DeviceKernel:
1170 OS << " __attribute__((device_kernel))";
1171 break;
1172 case CC_IntelOclBicc:
1173 OS << " __attribute__((intel_ocl_bicc))";
1174 break;
1175 case CC_Win64:
1176 OS << " __attribute__((ms_abi))";
1177 break;
1178 case CC_X86_64SysV:
1179 OS << " __attribute__((sysv_abi))";
1180 break;
1181 case CC_X86RegCall:
1182 OS << " __attribute__((regcall))";
1183 break;
1184 case CC_Swift:
1185 OS << " __attribute__((swiftcall))";
1186 break;
1187 case CC_SwiftAsync:
1188 OS << "__attribute__((swiftasynccall))";
1189 break;
1190 case CC_PreserveMost:
1191 OS << " __attribute__((preserve_most))";
1192 break;
1193 case CC_PreserveAll:
1194 OS << " __attribute__((preserve_all))";
1195 break;
1196 case CC_M68kRTD:
1197 OS << " __attribute__((m68k_rtd))";
1198 break;
1199 case CC_PreserveNone:
1200 OS << " __attribute__((preserve_none))";
1201 break;
1202 case CC_RISCVVectorCall:
1203 OS << "__attribute__((riscv_vector_cc))";
1204 break;
1205#define CC_VLS_CASE(ABI_VLEN) \
1206 case CC_RISCVVLSCall_##ABI_VLEN: \
1207 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \
1208 break;
1209 CC_VLS_CASE(32)
1210 CC_VLS_CASE(64)
1211 CC_VLS_CASE(128)
1212 CC_VLS_CASE(256)
1213 CC_VLS_CASE(512)
1214 CC_VLS_CASE(1024)
1215 CC_VLS_CASE(2048)
1216 CC_VLS_CASE(4096)
1217 CC_VLS_CASE(8192)
1218 CC_VLS_CASE(16384)
1219 CC_VLS_CASE(32768)
1220 CC_VLS_CASE(65536)
1221#undef CC_VLS_CASE
1222 }
1223 }
1224
1225 if (Info.getNoReturn())
1226 OS << " __attribute__((noreturn))";
1227 if (Info.getCmseNSCall())
1228 OS << " __attribute__((cmse_nonsecure_call))";
1229 if (Info.getProducesResult())
1230 OS << " __attribute__((ns_returns_retained))";
1231 if (Info.getRegParm())
1232 OS << " __attribute__((regparm ("
1233 << Info.getRegParm() << ")))";
1234 if (Info.getNoCallerSavedRegs())
1235 OS << " __attribute__((no_caller_saved_registers))";
1236 if (Info.getNoCfCheck())
1237 OS << " __attribute__((nocf_check))";
1238}
1239
1240void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1241 raw_ostream &OS) {
1242 // If needed for precedence reasons, wrap the inner part in grouping parens.
1243 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1244 printBefore(T->getReturnType(), OS);
1245 if (!PrevPHIsEmpty.get())
1246 OS << '(';
1247}
1248
1249void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1250 raw_ostream &OS) {
1251 // If needed for precedence reasons, wrap the inner part in grouping parens.
1252 if (!HasEmptyPlaceHolder)
1253 OS << ')';
1254 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1255
1256 OS << "()";
1257 printFunctionAfter(T->getExtInfo(), OS);
1258 printAfter(T->getReturnType(), OS);
1259}
1260
1261void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1262
1263 // Compute the full nested-name-specifier for this type.
1264 // In C, this will always be empty except when the type
1265 // being printed is anonymous within other Record.
1266 if (!Policy.SuppressScope)
1267 D->printNestedNameSpecifier(OS, Policy);
1268
1269 IdentifierInfo *II = D->getIdentifier();
1270 OS << II->getName();
1271 spaceBeforePlaceHolder(OS);
1272}
1273
1274void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1275 raw_ostream &OS) {
1276 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1277 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1278 OS << ' ';
1279 auto *D = T->getDecl();
1280 if (Policy.FullyQualifiedName || T->isCanonicalUnqualified()) {
1281 D->printNestedNameSpecifier(OS, Policy);
1282 } else {
1283 T->getQualifier().print(OS, Policy);
1284 }
1285 OS << D->getIdentifier()->getName();
1286 spaceBeforePlaceHolder(OS);
1287}
1288
1289void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1290 raw_ostream &OS) {}
1291
1292void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1293 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1294 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1295 OS << ' ';
1296 auto *D = T->getDecl();
1297 if (Policy.FullyQualifiedName) {
1298 D->printNestedNameSpecifier(OS, Policy);
1299 } else {
1300 T->getQualifier().print(OS, Policy);
1301 }
1302 OS << D->getIdentifier()->getName();
1303 spaceBeforePlaceHolder(OS);
1304}
1305
1306void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1307
1308void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1309 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1310 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1311 OS << ' ';
1312 auto *D = T->getDecl();
1313 if (Policy.FullyQualifiedName) {
1314 D->printNestedNameSpecifier(OS, Policy);
1315 } else {
1316 T->getQualifier().print(OS, Policy);
1317 }
1318 OS << D->getIdentifier()->getName();
1319 spaceBeforePlaceHolder(OS);
1320}
1321
1322void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1323 raw_ostream &OS) {
1324 StringRef MacroName = T->getMacroIdentifier()->getName();
1325 OS << MacroName << " ";
1326
1327 // Since this type is meant to print the macro instead of the whole attribute,
1328 // we trim any attributes and go directly to the original modified type.
1329 printBefore(T->getModifiedType(), OS);
1330}
1331
1332void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1333 raw_ostream &OS) {
1334 printAfter(T->getModifiedType(), OS);
1335}
1336
1337void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1338
1339void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1340 raw_ostream &OS) {
1341 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1342 : "typeof ");
1343 if (T->getUnderlyingExpr())
1344 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1345 spaceBeforePlaceHolder(OS);
1346}
1347
1348void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1349 raw_ostream &OS) {}
1350
1351void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1352 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1353 : "typeof(");
1354 print(T->getUnmodifiedType(), OS, StringRef());
1355 OS << ')';
1356 spaceBeforePlaceHolder(OS);
1357}
1358
1359void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1360
1361void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1362 OS << "decltype(";
1363 if (const Expr *E = T->getUnderlyingExpr()) {
1364 PrintingPolicy ExprPolicy = Policy;
1366 E->printPretty(OS, nullptr, ExprPolicy);
1367 }
1368 OS << ')';
1369 spaceBeforePlaceHolder(OS);
1370}
1371
1372void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1373 raw_ostream &OS) {
1374 if (T->hasSelectedType()) {
1375 OS << T->getSelectedType();
1376 } else {
1377 OS << T->getPattern() << "...[";
1378 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1379 OS << "]";
1380 }
1381 spaceBeforePlaceHolder(OS);
1382}
1383
1384void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1385 raw_ostream &OS) {}
1386
1387void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1388
1389void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1390 raw_ostream &OS) {
1391 IncludeStrongLifetimeRAII Strong(Policy);
1392
1393 static const llvm::DenseMap<int, const char *> Transformation = {{
1394#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1395 {UnaryTransformType::Enum, "__" #Trait},
1396#include "clang/Basic/BuiltinTraits.inc"
1397 }};
1398 OS << Transformation.lookup(T->getUTTKind()) << '(';
1399 print(T->getBaseType(), OS, StringRef());
1400 OS << ')';
1401 spaceBeforePlaceHolder(OS);
1402}
1403
1404void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1405 raw_ostream &OS) {}
1406
1407void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1408 // If the type has been deduced, do not print 'auto'.
1409 if (!T->getDeducedType().isNull()) {
1410 printBefore(T->getDeducedType(), OS);
1411 } else {
1412 if (T->isConstrained()) {
1413 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1414 // type as it was written.
1415 TemplateName Concept = T->getTypeConstraintConcept();
1416 Concept.print(OS, Policy, TemplateName::Qualified::None);
1417 auto Args = T->getTypeConstraintArguments();
1418 if (!Args.empty()) {
1419 const TemplateDecl *TD = Concept.getAsTemplateDecl();
1420 if (!TD)
1421 TD = Concept.getAsTemplateTemplateParmDecl();
1422 printTemplateArgumentList(OS, Args, Policy,
1423 TD->getTemplateParameters());
1424 }
1425 OS << ' ';
1426 }
1427 switch (T->getKeyword()) {
1428 case AutoTypeKeyword::Auto: OS << "auto"; break;
1429 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1430 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1431 }
1432 spaceBeforePlaceHolder(OS);
1433 }
1434}
1435
1436void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1437 // If the type has been deduced, do not print 'auto'.
1438 if (!T->getDeducedType().isNull())
1439 printAfter(T->getDeducedType(), OS);
1440}
1441
1442void TypePrinter::printDeducedTemplateSpecializationBefore(
1443 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1444 if (ElaboratedTypeKeyword Keyword = T->getKeyword();
1445 T->getKeyword() != ElaboratedTypeKeyword::None)
1447
1448 TemplateName Name = T->getTemplateName();
1449
1450 // If the type has been deduced, print the template arguments, as if this was
1451 // printing the deduced type, but including elaboration and template name
1452 // qualification.
1453 // FIXME: There should probably be a policy which controls this.
1454 // We would probably want to do this on diagnostics, but not on -ast-print.
1455 ArrayRef<TemplateArgument> Args;
1456 TemplateDecl *DeducedTD = nullptr;
1457 if (!T->getDeducedType().isNull()) {
1458 if (const auto *TST =
1459 dyn_cast<TemplateSpecializationType>(T->getDeducedType())) {
1460 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1461 /*IgnoreDeduced=*/true);
1462 Args = TST->template_arguments();
1463 } else {
1464 // Should only get here for canonical types.
1466 cast<RecordType>(T->getDeducedType())->getDecl());
1467 DeducedTD = CD->getSpecializedTemplate();
1468 Args = CD->getTemplateArgs().asArray();
1469 }
1470
1471 // FIXME: Workaround for alias template CTAD not producing guides which
1472 // include the alias template specialization type.
1473 // Purposefully disregard qualification when building this TemplateName;
1474 // any qualification we might have, might not make sense in the
1475 // context this was deduced.
1476 if (!declaresSameEntity(DeducedTD, Name.getAsTemplateDecl(
1477 /*IgnoreDeduced=*/true)))
1478 Name = TemplateName(DeducedTD);
1479 }
1480
1481 {
1482 IncludeStrongLifetimeRAII Strong(Policy);
1483 Name.print(OS, Policy);
1484 }
1485 if (DeducedTD) {
1486 printTemplateArgumentList(OS, Args, Policy,
1487 DeducedTD->getTemplateParameters());
1488 }
1489
1490 spaceBeforePlaceHolder(OS);
1491}
1492
1493void TypePrinter::printDeducedTemplateSpecializationAfter(
1494 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1495 // If the type has been deduced, print the deduced type.
1496 if (!T->getDeducedType().isNull())
1497 printAfter(T->getDeducedType(), OS);
1498}
1499
1500void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1501 IncludeStrongLifetimeRAII Strong(Policy);
1502
1503 OS << "_Atomic(";
1504 print(T->getValueType(), OS, StringRef());
1505 OS << ')';
1506 spaceBeforePlaceHolder(OS);
1507}
1508
1509void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1510
1511void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1512 IncludeStrongLifetimeRAII Strong(Policy);
1513
1514 if (T->isReadOnly())
1515 OS << "read_only ";
1516 else
1517 OS << "write_only ";
1518 OS << "pipe ";
1519 print(T->getElementType(), OS, StringRef());
1520 spaceBeforePlaceHolder(OS);
1521}
1522
1523void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1524
1525void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1526 if (T->isUnsigned())
1527 OS << "unsigned ";
1528 OS << "_BitInt(" << T->getNumBits() << ")";
1529 spaceBeforePlaceHolder(OS);
1530}
1531
1532void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1533
1534void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1535 raw_ostream &OS) {
1536 if (T->isUnsigned())
1537 OS << "unsigned ";
1538 OS << "_BitInt(";
1539 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1540 OS << ")";
1541 spaceBeforePlaceHolder(OS);
1542}
1543
1544void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1545 raw_ostream &OS) {}
1546
1547void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,
1548 raw_ostream &OS) {
1549 OS << T->getIdentifier()->getName();
1550 spaceBeforePlaceHolder(OS);
1551}
1552
1553void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,
1554 raw_ostream &OS) {}
1555
1556void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
1557 TagDecl *D = T->getDecl();
1558
1559 if (Policy.IncludeTagDefinition && T->isTagOwned()) {
1560 D->print(OS, Policy, Indentation);
1561 spaceBeforePlaceHolder(OS);
1562 return;
1563 }
1564
1565 bool PrintedKindDecoration = false;
1566 if (T->isCanonicalUnqualified()) {
1567 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1568 PrintedKindDecoration = true;
1569 OS << D->getKindName();
1570 OS << ' ';
1571 }
1572 } else {
1573 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1574 if (T->getKeyword() != ElaboratedTypeKeyword::None) {
1575 PrintedKindDecoration = true;
1576 OS << ' ';
1577 }
1578 }
1579
1580 if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
1581 T->getQualifier().print(OS, Policy);
1582 } else if (!Policy.SuppressScope) {
1583 // Compute the full nested-name-specifier for this type.
1584 // In C, this will always be empty except when the type
1585 // being printed is anonymous within other Record.
1586 D->printNestedNameSpecifier(OS, Policy);
1587 }
1588
1589 if (const IdentifierInfo *II = D->getIdentifier())
1590 OS << II->getName();
1591 else {
1592 clang::PrintingPolicy Copy(Policy);
1593
1594 // Suppress the redundant tag keyword if we just printed one.
1595 if (PrintedKindDecoration) {
1596 Copy.SuppressTagKeywordInAnonNames = true;
1597 Copy.SuppressTagKeyword = true;
1598 }
1599
1600 D->printName(OS, Copy);
1601 }
1602
1603 // If this is a class template specialization, print the template
1604 // arguments.
1605 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1606 const TemplateParameterList *TParams =
1607 S->getSpecializedTemplate()->getTemplateParameters();
1608 const ASTTemplateArgumentListInfo *TArgAsWritten =
1609 S->getTemplateArgsAsWritten();
1610 IncludeStrongLifetimeRAII Strong(Policy);
1611 if (TArgAsWritten && !Policy.PrintAsCanonical)
1612 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1613 TParams);
1614 else
1615 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1616 TParams);
1617 }
1618
1619 spaceBeforePlaceHolder(OS);
1620}
1621
1622void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1623 // Print the preferred name if we have one for this type.
1624 if (Policy.UsePreferredNames) {
1625 for (const auto *PNA : T->getDecl()
1626 ->getMostRecentDecl()
1627 ->specific_attrs<PreferredNameAttr>()) {
1628 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1629 T->getDecl()))
1630 continue;
1631 // Find the outermost typedef or alias template.
1632 QualType T = PNA->getTypedefType();
1633 while (true) {
1634 if (auto *TT = dyn_cast<TypedefType>(T))
1635 return printTypeSpec(TT->getDecl(), OS);
1636 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1637 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1639 }
1640 }
1641 }
1642
1643 printTagType(T, OS);
1644}
1645
1646void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1647
1648void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1649 printTagType(T, OS);
1650}
1651
1652void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1653
1654void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1655 raw_ostream &OS) {
1656 const ASTContext &Ctx = T->getDecl()->getASTContext();
1657 IncludeStrongLifetimeRAII Strong(Policy);
1658 T->getTemplateName(Ctx).print(OS, Policy);
1660 auto *Decl = T->getDecl();
1661 // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
1662 // arguments.
1663 if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {
1664 printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),
1665 Policy,
1666 T->getTemplateDecl()->getTemplateParameters());
1667 } else {
1668 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
1669 assert(TD);
1670 printTemplateArgumentList(
1671 OS, TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx), Policy,
1672 T->getTemplateDecl()->getTemplateParameters());
1673 }
1674 }
1675 spaceBeforePlaceHolder(OS);
1676}
1677
1678void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1679 raw_ostream &OS) {}
1680
1681void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1682 raw_ostream &OS) {
1683 TemplateTypeParmDecl *D = T->getDecl();
1684 if (D && D->isImplicit()) {
1685 if (auto *TC = D->getTypeConstraint()) {
1686 TC->print(OS, Policy);
1687 OS << ' ';
1688 }
1689 OS << "auto";
1690 } else if (IdentifierInfo *Id = T->getIdentifier())
1691 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1692 : Id->getName());
1693 else
1694 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1695
1696 spaceBeforePlaceHolder(OS);
1697}
1698
1699void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1700 raw_ostream &OS) {}
1701
1702void TypePrinter::printSubstTemplateTypeParmBefore(
1703 const SubstTemplateTypeParmType *T,
1704 raw_ostream &OS) {
1705 IncludeStrongLifetimeRAII Strong(Policy);
1706 printBefore(T->getReplacementType(), OS);
1707}
1708
1709void TypePrinter::printSubstTemplateTypeParmAfter(
1710 const SubstTemplateTypeParmType *T,
1711 raw_ostream &OS) {
1712 IncludeStrongLifetimeRAII Strong(Policy);
1713 printAfter(T->getReplacementType(), OS);
1714}
1715
1716void TypePrinter::printSubstBuiltinTemplatePackBefore(
1717 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
1718 IncludeStrongLifetimeRAII Strong(Policy);
1719 OS << "type-pack";
1720}
1721
1722void TypePrinter::printSubstBuiltinTemplatePackAfter(
1723 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
1724
1725void TypePrinter::printSubstTemplateTypeParmPackBefore(
1726 const SubstTemplateTypeParmPackType *T,
1727 raw_ostream &OS) {
1728 IncludeStrongLifetimeRAII Strong(Policy);
1729 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1730 if (D && D->isImplicit()) {
1731 if (auto *TC = D->getTypeConstraint()) {
1732 TC->print(OS, Policy);
1733 OS << ' ';
1734 }
1735 OS << "auto";
1736 } else if (IdentifierInfo *Id = D->getIdentifier())
1737 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1738 : Id->getName());
1739 else
1740 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1741
1742 spaceBeforePlaceHolder(OS);
1743 }
1744}
1745
1746void TypePrinter::printSubstTemplateTypeParmPackAfter(
1747 const SubstTemplateTypeParmPackType *T,
1748 raw_ostream &OS) {
1749 IncludeStrongLifetimeRAII Strong(Policy);
1750}
1751
1752void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1753 raw_ostream &OS, bool FullyQualify) {
1754 IncludeStrongLifetimeRAII Strong(Policy);
1755
1756 if (ElaboratedTypeKeyword K = T->getKeyword();
1757 K != ElaboratedTypeKeyword::None)
1758 OS << TypeWithKeyword::getKeywordName(K) << ' ';
1759
1760 TemplateDecl *TD =
1761 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1762 // FIXME: Null TD never exercised in test suite.
1763 if (FullyQualify && TD) {
1764 if (!Policy.SuppressScope)
1765 TD->printNestedNameSpecifier(OS, Policy);
1766
1767 OS << TD->getName();
1768 } else {
1769 T->getTemplateName().print(OS, Policy,
1770 !Policy.SuppressScope
1771 ? TemplateName::Qualified::AsWritten
1772 : TemplateName::Qualified::None);
1773 }
1774
1775 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1776 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1777 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1778 spaceBeforePlaceHolder(OS);
1779}
1780
1781void TypePrinter::printTemplateSpecializationBefore(
1782 const TemplateSpecializationType *T,
1783 raw_ostream &OS) {
1784 printTemplateId(T, OS, Policy.FullyQualifiedName);
1785}
1786
1787void TypePrinter::printTemplateSpecializationAfter(
1788 const TemplateSpecializationType *T,
1789 raw_ostream &OS) {}
1790
1791void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1792 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1793 printBefore(T->getInnerType(), OS);
1794 OS << '(';
1795 } else
1796 printBefore(T->getInnerType(), OS);
1797}
1798
1799void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1800 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1801 OS << ')';
1802 printAfter(T->getInnerType(), OS);
1803 } else
1804 printAfter(T->getInnerType(), OS);
1805}
1806
1807void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1808 raw_ostream &OS) {
1809 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1810 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1811 OS << " ";
1812 T->getQualifier().print(OS, Policy);
1813 OS << T->getIdentifier()->getName();
1814 spaceBeforePlaceHolder(OS);
1815}
1816
1817void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1818 raw_ostream &OS) {}
1819
1820void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1821 raw_ostream &OS) {
1822 printBefore(T->getPattern(), OS);
1823}
1824
1825void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1826 raw_ostream &OS) {
1827 printAfter(T->getPattern(), OS);
1828 OS << "...";
1829}
1830
1832 raw_ostream &OS,
1833 const PrintingPolicy &Policy) {
1834 OS << ' ';
1835 if (T->isCountInBytes() && T->isOrNull())
1836 OS << "__sized_by_or_null(";
1837 else if (T->isCountInBytes())
1838 OS << "__sized_by(";
1839 else if (T->isOrNull())
1840 OS << "__counted_by_or_null(";
1841 else
1842 OS << "__counted_by(";
1843 if (T->getCountExpr())
1844 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1845 OS << ')';
1846}
1847
1848void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1849 raw_ostream &OS) {
1850 printBefore(T->desugar(), OS);
1851 if (!T->isArrayType())
1852 printCountAttributedImpl(T, OS, Policy);
1853}
1854
1855void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1856 raw_ostream &OS) {
1857 printAfter(T->desugar(), OS);
1858 if (T->isArrayType())
1859 printCountAttributedImpl(T, OS, Policy);
1860}
1861
1862void TypePrinter::printLateParsedAttrBefore(const LateParsedAttrType *T,
1863 raw_ostream &OS) {
1864 // LateParsedAttrType is a transient placeholder that should not appear
1865 // in user-facing output. Just print the wrapped type.
1866 printBefore(T->getWrappedType(), OS);
1867}
1868
1869void TypePrinter::printLateParsedAttrAfter(const LateParsedAttrType *T,
1870 raw_ostream &OS) {
1871 // LateParsedAttrType is a transient placeholder that should not appear
1872 // in user-facing output. Just print the wrapped type.
1873 printAfter(T->getWrappedType(), OS);
1874}
1875
1876void TypePrinter::printAttributedBefore(const AttributedType *T,
1877 raw_ostream &OS) {
1878 // FIXME: Generate this with TableGen.
1879
1880 // Prefer the macro forms of the GC and ownership qualifiers.
1881 if (T->getAttrKind() == attr::ObjCGC ||
1882 T->getAttrKind() == attr::ObjCOwnership)
1883 return printBefore(T->getEquivalentType(), OS);
1884
1885 if (T->getAttrKind() == attr::ObjCKindOf)
1886 OS << "__kindof ";
1887
1888 if (T->getAttrKind() == attr::PreserveNone) {
1889 OS << "__attribute__((preserve_none)) ";
1890 spaceBeforePlaceHolder(OS);
1891 } else if (T->getAttrKind() == attr::PreserveMost) {
1892 OS << "__attribute__((preserve_most)) ";
1893 spaceBeforePlaceHolder(OS);
1894 } else if (T->getAttrKind() == attr::PreserveAll) {
1895 OS << "__attribute__((preserve_all)) ";
1896 spaceBeforePlaceHolder(OS);
1897 }
1898
1899 if (T->getAttrKind() == attr::AddressSpace)
1900 printBefore(T->getEquivalentType(), OS);
1901 else
1902 printBefore(T->getModifiedType(), OS);
1903
1904 if (T->isMSTypeSpec()) {
1905 switch (T->getAttrKind()) {
1906 default: return;
1907 case attr::Ptr32: OS << " __ptr32"; break;
1908 case attr::Ptr64: OS << " __ptr64"; break;
1909 case attr::SPtr: OS << " __sptr"; break;
1910 case attr::UPtr: OS << " __uptr"; break;
1911 }
1912 spaceBeforePlaceHolder(OS);
1913 }
1914
1915 if (T->isWebAssemblyFuncrefSpec())
1916 OS << "__funcref";
1917
1918 // Print nullability type specifiers.
1919 if (T->getImmediateNullability()) {
1920 if (T->getAttrKind() == attr::TypeNonNull)
1921 OS << " _Nonnull";
1922 else if (T->getAttrKind() == attr::TypeNullable)
1923 OS << " _Nullable";
1924 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1925 OS << " _Null_unspecified";
1926 else if (T->getAttrKind() == attr::TypeNullableResult)
1927 OS << " _Nullable_result";
1928 else
1929 llvm_unreachable("unhandled nullability");
1930 spaceBeforePlaceHolder(OS);
1931 }
1932}
1933
1934void TypePrinter::printAttributedAfter(const AttributedType *T,
1935 raw_ostream &OS) {
1936 // FIXME: Generate this with TableGen.
1937
1938 // Prefer the macro forms of the GC and ownership qualifiers.
1939 if (T->getAttrKind() == attr::ObjCGC ||
1940 T->getAttrKind() == attr::ObjCOwnership)
1941 return printAfter(T->getEquivalentType(), OS);
1942
1943 // If this is a calling convention attribute, don't print the implicit CC from
1944 // the modified type.
1945 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1946
1947 printAfter(T->getModifiedType(), OS);
1948
1949 // Some attributes are printed as qualifiers before the type, so we have
1950 // nothing left to do.
1951 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1952 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1953 return;
1954
1955 // Don't print the inert __unsafe_unretained attribute at all.
1956 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1957 return;
1958
1959 // Don't print ns_returns_retained unless it had an effect.
1960 if (T->getAttrKind() == attr::NSReturnsRetained &&
1961 !T->getEquivalentType()->castAs<FunctionType>()
1962 ->getExtInfo().getProducesResult())
1963 return;
1964
1965 if (T->getAttrKind() == attr::LifetimeBound) {
1966 OS << " [[clang::lifetimebound]]";
1967 return;
1968 }
1969 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1970 OS << " [[clang::lifetime_capture_by(";
1971 if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr()))
1972 llvm::interleaveComma(attr->getArgIdents(), OS,
1973 [&](auto it) { OS << it->getName(); });
1974 OS << ")]]";
1975 return;
1976 }
1977
1978 // The printing of the address_space attribute is handled by the qualifier
1979 // since it is still stored in the qualifier. Return early to prevent printing
1980 // this twice.
1981 if (T->getAttrKind() == attr::AddressSpace)
1982 return;
1983
1984 if (T->getAttrKind() == attr::AnnotateType) {
1985 // FIXME: Print the attribute arguments once we have a way to retrieve these
1986 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1987 // without the arguments so that we know at least that we had _some_
1988 // annotation on the type.
1989 OS << " [[clang::annotate_type(...)]]";
1990 return;
1991 }
1992
1993 if (T->getAttrKind() == attr::ArmStreaming) {
1994 OS << "__arm_streaming";
1995 return;
1996 }
1997 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1998 OS << "__arm_streaming_compatible";
1999 return;
2000 }
2001
2002 if (T->getAttrKind() == attr::SwiftAttr) {
2003 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
2004 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
2005 << "\")))";
2006 }
2007 return;
2008 }
2009
2010 if (T->getAttrKind() == attr::PreserveAll ||
2011 T->getAttrKind() == attr::PreserveMost ||
2012 T->getAttrKind() == attr::PreserveNone) {
2013 // This has to be printed before the type.
2014 return;
2015 }
2016
2017 OS << " __attribute__((";
2018 switch (T->getAttrKind()) {
2019#define TYPE_ATTR(NAME)
2020#define DECL_OR_TYPE_ATTR(NAME)
2021#define ATTR(NAME) case attr::NAME:
2022#include "clang/Basic/AttrList.inc"
2023 llvm_unreachable("non-type attribute attached to type");
2024
2025 case attr::BTFTypeTag:
2026 llvm_unreachable("BTFTypeTag attribute handled separately");
2027
2028 case attr::HLSLResourceClass:
2029 case attr::HLSLIsROV:
2030 case attr::HLSLRawBuffer:
2031 case attr::HLSLContainedType:
2032 case attr::HLSLIsCounter:
2033 case attr::HLSLResourceDimension:
2034 case attr::HLSLIsArray:
2035 case attr::HLSLIsMultiSampled:
2036 llvm_unreachable("HLSL resource type attributes handled separately");
2037
2038 case attr::OpenCLPrivateAddressSpace:
2039 case attr::OpenCLGlobalAddressSpace:
2040 case attr::OpenCLGlobalDeviceAddressSpace:
2041 case attr::OpenCLGlobalHostAddressSpace:
2042 case attr::OpenCLLocalAddressSpace:
2043 case attr::OpenCLConstantAddressSpace:
2044 case attr::OpenCLGenericAddressSpace:
2045 case attr::HLSLGroupSharedAddressSpace:
2046 // FIXME: Update printAttributedBefore to print these once we generate
2047 // AttributedType nodes for them.
2048 break;
2049
2050 case attr::CountedBy:
2051 case attr::CountedByOrNull:
2052 case attr::SizedBy:
2053 case attr::SizedByOrNull:
2054 case attr::LifetimeBound:
2055 case attr::LifetimeCaptureBy:
2056 case attr::TypeNonNull:
2057 case attr::TypeNullable:
2058 case attr::TypeNullableResult:
2059 case attr::TypeNullUnspecified:
2060 case attr::ObjCGC:
2061 case attr::ObjCInertUnsafeUnretained:
2062 case attr::ObjCKindOf:
2063 case attr::ObjCOwnership:
2064 case attr::Ptr32:
2065 case attr::Ptr64:
2066 case attr::SPtr:
2067 case attr::UPtr:
2068 case attr::PointerAuth:
2069 case attr::AddressSpace:
2070 case attr::CmseNSCall:
2071 case attr::AnnotateType:
2072 case attr::WebAssemblyFuncref:
2073 case attr::ArmAgnostic:
2074 case attr::ArmStreaming:
2075 case attr::ArmStreamingCompatible:
2076 case attr::ArmIn:
2077 case attr::ArmOut:
2078 case attr::ArmInOut:
2079 case attr::ArmPreserves:
2080 case attr::NonBlocking:
2081 case attr::NonAllocating:
2082 case attr::Blocking:
2083 case attr::Allocating:
2084 case attr::SwiftAttr:
2085 case attr::PreserveAll:
2086 case attr::PreserveMost:
2087 case attr::PreserveNone:
2088 case attr::OverflowBehavior:
2089 llvm_unreachable("This attribute should have been handled already");
2090
2091 case attr::NSReturnsRetained:
2092 OS << "ns_returns_retained";
2093 break;
2094
2095 case attr::HLSLRowMajor:
2096 OS << "row_major";
2097 break;
2098 case attr::HLSLColumnMajor:
2099 OS << "column_major";
2100 break;
2101
2102 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2103 // attribute again in printFunctionProtoAfter.
2104 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2105 case attr::CDecl: OS << "cdecl"; break;
2106 case attr::FastCall: OS << "fastcall"; break;
2107 case attr::StdCall: OS << "stdcall"; break;
2108 case attr::ThisCall: OS << "thiscall"; break;
2109 case attr::SwiftCall: OS << "swiftcall"; break;
2110 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2111 case attr::VectorCall: OS << "vectorcall"; break;
2112 case attr::Pascal: OS << "pascal"; break;
2113 case attr::MSABI: OS << "ms_abi"; break;
2114 case attr::SysVABI: OS << "sysv_abi"; break;
2115 case attr::RegCall: OS << "regcall"; break;
2116 case attr::Pcs: {
2117 OS << "pcs(";
2118 QualType t = T->getEquivalentType();
2119 while (!t->isFunctionType())
2120 t = t->getPointeeType();
2121 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2122 "\"aapcs\"" : "\"aapcs-vfp\"");
2123 OS << ')';
2124 break;
2125 }
2126 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2127 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2128 case attr::IntelOclBicc:
2129 OS << "inteloclbicc";
2130 break;
2131 case attr::M68kRTD:
2132 OS << "m68k_rtd";
2133 break;
2134 case attr::RISCVVectorCC:
2135 OS << "riscv_vector_cc";
2136 break;
2137 case attr::RISCVVLSCC:
2138 OS << "riscv_vls_cc";
2139 break;
2140 case attr::NoDeref:
2141 OS << "noderef";
2142 break;
2143 case attr::CFIUncheckedCallee:
2144 OS << "cfi_unchecked_callee";
2145 break;
2146 case attr::AcquireHandle:
2147 OS << "acquire_handle";
2148 break;
2149 case attr::ArmMveStrictPolymorphism:
2150 OS << "__clang_arm_mve_strict_polymorphism";
2151 break;
2152 case attr::ExtVectorType:
2153 OS << "ext_vector_type";
2154 break;
2155 case attr::CFISalt:
2156 OS << "cfi_salt(\"" << cast<CFISaltAttr>(T->getAttr())->getSalt() << "\")";
2157 break;
2158 case attr::NoFieldProtection:
2159 OS << "no_field_protection";
2160 break;
2161 case attr::PointerFieldProtection:
2162 OS << "pointer_field_protection";
2163 break;
2164 }
2165 OS << "))";
2166}
2167
2168void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2169 raw_ostream &OS) {
2170 printBefore(T->getWrappedType(), OS);
2171 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2172}
2173
2174void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2175 raw_ostream &OS) {
2176 printAfter(T->getWrappedType(), OS);
2177}
2178
2179void TypePrinter::printOverflowBehaviorBefore(const OverflowBehaviorType *T,
2180 raw_ostream &OS) {
2181 switch (T->getBehaviorKind()) {
2182 case clang::OverflowBehaviorType::OverflowBehaviorKind::Wrap:
2183 OS << "__ob_wrap ";
2184 break;
2185 case clang::OverflowBehaviorType::OverflowBehaviorKind::Trap:
2186 OS << "__ob_trap ";
2187 break;
2188 }
2189 printBefore(T->getUnderlyingType(), OS);
2190}
2191
2192void TypePrinter::printOverflowBehaviorAfter(const OverflowBehaviorType *T,
2193 raw_ostream &OS) {
2194 printAfter(T->getUnderlyingType(), OS);
2195}
2196
2197void TypePrinter::printHLSLAttributedResourceBefore(
2198 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2199 printBefore(T->getWrappedType(), OS);
2200}
2201
2202void TypePrinter::printHLSLAttributedResourceAfter(
2203 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2204 printAfter(T->getWrappedType(), OS);
2205 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2206 OS << " [[hlsl::resource_class(\""
2207 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2208 << "\")]]";
2209 if (Attrs.IsROV)
2210 OS << " [[hlsl::is_rov]]";
2211 if (Attrs.RawBuffer)
2212 OS << " [[hlsl::raw_buffer]]";
2213 if (Attrs.IsCounter)
2214 OS << " [[hlsl::is_counter]]";
2215 if (Attrs.IsArray)
2216 OS << " [[hlsl::is_array]]";
2217 if (Attrs.isMultiSampled())
2218 OS << " [[hlsl::is_ms]]";
2219
2220 QualType ContainedTy = T->getContainedType();
2221 if (!ContainedTy.isNull()) {
2222 OS << " [[hlsl::contained_type(";
2223 printBefore(ContainedTy, OS);
2224 printAfter(ContainedTy, OS);
2225 OS << ")]]";
2226 }
2227
2228 if (Attrs.ResourceDimension != llvm::dxil::ResourceDimension::Unknown)
2229 OS << " [[hlsl::dimension(\""
2230 << HLSLResourceDimensionAttr::ConvertResourceDimensionToStr(
2231 Attrs.ResourceDimension)
2232 << "\")]]";
2233}
2234
2235void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2236 raw_ostream &OS) {
2237 OS << "__hlsl_spirv_type<" << T->getOpcode();
2238
2239 OS << ", " << T->getSize();
2240 OS << ", " << T->getAlignment();
2241
2242 for (auto &Operand : T->getOperands()) {
2243 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2244
2245 OS << ", ";
2246 switch (Operand.getKind()) {
2247 case SpirvOperandKind::ConstantId: {
2248 QualType ConstantType = Operand.getResultType();
2249 OS << "vk::integral_constant<";
2250 printBefore(ConstantType, OS);
2251 printAfter(ConstantType, OS);
2252 OS << ", ";
2253 OS << Operand.getValue();
2254 OS << ">";
2255 break;
2256 }
2257 case SpirvOperandKind::Literal:
2258 OS << "vk::Literal<vk::integral_constant<uint, ";
2259 OS << Operand.getValue();
2260 OS << ">>";
2261 break;
2262 case SpirvOperandKind::TypeId: {
2263 QualType Type = Operand.getResultType();
2264 printBefore(Type, OS);
2265 printAfter(Type, OS);
2266 break;
2267 }
2268 default:
2269 llvm_unreachable("Invalid SpirvOperand kind!");
2270 break;
2271 }
2272 }
2273
2274 OS << ">";
2275}
2276
2277void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2278 raw_ostream &OS) {
2279 // nothing to do
2280}
2281
2282void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2283 raw_ostream &OS) {
2284 OS << T->getDecl()->getName();
2285 spaceBeforePlaceHolder(OS);
2286}
2287
2288void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2289 raw_ostream &OS) {}
2290
2291void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2292 raw_ostream &OS) {
2293 OS << T->getDecl()->getName();
2294 if (!T->qual_empty()) {
2295 bool isFirst = true;
2296 OS << '<';
2297 for (const auto *I : T->quals()) {
2298 if (isFirst)
2299 isFirst = false;
2300 else
2301 OS << ',';
2302 OS << I->getName();
2303 }
2304 OS << '>';
2305 }
2306
2307 spaceBeforePlaceHolder(OS);
2308}
2309
2310void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2311 raw_ostream &OS) {}
2312
2313void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2314 raw_ostream &OS) {
2315 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2316 !T->isKindOfTypeAsWritten())
2317 return printBefore(T->getBaseType(), OS);
2318
2319 if (T->isKindOfTypeAsWritten())
2320 OS << "__kindof ";
2321
2322 print(T->getBaseType(), OS, StringRef());
2323
2324 if (T->isSpecializedAsWritten()) {
2325 bool isFirst = true;
2326 OS << '<';
2327 for (auto typeArg : T->getTypeArgsAsWritten()) {
2328 if (isFirst)
2329 isFirst = false;
2330 else
2331 OS << ",";
2332
2333 print(typeArg, OS, StringRef());
2334 }
2335 OS << '>';
2336 }
2337
2338 if (!T->qual_empty()) {
2339 bool isFirst = true;
2340 OS << '<';
2341 for (const auto *I : T->quals()) {
2342 if (isFirst)
2343 isFirst = false;
2344 else
2345 OS << ',';
2346 OS << I->getName();
2347 }
2348 OS << '>';
2349 }
2350
2351 spaceBeforePlaceHolder(OS);
2352}
2353
2354void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2355 raw_ostream &OS) {
2356 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2357 !T->isKindOfTypeAsWritten())
2358 return printAfter(T->getBaseType(), OS);
2359}
2360
2361void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2362 raw_ostream &OS) {
2363 printBefore(T->getPointeeType(), OS);
2364
2365 // If we need to print the pointer, print it now.
2366 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2368 if (HasEmptyPlaceHolder)
2369 OS << ' ';
2370 OS << '*';
2371 }
2372}
2373
2374void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2375 raw_ostream &OS) {}
2376
2377static
2378const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2379
2381 return A.getArgument();
2382}
2383
2384static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2385 llvm::raw_ostream &OS, bool IncludeType) {
2386 A.print(PP, OS, IncludeType);
2387}
2388
2390 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2391 bool IncludeType) {
2392 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2394 return A.getTypeSourceInfo()->getType().print(OS, PP);
2395 return A.getArgument().print(PP, OS, IncludeType);
2396}
2397
2398static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2399 TemplateArgument Pattern,
2400 ArrayRef<TemplateArgument> Args,
2401 unsigned Depth);
2402
2404 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2405 if (Ctx.hasSameType(T, Pattern))
2406 return true;
2407
2408 // A type parameter matches its argument.
2409 if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {
2410 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2411 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2412 QualType SubstArg = Ctx.getQualifiedType(
2413 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2414 return Ctx.hasSameType(SubstArg, T);
2415 }
2416 return false;
2417 }
2418
2419 // FIXME: Recurse into array types.
2420
2421 // All other cases will need the types to be identically qualified.
2422 Qualifiers TQual, PatQual;
2423 T = Ctx.getUnqualifiedArrayType(T, TQual);
2424 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2425 if (TQual != PatQual)
2426 return false;
2427
2428 // Recurse into pointer-like types.
2429 {
2430 QualType TPointee = T->getPointeeType();
2431 QualType PPointee = Pattern->getPointeeType();
2432 if (!TPointee.isNull() && !PPointee.isNull())
2433 return T->getTypeClass() == Pattern->getTypeClass() &&
2434 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2435 }
2436
2437 // Recurse into template specialization types.
2438 if (auto *PTST =
2439 Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {
2441 ArrayRef<TemplateArgument> TemplateArgs;
2442 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2443 Template = TTST->getTemplateName();
2444 TemplateArgs = TTST->template_arguments();
2445 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2446 T->getAsCXXRecordDecl())) {
2447 Template = TemplateName(CTSD->getSpecializedTemplate());
2448 TemplateArgs = CTSD->getTemplateArgs().asArray();
2449 } else {
2450 return false;
2451 }
2452
2453 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2454 Args, Depth))
2455 return false;
2456 if (TemplateArgs.size() != PTST->template_arguments().size())
2457 return false;
2458 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2460 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2461 return false;
2462 return true;
2463 }
2464
2465 // FIXME: Handle more cases.
2466 return false;
2467}
2468
2469/// Evaluates the expression template argument 'Pattern' and returns true
2470/// if 'Arg' evaluates to the same result.
2472 TemplateArgument const &Pattern,
2473 TemplateArgument const &Arg) {
2474 if (Pattern.getKind() != TemplateArgument::Expression)
2475 return false;
2476
2477 // Can't evaluate value-dependent expressions so bail early
2478 Expr const *pattern_expr = Pattern.getAsExpr();
2479 if (pattern_expr->isValueDependent() ||
2480 !pattern_expr->isIntegerConstantExpr(Ctx))
2481 return false;
2482
2484 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2485 Arg.getAsIntegral());
2486
2488 Expr const *args_expr = Arg.getAsExpr();
2489 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2490 return false;
2491
2492 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2493 pattern_expr->EvaluateKnownConstInt(Ctx));
2494 }
2495
2496 return false;
2497}
2498
2500 TemplateArgument Pattern,
2502 unsigned Depth) {
2503 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2504 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2505 if (Arg.structurallyEquals(Pattern))
2506 return true;
2507
2508 if (Pattern.getKind() == TemplateArgument::Expression) {
2509 if (auto *DRE =
2510 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2511 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2512 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2513 Args[NTTP->getIndex()].structurallyEquals(Arg);
2514 }
2515 }
2516
2517 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2518 return true;
2519
2520 if (Arg.getKind() != Pattern.getKind())
2521 return false;
2522
2523 if (Arg.getKind() == TemplateArgument::Type)
2524 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2525 Depth);
2526
2527 if (Arg.getKind() == TemplateArgument::Template) {
2528 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2529 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2530 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2531 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2532 .structurallyEquals(Arg);
2533 }
2534
2535 // FIXME: Handle more cases.
2536 return false;
2537}
2538
2539bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2540 const NamedDecl *Param,
2541 ArrayRef<TemplateArgument> Args,
2542 unsigned Depth) {
2543 // An empty pack is equivalent to not providing a pack argument.
2544 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2545 return true;
2546
2547 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2548 return TTPD->hasDefaultArgument() &&
2550 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2551 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2552 return TTPD->hasDefaultArgument() &&
2554 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2555 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2556 return NTTPD->hasDefaultArgument() &&
2558 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2559 Depth);
2560 }
2561 return false;
2562}
2563
2564template <typename TA>
2565static void
2566printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2567 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2568 // Drop trailing template arguments that match default arguments.
2569 if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&
2570 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2572 for (const TA &A : Args)
2573 OrigArgs.push_back(getArgument(A));
2574 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2575 Args = Args.drop_back();
2576 }
2577
2578 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2579 if (!IsPack)
2580 OS << '<';
2581
2582 bool NeedSpace = false;
2583 bool FirstArg = true;
2584 for (const auto &Arg : Args) {
2585 // Print the argument into a string.
2586 SmallString<128> Buf;
2587 llvm::raw_svector_ostream ArgOS(Buf);
2588 const TemplateArgument &Argument = getArgument(Arg);
2589 if (Argument.getKind() == TemplateArgument::Pack) {
2590 if (Argument.pack_size() && !FirstArg)
2591 OS << Comma;
2592 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2593 /*IsPack*/ true, ParmIndex);
2594 } else {
2595 if (!FirstArg)
2596 OS << Comma;
2597 // Tries to print the argument with location info if exists.
2598 printArgument(Arg, Policy, ArgOS,
2600 Policy, TPL, ParmIndex));
2601 }
2602 StringRef ArgString = ArgOS.str();
2603
2604 // If this is the first argument and its string representation
2605 // begins with the global scope specifier ('::foo'), add a space
2606 // to avoid printing the diagraph '<:'.
2607 if (FirstArg && ArgString.starts_with(":"))
2608 OS << ' ';
2609
2610 OS << ArgString;
2611
2612 // If the last character of our string is '>', add another space to
2613 // keep the two '>''s separate tokens.
2614 if (!ArgString.empty()) {
2615 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2616 FirstArg = false;
2617 }
2618
2619 // Use same template parameter for all elements of Pack
2620 if (!IsPack)
2621 ParmIndex++;
2622 }
2623
2624 if (!IsPack) {
2625 if (NeedSpace)
2626 OS << ' ';
2627 OS << '>';
2628 }
2629}
2630
2631void clang::printTemplateArgumentList(raw_ostream &OS,
2632 const TemplateArgumentListInfo &Args,
2633 const PrintingPolicy &Policy,
2634 const TemplateParameterList *TPL) {
2635 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2636}
2637
2638void clang::printTemplateArgumentList(raw_ostream &OS,
2639 ArrayRef<TemplateArgument> Args,
2640 const PrintingPolicy &Policy,
2641 const TemplateParameterList *TPL) {
2642 PrintingPolicy InnerPolicy = Policy;
2643 InnerPolicy.SuppressScope = false;
2644 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2645}
2646
2647void clang::printTemplateArgumentList(raw_ostream &OS,
2648 ArrayRef<TemplateArgumentLoc> Args,
2649 const PrintingPolicy &Policy,
2650 const TemplateParameterList *TPL) {
2651 PrintingPolicy InnerPolicy = Policy;
2652 InnerPolicy.SuppressScope = false;
2653 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2654}
2655
2657 LangOptions LO;
2658 return getAsString(PrintingPolicy(LO));
2659}
2660
2662 SmallString<64> Buf;
2663 llvm::raw_svector_ostream StrOS(Buf);
2664 print(StrOS, P);
2665 return StrOS.str().str();
2666}
2667
2669 return !isPresent();
2670}
2671
2672void PointerAuthQualifier::print(raw_ostream &OS,
2673 const PrintingPolicy &P) const {
2674 if (!isPresent())
2675 return;
2676
2677 OS << "__ptrauth(";
2678 OS << getKey();
2679 OS << "," << unsigned(isAddressDiscriminated()) << ","
2680 << getExtraDiscriminator() << ")";
2681}
2682
2683std::string Qualifiers::getAsString() const {
2684 LangOptions LO;
2685 return getAsString(PrintingPolicy(LO));
2686}
2687
2688// Appends qualifiers to the given string, separated by spaces. Will
2689// prefix a space if the string is non-empty. Will not append a final
2690// space.
2691std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2692 SmallString<64> Buf;
2693 llvm::raw_svector_ostream StrOS(Buf);
2694 print(StrOS, Policy);
2695 return std::string(StrOS.str());
2696}
2697
2699 if (getCVRQualifiers())
2700 return false;
2701
2703 return false;
2704
2705 if (getObjCGCAttr())
2706 return false;
2707
2709 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2710 return false;
2711
2712 if (PointerAuthQualifier PointerAuth = getPointerAuth();
2713 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))
2714 return false;
2715
2716 return true;
2717}
2718
2720 switch (AS) {
2721 case LangAS::Default:
2722 return "";
2725 return "__global";
2727 case LangAS::sycl_local:
2728 return "__local";
2731 return "__private";
2733 return "__constant";
2735 return "__generic";
2738 return "__global_device";
2741 return "__global_host";
2743 return "__device__";
2745 return "__constant__";
2747 return "__shared__";
2748 case LangAS::ptr32_sptr:
2749 return "__sptr __ptr32";
2750 case LangAS::ptr32_uptr:
2751 return "__uptr __ptr32";
2752 case LangAS::ptr64:
2753 return "__ptr64";
2755 return "groupshared";
2757 return "hlsl_constant";
2759 return "hlsl_private";
2761 return "hlsl_device";
2762 case LangAS::hlsl_input:
2763 return "hlsl_input";
2765 return "hlsl_output";
2767 return "hlsl_push_constant";
2769 return "__funcref";
2771 return "amdgpu_barrier";
2772 default:
2773 return std::to_string(toTargetAddressSpace(AS));
2774 }
2775}
2776
2777// Appends qualifiers to the given string, separated by spaces. Will
2778// prefix a space if the string is non-empty. Will not append a final
2779// space.
2780void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2781 bool appendSpaceIfNonEmpty) const {
2782 bool addSpace = false;
2783
2784 unsigned quals = getCVRQualifiers();
2785 if (quals) {
2786 AppendTypeQualList(OS, quals, Policy.Restrict);
2787 addSpace = true;
2788 }
2789 if (hasUnaligned()) {
2790 if (addSpace)
2791 OS << ' ';
2792 OS << "__unaligned";
2793 addSpace = true;
2794 }
2795 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2796 if (!ASStr.empty()) {
2797 if (addSpace)
2798 OS << ' ';
2799 addSpace = true;
2800 // Wrap target address space into an attribute syntax
2802 OS << "__attribute__((address_space(" << ASStr << ")))";
2803 else
2804 OS << ASStr;
2805 }
2806
2807 if (Qualifiers::GC gc = getObjCGCAttr()) {
2808 if (addSpace)
2809 OS << ' ';
2810 addSpace = true;
2811 if (gc == Qualifiers::Weak)
2812 OS << "__weak";
2813 else
2814 OS << "__strong";
2815 }
2816 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2817 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2818 if (addSpace)
2819 OS << ' ';
2820 addSpace = true;
2821 }
2822
2823 switch (lifetime) {
2824 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2825 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2827 if (!Policy.SuppressStrongLifetime)
2828 OS << "__strong";
2829 break;
2830
2831 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2832 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2833 }
2834 }
2835
2836 if (PointerAuthQualifier PointerAuth = getPointerAuth()) {
2837 if (addSpace)
2838 OS << ' ';
2839 addSpace = true;
2840
2841 PointerAuth.print(OS, Policy);
2842 }
2843
2844 if (appendSpaceIfNonEmpty && addSpace)
2845 OS << ' ';
2846}
2847
2848std::string QualType::getAsString() const {
2849 return getAsString(split(), LangOptions());
2850}
2851
2852std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2853 std::string S;
2854 getAsStringInternal(S, Policy);
2855 return S;
2856}
2857
2858std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2859 const PrintingPolicy &Policy) {
2860 std::string buffer;
2861 getAsStringInternal(ty, qs, buffer, Policy);
2862 return buffer;
2863}
2864
2865void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2866 const Twine &PlaceHolder, unsigned Indentation) const {
2867 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2868 Indentation);
2869}
2870
2872 raw_ostream &OS, const PrintingPolicy &policy,
2873 const Twine &PlaceHolder, unsigned Indentation) {
2874 SmallString<128> PHBuf;
2875 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2876
2877 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2878}
2879
2880void QualType::getAsStringInternal(std::string &Str,
2881 const PrintingPolicy &Policy) const {
2882 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2883 Policy);
2884}
2885
2887 std::string &buffer,
2888 const PrintingPolicy &policy) {
2889 SmallString<256> Buf;
2890 llvm::raw_svector_ostream StrOS(Buf);
2891 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2892 std::string str = std::string(StrOS.str());
2893 buffer.swap(str);
2894}
2895
2896raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2897 SplitQualType S = QT.split();
2898 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2899 return OS;
2900}
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, const Context &Ctx, 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:239
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.
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4465
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition TypeBase.h:3498
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
This represents one expression.
Definition Expr.h:113
bool isIntegerConstantExpr(const ASTContext &Ctx) const
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:178
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:3123
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5385
QualType desugar() const
Definition TypeBase.h:5966
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5692
unsigned getNumParams() const
Definition TypeBase.h:5663
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition TypeBase.h:5805
Qualifiers getMethodQuals() const
Definition TypeBase.h:5811
QualType getParamType(unsigned i) const
Definition TypeBase.h:5665
FunctionEffectsRef getFunctionEffects() const
Definition TypeBase.h:5949
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition TypeBase.h:5882
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5743
bool hasCFIUncheckedCallee() const
Definition TypeBase.h:5807
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5735
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition TypeBase.h:5701
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5789
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition TypeBase.h:5750
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5819
CallingConv getCC() const
Definition TypeBase.h:4751
unsigned getRegParm() const
Definition TypeBase.h:4744
bool getNoCallerSavedRegs() const
Definition TypeBase.h:4740
ExtInfo getExtInfo() const
Definition TypeBase.h:4937
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition TypeBase.h:4890
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition TypeBase.h:4886
QualType getReturnType() const
Definition TypeBase.h:4921
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:296
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:302
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:1718
Pointer-authentication qualifiers.
Definition TypeBase.h:153
bool isAddressDiscriminated() const
Definition TypeBase.h:266
unsigned getExtraDiscriminator() const
Definition TypeBase.h:271
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:259
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8458
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:8470
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition TypeBase.h:8439
std::string getAsString() const
The collection of all-type qualifiers we support.
Definition TypeBase.h:332
unsigned getCVRQualifiers() const
Definition TypeBase.h:489
GC getObjCGCAttr() const
Definition TypeBase.h:520
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:362
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition TypeBase.h:355
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:351
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:365
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition TypeBase.h:368
bool hasUnaligned() const
Definition TypeBase.h:512
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
PointerAuthQualifier getPointerAuth() const
Definition TypeBase.h:604
ObjCLifetime getObjCLifetime() const
Definition TypeBase.h:546
bool empty() const
Definition TypeBase.h:648
std::string getAsString() const
LangAS getAddressSpace() const
Definition TypeBase.h:572
static std::string getAddrSpaceAsString(LangAS AS)
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3658
StringRef getKindName() const
Definition Decl.h:4048
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:4089
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override
Pretty-print the unqualified name of this declaration.
Definition Decl.cpp:5092
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.
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8400
The base class of the type hierarchy.
Definition TypeBase.h:1879
bool isArrayType() const
Definition TypeBase.h:8754
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition Type.cpp:558
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9321
bool isObjCQualifiedIdType() const
Definition TypeBase.h:8855
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
bool isObjCIdType() const
Definition TypeBase.h:8867
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition Type.cpp:3358
bool isFunctionType() const
Definition TypeBase.h:8651
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8861
bool isObjCClassType() const
Definition TypeBase.h:8873
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2998
TypeClass getTypeClass() const
Definition TypeBase.h:2449
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
Definition TypeBase.h:2475
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9254
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.
Top level wrappers for InstallAPI frontend operations.
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:1801
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1804
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1807
@ 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:379
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
Definition Specifiers.h:400
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
Definition Specifiers.h:390
@ Ordinary
This parameter uses ordinary ABI rules for its type.
Definition Specifiers.h:381
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
Definition Specifiers.h:385
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
Definition Specifiers.h:395
const FunctionProtoType * T
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:556
@ Type
The name was classified as a type.
Definition Sema.h:558
@ Concept
The name was classified as a concept name.
Definition Sema.h:585
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:1305
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:63
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
@ CC_X86Pascal
Definition Specifiers.h:285
@ CC_Swift
Definition Specifiers.h:293
@ CC_IntelOclBicc
Definition Specifiers.h:291
@ CC_PreserveMost
Definition Specifiers.h:295
@ CC_Win64
Definition Specifiers.h:286
@ CC_X86ThisCall
Definition Specifiers.h:283
@ CC_AArch64VectorCall
Definition Specifiers.h:297
@ CC_DeviceKernel
Definition Specifiers.h:292
@ CC_AAPCS
Definition Specifiers.h:289
@ CC_PreserveNone
Definition Specifiers.h:300
@ CC_M68kRTD
Definition Specifiers.h:299
@ CC_SwiftAsync
Definition Specifiers.h:294
@ CC_X86RegCall
Definition Specifiers.h:288
@ CC_RISCVVectorCall
Definition Specifiers.h:301
@ CC_X86VectorCall
Definition Specifiers.h:284
@ CC_AArch64SVEPCS
Definition Specifiers.h:298
@ CC_X86StdCall
Definition Specifiers.h:281
@ CC_X86_64SysV
Definition Specifiers.h:287
@ CC_PreserveAll
Definition Specifiers.h:296
@ CC_X86FastCall
Definition Specifiers.h:282
@ CC_AAPCS_VFP
Definition Specifiers.h:290
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:5983
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
ArrayRef< TemplateArgumentLoc > arguments() const
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition Type.cpp:3468
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:871
const Type * Ty
The locally-unqualified type.
Definition TypeBase.h:873
Qualifiers Quals
The local qualifiers.
Definition TypeBase.h:876