clang: lib/AST/TypePrinter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
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
45#include
46
47using namespace clang;
48
49namespace {
50
51
52
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}
148
150 bool HasRestrictKeyword) {
151 bool appendSpace = false;
153 OS << "const";
154 appendSpace = true;
155 }
157 if (appendSpace) OS << ' ';
158 OS << "volatile";
159 appendSpace = true;
160 }
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
180 return QT.split();
181}
182
183void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
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 () {
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
205
206
207
208
209 bool CanPrefixQualifiers = false;
210 NeedARCStrongQualifier = false;
211 const Type *UnderlyingType = T;
212 if (const auto *AT = dyn_cast(T))
213 UnderlyingType = AT->desugar().getTypePtr();
214 if (const auto *Subst = dyn_cast(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:
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(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::CountAttributed:
290 CanPrefixQualifiers = false;
291 break;
292
293 case Type::Attributed: {
294
295
297 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
298 break;
299 }
300 case Type::PackIndexing: {
301 return canPrefixQualifiers(
303 NeedARCStrongQualifier);
304 }
305 }
306
307 return CanPrefixQualifiers;
308}
309
310void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
312
313
314
315 Qualifiers Quals = Split.Quals;
316 if (const auto *Subst = dyn_cast(Split.Ty))
317 Quals -= QualType(Subst, 0).getQualifiers();
318
319 printBefore(Split.Ty, Quals, OS);
320}
321
322
323
324void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
326 return;
327
328 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);
329
330
331
332 bool CanPrefixQualifiers = false;
333 bool NeedARCStrongQualifier = false;
334 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
335
336 if (CanPrefixQualifiers && !Quals.empty()) {
337 if (NeedARCStrongQualifier) {
338 IncludeStrongLifetimeRAII Strong(Policy);
339 Quals.print(OS, Policy, true);
340 } else {
341 Quals.print(OS, Policy, true);
342 }
343 }
344
345 bool hasAfterQuals = false;
346 if (!CanPrefixQualifiers && !Quals.empty()) {
348 if (hasAfterQuals)
349 HasEmptyPlaceHolder = false;
350 }
351
353#define ABSTRACT_TYPE(CLASS, PARENT)
354#define TYPE(CLASS, PARENT) case Type::CLASS: \
355 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
356 break;
357#include "clang/AST/TypeNodes.inc"
358 }
359
360 if (hasAfterQuals) {
361 if (NeedARCStrongQualifier) {
362 IncludeStrongLifetimeRAII Strong(Policy);
363 Quals.print(OS, Policy, !PrevPHIsEmpty.get());
364 } else {
365 Quals.print(OS, Policy, !PrevPHIsEmpty.get());
366 }
367 }
368}
369
370void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
372 printAfter(split.Ty, split.Quals, OS);
373}
374
375
376
377void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
379#define ABSTRACT_TYPE(CLASS, PARENT)
380#define TYPE(CLASS, PARENT) case Type::CLASS: \
381 print##CLASS##After(cast<CLASS##Type>(T), OS); \
382 break;
383#include "clang/AST/TypeNodes.inc"
384 }
385}
386
387void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
389 spaceBeforePlaceHolder(OS);
390}
391
392void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}
393
394void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
395 OS << "_Complex ";
396 printBefore(T->getElementType(), OS);
397}
398
399void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
400 printAfter(T->getElementType(), OS);
401}
402
403void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
404 IncludeStrongLifetimeRAII Strong(Policy);
405 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
407
408
410 OS << '(';
411 OS << '*';
412}
413
414void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
415 IncludeStrongLifetimeRAII Strong(Policy);
416 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
417
418
420 OS << ')';
422}
423
424void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
425 raw_ostream &OS) {
426 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
428 OS << '^';
429}
430
431void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
432 raw_ostream &OS) {
433 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
435}
436
437
438
444
445void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
446 raw_ostream &OS) {
447 IncludeStrongLifetimeRAII Strong(Policy);
448 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
450 printBefore(Inner, OS);
451
452
454 OS << '(';
455 OS << '&';
456}
457
458void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
459 raw_ostream &OS) {
460 IncludeStrongLifetimeRAII Strong(Policy);
461 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
463
464
466 OS << ')';
467 printAfter(Inner, OS);
468}
469
470void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
471 raw_ostream &OS) {
472 IncludeStrongLifetimeRAII Strong(Policy);
473 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
475 printBefore(Inner, OS);
476
477
479 OS << '(';
480 OS << "&&";
481}
482
483void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
484 raw_ostream &OS) {
485 IncludeStrongLifetimeRAII Strong(Policy);
486 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
488
489
491 OS << ')';
492 printAfter(Inner, OS);
493}
494
495void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
496 raw_ostream &OS) {
497 IncludeStrongLifetimeRAII Strong(Policy);
498 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
500
501
503 OS << '(';
504 T->getQualifier().print(OS, Policy);
505 OS << "*";
506}
507
508void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
509 raw_ostream &OS) {
510 IncludeStrongLifetimeRAII Strong(Policy);
511 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
512
513
515 OS << ')';
517}
518
519void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
520 raw_ostream &OS) {
521 IncludeStrongLifetimeRAII Strong(Policy);
522 printBefore(T->getElementType(), OS);
523}
524
525void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
526 raw_ostream &OS) {
527 OS << '[';
528 if (T->getIndexTypeQualifiers().hasQualifiers()) {
531 OS << ' ';
532 }
533
534 if (T->getSizeModifier() == ArraySizeModifier::Static)
535 OS << "static ";
536
537 OS << T->getZExtSize() << ']';
538 printAfter(T->getElementType(), OS);
539}
540
541void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
542 raw_ostream &OS) {
543 IncludeStrongLifetimeRAII Strong(Policy);
544 printBefore(T->getElementType(), OS);
545}
546
547void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
548 raw_ostream &OS) {
549 OS << "[]";
550 printAfter(T->getElementType(), OS);
551}
552
553void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
554 raw_ostream &OS) {
555 IncludeStrongLifetimeRAII Strong(Policy);
556 printBefore(T->getElementType(), OS);
557}
558
559void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
560 raw_ostream &OS) {
561 OS << '[';
562 if (T->getIndexTypeQualifiers().hasQualifiers()) {
564 OS << ' ';
565 }
566
567 if (T->getSizeModifier() == ArraySizeModifier::Static)
568 OS << "static ";
569 else if (T->getSizeModifier() == ArraySizeModifier::Star)
570 OS << '*';
571
572 if (T->getSizeExpr())
573 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
574 OS << ']';
575
576 printAfter(T->getElementType(), OS);
577}
578
579void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
580
581
582 printBefore(T->getAdjustedType(), OS);
583}
584
585void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
586 printAfter(T->getAdjustedType(), OS);
587}
588
589void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
590
591 printAdjustedBefore(T, OS);
592}
593
594void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
595 raw_ostream &OS) {
596 printConstantArrayAfter(T, OS);
597}
598
599void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
600 raw_ostream &OS) {
601 printConstantArrayBefore(T, OS);
602}
603
604void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
605 printAdjustedAfter(T, OS);
606}
607
608void TypePrinter::printDependentSizedArrayBefore(
609 const DependentSizedArrayType *T,
610 raw_ostream &OS) {
611 IncludeStrongLifetimeRAII Strong(Policy);
612 printBefore(T->getElementType(), OS);
613}
614
615void TypePrinter::printDependentSizedArrayAfter(
616 const DependentSizedArrayType *T,
617 raw_ostream &OS) {
618 OS << '[';
619 if (T->getSizeExpr())
620 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
621 OS << ']';
622 printAfter(T->getElementType(), OS);
623}
624
625void TypePrinter::printDependentAddressSpaceBefore(
626 const DependentAddressSpaceType *T, raw_ostream &OS) {
628}
629
630void TypePrinter::printDependentAddressSpaceAfter(
631 const DependentAddressSpaceType *T, raw_ostream &OS) {
632 OS << " __attribute__((address_space(";
633 if (T->getAddrSpaceExpr())
634 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
635 OS << ")))";
637}
638
639void TypePrinter::printDependentSizedExtVectorBefore(
640 const DependentSizedExtVectorType *T,
641 raw_ostream &OS) {
643 OS << "vector<";
644 printBefore(T->getElementType(), OS);
645}
646
647void TypePrinter::printDependentSizedExtVectorAfter(
648 const DependentSizedExtVectorType *T,
649 raw_ostream &OS) {
651 OS << ", ";
652 if (T->getSizeExpr())
653 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
654 OS << ">";
655 } else {
656 OS << " __attribute__((ext_vector_type(";
657 if (T->getSizeExpr())
658 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
659 OS << ")))";
660 }
661 printAfter(T->getElementType(), OS);
662}
663
664void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
665 switch (T->getVectorKind()) {
666 case VectorKind::AltiVecPixel:
667 OS << "__vector __pixel ";
668 break;
669 case VectorKind::AltiVecBool:
670 OS << "__vector __bool ";
671 printBefore(T->getElementType(), OS);
672 break;
673 case VectorKind::AltiVecVector:
674 OS << "__vector ";
675 printBefore(T->getElementType(), OS);
676 break;
677 case VectorKind::Neon:
678 OS << "__attribute__((neon_vector_type("
679 << T->getNumElements() << "))) ";
680 printBefore(T->getElementType(), OS);
681 break;
682 case VectorKind::NeonPoly:
683 OS << "__attribute__((neon_polyvector_type(" <<
684 T->getNumElements() << "))) ";
685 printBefore(T->getElementType(), OS);
686 break;
687 case VectorKind::Generic: {
688
689
690 OS << "__attribute__((__vector_size__("
691 << T->getNumElements()
692 << " * sizeof(";
693 print(T->getElementType(), OS, StringRef());
694 OS << ")))) ";
695 printBefore(T->getElementType(), OS);
696 break;
697 }
698 case VectorKind::SveFixedLengthData:
699 case VectorKind::SveFixedLengthPredicate:
700
701
702 OS << "__attribute__((__arm_sve_vector_bits__(";
703
704 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
705
706
707 OS << T->getNumElements() * 8;
708 else
709 OS << T->getNumElements();
710
711 OS << " * sizeof(";
712 print(T->getElementType(), OS, StringRef());
713
714 OS << ") * 8))) ";
715 printBefore(T->getElementType(), OS);
716 break;
717 case VectorKind::RVVFixedLengthData:
718 case VectorKind::RVVFixedLengthMask:
719 case VectorKind::RVVFixedLengthMask_1:
720 case VectorKind::RVVFixedLengthMask_2:
721 case VectorKind::RVVFixedLengthMask_4:
722
723
724 OS << "__attribute__((__riscv_rvv_vector_bits__(";
725
726 OS << T->getNumElements();
727
728 OS << " * sizeof(";
729 print(T->getElementType(), OS, StringRef());
730
731 OS << ") * 8))) ";
732 printBefore(T->getElementType(), OS);
733 break;
734 }
735}
736
737void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
738 printAfter(T->getElementType(), OS);
739}
740
741void TypePrinter::printDependentVectorBefore(
742 const DependentVectorType *T, raw_ostream &OS) {
743 switch (T->getVectorKind()) {
744 case VectorKind::AltiVecPixel:
745 OS << "__vector __pixel ";
746 break;
747 case VectorKind::AltiVecBool:
748 OS << "__vector __bool ";
749 printBefore(T->getElementType(), OS);
750 break;
751 case VectorKind::AltiVecVector:
752 OS << "__vector ";
753 printBefore(T->getElementType(), OS);
754 break;
755 case VectorKind::Neon:
756 OS << "__attribute__((neon_vector_type(";
757 if (T->getSizeExpr())
758 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
759 OS << "))) ";
760 printBefore(T->getElementType(), OS);
761 break;
762 case VectorKind::NeonPoly:
763 OS << "__attribute__((neon_polyvector_type(";
764 if (T->getSizeExpr())
765 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
766 OS << "))) ";
767 printBefore(T->getElementType(), OS);
768 break;
769 case VectorKind::Generic: {
770
771
772 OS << "__attribute__((__vector_size__(";
773 if (T->getSizeExpr())
774 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
775 OS << " * sizeof(";
776 print(T->getElementType(), OS, StringRef());
777 OS << ")))) ";
778 printBefore(T->getElementType(), OS);
779 break;
780 }
781 case VectorKind::SveFixedLengthData:
782 case VectorKind::SveFixedLengthPredicate:
783
784
785 OS << "__attribute__((__arm_sve_vector_bits__(";
786 if (T->getSizeExpr()) {
787 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
788 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
789
790
791 OS << " * 8";
792 OS << " * sizeof(";
793 print(T->getElementType(), OS, StringRef());
794
795 OS << ") * 8";
796 }
797 OS << "))) ";
798 printBefore(T->getElementType(), OS);
799 break;
800 case VectorKind::RVVFixedLengthData:
801 case VectorKind::RVVFixedLengthMask:
802 case VectorKind::RVVFixedLengthMask_1:
803 case VectorKind::RVVFixedLengthMask_2:
804 case VectorKind::RVVFixedLengthMask_4:
805
806
807 OS << "__attribute__((__riscv_rvv_vector_bits__(";
808 if (T->getSizeExpr()) {
809 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
810 OS << " * sizeof(";
811 print(T->getElementType(), OS, StringRef());
812
813 OS << ") * 8";
814 }
815 OS << "))) ";
816 printBefore(T->getElementType(), OS);
817 break;
818 }
819}
820
821void TypePrinter::printDependentVectorAfter(
822 const DependentVectorType *T, raw_ostream &OS) {
823 printAfter(T->getElementType(), OS);
824}
825
826void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
827 raw_ostream &OS) {
829 OS << "vector<";
830 printBefore(T->getElementType(), OS);
831}
832
833void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
834 printAfter(T->getElementType(), OS);
835
837 OS << ", ";
838 OS << T->getNumElements();
839 OS << ">";
840 } else {
841 OS << " __attribute__((ext_vector_type(";
842 OS << T->getNumElements();
843 OS << ")))";
844 }
845}
846
848 OS << T->getNumRows() << ", " << T->getNumColumns();
849}
850
852 raw_ostream &OS) {
853 OS << "matrix<";
854 TP.printBefore(T->getElementType(), OS);
855}
856
858 OS << ", ";
860 OS << ">";
861}
862
864 raw_ostream &OS) {
865 TP.printBefore(T->getElementType(), OS);
866 OS << " __attribute__((matrix_type(";
868 OS << ")))";
869}
870
871void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,
872 raw_ostream &OS) {
875 return;
876 }
878}
879
880void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,
881 raw_ostream &OS) {
884 return;
885 }
886 printAfter(T->getElementType(), OS);
887}
888
889void TypePrinter::printDependentSizedMatrixBefore(
890 const DependentSizedMatrixType *T, raw_ostream &OS) {
891 printBefore(T->getElementType(), OS);
892 OS << " __attribute__((matrix_type(";
893 if (T->getRowExpr()) {
894 T->getRowExpr()->printPretty(OS, nullptr, Policy);
895 }
896 OS << ", ";
897 if (T->getColumnExpr()) {
898 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
899 }
900 OS << ")))";
901}
902
903void TypePrinter::printDependentSizedMatrixAfter(
904 const DependentSizedMatrixType *T, raw_ostream &OS) {
905 printAfter(T->getElementType(), OS);
906}
907
908void
911 const {
913 OS << " throw(";
915 OS << "...";
916 else
918 if (I)
919 OS << ", ";
920
922 }
923 OS << ')';
925 OS << " __attribute__((nothrow))";
927 OS << " noexcept";
928
929
931 OS << '(';
934 OS << ')';
935 }
936 }
937}
938
939void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
940 raw_ostream &OS) {
941 if (T->hasTrailingReturn()) {
942 OS << "auto ";
943 if (!HasEmptyPlaceHolder)
944 OS << '(';
945 } else {
946
947 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
948 printBefore(T->getReturnType(), OS);
949 if (!PrevPHIsEmpty.get())
950 OS << '(';
951 }
952}
953
955 switch (ABI) {
957 llvm_unreachable("asking for spelling of ordinary parameter ABI");
959 return "swift_context";
961 return "swift_async_context";
963 return "swift_error_result";
965 return "swift_indirect_result";
967 return "out";
969 return "inout";
970 }
971 llvm_unreachable("bad parameter ABI kind");
972}
973
975 raw_ostream &OS) {
976
977 if (!HasEmptyPlaceHolder)
978 OS << ')';
979 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
980
981 OS << '(';
982 {
983 ParamPolicyRAII ParamPolicy(Policy);
984 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
985 if (i) OS << ", ";
986
987 auto EPI = T->getExtParameterInfo(i);
988 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
989 if (EPI.isNoEscape())
990 OS << "__attribute__((noescape)) ";
991 auto ABI = EPI.getABI();
995
996
997
998
999 print(T->getParamType(i).getNonReferenceType(), OS, StringRef());
1000 continue;
1001 }
1002 } else if (ABI != ParameterABI::Ordinary)
1004
1006 }
1007 }
1008
1011 OS << ", ";
1012 OS << "...";
1014
1015 OS << "void";
1016 }
1017
1018 OS << ')';
1019
1020 FunctionType::ExtInfo Info = T->getExtInfo();
1022
1024 OS << " __arm_streaming_compatible";
1026 OS << " __arm_streaming";
1028 OS << "__arm_agnostic(\"sme_za_state\")";
1030 OS << " __arm_preserves(\"za\")";
1032 OS << " __arm_in(\"za\")";
1034 OS << " __arm_out(\"za\")";
1036 OS << " __arm_inout(\"za\")";
1038 OS << " __arm_preserves(\"zt0\")";
1040 OS << " __arm_in(\"zt0\")";
1042 OS << " __arm_out(\"zt0\")";
1044 OS << " __arm_inout(\"zt0\")";
1045
1046 printFunctionAfter(Info, OS);
1047
1050
1053 break;
1054
1056 OS << " &";
1057 break;
1058
1060 OS << " &&";
1061 break;
1062 }
1064
1066 for (const auto &CFE : FX) {
1067 OS << " __attribute__((" << CFE.Effect.name();
1068 if (const Expr *E = CFE.Cond.getCondition()) {
1069 OS << '(';
1070 E->printPretty(OS, nullptr, Policy);
1071 OS << ')';
1072 }
1073 OS << "))";
1074 }
1075
1077 OS << " __attribute__((cfi_unchecked_callee))";
1078
1080 OS << " -> ";
1082 } else
1084}
1085
1086void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
1087 raw_ostream &OS) {
1088 if (!InsideCCAttribute) {
1089 switch (Info.getCC()) {
1091
1092
1093
1094
1095
1096
1097
1098 break;
1100 OS << " __attribute__((stdcall))";
1101 break;
1103 OS << " __attribute__((fastcall))";
1104 break;
1106 OS << " __attribute__((thiscall))";
1107 break;
1109 OS << " __attribute__((vectorcall))";
1110 break;
1112 OS << " __attribute__((pascal))";
1113 break;
1115 OS << " __attribute__((pcs(\"aapcs\")))";
1116 break;
1118 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1119 break;
1121 OS << " __attribute__((aarch64_vector_pcs))";
1122 break;
1124 OS << " __attribute__((aarch64_sve_pcs))";
1125 break;
1127 OS << " __attribute__((device_kernel))";
1128 break;
1130 OS << " __attribute__((intel_ocl_bicc))";
1131 break;
1133 OS << " __attribute__((ms_abi))";
1134 break;
1136 OS << " __attribute__((sysv_abi))";
1137 break;
1139 OS << " __attribute__((regcall))";
1140 break;
1142
1143 break;
1145 OS << " __attribute__((swiftcall))";
1146 break;
1148 OS << "__attribute__((swiftasynccall))";
1149 break;
1151 OS << " __attribute__((preserve_most))";
1152 break;
1154 OS << " __attribute__((preserve_all))";
1155 break;
1157 OS << " __attribute__((m68k_rtd))";
1158 break;
1160 OS << " __attribute__((preserve_none))";
1161 break;
1163 OS << "__attribute__((riscv_vector_cc))";
1164 break;
1165#define CC_VLS_CASE(ABI_VLEN) \
1166 case CC_RISCVVLSCall_##ABI_VLEN: \
1167 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \
1168 break;
1181#undef CC_VLS_CASE
1182 }
1183 }
1184
1186 OS << " __attribute__((noreturn))";
1188 OS << " __attribute__((cmse_nonsecure_call))";
1190 OS << " __attribute__((ns_returns_retained))";
1192 OS << " __attribute__((regparm ("
1195 OS << " __attribute__((no_caller_saved_registers))";
1197 OS << " __attribute__((nocf_check))";
1198}
1199
1200void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
1201 raw_ostream &OS) {
1202
1203 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1205 if (!PrevPHIsEmpty.get())
1206 OS << '(';
1207}
1208
1209void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
1210 raw_ostream &OS) {
1211
1212 if (!HasEmptyPlaceHolder)
1213 OS << ')';
1214 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1215
1216 OS << "()";
1217 printFunctionAfter(T->getExtInfo(), OS);
1219}
1220
1221void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1222
1223
1224
1225
1228
1231 spaceBeforePlaceHolder(OS);
1232}
1233
1234void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
1235 raw_ostream &OS) {
1236 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1237 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1238 OS << ' ';
1239 auto *D = T->getDecl();
1242 } else {
1243 T->getQualifier().print(OS, Policy);
1244 }
1246 spaceBeforePlaceHolder(OS);
1247}
1248
1249void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
1250 raw_ostream &OS) {}
1251
1252void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1253 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1254 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1255 OS << ' ';
1256 auto *D = T->getDecl();
1259 } else {
1260 T->getQualifier().print(OS, Policy);
1261 }
1263 spaceBeforePlaceHolder(OS);
1264}
1265
1266void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1267
1268void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1269 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1270 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1271 OS << ' ';
1272 auto *D = T->getDecl();
1275 } else {
1276 T->getQualifier().print(OS, Policy);
1277 }
1279 spaceBeforePlaceHolder(OS);
1280}
1281
1282void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
1283 raw_ostream &OS) {
1284 StringRef MacroName = T->getMacroIdentifier()->getName();
1285 OS << MacroName << " ";
1286
1287
1288
1289 printBefore(T->getModifiedType(), OS);
1290}
1291
1292void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
1293 raw_ostream &OS) {
1294 printAfter(T->getModifiedType(), OS);
1295}
1296
1297void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1298
1299void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1300 raw_ostream &OS) {
1301 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "
1302 : "typeof ");
1303 if (T->getUnderlyingExpr())
1304 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1305 spaceBeforePlaceHolder(OS);
1306}
1307
1308void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1309 raw_ostream &OS) {}
1310
1311void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1312 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("
1313 : "typeof(");
1314 print(T->getUnmodifiedType(), OS, StringRef());
1315 OS << ')';
1316 spaceBeforePlaceHolder(OS);
1317}
1318
1319void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1320
1321void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1322 OS << "decltype(";
1323 if (const Expr *E = T->getUnderlyingExpr()) {
1324 PrintingPolicy ExprPolicy = Policy;
1326 E->printPretty(OS, nullptr, ExprPolicy);
1327 }
1328 OS << ')';
1329 spaceBeforePlaceHolder(OS);
1330}
1331
1332void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1333 raw_ostream &OS) {
1334 if (T->hasSelectedType()) {
1335 OS << T->getSelectedType();
1336 } else {
1337 OS << T->getPattern() << "...[";
1338 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1339 OS << "]";
1340 }
1341 spaceBeforePlaceHolder(OS);
1342}
1343
1344void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1345 raw_ostream &OS) {}
1346
1347void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1348
1349void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
1350 raw_ostream &OS) {
1351 IncludeStrongLifetimeRAII Strong(Policy);
1352
1353 static llvm::DenseMap<int, const char *> Transformation = {{
1354#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1355 {UnaryTransformType::Enum, "__" #Trait},
1356#include "clang/Basic/TransformTypeTraits.def"
1357 }};
1358 OS << Transformation[T->getUTTKind()] << '(';
1359 print(T->getBaseType(), OS, StringRef());
1360 OS << ')';
1361 spaceBeforePlaceHolder(OS);
1362}
1363
1364void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
1365 raw_ostream &OS) {}
1366
1367void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1368
1369 if (->getDeducedType().isNull()) {
1370 printBefore(T->getDeducedType(), OS);
1371 } else {
1372 if (T->isConstrained()) {
1373
1374
1375 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1376 auto Args = T->getTypeConstraintArguments();
1377 if (!Args.empty())
1378 printTemplateArgumentList(
1379 OS, Args, Policy,
1380 T->getTypeConstraintConcept()->getTemplateParameters());
1381 OS << ' ';
1382 }
1383 switch (T->getKeyword()) {
1384 case AutoTypeKeyword::Auto: OS << "auto"; break;
1385 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;
1386 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;
1387 }
1388 spaceBeforePlaceHolder(OS);
1389 }
1390}
1391
1392void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1393
1394 if (->getDeducedType().isNull())
1395 printAfter(T->getDeducedType(), OS);
1396}
1397
1398void TypePrinter::printDeducedTemplateSpecializationBefore(
1399 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1401 T->getKeyword() != ElaboratedTypeKeyword::None)
1403
1405
1406
1407
1408
1409
1410
1411 ArrayRef Args;
1412 TemplateDecl *DeducedTD = nullptr;
1413 if (->getDeducedType().isNull()) {
1414 if (const auto *TST =
1415 dyn_cast(T->getDeducedType())) {
1416 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1417 true);
1418 Args = TST->template_arguments();
1419 } else {
1420
1423 DeducedTD = CD->getSpecializedTemplate();
1424 Args = CD->getTemplateArgs().asArray();
1425 }
1426
1427
1428
1429
1430
1431
1433 true)))
1435 }
1436
1437 {
1438 IncludeStrongLifetimeRAII Strong(Policy);
1439 Name.print(OS, Policy);
1440 }
1441 if (DeducedTD) {
1442 printTemplateArgumentList(OS, Args, Policy,
1444 }
1445
1446 spaceBeforePlaceHolder(OS);
1447}
1448
1449void TypePrinter::printDeducedTemplateSpecializationAfter(
1450 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
1451
1452 if (->getDeducedType().isNull())
1453 printAfter(T->getDeducedType(), OS);
1454}
1455
1456void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1457 IncludeStrongLifetimeRAII Strong(Policy);
1458
1459 OS << "_Atomic(";
1460 print(T->getValueType(), OS, StringRef());
1461 OS << ')';
1462 spaceBeforePlaceHolder(OS);
1463}
1464
1465void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1466
1467void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1468 IncludeStrongLifetimeRAII Strong(Policy);
1469
1470 if (T->isReadOnly())
1471 OS << "read_only ";
1472 else
1473 OS << "write_only ";
1474 OS << "pipe ";
1475 print(T->getElementType(), OS, StringRef());
1476 spaceBeforePlaceHolder(OS);
1477}
1478
1479void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1480
1481void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1482 if (T->isUnsigned())
1483 OS << "unsigned ";
1484 OS << "_BitInt(" << T->getNumBits() << ")";
1485 spaceBeforePlaceHolder(OS);
1486}
1487
1488void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1489
1490void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,
1491 raw_ostream &OS) {
1492 if (T->isUnsigned())
1493 OS << "unsigned ";
1494 OS << "_BitInt(";
1495 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1496 OS << ")";
1497 spaceBeforePlaceHolder(OS);
1498}
1499
1500void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,
1501 raw_ostream &OS) {}
1502
1503void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,
1504 raw_ostream &OS) {
1505 OS << T->getIdentifier()->getName();
1506 spaceBeforePlaceHolder(OS);
1507}
1508
1509void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,
1510 raw_ostream &OS) {}
1511
1512void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
1513 TagDecl *D = T->getDecl();
1514
1516 D->print(OS, Policy, Indentation);
1517 spaceBeforePlaceHolder(OS);
1518 return;
1519 }
1520
1521 bool HasKindDecoration = false;
1522
1525 HasKindDecoration = true;
1527 OS << ' ';
1528 }
1529 } else {
1530 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1531 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1532 OS << ' ';
1533 }
1534
1536 T->getQualifier().print(OS, Policy);
1538
1539
1540
1542 }
1543
1544 if (const IdentifierInfo *II = D->getIdentifier())
1547 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1548 OS << Typedef->getIdentifier()->getName();
1549 } else {
1550
1551
1553
1555 OS << "lambda";
1556 HasKindDecoration = true;
1558 OS << "anonymous";
1559 } else {
1560 OS << "unnamed";
1561 }
1562
1564
1565
1566
1567 if (!HasKindDecoration)
1569
1573 OS << " at ";
1575 llvm::SmallString<1024> WrittenFile(File);
1576 if (auto *Callbacks = Policy.Callbacks)
1577 WrittenFile = Callbacks->remapPath(File);
1578
1579
1580
1581 llvm::sys::path::Style Style =
1582 llvm::sys::path::is_absolute(WrittenFile)
1583 ? llvm::sys::path::Style::native
1585 ? llvm::sys::path::Style::windows_backslash
1586 : llvm::sys::path::Style::posix);
1587 llvm::sys::path::native(WrittenFile, Style);
1588 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1589 }
1590 }
1591
1593 }
1594
1595
1596
1597 if (auto *S = dyn_cast(D)) {
1598 const TemplateParameterList *TParams =
1599 S->getSpecializedTemplate()->getTemplateParameters();
1600 const ASTTemplateArgumentListInfo *TArgAsWritten =
1601 S->getTemplateArgsAsWritten();
1602 IncludeStrongLifetimeRAII Strong(Policy);
1604 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
1605 TParams);
1606 else
1607 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
1608 TParams);
1609 }
1610
1611 spaceBeforePlaceHolder(OS);
1612}
1613
1614void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1615
1617 for (const auto *PNA : T->getDecl()
1618 ->getMostRecentDecl()
1619 ->specific_attrs()) {
1620 if ((PNA->getTypedefType()->getAsCXXRecordDecl(),
1621 T->getDecl()))
1622 continue;
1623
1624 QualType T = PNA->getTypedefType();
1625 while (true) {
1626 if (auto *TT = dyn_cast(T))
1627 return printTypeSpec(TT->getDecl(), OS);
1628 if (auto *TST = dyn_cast(T))
1629 return printTemplateId(TST, OS, true);
1631 }
1632 }
1633 }
1634
1635 printTagType(T, OS);
1636}
1637
1638void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1639
1640void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1641 printTagType(T, OS);
1642}
1643
1644void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1645
1646void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
1647 raw_ostream &OS) {
1648 const ASTContext &Ctx = T->getDecl()->getASTContext();
1649 IncludeStrongLifetimeRAII Strong(Policy);
1650 T->getTemplateName(Ctx).print(OS, Policy);
1652 auto *Decl = T->getDecl();
1653
1654
1655 if (auto *RD = dyn_cast(Decl)) {
1656 printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),
1657 Policy,
1658 T->getTemplateDecl()->getTemplateParameters());
1659 } else {
1660 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
1661 assert(TD);
1662 printTemplateArgumentList(
1664 T->getTemplateDecl()->getTemplateParameters());
1665 }
1666 }
1667 spaceBeforePlaceHolder(OS);
1668}
1669
1670void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
1671 raw_ostream &OS) {}
1672
1673void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
1674 raw_ostream &OS) {
1675 TemplateTypeParmDecl *D = T->getDecl();
1678 TC->print(OS, Policy);
1679 OS << ' ';
1680 }
1681 OS << "auto";
1682 } else if (IdentifierInfo *Id = T->getIdentifier())
1684 : Id->getName());
1685 else
1686 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1687
1688 spaceBeforePlaceHolder(OS);
1689}
1690
1691void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
1692 raw_ostream &OS) {}
1693
1694void TypePrinter::printSubstTemplateTypeParmBefore(
1695 const SubstTemplateTypeParmType *T,
1696 raw_ostream &OS) {
1697 IncludeStrongLifetimeRAII Strong(Policy);
1698 printBefore(T->getReplacementType(), OS);
1699}
1700
1701void TypePrinter::printSubstTemplateTypeParmAfter(
1702 const SubstTemplateTypeParmType *T,
1703 raw_ostream &OS) {
1704 IncludeStrongLifetimeRAII Strong(Policy);
1705 printAfter(T->getReplacementType(), OS);
1706}
1707
1708void TypePrinter::printSubstBuiltinTemplatePackBefore(
1709 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {
1710 IncludeStrongLifetimeRAII Strong(Policy);
1711 OS << "type-pack";
1712}
1713
1714void TypePrinter::printSubstBuiltinTemplatePackAfter(
1715 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}
1716
1717void TypePrinter::printSubstTemplateTypeParmPackBefore(
1718 const SubstTemplateTypeParmPackType *T,
1719 raw_ostream &OS) {
1720 IncludeStrongLifetimeRAII Strong(Policy);
1721 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {
1724 TC->print(OS, Policy);
1725 OS << ' ';
1726 }
1727 OS << "auto";
1728 } else if (IdentifierInfo *Id = D->getIdentifier())
1730 : Id->getName());
1731 else
1733
1734 spaceBeforePlaceHolder(OS);
1735 }
1736}
1737
1738void TypePrinter::printSubstTemplateTypeParmPackAfter(
1739 const SubstTemplateTypeParmPackType *T,
1740 raw_ostream &OS) {
1741 IncludeStrongLifetimeRAII Strong(Policy);
1742}
1743
1744void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
1745 raw_ostream &OS, bool FullyQualify) {
1746 IncludeStrongLifetimeRAII Strong(Policy);
1747
1749 K != ElaboratedTypeKeyword::None)
1750 OS << TypeWithKeyword::getKeywordName(K) << ' ';
1751
1752 TemplateDecl *TD =
1753 T->getTemplateName().getAsTemplateDecl(true);
1754
1755 if (FullyQualify && TD) {
1758
1760 } else {
1761 T->getTemplateName().print(OS, Policy,
1763 ? TemplateName::Qualified::AsWritten
1764 : TemplateName::Qualified::None);
1765 }
1766
1767 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1769 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);
1770 spaceBeforePlaceHolder(OS);
1771}
1772
1773void TypePrinter::printTemplateSpecializationBefore(
1774 const TemplateSpecializationType *T,
1775 raw_ostream &OS) {
1777}
1778
1779void TypePrinter::printTemplateSpecializationAfter(
1780 const TemplateSpecializationType *T,
1781 raw_ostream &OS) {}
1782
1783void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1784 if (!HasEmptyPlaceHolder && (T->getInnerType())) {
1785 printBefore(T->getInnerType(), OS);
1786 OS << '(';
1787 } else
1788 printBefore(T->getInnerType(), OS);
1789}
1790
1791void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1792 if (!HasEmptyPlaceHolder && (T->getInnerType())) {
1793 OS << ')';
1794 printAfter(T->getInnerType(), OS);
1795 } else
1796 printAfter(T->getInnerType(), OS);
1797}
1798
1799void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1800 raw_ostream &OS) {
1801 OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1802 if (T->getKeyword() != ElaboratedTypeKeyword::None)
1803 OS << " ";
1804 T->getQualifier().print(OS, Policy);
1805 OS << T->getIdentifier()->getName();
1806 spaceBeforePlaceHolder(OS);
1807}
1808
1809void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1810 raw_ostream &OS) {}
1811
1812void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1813 raw_ostream &OS) {
1814 printBefore(T->getPattern(), OS);
1815}
1816
1817void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1818 raw_ostream &OS) {
1819 printAfter(T->getPattern(), OS);
1820 OS << "...";
1821}
1822
1824 raw_ostream &OS,
1826 OS << ' ';
1827 if (T->isCountInBytes() && T->isOrNull())
1828 OS << "__sized_by_or_null(";
1829 else if (T->isCountInBytes())
1830 OS << "__sized_by(";
1831 else if (T->isOrNull())
1832 OS << "__counted_by_or_null(";
1833 else
1834 OS << "__counted_by(";
1835 if (T->getCountExpr())
1836 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1837 OS << ')';
1838}
1839
1840void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,
1841 raw_ostream &OS) {
1842 printBefore(T->desugar(), OS);
1845}
1846
1847void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,
1848 raw_ostream &OS) {
1849 printAfter(T->desugar(), OS);
1852}
1853
1854void TypePrinter::printAttributedBefore(const AttributedType *T,
1855 raw_ostream &OS) {
1856
1857
1858
1859 if (T->getAttrKind() == attr::ObjCGC ||
1860 T->getAttrKind() == attr::ObjCOwnership)
1861 return printBefore(T->getEquivalentType(), OS);
1862
1863 if (T->getAttrKind() == attr::ObjCKindOf)
1864 OS << "__kindof ";
1865
1866 if (T->getAttrKind() == attr::PreserveNone) {
1867 OS << "__attribute__((preserve_none)) ";
1868 spaceBeforePlaceHolder(OS);
1869 } else if (T->getAttrKind() == attr::PreserveMost) {
1870 OS << "__attribute__((preserve_most)) ";
1871 spaceBeforePlaceHolder(OS);
1872 } else if (T->getAttrKind() == attr::PreserveAll) {
1873 OS << "__attribute__((preserve_all)) ";
1874 spaceBeforePlaceHolder(OS);
1875 }
1876
1877 if (T->getAttrKind() == attr::AddressSpace)
1878 printBefore(T->getEquivalentType(), OS);
1879 else
1880 printBefore(T->getModifiedType(), OS);
1881
1882 if (T->isMSTypeSpec()) {
1883 switch (T->getAttrKind()) {
1884 default: return;
1885 case attr::Ptr32: OS << " __ptr32"; break;
1886 case attr::Ptr64: OS << " __ptr64"; break;
1887 case attr::SPtr: OS << " __sptr"; break;
1888 case attr::UPtr: OS << " __uptr"; break;
1889 }
1890 spaceBeforePlaceHolder(OS);
1891 }
1892
1893 if (T->isWebAssemblyFuncrefSpec())
1894 OS << "__funcref";
1895
1896
1897 if (T->getImmediateNullability()) {
1898 if (T->getAttrKind() == attr::TypeNonNull)
1899 OS << " _Nonnull";
1900 else if (T->getAttrKind() == attr::TypeNullable)
1901 OS << " _Nullable";
1902 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1903 OS << " _Null_unspecified";
1904 else if (T->getAttrKind() == attr::TypeNullableResult)
1905 OS << " _Nullable_result";
1906 else
1907 llvm_unreachable("unhandled nullability");
1908 spaceBeforePlaceHolder(OS);
1909 }
1910}
1911
1912void TypePrinter::printAttributedAfter(const AttributedType *T,
1913 raw_ostream &OS) {
1914
1915
1916
1917 if (T->getAttrKind() == attr::ObjCGC ||
1918 T->getAttrKind() == attr::ObjCOwnership)
1919 return printAfter(T->getEquivalentType(), OS);
1920
1921
1922
1923 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1924
1925 printAfter(T->getModifiedType(), OS);
1926
1927
1928
1929 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1930 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1931 return;
1932
1933
1934 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1935 return;
1936
1937
1938 if (T->getAttrKind() == attr::NSReturnsRetained &&
1939 ->getEquivalentType()->castAs()
1940 ->getExtInfo().getProducesResult())
1941 return;
1942
1943 if (T->getAttrKind() == attr::LifetimeBound) {
1944 OS << " [[clang::lifetimebound]]";
1945 return;
1946 }
1947 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1948 OS << " [[clang::lifetime_capture_by(";
1949 if (auto *attr = dyn_cast_or_null(T->getAttr()))
1950 llvm::interleaveComma(attr->getArgIdents(), OS,
1951 [&](auto it) { OS << it->getName(); });
1952 OS << ")]]";
1953 return;
1954 }
1955
1956
1957
1958
1959 if (T->getAttrKind() == attr::AddressSpace)
1960 return;
1961
1962 if (T->getAttrKind() == attr::AnnotateType) {
1963
1964
1965
1966
1967 OS << " [[clang::annotate_type(...)]]";
1968 return;
1969 }
1970
1971 if (T->getAttrKind() == attr::ArmStreaming) {
1972 OS << "__arm_streaming";
1973 return;
1974 }
1975 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1976 OS << "__arm_streaming_compatible";
1977 return;
1978 }
1979
1980 if (T->getAttrKind() == attr::SwiftAttr) {
1981 if (auto *swiftAttr = dyn_cast_or_null(T->getAttr())) {
1982 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1983 << "\")))";
1984 }
1985 return;
1986 }
1987
1988 if (T->getAttrKind() == attr::PreserveAll ||
1989 T->getAttrKind() == attr::PreserveMost ||
1990 T->getAttrKind() == attr::PreserveNone) {
1991
1992 return;
1993 }
1994
1995 OS << " __attribute__((";
1996 switch (T->getAttrKind()) {
1997#define TYPE_ATTR(NAME)
1998#define DECL_OR_TYPE_ATTR(NAME)
1999#define ATTR(NAME) case attr::NAME:
2000#include "clang/Basic/AttrList.inc"
2001 llvm_unreachable("non-type attribute attached to type");
2002
2003 case attr::BTFTypeTag:
2004 llvm_unreachable("BTFTypeTag attribute handled separately");
2005
2006 case attr::HLSLResourceClass:
2007 case attr::HLSLROV:
2008 case attr::HLSLRawBuffer:
2009 case attr::HLSLContainedType:
2010 case attr::HLSLIsCounter:
2011 llvm_unreachable("HLSL resource type attributes handled separately");
2012
2013 case attr::OpenCLPrivateAddressSpace:
2014 case attr::OpenCLGlobalAddressSpace:
2015 case attr::OpenCLGlobalDeviceAddressSpace:
2016 case attr::OpenCLGlobalHostAddressSpace:
2017 case attr::OpenCLLocalAddressSpace:
2018 case attr::OpenCLConstantAddressSpace:
2019 case attr::OpenCLGenericAddressSpace:
2020 case attr::HLSLGroupSharedAddressSpace:
2021
2022
2023 break;
2024
2025 case attr::CountedBy:
2026 case attr::CountedByOrNull:
2027 case attr::SizedBy:
2028 case attr::SizedByOrNull:
2029 case attr::LifetimeBound:
2030 case attr::LifetimeCaptureBy:
2031 case attr::TypeNonNull:
2032 case attr::TypeNullable:
2033 case attr::TypeNullableResult:
2034 case attr::TypeNullUnspecified:
2035 case attr::ObjCGC:
2036 case attr::ObjCInertUnsafeUnretained:
2037 case attr::ObjCKindOf:
2038 case attr::ObjCOwnership:
2039 case attr::Ptr32:
2040 case attr::Ptr64:
2041 case attr::SPtr:
2042 case attr::UPtr:
2043 case attr::PointerAuth:
2044 case attr::AddressSpace:
2045 case attr::CmseNSCall:
2046 case attr::AnnotateType:
2047 case attr::WebAssemblyFuncref:
2048 case attr::ArmAgnostic:
2049 case attr::ArmStreaming:
2050 case attr::ArmStreamingCompatible:
2051 case attr::ArmIn:
2052 case attr::ArmOut:
2053 case attr::ArmInOut:
2054 case attr::ArmPreserves:
2055 case attr::NonBlocking:
2056 case attr::NonAllocating:
2057 case attr::Blocking:
2058 case attr::Allocating:
2059 case attr::SwiftAttr:
2060 case attr::PreserveAll:
2061 case attr::PreserveMost:
2062 case attr::PreserveNone:
2063 llvm_unreachable("This attribute should have been handled already");
2064
2065 case attr::NSReturnsRetained:
2066 OS << "ns_returns_retained";
2067 break;
2068
2069
2070
2071 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2072 case attr::CDecl: OS << "cdecl"; break;
2073 case attr::FastCall: OS << "fastcall"; break;
2074 case attr::StdCall: OS << "stdcall"; break;
2075 case attr::ThisCall: OS << "thiscall"; break;
2076 case attr::SwiftCall: OS << "swiftcall"; break;
2077 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2078 case attr::VectorCall: OS << "vectorcall"; break;
2079 case attr::Pascal: OS << "pascal"; break;
2080 case attr::MSABI: OS << "ms_abi"; break;
2081 case attr::SysVABI: OS << "sysv_abi"; break;
2082 case attr::RegCall: OS << "regcall"; break;
2083 case attr::Pcs: {
2084 OS << "pcs(";
2085 QualType t = T->getEquivalentType();
2088 OS << (t->castAs()->getCallConv() == CC_AAPCS ?
2089 "\"aapcs\"" : "\"aapcs-vfp\"");
2090 OS << ')';
2091 break;
2092 }
2093 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2094 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2095 case attr::IntelOclBicc:
2096 OS << "inteloclbicc";
2097 break;
2098 case attr::M68kRTD:
2099 OS << "m68k_rtd";
2100 break;
2101 case attr::RISCVVectorCC:
2102 OS << "riscv_vector_cc";
2103 break;
2104 case attr::RISCVVLSCC:
2105 OS << "riscv_vls_cc";
2106 break;
2107 case attr::NoDeref:
2108 OS << "noderef";
2109 break;
2110 case attr::CFIUncheckedCallee:
2111 OS << "cfi_unchecked_callee";
2112 break;
2113 case attr::AcquireHandle:
2114 OS << "acquire_handle";
2115 break;
2116 case attr::ArmMveStrictPolymorphism:
2117 OS << "__clang_arm_mve_strict_polymorphism";
2118 break;
2119 case attr::ExtVectorType:
2120 OS << "ext_vector_type";
2121 break;
2122 case attr::CFISalt:
2124 break;
2125 }
2126 OS << "))";
2127}
2128
2129void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
2130 raw_ostream &OS) {
2131 printBefore(T->getWrappedType(), OS);
2132 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2133}
2134
2135void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,
2136 raw_ostream &OS) {
2137 printAfter(T->getWrappedType(), OS);
2138}
2139
2140void TypePrinter::printHLSLAttributedResourceBefore(
2141 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2142 printBefore(T->getWrappedType(), OS);
2143}
2144
2145void TypePrinter::printHLSLAttributedResourceAfter(
2146 const HLSLAttributedResourceType *T, raw_ostream &OS) {
2147 printAfter(T->getWrappedType(), OS);
2148 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
2149 OS << " [[hlsl::resource_class("
2150 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2151 << ")]]";
2152 if (Attrs.IsROV)
2153 OS << " [[hlsl::is_rov]]";
2154 if (Attrs.RawBuffer)
2155 OS << " [[hlsl::raw_buffer]]";
2156 if (Attrs.IsCounter)
2157 OS << " [[hlsl::is_counter]]";
2158
2159 QualType ContainedTy = T->getContainedType();
2160 if (!ContainedTy.isNull()) {
2161 OS << " [[hlsl::contained_type(";
2162 printBefore(ContainedTy, OS);
2163 printAfter(ContainedTy, OS);
2164 OS << ")]]";
2165 }
2166}
2167
2168void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,
2169 raw_ostream &OS) {
2170 OS << "__hlsl_spirv_type<" << T->getOpcode();
2171
2172 OS << ", " << T->getSize();
2173 OS << ", " << T->getAlignment();
2174
2175 for (auto &Operand : T->getOperands()) {
2176 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
2177
2178 OS << ", ";
2179 switch (Operand.getKind()) {
2180 case SpirvOperandKind::ConstantId: {
2181 QualType ConstantType = Operand.getResultType();
2182 OS << "vk::integral_constant<";
2183 printBefore(ConstantType, OS);
2184 printAfter(ConstantType, OS);
2185 OS << ", ";
2187 OS << ">";
2188 break;
2189 }
2190 case SpirvOperandKind::Literal:
2191 OS << "vk::Literal<vk::integral_constant<uint, ";
2193 OS << ">>";
2194 break;
2195 case SpirvOperandKind::TypeId: {
2196 QualType Type = Operand.getResultType();
2197 printBefore(Type, OS);
2198 printAfter(Type, OS);
2199 break;
2200 }
2201 default:
2202 llvm_unreachable("Invalid SpirvOperand kind!");
2203 break;
2204 }
2205 }
2206
2207 OS << ">";
2208}
2209
2210void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,
2211 raw_ostream &OS) {
2212
2213}
2214
2215void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2216 raw_ostream &OS) {
2217 OS << T->getDecl()->getName();
2218 spaceBeforePlaceHolder(OS);
2219}
2220
2221void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2222 raw_ostream &OS) {}
2223
2224void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2225 raw_ostream &OS) {
2226 OS << T->getDecl()->getName();
2227 if (->qual_empty()) {
2228 bool isFirst = true;
2229 OS << '<';
2230 for (const auto *I : T->quals()) {
2231 if (isFirst)
2232 isFirst = false;
2233 else
2234 OS << ',';
2235 OS << I->getName();
2236 }
2237 OS << '>';
2238 }
2239
2240 spaceBeforePlaceHolder(OS);
2241}
2242
2243void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2244 raw_ostream &OS) {}
2245
2246void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2247 raw_ostream &OS) {
2248 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2249 ->isKindOfTypeAsWritten())
2250 return printBefore(T->getBaseType(), OS);
2251
2252 if (T->isKindOfTypeAsWritten())
2253 OS << "__kindof ";
2254
2255 print(T->getBaseType(), OS, StringRef());
2256
2257 if (T->isSpecializedAsWritten()) {
2258 bool isFirst = true;
2259 OS << '<';
2260 for (auto typeArg : T->getTypeArgsAsWritten()) {
2261 if (isFirst)
2262 isFirst = false;
2263 else
2264 OS << ",";
2265
2266 print(typeArg, OS, StringRef());
2267 }
2268 OS << '>';
2269 }
2270
2271 if (->qual_empty()) {
2272 bool isFirst = true;
2273 OS << '<';
2274 for (const auto *I : T->quals()) {
2275 if (isFirst)
2276 isFirst = false;
2277 else
2278 OS << ',';
2279 OS << I->getName();
2280 }
2281 OS << '>';
2282 }
2283
2284 spaceBeforePlaceHolder(OS);
2285}
2286
2287void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2288 raw_ostream &OS) {
2289 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2290 ->isKindOfTypeAsWritten())
2291 return printAfter(T->getBaseType(), OS);
2292}
2293
2294void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
2295 raw_ostream &OS) {
2297
2298
2301 if (HasEmptyPlaceHolder)
2302 OS << ' ';
2303 OS << '*';
2304 }
2305}
2306
2307void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
2308 raw_ostream &OS) {}
2309
2310static
2312
2316
2318 llvm::raw_ostream &OS, bool IncludeType) {
2319 A.print(PP, OS, IncludeType);
2320}
2321
2324 bool IncludeType) {
2329}
2330
2332 TemplateArgument Pattern,
2333 ArrayRef Args,
2334 unsigned Depth);
2335
2339 return true;
2340
2341
2342 if (auto *TTPT = Pattern->getAsCanonical()) {
2343 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2346 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2348 }
2349 return false;
2350 }
2351
2352
2353
2354
2358 if (TQual != PatQual)
2359 return false;
2360
2361
2362 {
2363 QualType TPointee = T->getPointeeType();
2365 if (!TPointee.isNull() && !PPointee.isNull())
2366 return T->getTypeClass() == Pattern->getTypeClass() &&
2368 }
2369
2370
2371 if (auto *PTST =
2375 if (auto *TTST = T->getAs()) {
2376 Template = TTST->getTemplateName();
2377 TemplateArgs = TTST->template_arguments();
2378 } else if (auto *CTSD = dyn_cast_or_null(
2379 T->getAsCXXRecordDecl())) {
2381 TemplateArgs = CTSD->getTemplateArgs().asArray();
2382 } else {
2383 return false;
2384 }
2385
2387 Args, Depth))
2388 return false;
2389 if (TemplateArgs.size() != PTST->template_arguments().size())
2390 return false;
2391 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2393 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2394 return false;
2395 return true;
2396 }
2397
2398
2399 return false;
2400}
2401
2402
2403
2408 return false;
2409
2410
2414 return false;
2415
2419
2423 return false;
2424
2427 }
2428
2429 return false;
2430}
2431
2435 unsigned Depth) {
2439 return true;
2440
2442 if (auto *DRE =
2444 if (auto *NTTP = dyn_cast(DRE->getDecl()))
2445 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2446 Args[NTTP->getIndex()].structurallyEquals(Arg);
2447 }
2448 }
2449
2451 return true;
2452
2454 return false;
2455
2458 Depth);
2459
2462 if (auto *TTPD = dyn_cast_or_null(PatTD))
2463 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2466 }
2467
2468
2469 return false;
2470}
2471
2472bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
2473 const NamedDecl *Param,
2474 ArrayRef Args,
2475 unsigned Depth) {
2476
2478 return true;
2479
2480 if (auto *TTPD = dyn_cast(Param)) {
2481 return TTPD->hasDefaultArgument() &&
2483 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2484 } else if (auto *TTPD = dyn_cast(Param)) {
2485 return TTPD->hasDefaultArgument() &&
2487 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2488 } else if (auto *NTTPD = dyn_cast(Param)) {
2489 return NTTPD->hasDefaultArgument() &&
2491 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2492 Depth);
2493 }
2494 return false;
2495}
2496
2497template
2498static void
2501
2503 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {
2505 for (const TA &A : Args)
2507 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
2508 Args = Args.drop_back();
2509 }
2510
2511 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2512 if (!IsPack)
2513 OS << '<';
2514
2515 bool NeedSpace = false;
2516 bool FirstArg = true;
2517 for (const auto &Arg : Args) {
2518
2520 llvm::raw_svector_ostream ArgOS(Buf);
2523 if (Argument.pack_size() && !FirstArg)
2524 OS << Comma;
2526 true, ParmIndex);
2527 } else {
2528 if (!FirstArg)
2529 OS << Comma;
2530
2533 Policy, TPL, ParmIndex));
2534 }
2535 StringRef ArgString = ArgOS.str();
2536
2537
2538
2539
2540 if (FirstArg && ArgString.starts_with(":"))
2541 OS << ' ';
2542
2543 OS << ArgString;
2544
2545
2546
2547 if (!ArgString.empty()) {
2549 FirstArg = false;
2550 }
2551
2552
2553 if (!IsPack)
2554 ParmIndex++;
2555 }
2556
2557 if (!IsPack) {
2558 if (NeedSpace)
2559 OS << ' ';
2560 OS << '>';
2561 }
2562}
2563
2564void clang::printTemplateArgumentList(raw_ostream &OS,
2565 const TemplateArgumentListInfo &Args,
2566 const PrintingPolicy &Policy,
2567 const TemplateParameterList *TPL) {
2568 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);
2569}
2570
2571void clang::printTemplateArgumentList(raw_ostream &OS,
2572 ArrayRef Args,
2573 const PrintingPolicy &Policy,
2574 const TemplateParameterList *TPL) {
2575 PrintingPolicy InnerPolicy = Policy;
2577 printTo(OS, Args, InnerPolicy, TPL, false, 0);
2578}
2579
2580void clang::printTemplateArgumentList(raw_ostream &OS,
2581 ArrayRef Args,
2582 const PrintingPolicy &Policy,
2583 const TemplateParameterList *TPL) {
2584 PrintingPolicy InnerPolicy = Policy;
2586 printTo(OS, Args, InnerPolicy, TPL, false, 0);
2587}
2588
2593
2596 llvm::raw_svector_ostream StrOS(Buf);
2597 print(StrOS, P);
2598 return StrOS.str().str();
2599}
2600
2604
2608 return;
2609
2610 OS << "__ptrauth(";
2614}
2615
2620
2621
2622
2623
2626 llvm::raw_svector_ostream StrOS(Buf);
2627 print(StrOS, Policy);
2628 return std::string(StrOS.str());
2629}
2630
2633 return false;
2634
2636 return false;
2637
2639 return false;
2640
2643 return false;
2644
2646 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))
2647 return false;
2648
2649 return true;
2650}
2651
2653 switch (AS) {
2655 return "";
2658 return "__global";
2661 return "__local";
2664 return "__private";
2666 return "__constant";
2668 return "__generic";
2671 return "__global_device";
2674 return "__global_host";
2676 return "__device__";
2678 return "__constant__";
2680 return "__shared__";
2682 return "__sptr __ptr32";
2684 return "__uptr __ptr32";
2686 return "__ptr64";
2688 return "groupshared";
2690 return "hlsl_constant";
2692 return "hlsl_private";
2694 return "hlsl_device";
2696 return "hlsl_input";
2698 return "__funcref";
2699 default:
2701 }
2702}
2703
2704
2705
2706
2708 bool appendSpaceIfNonEmpty) const {
2709 bool addSpace = false;
2710
2712 if (quals) {
2714 addSpace = true;
2715 }
2717 if (addSpace)
2718 OS << ' ';
2719 OS << "__unaligned";
2720 addSpace = true;
2721 }
2723 if (!ASStr.empty()) {
2724 if (addSpace)
2725 OS << ' ';
2726 addSpace = true;
2727
2729 OS << "__attribute__((address_space(" << ASStr << ")))";
2730 else
2731 OS << ASStr;
2732 }
2733
2735 if (addSpace)
2736 OS << ' ';
2737 addSpace = true;
2739 OS << "__weak";
2740 else
2741 OS << "__strong";
2742 }
2745 if (addSpace)
2746 OS << ' ';
2747 addSpace = true;
2748 }
2749
2750 switch (lifetime) {
2755 OS << "__strong";
2756 break;
2757
2760 }
2761 }
2762
2764 if (addSpace)
2765 OS << ' ';
2766 addSpace = true;
2767
2768 PointerAuth.print(OS, Policy);
2769 }
2770
2771 if (appendSpaceIfNonEmpty && addSpace)
2772 OS << ' ';
2773}
2774
2778
2780 std::string S;
2782 return S;
2783}
2784
2787 std::string buffer;
2789 return buffer;
2790}
2791
2793 const Twine &PlaceHolder, unsigned Indentation) const {
2795 Indentation);
2796}
2797
2800 const Twine &PlaceHolder, unsigned Indentation) {
2802 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2803
2804 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2805}
2806
2812
2814 std::string &buffer,
2817 llvm::raw_svector_ostream StrOS(Buf);
2818 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2819 std::string str = std::string(StrOS.str());
2820 buffer.swap(str);
2821}
2822
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the clang::attr::Kind enum.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)
#define CC_VLS_CASE(ABI_VLEN)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
static void printHLSLMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T, raw_ostream &OS)
Definition TypePrinter.cpp:851
static void printTo(raw_ostream &OS, ArrayRef< TA > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex)
Definition TypePrinter.cpp:2499
static const TemplateArgument & getArgument(const TemplateArgument &A)
Definition TypePrinter.cpp:2311
static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
Definition TypePrinter.cpp:2336
static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, llvm::raw_ostream &OS, bool IncludeType)
Definition TypePrinter.cpp:2317
static QualType skipTopLevelReferences(QualType T)
Definition TypePrinter.cpp:439
static void printClangMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T, raw_ostream &OS)
Definition TypePrinter.cpp:863
static void printDims(const ConstantMatrixType *T, raw_ostream &OS)
Definition TypePrinter.cpp:847
static void printHLSLMatrixAfter(const ConstantMatrixType *T, raw_ostream &OS)
Definition TypePrinter.cpp:857
static void printCountAttributedImpl(const CountAttributedType *T, raw_ostream &OS, const PrintingPolicy &Policy)
Definition TypePrinter.cpp:1823
static SplitQualType splitAccordingToPolicy(QualType QT, const PrintingPolicy &Policy)
Definition TypePrinter.cpp:176
static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg, TemplateArgument Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
Definition TypePrinter.cpp:2432
static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)
Definition TypePrinter.cpp:149
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 ...
Definition TypePrinter.cpp:2404
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Represents a concrete matrix type with constant number of rows and columns.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
SourceLocation getLocation() const
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
This represents one expression.
bool isIntegerConstantExpr(const ASTContext &Ctx) const
bool isValueDependent() const
Determines whether the value of this expression depends on.
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...
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
Definition TypePrinter.cpp:909
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Qualifiers getMethodQuals() const
QualType getParamType(unsigned i) const
FunctionEffectsRef getFunctionEffects() const
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
bool hasCFIUncheckedCallee() const
unsigned getNumExceptions() const
Return the number of types in the exception specification.
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
bool isVariadic() const
Whether this function prototype is variadic.
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
CallingConv getCC() const
bool getCmseNSCall() const
bool getNoCfCheck() const
unsigned getRegParm() const
bool getNoCallerSavedRegs() const
bool getProducesResult() const
ExtInfo getExtInfo() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
void printNestedNameSpecifier(raw_ostream &OS) const
Print only the nested name specifier part of a fully-qualified name, including the '::' at the end.
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
Definition TypePrinter.cpp:2605
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
Definition TypePrinter.cpp:2601
std::string getAsString() const
Definition TypePrinter.cpp:2589
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition TypePrinter.cpp:2792
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
Definition TypePrinter.cpp:2807
QualType getCanonicalType() const
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
std::string getAsString() const
Definition TypePrinter.cpp:2775
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
Definition TypePrinter.cpp:2707
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
Definition TypePrinter.cpp:2631
PointerAuthQualifier getPointerAuth() const
ObjCLifetime getObjCLifetime() const
std::string getAsString() const
Definition TypePrinter.cpp:2616
LangAS getAddressSpace() const
static std::string getAddrSpaceAsString(LangAS AS)
Definition TypePrinter.cpp:2652
Base for LValueReferenceType and RValueReferenceType.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
StringRef getKindName() const
TypedefNameDecl * getTypedefNameForAnonDecl() const
ArrayRef< TemplateArgumentLoc > arguments() const
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
TypeSourceInfo * getTypeSourceInfo() const
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
ArgKind
The kind of template argument we're storing.
@ Template
The template argument is a template name that was provided for a template template parameter.
@ Pack
The template argument is actually a parameter pack.
@ Type
The template argument is a type.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Stores a list of template parameters for a TemplateDecl and its derived classes.
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
unsigned getIndex() const
Retrieve the index of the template parameter.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
unsigned getDepth() const
Retrieve the depth of the template parameter.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
QualType getLocallyUnqualifiedSingleStepDesugaredType() const
Pull a single level of sugar off of this locally-unqualified type.
const T * castAs() const
Member-template castAs.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCIdType() const
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
bool isFunctionType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs'.
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)
llvm::StringRef getParameterABISpelling(ParameterABI kind)
Definition TypePrinter.cpp:954
bool isTargetAddressSpace(LangAS AS)
@ RQ_None
No ref-qualifier was provided.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
unsigned toTargetAddressSpace(LangAS AS)
ParameterABI
Kinds of parameter ABI.
@ SwiftAsyncContext
This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...
@ SwiftErrorResult
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
@ Ordinary
This parameter uses ordinary ABI rules for its type.
@ SwiftIndirectResult
This parameter (which must have pointer type) is a Swift indirect result parameter.
@ SwiftContext
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.
const FunctionProtoType * T
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
@ Template
We are parsing a template declaration.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Keyword
The name has been typo-corrected to a keyword.
@ Type
The name was classified as a type.
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.
llvm::StringRef getAsString(SyncScope S)
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
U cast(CodeGen::Address addr)
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
ArrayRef< TemplateArgumentLoc > arguments() const
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
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 >' rather than 'a<b>'.
unsigned PrintInjectedClassNameWithArguments
Whether to print an InjectedClassNameType with template arguments or as written.
unsigned UseVoidForZeroParams
Whether we should use '(void)' rather than '()' for a function prototype with zero parameters.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration.
unsigned SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
unsigned UsePreferredNames
Whether to use C++ template preferred_name attributes when printing templates.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned Restrict
Whether we can use 'restrict' rather than '__restrict'.
unsigned UseHLSLTypes
Whether or not we're printing known HLSL code and should print HLSL sugared types when possible.
unsigned SuppressScope
Suppresses printing of scope specifiers.
const PrintingCallbacks * Callbacks
Callbacks to use to allow the behavior of printing to be customized.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
const Type * Ty
The locally-unqualified type.
Qualifiers Quals
The local qualifiers.