Thanks to visit codestin.com
Credit goes to clang.llvm.org

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