clang 22.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 AppendScope(DeclContext *DC, raw_ostream &OS,
135 DeclarationName NameInScope);
136 void printTagType(const TagType *T, raw_ostream &OS);
137 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
138#define ABSTRACT_TYPE(CLASS, PARENT)
139#define TYPE(CLASS, PARENT) \
140 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
141 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
142#include "clang/AST/TypeNodes.inc"
143
144private:
145 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
146 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
147};
148
149} // namespace
150
151static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,
152 bool HasRestrictKeyword) {
153 bool appendSpace = false;
154 if (TypeQuals & Qualifiers::Const) {
155 OS << "const";
156 appendSpace = true;
157 }
158 if (TypeQuals & Qualifiers::Volatile) {
159 if (appendSpace) OS << ' ';
160 OS << "volatile";
161 appendSpace = true;
162 }
163 if (TypeQuals & Qualifiers::Restrict) {
164 if (appendSpace) OS << ' ';
165 if (HasRestrictKeyword) {
166 OS << "restrict";
167 } else {
168 OS << "__restrict";
169 }
170 }
171}
172
173void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
174 if (!HasEmptyPlaceHolder)
175 OS << ' ';
176}
177
179 const PrintingPolicy &Policy) {
180 if (Policy.PrintAsCanonical)
181 QT = QT.getCanonicalType();
182 return QT.split();
183}
184
185void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
186 SplitQualType split = splitAccordingToPolicy(t, Policy);
187 print(split.Ty, split.Quals, OS, PlaceHolder);
188}
189
190void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
191 StringRef PlaceHolder) {
192 if (!T) {
193 OS << "NULL TYPE";
194 return;
195 }
196
197 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
198
199 printBefore(T, Quals, OS);
200 OS << PlaceHolder;
201 printAfter(T, Quals, OS);
202}
203
204bool TypePrinter::canPrefixQualifiers(const Type *T,
205 bool &NeedARCStrongQualifier) {
206 // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
207 // so that we get "const int" instead of "int const", but we can't do this if
208 // the type is complex. For example if the type is "int*", we *must* print
209 // "int * const", printing "const int *" is different. Only do this when the
210 // type expands to a simple string.
211 bool CanPrefixQualifiers = false;
212 NeedARCStrongQualifier = false;
213 const Type *UnderlyingType = T;
214 if (const auto *AT = dyn_cast<AutoType>(T))
215 UnderlyingType = AT->desugar().getTypePtr();
216 if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))
217 UnderlyingType = Subst->getReplacementType().getTypePtr();
218 Type::TypeClass TC = UnderlyingType->getTypeClass();
219
220 switch (TC) {
221 case Type::Auto:
222 case Type::Builtin:
223 case Type::Complex:
224 case Type::UnresolvedUsing:
225 case Type::Using:
226 case Type::Typedef:
227 case Type::TypeOfExpr:
228 case Type::TypeOf:
229 case Type::Decltype:
230 case Type::UnaryTransform:
231 case Type::Record:
232 case Type::Enum:
233 case Type::TemplateTypeParm:
234 case Type::SubstTemplateTypeParmPack:
235 case Type::SubstBuiltinTemplatePack:
236 case Type::DeducedTemplateSpecialization:
237 case Type::TemplateSpecialization:
238 case Type::InjectedClassName:
239 case Type::DependentName:
240 case Type::ObjCObject:
241 case Type::ObjCTypeParam:
242 case Type::ObjCInterface:
243 case Type::Atomic:
244 case Type::Pipe:
245 case Type::BitInt:
246 case Type::DependentBitInt:
247 case Type::BTFTagAttributed:
248 case Type::HLSLAttributedResource:
249 case Type::HLSLInlineSpirv:
250 case Type::PredefinedSugar:
251 CanPrefixQualifiers = true;
252 break;
253
254 case Type::ObjCObjectPointer:
255 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
257 break;
258
259 case Type::VariableArray:
260 case Type::DependentSizedArray:
261 NeedARCStrongQualifier = true;
262 [[fallthrough]];
263
264 case Type::ConstantArray:
265 case Type::IncompleteArray:
266 return canPrefixQualifiers(
267 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
268 NeedARCStrongQualifier);
269
270 case Type::Adjusted:
271 case Type::Decayed:
272 case Type::ArrayParameter:
273 case Type::Pointer:
274 case Type::BlockPointer:
275 case Type::LValueReference:
276 case Type::RValueReference:
277 case Type::MemberPointer:
278 case Type::DependentAddressSpace:
279 case Type::DependentVector:
280 case Type::DependentSizedExtVector:
281 case Type::Vector:
282 case Type::ExtVector:
283 case Type::ConstantMatrix:
284 case Type::DependentSizedMatrix:
285 case Type::FunctionProto:
286 case Type::FunctionNoProto:
287 case Type::Paren:
288 case Type::PackExpansion:
289 case Type::SubstTemplateTypeParm:
290 case Type::MacroQualified:
291 case Type::CountAttributed:
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,
643 raw_ostream &OS) {
644 if (Policy.UseHLSLTypes)
645 OS << "vector<";
646 printBefore(T->getElementType(), OS);
647}
648
649void TypePrinter::printDependentSizedExtVectorAfter(
650 const DependentSizedExtVectorType *T,
651 raw_ostream &OS) {
652 if (Policy.UseHLSLTypes) {
653 OS << ", ";
654 if (T->getSizeExpr())
655 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
656 OS << ">";
657 } else {
658 OS << " __attribute__((ext_vector_type(";
659 if (T->getSizeExpr())
660 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
661 OS << ")))";
662 }
663 printAfter(T->getElementType(), OS);
664}
665
666void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
667 switch (T->getVectorKind()) {
668 case VectorKind::AltiVecPixel:
669 OS << "__vector __pixel ";
670 break;
671 case VectorKind::AltiVecBool:
672 OS << "__vector __bool ";
673 printBefore(T->getElementType(), OS);
674 break;
675 case VectorKind::AltiVecVector:
676 OS << "__vector ";
677 printBefore(T->getElementType(), OS);
678 break;
679 case VectorKind::Neon:
680 OS << "__attribute__((neon_vector_type("
681 << T->getNumElements() << "))) ";
682 printBefore(T->getElementType(), OS);
683 break;
684 case VectorKind::NeonPoly:
685 OS << "__attribute__((neon_polyvector_type(" <<
686 T->getNumElements() << "))) ";
687 printBefore(T->getElementType(), OS);
688 break;
689 case VectorKind::Generic: {
690 // FIXME: We prefer to print the size directly here, but have no way
691 // to get the size of the type.
692 OS << "__attribute__((__vector_size__("
693 << T->getNumElements()
694 << " * sizeof(";
695 print(T->getElementType(), OS, StringRef());
696 OS << ")))) ";
697 printBefore(T->getElementType(), OS);
698 break;
699 }
700 case VectorKind::SveFixedLengthData:
701 case VectorKind::SveFixedLengthPredicate:
702 // FIXME: We prefer to print the size directly here, but have no way
703 // to get the size of the type.
704 OS << "__attribute__((__arm_sve_vector_bits__(";
705
706 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
707 // Predicates take a bit per byte of the vector size, multiply by 8 to
708 // get the number of bits passed to the attribute.
709 OS << T->getNumElements() * 8;
710 else
711 OS << T->getNumElements();
712
713 OS << " * sizeof(";
714 print(T->getElementType(), OS, StringRef());
715 // Multiply by 8 for the number of bits.
716 OS << ") * 8))) ";
717 printBefore(T->getElementType(), OS);
718 break;
719 case VectorKind::RVVFixedLengthData:
720 case VectorKind::RVVFixedLengthMask:
721 case VectorKind::RVVFixedLengthMask_1:
722 case VectorKind::RVVFixedLengthMask_2:
723 case VectorKind::RVVFixedLengthMask_4:
724 // FIXME: We prefer to print the size directly here, but have no way
725 // to get the size of the type.
726 OS << "__attribute__((__riscv_rvv_vector_bits__(";
727
728 OS << T->getNumElements();
729
730 OS << " * sizeof(";
731 print(T->getElementType(), OS, StringRef());
732 // Multiply by 8 for the number of bits.
733 OS << ") * 8))) ";
734 printBefore(T->getElementType(), OS);
735 break;
736 }
737}
738
739void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
740 printAfter(T->getElementType(), OS);
741}
742
743void TypePrinter::printDependentVectorBefore(
744 const DependentVectorType *T, raw_ostream &OS) {
745 switch (T->getVectorKind()) {
746 case VectorKind::AltiVecPixel:
747 OS << "__vector __pixel ";
748 break;
749 case VectorKind::AltiVecBool:
750 OS << "__vector __bool ";
751 printBefore(T->getElementType(), OS);
752 break;
753 case VectorKind::AltiVecVector:
754 OS << "__vector ";
755 printBefore(T->getElementType(), OS);
756 break;
757 case VectorKind::Neon:
758 OS << "__attribute__((neon_vector_type(";
759 if (T->getSizeExpr())
760 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
761 OS << "))) ";
762 printBefore(T->getElementType(), OS);
763 break;
764 case VectorKind::NeonPoly:
765 OS << "__attribute__((neon_polyvector_type(";
766 if (T->getSizeExpr())
767 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
768 OS << "))) ";
769 printBefore(T->getElementType(), OS);
770 break;
771 case VectorKind::Generic: {
772 // FIXME: We prefer to print the size directly here, but have no way
773 // to get the size of the type.
774 OS << "__attribute__((__vector_size__(";
775 if (T->getSizeExpr())
776 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
777 OS << " * sizeof(";
778 print(T->getElementType(), OS, StringRef());
779 OS << ")))) ";
780 printBefore(T->getElementType(), OS);
781 break;
782 }
783 case VectorKind::SveFixedLengthData:
784 case VectorKind::SveFixedLengthPredicate:
785 // FIXME: We prefer to print the size directly here, but have no way
786 // to get the size of the type.
787 OS << "__attribute__((__arm_sve_vector_bits__(";
788 if (T->getSizeExpr()) {
789 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
790 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
791 // Predicates take a bit per byte of the vector size, multiply by 8 to
792 // get the number of bits passed to the attribute.
793 OS << " * 8";
794 OS << " * sizeof(";
795 print(T->getElementType(), OS, StringRef());
796 // Multiply by 8 for the number of bits.
797 OS << ") * 8";
798 }
799 OS << "))) ";
800 printBefore(T->getElementType(), OS);
801 break;
802 case VectorKind::RVVFixedLengthData:
803 case VectorKind::RVVFixedLengthMask:
804 case VectorKind::RVVFixedLengthMask_1:
805 case VectorKind::RVVFixedLengthMask_2:
806 case VectorKind::RVVFixedLengthMask_4:
807 // FIXME: We prefer to print the size directly here, but have no way
808 // to get the size of the type.
809 OS << "__attribute__((__riscv_rvv_vector_bits__(";
810 if (T->getSizeExpr()) {
811 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
812 OS << " * sizeof(";
813 print(T->getElementType(), OS, StringRef());
814 // Multiply by 8 for the number of bits.
815 OS << ") * 8";
816 }
817 OS << "))) ";
818 printBefore(T->getElementType(), OS);
819 break;
820 }
821}
822
823void TypePrinter::printDependentVectorAfter(
824 const DependentVectorType *T, raw_ostream &OS) {
825 printAfter(T->getElementType(), OS);
826}
827
828void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
829 raw_ostream &OS) {
830 if (Policy.UseHLSLTypes)
831 OS << "vector<";
832 printBefore(T->getElementType(), OS);
833}
834
835void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
836 printAfter(T->getElementType(), OS);
837
838 if (Policy.UseHLSLTypes) {
839 OS << ", ";
840 OS << T->getNumElements();
841 OS << ">";
842 } else {
843 OS << " __attribute__((ext_vector_type(";
844 OS << T->getNumElements();
845 OS << ")))";
846 }
847}
848
849void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
850 raw_ostream &OS) {
851 printBefore(T->getElementType(), OS);
852 OS << " __attribute__((matrix_type(";
853 OS << T->getNumRows() << ", " << T->getNumColumns();
854 OS << ")))";
855}
856
857void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
858 raw_ostream &OS) {
859 printAfter(T->getElementType(), OS);
860}
861
862void TypePrinter::printDependentSizedMatrixBefore(
863 const DependentSizedMatrixType *T, raw_ostream &OS) {
864 printBefore(T->getElementType(), OS);
865 OS << " __attribute__((matrix_type(";
866 if (T->getRowExpr()) {
867 T->getRowExpr()->printPretty(OS, nullptr, Policy);
868 }
869 OS << ", ";
870 if (T->getColumnExpr()) {
871 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
872 }
873 OS << ")))";
874}
875
876void TypePrinter::printDependentSizedMatrixAfter(
877 const DependentSizedMatrixType *T, raw_ostream &OS) {
878 printAfter(T->getElementType(), OS);
879}
880
881void
883 const PrintingPolicy &Policy)
884 const {
886 OS << " throw(";
888 OS << "...";
889 else
890 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
891 if (I)
892 OS << ", ";
893
894 OS << getExceptionType(I).stream(Policy);
895 }
896 OS << ')';
897 } else if (EST_NoThrow == getExceptionSpecType()) {
898 OS << " __attribute__((nothrow))";
900 OS << " noexcept";
901 // FIXME:Is it useful to print out the expression for a non-dependent
902 // noexcept specification?
904 OS << '(';
905 if (getNoexceptExpr())
906 getNoexceptExpr()->printPretty(OS, nullptr, Policy);
907 OS << ')';
908 }
909 }
910}
911
912void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
913 raw_ostream &OS) {
914 if (T->hasTrailingReturn()) {
915 OS << "auto ";
916 if (!HasEmptyPlaceHolder)
917 OS << '(';
918 } else {
919 // If needed for precedence reasons, wrap the inner part in grouping parens.
920 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
921 printBefore(T->getReturnType(), OS);
922 if (!PrevPHIsEmpty.get())
923 OS << '(';
924 }
925}
926
928 switch (ABI) {
930 llvm_unreachable("asking for spelling of ordinary parameter ABI");
932 return "swift_context";
934 return "swift_async_context";
936 return "swift_error_result";
938 return "swift_indirect_result";
940 return "out";
942 return "inout";
943 }
944 llvm_unreachable("bad parameter ABI kind");
945}
946
947void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
948 raw_ostream &OS) {
949 // If needed for precedence reasons, wrap the inner part in grouping parens.
950 if (!HasEmptyPlaceHolder)
951 OS << ')';
952 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
953
954 OS << '(';
955 {
956 ParamPolicyRAII ParamPolicy(Policy);
957 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
958 if (i) OS << ", ";
959
960 auto EPI = T->getExtParameterInfo(i);
961 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
962 if (EPI.isNoEscape())
963 OS << "__attribute__((noescape)) ";
964 auto ABI = EPI.getABI();
965 if (ABI == ParameterABI::HLSLInOut || ABI == ParameterABI::HLSLOut) {
966 OS << getParameterABISpelling(ABI) << " ";
967 if (Policy.UseHLSLTypes) {
968 // This is a bit of a hack because we _do_ use reference types in the
969 // AST for representing inout and out parameters so that code
970 // generation is sane, but when re-printing these for HLSL we need to
971 // skip the reference.
972 print(T->getParamType(i).getNonReferenceType(), OS, StringRef());
973 continue;
974 }
975 } else if (ABI != ParameterABI::Ordinary)
976 OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
977
978 print(T->getParamType(i), OS, StringRef());
979 }
980 }
981
982 if (T->isVariadic()) {
983 if (T->getNumParams())
984 OS << ", ";
985 OS << "...";
986 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
987 // Do not emit int() if we have a proto, emit 'int(void)'.
988 OS << "void";
989 }
990
991 OS << ')';
992
993 FunctionType::ExtInfo Info = T->getExtInfo();
994 unsigned SMEBits = T->getAArch64SMEAttributes();
995
997 OS << " __arm_streaming_compatible";
999 OS << " __arm_streaming";
1001 OS << "__arm_agnostic(\"sme_za_state\")";
1003 OS << " __arm_preserves(\"za\")";
1005 OS << " __arm_in(\"za\")";
1007 OS << " __arm_out(\"za\")";
1009 OS << " __arm_inout(\"za\")";
1011 OS << " __arm_preserves(\"zt0\")";
1013 OS << " __arm_in(\"zt0\")";
1015 OS << " __arm_out(\"zt0\")";
1017 OS << " __arm_inout(\"zt0\")";
1018
1019 printFunctionAfter(Info, OS);
1020
1021 if (!T->getMethodQuals().empty())
1022 OS << " " << T->getMethodQuals().getAsString();
1023
1024 switch (T->getRefQualifier()) {
1025 case RQ_None:
1026 break;
1027
1028 case RQ_LValue:
1029 OS << " &";
1030 break;
1031
1032 case RQ_RValue:
1033 OS << " &&";
1034 break;
1035 }
1036 T->printExceptionSpecification(OS, Policy);
1037
1038 const FunctionEffectsRef FX = T->getFunctionEffects();
1039 for (const auto &CFE : FX) {
1040 OS << " __attribute__((" << CFE.Effect.name();
1041 if (const Expr *E = CFE.Cond.getCondition()) {
1042 OS << '(';
1043 E->printPretty(OS, nullptr, Policy);
1044 OS << ')';
1045 }
1046 OS << "))";
1047 }
1048
1049 if (T->hasCFIUncheckedCallee())
1050 OS << " __attribute__((cfi_unchecked_callee))";
1051
1052 if (T->hasTrailingReturn()) {
1053 OS << " -> ";
1054 print(T->getReturnType(), OS, StringRef());
1055 } else
1056 printAfter(T->getReturnType(), OS);
1057}
1058
1059void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1060 raw_ostream &OS) {
1061 if (!InsideCCAttribute) {
1062 switch (Info.getCC()) {
1063 case CC_C:
1064 // The C calling convention is the default on the vast majority of platforms
1065 // we support. If the user wrote it explicitly, it will usually be printed
1066 // while traversing the AttributedType. If the type has been desugared, let
1067 // the canonical spelling be the implicit calling convention.
1068 // FIXME: It would be better to be explicit in certain contexts, such as a
1069 // cdecl function typedef used to declare a member function with the
1070 // Microsoft C++ ABI.
1071 break;
1072 case CC_X86StdCall:
1073 OS << " __attribute__((stdcall))";
1074 break;
1075 case CC_X86FastCall:
1076 OS << " __attribute__((fastcall))";
1077 break;
1078 case CC_X86ThisCall:
1079 OS << " __attribute__((thiscall))";
1080 break;
1081 case CC_X86VectorCall:
1082 OS << " __attribute__((vectorcall))";
1083 break;
1084 case CC_X86Pascal:
1085 OS << " __attribute__((pascal))";
1086 break;
1087 case CC_AAPCS:
1088 OS << " __attribute__((pcs(\"aapcs\")))";
1089 break;
1090 case CC_AAPCS_VFP:
1091 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1092 break;
1094 OS << " __attribute__((aarch64_vector_pcs))";
1095 break;
1096 case CC_AArch64SVEPCS:
1097 OS << " __attribute__((aarch64_sve_pcs))";
1098 break;
1099 case CC_DeviceKernel:
1100 OS << " __attribute__((device_kernel))";
1101 break;
1102 case CC_IntelOclBicc:
1103 OS << " __attribute__((intel_ocl_bicc))";
1104 break;
1105 case CC_Win64:
1106 OS << " __attribute__((ms_abi))";
1107 break;
1108 case CC_X86_64SysV:
1109 OS << " __attribute__((sysv_abi))";
1110 break;
1111 case CC_X86RegCall:
1112 OS << " __attribute__((regcall))";
1113 break;
1114 case CC_SpirFunction:
1115 // Do nothing. These CCs are not available as attributes.
1116 break;
1117 case CC_Swift:
1118 OS << " __attribute__((swiftcall))";
1119 break;
1120 case CC_SwiftAsync:
1121 OS << "__attribute__((swiftasynccall))";
1122 break;
1123 case CC_PreserveMost:
1124 OS << " __attribute__((preserve_most))";
1125 break;
1126 case CC_PreserveAll:
1127 OS << " __attribute__((preserve_all))";
1128 break;
1129 case CC_M68kRTD:
1130 OS << " __attribute__((m68k_rtd))";
1131 break;
1132 case CC_PreserveNone:
1133 OS << " __attribute__((preserve_none))";
1134 break;
1135 case CC_RISCVVectorCall:
1136 OS << "__attribute__((riscv_vector_cc))";
1137 break;
1138#define CC_VLS_CASE(ABI_VLEN) \
1139 case CC_RISCVVLSCall_##ABI_VLEN: \
1140 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \
1141 break;
1142 CC_VLS_CASE(32)
1143 CC_VLS_CASE(64)
1144 CC_VLS_CASE(128)
1145 CC_VLS_CASE(256)
1146 CC_VLS_CASE(512)
1147 CC_VLS_CASE(1024)
1148 CC_VLS_CASE(2048)
1149 CC_VLS_CASE(4096)
1150 CC_VLS_CASE(8192)
1151 CC_VLS_CASE(16384)
1152 CC_VLS_CASE(32768)
1153 CC_VLS_CASE(65536)
1154#undef CC_VLS_CASE
1155 }
1156 }
1157
1158 if (Info.getNoReturn())
1159 OS << " __attribute__((noreturn))";
1160 if (Info.getCmseNSCall())
1161 OS << " __attribute__((cmse_nonsecure_call))";
1162 if (Info.getProducesResult())
1163 OS << " __attribute__((ns_returns_retained))";
1164 if (Info.getRegParm())
1165 OS << " __attribute__((regparm ("
1166 << Info.getRegParm() << ")))";
1167 if (Info.getNoCallerSavedRegs())
1168 OS << " __attribute__((no_caller_saved_registers))";
1169 if (Info.getNoCfCheck())
1170 OS << " __attribute__((nocf_check))";
1171}
1172
1173void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1174 raw_ostream &OS) {
1175 // If needed for precedence reasons, wrap the inner part in grouping parens.
1176 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1177 printBefore(T->getReturnType(), OS);
1178 if (!PrevPHIsEmpty.get())
1179 OS << '(';
1180}
1181
1182void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1183 raw_ostream &OS) {
1184 // If needed for precedence reasons, wrap the inner part in grouping parens.
1185 if (!HasEmptyPlaceHolder)
1186 OS << ')';
1187 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1188
1189 OS << "()";
1190 printFunctionAfter(T->getExtInfo(), OS);
1191 printAfter(T->getReturnType(), OS);
1192}
1193
1194void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1195
1196 // Compute the full nested-name-specifier for this type.
1197 // In C, this will always be empty except when the type
1198 // being printed is anonymous within other Record.
1199 if (!Policy.SuppressScope)
1200 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1201
1202 IdentifierInfo *II = D->getIdentifier();
1203 OS << II->getName();
1204 spaceBeforePlaceHolder(OS);
1205}
1206
1207void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1208 raw_ostream &OS) {
1209 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1210 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1211 OS << ' ';
1212 auto *D = T->getDecl();
1213 if (Policy.FullyQualifiedName || T->isCanonicalUnqualified()) {
1214 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1215 } else {
1216 T->getQualifier().print(OS, Policy);
1217 }
1218 OS << D->getIdentifier()->getName();
1219 spaceBeforePlaceHolder(OS);
1220}
1221
1222void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1223 raw_ostream &OS) {}
1224
1225void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1226 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1227 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1228 OS << ' ';
1229 auto *D = T->getDecl();
1230 if (Policy.FullyQualifiedName) {
1231 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1232 } else {
1233 T->getQualifier().print(OS, Policy);
1234 }
1235 OS << D->getIdentifier()->getName();
1236 spaceBeforePlaceHolder(OS);
1237}
1238
1239void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1240
1241void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1242 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1243 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1244 OS << ' ';
1245 auto *D = T->getDecl();
1246 if (Policy.FullyQualifiedName) {
1247 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1248 } else {
1249 T->getQualifier().print(OS, Policy);
1250 }
1251 OS << D->getIdentifier()->getName();
1252 spaceBeforePlaceHolder(OS);
1253}
1254
1255void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1256 raw_ostream &OS) {
1257 StringRef MacroName = T->getMacroIdentifier()->getName();
1258 OS << MacroName << " ";
1259
1260 // Since this type is meant to print the macro instead of the whole attribute,
1261 // we trim any attributes and go directly to the original modified type.
1262 printBefore(T->getModifiedType(), OS);
1263}
1264
1265void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1266 raw_ostream &OS) {
1267 printAfter(T->getModifiedType(), OS);
1268}
1269
1270void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1271
1272void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1273 raw_ostream &OS) {
1274 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1275 : "typeof ");
1276 if (T->getUnderlyingExpr())
1277 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1278 spaceBeforePlaceHolder(OS);
1279}
1280
1281void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1282 raw_ostream &OS) {}
1283
1284void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1285 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1286 : "typeof(");
1287 print(T->getUnmodifiedType(), OS, StringRef());
1288 OS << ')';
1289 spaceBeforePlaceHolder(OS);
1290}
1291
1292void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1293
1294void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1295 OS << "decltype(";
1296 if (const Expr *E = T->getUnderlyingExpr()) {
1297 PrintingPolicy ExprPolicy = Policy;
1299 E->printPretty(OS, nullptr, ExprPolicy);
1300 }
1301 OS << ')';
1302 spaceBeforePlaceHolder(OS);
1303}
1304
1305void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1306 raw_ostream &OS) {
1307 if (T->hasSelectedType()) {
1308 OS << T->getSelectedType();
1309 } else {
1310 OS << T->getPattern() << "...[";
1311 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1312 OS << "]";
1313 }
1314 spaceBeforePlaceHolder(OS);
1315}
1316
1317void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1318 raw_ostream &OS) {}
1319
1320void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1321
1322void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1323 raw_ostream &OS) {
1324 IncludeStrongLifetimeRAII Strong(Policy);
1325
1326 static llvm::DenseMap<int, const char *> Transformation = {{
1327#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1328 {UnaryTransformType::Enum, "__" #Trait},
1329#include "clang/Basic/TransformTypeTraits.def"
1330 }};
1331 OS << Transformation[T->getUTTKind()] << '(';
1332 print(T->getBaseType(), OS, StringRef());
1333 OS << ')';
1334 spaceBeforePlaceHolder(OS);
1335}
1336
1337void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1338 raw_ostream &OS) {}
1339
1340void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1341 // If the type has been deduced, do not print 'auto'.
1342 if (!T->getDeducedType().isNull()) {
1343 printBefore(T->getDeducedType(), OS);
1344 } else {
1345 if (T->isConstrained()) {
1346 // FIXME: Track a TypeConstraint as type sugar, so that we can print the
1347 // type as it was written.
1348 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1349 auto Args = T->getTypeConstraintArguments();
1350 if (!Args.empty())
1351 printTemplateArgumentList(
1352 OS, Args, Policy,
1353 T->getTypeConstraintConcept()->getTemplateParameters());
1354 OS << ' ';
1355 }
1356 switch (T->getKeyword()) {
1357 case AutoTypeKeyword::Auto: OS << "auto"; break;
1358 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1359 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1360 }
1361 spaceBeforePlaceHolder(OS);
1362 }
1363}
1364
1365void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1366 // If the type has been deduced, do not print 'auto'.
1367 if (!T->getDeducedType().isNull())
1368 printAfter(T->getDeducedType(), OS);
1369}
1370
1371void TypePrinter::printDeducedTemplateSpecializationBefore(
1372 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1373 if (ElaboratedTypeKeyword Keyword = T->getKeyword();
1374 T->getKeyword() != ElaboratedTypeKeyword::None)
1376
1377 TemplateName Name = T->getTemplateName();
1378
1379 // If the type has been deduced, print the template arguments, as if this was
1380 // printing the deduced type, but including elaboration and template name
1381 // qualification.
1382 // FIXME: There should probably be a policy which controls this.
1383 // We would probably want to do this on diagnostics, but not on -ast-print.
1384 ArrayRef<TemplateArgument> Args;
1385 TemplateDecl *DeducedTD = nullptr;
1386 if (!T->getDeducedType().isNull()) {
1387 if (const auto *TST =
1388 dyn_cast<TemplateSpecializationType>(T->getDeducedType())) {
1389 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1390 /*IgnoreDeduced=*/true);
1391 Args = TST->template_arguments();
1392 } else {
1393 // Should only get here for canonical types.
1395 cast<RecordType>(T->getDeducedType())->getOriginalDecl());
1396 DeducedTD = CD->getSpecializedTemplate();
1397 Args = CD->getTemplateArgs().asArray();
1398 }
1399
1400 // FIXME: Workaround for alias template CTAD not producing guides which
1401 // include the alias template specialization type.
1402 // Purposefully disregard qualification when building this TemplateName;
1403 // any qualification we might have, might not make sense in the
1404 // context this was deduced.
1405 if (!declaresSameEntity(DeducedTD, Name.getAsTemplateDecl(
1406 /*IgnoreDeduced=*/true)))
1407 Name = TemplateName(DeducedTD);
1408 }
1409
1410 {
1411 IncludeStrongLifetimeRAII Strong(Policy);
1412 Name.print(OS, Policy);
1413 }
1414 if (DeducedTD) {
1415 printTemplateArgumentList(OS, Args, Policy,
1416 DeducedTD->getTemplateParameters());
1417 }
1418
1419 spaceBeforePlaceHolder(OS);
1420}
1421
1422void TypePrinter::printDeducedTemplateSpecializationAfter(
1423 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1424 // If the type has been deduced, print the deduced type.
1425 if (!T->getDeducedType().isNull())
1426 printAfter(T->getDeducedType(), OS);
1427}
1428
1429void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1430 IncludeStrongLifetimeRAII Strong(Policy);
1431
1432 OS << "_Atomic(";
1433 print(T->getValueType(), OS, StringRef());
1434 OS << ')';
1435 spaceBeforePlaceHolder(OS);
1436}
1437
1438void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1439
1440void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1441 IncludeStrongLifetimeRAII Strong(Policy);
1442
1443 if (T->isReadOnly())
1444 OS << "read_only ";
1445 else
1446 OS << "write_only ";
1447 OS << "pipe ";
1448 print(T->getElementType(), OS, StringRef());
1449 spaceBeforePlaceHolder(OS);
1450}
1451
1452void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1453
1454void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1455 if (T->isUnsigned())
1456 OS << "unsigned ";
1457 OS << "_BitInt(" << T->getNumBits() << ")";
1458 spaceBeforePlaceHolder(OS);
1459}
1460
1461void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1462
1463void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1464 raw_ostream &OS) {
1465 if (T->isUnsigned())
1466 OS << "unsigned ";
1467 OS << "_BitInt(";
1468 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1469 OS << ")";
1470 spaceBeforePlaceHolder(OS);
1471}
1472
1473void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1474 raw_ostream &OS) {}
1475
1476void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,
1477 raw_ostream &OS) {
1478 OS << T->getIdentifier()->getName();
1479 spaceBeforePlaceHolder(OS);
1480}
1481
1482void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,
1483 raw_ostream &OS) {}
1484
1485/// Appends the given scope to the end of a string.
1486void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1487 DeclarationName NameInScope) {
1488 if (DC->isTranslationUnit())
1489 return;
1490
1491 // FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1492 // which can also print names for function and method scopes.
1493 if (DC->isFunctionOrMethod())
1494 return;
1495
1496 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1497 return;
1498
1499 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1500 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1501 return AppendScope(DC->getParent(), OS, NameInScope);
1502
1503 // Only suppress an inline namespace if the name has the same lookup
1504 // results in the enclosing namespace.
1505 if (Policy.SuppressInlineNamespace !=
1506 PrintingPolicy::SuppressInlineNamespaceMode::None &&
1507 NS->isInline() && NameInScope &&
1508 NS->isRedundantInlineQualifierFor(NameInScope))
1509 return AppendScope(DC->getParent(), OS, NameInScope);
1510
1511 AppendScope(DC->getParent(), OS, NS->getDeclName());
1512 if (NS->getIdentifier())
1513 OS << NS->getName() << "::";
1514 else
1515 OS << "(anonymous namespace)::";
1516 } else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1517 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1518 IncludeStrongLifetimeRAII Strong(Policy);
1519 OS << Spec->getIdentifier()->getName();
1520 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
1521 printTemplateArgumentList(
1522 OS, TemplateArgs.asArray(), Policy,
1523 Spec->getSpecializedTemplate()->getTemplateParameters());
1524 OS << "::";
1525 } else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1526 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1527 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
1528 OS << Typedef->getIdentifier()->getName() << "::";
1529 else if (Tag->getIdentifier())
1530 OS << Tag->getIdentifier()->getName() << "::";
1531 else
1532 return;
1533 } else {
1534 AppendScope(DC->getParent(), OS, NameInScope);
1535 }
1536}
1537
1538void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
1539 TagDecl *D = T->getOriginalDecl();
1540
1541 if (Policy.IncludeTagDefinition && T->isTagOwned()) {
1542 D->print(OS, Policy, Indentation);
1543 spaceBeforePlaceHolder(OS);
1544 return;
1545 }
1546
1547 bool HasKindDecoration = false;
1548
1549 if (T->isCanonicalUnqualified()) {
1550 if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1551 HasKindDecoration = true;
1552 OS << D->getKindName();
1553 OS << ' ';
1554 }
1555 } else {
1556 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1557 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1558 OS << ' ';
1559 }
1560
1561 if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
1562 T->getQualifier().print(OS, Policy);
1563 } else if (!Policy.SuppressScope) {
1564 // Compute the full nested-name-specifier for this type.
1565 // In C, this will always be empty except when the type
1566 // being printed is anonymous within other Record.
1567 AppendScope(D->getDeclContext(), OS, D->getDeclName());
1568 }
1569
1570 if (const IdentifierInfo *II = D->getIdentifier())
1571 OS << II->getName();
1572 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1573 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1574 OS << Typedef->getIdentifier()->getName();
1575 } else {
1576 // Make an unambiguous representation for anonymous types, e.g.
1577 // (anonymous enum at /usr/include/string.h:120:9)
1578 OS << (Policy.MSVCFormatting ? '`' : '(');
1579
1580 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1581 OS << "lambda";
1582 HasKindDecoration = true;
1583 } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
1584 OS << "anonymous";
1585 } else {
1586 OS << "unnamed";
1587 }
1588
1589 if (Policy.AnonymousTagLocations) {
1590 // Suppress the redundant tag keyword if we just printed one.
1591 // We don't have to worry about ElaboratedTypes here because you can't
1592 // refer to an anonymous type with one.
1593 if (!HasKindDecoration)
1594 OS << " " << D->getKindName();
1595
1596 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
1597 D->getLocation());
1598 if (PLoc.isValid()) {
1599 OS << " at ";
1600 StringRef File = PLoc.getFilename();
1601 llvm::SmallString<1024> WrittenFile(File);
1602 if (auto *Callbacks = Policy.Callbacks)
1603 WrittenFile = Callbacks->remapPath(File);
1604 // Fix inconsistent path separator created by
1605 // clang::DirectoryLookup::LookupFile when the file path is relative
1606 // path.
1607 llvm::sys::path::Style Style =
1608 llvm::sys::path::is_absolute(WrittenFile)
1609 ? llvm::sys::path::Style::native
1610 : (Policy.MSVCFormatting
1611 ? llvm::sys::path::Style::windows_backslash
1612 : llvm::sys::path::Style::posix);
1613 llvm::sys::path::native(WrittenFile, Style);
1614 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1615 }
1616 }
1617
1618 OS << (Policy.MSVCFormatting ? '\'' : ')');
1619 }
1620
1621 // If this is a class template specialization, print the template
1622 // arguments.
1623 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1624 const TemplateParameterList *TParams =
1625 S->getSpecializedTemplate()->getTemplateParameters();
1626 const ASTTemplateArgumentListInfo *TArgAsWritten =
1627 S->getTemplateArgsAsWritten();
1628 IncludeStrongLifetimeRAII Strong(Policy);
1629 if (TArgAsWritten && !Policy.PrintAsCanonical)
1630 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1631 TParams);
1632 else
1633 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1634 TParams);
1635 }
1636
1637 spaceBeforePlaceHolder(OS);
1638}
1639
1640void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1641 // Print the preferred name if we have one for this type.
1642 if (Policy.UsePreferredNames) {
1643 for (const auto *PNA : T->getOriginalDecl()
1644 ->getMostRecentDecl()
1645 ->specific_attrs<PreferredNameAttr>()) {
1646 if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
1647 T->getOriginalDecl()))
1648 continue;
1649 // Find the outermost typedef or alias template.
1650 QualType T = PNA->getTypedefType();
1651 while (true) {
1652 if (auto *TT = dyn_cast<TypedefType>(T))
1653 return printTypeSpec(TT->getDecl(), OS);
1654 if (auto *TST = dyn_cast<TemplateSpecializationType>(T))
1655 return printTemplateId(TST, OS, /*FullyQualify=*/true);
1657 }
1658 }
1659 }
1660
1661 printTagType(T, OS);
1662}
1663
1664void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1665
1666void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1667 printTagType(T, OS);
1668}
1669
1670void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1671
1672void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1673 raw_ostream &OS) {
1674 const ASTContext &Ctx = T->getOriginalDecl()->getASTContext();
1675 IncludeStrongLifetimeRAII Strong(Policy);
1676 T->getTemplateName(Ctx).print(OS, Policy);
1678 auto *Decl = T->getOriginalDecl();
1679 // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
1680 // arguments.
1681 if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {
1682 printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),
1683 Policy,
1684 T->getTemplateDecl()->getTemplateParameters());
1685 } else {
1686 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
1687 assert(TD);
1688 printTemplateArgumentList(
1689 OS, TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx), Policy,
1690 T->getTemplateDecl()->getTemplateParameters());
1691 }
1692 }
1693 spaceBeforePlaceHolder(OS);
1694}
1695
1696void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1697 raw_ostream &OS) {}
1698
1699void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1700 raw_ostream &OS) {
1701 TemplateTypeParmDecl *D = T->getDecl();
1702 if (D && D->isImplicit()) {
1703 if (auto *TC = D->getTypeConstraint()) {
1704 TC->print(OS, Policy);
1705 OS << ' ';
1706 }
1707 OS << "auto";
1708 } else if (IdentifierInfo *Id = T->getIdentifier())
1709 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1710 : Id->getName());
1711 else
1712 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1713
1714 spaceBeforePlaceHolder(OS);
1715}
1716
1717void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1718 raw_ostream &OS) {}
1719
1720void TypePrinter::printSubstTemplateTypeParmBefore(
1721 const SubstTemplateTypeParmType *T,
1722 raw_ostream &OS) {
1723 IncludeStrongLifetimeRAII Strong(Policy);
1724 printBefore(T->getReplacementType(), OS);
1725}
1726
1727void TypePrinter::printSubstTemplateTypeParmAfter(
1728 const SubstTemplateTypeParmType *T,
1729 raw_ostream &OS) {
1730 IncludeStrongLifetimeRAII Strong(Policy);
1731 printAfter(T->getReplacementType(), OS);
1732}
1733
1734void TypePrinter::printSubstBuiltinTemplatePackBefore(
1735 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
1736 IncludeStrongLifetimeRAII Strong(Policy);
1737 OS << "type-pack";
1738}
1739
1740void TypePrinter::printSubstBuiltinTemplatePackAfter(
1741 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
1742
1743void TypePrinter::printSubstTemplateTypeParmPackBefore(
1744 const SubstTemplateTypeParmPackType *T,
1745 raw_ostream &OS) {
1746 IncludeStrongLifetimeRAII Strong(Policy);
1747 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1748 if (D && D->isImplicit()) {
1749 if (auto *TC = D->getTypeConstraint()) {
1750 TC->print(OS, Policy);
1751 OS << ' ';
1752 }
1753 OS << "auto";
1754 } else if (IdentifierInfo *Id = D->getIdentifier())
1755 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1756 : Id->getName());
1757 else
1758 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1759
1760 spaceBeforePlaceHolder(OS);
1761 }
1762}
1763
1764void TypePrinter::printSubstTemplateTypeParmPackAfter(
1765 const SubstTemplateTypeParmPackType *T,
1766 raw_ostream &OS) {
1767 IncludeStrongLifetimeRAII Strong(Policy);
1768}
1769
1770void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1771 raw_ostream &OS, bool FullyQualify) {
1772 IncludeStrongLifetimeRAII Strong(Policy);
1773
1774 if (ElaboratedTypeKeyword K = T->getKeyword();
1775 K != ElaboratedTypeKeyword::None)
1776 OS << TypeWithKeyword::getKeywordName(K) << ' ';
1777
1778 TemplateDecl *TD =
1779 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
1780 // FIXME: Null TD never exercised in test suite.
1781 if (FullyQualify && TD) {
1782 if (!Policy.SuppressScope)
1783 AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
1784
1785 OS << TD->getName();
1786 } else {
1787 T->getTemplateName().print(OS, Policy,
1788 !Policy.SuppressScope
1789 ? TemplateName::Qualified::AsWritten
1790 : TemplateName::Qualified::None);
1791 }
1792
1793 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1794 const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;
1795 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1796 spaceBeforePlaceHolder(OS);
1797}
1798
1799void TypePrinter::printTemplateSpecializationBefore(
1800 const TemplateSpecializationType *T,
1801 raw_ostream &OS) {
1802 printTemplateId(T, OS, Policy.FullyQualifiedName);
1803}
1804
1805void TypePrinter::printTemplateSpecializationAfter(
1806 const TemplateSpecializationType *T,
1807 raw_ostream &OS) {}
1808
1809void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1810 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1811 printBefore(T->getInnerType(), OS);
1812 OS << '(';
1813 } else
1814 printBefore(T->getInnerType(), OS);
1815}
1816
1817void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1818 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
1819 OS << ')';
1820 printAfter(T->getInnerType(), OS);
1821 } else
1822 printAfter(T->getInnerType(), OS);
1823}
1824
1825void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1826 raw_ostream &OS) {
1827 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1828 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1829 OS << " ";
1830 T->getQualifier().print(OS, Policy);
1831 OS << T->getIdentifier()->getName();
1832 spaceBeforePlaceHolder(OS);
1833}
1834
1835void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1836 raw_ostream &OS) {}
1837
1838void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1839 raw_ostream &OS) {
1840 printBefore(T->getPattern(), OS);
1841}
1842
1843void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1844 raw_ostream &OS) {
1845 printAfter(T->getPattern(), OS);
1846 OS << "...";
1847}
1848
1850 raw_ostream &OS,
1851 const PrintingPolicy &Policy) {
1852 OS << ' ';
1853 if (T->isCountInBytes() && T->isOrNull())
1854 OS << "__sized_by_or_null(";
1855 else if (T->isCountInBytes())
1856 OS << "__sized_by(";
1857 else if (T->isOrNull())
1858 OS << "__counted_by_or_null(";
1859 else
1860 OS << "__counted_by(";
1861 if (T->getCountExpr())
1862 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1863 OS << ')';
1864}
1865
1866void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1867 raw_ostream &OS) {
1868 printBefore(T->desugar(), OS);
1869 if (!T->isArrayType())
1870 printCountAttributedImpl(T, OS, Policy);
1871}
1872
1873void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1874 raw_ostream &OS) {
1875 printAfter(T->desugar(), OS);
1876 if (T->isArrayType())
1877 printCountAttributedImpl(T, OS, Policy);
1878}
1879
1880void TypePrinter::printAttributedBefore(const AttributedType *T,
1881 raw_ostream &OS) {
1882 // FIXME: Generate this with TableGen.
1883
1884 // Prefer the macro forms of the GC and ownership qualifiers.
1885 if (T->getAttrKind() == attr::ObjCGC ||
1886 T->getAttrKind() == attr::ObjCOwnership)
1887 return printBefore(T->getEquivalentType(), OS);
1888
1889 if (T->getAttrKind() == attr::ObjCKindOf)
1890 OS << "__kindof ";
1891
1892 if (T->getAttrKind() == attr::PreserveNone) {
1893 OS << "__attribute__((preserve_none)) ";
1894 spaceBeforePlaceHolder(OS);
1895 } else if (T->getAttrKind() == attr::PreserveMost) {
1896 OS << "__attribute__((preserve_most)) ";
1897 spaceBeforePlaceHolder(OS);
1898 } else if (T->getAttrKind() == attr::PreserveAll) {
1899 OS << "__attribute__((preserve_all)) ";
1900 spaceBeforePlaceHolder(OS);
1901 }
1902
1903 if (T->getAttrKind() == attr::AddressSpace)
1904 printBefore(T->getEquivalentType(), OS);
1905 else
1906 printBefore(T->getModifiedType(), OS);
1907
1908 if (T->isMSTypeSpec()) {
1909 switch (T->getAttrKind()) {
1910 default: return;
1911 case attr::Ptr32: OS << " __ptr32"; break;
1912 case attr::Ptr64: OS << " __ptr64"; break;
1913 case attr::SPtr: OS << " __sptr"; break;
1914 case attr::UPtr: OS << " __uptr"; break;
1915 }
1916 spaceBeforePlaceHolder(OS);
1917 }
1918
1919 if (T->isWebAssemblyFuncrefSpec())
1920 OS << "__funcref";
1921
1922 // Print nullability type specifiers.
1923 if (T->getImmediateNullability()) {
1924 if (T->getAttrKind() == attr::TypeNonNull)
1925 OS << " _Nonnull";
1926 else if (T->getAttrKind() == attr::TypeNullable)
1927 OS << " _Nullable";
1928 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1929 OS << " _Null_unspecified";
1930 else if (T->getAttrKind() == attr::TypeNullableResult)
1931 OS << " _Nullable_result";
1932 else
1933 llvm_unreachable("unhandled nullability");
1934 spaceBeforePlaceHolder(OS);
1935 }
1936}
1937
1938void TypePrinter::printAttributedAfter(const AttributedType *T,
1939 raw_ostream &OS) {
1940 // FIXME: Generate this with TableGen.
1941
1942 // Prefer the macro forms of the GC and ownership qualifiers.
1943 if (T->getAttrKind() == attr::ObjCGC ||
1944 T->getAttrKind() == attr::ObjCOwnership)
1945 return printAfter(T->getEquivalentType(), OS);
1946
1947 // If this is a calling convention attribute, don't print the implicit CC from
1948 // the modified type.
1949 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1950
1951 printAfter(T->getModifiedType(), OS);
1952
1953 // Some attributes are printed as qualifiers before the type, so we have
1954 // nothing left to do.
1955 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1956 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1957 return;
1958
1959 // Don't print the inert __unsafe_unretained attribute at all.
1960 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1961 return;
1962
1963 // Don't print ns_returns_retained unless it had an effect.
1964 if (T->getAttrKind() == attr::NSReturnsRetained &&
1965 !T->getEquivalentType()->castAs<FunctionType>()
1966 ->getExtInfo().getProducesResult())
1967 return;
1968
1969 if (T->getAttrKind() == attr::LifetimeBound) {
1970 OS << " [[clang::lifetimebound]]";
1971 return;
1972 }
1973 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1974 OS << " [[clang::lifetime_capture_by(";
1975 if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr()))
1976 llvm::interleaveComma(attr->getArgIdents(), OS,
1977 [&](auto it) { OS << it->getName(); });
1978 OS << ")]]";
1979 return;
1980 }
1981
1982 // The printing of the address_space attribute is handled by the qualifier
1983 // since it is still stored in the qualifier. Return early to prevent printing
1984 // this twice.
1985 if (T->getAttrKind() == attr::AddressSpace)
1986 return;
1987
1988 if (T->getAttrKind() == attr::AnnotateType) {
1989 // FIXME: Print the attribute arguments once we have a way to retrieve these
1990 // here. For the meantime, we just print `[[clang::annotate_type(...)]]`
1991 // without the arguments so that we know at least that we had _some_
1992 // annotation on the type.
1993 OS << " [[clang::annotate_type(...)]]";
1994 return;
1995 }
1996
1997 if (T->getAttrKind() == attr::ArmStreaming) {
1998 OS << "__arm_streaming";
1999 return;
2000 }
2001 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
2002 OS << "__arm_streaming_compatible";
2003 return;
2004 }
2005
2006 if (T->getAttrKind() == attr::SwiftAttr) {
2007 if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
2008 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
2009 << "\")))";
2010 }
2011 return;
2012 }
2013
2014 if (T->getAttrKind() == attr::PreserveAll ||
2015 T->getAttrKind() == attr::PreserveMost ||
2016 T->getAttrKind() == attr::PreserveNone) {
2017 // This has to be printed before the type.
2018 return;
2019 }
2020
2021 OS << " __attribute__((";
2022 switch (T->getAttrKind()) {
2023#define TYPE_ATTR(NAME)
2024#define DECL_OR_TYPE_ATTR(NAME)
2025#define ATTR(NAME) case attr::NAME:
2026#include "clang/Basic/AttrList.inc"
2027 llvm_unreachable("non-type attribute attached to type");
2028
2029 case attr::BTFTypeTag:
2030 llvm_unreachable("BTFTypeTag attribute handled separately");
2031
2032 case attr::HLSLResourceClass:
2033 case attr::HLSLROV:
2034 case attr::HLSLRawBuffer:
2035 case attr::HLSLContainedType:
2036 llvm_unreachable("HLSL resource type attributes handled separately");
2037
2038 case attr::OpenCLPrivateAddressSpace:
2039 case attr::OpenCLGlobalAddressSpace:
2040 case attr::OpenCLGlobalDeviceAddressSpace:
2041 case attr::OpenCLGlobalHostAddressSpace:
2042 case attr::OpenCLLocalAddressSpace:
2043 case attr::OpenCLConstantAddressSpace:
2044 case attr::OpenCLGenericAddressSpace:
2045 case attr::HLSLGroupSharedAddressSpace:
2046 // FIXME: Update printAttributedBefore to print these once we generate
2047 // AttributedType nodes for them.
2048 break;
2049
2050 case attr::CountedBy:
2051 case attr::CountedByOrNull:
2052 case attr::SizedBy:
2053 case attr::SizedByOrNull:
2054 case attr::LifetimeBound:
2055 case attr::LifetimeCaptureBy:
2056 case attr::TypeNonNull:
2057 case attr::TypeNullable:
2058 case attr::TypeNullableResult:
2059 case attr::TypeNullUnspecified:
2060 case attr::ObjCGC:
2061 case attr::ObjCInertUnsafeUnretained:
2062 case attr::ObjCKindOf:
2063 case attr::ObjCOwnership:
2064 case attr::Ptr32:
2065 case attr::Ptr64:
2066 case attr::SPtr:
2067 case attr::UPtr:
2068 case attr::PointerAuth:
2069 case attr::AddressSpace:
2070 case attr::CmseNSCall:
2071 case attr::AnnotateType:
2072 case attr::WebAssemblyFuncref:
2073 case attr::ArmAgnostic:
2074 case attr::ArmStreaming:
2075 case attr::ArmStreamingCompatible:
2076 case attr::ArmIn:
2077 case attr::ArmOut:
2078 case attr::ArmInOut:
2079 case attr::ArmPreserves:
2080 case attr::NonBlocking:
2081 case attr::NonAllocating:
2082 case attr::Blocking:
2083 case attr::Allocating:
2084 case attr::SwiftAttr:
2085 case attr::PreserveAll:
2086 case attr::PreserveMost:
2087 case attr::PreserveNone:
2088 llvm_unreachable("This attribute should have been handled already");
2089
2090 case attr::NSReturnsRetained:
2091 OS << "ns_returns_retained";
2092 break;
2093
2094 // FIXME: When Sema learns to form this AttributedType, avoid printing the
2095 // attribute again in printFunctionProtoAfter.
2096 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2097 case attr::CDecl: OS << "cdecl"; break;
2098 case attr::FastCall: OS << "fastcall"; break;
2099 case attr::StdCall: OS << "stdcall"; break;
2100 case attr::ThisCall: OS << "thiscall"; break;
2101 case attr::SwiftCall: OS << "swiftcall"; break;
2102 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2103 case attr::VectorCall: OS << "vectorcall"; break;
2104 case attr::Pascal: OS << "pascal"; break;
2105 case attr::MSABI: OS << "ms_abi"; break;
2106 case attr::SysVABI: OS << "sysv_abi"; break;
2107 case attr::RegCall: OS << "regcall"; break;
2108 case attr::Pcs: {
2109 OS << "pcs(";
2110 QualType t = T->getEquivalentType();
2111 while (!t->isFunctionType())
2112 t = t->getPointeeType();
2113 OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?
2114 "\"aapcs\"" : "\"aapcs-vfp\"");
2115 OS << ')';
2116 break;
2117 }
2118 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2119 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2120 case attr::DeviceKernel:
2121 OS << T->getAttr()->getSpelling();
2122 break;
2123 case attr::IntelOclBicc:
2124 OS << "inteloclbicc";
2125 break;
2126 case attr::M68kRTD:
2127 OS << "m68k_rtd";
2128 break;
2129 case attr::RISCVVectorCC:
2130 OS << "riscv_vector_cc";
2131 break;
2132 case attr::RISCVVLSCC:
2133 OS << "riscv_vls_cc";
2134 break;
2135 case attr::NoDeref:
2136 OS << "noderef";
2137 break;
2138 case attr::CFIUncheckedCallee:
2139 OS << "cfi_unchecked_callee";
2140 break;
2141 case attr::AcquireHandle:
2142 OS << "acquire_handle";
2143 break;
2144 case attr::ArmMveStrictPolymorphism:
2145 OS << "__clang_arm_mve_strict_polymorphism";
2146 break;
2147 case attr::ExtVectorType:
2148 OS << "ext_vector_type";
2149 break;
2150 case attr::CFISalt:
2151 OS << "cfi_salt(\"" << cast<CFISaltAttr>(T->getAttr())->getSalt() << "\")";
2152 break;
2153 }
2154 OS << "))";
2155}
2156
2157void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2158 raw_ostream &OS) {
2159 printBefore(T->getWrappedType(), OS);
2160 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2161}
2162
2163void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2164 raw_ostream &OS) {
2165 printAfter(T->getWrappedType(), OS);
2166}
2167
2168void TypePrinter::printHLSLAttributedResourceBefore(
2169 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2170 printBefore(T->getWrappedType(), OS);
2171}
2172
2173void TypePrinter::printHLSLAttributedResourceAfter(
2174 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2175 printAfter(T->getWrappedType(), OS);
2176 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2177 OS << " [[hlsl::resource_class("
2178 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2179 << ")]]";
2180 if (Attrs.IsROV)
2181 OS << " [[hlsl::is_rov]]";
2182 if (Attrs.RawBuffer)
2183 OS << " [[hlsl::raw_buffer]]";
2184
2185 QualType ContainedTy = T->getContainedType();
2186 if (!ContainedTy.isNull()) {
2187 OS << " [[hlsl::contained_type(";
2188 printBefore(ContainedTy, OS);
2189 printAfter(ContainedTy, OS);
2190 OS << ")]]";
2191 }
2192}
2193
2194void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2195 raw_ostream &OS) {
2196 OS << "__hlsl_spirv_type<" << T->getOpcode();
2197
2198 OS << ", " << T->getSize();
2199 OS << ", " << T->getAlignment();
2200
2201 for (auto &Operand : T->getOperands()) {
2202 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2203
2204 OS << ", ";
2205 switch (Operand.getKind()) {
2206 case SpirvOperandKind::ConstantId: {
2207 QualType ConstantType = Operand.getResultType();
2208 OS << "vk::integral_constant<";
2209 printBefore(ConstantType, OS);
2210 printAfter(ConstantType, OS);
2211 OS << ", ";
2212 OS << Operand.getValue();
2213 OS << ">";
2214 break;
2215 }
2216 case SpirvOperandKind::Literal:
2217 OS << "vk::Literal<vk::integral_constant<uint, ";
2218 OS << Operand.getValue();
2219 OS << ">>";
2220 break;
2221 case SpirvOperandKind::TypeId: {
2222 QualType Type = Operand.getResultType();
2223 printBefore(Type, OS);
2224 printAfter(Type, OS);
2225 break;
2226 }
2227 default:
2228 llvm_unreachable("Invalid SpirvOperand kind!");
2229 break;
2230 }
2231 }
2232
2233 OS << ">";
2234}
2235
2236void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2237 raw_ostream &OS) {
2238 // nothing to do
2239}
2240
2241void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2242 raw_ostream &OS) {
2243 OS << T->getDecl()->getName();
2244 spaceBeforePlaceHolder(OS);
2245}
2246
2247void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2248 raw_ostream &OS) {}
2249
2250void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2251 raw_ostream &OS) {
2252 OS << T->getDecl()->getName();
2253 if (!T->qual_empty()) {
2254 bool isFirst = true;
2255 OS << '<';
2256 for (const auto *I : T->quals()) {
2257 if (isFirst)
2258 isFirst = false;
2259 else
2260 OS << ',';
2261 OS << I->getName();
2262 }
2263 OS << '>';
2264 }
2265
2266 spaceBeforePlaceHolder(OS);
2267}
2268
2269void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2270 raw_ostream &OS) {}
2271
2272void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2273 raw_ostream &OS) {
2274 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2275 !T->isKindOfTypeAsWritten())
2276 return printBefore(T->getBaseType(), OS);
2277
2278 if (T->isKindOfTypeAsWritten())
2279 OS << "__kindof ";
2280
2281 print(T->getBaseType(), OS, StringRef());
2282
2283 if (T->isSpecializedAsWritten()) {
2284 bool isFirst = true;
2285 OS << '<';
2286 for (auto typeArg : T->getTypeArgsAsWritten()) {
2287 if (isFirst)
2288 isFirst = false;
2289 else
2290 OS << ",";
2291
2292 print(typeArg, OS, StringRef());
2293 }
2294 OS << '>';
2295 }
2296
2297 if (!T->qual_empty()) {
2298 bool isFirst = true;
2299 OS << '<';
2300 for (const auto *I : T->quals()) {
2301 if (isFirst)
2302 isFirst = false;
2303 else
2304 OS << ',';
2305 OS << I->getName();
2306 }
2307 OS << '>';
2308 }
2309
2310 spaceBeforePlaceHolder(OS);
2311}
2312
2313void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2314 raw_ostream &OS) {
2315 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2316 !T->isKindOfTypeAsWritten())
2317 return printAfter(T->getBaseType(), OS);
2318}
2319
2320void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2321 raw_ostream &OS) {
2322 printBefore(T->getPointeeType(), OS);
2323
2324 // If we need to print the pointer, print it now.
2325 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
2327 if (HasEmptyPlaceHolder)
2328 OS << ' ';
2329 OS << '*';
2330 }
2331}
2332
2333void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2334 raw_ostream &OS) {}
2335
2336static
2337const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
2338
2340 return A.getArgument();
2341}
2342
2343static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
2344 llvm::raw_ostream &OS, bool IncludeType) {
2345 A.print(PP, OS, IncludeType);
2346}
2347
2349 const PrintingPolicy &PP, llvm::raw_ostream &OS,
2350 bool IncludeType) {
2351 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
2353 return A.getTypeSourceInfo()->getType().print(OS, PP);
2354 return A.getArgument().print(PP, OS, IncludeType);
2355}
2356
2357static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
2358 TemplateArgument Pattern,
2359 ArrayRef<TemplateArgument> Args,
2360 unsigned Depth);
2361
2363 ArrayRef<TemplateArgument> Args, unsigned Depth) {
2364 if (Ctx.hasSameType(T, Pattern))
2365 return true;
2366
2367 // A type parameter matches its argument.
2368 if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {
2369 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2370 Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {
2371 QualType SubstArg = Ctx.getQualifiedType(
2372 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2373 return Ctx.hasSameType(SubstArg, T);
2374 }
2375 return false;
2376 }
2377
2378 // FIXME: Recurse into array types.
2379
2380 // All other cases will need the types to be identically qualified.
2381 Qualifiers TQual, PatQual;
2382 T = Ctx.getUnqualifiedArrayType(T, TQual);
2383 Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);
2384 if (TQual != PatQual)
2385 return false;
2386
2387 // Recurse into pointer-like types.
2388 {
2389 QualType TPointee = T->getPointeeType();
2390 QualType PPointee = Pattern->getPointeeType();
2391 if (!TPointee.isNull() && !PPointee.isNull())
2392 return T->getTypeClass() == Pattern->getTypeClass() &&
2393 isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);
2394 }
2395
2396 // Recurse into template specialization types.
2397 if (auto *PTST =
2398 Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {
2400 ArrayRef<TemplateArgument> TemplateArgs;
2401 if (auto *TTST = T->getAs<TemplateSpecializationType>()) {
2402 Template = TTST->getTemplateName();
2403 TemplateArgs = TTST->template_arguments();
2404 } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2405 T->getAsCXXRecordDecl())) {
2406 Template = TemplateName(CTSD->getSpecializedTemplate());
2407 TemplateArgs = CTSD->getTemplateArgs().asArray();
2408 } else {
2409 return false;
2410 }
2411
2412 if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),
2413 Args, Depth))
2414 return false;
2415 if (TemplateArgs.size() != PTST->template_arguments().size())
2416 return false;
2417 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2419 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2420 return false;
2421 return true;
2422 }
2423
2424 // FIXME: Handle more cases.
2425 return false;
2426}
2427
2428/// Evaluates the expression template argument 'Pattern' and returns true
2429/// if 'Arg' evaluates to the same result.
2431 TemplateArgument const &Pattern,
2432 TemplateArgument const &Arg) {
2433 if (Pattern.getKind() != TemplateArgument::Expression)
2434 return false;
2435
2436 // Can't evaluate value-dependent expressions so bail early
2437 Expr const *pattern_expr = Pattern.getAsExpr();
2438 if (pattern_expr->isValueDependent() ||
2439 !pattern_expr->isIntegerConstantExpr(Ctx))
2440 return false;
2441
2443 return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),
2444 Arg.getAsIntegral());
2445
2447 Expr const *args_expr = Arg.getAsExpr();
2448 if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))
2449 return false;
2450
2451 return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),
2452 pattern_expr->EvaluateKnownConstInt(Ctx));
2453 }
2454
2455 return false;
2456}
2457
2459 TemplateArgument Pattern,
2461 unsigned Depth) {
2462 Arg = Ctx.getCanonicalTemplateArgument(Arg);
2463 Pattern = Ctx.getCanonicalTemplateArgument(Pattern);
2464 if (Arg.structurallyEquals(Pattern))
2465 return true;
2466
2467 if (Pattern.getKind() == TemplateArgument::Expression) {
2468 if (auto *DRE =
2469 dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {
2470 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2471 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2472 Args[NTTP->getIndex()].structurallyEquals(Arg);
2473 }
2474 }
2475
2476 if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))
2477 return true;
2478
2479 if (Arg.getKind() != Pattern.getKind())
2480 return false;
2481
2482 if (Arg.getKind() == TemplateArgument::Type)
2483 return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,
2484 Depth);
2485
2486 if (Arg.getKind() == TemplateArgument::Template) {
2487 TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();
2488 if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2489 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2490 Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])
2491 .structurallyEquals(Arg);
2492 }
2493
2494 // FIXME: Handle more cases.
2495 return false;
2496}
2497
2498bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2499 const NamedDecl *Param,
2500 ArrayRef<TemplateArgument> Args,
2501 unsigned Depth) {
2502 // An empty pack is equivalent to not providing a pack argument.
2503 if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)
2504 return true;
2505
2506 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2507 return TTPD->hasDefaultArgument() &&
2509 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2510 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2511 return TTPD->hasDefaultArgument() &&
2513 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2514 } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2515 return NTTPD->hasDefaultArgument() &&
2517 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2518 Depth);
2519 }
2520 return false;
2521}
2522
2523template <typename TA>
2524static void
2525printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,
2526 const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {
2527 // Drop trailing template arguments that match default arguments.
2528 if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&
2529 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2531 for (const TA &A : Args)
2532 OrigArgs.push_back(getArgument(A));
2533 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2534 Args = Args.drop_back();
2535 }
2536
2537 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2538 if (!IsPack)
2539 OS << '<';
2540
2541 bool NeedSpace = false;
2542 bool FirstArg = true;
2543 for (const auto &Arg : Args) {
2544 // Print the argument into a string.
2545 SmallString<128> Buf;
2546 llvm::raw_svector_ostream ArgOS(Buf);
2547 const TemplateArgument &Argument = getArgument(Arg);
2548 if (Argument.getKind() == TemplateArgument::Pack) {
2549 if (Argument.pack_size() && !FirstArg)
2550 OS << Comma;
2551 printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,
2552 /*IsPack*/ true, ParmIndex);
2553 } else {
2554 if (!FirstArg)
2555 OS << Comma;
2556 // Tries to print the argument with location info if exists.
2557 printArgument(Arg, Policy, ArgOS,
2559 Policy, TPL, ParmIndex));
2560 }
2561 StringRef ArgString = ArgOS.str();
2562
2563 // If this is the first argument and its string representation
2564 // begins with the global scope specifier ('::foo'), add a space
2565 // to avoid printing the diagraph '<:'.
2566 if (FirstArg && ArgString.starts_with(":"))
2567 OS << ' ';
2568
2569 OS << ArgString;
2570
2571 // If the last character of our string is '>', add another space to
2572 // keep the two '>''s separate tokens.
2573 if (!ArgString.empty()) {
2574 NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';
2575 FirstArg = false;
2576 }
2577
2578 // Use same template parameter for all elements of Pack
2579 if (!IsPack)
2580 ParmIndex++;
2581 }
2582
2583 if (!IsPack) {
2584 if (NeedSpace)
2585 OS << ' ';
2586 OS << '>';
2587 }
2588}
2589
2590void clang::printTemplateArgumentList(raw_ostream &OS,
2591 const TemplateArgumentListInfo &Args,
2592 const PrintingPolicy &Policy,
2593 const TemplateParameterList *TPL) {
2594 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2595}
2596
2597void clang::printTemplateArgumentList(raw_ostream &OS,
2598 ArrayRef<TemplateArgument> Args,
2599 const PrintingPolicy &Policy,
2600 const TemplateParameterList *TPL) {
2601 PrintingPolicy InnerPolicy = Policy;
2602 InnerPolicy.SuppressScope = false;
2603 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2604}
2605
2606void clang::printTemplateArgumentList(raw_ostream &OS,
2607 ArrayRef<TemplateArgumentLoc> Args,
2608 const PrintingPolicy &Policy,
2609 const TemplateParameterList *TPL) {
2610 PrintingPolicy InnerPolicy = Policy;
2611 InnerPolicy.SuppressScope = false;
2612 printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);
2613}
2614
2616 LangOptions LO;
2617 return getAsString(PrintingPolicy(LO));
2618}
2619
2621 SmallString<64> Buf;
2622 llvm::raw_svector_ostream StrOS(Buf);
2623 print(StrOS, P);
2624 return StrOS.str().str();
2625}
2626
2628 return !isPresent();
2629}
2630
2631void PointerAuthQualifier::print(raw_ostream &OS,
2632 const PrintingPolicy &P) const {
2633 if (!isPresent())
2634 return;
2635
2636 OS << "__ptrauth(";
2637 OS << getKey();
2638 OS << "," << unsigned(isAddressDiscriminated()) << ","
2639 << getExtraDiscriminator() << ")";
2640}
2641
2642std::string Qualifiers::getAsString() const {
2643 LangOptions LO;
2644 return getAsString(PrintingPolicy(LO));
2645}
2646
2647// Appends qualifiers to the given string, separated by spaces. Will
2648// prefix a space if the string is non-empty. Will not append a final
2649// space.
2650std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
2651 SmallString<64> Buf;
2652 llvm::raw_svector_ostream StrOS(Buf);
2653 print(StrOS, Policy);
2654 return std::string(StrOS.str());
2655}
2656
2658 if (getCVRQualifiers())
2659 return false;
2660
2662 return false;
2663
2664 if (getObjCGCAttr())
2665 return false;
2666
2668 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
2669 return false;
2670
2671 if (PointerAuthQualifier PointerAuth = getPointerAuth();
2672 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))
2673 return false;
2674
2675 return true;
2676}
2677
2679 switch (AS) {
2680 case LangAS::Default:
2681 return "";
2684 return "__global";
2686 case LangAS::sycl_local:
2687 return "__local";
2690 return "__private";
2692 return "__constant";
2694 return "__generic";
2697 return "__global_device";
2700 return "__global_host";
2702 return "__device__";
2704 return "__constant__";
2706 return "__shared__";
2707 case LangAS::ptr32_sptr:
2708 return "__sptr __ptr32";
2709 case LangAS::ptr32_uptr:
2710 return "__uptr __ptr32";
2711 case LangAS::ptr64:
2712 return "__ptr64";
2714 return "groupshared";
2716 return "hlsl_constant";
2718 return "hlsl_private";
2720 return "hlsl_device";
2721 case LangAS::hlsl_input:
2722 return "hlsl_input";
2724 return "__funcref";
2725 default:
2726 return std::to_string(toTargetAddressSpace(AS));
2727 }
2728}
2729
2730// Appends qualifiers to the given string, separated by spaces. Will
2731// prefix a space if the string is non-empty. Will not append a final
2732// space.
2733void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
2734 bool appendSpaceIfNonEmpty) const {
2735 bool addSpace = false;
2736
2737 unsigned quals = getCVRQualifiers();
2738 if (quals) {
2739 AppendTypeQualList(OS, quals, Policy.Restrict);
2740 addSpace = true;
2741 }
2742 if (hasUnaligned()) {
2743 if (addSpace)
2744 OS << ' ';
2745 OS << "__unaligned";
2746 addSpace = true;
2747 }
2748 auto ASStr = getAddrSpaceAsString(getAddressSpace());
2749 if (!ASStr.empty()) {
2750 if (addSpace)
2751 OS << ' ';
2752 addSpace = true;
2753 // Wrap target address space into an attribute syntax
2755 OS << "__attribute__((address_space(" << ASStr << ")))";
2756 else
2757 OS << ASStr;
2758 }
2759
2760 if (Qualifiers::GC gc = getObjCGCAttr()) {
2761 if (addSpace)
2762 OS << ' ';
2763 addSpace = true;
2764 if (gc == Qualifiers::Weak)
2765 OS << "__weak";
2766 else
2767 OS << "__strong";
2768 }
2769 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
2770 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
2771 if (addSpace)
2772 OS << ' ';
2773 addSpace = true;
2774 }
2775
2776 switch (lifetime) {
2777 case Qualifiers::OCL_None: llvm_unreachable("none but true");
2778 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
2780 if (!Policy.SuppressStrongLifetime)
2781 OS << "__strong";
2782 break;
2783
2784 case Qualifiers::OCL_Weak: OS << "__weak"; break;
2785 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
2786 }
2787 }
2788
2789 if (PointerAuthQualifier PointerAuth = getPointerAuth()) {
2790 if (addSpace)
2791 OS << ' ';
2792 addSpace = true;
2793
2794 PointerAuth.print(OS, Policy);
2795 }
2796
2797 if (appendSpaceIfNonEmpty && addSpace)
2798 OS << ' ';
2799}
2800
2801std::string QualType::getAsString() const {
2802 return getAsString(split(), LangOptions());
2803}
2804
2805std::string QualType::getAsString(const PrintingPolicy &Policy) const {
2806 std::string S;
2807 getAsStringInternal(S, Policy);
2808 return S;
2809}
2810
2811std::string QualType::getAsString(const Type *ty, Qualifiers qs,
2812 const PrintingPolicy &Policy) {
2813 std::string buffer;
2814 getAsStringInternal(ty, qs, buffer, Policy);
2815 return buffer;
2816}
2817
2818void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,
2819 const Twine &PlaceHolder, unsigned Indentation) const {
2820 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,
2821 Indentation);
2822}
2823
2825 raw_ostream &OS, const PrintingPolicy &policy,
2826 const Twine &PlaceHolder, unsigned Indentation) {
2827 SmallString<128> PHBuf;
2828 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2829
2830 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2831}
2832
2833void QualType::getAsStringInternal(std::string &Str,
2834 const PrintingPolicy &Policy) const {
2835 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,
2836 Policy);
2837}
2838
2840 std::string &buffer,
2841 const PrintingPolicy &policy) {
2842 SmallString<256> Buf;
2843 llvm::raw_svector_ostream StrOS(Buf);
2844 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2845 std::string str = std::string(StrOS.str());
2846 buffer.swap(str);
2847}
2848
2849raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {
2850 SplitQualType S = QT.split();
2851 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");
2852 return OS;
2853}
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, ASTContext &ASTCtx, 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 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 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:188
SourceManager & getSourceManager()
Definition ASTContext.h:798
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition TypeBase.h:3436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
bool isTranslationUnit() const
Definition DeclBase.h:2185
bool isFunctionOrMethod() const
Definition DeclBase.h:2161
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:524
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:593
SourceLocation getLocation() const
Definition DeclBase.h:439
DeclContext * getDeclContext()
Definition DeclBase.h:448
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, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) 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:3073
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5264
QualType desugar() const
Definition TypeBase.h:5845
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5571
unsigned getNumParams() const
Definition TypeBase.h:5542
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition TypeBase.h:5684
Qualifiers getMethodQuals() const
Definition TypeBase.h:5690
QualType getParamType(unsigned i) const
Definition TypeBase.h:5544
FunctionEffectsRef getFunctionEffects() const
Definition TypeBase.h:5828
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
Definition TypeBase.h:5761
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5622
bool hasCFIUncheckedCallee() const
Definition TypeBase.h:5686
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5614
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition TypeBase.h:5580
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5668
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition TypeBase.h:5629
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5698
CallingConv getCC() const
Definition TypeBase.h:4630
unsigned getRegParm() const
Definition TypeBase.h:4623
bool getNoCallerSavedRegs() const
Definition TypeBase.h:4619
ExtInfo getExtInfo() const
Definition TypeBase.h:4816
static ArmStateValue getArmZT0State(unsigned AttrBits)
Definition TypeBase.h:4769
static ArmStateValue getArmZAState(unsigned AttrBits)
Definition TypeBase.h:4765
QualType getReturnType() const
Definition TypeBase.h:4800
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:294
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:300
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:339
Pointer-authentication qualifiers.
Definition TypeBase.h:152
bool isAddressDiscriminated() const
Definition TypeBase.h:265
unsigned getExtraDiscriminator() const
Definition TypeBase.h:270
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:258
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
virtual bool isScopeVisible(const DeclContext *DC) const
When printing type to be inserted into code in specific context, this callback can be used to avoid p...
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8325
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:8337
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition TypeBase.h:8306
std::string getAsString() const
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
unsigned getCVRQualifiers() const
Definition TypeBase.h:488
GC getObjCGCAttr() const
Definition TypeBase.h:519
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Definition TypeBase.h:361
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
Definition TypeBase.h:354
@ OCL_None
There is no lifetime qualification on this type.
Definition TypeBase.h:350
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:364
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Definition TypeBase.h:367
bool hasUnaligned() const
Definition TypeBase.h:511
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
PointerAuthQualifier getPointerAuth() const
Definition TypeBase.h:603
ObjCLifetime getObjCLifetime() const
Definition TypeBase.h:545
bool empty() const
Definition TypeBase.h:647
std::string getAsString() const
LangAS getAddressSpace() const
Definition TypeBase.h:571
static std::string getAddrSpaceAsString(LangAS AS)
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3571
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
StringRef getKindName() const
Definition Decl.h:3904
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:3945
ArrayRef< TemplateArgumentLoc > arguments() const
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
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:8267
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isArrayType() const
Definition TypeBase.h:8621
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
Definition Type.cpp:521
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9165
bool isObjCQualifiedIdType() const
Definition TypeBase.h:8712
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
bool isObjCIdType() const
Definition TypeBase.h:8724
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition Type.cpp:3200
bool isFunctionType() const
Definition TypeBase.h:8518
bool isObjCQualifiedClassType() const
Definition TypeBase.h:8718
bool isObjCClassType() const
Definition TypeBase.h:8730
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2921
TypeClass getTypeClass() const
Definition TypeBase.h:2385
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
Definition TypeBase.h:2411
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9098
const internal::VariadicAllOfMatcher< Attr > attr
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
llvm::StringRef getParameterABISpelling(ParameterABI kind)
bool isTargetAddressSpace(LangAS AS)
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1782
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1785
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1788
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
unsigned toTargetAddressSpace(LangAS AS)
ParameterABI
Kinds of parameter ABI.
Definition Specifiers.h:378
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
Definition Specifiers.h:399
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
Definition Specifiers.h:389
@ Ordinary
This parameter uses ordinary ABI rules for its type.
Definition Specifiers.h:380
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
Definition Specifiers.h:384
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
Definition Specifiers.h:394
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:560
@ Type
The name was classified as a type.
Definition Sema.h:562
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:1288
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:60
@ CC_X86Pascal
Definition Specifiers.h:284
@ CC_Swift
Definition Specifiers.h:293
@ CC_IntelOclBicc
Definition Specifiers.h:290
@ CC_PreserveMost
Definition Specifiers.h:295
@ CC_Win64
Definition Specifiers.h:285
@ CC_X86ThisCall
Definition Specifiers.h:282
@ CC_AArch64VectorCall
Definition Specifiers.h:297
@ CC_DeviceKernel
Definition Specifiers.h:292
@ CC_AAPCS
Definition Specifiers.h:288
@ CC_PreserveNone
Definition Specifiers.h:300
@ CC_M68kRTD
Definition Specifiers.h:299
@ CC_SwiftAsync
Definition Specifiers.h:294
@ CC_X86RegCall
Definition Specifiers.h:287
@ CC_RISCVVectorCall
Definition Specifiers.h:301
@ CC_X86VectorCall
Definition Specifiers.h:283
@ CC_SpirFunction
Definition Specifiers.h:291
@ CC_AArch64SVEPCS
Definition Specifiers.h:298
@ CC_X86StdCall
Definition Specifiers.h:280
@ CC_X86_64SysV
Definition Specifiers.h:286
@ CC_PreserveAll
Definition Specifiers.h:296
@ CC_X86FastCall
Definition Specifiers.h:281
@ CC_AAPCS_VFP
Definition Specifiers.h:289
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:5863
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
ArrayRef< TemplateArgumentLoc > arguments() const
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Definition Type.cpp:3310
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressUnwrittenScope
Suppress printing parts of scope specifiers that are never written, e.g., for anonymous namespaces.
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 AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
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 SuppressInlineNamespace
Suppress printing parts of scope specifiers that correspond to inline namespaces.
unsigned SuppressScope
Suppresses printing of scope specifiers.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
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:870
const Type * Ty
The locally-unqualified type.
Definition TypeBase.h:872
Qualifiers Quals
The local qualifiers.
Definition TypeBase.h:875