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