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