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