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