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 {
55 bool Old;
56
57public:
58 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
59 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
62 }
63
65};
66
67class ParamPolicyRAII {
69 bool Old;
70
71public:
73 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
75 }
76
78};
79
80class DefaultTemplateArgsPolicyRAII {
82 bool Old;
83
84public:
85 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)
86 : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {
88 }
89
91};
92
93class ElaboratedTypePolicyRAII {
95 bool SuppressTagKeyword;
96 bool SuppressScope;
97
98public:
99 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
104 }
105
106 ~ElaboratedTypePolicyRAII() {
109 }
110};
111
112class TypePrinter {
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
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);
130 bool FullyQualify);
131
132 void printBefore(QualType T, raw_ostream &OS);
133 void printAfter(QualType T, raw_ostream &OS);
134 void AppendScope(DeclContext *DC, raw_ostream &OS,
136 void printTag(TagDecl *T, raw_ostream &OS);
138#define ABSTRACT_TYPE(CLASS, PARENT)
139#define TYPE(CLASS, PARENT) \
140 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
141 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
142#include "clang/AST/TypeNodes.inc"
143
144private:
145 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
146 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
147};
148
149}
150
152 bool HasRestrictKeyword) {
153 bool appendSpace = false;
155 OS << "const";
156 appendSpace = true;
157 }
159 if (appendSpace) OS << ' ';
160 OS << "volatile";
161 appendSpace = true;
162 }
164 if (appendSpace) OS << ' ';
165 if (HasRestrictKeyword) {
166 OS << "restrict";
167 } else {
168 OS << "__restrict";
169 }
170 }
171}
172
173void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
174 if (!HasEmptyPlaceHolder)
175 OS << ' ';
176}
177
182 return QT.split();
183}
184
185void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
187 print(split.Ty, split.Quals, OS, PlaceHolder);
188}
189
190void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
191 StringRef PlaceHolder) {
192 if () {
193 OS << "NULL TYPE";
194 return;
195 }
196
197 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
198
199 printBefore(T, Quals, OS);
200 OS << PlaceHolder;
201 printAfter(T, Quals, OS);
202}
203
204bool TypePrinter::canPrefixQualifiers(const Type *T,
205 bool &NeedARCStrongQualifier) {
206
207
208
209
210
211 bool CanPrefixQualifiers = false;
212 NeedARCStrongQualifier = false;
213 const Type *UnderlyingType = T;
214 if (const auto *AT = dyn_cast(T))
215 UnderlyingType = AT->desugar().getTypePtr();
216 if (const auto *Subst = dyn_cast(T))
217 UnderlyingType = Subst->getReplacementType().getTypePtr();
219
220 switch (TC) {
221 case Type::Auto:
222 case Type::Builtin:
223 case Type::Complex:
224 case Type::UnresolvedUsing:
225 case Type::Using:
226 case Type::Typedef:
227 case Type::TypeOfExpr:
228 case Type::TypeOf:
229 case Type::Decltype:
230 case Type::UnaryTransform:
231 case Type::Record:
232 case Type::Enum:
233 case Type::Elaborated:
234 case Type::TemplateTypeParm:
235 case Type::SubstTemplateTypeParmPack:
236 case Type::DeducedTemplateSpecialization:
237 case Type::TemplateSpecialization:
238 case Type::InjectedClassName:
239 case Type::DependentName:
240 case Type::DependentTemplateSpecialization:
241 case Type::ObjCObject:
242 case Type::ObjCTypeParam:
243 case Type::ObjCInterface:
244 case Type::Atomic:
245 case Type::Pipe:
246 case Type::BitInt:
247 case Type::DependentBitInt:
248 case Type::BTFTagAttributed:
249 case Type::HLSLAttributedResource:
250 CanPrefixQualifiers = true;
251 break;
252
253 case Type::ObjCObjectPointer:
256 break;
257
258 case Type::VariableArray:
259 case Type::DependentSizedArray:
260 NeedARCStrongQualifier = true;
261 [[fallthrough]];
262
263 case Type::ConstantArray:
264 case Type::IncompleteArray:
265 return canPrefixQualifiers(
266 cast(UnderlyingType)->getElementType().getTypePtr(),
267 NeedARCStrongQualifier);
268
269 case Type::Adjusted:
270 case Type::Decayed:
271 case Type::ArrayParameter:
272 case Type::Pointer:
273 case Type::BlockPointer:
274 case Type::LValueReference:
275 case Type::RValueReference:
276 case Type::MemberPointer:
277 case Type::DependentAddressSpace:
278 case Type::DependentVector:
279 case Type::DependentSizedExtVector:
280 case Type::Vector:
281 case Type::ExtVector:
282 case Type::ConstantMatrix:
283 case Type::DependentSizedMatrix:
284 case Type::FunctionProto:
285 case Type::FunctionNoProto:
286 case Type::Paren:
287 case Type::PackExpansion:
288 case Type::SubstTemplateTypeParm:
289 case Type::MacroQualified:
290 case Type::CountAttributed:
291 CanPrefixQualifiers = false;
292 break;
293
294 case Type::Attributed: {
295
296
297 const auto *AttrTy = cast(UnderlyingType);
298 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
299 break;
300 }
301 case Type::PackIndexing: {
302 return canPrefixQualifiers(
303 cast(UnderlyingType)->getPattern().getTypePtr(),
304 NeedARCStrongQualifier);
305 }
306 }
307
308 return CanPrefixQualifiers;
309}
310
311void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
313
314
315
317 if (const auto *Subst = dyn_cast(Split.Ty))
319
320 printBefore(Split.Ty, Quals, OS);
321}
322
323
324
325void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
327 return;
328
330
331
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, true);
341 } else {
342 Quals.print(OS, Policy, true);
343 }
344 }
345
346 bool hasAfterQuals = false;
347 if (!CanPrefixQualifiers && !Quals.empty()) {
349 if (hasAfterQuals)
350 HasEmptyPlaceHolder = false;
351 }
352
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, !PrevPHIsEmpty.get());
365 } else {
366 Quals.print(OS, Policy, !PrevPHIsEmpty.get());
367 }
368 }
369}
370
371void TypePrinter::printAfter(QualType t, raw_ostream &OS) {
373 printAfter(split.Ty, split.Quals, OS);
374}
375
376
377
378void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
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);
408
409
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
419
421 OS << ')';
423}
424
425void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
426 raw_ostream &OS) {
427 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
429 OS << '^';
430}
431
432void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
433 raw_ostream &OS) {
434 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
436}
437
438
439
443 return T;
444}
445
447 raw_ostream &OS) {
448 IncludeStrongLifetimeRAII Strong(Policy);
449 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
451 printBefore(Inner, OS);
452
453
454 if (isa(Inner))
455 OS << '(';
456 OS << '&';
457}
458
460 raw_ostream &OS) {
461 IncludeStrongLifetimeRAII Strong(Policy);
462 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
464
465
466 if (isa(Inner))
467 OS << ')';
468 printAfter(Inner, OS);
469}
470
472 raw_ostream &OS) {
473 IncludeStrongLifetimeRAII Strong(Policy);
474 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
476 printBefore(Inner, OS);
477
478
479 if (isa(Inner))
480 OS << '(';
481 OS << "&&";
482}
483
485 raw_ostream &OS) {
486 IncludeStrongLifetimeRAII Strong(Policy);
487 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
489
490
491 if (isa(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);
501
502
504 OS << '(';
505
507 InnerPolicy.IncludeTagDefinition = false;
508 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
509
510 OS << "::*";
511}
512
514 raw_ostream &OS) {
515 IncludeStrongLifetimeRAII Strong(Policy);
516 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
517
518
520 OS << ')';
522}
523
524void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
525 raw_ostream &OS) {
526 IncludeStrongLifetimeRAII Strong(Policy);
527 printBefore(T->getElementType(), OS);
528}
529
531 raw_ostream &OS) {
532 OS << '[';
533 if (T->getIndexTypeQualifiers().hasQualifiers()) {
535 Policy.Restrict);
536 OS << ' ';
537 }
538
539 if (T->getSizeModifier() == ArraySizeModifier::Static)
540 OS << "static ";
541
542 OS << T->getZExtSize() << ']';
543 printAfter(T->getElementType(), OS);
544}
545
547 raw_ostream &OS) {
548 IncludeStrongLifetimeRAII Strong(Policy);
549 printBefore(T->getElementType(), OS);
550}
551
553 raw_ostream &OS) {
554 OS << "[]";
555 printAfter(T->getElementType(), OS);
556}
557
558void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
559 raw_ostream &OS) {
560 IncludeStrongLifetimeRAII Strong(Policy);
561 printBefore(T->getElementType(), OS);
562}
563
565 raw_ostream &OS) {
566 OS << '[';
567 if (T->getIndexTypeQualifiers().hasQualifiers()) {
569 OS << ' ';
570 }
571
572 if (T->getSizeModifier() == ArraySizeModifier::Static)
573 OS << "static ";
574 else if (T->getSizeModifier() == ArraySizeModifier::Star)
575 OS << '*';
576
577 if (T->getSizeExpr())
578 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
579 OS << ']';
580
581 printAfter(T->getElementType(), OS);
582}
583
584void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
585
586
587 printBefore(T->getAdjustedType(), OS);
588}
589
590void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
591 printAfter(T->getAdjustedType(), OS);
592}
593
594void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
595
596 printAdjustedBefore(T, OS);
597}
598
600 raw_ostream &OS) {
601 printConstantArrayAfter(T, OS);
602}
603
605 raw_ostream &OS) {
606 printConstantArrayBefore(T, OS);
607}
608
609void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
610 printAdjustedAfter(T, OS);
611}
612
613void TypePrinter::printDependentSizedArrayBefore(
615 raw_ostream &OS) {
616 IncludeStrongLifetimeRAII Strong(Policy);
617 printBefore(T->getElementType(), OS);
618}
619
620void TypePrinter::printDependentSizedArrayAfter(
622 raw_ostream &OS) {
623 OS << '[';
624 if (T->getSizeExpr())
625 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
626 OS << ']';
627 printAfter(T->getElementType(), OS);
628}
629
630void TypePrinter::printDependentAddressSpaceBefore(
633}
634
635void TypePrinter::printDependentAddressSpaceAfter(
637 OS << " __attribute__((address_space(";
638 if (T->getAddrSpaceExpr())
639 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
640 OS << ")))";
642}
643
644void TypePrinter::printDependentSizedExtVectorBefore(
646 raw_ostream &OS) {
647 if (Policy.UseHLSLTypes)
648 OS << "vector<";
649 printBefore(T->getElementType(), OS);
650}
651
652void TypePrinter::printDependentSizedExtVectorAfter(
654 raw_ostream &OS) {
655 if (Policy.UseHLSLTypes) {
656 OS << ", ";
657 if (T->getSizeExpr())
658 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
659 OS << ">";
660 } else {
661 OS << " __attribute__((ext_vector_type(";
662 if (T->getSizeExpr())
663 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
664 OS << ")))";
665 }
666 printAfter(T->getElementType(), OS);
667}
668
669void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
670 switch (T->getVectorKind()) {
671 case VectorKind::AltiVecPixel:
672 OS << "__vector __pixel ";
673 break;
674 case VectorKind::AltiVecBool:
675 OS << "__vector __bool ";
676 printBefore(T->getElementType(), OS);
677 break;
678 case VectorKind::AltiVecVector:
679 OS << "__vector ";
680 printBefore(T->getElementType(), OS);
681 break;
682 case VectorKind::Neon:
683 OS << "__attribute__((neon_vector_type("
684 << T->getNumElements() << "))) ";
685 printBefore(T->getElementType(), OS);
686 break;
687 case VectorKind::NeonPoly:
688 OS << "__attribute__((neon_polyvector_type(" <<
689 T->getNumElements() << "))) ";
690 printBefore(T->getElementType(), OS);
691 break;
692 case VectorKind::Generic: {
693
694
695 OS << "__attribute__((__vector_size__("
696 << T->getNumElements()
697 << " * sizeof(";
698 print(T->getElementType(), OS, StringRef());
699 OS << ")))) ";
700 printBefore(T->getElementType(), OS);
701 break;
702 }
703 case VectorKind::SveFixedLengthData:
704 case VectorKind::SveFixedLengthPredicate:
705
706
707 OS << "__attribute__((__arm_sve_vector_bits__(";
708
709 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
710
711
712 OS << T->getNumElements() * 8;
713 else
714 OS << T->getNumElements();
715
716 OS << " * sizeof(";
717 print(T->getElementType(), OS, StringRef());
718
719 OS << ") * 8))) ";
720 printBefore(T->getElementType(), OS);
721 break;
722 case VectorKind::RVVFixedLengthData:
723 case VectorKind::RVVFixedLengthMask:
724 case VectorKind::RVVFixedLengthMask_1:
725 case VectorKind::RVVFixedLengthMask_2:
726 case VectorKind::RVVFixedLengthMask_4:
727
728
729 OS << "__attribute__((__riscv_rvv_vector_bits__(";
730
731 OS << T->getNumElements();
732
733 OS << " * sizeof(";
734 print(T->getElementType(), OS, StringRef());
735
736 OS << ") * 8))) ";
737 printBefore(T->getElementType(), OS);
738 break;
739 }
740}
741
742void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
743 printAfter(T->getElementType(), OS);
744}
745
746void TypePrinter::printDependentVectorBefore(
748 switch (T->getVectorKind()) {
749 case VectorKind::AltiVecPixel:
750 OS << "__vector __pixel ";
751 break;
752 case VectorKind::AltiVecBool:
753 OS << "__vector __bool ";
754 printBefore(T->getElementType(), OS);
755 break;
756 case VectorKind::AltiVecVector:
757 OS << "__vector ";
758 printBefore(T->getElementType(), OS);
759 break;
760 case VectorKind::Neon:
761 OS << "__attribute__((neon_vector_type(";
762 if (T->getSizeExpr())
763 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
764 OS << "))) ";
765 printBefore(T->getElementType(), OS);
766 break;
767 case VectorKind::NeonPoly:
768 OS << "__attribute__((neon_polyvector_type(";
769 if (T->getSizeExpr())
770 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
771 OS << "))) ";
772 printBefore(T->getElementType(), OS);
773 break;
774 case VectorKind::Generic: {
775
776
777 OS << "__attribute__((__vector_size__(";
778 if (T->getSizeExpr())
779 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
780 OS << " * sizeof(";
781 print(T->getElementType(), OS, StringRef());
782 OS << ")))) ";
783 printBefore(T->getElementType(), OS);
784 break;
785 }
786 case VectorKind::SveFixedLengthData:
787 case VectorKind::SveFixedLengthPredicate:
788
789
790 OS << "__attribute__((__arm_sve_vector_bits__(";
791 if (T->getSizeExpr()) {
792 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
793 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
794
795
796 OS << " * 8";
797 OS << " * sizeof(";
798 print(T->getElementType(), OS, StringRef());
799
800 OS << ") * 8";
801 }
802 OS << "))) ";
803 printBefore(T->getElementType(), OS);
804 break;
805 case VectorKind::RVVFixedLengthData:
806 case VectorKind::RVVFixedLengthMask:
807 case VectorKind::RVVFixedLengthMask_1:
808 case VectorKind::RVVFixedLengthMask_2:
809 case VectorKind::RVVFixedLengthMask_4:
810
811
812 OS << "__attribute__((__riscv_rvv_vector_bits__(";
813 if (T->getSizeExpr()) {
814 T->getSizeExpr()->printPretty(OS, nullptr, Policy);
815 OS << " * sizeof(";
816 print(T->getElementType(), OS, StringRef());
817
818 OS << ") * 8";
819 }
820 OS << "))) ";
821 printBefore(T->getElementType(), OS);
822 break;
823 }
824}
825
826void TypePrinter::printDependentVectorAfter(
828 printAfter(T->getElementType(), OS);
829}
830
831void TypePrinter::printExtVectorBefore(const ExtVectorType *T,
832 raw_ostream &OS) {
833 if (Policy.UseHLSLTypes)
834 OS << "vector<";
835 printBefore(T->getElementType(), OS);
836}
837
838void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
839 printAfter(T->getElementType(), OS);
840
841 if (Policy.UseHLSLTypes) {
842 OS << ", ";
843 OS << T->getNumElements();
844 OS << ">";
845 } else {
846 OS << " __attribute__((ext_vector_type(";
847 OS << T->getNumElements();
848 OS << ")))";
849 }
850}
851
853 raw_ostream &OS) {
854 printBefore(T->getElementType(), OS);
855 OS << " __attribute__((matrix_type(";
856 OS << T->getNumRows() << ", " << T->getNumColumns();
857 OS << ")))";
858}
859
861 raw_ostream &OS) {
862 printAfter(T->getElementType(), OS);
863}
864
865void TypePrinter::printDependentSizedMatrixBefore(
867 printBefore(T->getElementType(), OS);
868 OS << " __attribute__((matrix_type(";
869 if (T->getRowExpr()) {
870 T->getRowExpr()->printPretty(OS, nullptr, Policy);
871 }
872 OS << ", ";
873 if (T->getColumnExpr()) {
874 T->getColumnExpr()->printPretty(OS, nullptr, Policy);
875 }
876 OS << ")))";
877}
878
879void TypePrinter::printDependentSizedMatrixAfter(
881 printAfter(T->getElementType(), OS);
882}
883
884void
887 const {
889 OS << " throw(";
891 OS << "...";
892 else
894 if (I)
895 OS << ", ";
896
898 }
899 OS << ')';
901 OS << " __attribute__((nothrow))";
903 OS << " noexcept";
904
905
907 OS << '(';
910 OS << ')';
911 }
912 }
913}
914
915void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
916 raw_ostream &OS) {
918 OS << "auto ";
919 if (!HasEmptyPlaceHolder)
920 OS << '(';
921 } else {
922
923 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
925 if (!PrevPHIsEmpty.get())
926 OS << '(';
927 }
928}
929
931 switch (ABI) {
933 llvm_unreachable("asking for spelling of ordinary parameter ABI");
935 return "swift_context";
937 return "swift_async_context";
939 return "swift_error_result";
941 return "swift_indirect_result";
943 return "out";
945 return "inout";
946 }
947 llvm_unreachable("bad parameter ABI kind");
948}
949
951 raw_ostream &OS) {
952
953 if (!HasEmptyPlaceHolder)
954 OS << ')';
955 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
956
957 OS << '(';
958 {
959 ParamPolicyRAII ParamPolicy(Policy);
960 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
961 if (i) OS << ", ";
962
964 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
965 if (EPI.isNoEscape())
966 OS << "__attribute__((noescape)) ";
967 auto ABI = EPI.getABI();
970 if (Policy.UseHLSLTypes) {
971
972
973
974
976 continue;
977 }
980
982 }
983 }
984
987 OS << ", ";
988 OS << "...";
989 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {
990
991 OS << "void";
992 }
993
994 OS << ')';
995
998
1000 OS << " __arm_streaming_compatible";
1002 OS << " __arm_streaming";
1004 OS << "__arm_agnostic(\"sme_za_state\")";
1006 OS << " __arm_preserves(\"za\")";
1008 OS << " __arm_in(\"za\")";
1010 OS << " __arm_out(\"za\")";
1012 OS << " __arm_inout(\"za\")";
1014 OS << " __arm_preserves(\"zt0\")";
1016 OS << " __arm_in(\"zt0\")";
1018 OS << " __arm_out(\"zt0\")";
1020 OS << " __arm_inout(\"zt0\")";
1021
1022 printFunctionAfter(Info, OS);
1023
1026
1029 break;
1030
1032 OS << " &";
1033 break;
1034
1036 OS << " &&";
1037 break;
1038 }
1040
1042 for (const auto &CFE : FX) {
1043 OS << " __attribute__((" << CFE.Effect.name();
1044 if (const Expr *E = CFE.Cond.getCondition()) {
1045 OS << '(';
1047 OS << ')';
1048 }
1049 OS << "))";
1050 }
1051
1053 OS << " -> ";
1055 } else
1057}
1058
1060 raw_ostream &OS) {
1061 if (!InsideCCAttribute) {
1062 switch (Info.getCC()) {
1064
1065
1066
1067
1068
1069
1070
1071 break;
1073 OS << " __attribute__((stdcall))";
1074 break;
1076 OS << " __attribute__((fastcall))";
1077 break;
1079 OS << " __attribute__((thiscall))";
1080 break;
1082 OS << " __attribute__((vectorcall))";
1083 break;
1085 OS << " __attribute__((pascal))";
1086 break;
1088 OS << " __attribute__((pcs(\"aapcs\")))";
1089 break;
1091 OS << " __attribute__((pcs(\"aapcs-vfp\")))";
1092 break;
1094 OS << "__attribute__((aarch64_vector_pcs))";
1095 break;
1097 OS << "__attribute__((aarch64_sve_pcs))";
1098 break;
1100 OS << "__attribute__((amdgpu_kernel))";
1101 break;
1103 OS << " __attribute__((intel_ocl_bicc))";
1104 break;
1106 OS << " __attribute__((ms_abi))";
1107 break;
1109 OS << " __attribute__((sysv_abi))";
1110 break;
1112 OS << " __attribute__((regcall))";
1113 break;
1116
1117 break;
1119 OS << " __attribute__((swiftcall))";
1120 break;
1122 OS << "__attribute__((swiftasynccall))";
1123 break;
1125 OS << " __attribute__((preserve_most))";
1126 break;
1128 OS << " __attribute__((preserve_all))";
1129 break;
1131 OS << " __attribute__((m68k_rtd))";
1132 break;
1134 OS << " __attribute__((preserve_none))";
1135 break;
1137 OS << "__attribute__((riscv_vector_cc))";
1138 break;
1139 }
1140 }
1141
1143 OS << " __attribute__((noreturn))";
1145 OS << " __attribute__((cmse_nonsecure_call))";
1147 OS << " __attribute__((ns_returns_retained))";
1149 OS << " __attribute__((regparm ("
1152 OS << " __attribute__((no_caller_saved_registers))";
1154 OS << " __attribute__((nocf_check))";
1155}
1156
1158 raw_ostream &OS) {
1159
1160 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);
1162 if (!PrevPHIsEmpty.get())
1163 OS << '(';
1164}
1165
1167 raw_ostream &OS) {
1168
1169 if (!HasEmptyPlaceHolder)
1170 OS << ')';
1171 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);
1172
1173 OS << "()";
1174 printFunctionAfter(T->getExtInfo(), OS);
1176}
1177
1178void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
1179
1180
1181
1182
1183 if (!Policy.SuppressScope)
1185
1188 spaceBeforePlaceHolder(OS);
1189}
1190
1192 raw_ostream &OS) {
1193 printTypeSpec(T->getDecl(), OS);
1194}
1195
1197 raw_ostream &OS) {}
1198
1199void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209 printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
1210}
1211
1212void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
1213
1214void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
1215 printTypeSpec(T->getDecl(), OS);
1216}
1217
1219 raw_ostream &OS) {
1220 StringRef MacroName = T->getMacroIdentifier()->getName();
1221 OS << MacroName << " ";
1222
1223
1224
1225 printBefore(T->getModifiedType(), OS);
1226}
1227
1229 raw_ostream &OS) {
1230 printAfter(T->getModifiedType(), OS);
1231}
1232
1233void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
1234
1235void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
1236 raw_ostream &OS) {
1238 : "typeof ");
1239 if (T->getUnderlyingExpr())
1240 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1241 spaceBeforePlaceHolder(OS);
1242}
1243
1244void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
1245 raw_ostream &OS) {}
1246
1247void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
1249 : "typeof(");
1250 print(T->getUnmodifiedType(), OS, StringRef());
1251 OS << ')';
1252 spaceBeforePlaceHolder(OS);
1253}
1254
1255void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}
1256
1257void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
1258 OS << "decltype(";
1259 if (T->getUnderlyingExpr())
1260 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
1261 OS << ')';
1262 spaceBeforePlaceHolder(OS);
1263}
1264
1265void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,
1266 raw_ostream &OS) {
1267 if (T->hasSelectedType()) {
1268 OS << T->getSelectedType();
1269 } else {
1270 OS << T->getPattern() << "...[";
1271 T->getIndexExpr()->printPretty(OS, nullptr, Policy);
1272 OS << "]";
1273 }
1274 spaceBeforePlaceHolder(OS);
1275}
1276
1277void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,
1278 raw_ostream &OS) {}
1279
1280void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}
1281
1283 raw_ostream &OS) {
1284 IncludeStrongLifetimeRAII Strong(Policy);
1285
1286 static llvm::DenseMap<int, const char *> Transformation = {{
1287#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1288 {UnaryTransformType::Enum, "__" #Trait},
1289#include "clang/Basic/TransformTypeTraits.def"
1290 }};
1291 OS << Transformation[T->getUTTKind()] << '(';
1292 print(T->getBaseType(), OS, StringRef());
1293 OS << ')';
1294 spaceBeforePlaceHolder(OS);
1295}
1296
1298 raw_ostream &OS) {}
1299
1300void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
1301
1302 if (->getDeducedType().isNull()) {
1303 printBefore(T->getDeducedType(), OS);
1304 } else {
1305 if (T->isConstrained()) {
1306
1307
1308 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1309 auto Args = T->getTypeConstraintArguments();
1310 if (!Args.empty())
1312 OS, Args, Policy,
1313 T->getTypeConstraintConcept()->getTemplateParameters());
1314 OS << ' ';
1315 }
1316 switch (T->getKeyword()) {
1320 }
1321 spaceBeforePlaceHolder(OS);
1322 }
1323}
1324
1325void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
1326
1327 if (->getDeducedType().isNull())
1328 printAfter(T->getDeducedType(), OS);
1329}
1330
1331void TypePrinter::printDeducedTemplateSpecializationBefore(
1333
1334 if (->getDeducedType().isNull()) {
1335 printBefore(T->getDeducedType(), OS);
1336 } else {
1337 IncludeStrongLifetimeRAII Strong(Policy);
1338 T->getTemplateName().print(OS, Policy);
1339 spaceBeforePlaceHolder(OS);
1340 }
1341}
1342
1343void TypePrinter::printDeducedTemplateSpecializationAfter(
1345
1346 if (->getDeducedType().isNull())
1347 printAfter(T->getDeducedType(), OS);
1348}
1349
1350void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
1351 IncludeStrongLifetimeRAII Strong(Policy);
1352
1353 OS << "_Atomic(";
1354 print(T->getValueType(), OS, StringRef());
1355 OS << ')';
1356 spaceBeforePlaceHolder(OS);
1357}
1358
1359void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}
1360
1361void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {
1362 IncludeStrongLifetimeRAII Strong(Policy);
1363
1364 if (T->isReadOnly())
1365 OS << "read_only ";
1366 else
1367 OS << "write_only ";
1368 OS << "pipe ";
1369 print(T->getElementType(), OS, StringRef());
1370 spaceBeforePlaceHolder(OS);
1371}
1372
1373void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}
1374
1375void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {
1376 if (T->isUnsigned())
1377 OS << "unsigned ";
1378 OS << "_BitInt(" << T->getNumBits() << ")";
1379 spaceBeforePlaceHolder(OS);
1380}
1381
1382void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}
1383
1385 raw_ostream &OS) {
1386 if (T->isUnsigned())
1387 OS << "unsigned ";
1388 OS << "_BitInt(";
1389 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);
1390 OS << ")";
1391 spaceBeforePlaceHolder(OS);
1392}
1393
1395 raw_ostream &OS) {}
1396
1397
1398void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1401 return;
1402
1403
1404
1406 return;
1407
1408 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1409 return;
1410
1411 if (const auto *NS = dyn_cast(DC)) {
1412 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1413 return AppendScope(DC->getParent(), OS, NameInScope);
1414
1415
1416
1417 if (Policy.SuppressInlineNamespace !=
1419 NS->isInline() && NameInScope &&
1420 NS->isRedundantInlineQualifierFor(NameInScope))
1421 return AppendScope(DC->getParent(), OS, NameInScope);
1422
1423 AppendScope(DC->getParent(), OS, NS->getDeclName());
1424 if (NS->getIdentifier())
1425 OS << NS->getName() << "::";
1426 else
1427 OS << "(anonymous namespace)::";
1428 } else if (const auto *Spec = dyn_cast(DC)) {
1429 AppendScope(DC->getParent(), OS, Spec->getDeclName());
1430 IncludeStrongLifetimeRAII Strong(Policy);
1431 OS << Spec->getIdentifier()->getName();
1434 OS, TemplateArgs.asArray(), Policy,
1435 Spec->getSpecializedTemplate()->getTemplateParameters());
1436 OS << "::";
1437 } else if (const auto *Tag = dyn_cast(DC)) {
1438 AppendScope(DC->getParent(), OS, Tag->getDeclName());
1440 OS << Typedef->getIdentifier()->getName() << "::";
1441 else if (Tag->getIdentifier())
1442 OS << Tag->getIdentifier()->getName() << "::";
1443 else
1444 return;
1445 } else {
1446 AppendScope(DC->getParent(), OS, NameInScope);
1447 }
1448}
1449
1450void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
1451 if (Policy.IncludeTagDefinition) {
1454 D->print(OS, SubPolicy, Indentation);
1455 spaceBeforePlaceHolder(OS);
1456 return;
1457 }
1458
1459 bool HasKindDecoration = false;
1460
1461
1462
1463 if (!Policy.SuppressTagKeyword && ->getTypedefNameForAnonDecl()) {
1464 HasKindDecoration = true;
1465 OS << D->getKindName();
1466 OS << ' ';
1467 }
1468
1469
1470
1471
1472 if (!Policy.SuppressScope)
1474
1477 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1478 assert(Typedef->getIdentifier() && "Typedef without identifier?");
1479 OS << Typedef->getIdentifier()->getName();
1480 } else {
1481
1482
1483 OS << (Policy.MSVCFormatting ? '`' : '(');
1484
1485 if (isa(D) && cast(D)->isLambda()) {
1486 OS << "lambda";
1487 HasKindDecoration = true;
1488 } else if ((isa(D) && cast(D)->isAnonymousStructOrUnion())) {
1489 OS << "anonymous";
1490 } else {
1491 OS << "unnamed";
1492 }
1493
1494 if (Policy.AnonymousTagLocations) {
1495
1496
1497
1498 if (!HasKindDecoration)
1499 OS << " " << D->getKindName();
1500
1504 OS << " at ";
1507 if (auto *Callbacks = Policy.Callbacks)
1508 WrittenFile = Callbacks->remapPath(File);
1509
1510
1511
1512 llvm::sys::path::Style Style =
1513 llvm::sys::path::is_absolute(WrittenFile)
1514 ? llvm::sys::path::Style::native
1515 : (Policy.MSVCFormatting
1516 ? llvm::sys::path::Style::windows_backslash
1517 : llvm::sys::path::Style::posix);
1518 llvm::sys::path::native(WrittenFile, Style);
1519 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
1520 }
1521 }
1522
1523 OS << (Policy.MSVCFormatting ? '\'' : ')');
1524 }
1525
1526
1527
1528 if (auto *S = dyn_cast(D)) {
1530 S->getSpecializedTemplate()->getTemplateParameters();
1532 S->getTemplateArgsAsWritten();
1533 IncludeStrongLifetimeRAII Strong(Policy);
1534 if (TArgAsWritten && !Policy.PrintCanonicalTypes)
1536 TParams);
1537 else
1539 TParams);
1540 }
1541
1542 spaceBeforePlaceHolder(OS);
1543}
1544
1545void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
1546
1547 if (Policy.UsePreferredNames) {
1548 for (const auto *PNA : T->getDecl()->specific_attrs()) {
1549 if ((PNA->getTypedefType()->getAsCXXRecordDecl(),
1550 T->getDecl()))
1551 continue;
1552
1553 QualType T = PNA->getTypedefType();
1554 while (true) {
1555 if (auto *TT = dyn_cast(T))
1556 return printTypeSpec(TT->getDecl(), OS);
1557 if (auto *TST = dyn_cast(T))
1558 return printTemplateId(TST, OS, true);
1560 }
1561 }
1562 }
1563
1564 printTag(T->getDecl(), OS);
1565}
1566
1567void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
1568
1569void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
1570 printTag(T->getDecl(), OS);
1571}
1572
1573void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
1574
1576 raw_ostream &OS) {
1579 if (auto *TC = D->getTypeConstraint()) {
1580 TC->print(OS, Policy);
1581 OS << ' ';
1582 }
1583 OS << "auto";
1585 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1586 : Id->getName());
1587 else
1588 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
1589
1590 spaceBeforePlaceHolder(OS);
1591}
1592
1594 raw_ostream &OS) {}
1595
1596void TypePrinter::printSubstTemplateTypeParmBefore(
1598 raw_ostream &OS) {
1599 IncludeStrongLifetimeRAII Strong(Policy);
1600 printBefore(T->getReplacementType(), OS);
1601}
1602
1603void TypePrinter::printSubstTemplateTypeParmAfter(
1605 raw_ostream &OS) {
1606 IncludeStrongLifetimeRAII Strong(Policy);
1607 printAfter(T->getReplacementType(), OS);
1608}
1609
1610void TypePrinter::printSubstTemplateTypeParmPackBefore(
1612 raw_ostream &OS) {
1613 IncludeStrongLifetimeRAII Strong(Policy);
1616 if (auto *TC = D->getTypeConstraint()) {
1617 TC->print(OS, Policy);
1618 OS << ' ';
1619 }
1620 OS << "auto";
1622 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()
1623 : Id->getName());
1624 else
1625 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();
1626
1627 spaceBeforePlaceHolder(OS);
1628 }
1629}
1630
1631void TypePrinter::printSubstTemplateTypeParmPackAfter(
1633 raw_ostream &OS) {
1634 IncludeStrongLifetimeRAII Strong(Policy);
1635}
1636
1638 raw_ostream &OS, bool FullyQualify) {
1639 IncludeStrongLifetimeRAII Strong(Policy);
1640
1642 T->getTemplateName().getAsTemplateDecl(true);
1643
1644 if (FullyQualify && TD) {
1645 if (!Policy.SuppressScope)
1647
1649 } else {
1651 }
1652
1653 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1656 spaceBeforePlaceHolder(OS);
1657}
1658
1659void TypePrinter::printTemplateSpecializationBefore(
1661 raw_ostream &OS) {
1662 printTemplateId(T, OS, Policy.FullyQualifiedName);
1663}
1664
1665void TypePrinter::printTemplateSpecializationAfter(
1667 raw_ostream &OS) {}
1668
1670 raw_ostream &OS) {
1671 if (Policy.PrintInjectedClassNameWithArguments)
1672 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
1673
1674 IncludeStrongLifetimeRAII Strong(Policy);
1675 T->getTemplateName().print(OS, Policy);
1676 spaceBeforePlaceHolder(OS);
1677}
1678
1680 raw_ostream &OS) {}
1681
1682void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
1683 raw_ostream &OS) {
1684 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
1685 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
1686 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
1687 "OwnedTagDecl expected to be a declaration for the type");
1690 OwnedTagDecl->print(OS, SubPolicy, Indentation);
1691 spaceBeforePlaceHolder(OS);
1692 return;
1693 }
1694
1695 if (Policy.SuppressElaboration) {
1696 printBefore(T->getNamedType(), OS);
1697 return;
1698 }
1699
1700
1701 if (!Policy.IncludeTagDefinition)
1702 {
1705 OS << " ";
1707 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
1708 !Policy.SuppressUnwrittenScope) {
1709 bool OldTagKeyword = Policy.SuppressTagKeyword;
1710 bool OldSupressScope = Policy.SuppressScope;
1711 Policy.SuppressTagKeyword = true;
1712 Policy.SuppressScope = false;
1713 printBefore(T->getNamedType(), OS);
1714 Policy.SuppressTagKeyword = OldTagKeyword;
1715 Policy.SuppressScope = OldSupressScope;
1716 return;
1717 }
1718 if (Qualifier)
1720 }
1721
1722 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1723 printBefore(T->getNamedType(), OS);
1724}
1725
1726void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
1727 raw_ostream &OS) {
1728 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
1729 return;
1730
1731 if (Policy.SuppressElaboration) {
1732 printAfter(T->getNamedType(), OS);
1733 return;
1734 }
1735
1736 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1737 printAfter(T->getNamedType(), OS);
1738}
1739
1740void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
1741 if (!HasEmptyPlaceHolder && !isa(T->getInnerType())) {
1742 printBefore(T->getInnerType(), OS);
1743 OS << '(';
1744 } else
1745 printBefore(T->getInnerType(), OS);
1746}
1747
1748void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
1749 if (!HasEmptyPlaceHolder && !isa(T->getInnerType())) {
1750 OS << ')';
1751 printAfter(T->getInnerType(), OS);
1752 } else
1753 printAfter(T->getInnerType(), OS);
1754}
1755
1756void TypePrinter::printDependentNameBefore(const DependentNameType *T,
1757 raw_ostream &OS) {
1760 OS << " ";
1761
1762 T->getQualifier()->print(OS, Policy);
1763
1764 OS << T->getIdentifier()->getName();
1765 spaceBeforePlaceHolder(OS);
1766}
1767
1768void TypePrinter::printDependentNameAfter(const DependentNameType *T,
1769 raw_ostream &OS) {}
1770
1771void TypePrinter::printDependentTemplateSpecializationBefore(
1773 IncludeStrongLifetimeRAII Strong(Policy);
1774
1777 OS << " ";
1778
1779 if (T->getQualifier())
1780 T->getQualifier()->print(OS, Policy);
1781 OS << "template " << T->getIdentifier()->getName();
1783 spaceBeforePlaceHolder(OS);
1784}
1785
1786void TypePrinter::printDependentTemplateSpecializationAfter(
1788
1789void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
1790 raw_ostream &OS) {
1791 printBefore(T->getPattern(), OS);
1792}
1793
1794void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
1795 raw_ostream &OS) {
1796 printAfter(T->getPattern(), OS);
1797 OS << "...";
1798}
1799
1801 raw_ostream &OS,
1803 OS << ' ';
1804 if (T->isCountInBytes() && T->isOrNull())
1805 OS << "__sized_by_or_null(";
1806 else if (T->isCountInBytes())
1807 OS << "__sized_by(";
1808 else if (T->isOrNull())
1809 OS << "__counted_by_or_null(";
1810 else
1811 OS << "__counted_by(";
1812 if (T->getCountExpr())
1813 T->getCountExpr()->printPretty(OS, nullptr, Policy);
1814 OS << ')';
1815}
1816
1818 raw_ostream &OS) {
1819 printBefore(T->desugar(), OS);
1822}
1823
1825 raw_ostream &OS) {
1826 printAfter(T->desugar(), OS);
1829}
1830
1831void TypePrinter::printAttributedBefore(const AttributedType *T,
1832 raw_ostream &OS) {
1833
1834
1835
1836 if (T->getAttrKind() == attr::ObjCGC ||
1837 T->getAttrKind() == attr::ObjCOwnership)
1838 return printBefore(T->getEquivalentType(), OS);
1839
1840 if (T->getAttrKind() == attr::ObjCKindOf)
1841 OS << "__kindof ";
1842
1843 if (T->getAttrKind() == attr::AddressSpace)
1844 printBefore(T->getEquivalentType(), OS);
1845 else
1846 printBefore(T->getModifiedType(), OS);
1847
1848 if (T->isMSTypeSpec()) {
1849 switch (T->getAttrKind()) {
1850 default: return;
1851 case attr::Ptr32: OS << " __ptr32"; break;
1852 case attr::Ptr64: OS << " __ptr64"; break;
1853 case attr::SPtr: OS << " __sptr"; break;
1854 case attr::UPtr: OS << " __uptr"; break;
1855 }
1856 spaceBeforePlaceHolder(OS);
1857 }
1858
1859 if (T->isWebAssemblyFuncrefSpec())
1860 OS << "__funcref";
1861
1862
1863 if (T->getImmediateNullability()) {
1864 if (T->getAttrKind() == attr::TypeNonNull)
1865 OS << " _Nonnull";
1866 else if (T->getAttrKind() == attr::TypeNullable)
1867 OS << " _Nullable";
1868 else if (T->getAttrKind() == attr::TypeNullUnspecified)
1869 OS << " _Null_unspecified";
1870 else if (T->getAttrKind() == attr::TypeNullableResult)
1871 OS << " _Nullable_result";
1872 else
1873 llvm_unreachable("unhandled nullability");
1874 spaceBeforePlaceHolder(OS);
1875 }
1876}
1877
1878void TypePrinter::printAttributedAfter(const AttributedType *T,
1879 raw_ostream &OS) {
1880
1881
1882
1883 if (T->getAttrKind() == attr::ObjCGC ||
1884 T->getAttrKind() == attr::ObjCOwnership)
1885 return printAfter(T->getEquivalentType(), OS);
1886
1887
1888
1889 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());
1890
1891 printAfter(T->getModifiedType(), OS);
1892
1893
1894
1895 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||
1896 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())
1897 return;
1898
1899
1900 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1901 return;
1902
1903
1904 if (T->getAttrKind() == attr::NSReturnsRetained &&
1907 return;
1908
1909 if (T->getAttrKind() == attr::LifetimeBound) {
1910 OS << " [[clang::lifetimebound]]";
1911 return;
1912 }
1913 if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1914 OS << " [[clang::lifetime_capture_by(";
1915 if (auto *attr = dyn_cast_or_null(T->getAttr()))
1916 llvm::interleaveComma(attr->getArgIdents(), OS,
1917 [&](auto it) { OS << it->getName(); });
1918 OS << ")]]";
1919 return;
1920 }
1921
1922
1923
1924
1925 if (T->getAttrKind() == attr::AddressSpace)
1926 return;
1927
1928 if (T->getAttrKind() == attr::AnnotateType) {
1929
1930
1931
1932
1933 OS << " [[clang::annotate_type(...)]]";
1934 return;
1935 }
1936
1937 if (T->getAttrKind() == attr::ArmStreaming) {
1938 OS << "__arm_streaming";
1939 return;
1940 }
1941 if (T->getAttrKind() == attr::ArmStreamingCompatible) {
1942 OS << "__arm_streaming_compatible";
1943 return;
1944 }
1945
1946 if (T->getAttrKind() == attr::SwiftAttr) {
1947 if (auto *swiftAttr = dyn_cast_or_null(T->getAttr())) {
1948 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1949 << "\")))";
1950 }
1951 return;
1952 }
1953
1954 OS << " __attribute__((";
1955 switch (T->getAttrKind()) {
1956#define TYPE_ATTR(NAME)
1957#define DECL_OR_TYPE_ATTR(NAME)
1958#define ATTR(NAME) case attr::NAME:
1959#include "clang/Basic/AttrList.inc"
1960 llvm_unreachable("non-type attribute attached to type");
1961
1962 case attr::BTFTypeTag:
1963 llvm_unreachable("BTFTypeTag attribute handled separately");
1964
1965 case attr::HLSLResourceClass:
1966 case attr::HLSLROV:
1967 case attr::HLSLRawBuffer:
1968 case attr::HLSLContainedType:
1969 llvm_unreachable("HLSL resource type attributes handled separately");
1970
1971 case attr::OpenCLPrivateAddressSpace:
1972 case attr::OpenCLGlobalAddressSpace:
1973 case attr::OpenCLGlobalDeviceAddressSpace:
1974 case attr::OpenCLGlobalHostAddressSpace:
1975 case attr::OpenCLLocalAddressSpace:
1976 case attr::OpenCLConstantAddressSpace:
1977 case attr::OpenCLGenericAddressSpace:
1978 case attr::HLSLGroupSharedAddressSpace:
1979
1980
1981 break;
1982
1983 case attr::CountedBy:
1984 case attr::CountedByOrNull:
1985 case attr::SizedBy:
1986 case attr::SizedByOrNull:
1987 case attr::LifetimeBound:
1988 case attr::LifetimeCaptureBy:
1989 case attr::TypeNonNull:
1990 case attr::TypeNullable:
1991 case attr::TypeNullableResult:
1992 case attr::TypeNullUnspecified:
1993 case attr::ObjCGC:
1994 case attr::ObjCInertUnsafeUnretained:
1995 case attr::ObjCKindOf:
1996 case attr::ObjCOwnership:
1997 case attr::Ptr32:
1998 case attr::Ptr64:
1999 case attr::SPtr:
2000 case attr::UPtr:
2001 case attr::AddressSpace:
2002 case attr::CmseNSCall:
2003 case attr::AnnotateType:
2004 case attr::WebAssemblyFuncref:
2005 case attr::ArmAgnostic:
2006 case attr::ArmStreaming:
2007 case attr::ArmStreamingCompatible:
2008 case attr::ArmIn:
2009 case attr::ArmOut:
2010 case attr::ArmInOut:
2011 case attr::ArmPreserves:
2012 case attr::NonBlocking:
2013 case attr::NonAllocating:
2014 case attr::Blocking:
2015 case attr::Allocating:
2016 case attr::SwiftAttr:
2017 llvm_unreachable("This attribute should have been handled already");
2018
2019 case attr::NSReturnsRetained:
2020 OS << "ns_returns_retained";
2021 break;
2022
2023
2024
2025 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;
2026 case attr::CDecl: OS << "cdecl"; break;
2027 case attr::FastCall: OS << "fastcall"; break;
2028 case attr::StdCall: OS << "stdcall"; break;
2029 case attr::ThisCall: OS << "thiscall"; break;
2030 case attr::SwiftCall: OS << "swiftcall"; break;
2031 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;
2032 case attr::VectorCall: OS << "vectorcall"; break;
2033 case attr::Pascal: OS << "pascal"; break;
2034 case attr::MSABI: OS << "ms_abi"; break;
2035 case attr::SysVABI: OS << "sysv_abi"; break;
2036 case attr::RegCall: OS << "regcall"; break;
2037 case attr::Pcs: {
2038 OS << "pcs(";
2039 QualType t = T->getEquivalentType();
2043 "\"aapcs\"" : "\"aapcs-vfp\"");
2044 OS << ')';
2045 break;
2046 }
2047 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
2048 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2049 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
2050 case attr::IntelOclBicc: OS << "inteloclbicc"; break;
2051 case attr::PreserveMost:
2052 OS << "preserve_most";
2053 break;
2054
2055 case attr::PreserveAll:
2056 OS << "preserve_all";
2057 break;
2058 case attr::M68kRTD:
2059 OS << "m68k_rtd";
2060 break;
2061 case attr::PreserveNone:
2062 OS << "preserve_none";
2063 break;
2064 case attr::RISCVVectorCC:
2065 OS << "riscv_vector_cc";
2066 break;
2067 case attr::NoDeref:
2068 OS << "noderef";
2069 break;
2070 case attr::AcquireHandle:
2071 OS << "acquire_handle";
2072 break;
2073 case attr::ArmMveStrictPolymorphism:
2074 OS << "__clang_arm_mve_strict_polymorphism";
2075 break;
2076 }
2077 OS << "))";
2078}
2079
2081 raw_ostream &OS) {
2082 printBefore(T->getWrappedType(), OS);
2083 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";
2084}
2085
2087 raw_ostream &OS) {
2088 printAfter(T->getWrappedType(), OS);
2089}
2090
2091void TypePrinter::printHLSLAttributedResourceBefore(
2093 printBefore(T->getWrappedType(), OS);
2094}
2095
2096void TypePrinter::printHLSLAttributedResourceAfter(
2098 printAfter(T->getWrappedType(), OS);
2100 OS << " [[hlsl::resource_class("
2101 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)
2102 << ")]]";
2103 if (Attrs.IsROV)
2104 OS << " [[hlsl::is_rov]]";
2106 OS << " [[hlsl::raw_buffer]]";
2107
2108 QualType ContainedTy = T->getContainedType();
2109 if (!ContainedTy.isNull()) {
2110 OS << " [[hlsl::contained_type(";
2111 printBefore(ContainedTy, OS);
2112 printAfter(ContainedTy, OS);
2113 OS << ")]]";
2114 }
2115}
2116
2117void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
2118 raw_ostream &OS) {
2119 OS << T->getDecl()->getName();
2120 spaceBeforePlaceHolder(OS);
2121}
2122
2123void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
2124 raw_ostream &OS) {}
2125
2126void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
2127 raw_ostream &OS) {
2128 OS << T->getDecl()->getName();
2129 if (->qual_empty()) {
2130 bool isFirst = true;
2131 OS << '<';
2132 for (const auto *I : T->quals()) {
2133 if (isFirst)
2134 isFirst = false;
2135 else
2136 OS << ',';
2137 OS << I->getName();
2138 }
2139 OS << '>';
2140 }
2141
2142 spaceBeforePlaceHolder(OS);
2143}
2144
2145void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
2146 raw_ostream &OS) {}
2147
2148void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
2149 raw_ostream &OS) {
2150 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2151 ->isKindOfTypeAsWritten())
2152 return printBefore(T->getBaseType(), OS);
2153
2154 if (T->isKindOfTypeAsWritten())
2155 OS << "__kindof ";
2156
2157 print(T->getBaseType(), OS, StringRef());
2158
2159 if (T->isSpecializedAsWritten()) {
2160 bool isFirst = true;
2161 OS << '<';
2162 for (auto typeArg : T->getTypeArgsAsWritten()) {
2163 if (isFirst)
2164 isFirst = false;
2165 else
2166 OS << ",";
2167
2168 print(typeArg, OS, StringRef());
2169 }
2170 OS << '>';
2171 }
2172
2173 if (->qual_empty()) {
2174 bool isFirst = true;
2175 OS << '<';
2176 for (const auto *I : T->quals()) {
2177 if (isFirst)
2178 isFirst = false;
2179 else
2180 OS << ',';
2181 OS << I->getName();
2182 }
2183 OS << '>';
2184 }
2185
2186 spaceBeforePlaceHolder(OS);
2187}
2188
2189void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
2190 raw_ostream &OS) {
2191 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
2192 ->isKindOfTypeAsWritten())
2193 return printAfter(T->getBaseType(), OS);
2194}
2195
2197 raw_ostream &OS) {
2199
2200
2203 if (HasEmptyPlaceHolder)
2204 OS << ' ';
2205 OS << '*';
2206 }
2207}
2208
2210 raw_ostream &OS) {}
2211
2212static
2214
2217}
2218
2220 llvm::raw_ostream &OS, bool IncludeType) {
2221 A.print(PP, OS, IncludeType);
2222}
2223
2226 bool IncludeType) {
2231}
2232
2236 unsigned Depth);
2237
2241 return true;
2242
2243
2245 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2248 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());
2250 }
2251 return false;
2252 }
2253
2254
2255
2256
2260 if (TQual != PatQual)
2261 return false;
2262
2263
2264 {
2267 if (!TPointee.isNull() && !PPointee.isNull())
2270 }
2271
2272
2273 if (auto *PTST =
2278 Template = TTST->getTemplateName();
2279 TemplateArgs = TTST->template_arguments();
2280 } else if (auto *CTSD = dyn_cast_or_null(
2282 Template = TemplateName(CTSD->getSpecializedTemplate());
2283 TemplateArgs = CTSD->getTemplateArgs().asArray();
2284 } else {
2285 return false;
2286 }
2287
2289 Args, Depth))
2290 return false;
2291 if (TemplateArgs.size() != PTST->template_arguments().size())
2292 return false;
2293 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2295 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2296 return false;
2297 return true;
2298 }
2299
2300
2301 return false;
2302}
2303
2304
2305
2310 return false;
2311
2312
2316 return false;
2317
2321
2325 return false;
2326
2329 }
2330
2331 return false;
2332}
2333
2337 unsigned Depth) {
2341 return true;
2342
2344 if (auto *DRE =
2346 if (auto *NTTP = dyn_cast(DRE->getDecl()))
2347 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2348 Args[NTTP->getIndex()].structurallyEquals(Arg);
2349 }
2350 }
2351
2353 return true;
2354
2356 return false;
2357
2360 Depth);
2361
2364 if (auto *TTPD = dyn_cast_or_null(PatTD))
2365 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2368 }
2369
2370
2371 return false;
2372}
2373
2377 unsigned Depth) {
2378
2380 return true;
2381
2382 if (auto *TTPD = dyn_cast(Param)) {
2383 return TTPD->hasDefaultArgument() &&
2385 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2386 } else if (auto *TTPD = dyn_cast(Param)) {
2387 return TTPD->hasDefaultArgument() &&
2389 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2390 } else if (auto *NTTPD = dyn_cast(Param)) {
2391 return NTTPD->hasDefaultArgument() &&
2393 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2394 Depth);
2395 }
2396 return false;
2397}
2398
2399template
2400static void
2403
2406 Args.size() <= TPL->size()) {
2408 for (const TA &A : Args)
2411 Args = Args.drop_back();
2412 }
2413
2414 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
2415 if (!IsPack)
2416 OS << '<';
2417
2418 bool NeedSpace = false;
2419 bool FirstArg = true;
2420 for (const auto &Arg : Args) {
2421
2423 llvm::raw_svector_ostream ArgOS(Buf);
2426 if (Argument.pack_size() && !FirstArg)
2427 OS << Comma;
2429 true, ParmIndex);
2430 } else {
2431 if (!FirstArg)
2432 OS << Comma;
2433
2436 Policy, TPL, ParmIndex));
2437 }
2438 StringRef ArgString = ArgOS.str();
2439
2440
2441
2442
2443 if (FirstArg && ArgString.starts_with(":"))
2444 OS << ' ';
2445
2446 OS << ArgString;
2447
2448
2449
2450 if (!ArgString.empty()) {
2452 FirstArg = false;
2453 }
2454
2455
2456 if (!IsPack)
2457 ParmIndex++;
2458 }
2459
2460 if (!IsPack) {
2461 if (NeedSpace)
2462 OS << ' ';
2463 OS << '>';
2464 }
2465}
2466
2472}
2473
2478 printTo(OS, Args, Policy, TPL, false, 0);
2479}
2480
2485 printTo(OS, Args, Policy, TPL, false, 0);
2486}
2487
2491}
2492
2493
2494
2495
2498 llvm::raw_svector_ostream StrOS(Buf);
2499 print(StrOS, Policy);
2500 return std::string(StrOS.str());
2501}
2502
2505 return false;
2506
2508 return false;
2509
2511 return false;
2512
2515 return false;
2516
2517 return true;
2518}
2519
2521 switch (AS) {
2523 return "";
2526 return "__global";
2529 return "__local";
2532 return "__private";
2534 return "__constant";
2536 return "__generic";
2539 return "__global_device";
2542 return "__global_host";
2544 return "__device__";
2546 return "__constant__";
2548 return "__shared__";
2550 return "__sptr __ptr32";
2552 return "__uptr __ptr32";
2554 return "__ptr64";
2556 return "__funcref";
2558 return "groupshared";
2559 default:
2561 }
2562}
2563
2564
2565
2566
2568 bool appendSpaceIfNonEmpty) const {
2569 bool addSpace = false;
2570
2572 if (quals) {
2574 addSpace = true;
2575 }
2577 if (addSpace)
2578 OS << ' ';
2579 OS << "__unaligned";
2580 addSpace = true;
2581 }
2583 if (!ASStr.empty()) {
2584 if (addSpace)
2585 OS << ' ';
2586 addSpace = true;
2587
2589 OS << "__attribute__((address_space(" << ASStr << ")))";
2590 else
2591 OS << ASStr;
2592 }
2593
2595 if (addSpace)
2596 OS << ' ';
2597 addSpace = true;
2599 OS << "__weak";
2600 else
2601 OS << "__strong";
2602 }
2605 if (addSpace)
2606 OS << ' ';
2607 addSpace = true;
2608 }
2609
2610 switch (lifetime) {
2615 OS << "__strong";
2616 break;
2617
2620 }
2621 }
2622
2623 if (appendSpaceIfNonEmpty && addSpace)
2624 OS << ' ';
2625}
2626
2629}
2630
2632 std::string S;
2634 return S;
2635}
2636
2639 std::string buffer;
2641 return buffer;
2642}
2643
2645 const Twine &PlaceHolder, unsigned Indentation) const {
2647 Indentation);
2648}
2649
2652 const Twine &PlaceHolder, unsigned Indentation) {
2654 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2655
2656 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2657}
2658
2662 Policy);
2663}
2664
2666 std::string &buffer,
2669 llvm::raw_svector_ostream StrOS(Buf);
2670 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2671 std::string str = std::string(StrOS.str());
2672 buffer.swap(str);
2673}
2674
2677 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, "");
2678 return OS;
2679}
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)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
static void printTo(raw_ostream &OS, ArrayRef< TA > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex)
static const TemplateArgument & getArgument(const TemplateArgument &A)
static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, llvm::raw_ostream &OS, bool IncludeType)
static QualType skipTopLevelReferences(QualType T)
static void printCountAttributedImpl(const CountAttributedType *T, raw_ostream &OS, const PrintingPolicy &Policy)
static SplitQualType splitAccordingToPolicy(QualType QT, const PrintingPolicy &Policy)
static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg, TemplateArgument Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)
static bool templateArgumentExpressionsEqual(ASTContext const &Ctx, TemplateArgument const &Pattern, TemplateArgument const &Arg)
Evaluates the expression template argument 'Pattern' and returns true if 'Arg' evaluates to the same ...
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const
Retrieve the "canonical" template argument.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Represents a constant array type that does not decay to a pointer when used as a function parameter.
An attributed type is a type to which a type attribute has been applied.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
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...
Represents a pointer type decayed from an array or function type.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
bool isFunctionOrMethod() const
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
SourceLocation getLocation() const
DeclContext * getDeclContext()
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
The name of a declaration.
Represents the type decltype(expr) (C++11).
Represents a C++17 deduced template specialization type.
Represents an extended address space qualifier where the input address space value is dependent.
Represents a qualified type name for which the type name is dependent.
Represents an array type in C++ whose size is a value-dependent expression.
Represents an extended vector type where either the type or size is dependent.
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Represents a template specialization type whose template cannot be resolved, e.g.
Represents a vector type where either the type or size is dependent.
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
ExtVectorType - Extended vector type.
An immutable set of FunctionEffects and possibly conditions attached to them.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Represents a prototype with parameter type info, e.g.
ExtParameterInfo getExtParameterInfo(unsigned I) const
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
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().
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.
A class which abstracts out some details necessary for making a call.
CallingConv getCC() const
bool getCmseNSCall() const
bool getNoCfCheck() const
unsigned getRegParm() const
bool getNoCallerSavedRegs() const
bool getProducesResult() const
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Represents a C array with an unspecified size.
The injected class name of a C++ class template or class template partial specialization.
An lvalue reference type, per C++11 [dcl.ref].
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ nested name specifier, such as "\::std::vector::".
Interfaces are the core concept in Objective-C for object oriented design.
Represents a pointer to an Objective C object.
Represents a class type in Objective C.
Represents a type parameter type in Objective C.
Represents a pack expansion of types.
Sugar for parentheses used when specifying types.
PointerType - C99 6.7.5.1 - Pointer Declarators.
Represents an unpacked "presumed" location which can be presented to the user.
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
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
std::string getAsString() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
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
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
ObjCLifetime getObjCLifetime() const
std::string getAsString() const
LangAS getAddressSpace() const
static std::string getAddrSpaceAsString(LangAS AS)
An rvalue reference type, per C++11 [dcl.ref].
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
Represents the result of substituting a set of types for a template type parameter pack.
Represents the result of substituting a type for a template type parameter.
Represents the declaration of a struct/union/class/enum.
A convenient class for passing around template argument information.
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
TypeSourceInfo * getTypeSourceInfo() const
Represents a template argument.
ArrayRef< TemplateArgument > getPackAsArray() const
Return the array of arguments in this template argument pack.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
bool getIsDefaulted() const
If returns 'true', this TemplateArgument corresponds to a default template parameter.
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.
Stores a list of template parameters for a TemplateDecl and its derived classes.
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
Represents a type template specialization; the template must be a class template, a type alias templa...
Declaration of a template type parameter.
const Type * getTypeForDecl() const
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
QualType getType() const
Return the type wrapped by this type source info.
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs'.
Base class for declarations which introduce a typedef-name.
A unary type transform, which is a type constructed from another.
Represents the dependent type named by a dependently-scoped typename using declaration,...
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
The JSON file list parser is used to communicate input to InstallAPI.
@ GNUAutoType
__auto_type (GNU extension)
@ DecltypeAuto
decltype(auto)
llvm::StringRef getParameterABISpelling(ParameterABI kind)
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 (&&).
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
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.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg, const NamedDecl *Param, ArrayRef< TemplateArgument > Args, unsigned Depth)
Make a best-effort determination of whether the type T can be produced by substituting Args into the ...
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
@ None
No keyword precedes the qualified type name.
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_MSAny
Microsoft throw(...) extension.
Represents an explicit template argument list in C++, e.g., the "" in "sort".
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
llvm::dxil::ResourceClass ResourceClass
Describes how types, statements, expressions, and declarations should be printed.
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 PrintCanonicalTypes
Whether to print types as written or canonically.
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 SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned Restrict
Whether we can use 'restrict' rather than '__restrict'.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned SuppressLifetimeQualifiers
When true, suppress printing of lifetime qualifier in ARC.
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.