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::OverflowBehavior:
246 case Type::BTFTagAttributed:
247 case Type::HLSLAttributedResource:
248 case Type::HLSLInlineSpirv:
249 case Type::PredefinedSugar:
250 CanPrefixQualifiers = true;
251 break;
252
253 case Type::ObjCObjectPointer:
254 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
256 break;
257
258 case Type::VariableArray:
259 case Type::DependentSizedArray:
260 NeedARCStrongQualifier = true;
261 [[fallthrough]];
262
263 case Type::ConstantArray:
264 case Type::IncompleteArray:
265 return canPrefixQualifiers(
266 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
267 NeedARCStrongQualifier);
268
269 case Type::Adjusted:
270 case Type::Decayed:
271 case Type::ArrayParameter:
272 case Type::Pointer:
273 case Type::BlockPointer:
274 case Type::LValueReference:
275 case Type::RValueReference:
276 case Type::MemberPointer:
277 case Type::DependentAddressSpace:
278 case Type::DependentVector:
279 case Type::DependentSizedExtVector:
280 case Type::Vector:
281 case Type::ExtVector:
282 case Type::ConstantMatrix:
283 case Type::DependentSizedMatrix:
284 case Type::FunctionProto:
285 case Type::FunctionNoProto:
286 case Type::Paren:
287 case Type::PackExpansion:
288 case Type::SubstTemplateTypeParm:
289 case Type::MacroQualified:
290 case Type::CountAttributed:
291 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 if (Policy.ResolveDecltype && T->isSugared()) {
1363 printBefore(T->desugar(), OS);
1364 return;
1365 }
1366 OS << "decltype(";
1367 if (const Expr *E = T->getUnderlyingExpr()) {
1368 PrintingPolicy ExprPolicy = Policy;
1369 ExprPolicy.PrintAsCanonical = T->isCanonicalUnqualified();
1370 E->printPretty(OS, nullptr, ExprPolicy);
1371 }
1372 OS << ')';
1373 spaceBeforePlaceHolder(OS);
1374}
1375
1376void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1377 raw_ostream &OS) {
1378 if (T->hasSelectedType()) {
1379 OS << T->getSelectedType();
1380 } else {
1381 OS << T->getPattern() << "...[";
1382 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1383 OS << "]";
1384 }
1385 spaceBeforePlaceHolder(OS);
1386}
1387
1388void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1389 raw_ostream &OS) {}
1390
1391void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {
1392 if (Policy.ResolveDecltype && T->isSugared())
1393 printAfter(T->desugar(), OS);
1394}
1395
1396void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1397 raw_ostream &OS) {
1398 IncludeStrongLifetimeRAII Strong(Policy);
1399
1400 static const llvm::DenseMap<int, const char *> Transformation = {{
1401#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1402 {UnaryTransformType::Enum, "__" #Trait},
1403#include "clang/Basic/BuiltinTraits.inc"
1404 }};
1405 OS << Transformation.lookup(T->getUTTKind()) << '(';
1406 print(T->getBaseType(), OS, StringRef());
1407 OS << ')';
1408 spaceBeforePlaceHolder(OS);
1409}
1410
1411void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1412 raw_ostream &OS) {}
1413
1414void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1415 // If the type has been deduced, do not print 'auto'.
1416 if (!T->getDeducedType().isNull()) {
1417 printBefore(T->getDeducedType(), OS);
1418 } else {
1419 if (T->isConstrained()) {
1420 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1421 // type as it was written.
1422 TemplateName Concept = T->getTypeConstraintConcept();
1423 Concept.print(OS, Policy, TemplateName::Qualified::None);
1424 auto Args = T->getTypeConstraintArguments();
1425 if (!Args.empty()) {
1426 const TemplateDecl *TD = Concept.getAsTemplateDecl();
1427 if (!TD)
1428 TD = Concept.getAsTemplateTemplateParmDecl();
1429 printTemplateArgumentList(OS, Args, Policy,
1430 TD->getTemplateParameters());
1431 }
1432 OS << ' ';
1433 }
1434 switch (T->getKeyword()) {
1435 case AutoTypeKeyword::Auto: OS << "auto"; break;
1436 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1437 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1438 }
1439 spaceBeforePlaceHolder(OS);
1440 }
1441}
1442
1443void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1444 // If the type has been deduced, do not print 'auto'.
1445 if (!T->getDeducedType().isNull())
1446 printAfter(T->getDeducedType(), OS);
1447}
1448
1449void TypePrinter::printDeducedTemplateSpecializationBefore(
1450 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1451 if (ElaboratedTypeKeyword Keyword = T->getKeyword();
1452 T->getKeyword() != ElaboratedTypeKeyword::None)
1454
1455 TemplateName Name = T->getTemplateName();
1456
1457 // If the type has been deduced, print the template arguments, as if this was
1458 // printing the deduced type, but including elaboration and template name
1459 // qualification.
1460 // FIXME: There should probably be a policy which controls this.
1461 // We would probably want to do this on diagnostics, but not on -ast-print.
1462 ArrayRef<TemplateArgument> Args;
1463 TemplateDecl *DeducedTD = nullptr;
1464 if (!T->getDeducedType().isNull()) {
1465 if (const auto *TST =
1466 dyn_cast<TemplateSpecializationType>(T->getDeducedType())) {
1467 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1468 /*IgnoreDeduced=*/true);
1469 Args = TST->template_arguments();
1470 } else {
1471 // Should only get here for canonical types.
1473 cast<RecordType>(T->getDeducedType())->getDecl());
1474 DeducedTD = CD->getSpecializedTemplate();
1475 Args = CD->getTemplateArgs().asArray();
1476 }
1477
1478 // FIXME: Workaround for alias template CTAD not producing guides which
1479 // include the alias template specialization type.
1480 // Purposefully disregard qualification when building this TemplateName;
1481 // any qualification we might have, might not make sense in the
1482 // context this was deduced.
1483 if (!declaresSameEntity(DeducedTD, Name.getAsTemplateDecl(
1484 /*IgnoreDeduced=*/true)))
1485 Name = TemplateName(DeducedTD);
1486 }
1487
1488 {
1489 IncludeStrongLifetimeRAII Strong(Policy);
1490 Name.print(OS, Policy);
1491 }
1492 if (DeducedTD) {
1493 printTemplateArgumentList(OS, Args, Policy,
1494 DeducedTD->getTemplateParameters());
1495 }
1496
1497 spaceBeforePlaceHolder(OS);
1498}
1499
1500void TypePrinter::printDeducedTemplateSpecializationAfter(
1501 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1502 // If the type has been deduced, print the deduced type.
1503 if (!T->getDeducedType().isNull())
1504 printAfter(T->getDeducedType(), OS);
1505}
1506
1507void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1508 IncludeStrongLifetimeRAII Strong(Policy);
1509
1510 OS << "_Atomic(";
1511 print(T->getValueType(), OS, StringRef());
1512 OS << ')';
1513 spaceBeforePlaceHolder(OS);
1514}
1515
1516void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1517
1518void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1519 IncludeStrongLifetimeRAII Strong(Policy);
1520
1521 if (T->isReadOnly())
1522 OS << "read_only ";
1523 else
1524 OS << "write_only ";
1525 OS << "pipe ";
1526 print(T->getElementType(), OS, StringRef());
1527 spaceBeforePlaceHolder(OS);
1528}
1529
1530void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1531
1532void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1533 if (T->isUnsigned())
1534 OS << "unsigned ";
1535 OS << "_BitInt(" << T->getNumBits() << ")";
1536 spaceBeforePlaceHolder(OS);
1537}
1538
1539void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1540
1541void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1542 raw_ostream &OS) {
1543 if (T->isUnsigned())
1544 OS << "unsigned ";
1545 OS << "_BitInt(";
1546 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1547 OS << ")";
1548 spaceBeforePlaceHolder(OS);
1549}
1550
1551void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1552 raw_ostream &OS) {}
1553
1554void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,
1555 raw_ostream &OS) {
1556 OS << T->getIdentifier()->getName();
1557 spaceBeforePlaceHolder(OS);
1558}
1559
1560void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,
1561 raw_ostream &OS) {}
1562
1563void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
1564 TagDecl *D = T->getDecl();
1565
1566 if (Policy.IncludeTagDefinition && T->isTagOwned()) {
1567 D->print(OS, Policy, Indentation);
1568 spaceBeforePlaceHolder(OS);
1569 return;
1570 }
1571
1572 bool PrintedKindDecoration = false;
1573 if (T->isCanonicalUnqualified()) {
1574 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1575 PrintedKindDecoration = true;
1576 OS << D->getKindName();
1577 OS << ' ';
1578 }
1579 } else {
1580 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1581 if (T->getKeyword() != ElaboratedTypeKeyword::None) {
1582 PrintedKindDecoration = true;
1583 OS << ' ';
1584 }
1585 }
1586
1587 if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
1588 T->getQualifier().print(OS, Policy);
1589 } else if (!Policy.SuppressScope) {
1590 // Compute the full nested-name-specifier for this type.
1591 // In C, this will always be empty except when the type
1592 // being printed is anonymous within other Record.
1593 D->printNestedNameSpecifier(OS, Policy);
1594 }
1595
1596 if (const IdentifierInfo *II = D->getIdentifier())
1597 OS << II->getName();
1598 else {
1599 clang::PrintingPolicy Copy(Policy);
1600
1601 // Suppress the redundant tag keyword if we just printed one.
1602 if (PrintedKindDecoration) {
1603 Copy.SuppressTagKeywordInAnonNames = true;
1604 Copy.SuppressTagKeyword = true;
1605 }
1606
1607 D->printName(OS, Copy);
1608 }
1609
1610 // If this is a class template specialization, print the template
1611 // arguments.
1612 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1613 const TemplateParameterList *TParams =
1614 S->getSpecializedTemplate()->getTemplateParameters();
1615 const ASTTemplateArgumentListInfo *TArgAsWritten =
1616 S->getTemplateArgsAsWritten();
1617 IncludeStrongLifetimeRAII Strong(Policy);
1618 if (TArgAsWritten && !Policy.PrintAsCanonical)
1619 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1620 TParams);
1621 else
1622 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1623 TParams);
1624 }
1625
1626 spaceBeforePlaceHolder(OS);
1627}
1628
1629void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1630 // Print the preferred name if we have one for this type.
1631 if (Policy.UsePreferredNames) {
1632 for (const auto *PNA : T->getDecl()
1633 ->getMostRecentDecl()
1634 ->specific_attrs<PreferredNameAttr>()) {
1635 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1636 T->getDecl()))
1637 continue;
1638 // Find the outermost typedef or alias template.
1639 QualType T = PNA->getTypedefType();
1640 while (true) {
1641 if (auto *TT = dyn_cast<TypedefType>(T))
1642 return printTypeSpec(TT->getDecl(), OS);
1643 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1644 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1646 }
1647 }
1648 }
1649
1650 printTagType(T, OS);
1651}
1652
1653void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1654
1655void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1656 printTagType(T, OS);
1657}
1658
1659void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1660
1661void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1662 raw_ostream &OS) {
1663 const ASTContext &Ctx = T->getDecl()->getASTContext();
1664 IncludeStrongLifetimeRAII Strong(Policy);
1665 T->getTemplateName(Ctx).print(OS, Policy);
1666 if (Policy.PrintInjectedClassNameWithArguments) {
1667 auto *Decl = T->getDecl();
1668 // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
1669 // arguments.
1670 if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {
1671 printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),
1672 Policy,
1673 T->getTemplateDecl()->getTemplateParameters());
1674 } else {
1675 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
1676 assert(TD);
1677 printTemplateArgumentList(
1678 OS, TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx), Policy,
1679 T->getTemplateDecl()->getTemplateParameters());
1680 }
1681 }
1682 spaceBeforePlaceHolder(OS);
1683}
1684
1685void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1686 raw_ostream &OS) {}
1687
1688void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1689 raw_ostream &OS) {
1690 TemplateTypeParmDecl *D = T->getDecl();
1691 if (D && D->isImplicit()) {
1692 if (auto *TC = D->getTypeConstraint()) {
1693 TC->print(OS, Policy);
1694 OS << ' ';
1695 }
1696 OS << "auto";
1697 } else if (IdentifierInfo *Id = T->getIdentifier())
1698 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1699 : Id->getName());
1700 else
1701 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1702
1703 spaceBeforePlaceHolder(OS);
1704}
1705
1706void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1707 raw_ostream &OS) {}
1708
1709void TypePrinter::printSubstTemplateTypeParmBefore(
1710 const SubstTemplateTypeParmType *T,
1711 raw_ostream &OS) {
1712 IncludeStrongLifetimeRAII Strong(Policy);
1713 printBefore(T->getReplacementType(), OS);
1714}
1715
1716void TypePrinter::printSubstTemplateTypeParmAfter(
1717 const SubstTemplateTypeParmType *T,
1718 raw_ostream &OS) {
1719 IncludeStrongLifetimeRAII Strong(Policy);
1720 printAfter(T->getReplacementType(), OS);
1721}
1722
1723void TypePrinter::printSubstBuiltinTemplatePackBefore(
1724 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
1725 IncludeStrongLifetimeRAII Strong(Policy);
1726 OS << "type-pack";
1727}
1728
1729void TypePrinter::printSubstBuiltinTemplatePackAfter(
1730 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
1731
1732void TypePrinter::printSubstTemplateTypeParmPackBefore(
1733 const SubstTemplateTypeParmPackType *T,
1734 raw_ostream &OS) {
1735 IncludeStrongLifetimeRAII Strong(Policy);
1736 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1737 if (D && D->isImplicit()) {
1738 if (auto *TC = D->getTypeConstraint()) {
1739 TC->print(OS, Policy);
1740 OS << ' ';
1741 }
1742 OS << "auto";
1743 } else if (IdentifierInfo *Id = D->getIdentifier())
1744 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1745 : Id->getName());
1746 else
1747 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1748
1749 spaceBeforePlaceHolder(OS);
1750 }
1751}
1752
1753void TypePrinter::printSubstTemplateTypeParmPackAfter(
1754 const SubstTemplateTypeParmPackType *T,
1755 raw_ostream &OS) {
1756 IncludeStrongLifetimeRAII Strong(Policy);
1757}
1758
1759void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1760 raw_ostream &OS, bool FullyQualify) {
1761 IncludeStrongLifetimeRAII Strong(Policy);
1762
1763 if (ElaboratedTypeKeyword K = T->getKeyword();
1764 K != ElaboratedTypeKeyword::None)
1765 OS << TypeWithKeyword::getKeywordName(K) << ' ';
1766
1767 TemplateDecl *TD =
1768 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1769 // FIXME: Null TD never exercised in test suite.
1770 if (FullyQualify && TD) {
1771 if (!Policy.SuppressScope)
1772 TD->printNestedNameSpecifier(OS, Policy);
1773
1774 OS << TD->getName();
1775 } else {
1776 T->getTemplateName().print(OS, Policy,
1777 !Policy.SuppressScope
1778 ? TemplateName::Qualified::AsWritten
1779 : TemplateName::Qualified::None);
1780 }
1781
1782 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1783 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1784 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1785 spaceBeforePlaceHolder(OS);
1786}
1787
1788void TypePrinter::printTemplateSpecializationBefore(
1789 const TemplateSpecializationType *T,
1790 raw_ostream &OS) {
1791 printTemplateId(T, OS, Policy.FullyQualifiedName);
1792}
1793
1794void TypePrinter::printTemplateSpecializationAfter(
1795 const TemplateSpecializationType *T,
1796 raw_ostream &OS) {}
1797
1798void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1799 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1800 printBefore(T->getInnerType(), OS);
1801 OS << '(';
1802 } else
1803 printBefore(T->getInnerType(), OS);
1804}
1805
1806void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1807 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1808 OS << ')';
1809 printAfter(T->getInnerType(), OS);
1810 } else
1811 printAfter(T->getInnerType(), OS);
1812}
1813
1814void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1815 raw_ostream &OS) {
1816 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1817 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1818 OS << " ";
1819 T->getQualifier().print(OS, Policy);
1820 OS << T->getIdentifier()->getName();
1821 spaceBeforePlaceHolder(OS);
1822}
1823
1824void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1825 raw_ostream &OS) {}
1826
1827void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1828 raw_ostream &OS) {
1829 printBefore(T->getPattern(), OS);
1830}
1831
1832void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1833 raw_ostream &OS) {
1834 printAfter(T->getPattern(), OS);
1835 OS << "...";
1836}
1837
1839 raw_ostream &OS,
1840 const PrintingPolicy &Policy) {
1841 OS << ' ';
1842 if (T->isCountInBytes() && T->isOrNull())
1843 OS << "__sized_by_or_null(";
1844 else if (T->isCountInBytes())
1845 OS << "__sized_by(";
1846 else if (T->isOrNull())
1847 OS << "__counted_by_or_null(";
1848 else
1849 OS << "__counted_by(";
1850 if (T->getCountExpr())
1851 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1852 OS << ')';
1853}
1854
1855void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1856 raw_ostream &OS) {
1857 printBefore(T->desugar(), OS);
1858 if (!T->isArrayType())
1859 printCountAttributedImpl(T, OS, Policy);
1860}
1861
1862void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1863 raw_ostream &OS) {
1864 printAfter(T->desugar(), OS);
1865 if (T->isArrayType())
1866 printCountAttributedImpl(T, OS, Policy);
1867}
1868
1869void TypePrinter::printLateParsedAttrBefore(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 printBefore(T->getWrappedType(), OS);
1874}
1875
1876void TypePrinter::printLateParsedAttrAfter(const LateParsedAttrType *T,
1877 raw_ostream &OS) {
1878 // LateParsedAttrType is a transient placeholder that should not appear
1879 // in user-facing output. Just print the wrapped type.
1880 printAfter(T->getWrappedType(), OS);
1881}
1882
1883void TypePrinter::printAttributedBefore(const AttributedType *T,
1884 raw_ostream &OS) {
1885 // FIXME: Generate this with TableGen.
1886
1887 // Prefer the macro forms of the GC and ownership qualifiers.
1888 if (T->getAttrKind() == attr::ObjCGC ||
1889 T->getAttrKind() == attr::ObjCOwnership)
1890 return printBefore(T->getEquivalentType(), OS);
1891
1892 if (T->getAttrKind() == attr::ObjCKindOf)
1893 OS << "__kindof ";
1894
1895 if (T->getAttrKind() == attr::PreserveNone) {
1896 OS << "__attribute__((preserve_none)) ";
1897 spaceBeforePlaceHolder(OS);
1898 } else if (T->getAttrKind() == attr::PreserveMost) {
1899 OS << "__attribute__((preserve_most)) ";
1900 spaceBeforePlaceHolder(OS);
1901 } else if (T->getAttrKind() == attr::PreserveAll) {
1902 OS << "__attribute__((preserve_all)) ";
1903 spaceBeforePlaceHolder(OS);
1904 }
1905
1906 if (T->getAttrKind() == attr::AddressSpace)
1907 printBefore(T->getEquivalentType(), OS);
1908 else
1909 printBefore(T->getModifiedType(), OS);
1910
1911 if (T->isMSTypeSpec()) {
1912 switch (T->getAttrKind()) {
1913 default: return;
1914 case attr::Ptr32: OS << " __ptr32"; break;
1915 case attr::Ptr64: OS << " __ptr64"; break;
1916 case attr::SPtr: OS << " __sptr"; break;
1917 case attr::UPtr: OS << " __uptr"; break;
1918 }
1919 spaceBeforePlaceHolder(OS);
1920 }
1921
1922 if (T->isWebAssemblyFuncrefSpec())
1923 OS << "__funcref";
1924
1925 // Print nullability type specifiers.
1926 if (T->getImmediateNullability()) {
1927 if (T->getAttrKind() == attr::TypeNonNull)
1928 OS << " _Nonnull";
1929 else if (T->getAttrKind() == attr::TypeNullable)
1930 OS << " _Nullable";
1931 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1932 OS << " _Null_unspecified";
1933 else if (T->getAttrKind() == attr::TypeNullableResult)
1934 OS << " _Nullable_result";
1935 else
1936 llvm_unreachable("unhandled nullability");
1937 spaceBeforePlaceHolder(OS);
1938 }
1939}
1940
1941void TypePrinter::printAttributedAfter(const AttributedType *T,
1942 raw_ostream &OS) {
1943 // FIXME: Generate this with TableGen.
1944
1945 // Prefer the macro forms of the GC and ownership qualifiers.
1946 if (T->getAttrKind() == attr::ObjCGC ||
1947 T->getAttrKind() == attr::ObjCOwnership)
1948 return printAfter(T->getEquivalentType(), OS);
1949
1950 // If this is a calling convention attribute, don't print the implicit CC from
1951 // the modified type.
1952 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1953
1954 printAfter(T->getModifiedType(), OS);
1955
1956 // Some attributes are printed as qualifiers before the type, so we have
1957 // nothing left to do.
1958 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1959 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1960 return;
1961
1962 // Don't print the inert __unsafe_unretained attribute at all.
1963 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1964 return;
1965
1966 // Don't print ns_returns_retained unless it had an effect.
1967 if (T->getAttrKind() == attr::NSReturnsRetained &&
1968 !T->getEquivalentType()->castAs<FunctionType>()
1969 ->getExtInfo().getProducesResult())
1970 return;
1971
1972 if (T->getAttrKind() == attr::LifetimeBound) {
1973 OS << " [[clang::lifetimebound]]";
1974 return;
1975 }
1976 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1977 OS << " [[clang::lifetime_capture_by(";
1978 if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr()))
1979 llvm::interleaveComma(attr->getArgIdents(), OS,
1980 [&](auto it) { OS << it->getName(); });
1981 OS << ")]]";
1982 return;
1983 }
1984
1985 // The printing of the address_space attribute is handled by the qualifier
1986 // since it is still stored in the qualifier. Return early to prevent printing
1987 // this twice.
1988 if (T->getAttrKind() == attr::AddressSpace)
1989 return;
1990
1991 if (T->getAttrKind() == attr::AnnotateType) {
1992 // FIXME: Print the attribute arguments once we have a way to retrieve these
1993 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1994 // without the arguments so that we know at least that we had _some_
1995 // annotation on the type.
1996 OS << " [[clang::annotate_type(...)]]";
1997 return;
1998 }
1999
2000 if (T->getAttrKind() == attr::ArmStreaming) {
2001 OS << "__arm_streaming";
2002 return;
2003 }
2004 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
2005 OS << "__arm_streaming_compatible";
2006 return;
2007 }
2008
2009 if (T->getAttrKind() == attr::SwiftAttr) {
2010 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
2011 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
2012 << "\")))";
2013 }
2014 return;
2015 }
2016
2017 if (T->getAttrKind() == attr::PreserveAll ||
2018 T->getAttrKind() == attr::PreserveMost ||
2019 T->getAttrKind() == attr::PreserveNone) {
2020 // This has to be printed before the type.
2021 return;
2022 }
2023
2024 OS << " __attribute__((";
2025 switch (T->getAttrKind()) {
2026#define TYPE_ATTR(NAME)
2027#define DECL_OR_TYPE_ATTR(NAME)
2028#define ATTR(NAME) case attr::NAME:
2029#include "clang/Basic/AttrList.inc"
2030 llvm_unreachable("non-type attribute attached to type");
2031
2032 case attr::BTFTypeTag:
2033 llvm_unreachable("BTFTypeTag attribute handled separately");
2034
2035 case attr::HLSLResourceClass:
2036 case attr::HLSLIsROV:
2037 case attr::HLSLRawBuffer:
2038 case attr::HLSLContainedType:
2039 case attr::HLSLIsCounter:
2040 case attr::HLSLResourceDimension:
2041 case attr::HLSLIsArray:
2042 case attr::HLSLIsMultiSampled:
2043 llvm_unreachable("HLSL resource type attributes handled separately");
2044
2045 case attr::OpenCLPrivateAddressSpace:
2046 case attr::OpenCLGlobalAddressSpace:
2047 case attr::OpenCLGlobalDeviceAddressSpace:
2048 case attr::OpenCLGlobalHostAddressSpace:
2049 case attr::OpenCLLocalAddressSpace:
2050 case attr::OpenCLConstantAddressSpace:
2051 case attr::OpenCLGenericAddressSpace:
2052 case attr::HLSLGroupSharedAddressSpace:
2053 case attr::SYCLPrivateAddressSpace:
2054 case attr::SYCLGlobalAddressSpace:
2055 case attr::SYCLLocalAddressSpace:
2056 case attr::SYCLConstantAddressSpace:
2057 case attr::SYCLGenericAddressSpace:
2058 // FIXME: Update printAttributedBefore to print these once we generate
2059 // AttributedType nodes for them.
2060 llvm_unreachable("Address space attributes handled separately");
2061 case attr::CountedBy:
2062 case attr::CountedByOrNull:
2063 case attr::SizedBy:
2064 case attr::SizedByOrNull:
2065 case attr::LifetimeBound:
2066 case attr::LifetimeCaptureBy:
2067 case attr::TypeNonNull:
2068 case attr::TypeNullable:
2069 case attr::TypeNullableResult:
2070 case attr::TypeNullUnspecified:
2071 case attr::ObjCGC:
2072 case attr::ObjCInertUnsafeUnretained:
2073 case attr::ObjCKindOf:
2074 case attr::ObjCOwnership:
2075 case attr::Ptr32:
2076 case attr::Ptr64:
2077 case attr::SPtr:
2078 case attr::UPtr:
2079 case attr::PointerAuth:
2080 case attr::AddressSpace:
2081 case attr::CmseNSCall:
2082 case attr::AnnotateType:
2083 case attr::WebAssemblyFuncref:
2084 case attr::ArmAgnostic:
2085 case attr::ArmStreaming:
2086 case attr::ArmStreamingCompatible:
2087 case attr::ArmIn:
2088 case attr::ArmOut:
2089 case attr::ArmInOut:
2090 case attr::ArmPreserves:
2091 case attr::NonBlocking:
2092 case attr::NonAllocating:
2093 case attr::Blocking:
2094 case attr::Allocating:
2095 case attr::SwiftAttr:
2096 case attr::PreserveAll:
2097 case attr::PreserveMost:
2098 case attr::PreserveNone:
2099 case attr::OverflowBehavior:
2100 llvm_unreachable("This attribute should have been handled already");
2101
2102 case attr::NSReturnsRetained:
2103 OS << "ns_returns_retained";
2104 break;
2105
2106 case attr::HLSLRowMajor:
2107 OS << "row_major";
2108 break;
2109 case attr::HLSLColumnMajor:
2110 OS << "column_major";
2111 break;
2112
2113 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2114 // attribute again in printFunctionProtoAfter.
2115 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2116 case attr::CDecl: OS << "cdecl"; break;
2117 case attr::FastCall: OS << "fastcall"; break;
2118 case attr::StdCall: OS << "stdcall"; break;
2119 case attr::ThisCall: OS << "thiscall"; break;
2120 case attr::SwiftCall: OS << "swiftcall"; break;
2121 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2122 case attr::VectorCall: OS << "vectorcall"; break;
2123 case attr::Pascal: OS << "pascal"; break;
2124 case attr::MSABI: OS << "ms_abi"; break;
2125 case attr::SysVABI: OS << "sysv_abi"; break;
2126 case attr::RegCall: OS << "regcall"; break;
2127 case attr::Pcs: {
2128 OS << "pcs(";
2129 QualType t = T->getEquivalentType();
2130 while (!t->isFunctionType())
2131 t = t->getPointeeType();
2132 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2133 "\"aapcs\"" : "\"aapcs-vfp\"");
2134 OS << ')';
2135 break;
2136 }
2137 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2138 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2139 case attr::IntelOclBicc:
2140 OS << "inteloclbicc";
2141 break;
2142 case attr::M68kRTD:
2143 OS << "m68k_rtd";
2144 break;
2145 case attr::RISCVVectorCC:
2146 OS << "riscv_vector_cc";
2147 break;
2148 case attr::RISCVVLSCC:
2149 OS << "riscv_vls_cc";
2150 break;
2151 case attr::NoDeref:
2152 OS << "noderef";
2153 break;
2154 case attr::CFIUncheckedCallee:
2155 OS << "cfi_unchecked_callee";
2156 break;
2157 case attr::AcquireHandle:
2158 OS << "acquire_handle";
2159 break;
2160 case attr::ArmMveStrictPolymorphism:
2161 OS << "__clang_arm_mve_strict_polymorphism";
2162 break;
2163 case attr::ExtVectorType:
2164 OS << "ext_vector_type";
2165 break;
2166 case attr::CFISalt:
2167 OS << "cfi_salt(\"" << cast<CFISaltAttr>(T->getAttr())->getSalt() << "\")";
2168 break;
2169 case attr::NoFieldProtection:
2170 OS << "no_field_protection";
2171 break;
2172 case attr::PointerFieldProtection:
2173 OS << "pointer_field_protection";
2174 break;
2175 }
2176 OS << "))";
2177}
2178
2179void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2180 raw_ostream &OS) {
2181 printBefore(T->getWrappedType(), OS);
2182 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2183}
2184
2185void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2186 raw_ostream &OS) {
2187 printAfter(T->getWrappedType(), OS);
2188}
2189
2190void TypePrinter::printOverflowBehaviorBefore(const OverflowBehaviorType *T,
2191 raw_ostream &OS) {
2192 switch (T->getBehaviorKind()) {
2193 case clang::OverflowBehaviorType::OverflowBehaviorKind::Wrap:
2194 OS << "__ob_wrap ";
2195 break;
2196 case clang::OverflowBehaviorType::OverflowBehaviorKind::Trap:
2197 OS << "__ob_trap ";
2198 break;
2199 }
2200 printBefore(T->getUnderlyingType(), OS);
2201}
2202
2203void TypePrinter::printOverflowBehaviorAfter(const OverflowBehaviorType *T,
2204 raw_ostream &OS) {
2205 printAfter(T->getUnderlyingType(), OS);
2206}
2207
2208void TypePrinter::printHLSLAttributedResourceBefore(
2209 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2210 printBefore(T->getWrappedType(), OS);
2211}
2212
2213void TypePrinter::printHLSLAttributedResourceAfter(
2214 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2215 printAfter(T->getWrappedType(), OS);
2216 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2217 OS << " [[hlsl::resource_class(\""
2218 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2219 << "\")]]";
2220 if (Attrs.IsROV)
2221 OS << " [[hlsl::is_rov]]";
2222 if (Attrs.RawBuffer)
2223 OS << " [[hlsl::raw_buffer]]";
2224 if (Attrs.IsCounter)
2225 OS << " [[hlsl::is_counter]]";
2226 if (Attrs.IsArray)
2227 OS << " [[hlsl::is_array]]";
2228 if (Attrs.isMultiSampled())
2229 OS << " [[hlsl::is_ms]]";
2230
2231 QualType ContainedTy = T->getContainedType();
2232 if (!ContainedTy.isNull()) {
2233 OS << " [[hlsl::contained_type(";
2234 printBefore(ContainedTy, OS);
2235 printAfter(ContainedTy, OS);
2236 OS << ")]]";
2237 }
2238
2239 if (Attrs.ResourceDimension != llvm::dxil::ResourceDimension::Unknown)
2240 OS << " [[hlsl::dimension(\""
2241 << HLSLResourceDimensionAttr::ConvertResourceDimensionToStr(
2242 Attrs.ResourceDimension)
2243 << "\")]]";
2244}
2245
2246void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2247 raw_ostream &OS) {
2248 OS << "__hlsl_spirv_type<" << T->getOpcode();
2249
2250 OS << ", " << T->getSize();
2251 OS << ", " << T->getAlignment();
2252
2253 for (auto &Operand : T->getOperands()) {
2254 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2255
2256 OS << ", ";
2257 switch (Operand.getKind()) {
2258 case SpirvOperandKind::ConstantId: {
2259 QualType ConstantType = Operand.getResultType();
2260 OS << "vk::integral_constant<";
2261 printBefore(ConstantType, OS);
2262 printAfter(ConstantType, OS);
2263 OS << ", ";
2264 OS << Operand.getValue();
2265 OS << ">";
2266 break;
2267 }
2268 case SpirvOperandKind::Literal:
2269 OS << "vk::Literal<vk::integral_constant<uint, ";
2270 OS << Operand.getValue();
2271 OS << ">>";
2272 break;
2273 case SpirvOperandKind::TypeId: {
2274 QualType Type = Operand.getResultType();
2275 printBefore(Type, OS);
2276 printAfter(Type, OS);
2277 break;
2278 }
2279 default:
2280 llvm_unreachable("Invalid SpirvOperand kind!");
2281 break;
2282 }
2283 }
2284
2285 OS << ">";
2286}
2287
2288void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2289 raw_ostream &OS) {
2290 // nothing to do
2291}
2292
2293void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2294 raw_ostream &OS) {
2295 OS << T->getDecl()->getName();
2296 spaceBeforePlaceHolder(OS);
2297}
2298
2299void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2300 raw_ostream &OS) {}
2301
2302void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2303 raw_ostream &OS) {
2304 OS << T->getDecl()->getName();
2305 if (!T->qual_empty()) {
2306 bool isFirst = true;
2307 OS << '<';
2308 for (const auto *I : T->quals()) {
2309 if (isFirst)
2310 isFirst = false;
2311 else
2312 OS << ',';
2313 OS << I->getName();
2314 }
2315 OS << '>';
2316 }
2317
2318 spaceBeforePlaceHolder(OS);
2319}
2320
2321void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2322 raw_ostream &OS) {}
2323
2324void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2325 raw_ostream &OS) {
2326 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2327 !T->isKindOfTypeAsWritten())
2328 return printBefore(T->getBaseType(), OS);
2329
2330 if (T->isKindOfTypeAsWritten())
2331 OS << "__kindof ";
2332
2333 print(T->getBaseType(), OS, StringRef());
2334
2335 if (T->isSpecializedAsWritten()) {
2336 bool isFirst = true;
2337 OS << '<';
2338 for (auto typeArg : T->getTypeArgsAsWritten()) {
2339 if (isFirst)
2340 isFirst = false;
2341 else
2342 OS << ",";
2343
2344 print(typeArg, OS, StringRef());
2345 }
2346 OS << '>';
2347 }
2348
2349 if (!T->qual_empty()) {
2350 bool isFirst = true;
2351 OS << '<';
2352 for (const auto *I : T->quals()) {
2353 if (isFirst)
2354 isFirst = false;
2355 else
2356 OS << ',';
2357 OS << I->getName();
2358 }
2359 OS << '>';
2360 }
2361
2362 spaceBeforePlaceHolder(OS);
2363}
2364
2365void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2366 raw_ostream &OS) {
2367 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2368 !T->isKindOfTypeAsWritten())
2369 return printAfter(T->getBaseType(), OS);
2370}
2371
2372void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2373 raw_ostream &OS) {
2374 printBefore(T->getPointeeType(), OS);
2375
2376 // If we need to print the pointer, print it now.
2377 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2379 if (HasEmptyPlaceHolder)
2380 OS << ' ';
2381 OS << '*';
2382 }
2383}
2384
2385void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2386 raw_ostream &OS) {}
2387
2388static
2389const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2390
2392 return A.getArgument();
2393}
2394
2395static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2396 llvm::raw_ostream &OS, bool IncludeType) {
2397 A.print(PP, OS, IncludeType);
2398}
2399
2401 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2402 bool IncludeType) {
2403 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2405 return A.getTypeSourceInfo()->getType().print(OS, PP);
2406 return A.getArgument().print(PP, OS, IncludeType);
2407}
2408
2409static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2410 TemplateArgument Pattern,
2411 ArrayRef<TemplateArgument> Args,
2412 unsigned Depth);
2413
2415 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2416 if (Ctx.hasSameType(T, Pattern))
2417 return true;
2418
2419 // A type parameter matches its argument.
2420 if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {
2421 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2422 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2423 QualType SubstArg = Ctx.getQualifiedType(
2424 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2425 return Ctx.hasSameType(SubstArg, T);
2426 }
2427 return false;
2428 }
2429
2430 // FIXME: Recurse into array types.
2431
2432 // All other cases will need the types to be identically qualified.
2433 Qualifiers TQual, PatQual;
2434 T = Ctx.getUnqualifiedArrayType(T, TQual);
2435 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2436 if (TQual != PatQual)
2437 return false;
2438
2439 // Recurse into pointer-like types.
2440 {
2441 QualType TPointee = T->getPointeeType();
2442 QualType PPointee = Pattern->getPointeeType();
2443 if (!TPointee.isNull() && !PPointee.isNull())
2444 return T->getTypeClass() == Pattern->getTypeClass() &&
2445 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2446 }
2447
2448 // Recurse into template specialization types.
2449 if (auto *PTST =
2450 Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {
2452 ArrayRef<TemplateArgument> TemplateArgs;
2453 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2454 Template = TTST->getTemplateName();
2455 TemplateArgs = TTST->template_arguments();
2456 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2457 T->getAsCXXRecordDecl())) {
2458 Template = TemplateName(CTSD->getSpecializedTemplate());
2459 TemplateArgs = CTSD->getTemplateArgs().asArray();
2460 } else {
2461 return false;
2462 }
2463
2464 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2465 Args, Depth))
2466 return false;
2467 if (TemplateArgs.size() != PTST->template_arguments().size())
2468 return false;
2469 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2471 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2472 return false;
2473 return true;
2474 }
2475
2476 // FIXME: Handle more cases.
2477 return false;
2478}
2479
2480/// Evaluates the expression template argument 'Pattern' and returns true
2481/// if 'Arg' evaluates to the same result.
2483 TemplateArgument const &Pattern,
2484 TemplateArgument const &Arg) {
2485 if (Pattern.getKind() != TemplateArgument::Expression)
2486 return false;
2487
2488 // Can't evaluate value-dependent expressions so bail early
2489 Expr const *pattern_expr = Pattern.getAsExpr();
2490 if (pattern_expr->isValueDependent() ||
2491 !pattern_expr->isIntegerConstantExpr(Ctx))
2492 return false;
2493
2495 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2496 Arg.getAsIntegral());
2497
2499 Expr const *args_expr = Arg.getAsExpr();
2500 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2501 return false;
2502
2503 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2504 pattern_expr->EvaluateKnownConstInt(Ctx));
2505 }
2506
2507 return false;
2508}
2509
2511 TemplateArgument Pattern,
2513 unsigned Depth) {
2514 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2515 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2516 if (Arg.structurallyEquals(Pattern))
2517 return true;
2518
2519 if (Pattern.getKind() == TemplateArgument::Expression) {
2520 if (auto *DRE =
2521 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2522 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2523 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2524 Args[NTTP->getIndex()].structurallyEquals(Arg);
2525 }
2526 }
2527
2528 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2529 return true;
2530
2531 if (Arg.getKind() != Pattern.getKind())
2532 return false;
2533
2534 if (Arg.getKind() == TemplateArgument::Type)
2535 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2536 Depth);
2537
2538 if (Arg.getKind() == TemplateArgument::Template) {
2539 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2540 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2541 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2542 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2543 .structurallyEquals(Arg);
2544 }
2545
2546 // FIXME: Handle more cases.
2547 return false;
2548}
2549
2550bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2551 const NamedDecl *Param,
2552 ArrayRef<TemplateArgument> Args,
2553 unsigned Depth) {
2554 // An empty pack is equivalent to not providing a pack argument.
2555 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2556 return true;
2557
2558 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2559 return TTPD->hasDefaultArgument() &&
2561 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2562 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2563 return TTPD->hasDefaultArgument() &&
2565 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2566 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2567 return NTTPD->hasDefaultArgument() &&
2569 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2570 Depth);
2571 }
2572 return false;
2573}
2574
2575template <typename TA>
2576static void
2577printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2578 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2579 // Drop trailing template arguments that match default arguments.
2580 if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&
2581 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2583 for (const TA &A : Args)
2584 OrigArgs.push_back(getArgument(A));
2585 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2586 Args = Args.drop_back();
2587 }
2588
2589 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2590 if (!IsPack)
2591 OS << '<';
2592
2593 bool NeedSpace = false;
2594 bool FirstArg = true;
2595 for (const auto &Arg : Args) {
2596 // Print the argument into a string.
2597 SmallString<128> Buf;
2598 llvm::raw_svector_ostream ArgOS(Buf);
2599 const TemplateArgument &Argument = getArgument(Arg);
2600 if (Argument.getKind() == TemplateArgument::Pack) {
2601 if (Argument.pack_size() && !FirstArg)
2602 OS << Comma;
2603 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2604 /*IsPack*/ true, ParmIndex);
2605 } else {
2606 if (!FirstArg)
2607 OS << Comma;
2608 // Tries to print the argument with location info if exists.
2609 printArgument(Arg, Policy, ArgOS,
2611 Policy, TPL, ParmIndex));
2612 }
2613 StringRef ArgString = ArgOS.str();
2614
2615 // If this is the first argument and its string representation
2616 // begins with the global scope specifier ('::foo'), add a space
2617 // to avoid printing the diagraph '<:'.
2618 if (FirstArg && ArgString.starts_with(":"))
2619 OS << ' ';
2620
2621 OS << ArgString;
2622
2623 // If the last character of our string is '>', add another space to
2624 // keep the two '>''s separate tokens.
2625 if (!ArgString.empty()) {
2626 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2627 FirstArg = false;
2628 }
2629
2630 // Use same template parameter for all elements of Pack
2631 if (!IsPack)
2632 ParmIndex++;
2633 }
2634
2635 if (!IsPack) {
2636 if (NeedSpace)
2637 OS << ' ';
2638 OS << '>';
2639 }
2640}
2641
2642void clang::printTemplateArgumentList(raw_ostream &OS,
2643 const TemplateArgumentListInfo &Args,
2644 const PrintingPolicy &Policy,
2645 const TemplateParameterList *TPL) {
2646 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2647}
2648
2649void clang::printTemplateArgumentList(raw_ostream &OS,
2650 ArrayRef<TemplateArgument> Args,
2651 const PrintingPolicy &Policy,
2652 const TemplateParameterList *TPL) {
2653 PrintingPolicy InnerPolicy = Policy;
2654 InnerPolicy.SuppressScope = false;
2655 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2656}
2657
2658void clang::printTemplateArgumentList(raw_ostream &OS,
2659 ArrayRef<TemplateArgumentLoc> Args,
2660 const PrintingPolicy &Policy,
2661 const TemplateParameterList *TPL) {
2662 PrintingPolicy InnerPolicy = Policy;
2663 InnerPolicy.SuppressScope = false;
2664 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2665}
2666
2668 LangOptions LO;
2669 return getAsString(PrintingPolicy(LO));
2670}
2671
2673 SmallString<64> Buf;
2674 llvm::raw_svector_ostream StrOS(Buf);
2675 print(StrOS, P);
2676 return StrOS.str().str();
2677}
2678
2680 return !isPresent();
2681}
2682
2683void PointerAuthQualifier::print(raw_ostream &OS,
2684 const PrintingPolicy &P) const {
2685 if (!isPresent())
2686 return;
2687
2688 OS << "__ptrauth(";
2689 OS << getKey();
2690 OS << "," << unsigned(isAddressDiscriminated()) << ","
2691 << getExtraDiscriminator() << ")";
2692}
2693
2694std::string Qualifiers::getAsString() const {
2695 LangOptions LO;
2696 return getAsString(PrintingPolicy(LO));
2697}
2698
2699// Appends qualifiers to the given string, separated by spaces. Will
2700// prefix a space if the string is non-empty. Will not append a final
2701// space.
2702std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2703 SmallString<64> Buf;
2704 llvm::raw_svector_ostream StrOS(Buf);
2705 print(StrOS, Policy);
2706 return std::string(StrOS.str());
2707}
2708
2710 if (getCVRQualifiers())
2711 return false;
2712
2714 return false;
2715
2716 if (getObjCGCAttr())
2717 return false;
2718
2720 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2721 return false;
2722
2723 if (PointerAuthQualifier PointerAuth = getPointerAuth();
2724 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))
2725 return false;
2726
2727 return true;
2728}
2729
2731 switch (AS) {
2732 case LangAS::Default:
2733 return "";
2735 return "__global";
2737 return "__local";
2739 return "__private";
2741 return "__constant";
2743 return "__generic";
2744 // TODO: Remove *_global_device and *_global_host after corresponding
2745 // attributes are deprecated for the required time.
2748 return "__global_device";
2751 return "__global_host";
2753 return "[[clang::sycl_global]]";
2754 case LangAS::sycl_local:
2755 return "[[clang::sycl_local]]";
2757 return "[[clang::sycl_private]]";
2759 return "[[clang::sycl_generic]]";
2761 return "[[clang::sycl_constant]]";
2763 return "__device__";
2765 return "__constant__";
2767 return "__shared__";
2768 case LangAS::ptr32_sptr:
2769 return "__sptr __ptr32";
2770 case LangAS::ptr32_uptr:
2771 return "__uptr __ptr32";
2772 case LangAS::ptr64:
2773 return "__ptr64";
2775 return "groupshared";
2777 return "hlsl_constant";
2779 return "hlsl_private";
2781 return "hlsl_device";
2782 case LangAS::hlsl_input:
2783 return "hlsl_input";
2785 return "hlsl_output";
2787 return "hlsl_push_constant";
2789 return "__funcref";
2791 return "amdgpu_barrier";
2792 default:
2793 return std::to_string(toTargetAddressSpace(AS));
2794 }
2795}
2796
2797// Appends qualifiers to the given string, separated by spaces. Will
2798// prefix a space if the string is non-empty. Will not append a final
2799// space.
2800void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2801 bool appendSpaceIfNonEmpty) const {
2802 bool addSpace = false;
2803
2804 unsigned quals = getCVRQualifiers();
2805 if (quals) {
2806 AppendTypeQualList(OS, quals, Policy.Restrict);
2807 addSpace = true;
2808 }
2809 if (hasUnaligned()) {
2810 if (addSpace)
2811 OS << ' ';
2812 OS << "__unaligned";
2813 addSpace = true;
2814 }
2815 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2816 if (!ASStr.empty()) {
2817 if (addSpace)
2818 OS << ' ';
2819 addSpace = true;
2820 // Wrap target address space into an attribute syntax
2822 OS << "__attribute__((address_space(" << ASStr << ")))";
2823 else
2824 OS << ASStr;
2825 }
2826
2827 if (Qualifiers::GC gc = getObjCGCAttr()) {
2828 if (addSpace)
2829 OS << ' ';
2830 addSpace = true;
2831 if (gc == Qualifiers::Weak)
2832 OS << "__weak";
2833 else
2834 OS << "__strong";
2835 }
2836 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2837 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2838 if (addSpace)
2839 OS << ' ';
2840 addSpace = true;
2841 }
2842
2843 switch (lifetime) {
2844 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2845 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2847 if (!Policy.SuppressStrongLifetime)
2848 OS << "__strong";
2849 break;
2850
2851 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2852 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2853 }
2854 }
2855
2856 if (PointerAuthQualifier PointerAuth = getPointerAuth()) {
2857 if (addSpace)
2858 OS << ' ';
2859 addSpace = true;
2860
2861 PointerAuth.print(OS, Policy);
2862 }
2863
2864 if (appendSpaceIfNonEmpty && addSpace)
2865 OS << ' ';
2866}
2867
2868std::string QualType::getAsString() const {
2869 return getAsString(split(), LangOptions());
2870}
2871
2872std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2873 std::string S;
2874 getAsStringInternal(S, Policy);
2875 return S;
2876}
2877
2878std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2879 const PrintingPolicy &Policy) {
2880 std::string buffer;
2881 getAsStringInternal(ty, qs, buffer, Policy);
2882 return buffer;
2883}
2884
2885void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2886 const Twine &PlaceHolder, unsigned Indentation) const {
2887 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2888 Indentation);
2889}
2890
2892 raw_ostream &OS, const PrintingPolicy &policy,
2893 const Twine &PlaceHolder, unsigned Indentation) {
2894 SmallString<128> PHBuf;
2895 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2896
2897 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2898}
2899
2900void QualType::getAsStringInternal(std::string &Str,
2901 const PrintingPolicy &Policy) const {
2902 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2903 Policy);
2904}
2905
2907 std::string &buffer,
2908 const PrintingPolicy &policy) {
2909 SmallString<256> Buf;
2910 llvm::raw_svector_ostream StrOS(Buf);
2911 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2912 std::string str = std::string(StrOS.str());
2913 buffer.swap(str);
2914}
2915
2916raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2917 SplitQualType S = QT.split();
2918 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2919 return OS;
2920}
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:4478
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition TypeBase.h:3502
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:5398
QualType desugar() const
Definition TypeBase.h:5979
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5705
unsigned getNumParams() const
Definition TypeBase.h:5676
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition TypeBase.h:5818
Qualifiers getMethodQuals() const
Definition TypeBase.h:5824
QualType getParamType(unsigned i) const
Definition TypeBase.h:5678
FunctionEffectsRef getFunctionEffects() const
Definition TypeBase.h:5962
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition TypeBase.h:5895
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5756
bool hasCFIUncheckedCallee() const
Definition TypeBase.h:5820
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5748
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition TypeBase.h:5714
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5802
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition TypeBase.h:5763
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5832
CallingConv getCC() const
Definition TypeBase.h:4764
unsigned getRegParm() const
Definition TypeBase.h:4757
bool getNoCallerSavedRegs() const
Definition TypeBase.h:4753
ExtInfo getExtInfo() const
Definition TypeBase.h:4950
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition TypeBase.h:4903
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition TypeBase.h:4899
QualType getReturnType() const
Definition TypeBase.h:4934
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:1716
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:8468
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:8480
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition TypeBase.h:8449
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:3671
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:5093
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:8410
The base class of the type hierarchy.
Definition TypeBase.h:1879
bool isArrayType() const
Definition TypeBase.h:8764
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition Type.cpp:641
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9331
bool isObjCQualifiedIdType() const
Definition TypeBase.h:8865
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:881
bool isObjCIdType() const
Definition TypeBase.h:8877
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition Type.cpp:3450
bool isFunctionType() const
Definition TypeBase.h:8661
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8871
bool isObjCClassType() const
Definition TypeBase.h:8883
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:9264
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:5996
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
ArrayRef< TemplateArgumentLoc > arguments() const
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition Type.cpp:3560
Describes how types, statements, expressions, and declarations should be printed.
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 UseVoidForZeroParams
Whether we should use '(void)' rather than '()' for a function prototype with zero parameters.
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 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 ResolveDecltype
Use whitespace and punctuation like MSVC does.
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