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"
53class IncludeStrongLifetimeRAII {
59 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
67class ParamPolicyRAII {
73 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
80class DefaultTemplateArgsPolicyRAII {
86 : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {
93class ElaboratedTypePolicyRAII {
95 bool SuppressTagKeyword;
99 explicit ElaboratedTypePolicyRAII(
PrintingPolicy &Policy) : Policy(Policy) {
106 ~ElaboratedTypePolicyRAII() {
114 unsigned Indentation;
115 bool HasEmptyPlaceHolder =
false;
116 bool InsideCCAttribute =
false;
119 explicit TypePrinter(
const PrintingPolicy &Policy,
unsigned Indentation = 0)
120 : Policy(Policy), Indentation(Indentation) {}
123 StringRef PlaceHolder);
126 static bool canPrefixQualifiers(
const Type *
T,
bool &NeedARCStrongQualifier);
127 void spaceBeforePlaceHolder(raw_ostream &OS);
128 void printTypeSpec(
NamedDecl *
D, raw_ostream &OS);
132 void printBefore(
QualType T, raw_ostream &OS);
133 void printAfter(
QualType T, raw_ostream &OS);
136 void printTagType(
const TagType *
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"
152 bool HasRestrictKeyword) {
153 bool appendSpace =
false;
159 if (appendSpace) OS <<
' ';
164 if (appendSpace) OS <<
' ';
165 if (HasRestrictKeyword) {
173void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
174 if (!HasEmptyPlaceHolder)
185void TypePrinter::print(
QualType t, raw_ostream &OS, StringRef PlaceHolder) {
190void TypePrinter::print(
const Type *
T,
Qualifiers Quals, raw_ostream &OS,
191 StringRef PlaceHolder) {
199 printBefore(
T, Quals, OS);
201 printAfter(
T, Quals, OS);
204bool TypePrinter::canPrefixQualifiers(
const Type *
T,
205 bool &NeedARCStrongQualifier) {
211 bool CanPrefixQualifiers =
false;
212 NeedARCStrongQualifier =
false;
213 const Type *UnderlyingType =
T;
214 if (
const auto *AT = dyn_cast<AutoType>(
T))
215 UnderlyingType = AT->desugar().getTypePtr();
216 if (
const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(
T))
217 UnderlyingType = Subst->getReplacementType().getTypePtr();
224 case Type::UnresolvedUsing:
227 case Type::TypeOfExpr:
230 case Type::UnaryTransform:
233 case Type::TemplateTypeParm:
234 case Type::SubstTemplateTypeParmPack:
235 case Type::SubstBuiltinTemplatePack:
236 case Type::DeducedTemplateSpecialization:
237 case Type::TemplateSpecialization:
238 case Type::InjectedClassName:
239 case Type::DependentName:
240 case Type::DependentTemplateSpecialization:
241 case Type::ObjCObject:
242 case Type::ObjCTypeParam:
243 case Type::ObjCInterface:
247 case Type::DependentBitInt:
248 case Type::BTFTagAttributed:
249 case Type::HLSLAttributedResource:
250 case Type::HLSLInlineSpirv:
251 case Type::PredefinedSugar:
252 CanPrefixQualifiers =
true;
255 case Type::ObjCObjectPointer:
260 case Type::VariableArray:
261 case Type::DependentSizedArray:
262 NeedARCStrongQualifier =
true;
265 case Type::ConstantArray:
266 case Type::IncompleteArray:
267 return canPrefixQualifiers(
268 cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),
269 NeedARCStrongQualifier);
273 case Type::ArrayParameter:
275 case Type::BlockPointer:
276 case Type::LValueReference:
277 case Type::RValueReference:
278 case Type::MemberPointer:
279 case Type::DependentAddressSpace:
280 case Type::DependentVector:
281 case Type::DependentSizedExtVector:
283 case Type::ExtVector:
284 case Type::ConstantMatrix:
285 case Type::DependentSizedMatrix:
286 case Type::FunctionProto:
287 case Type::FunctionNoProto:
289 case Type::PackExpansion:
290 case Type::SubstTemplateTypeParm:
291 case Type::MacroQualified:
292 case Type::CountAttributed:
293 CanPrefixQualifiers =
false;
296 case Type::Attributed: {
299 const auto *AttrTy = cast<AttributedType>(UnderlyingType);
300 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
303 case Type::PackIndexing: {
304 return canPrefixQualifiers(
305 cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),
306 NeedARCStrongQualifier);
310 return CanPrefixQualifiers;
313void TypePrinter::printBefore(
QualType T, raw_ostream &OS) {
319 if (
const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(
Split.Ty))
322 printBefore(
Split.Ty, Quals, OS);
327void TypePrinter::printBefore(
const Type *
T,
Qualifiers Quals, raw_ostream &OS) {
335 bool CanPrefixQualifiers =
false;
336 bool NeedARCStrongQualifier =
false;
337 CanPrefixQualifiers = canPrefixQualifiers(
T, NeedARCStrongQualifier);
339 if (CanPrefixQualifiers && !Quals.
empty()) {
340 if (NeedARCStrongQualifier) {
341 IncludeStrongLifetimeRAII Strong(Policy);
342 Quals.
print(OS, Policy,
true);
344 Quals.
print(OS, Policy,
true);
348 bool hasAfterQuals =
false;
349 if (!CanPrefixQualifiers && !Quals.
empty()) {
352 HasEmptyPlaceHolder =
false;
356#define ABSTRACT_TYPE(CLASS, PARENT)
357#define TYPE(CLASS, PARENT) case Type::CLASS: \
358 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
360#include "clang/AST/TypeNodes.inc"
364 if (NeedARCStrongQualifier) {
365 IncludeStrongLifetimeRAII Strong(Policy);
366 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
368 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
373void TypePrinter::printAfter(
QualType t, raw_ostream &OS) {
375 printAfter(split.
Ty, split.
Quals, OS);
380void TypePrinter::printAfter(
const Type *
T,
Qualifiers Quals, raw_ostream &OS) {
382#define ABSTRACT_TYPE(CLASS, PARENT)
383#define TYPE(CLASS, PARENT) case Type::CLASS: \
384 print##CLASS##After(cast<CLASS##Type>(T), OS); \
386#include "clang/AST/TypeNodes.inc"
390void TypePrinter::printBuiltinBefore(
const BuiltinType *
T, raw_ostream &OS) {
391 OS <<
T->getName(Policy);
392 spaceBeforePlaceHolder(OS);
395void TypePrinter::printBuiltinAfter(
const BuiltinType *
T, raw_ostream &OS) {}
397void TypePrinter::printComplexBefore(
const ComplexType *
T, raw_ostream &OS) {
399 printBefore(
T->getElementType(), OS);
402void TypePrinter::printComplexAfter(
const ComplexType *
T, raw_ostream &OS) {
403 printAfter(
T->getElementType(), OS);
406void TypePrinter::printPointerBefore(
const PointerType *
T, raw_ostream &OS) {
407 IncludeStrongLifetimeRAII Strong(Policy);
417void TypePrinter::printPointerAfter(
const PointerType *
T, raw_ostream &OS) {
418 IncludeStrongLifetimeRAII Strong(Policy);
450 IncludeStrongLifetimeRAII Strong(Policy);
453 printBefore(Inner, OS);
456 if (isa<ArrayType>(Inner))
463 IncludeStrongLifetimeRAII Strong(Policy);
468 if (isa<ArrayType>(Inner))
470 printAfter(Inner, OS);
475 IncludeStrongLifetimeRAII Strong(Policy);
478 printBefore(Inner, OS);
481 if (isa<ArrayType>(Inner))
488 IncludeStrongLifetimeRAII Strong(Policy);
493 if (isa<ArrayType>(Inner))
495 printAfter(Inner, OS);
500 IncludeStrongLifetimeRAII Strong(Policy);
507 T->getQualifier().print(OS, Policy);
513 IncludeStrongLifetimeRAII Strong(Policy);
524 IncludeStrongLifetimeRAII Strong(Policy);
525 printBefore(
T->getElementType(), OS);
531 if (
T->getIndexTypeQualifiers().hasQualifiers()) {
537 if (
T->getSizeModifier() == ArraySizeModifier::Static)
540 OS <<
T->getZExtSize() <<
']';
541 printAfter(
T->getElementType(), OS);
546 IncludeStrongLifetimeRAII Strong(Policy);
547 printBefore(
T->getElementType(), OS);
553 printAfter(
T->getElementType(), OS);
558 IncludeStrongLifetimeRAII Strong(Policy);
559 printBefore(
T->getElementType(), OS);
565 if (
T->getIndexTypeQualifiers().hasQualifiers()) {
570 if (
T->getSizeModifier() == ArraySizeModifier::Static)
572 else if (
T->getSizeModifier() == ArraySizeModifier::Star)
575 if (
T->getSizeExpr())
576 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
579 printAfter(
T->getElementType(), OS);
582void TypePrinter::printAdjustedBefore(
const AdjustedType *
T, raw_ostream &OS) {
585 printBefore(
T->getAdjustedType(), OS);
588void TypePrinter::printAdjustedAfter(
const AdjustedType *
T, raw_ostream &OS) {
589 printAfter(
T->getAdjustedType(), OS);
592void TypePrinter::printDecayedBefore(
const DecayedType *
T, raw_ostream &OS) {
594 printAdjustedBefore(
T, OS);
599 printConstantArrayAfter(
T, OS);
604 printConstantArrayBefore(
T, OS);
607void TypePrinter::printDecayedAfter(
const DecayedType *
T, raw_ostream &OS) {
608 printAdjustedAfter(
T, OS);
611void TypePrinter::printDependentSizedArrayBefore(
614 IncludeStrongLifetimeRAII Strong(Policy);
615 printBefore(
T->getElementType(), OS);
618void TypePrinter::printDependentSizedArrayAfter(
622 if (
T->getSizeExpr())
623 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
625 printAfter(
T->getElementType(), OS);
628void TypePrinter::printDependentAddressSpaceBefore(
633void TypePrinter::printDependentAddressSpaceAfter(
635 OS <<
" __attribute__((address_space(";
636 if (
T->getAddrSpaceExpr())
637 T->getAddrSpaceExpr()->printPretty(OS,
nullptr, Policy);
642void TypePrinter::printDependentSizedExtVectorBefore(
645 if (Policy.UseHLSLTypes)
647 printBefore(
T->getElementType(), OS);
650void TypePrinter::printDependentSizedExtVectorAfter(
653 if (Policy.UseHLSLTypes) {
655 if (
T->getSizeExpr())
656 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
659 OS <<
" __attribute__((ext_vector_type(";
660 if (
T->getSizeExpr())
661 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
664 printAfter(
T->getElementType(), OS);
667void TypePrinter::printVectorBefore(
const VectorType *
T, raw_ostream &OS) {
668 switch (
T->getVectorKind()) {
669 case VectorKind::AltiVecPixel:
670 OS <<
"__vector __pixel ";
672 case VectorKind::AltiVecBool:
673 OS <<
"__vector __bool ";
674 printBefore(
T->getElementType(), OS);
676 case VectorKind::AltiVecVector:
678 printBefore(
T->getElementType(), OS);
680 case VectorKind::Neon:
681 OS <<
"__attribute__((neon_vector_type("
682 <<
T->getNumElements() <<
"))) ";
683 printBefore(
T->getElementType(), OS);
685 case VectorKind::NeonPoly:
686 OS <<
"__attribute__((neon_polyvector_type(" <<
687 T->getNumElements() <<
"))) ";
688 printBefore(
T->getElementType(), OS);
690 case VectorKind::Generic: {
693 OS <<
"__attribute__((__vector_size__("
694 <<
T->getNumElements()
696 print(
T->getElementType(), OS, StringRef());
698 printBefore(
T->getElementType(), OS);
701 case VectorKind::SveFixedLengthData:
702 case VectorKind::SveFixedLengthPredicate:
705 OS <<
"__attribute__((__arm_sve_vector_bits__(";
707 if (
T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
710 OS <<
T->getNumElements() * 8;
712 OS <<
T->getNumElements();
715 print(
T->getElementType(), OS, StringRef());
718 printBefore(
T->getElementType(), OS);
720 case VectorKind::RVVFixedLengthData:
721 case VectorKind::RVVFixedLengthMask:
722 case VectorKind::RVVFixedLengthMask_1:
723 case VectorKind::RVVFixedLengthMask_2:
724 case VectorKind::RVVFixedLengthMask_4:
727 OS <<
"__attribute__((__riscv_rvv_vector_bits__(";
729 OS <<
T->getNumElements();
732 print(
T->getElementType(), OS, StringRef());
735 printBefore(
T->getElementType(), OS);
740void TypePrinter::printVectorAfter(
const VectorType *
T, raw_ostream &OS) {
741 printAfter(
T->getElementType(), OS);
744void TypePrinter::printDependentVectorBefore(
746 switch (
T->getVectorKind()) {
747 case VectorKind::AltiVecPixel:
748 OS <<
"__vector __pixel ";
750 case VectorKind::AltiVecBool:
751 OS <<
"__vector __bool ";
752 printBefore(
T->getElementType(), OS);
754 case VectorKind::AltiVecVector:
756 printBefore(
T->getElementType(), OS);
758 case VectorKind::Neon:
759 OS <<
"__attribute__((neon_vector_type(";
760 if (
T->getSizeExpr())
761 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
763 printBefore(
T->getElementType(), OS);
765 case VectorKind::NeonPoly:
766 OS <<
"__attribute__((neon_polyvector_type(";
767 if (
T->getSizeExpr())
768 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
770 printBefore(
T->getElementType(), OS);
772 case VectorKind::Generic: {
775 OS <<
"__attribute__((__vector_size__(";
776 if (
T->getSizeExpr())
777 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
779 print(
T->getElementType(), OS, StringRef());
781 printBefore(
T->getElementType(), OS);
784 case VectorKind::SveFixedLengthData:
785 case VectorKind::SveFixedLengthPredicate:
788 OS <<
"__attribute__((__arm_sve_vector_bits__(";
789 if (
T->getSizeExpr()) {
790 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
791 if (
T->getVectorKind() == VectorKind::SveFixedLengthPredicate)
796 print(
T->getElementType(), OS, StringRef());
801 printBefore(
T->getElementType(), OS);
803 case VectorKind::RVVFixedLengthData:
804 case VectorKind::RVVFixedLengthMask:
805 case VectorKind::RVVFixedLengthMask_1:
806 case VectorKind::RVVFixedLengthMask_2:
807 case VectorKind::RVVFixedLengthMask_4:
810 OS <<
"__attribute__((__riscv_rvv_vector_bits__(";
811 if (
T->getSizeExpr()) {
812 T->getSizeExpr()->printPretty(OS,
nullptr, Policy);
814 print(
T->getElementType(), OS, StringRef());
819 printBefore(
T->getElementType(), OS);
824void TypePrinter::printDependentVectorAfter(
826 printAfter(
T->getElementType(), OS);
831 if (Policy.UseHLSLTypes)
833 printBefore(
T->getElementType(), OS);
836void TypePrinter::printExtVectorAfter(
const ExtVectorType *
T, raw_ostream &OS) {
837 printAfter(
T->getElementType(), OS);
839 if (Policy.UseHLSLTypes) {
841 OS <<
T->getNumElements();
844 OS <<
" __attribute__((ext_vector_type(";
845 OS <<
T->getNumElements();
852 printBefore(
T->getElementType(), OS);
853 OS <<
" __attribute__((matrix_type(";
854 OS <<
T->getNumRows() <<
", " <<
T->getNumColumns();
860 printAfter(
T->getElementType(), OS);
863void TypePrinter::printDependentSizedMatrixBefore(
865 printBefore(
T->getElementType(), OS);
866 OS <<
" __attribute__((matrix_type(";
867 if (
T->getRowExpr()) {
868 T->getRowExpr()->printPretty(OS,
nullptr, Policy);
871 if (
T->getColumnExpr()) {
872 T->getColumnExpr()->printPretty(OS,
nullptr, Policy);
877void TypePrinter::printDependentSizedMatrixAfter(
879 printAfter(
T->getElementType(), OS);
899 OS <<
" __attribute__((nothrow))";
917 if (!HasEmptyPlaceHolder)
923 if (!PrevPHIsEmpty.get())
931 llvm_unreachable(
"asking for spelling of ordinary parameter ABI");
933 return "swift_context";
935 return "swift_async_context";
937 return "swift_error_result";
939 return "swift_indirect_result";
945 llvm_unreachable(
"bad parameter ABI kind");
951 if (!HasEmptyPlaceHolder)
957 ParamPolicyRAII ParamPolicy(Policy);
962 if (EPI.isConsumed()) OS <<
"__attribute__((ns_consumed)) ";
963 if (EPI.isNoEscape())
964 OS <<
"__attribute__((noescape)) ";
965 auto ABI = EPI.getABI();
968 if (Policy.UseHLSLTypes) {
987 }
else if (
T->
getNumParams() == 0 && Policy.UseVoidForZeroParams) {
998 OS <<
" __arm_streaming_compatible";
1000 OS <<
" __arm_streaming";
1002 OS <<
"__arm_agnostic(\"sme_za_state\")";
1004 OS <<
" __arm_preserves(\"za\")";
1006 OS <<
" __arm_in(\"za\")";
1008 OS <<
" __arm_out(\"za\")";
1010 OS <<
" __arm_inout(\"za\")";
1012 OS <<
" __arm_preserves(\"zt0\")";
1014 OS <<
" __arm_in(\"zt0\")";
1016 OS <<
" __arm_out(\"zt0\")";
1018 OS <<
" __arm_inout(\"zt0\")";
1020 printFunctionAfter(Info, OS);
1040 for (
const auto &CFE : FX) {
1041 OS <<
" __attribute__((" << CFE.Effect.name();
1042 if (
const Expr *
E = CFE.Cond.getCondition()) {
1051 OS <<
" __attribute__((cfi_unchecked_callee))";
1062 if (!InsideCCAttribute) {
1063 switch (Info.
getCC()) {
1074 OS <<
" __attribute__((stdcall))";
1077 OS <<
" __attribute__((fastcall))";
1080 OS <<
" __attribute__((thiscall))";
1083 OS <<
" __attribute__((vectorcall))";
1086 OS <<
" __attribute__((pascal))";
1089 OS <<
" __attribute__((pcs(\"aapcs\")))";
1092 OS <<
" __attribute__((pcs(\"aapcs-vfp\")))";
1095 OS <<
" __attribute__((aarch64_vector_pcs))";
1098 OS <<
" __attribute__((aarch64_sve_pcs))";
1101 OS <<
" __attribute__((device_kernel))";
1104 OS <<
" __attribute__((intel_ocl_bicc))";
1107 OS <<
" __attribute__((ms_abi))";
1110 OS <<
" __attribute__((sysv_abi))";
1113 OS <<
" __attribute__((regcall))";
1119 OS <<
" __attribute__((swiftcall))";
1122 OS <<
"__attribute__((swiftasynccall))";
1125 OS <<
" __attribute__((preserve_most))";
1128 OS <<
" __attribute__((preserve_all))";
1131 OS <<
" __attribute__((m68k_rtd))";
1134 OS <<
" __attribute__((preserve_none))";
1137 OS <<
"__attribute__((riscv_vector_cc))";
1139#define CC_VLS_CASE(ABI_VLEN) \
1140 case CC_RISCVVLSCall_##ABI_VLEN: \
1141 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \
1160 OS <<
" __attribute__((noreturn))";
1162 OS <<
" __attribute__((cmse_nonsecure_call))";
1164 OS <<
" __attribute__((ns_returns_retained))";
1166 OS <<
" __attribute__((regparm ("
1169 OS <<
" __attribute__((no_caller_saved_registers))";
1171 OS <<
" __attribute__((nocf_check))";
1179 if (!PrevPHIsEmpty.get())
1186 if (!HasEmptyPlaceHolder)
1195void TypePrinter::printTypeSpec(
NamedDecl *
D, raw_ostream &OS) {
1200 if (!Policy.SuppressScope)
1205 spaceBeforePlaceHolder(OS);
1213 auto *
D =
T->getDecl();
1217 T->getQualifier().print(OS, Policy);
1219 OS <<
D->getIdentifier()->getName();
1220 spaceBeforePlaceHolder(OS);
1226void TypePrinter::printUsingBefore(
const UsingType *
T, raw_ostream &OS) {
1230 auto *
D =
T->getDecl();
1231 if (Policy.FullyQualifiedName) {
1234 T->getQualifier().print(OS, Policy);
1236 OS <<
D->getIdentifier()->getName();
1237 spaceBeforePlaceHolder(OS);
1240void TypePrinter::printUsingAfter(
const UsingType *
T, raw_ostream &OS) {}
1242void TypePrinter::printTypedefBefore(
const TypedefType *
T, raw_ostream &OS) {
1246 auto *
D =
T->getDecl();
1247 if (Policy.FullyQualifiedName) {
1250 T->getQualifier().print(OS, Policy);
1252 OS <<
D->getIdentifier()->getName();
1253 spaceBeforePlaceHolder(OS);
1258 StringRef MacroName =
T->getMacroIdentifier()->getName();
1259 OS << MacroName <<
" ";
1263 printBefore(
T->getModifiedType(), OS);
1268 printAfter(
T->getModifiedType(), OS);
1271void TypePrinter::printTypedefAfter(
const TypedefType *
T, raw_ostream &OS) {}
1277 if (
T->getUnderlyingExpr())
1278 T->getUnderlyingExpr()->printPretty(OS,
nullptr, Policy);
1279 spaceBeforePlaceHolder(OS);
1285void TypePrinter::printTypeOfBefore(
const TypeOfType *
T, raw_ostream &OS) {
1288 print(
T->getUnmodifiedType(), OS, StringRef());
1290 spaceBeforePlaceHolder(OS);
1293void TypePrinter::printTypeOfAfter(
const TypeOfType *
T, raw_ostream &OS) {}
1295void TypePrinter::printDecltypeBefore(
const DecltypeType *
T, raw_ostream &OS) {
1297 if (
const Expr *
E =
T->getUnderlyingExpr()) {
1303 spaceBeforePlaceHolder(OS);
1308 if (
T->hasSelectedType()) {
1309 OS <<
T->getSelectedType();
1311 OS <<
T->getPattern() <<
"...[";
1312 T->getIndexExpr()->printPretty(OS,
nullptr, Policy);
1315 spaceBeforePlaceHolder(OS);
1321void TypePrinter::printDecltypeAfter(
const DecltypeType *
T, raw_ostream &OS) {}
1325 IncludeStrongLifetimeRAII Strong(Policy);
1327 static llvm::DenseMap<int, const char *> Transformation = {{
1328#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1329 {UnaryTransformType::Enum, "__" #Trait},
1330#include "clang/Basic/TransformTypeTraits.def"
1332 OS << Transformation[
T->getUTTKind()] <<
'(';
1333 print(
T->getBaseType(), OS, StringRef());
1335 spaceBeforePlaceHolder(OS);
1341void TypePrinter::printAutoBefore(
const AutoType *
T, raw_ostream &OS) {
1343 if (!
T->getDeducedType().isNull()) {
1344 printBefore(
T->getDeducedType(), OS);
1346 if (
T->isConstrained()) {
1349 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);
1350 auto Args =
T->getTypeConstraintArguments();
1354 T->getTypeConstraintConcept()->getTemplateParameters());
1357 switch (
T->getKeyword()) {
1362 spaceBeforePlaceHolder(OS);
1366void TypePrinter::printAutoAfter(
const AutoType *
T, raw_ostream &OS) {
1368 if (!
T->getDeducedType().isNull())
1369 printAfter(
T->getDeducedType(), OS);
1372void TypePrinter::printDeducedTemplateSpecializationBefore(
1387 if (!
T->getDeducedType().isNull()) {
1388 if (
const auto *TST =
1389 dyn_cast<TemplateSpecializationType>(
T->getDeducedType())) {
1390 DeducedTD = TST->getTemplateName().getAsTemplateDecl(
1392 Args = TST->template_arguments();
1395 const auto *CD = cast<ClassTemplateSpecializationDecl>(
1396 cast<RecordType>(
T->getDeducedType())->getOriginalDecl());
1397 DeducedTD = CD->getSpecializedTemplate();
1398 Args = CD->getTemplateArgs().asArray();
1412 IncludeStrongLifetimeRAII Strong(Policy);
1413 Name.print(OS, Policy);
1420 spaceBeforePlaceHolder(OS);
1423void TypePrinter::printDeducedTemplateSpecializationAfter(
1426 if (!
T->getDeducedType().isNull())
1427 printAfter(
T->getDeducedType(), OS);
1430void TypePrinter::printAtomicBefore(
const AtomicType *
T, raw_ostream &OS) {
1431 IncludeStrongLifetimeRAII Strong(Policy);
1434 print(
T->getValueType(), OS, StringRef());
1436 spaceBeforePlaceHolder(OS);
1439void TypePrinter::printAtomicAfter(
const AtomicType *
T, raw_ostream &OS) {}
1441void TypePrinter::printPipeBefore(
const PipeType *
T, raw_ostream &OS) {
1442 IncludeStrongLifetimeRAII Strong(Policy);
1444 if (
T->isReadOnly())
1447 OS <<
"write_only ";
1449 print(
T->getElementType(), OS, StringRef());
1450 spaceBeforePlaceHolder(OS);
1453void TypePrinter::printPipeAfter(
const PipeType *
T, raw_ostream &OS) {}
1455void TypePrinter::printBitIntBefore(
const BitIntType *
T, raw_ostream &OS) {
1456 if (
T->isUnsigned())
1458 OS <<
"_BitInt(" <<
T->getNumBits() <<
")";
1459 spaceBeforePlaceHolder(OS);
1462void TypePrinter::printBitIntAfter(
const BitIntType *
T, raw_ostream &OS) {}
1466 if (
T->isUnsigned())
1469 T->getNumBitsExpr()->printPretty(OS,
nullptr, Policy);
1471 spaceBeforePlaceHolder(OS);
1479 OS <<
T->getIdentifier()->getName();
1480 spaceBeforePlaceHolder(OS);
1487void TypePrinter::AppendScope(
DeclContext *DC, raw_ostream &OS,
1497 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))
1500 if (
const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1501 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1502 return AppendScope(DC->
getParent(), OS, NameInScope);
1506 if (Policy.SuppressInlineNamespace !=
1508 NS->isInline() && NameInScope &&
1509 NS->isRedundantInlineQualifierFor(NameInScope))
1510 return AppendScope(DC->
getParent(), OS, NameInScope);
1512 AppendScope(DC->
getParent(), OS, NS->getDeclName());
1513 if (NS->getIdentifier())
1514 OS << NS->getName() <<
"::";
1516 OS <<
"(anonymous namespace)::";
1517 }
else if (
const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1518 AppendScope(DC->
getParent(), OS, Spec->getDeclName());
1519 IncludeStrongLifetimeRAII Strong(Policy);
1520 OS << Spec->getIdentifier()->getName();
1523 OS, TemplateArgs.
asArray(), Policy,
1524 Spec->getSpecializedTemplate()->getTemplateParameters());
1526 }
else if (
const auto *Tag = dyn_cast<TagDecl>(DC)) {
1529 OS <<
Typedef->getIdentifier()->getName() <<
"::";
1530 else if (
Tag->getIdentifier())
1531 OS <<
Tag->getIdentifier()->getName() <<
"::";
1535 AppendScope(DC->
getParent(), OS, NameInScope);
1539void TypePrinter::printTagType(
const TagType *
T, raw_ostream &OS) {
1542 if (Policy.IncludeTagDefinition &&
T->isTagOwned()) {
1543 D->
print(OS, Policy, Indentation);
1544 spaceBeforePlaceHolder(OS);
1548 bool HasKindDecoration =
false;
1551 if (!Policy.SuppressTagKeyword && !
D->getTypedefNameForAnonDecl()) {
1552 HasKindDecoration =
true;
1553 OS <<
D->getKindName();
1563 T->getQualifier().print(OS, Policy);
1564 }
else if (!Policy.SuppressScope) {
1574 assert(
Typedef->getIdentifier() &&
"Typedef without identifier?");
1575 OS <<
Typedef->getIdentifier()->getName();
1579 OS << (Policy.MSVCFormatting ?
'`' :
'(');
1581 if (isa<CXXRecordDecl>(
D) && cast<CXXRecordDecl>(
D)->isLambda()) {
1583 HasKindDecoration =
true;
1584 }
else if ((isa<RecordDecl>(
D) && cast<RecordDecl>(
D)->isAnonymousStructOrUnion())) {
1590 if (Policy.AnonymousTagLocations) {
1594 if (!HasKindDecoration)
1595 OS <<
" " <<
D->getKindName();
1603 if (
auto *Callbacks = Policy.Callbacks)
1604 WrittenFile = Callbacks->remapPath(
File);
1608 llvm::sys::path::Style Style =
1609 llvm::sys::path::is_absolute(WrittenFile)
1610 ? llvm::sys::path::Style::native
1611 : (Policy.MSVCFormatting
1612 ? llvm::sys::path::Style::windows_backslash
1613 : llvm::sys::path::Style::posix);
1614 llvm::sys::path::native(WrittenFile, Style);
1619 OS << (Policy.MSVCFormatting ?
'\'' :
')');
1624 if (
auto *S = dyn_cast<ClassTemplateSpecializationDecl>(
D)) {
1626 S->getSpecializedTemplate()->getTemplateParameters();
1628 S->getTemplateArgsAsWritten();
1629 IncludeStrongLifetimeRAII Strong(Policy);
1630 if (TArgAsWritten && !Policy.PrintAsCanonical)
1638 spaceBeforePlaceHolder(OS);
1641void TypePrinter::printRecordBefore(
const RecordType *
T, raw_ostream &OS) {
1643 if (Policy.UsePreferredNames) {
1644 for (
const auto *PNA :
T->getOriginalDecl()
1645 ->getMostRecentDecl()
1646 ->specific_attrs<PreferredNameAttr>()) {
1648 T->getOriginalDecl()))
1653 if (
auto *TT = dyn_cast<TypedefType>(
T))
1654 return printTypeSpec(TT->getDecl(), OS);
1655 if (
auto *TST = dyn_cast<TemplateSpecializationType>(
T))
1656 return printTemplateId(TST, OS,
true);
1662 printTagType(
T, OS);
1665void TypePrinter::printRecordAfter(
const RecordType *
T, raw_ostream &OS) {}
1667void TypePrinter::printEnumBefore(
const EnumType *
T, raw_ostream &OS) {
1668 printTagType(
T, OS);
1671void TypePrinter::printEnumAfter(
const EnumType *
T, raw_ostream &OS) {}
1675 const ASTContext &Ctx =
T->getOriginalDecl()->getASTContext();
1676 IncludeStrongLifetimeRAII Strong(Policy);
1677 T->getTemplateName(Ctx).print(OS, Policy);
1678 if (Policy.PrintInjectedClassNameWithArguments) {
1679 auto *
Decl =
T->getOriginalDecl();
1682 if (
auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(
Decl)) {
1685 T->getTemplateDecl()->getTemplateParameters());
1691 T->getTemplateDecl()->getTemplateParameters());
1694 spaceBeforePlaceHolder(OS);
1704 if (
auto *TC =
D->getTypeConstraint()) {
1705 TC->print(OS, Policy);
1710 OS << (Policy.CleanUglifiedParameters ?
Id->deuglifiedName()
1713 OS <<
"type-parameter-" <<
T->getDepth() <<
'-' <<
T->getIndex();
1715 spaceBeforePlaceHolder(OS);
1721void TypePrinter::printSubstTemplateTypeParmBefore(
1724 IncludeStrongLifetimeRAII Strong(Policy);
1725 printBefore(
T->getReplacementType(), OS);
1728void TypePrinter::printSubstTemplateTypeParmAfter(
1731 IncludeStrongLifetimeRAII Strong(Policy);
1732 printAfter(
T->getReplacementType(), OS);
1735void TypePrinter::printSubstBuiltinTemplatePackBefore(
1737 IncludeStrongLifetimeRAII Strong(Policy);
1741void TypePrinter::printSubstBuiltinTemplatePackAfter(
1744void TypePrinter::printSubstTemplateTypeParmPackBefore(
1747 IncludeStrongLifetimeRAII Strong(Policy);
1750 if (
auto *TC =
D->getTypeConstraint()) {
1751 TC->print(OS, Policy);
1756 OS << (Policy.CleanUglifiedParameters ?
Id->deuglifiedName()
1759 OS <<
"type-parameter-" <<
D->getDepth() <<
'-' <<
D->getIndex();
1761 spaceBeforePlaceHolder(OS);
1765void TypePrinter::printSubstTemplateTypeParmPackAfter(
1768 IncludeStrongLifetimeRAII Strong(Policy);
1772 raw_ostream &OS,
bool FullyQualify) {
1773 IncludeStrongLifetimeRAII Strong(Policy);
1780 T->getTemplateName().getAsTemplateDecl(
true);
1782 if (FullyQualify && TD) {
1783 if (!Policy.SuppressScope)
1788 T->getTemplateName().print(OS, Policy,
1789 !Policy.SuppressScope
1794 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
1797 spaceBeforePlaceHolder(OS);
1800void TypePrinter::printTemplateSpecializationBefore(
1803 printTemplateId(
T, OS, Policy.FullyQualifiedName);
1806void TypePrinter::printTemplateSpecializationAfter(
1810void TypePrinter::printParenBefore(
const ParenType *
T, raw_ostream &OS) {
1811 if (!HasEmptyPlaceHolder && !isa<FunctionType>(
T->getInnerType())) {
1812 printBefore(
T->getInnerType(), OS);
1815 printBefore(
T->getInnerType(), OS);
1818void TypePrinter::printParenAfter(
const ParenType *
T, raw_ostream &OS) {
1819 if (!HasEmptyPlaceHolder && !isa<FunctionType>(
T->getInnerType())) {
1821 printAfter(
T->getInnerType(), OS);
1823 printAfter(
T->getInnerType(), OS);
1831 T->getQualifier().print(OS, Policy);
1832 OS <<
T->getIdentifier()->getName();
1833 spaceBeforePlaceHolder(OS);
1839void TypePrinter::printDependentTemplateSpecializationBefore(
1841 IncludeStrongLifetimeRAII Strong(Policy);
1847 T->getDependentTemplateName().print(OS, Policy);
1849 spaceBeforePlaceHolder(OS);
1852void TypePrinter::printDependentTemplateSpecializationAfter(
1857 printBefore(
T->getPattern(), OS);
1862 printAfter(
T->getPattern(), OS);
1870 if (
T->isCountInBytes() &&
T->isOrNull())
1871 OS <<
"__sized_by_or_null(";
1872 else if (
T->isCountInBytes())
1873 OS <<
"__sized_by(";
1874 else if (
T->isOrNull())
1875 OS <<
"__counted_by_or_null(";
1877 OS <<
"__counted_by(";
1878 if (
T->getCountExpr())
1879 T->getCountExpr()->printPretty(OS,
nullptr, Policy);
1902 if (
T->getAttrKind() == attr::ObjCGC ||
1903 T->getAttrKind() == attr::ObjCOwnership)
1904 return printBefore(
T->getEquivalentType(), OS);
1906 if (
T->getAttrKind() == attr::ObjCKindOf)
1909 if (
T->getAttrKind() == attr::PreserveNone) {
1910 OS <<
"__attribute__((preserve_none)) ";
1911 spaceBeforePlaceHolder(OS);
1912 }
else if (
T->getAttrKind() == attr::PreserveMost) {
1913 OS <<
"__attribute__((preserve_most)) ";
1914 spaceBeforePlaceHolder(OS);
1915 }
else if (
T->getAttrKind() == attr::PreserveAll) {
1916 OS <<
"__attribute__((preserve_all)) ";
1917 spaceBeforePlaceHolder(OS);
1920 if (
T->getAttrKind() == attr::AddressSpace)
1921 printBefore(
T->getEquivalentType(), OS);
1923 printBefore(
T->getModifiedType(), OS);
1925 if (
T->isMSTypeSpec()) {
1926 switch (
T->getAttrKind()) {
1928 case attr::Ptr32: OS <<
" __ptr32";
break;
1929 case attr::Ptr64: OS <<
" __ptr64";
break;
1930 case attr::SPtr: OS <<
" __sptr";
break;
1931 case attr::UPtr: OS <<
" __uptr";
break;
1933 spaceBeforePlaceHolder(OS);
1936 if (
T->isWebAssemblyFuncrefSpec())
1940 if (
T->getImmediateNullability()) {
1941 if (
T->getAttrKind() == attr::TypeNonNull)
1943 else if (
T->getAttrKind() == attr::TypeNullable)
1945 else if (
T->getAttrKind() == attr::TypeNullUnspecified)
1946 OS <<
" _Null_unspecified";
1947 else if (
T->getAttrKind() == attr::TypeNullableResult)
1948 OS <<
" _Nullable_result";
1950 llvm_unreachable(
"unhandled nullability");
1951 spaceBeforePlaceHolder(OS);
1960 if (
T->getAttrKind() == attr::ObjCGC ||
1961 T->getAttrKind() == attr::ObjCOwnership)
1962 return printAfter(
T->getEquivalentType(), OS);
1966 SaveAndRestore MaybeSuppressCC(InsideCCAttribute,
T->isCallingConv());
1968 printAfter(
T->getModifiedType(), OS);
1972 if (
T->getAttrKind() == attr::ObjCKindOf ||
T->isMSTypeSpec() ||
1973 T->getImmediateNullability() ||
T->isWebAssemblyFuncrefSpec())
1977 if (
T->getAttrKind() == attr::ObjCInertUnsafeUnretained)
1981 if (
T->getAttrKind() == attr::NSReturnsRetained &&
1986 if (
T->getAttrKind() == attr::LifetimeBound) {
1987 OS <<
" [[clang::lifetimebound]]";
1990 if (
T->getAttrKind() == attr::LifetimeCaptureBy) {
1991 OS <<
" [[clang::lifetime_capture_by(";
1992 if (
auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(
T->getAttr()))
1993 llvm::interleaveComma(
attr->getArgIdents(), OS,
1994 [&](
auto it) { OS << it->getName(); });
2002 if (
T->getAttrKind() == attr::AddressSpace)
2005 if (
T->getAttrKind() == attr::AnnotateType) {
2010 OS <<
" [[clang::annotate_type(...)]]";
2014 if (
T->getAttrKind() == attr::ArmStreaming) {
2015 OS <<
"__arm_streaming";
2018 if (
T->getAttrKind() == attr::ArmStreamingCompatible) {
2019 OS <<
"__arm_streaming_compatible";
2023 if (
T->getAttrKind() == attr::SwiftAttr) {
2024 if (
auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(
T->getAttr())) {
2025 OS <<
" __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
2031 if (
T->getAttrKind() == attr::PreserveAll ||
2032 T->getAttrKind() == attr::PreserveMost ||
2033 T->getAttrKind() == attr::PreserveNone) {
2038 OS <<
" __attribute__((";
2039 switch (
T->getAttrKind()) {
2040#define TYPE_ATTR(NAME)
2041#define DECL_OR_TYPE_ATTR(NAME)
2042#define ATTR(NAME) case attr::NAME:
2043#include "clang/Basic/AttrList.inc"
2044 llvm_unreachable(
"non-type attribute attached to type");
2046 case attr::BTFTypeTag:
2047 llvm_unreachable(
"BTFTypeTag attribute handled separately");
2049 case attr::HLSLResourceClass:
2051 case attr::HLSLRawBuffer:
2052 case attr::HLSLContainedType:
2053 llvm_unreachable(
"HLSL resource type attributes handled separately");
2055 case attr::OpenCLPrivateAddressSpace:
2056 case attr::OpenCLGlobalAddressSpace:
2057 case attr::OpenCLGlobalDeviceAddressSpace:
2058 case attr::OpenCLGlobalHostAddressSpace:
2059 case attr::OpenCLLocalAddressSpace:
2060 case attr::OpenCLConstantAddressSpace:
2061 case attr::OpenCLGenericAddressSpace:
2062 case attr::HLSLGroupSharedAddressSpace:
2067 case attr::CountedBy:
2068 case attr::CountedByOrNull:
2070 case attr::SizedByOrNull:
2071 case attr::LifetimeBound:
2072 case attr::LifetimeCaptureBy:
2073 case attr::TypeNonNull:
2074 case attr::TypeNullable:
2075 case attr::TypeNullableResult:
2076 case attr::TypeNullUnspecified:
2078 case attr::ObjCInertUnsafeUnretained:
2079 case attr::ObjCKindOf:
2080 case attr::ObjCOwnership:
2085 case attr::PointerAuth:
2086 case attr::AddressSpace:
2087 case attr::CmseNSCall:
2088 case attr::AnnotateType:
2089 case attr::WebAssemblyFuncref:
2090 case attr::ArmAgnostic:
2091 case attr::ArmStreaming:
2092 case attr::ArmStreamingCompatible:
2095 case attr::ArmInOut:
2096 case attr::ArmPreserves:
2097 case attr::NonBlocking:
2098 case attr::NonAllocating:
2099 case attr::Blocking:
2100 case attr::Allocating:
2101 case attr::SwiftAttr:
2102 case attr::PreserveAll:
2103 case attr::PreserveMost:
2104 case attr::PreserveNone:
2105 llvm_unreachable(
"This attribute should have been handled already");
2107 case attr::NSReturnsRetained:
2108 OS <<
"ns_returns_retained";
2113 case attr::AnyX86NoCfCheck: OS <<
"nocf_check";
break;
2114 case attr::CDecl: OS <<
"cdecl";
break;
2115 case attr::FastCall: OS <<
"fastcall";
break;
2116 case attr::StdCall: OS <<
"stdcall";
break;
2117 case attr::ThisCall: OS <<
"thiscall";
break;
2118 case attr::SwiftCall: OS <<
"swiftcall";
break;
2119 case attr::SwiftAsyncCall: OS <<
"swiftasynccall";
break;
2120 case attr::VectorCall: OS <<
"vectorcall";
break;
2121 case attr::Pascal: OS <<
"pascal";
break;
2122 case attr::MSABI: OS <<
"ms_abi";
break;
2123 case attr::SysVABI: OS <<
"sysv_abi";
break;
2124 case attr::RegCall: OS <<
"regcall";
break;
2131 "\"aapcs\"" :
"\"aapcs-vfp\"");
2135 case attr::AArch64VectorPcs: OS <<
"aarch64_vector_pcs";
break;
2136 case attr::AArch64SVEPcs: OS <<
"aarch64_sve_pcs";
break;
2137 case attr::DeviceKernel:
2138 OS <<
T->getAttr()->getSpelling();
2140 case attr::IntelOclBicc:
2141 OS <<
"inteloclbicc";
2146 case attr::RISCVVectorCC:
2147 OS <<
"riscv_vector_cc";
2149 case attr::RISCVVLSCC:
2150 OS <<
"riscv_vls_cc";
2155 case attr::CFIUncheckedCallee:
2156 OS <<
"cfi_unchecked_callee";
2158 case attr::AcquireHandle:
2159 OS <<
"acquire_handle";
2161 case attr::ArmMveStrictPolymorphism:
2162 OS <<
"__clang_arm_mve_strict_polymorphism";
2164 case attr::ExtVectorType:
2165 OS <<
"ext_vector_type";
2168 OS <<
"cfi_salt(\"" << cast<CFISaltAttr>(
T->getAttr())->getSalt() <<
"\")";
2176 printBefore(
T->getWrappedType(), OS);
2177 OS <<
" __attribute__((btf_type_tag(\"" <<
T->getAttr()->getBTFTypeTag() <<
"\")))";
2182 printAfter(
T->getWrappedType(), OS);
2185void TypePrinter::printHLSLAttributedResourceBefore(
2187 printBefore(
T->getWrappedType(), OS);
2190void TypePrinter::printHLSLAttributedResourceAfter(
2192 printAfter(
T->getWrappedType(), OS);
2194 OS <<
" [[hlsl::resource_class("
2195 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.
ResourceClass)
2198 OS <<
" [[hlsl::is_rov]]";
2200 OS <<
" [[hlsl::raw_buffer]]";
2202 QualType ContainedTy =
T->getContainedType();
2203 if (!ContainedTy.
isNull()) {
2204 OS <<
" [[hlsl::contained_type(";
2205 printBefore(ContainedTy, OS);
2206 printAfter(ContainedTy, OS);
2213 OS <<
"__hlsl_spirv_type<" <<
T->getOpcode();
2215 OS <<
", " <<
T->getSize();
2216 OS <<
", " <<
T->getAlignment();
2218 for (
auto &Operand :
T->getOperands()) {
2223 case SpirvOperandKind::ConstantId: {
2225 OS <<
"vk::integral_constant<";
2226 printBefore(ConstantType, OS);
2227 printAfter(ConstantType, OS);
2233 case SpirvOperandKind::Literal:
2234 OS <<
"vk::Literal<vk::integral_constant<uint, ";
2238 case SpirvOperandKind::TypeId: {
2240 printBefore(
Type, OS);
2241 printAfter(
Type, OS);
2245 llvm_unreachable(
"Invalid SpirvOperand kind!");
2260 OS <<
T->getDecl()->getName();
2261 spaceBeforePlaceHolder(OS);
2269 OS <<
T->getDecl()->getName();
2270 if (!
T->qual_empty()) {
2271 bool isFirst =
true;
2273 for (
const auto *I :
T->quals()) {
2283 spaceBeforePlaceHolder(OS);
2291 if (
T->qual_empty() &&
T->isUnspecializedAsWritten() &&
2292 !
T->isKindOfTypeAsWritten())
2293 return printBefore(
T->getBaseType(), OS);
2295 if (
T->isKindOfTypeAsWritten())
2298 print(
T->getBaseType(), OS, StringRef());
2300 if (
T->isSpecializedAsWritten()) {
2301 bool isFirst =
true;
2303 for (
auto typeArg :
T->getTypeArgsAsWritten()) {
2309 print(typeArg, OS, StringRef());
2314 if (!
T->qual_empty()) {
2315 bool isFirst =
true;
2317 for (
const auto *I :
T->quals()) {
2327 spaceBeforePlaceHolder(OS);
2332 if (
T->qual_empty() &&
T->isUnspecializedAsWritten() &&
2333 !
T->isKindOfTypeAsWritten())
2334 return printAfter(
T->getBaseType(), OS);
2344 if (HasEmptyPlaceHolder)
2361 llvm::raw_ostream &OS,
bool IncludeType) {
2362 A.
print(PP, OS, IncludeType);
2386 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&
2389 Args[TTPT->getIndex()].getAsType(), Pattern.
getQualifiers());
2401 if (TQual != PatQual)
2419 Template = TTST->getTemplateName();
2420 TemplateArgs = TTST->template_arguments();
2421 }
else if (
auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2424 TemplateArgs = CTSD->getTemplateArgs().asArray();
2432 if (TemplateArgs.size() != PTST->template_arguments().size())
2434 for (
unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
2436 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))
2487 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))
2488 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&
2489 Args[NTTP->getIndex()].structurallyEquals(Arg);
2505 if (
auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))
2506 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&
2523 if (
auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {
2524 return TTPD->hasDefaultArgument() &&
2526 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2527 }
else if (
auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
2528 return TTPD->hasDefaultArgument() &&
2530 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);
2531 }
else if (
auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
2532 return NTTPD->hasDefaultArgument() &&
2534 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,
2540template <
typename TA>
2546 !Args.empty() && !IsPack && Args.size() <= TPL->
size()) {
2548 for (
const TA &A : Args)
2551 Args = Args.drop_back();
2558 bool NeedSpace =
false;
2559 bool FirstArg =
true;
2560 for (
const auto &Arg : Args) {
2563 llvm::raw_svector_ostream ArgOS(Buf);
2576 Policy, TPL, ParmIndex));
2578 StringRef ArgString = ArgOS.str();
2583 if (FirstArg && ArgString.starts_with(
":"))
2590 if (!ArgString.empty()) {
2620 printTo(OS, Args, InnerPolicy, TPL,
false, 0);
2629 printTo(OS, Args, InnerPolicy, TPL,
false, 0);
2639 llvm::raw_svector_ostream StrOS(Buf);
2641 return StrOS.str().str();
2669 llvm::raw_svector_ostream StrOS(Buf);
2670 print(StrOS, Policy);
2671 return std::string(StrOS.str());
2709 return "__constant";
2714 return "__global_device";
2717 return "__global_host";
2719 return "__device__";
2721 return "__constant__";
2723 return "__shared__";
2725 return "__sptr __ptr32";
2727 return "__uptr __ptr32";
2731 return "groupshared";
2733 return "hlsl_constant";
2735 return "hlsl_private";
2737 return "hlsl_device";
2739 return "hlsl_input";
2751 bool appendSpaceIfNonEmpty)
const {
2752 bool addSpace =
false;
2762 OS <<
"__unaligned";
2766 if (!ASStr.empty()) {
2772 OS <<
"__attribute__((address_space(" << ASStr <<
")))";
2811 PointerAuth.print(OS, Policy);
2814 if (appendSpaceIfNonEmpty && addSpace)
2836 const Twine &PlaceHolder,
unsigned Indentation)
const {
2843 const Twine &PlaceHolder,
unsigned Indentation) {
2845 StringRef PH = PlaceHolder.toStringRef(PHBuf);
2847 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
2857 std::string &buffer,
2860 llvm::raw_svector_ostream StrOS(Buf);
2861 TypePrinter(policy).print(ty, qs, StrOS, buffer);
2862 std::string str = std::string(StrOS.str());
2868 TypePrinter(
LangOptions()).print(S.Ty, S.Quals, OS,
"");
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the clang::attr::Kind enum.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the ExceptionSpecificationType enumeration and various utility functions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)
#define CC_VLS_CASE(ABI_VLEN)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
static void printTo(raw_ostream &OS, ArrayRef< TA > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex)
static const TemplateArgument & getArgument(const TemplateArgument &A)
static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, llvm::raw_ostream &OS, bool IncludeType)
static QualType skipTopLevelReferences(QualType T)
static void printCountAttributedImpl(const CountAttributedType *T, raw_ostream &OS, const PrintingPolicy &Policy)
static SplitQualType splitAccordingToPolicy(QualType QT, const PrintingPolicy &Policy)
static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg, TemplateArgument Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)
static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)
static bool templateArgumentExpressionsEqual(ASTContext const &Ctx, TemplateArgument const &Pattern, TemplateArgument const &Arg)
Evaluates the expression template argument 'Pattern' and returns true if 'Arg' evaluates to the same ...
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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'.
Declaration of a class template.
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
Decl - This represents one declaration (or definition), e.g.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
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, 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...
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().
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.
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
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
@ SME_AgnosticZAStateMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
Represents an arbitrary, user-specified SPIR-V type instruction.
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.
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.
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
unsigned getExtraDiscriminator() const
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
std::string getAsString() const
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
PointerAuthQualifier getPointerAuth() 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 builtin template as a pack.
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.
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.
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)
Represents a type template specialization; the template must be a class template, a type alias templa...
Declaration of a template type parameter.
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.
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<specific type>.
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<specific type>'.
Base class for declarations which introduce a typedef-name.
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)
@ Template
We are parsing a template declaration.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Keyword
The name has been typo-corrected to a keyword.
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.
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
@ 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 "<int>" in "sort<int>".
ArrayRef< TemplateArgumentLoc > arguments() const
llvm::dxil::ResourceClass ResourceClass
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
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<c> >' rather than 'a<b<c>>'.
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 PrintAsCanonical
Whether to print entities as written or canonically.
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.