33 #include "llvm/ADT/ArrayRef.h" 34 #include "llvm/ADT/SmallString.h" 35 #include "llvm/ADT/StringRef.h" 36 #include "llvm/ADT/Twine.h" 37 #include "llvm/Support/Casting.h" 38 #include "llvm/Support/Compiler.h" 39 #include "llvm/Support/ErrorHandling.h" 40 #include "llvm/Support/SaveAndRestore.h" 41 #include "llvm/Support/raw_ostream.h" 45 using namespace clang;
51 class IncludeStrongLifetimeRAII {
57 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
62 ~IncludeStrongLifetimeRAII() {
67 class ParamPolicyRAII {
73 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
82 class ElaboratedTypePolicyRAII {
84 bool SuppressTagKeyword;
88 explicit ElaboratedTypePolicyRAII(
PrintingPolicy &Policy) : Policy(Policy) {
95 ~ElaboratedTypePolicyRAII() {
103 unsigned Indentation;
104 bool HasEmptyPlaceHolder =
false;
105 bool InsideCCAttribute =
false;
108 explicit TypePrinter(
const PrintingPolicy &Policy,
unsigned Indentation = 0)
109 : Policy(Policy), Indentation(Indentation) {}
112 StringRef PlaceHolder);
113 void print(
QualType T, raw_ostream &OS, StringRef PlaceHolder);
115 static bool canPrefixQualifiers(
const Type *T,
bool &NeedARCStrongQualifier);
116 void spaceBeforePlaceHolder(raw_ostream &OS);
117 void printTypeSpec(
NamedDecl *D, raw_ostream &OS);
119 void printBefore(
QualType T, raw_ostream &OS);
120 void printAfter(
QualType T, raw_ostream &OS);
121 void AppendScope(
DeclContext *DC, raw_ostream &OS);
122 void printTag(
TagDecl *T, raw_ostream &OS);
124 #define ABSTRACT_TYPE(CLASS, PARENT) 125 #define TYPE(CLASS, PARENT) \ 126 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \ 127 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS); 128 #include "clang/AST/TypeNodes.def" 138 bool HasRestrictKeyword) {
139 bool appendSpace =
false;
145 if (appendSpace) OS <<
' ';
150 if (appendSpace) OS <<
' ';
151 if (HasRestrictKeyword) {
159 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
160 if (!HasEmptyPlaceHolder)
171 void TypePrinter::print(
QualType t, raw_ostream &OS, StringRef PlaceHolder) {
173 print(split.
Ty, split.
Quals, OS, PlaceHolder);
176 void TypePrinter::print(
const Type *T,
Qualifiers Quals, raw_ostream &OS,
177 StringRef PlaceHolder) {
185 printBefore(T, Quals, OS);
187 printAfter(T, Quals, OS);
190 bool TypePrinter::canPrefixQualifiers(
const Type *T,
191 bool &NeedARCStrongQualifier) {
197 bool CanPrefixQualifiers =
false;
198 NeedARCStrongQualifier =
false;
200 if (
const auto *AT = dyn_cast<AutoType>(T))
201 TC = AT->desugar()->getTypeClass();
202 if (
const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))
203 TC = Subst->getReplacementType()->getTypeClass();
209 case Type::UnresolvedUsing:
211 case Type::TypeOfExpr:
214 case Type::UnaryTransform:
217 case Type::Elaborated:
218 case Type::TemplateTypeParm:
219 case Type::SubstTemplateTypeParmPack:
220 case Type::DeducedTemplateSpecialization:
221 case Type::TemplateSpecialization:
222 case Type::InjectedClassName:
223 case Type::DependentName:
224 case Type::DependentTemplateSpecialization:
225 case Type::ObjCObject:
226 case Type::ObjCTypeParam:
227 case Type::ObjCInterface:
230 CanPrefixQualifiers =
true;
233 case Type::ObjCObjectPointer:
238 case Type::ConstantArray:
239 case Type::IncompleteArray:
240 case Type::VariableArray:
241 case Type::DependentSizedArray:
242 NeedARCStrongQualifier =
true;
248 case Type::BlockPointer:
249 case Type::LValueReference:
250 case Type::RValueReference:
251 case Type::MemberPointer:
252 case Type::DependentAddressSpace:
253 case Type::DependentVector:
254 case Type::DependentSizedExtVector:
256 case Type::ExtVector:
257 case Type::FunctionProto:
258 case Type::FunctionNoProto:
260 case Type::PackExpansion:
261 case Type::SubstTemplateTypeParm:
262 case Type::MacroQualified:
263 CanPrefixQualifiers =
false;
266 case Type::Attributed: {
269 const auto *AttrTy = cast<AttributedType>(T);
270 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
274 return CanPrefixQualifiers;
277 void TypePrinter::printBefore(
QualType T, raw_ostream &OS) {
283 if (
const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.
Ty))
286 printBefore(Split.
Ty, Quals, OS);
291 void TypePrinter::printBefore(
const Type *T,
Qualifiers Quals, raw_ostream &OS) {
299 bool CanPrefixQualifiers =
false;
300 bool NeedARCStrongQualifier =
false;
301 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
303 if (CanPrefixQualifiers && !Quals.
empty()) {
304 if (NeedARCStrongQualifier) {
305 IncludeStrongLifetimeRAII Strong(Policy);
306 Quals.
print(OS, Policy,
true);
308 Quals.
print(OS, Policy,
true);
312 bool hasAfterQuals =
false;
313 if (!CanPrefixQualifiers && !Quals.
empty()) {
316 HasEmptyPlaceHolder =
false;
320 #define ABSTRACT_TYPE(CLASS, PARENT) 321 #define TYPE(CLASS, PARENT) case Type::CLASS: \ 322 print##CLASS##Before(cast<CLASS##Type>(T), OS); \ 324 #include "clang/AST/TypeNodes.def" 328 if (NeedARCStrongQualifier) {
329 IncludeStrongLifetimeRAII Strong(Policy);
330 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
332 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
337 void TypePrinter::printAfter(
QualType t, raw_ostream &OS) {
339 printAfter(split.
Ty, split.
Quals, OS);
344 void TypePrinter::printAfter(
const Type *T,
Qualifiers Quals, raw_ostream &OS) {
346 #define ABSTRACT_TYPE(CLASS, PARENT) 347 #define TYPE(CLASS, PARENT) case Type::CLASS: \ 348 print##CLASS##After(cast<CLASS##Type>(T), OS); \ 350 #include "clang/AST/TypeNodes.def" 354 void TypePrinter::printBuiltinBefore(
const BuiltinType *T, raw_ostream &OS) {
356 spaceBeforePlaceHolder(OS);
359 void TypePrinter::printBuiltinAfter(
const BuiltinType *T, raw_ostream &OS) {}
361 void TypePrinter::printComplexBefore(
const ComplexType *T, raw_ostream &OS) {
366 void TypePrinter::printComplexAfter(
const ComplexType *T, raw_ostream &OS) {
370 void TypePrinter::printPointerBefore(
const PointerType *T, raw_ostream &OS) {
371 IncludeStrongLifetimeRAII Strong(Policy);
381 void TypePrinter::printPointerAfter(
const PointerType *T, raw_ostream &OS) {
382 IncludeStrongLifetimeRAII Strong(Policy);
414 IncludeStrongLifetimeRAII Strong(Policy);
417 printBefore(Inner, OS);
420 if (isa<ArrayType>(Inner))
427 IncludeStrongLifetimeRAII Strong(Policy);
432 if (isa<ArrayType>(Inner))
434 printAfter(Inner, OS);
439 IncludeStrongLifetimeRAII Strong(Policy);
442 printBefore(Inner, OS);
445 if (isa<ArrayType>(Inner))
452 IncludeStrongLifetimeRAII Strong(Policy);
457 if (isa<ArrayType>(Inner))
459 printAfter(Inner, OS);
464 IncludeStrongLifetimeRAII Strong(Policy);
474 TypePrinter(InnerPolicy).print(
QualType(T->
getClass(), 0), OS, StringRef());
481 IncludeStrongLifetimeRAII Strong(Policy);
492 IncludeStrongLifetimeRAII Strong(Policy);
509 OS << T->
getSize().getZExtValue() <<
']';
515 IncludeStrongLifetimeRAII Strong(Policy);
528 IncludeStrongLifetimeRAII Strong(Policy);
553 void TypePrinter::printAdjustedBefore(
const AdjustedType *T, raw_ostream &OS) {
559 void TypePrinter::printAdjustedAfter(
const AdjustedType *T, raw_ostream &OS) {
563 void TypePrinter::printDecayedBefore(
const DecayedType *T, raw_ostream &OS) {
565 printAdjustedBefore(T, OS);
568 void TypePrinter::printDecayedAfter(
const DecayedType *T, raw_ostream &OS) {
569 printAdjustedAfter(T, OS);
572 void TypePrinter::printDependentSizedArrayBefore(
575 IncludeStrongLifetimeRAII Strong(Policy);
580 void TypePrinter::printDependentSizedArrayAfter(
590 void TypePrinter::printDependentAddressSpaceBefore(
595 void TypePrinter::printDependentAddressSpaceAfter(
597 OS <<
" __attribute__((address_space(";
604 void TypePrinter::printDependentSizedExtVectorBefore(
610 void TypePrinter::printDependentSizedExtVectorAfter(
613 OS <<
" __attribute__((ext_vector_type(";
620 void TypePrinter::printVectorBefore(
const VectorType *T, raw_ostream &OS) {
623 OS <<
"__vector __pixel ";
626 OS <<
"__vector __bool ";
634 OS <<
"__attribute__((neon_vector_type(" 639 OS <<
"__attribute__((neon_polyvector_type(" <<
646 OS <<
"__attribute__((__vector_size__(" 657 void TypePrinter::printVectorAfter(
const VectorType *T, raw_ostream &OS) {
661 void TypePrinter::printDependentVectorBefore(
665 OS <<
"__vector __pixel ";
668 OS <<
"__vector __bool ";
676 OS <<
"__attribute__((neon_vector_type(";
683 OS <<
"__attribute__((neon_polyvector_type(";
692 OS <<
"__attribute__((__vector_size__(";
704 void TypePrinter::printDependentVectorAfter(
709 void TypePrinter::printExtVectorBefore(
const ExtVectorType *T,
714 void TypePrinter::printExtVectorAfter(
const ExtVectorType *T, raw_ostream &OS) {
716 OS <<
" __attribute__((ext_vector_type(";
725 if (hasDynamicExceptionSpec()) {
730 for (
unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
734 OS << getExceptionType(I).stream(Policy);
737 }
else if (
EST_NoThrow == getExceptionSpecType()) {
738 OS <<
" __attribute__((nothrow))";
745 if (getNoexceptExpr())
746 getNoexceptExpr()->printPretty(OS,
nullptr, Policy);
756 if (!HasEmptyPlaceHolder)
762 if (!PrevPHIsEmpty.get())
770 llvm_unreachable(
"asking for spelling of ordinary parameter ABI");
772 return "swift_context";
774 return "swift_error_result";
776 return "swift_indirect_result";
778 llvm_unreachable(
"bad parameter ABI kind");
784 if (!HasEmptyPlaceHolder)
790 ParamPolicyRAII ParamPolicy(Policy);
795 if (EPI.isConsumed()) OS <<
"__attribute__((ns_consumed)) ";
796 if (EPI.isNoEscape())
797 OS <<
"__attribute__((noescape)) ";
810 }
else if (T->
getNumParams() == 0 && Policy.UseVoidForZeroParams) {
819 printFunctionAfter(Info, OS);
847 if (!InsideCCAttribute) {
848 switch (Info.
getCC()) {
859 OS <<
" __attribute__((stdcall))";
862 OS <<
" __attribute__((fastcall))";
865 OS <<
" __attribute__((thiscall))";
868 OS <<
" __attribute__((vectorcall))";
871 OS <<
" __attribute__((pascal))";
874 OS <<
" __attribute__((pcs(\"aapcs\")))";
877 OS <<
" __attribute__((pcs(\"aapcs-vfp\")))";
880 OS <<
"__attribute__((aarch64_vector_pcs))";
883 OS <<
" __attribute__((intel_ocl_bicc))";
886 OS <<
" __attribute__((ms_abi))";
889 OS <<
" __attribute__((sysv_abi))";
892 OS <<
" __attribute__((regcall))";
899 OS <<
" __attribute__((swiftcall))";
902 OS <<
" __attribute__((preserve_most))";
905 OS <<
" __attribute__((preserve_all))";
911 OS <<
" __attribute__((noreturn))";
913 OS <<
" __attribute__((ns_returns_retained))";
915 OS <<
" __attribute__((regparm (" 918 OS <<
" __attribute__((no_caller_saved_registers))";
920 OS <<
" __attribute__((nocf_check))";
928 if (!PrevPHIsEmpty.get())
935 if (!HasEmptyPlaceHolder)
944 void TypePrinter::printTypeSpec(
NamedDecl *D, raw_ostream &OS) {
949 if (!Policy.SuppressScope)
954 spaceBeforePlaceHolder(OS);
959 printTypeSpec(T->
getDecl(), OS);
965 void TypePrinter::printTypedefBefore(
const TypedefType *T, raw_ostream &OS) {
966 printTypeSpec(T->
getDecl(), OS);
972 OS << MacroName <<
" ";
984 void TypePrinter::printTypedefAfter(
const TypedefType *T, raw_ostream &OS) {}
991 spaceBeforePlaceHolder(OS);
997 void TypePrinter::printTypeOfBefore(
const TypeOfType *T, raw_ostream &OS) {
1001 spaceBeforePlaceHolder(OS);
1004 void TypePrinter::printTypeOfAfter(
const TypeOfType *T, raw_ostream &OS) {}
1006 void TypePrinter::printDecltypeBefore(
const DecltypeType *T, raw_ostream &OS) {
1011 spaceBeforePlaceHolder(OS);
1014 void TypePrinter::printDecltypeAfter(
const DecltypeType *T, raw_ostream &OS) {}
1018 IncludeStrongLifetimeRAII Strong(Policy);
1022 OS <<
"__underlying_type(";
1025 spaceBeforePlaceHolder(OS);
1034 IncludeStrongLifetimeRAII Strong(Policy);
1044 void TypePrinter::printAutoBefore(
const AutoType *T, raw_ostream &OS) {
1054 spaceBeforePlaceHolder(OS);
1058 void TypePrinter::printAutoAfter(
const AutoType *T, raw_ostream &OS) {
1064 void TypePrinter::printDeducedTemplateSpecializationBefore(
1070 IncludeStrongLifetimeRAII Strong(Policy);
1072 spaceBeforePlaceHolder(OS);
1076 void TypePrinter::printDeducedTemplateSpecializationAfter(
1083 void TypePrinter::printAtomicBefore(
const AtomicType *T, raw_ostream &OS) {
1084 IncludeStrongLifetimeRAII Strong(Policy);
1089 spaceBeforePlaceHolder(OS);
1092 void TypePrinter::printAtomicAfter(
const AtomicType *T, raw_ostream &OS) {}
1094 void TypePrinter::printPipeBefore(
const PipeType *T, raw_ostream &OS) {
1095 IncludeStrongLifetimeRAII Strong(Policy);
1100 OS <<
"write_only ";
1103 spaceBeforePlaceHolder(OS);
1106 void TypePrinter::printPipeAfter(
const PipeType *T, raw_ostream &OS) {}
1109 void TypePrinter::AppendScope(
DeclContext *DC, raw_ostream &OS) {
1114 if (
const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1115 if (Policy.SuppressUnwrittenScope &&
1116 (NS->isAnonymousNamespace() || NS->isInline()))
1118 if (NS->getIdentifier())
1119 OS << NS->getName() <<
"::";
1121 OS <<
"(anonymous namespace)::";
1122 }
else if (
const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1123 IncludeStrongLifetimeRAII Strong(Policy);
1124 OS << Spec->getIdentifier()->getName();
1128 }
else if (
const auto *Tag = dyn_cast<TagDecl>(DC)) {
1130 OS << Typedef->getIdentifier()->getName() <<
"::";
1131 else if (Tag->getIdentifier())
1132 OS << Tag->getIdentifier()->getName() <<
"::";
1138 void TypePrinter::printTag(
TagDecl *D, raw_ostream &OS) {
1139 if (Policy.IncludeTagDefinition) {
1142 D->
print(OS, SubPolicy, Indentation);
1143 spaceBeforePlaceHolder(OS);
1147 bool HasKindDecoration =
false;
1152 HasKindDecoration =
true;
1160 if (!Policy.SuppressScope)
1164 OS << II->getName();
1166 assert(Typedef->getIdentifier() &&
"Typedef without identifier?");
1167 OS << Typedef->getIdentifier()->getName();
1171 OS << (Policy.MSVCFormatting ?
'`' :
'(');
1173 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1175 HasKindDecoration =
true;
1180 if (Policy.AnonymousTagLocations) {
1184 if (!HasKindDecoration)
1192 if (Policy.RemapFilePaths)
1193 OS << Policy.remapPath(File);
1200 OS << (Policy.MSVCFormatting ?
'\'' :
')');
1205 if (
const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1209 cast<TemplateSpecializationType>(TAW->getType());
1213 Args = TemplateArgs.
asArray();
1215 IncludeStrongLifetimeRAII Strong(Policy);
1219 spaceBeforePlaceHolder(OS);
1222 void TypePrinter::printRecordBefore(
const RecordType *T, raw_ostream &OS) {
1226 void TypePrinter::printRecordAfter(
const RecordType *T, raw_ostream &OS) {}
1228 void TypePrinter::printEnumBefore(
const EnumType *T, raw_ostream &OS) {
1232 void TypePrinter::printEnumAfter(
const EnumType *T, raw_ostream &OS) {}
1237 OS <<
Id->getName();
1239 bool IsLambdaAutoParam =
false;
1241 if (
auto M = dyn_cast_or_null<CXXMethodDecl>(D->
getDeclContext()))
1242 IsLambdaAutoParam = D->
isImplicit() && M->getParent()->isLambda();
1245 if (IsLambdaAutoParam)
1250 spaceBeforePlaceHolder(OS);
1256 void TypePrinter::printSubstTemplateTypeParmBefore(
1259 IncludeStrongLifetimeRAII Strong(Policy);
1263 void TypePrinter::printSubstTemplateTypeParmAfter(
1266 IncludeStrongLifetimeRAII Strong(Policy);
1270 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1273 IncludeStrongLifetimeRAII Strong(Policy);
1277 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1280 IncludeStrongLifetimeRAII Strong(Policy);
1284 void TypePrinter::printTemplateSpecializationBefore(
1287 IncludeStrongLifetimeRAII Strong(Policy);
1291 spaceBeforePlaceHolder(OS);
1294 void TypePrinter::printTemplateSpecializationAfter(
1311 "OwnedTagDecl expected to be a declaration for the type");
1314 OwnedTagDecl->
print(OS, SubPolicy, Indentation);
1315 spaceBeforePlaceHolder(OS);
1320 if (!Policy.IncludeTagDefinition)
1327 Qualifier->
print(OS, Policy);
1330 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1338 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1342 void TypePrinter::printParenBefore(
const ParenType *T, raw_ostream &OS) {
1343 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1350 void TypePrinter::printParenAfter(
const ParenType *T, raw_ostream &OS) {
1351 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1367 spaceBeforePlaceHolder(OS);
1373 void TypePrinter::printDependentTemplateSpecializationBefore(
1375 IncludeStrongLifetimeRAII Strong(Policy);
1385 spaceBeforePlaceHolder(OS);
1388 void TypePrinter::printDependentTemplateSpecializationAfter(
1422 case attr::Ptr32: OS <<
" __ptr32";
break;
1423 case attr::Ptr64: OS <<
" __ptr64";
break;
1424 case attr::SPtr: OS <<
" __sptr";
break;
1425 case attr::UPtr: OS <<
" __uptr";
break;
1427 spaceBeforePlaceHolder(OS);
1436 else if (T->
getAttrKind() == attr::TypeNullUnspecified)
1437 OS <<
" _Null_unspecified";
1439 llvm_unreachable(
"unhandled nullability");
1440 spaceBeforePlaceHolder(OS);
1466 if (T->
getAttrKind() == attr::ObjCInertUnsafeUnretained)
1470 if (T->
getAttrKind() == attr::NSReturnsRetained &&
1472 ->getExtInfo().getProducesResult())
1476 OS <<
" [[clang::lifetimebound]]";
1486 OS <<
" __attribute__((";
1488 #define TYPE_ATTR(NAME) 1489 #define DECL_OR_TYPE_ATTR(NAME) 1490 #define ATTR(NAME) case attr::NAME: 1491 #include "clang/Basic/AttrList.inc" 1492 llvm_unreachable(
"non-type attribute attached to type");
1494 case attr::OpenCLPrivateAddressSpace:
1495 case attr::OpenCLGlobalAddressSpace:
1496 case attr::OpenCLLocalAddressSpace:
1497 case attr::OpenCLConstantAddressSpace:
1498 case attr::OpenCLGenericAddressSpace:
1503 case attr::LifetimeBound:
1504 case attr::TypeNonNull:
1505 case attr::TypeNullable:
1506 case attr::TypeNullUnspecified:
1508 case attr::ObjCInertUnsafeUnretained:
1509 case attr::ObjCKindOf:
1510 case attr::ObjCOwnership:
1515 case attr::AddressSpace:
1516 llvm_unreachable(
"This attribute should have been handled already");
1518 case attr::NSReturnsRetained:
1519 OS <<
"ns_returns_retained";
1524 case attr::AnyX86NoCfCheck: OS <<
"nocf_check";
break;
1525 case attr::CDecl: OS <<
"cdecl";
break;
1526 case attr::FastCall: OS <<
"fastcall";
break;
1527 case attr::StdCall: OS <<
"stdcall";
break;
1528 case attr::ThisCall: OS <<
"thiscall";
break;
1529 case attr::SwiftCall: OS <<
"swiftcall";
break;
1530 case attr::VectorCall: OS <<
"vectorcall";
break;
1531 case attr::Pascal: OS <<
"pascal";
break;
1532 case attr::MSABI: OS <<
"ms_abi";
break;
1533 case attr::SysVABI: OS <<
"sysv_abi";
break;
1534 case attr::RegCall: OS <<
"regcall";
break;
1541 "\"aapcs\"" :
"\"aapcs-vfp\"");
1545 case attr::AArch64VectorPcs: OS <<
"aarch64_vector_pcs";
break;
1546 case attr::IntelOclBicc: OS <<
"inteloclbicc";
break;
1547 case attr::PreserveMost:
1548 OS <<
"preserve_most";
1551 case attr::PreserveAll:
1552 OS <<
"preserve_all";
1564 spaceBeforePlaceHolder(OS);
1574 bool isFirst =
true;
1576 for (
const auto *I : T->
quals()) {
1586 spaceBeforePlaceHolder(OS); 1589 void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T, 1592 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T, 1594 if (T->qual_empty() && T->isUnspecializedAsWritten() && 1595 !T->isKindOfTypeAsWritten()) 1596 return printBefore(T->getBaseType(), OS); 1598 if (T->isKindOfTypeAsWritten()) 1601 print(T->getBaseType(), OS, StringRef()); 1603 if (T->isSpecializedAsWritten()) { 1604 bool isFirst = true; 1606 for (auto typeArg : T->getTypeArgsAsWritten()) { 1612 print(typeArg, OS, StringRef()); 1617 if (!T->qual_empty()) { 1618 bool isFirst = true; 1620 for (const auto *I : T->quals()) { 1630 spaceBeforePlaceHolder(OS); 1633 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T, 1635 if (T->qual_empty() && T->isUnspecializedAsWritten() && 1636 !T->isKindOfTypeAsWritten()) 1637 return printAfter(T->getBaseType(), OS); 1640 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T, 1642 printBefore(T->getPointeeType(), OS); 1644 // If we need to print the pointer, print it now. 1645 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() && 1646 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) { 1647 if (HasEmptyPlaceHolder) 1653 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T, 1657 const TemplateArgument &getArgument(const TemplateArgument &A) { return A; } 1659 static const TemplateArgument &getArgument(const TemplateArgumentLoc &A) { 1660 return A.getArgument(); 1663 static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, 1664 llvm::raw_ostream &OS) { 1668 static void printArgument(const TemplateArgumentLoc &A, 1669 const PrintingPolicy &PP, llvm::raw_ostream &OS) { 1670 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind(); 1671 if (Kind == TemplateArgument::ArgKind::Type) 1672 return A.getTypeSourceInfo()->getType().print(OS, PP); 1673 return A.getArgument().print(PP, OS); 1676 template<typename TA> 1677 static void printTo(raw_ostream &OS, ArrayRef<TA> Args, 1678 const PrintingPolicy &Policy, bool SkipBrackets) { 1679 const char *Comma = Policy.MSVCFormatting ? "," : ", "; 1683 bool NeedSpace = false; 1684 bool FirstArg = true; 1685 for (const auto &Arg : Args) { 1686 // Print the argument into a string. 1687 SmallString<128> Buf; 1688 llvm::raw_svector_ostream ArgOS(Buf); 1689 const TemplateArgument &Argument = getArgument(Arg); 1690 if (Argument.getKind() == TemplateArgument::Pack) { 1691 if (Argument.pack_size() && !FirstArg) 1693 printTo(ArgOS, Argument.getPackAsArray(), Policy, true); 1697 // Tries to print the argument with location info if exists. 1698 printArgument(Arg, Policy, ArgOS); 1700 StringRef ArgString = ArgOS.str(); 1702 // If this is the first argument and its string representation 1703 // begins with the global scope specifier ('::foo
'), add a space 1704 // to avoid printing the diagraph '<:
'. 1705 if (FirstArg && !ArgString.empty() && ArgString[0] == ':
') 1710 NeedSpace = (!ArgString.empty() && ArgString.back() == '>
'); 1714 // If the last character of our string is '>
', add another space to 1715 // keep the two '>
''s separate tokens. We don
't *have* to do this in 1716 // C++0x, but it's still good hygiene.
1724 void clang::printTemplateArgumentList(raw_ostream &OS, 1725 const TemplateArgumentListInfo &Args, 1726 const PrintingPolicy &Policy) { 1727 return printTo(OS, Args.arguments(), Policy, false); 1730 void clang::printTemplateArgumentList(raw_ostream &OS, 1731 ArrayRef<TemplateArgument> Args, 1732 const PrintingPolicy &Policy) { 1733 printTo(OS, Args, Policy, false); 1736 void clang::printTemplateArgumentList(raw_ostream &OS, 1737 ArrayRef<TemplateArgumentLoc> Args, 1738 const PrintingPolicy &Policy) { 1739 printTo(OS, Args, Policy, false); 1742 std::string Qualifiers::getAsString() const { 1744 return getAsString(PrintingPolicy(LO)); 1747 // Appends qualifiers to the given string, separated by spaces. Will 1748 // prefix a space if the string is non-empty. Will not append a final 1750 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const { 1751 SmallString<64> Buf; 1752 llvm::raw_svector_ostream StrOS(Buf); 1753 print(StrOS, Policy); 1757 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const { 1758 if (getCVRQualifiers()) 1761 if (getAddressSpace() != LangAS::Default) 1764 if (getObjCGCAttr()) 1767 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) 1768 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)) 1774 // Appends qualifiers to the given string, separated by spaces. Will 1775 // prefix a space if the string is non-empty. Will not append a final 1777 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, 1778 bool appendSpaceIfNonEmpty) const { 1779 bool addSpace = false; 1781 unsigned quals = getCVRQualifiers(); 1783 AppendTypeQualList(OS, quals, Policy.Restrict); 1786 if (hasUnaligned()) { 1789 OS << "__unaligned"; 1792 LangAS addrspace = getAddressSpace(); 1793 if (addrspace != LangAS::Default) { 1794 if (addrspace != LangAS::opencl_private) { 1798 switch (addrspace) { 1799 case LangAS::opencl_global: 1802 case LangAS::opencl_local: 1805 case LangAS::opencl_private: 1807 case LangAS::opencl_constant: 1810 case LangAS::opencl_generic: 1813 case LangAS::cuda_device: 1816 case LangAS::cuda_constant: 1817 OS << "__constant__"; 1819 case LangAS::cuda_shared: 1823 OS << "__attribute__((address_space("; 1824 OS << toTargetAddressSpace(addrspace); 1829 if (Qualifiers::GC gc = getObjCGCAttr()) { 1833 if (gc == Qualifiers::Weak) 1838 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) { 1839 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){ 1846 case Qualifiers::OCL_None: llvm_unreachable("none but true"); 1847 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break; 1848 case Qualifiers::OCL_Strong: 1849 if (!Policy.SuppressStrongLifetime) 1853 case Qualifiers::OCL_Weak: OS << "__weak"; break; 1854 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break; 1858 if (appendSpaceIfNonEmpty && addSpace) 1862 std::string QualType::getAsString() const { 1863 return getAsString(split(), LangOptions()); 1866 std::string QualType::getAsString(const PrintingPolicy &Policy) const { 1868 getAsStringInternal(S, Policy); 1872 std::string QualType::getAsString(const Type *ty, Qualifiers qs, 1873 const PrintingPolicy &Policy) { 1875 getAsStringInternal(ty, qs, buffer, Policy); 1879 void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy, 1880 const Twine &PlaceHolder, unsigned Indentation) const { 1881 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder, 1885 void QualType::print(const Type *ty, Qualifiers qs, 1886 raw_ostream &OS, const PrintingPolicy &policy, 1887 const Twine &PlaceHolder, unsigned Indentation) { 1888 SmallString<128> PHBuf; 1889 StringRef PH = PlaceHolder.toStringRef(PHBuf); 1891 TypePrinter(policy, Indentation).print(ty, qs, OS, PH); 1894 void QualType::getAsStringInternal(std::string &Str, 1895 const PrintingPolicy &Policy) const { 1896 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str, 1900 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, 1901 std::string &buffer, 1902 const PrintingPolicy &policy) { 1903 SmallString<256> Buf; 1904 llvm::raw_svector_ostream StrOS(Buf); 1905 TypePrinter(policy).print(ty, qs, StrOS, buffer); 1906 std::string str = StrOS.str();
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
Defines the clang::ASTContext interface.
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it's either not been deduced or was deduce...
Represents a type that was referred to using an elaborated type keyword, e.g., struct S...
const Type * Ty
The locally-unqualified type.
static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)
const TemplateSpecializationType * getInjectedTST() const
StringRef getName(const PrintingPolicy &Policy) const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getElementType() const
QualType getPointeeType() const
Represents the dependent type named by a dependently-scoped typename using declaration, e.g.
A (possibly-)qualified type.
bool getNoCfCheck() const
__auto_type (GNU extension)
Expr * getUnderlyingExpr() const
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
C Language Family Type Representation.
Defines the SourceManager interface.
Represents a qualified type name for which the type name is dependent.
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
const Type * getTypeForDecl() const
bool isVariadic() const
Whether this function prototype is variadic.
Defines the C++ template declaration subclasses.
Represents a C++11 auto or C++14 decltype(auto) type.
The base class of the type hierarchy.
A container of type source information.
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
TemplateTypeParmDecl * getDecl() const
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
QualType getElementType() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
unsigned getNumParams() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a C++17 deduced template specialization type.
bool isCallingConv() const
Describes how types, statements, expressions, and declarations should be printed. ...
Represents the result of substituting a type for a template type parameter.
The collection of all-type qualifiers we support.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
One of these records is kept for each identifier that is lexed.
unsigned SuppressLifetimeQualifiers
When true, suppress printing of lifetime qualifier in ARC.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS=false) const
Print the template name.
unsigned getRegParm() const
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
QualType getPointeeType() const
bool isObjCIdType() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
Defines the ExceptionSpecificationType enumeration and various utility functions. ...
const IdentifierInfo * getMacroIdentifier() const
Represents the result of substituting a set of types for a template type parameter pack...
TagDecl * getOwnedTagDecl() const
Return the (re)declaration of this type owned by this occurrence of this type, or nullptr if there is...
bool isObjCQualifiedClassType() const
QualType getModifiedType() const
Return this attributed type's modified type with no qualifiers attached to it.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
bool getProducesResult() const
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment...
An rvalue reference type, per C++11 [dcl.ref].
UnresolvedUsingTypenameDecl * getDecl() const
bool isMSTypeSpec() const
An lvalue ref-qualifier was provided (&).
Microsoft throw(...) extension.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation...
Represents a typeof (or typeof) expression (a GCC extension).
const Type * getClass() const
Expr * getSizeExpr() const
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
is ARM Neon polynomial vector
Expr * getSizeExpr() const
bool getNoCallerSavedRegs() const
QualType getPointeeTypeAsWritten() const
Expr * getSizeExpr() const
QualType getElementType() const
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
unsigned PrintCanonicalTypes
Whether to print types as written or canonically.
Represents an extended vector type where either the type or size is dependent.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
Represents a K&R-style 'int foo()' function, which has no information available about its arguments...
Expr * getAddrSpaceExpr() const
Provides definitions for the various language-specific address spaces.
llvm::StringRef getParameterABISpelling(ParameterABI kind)
Represents a prototype with parameter type info, e.g.
static SplitQualType splitAccordingToPolicy(QualType QT, const PrintingPolicy &Policy)
ObjCTypeParamDecl * getDecl() const
Represents an array type in C++ whose size is a value-dependent expression.
QualType getElementType() const
unsigned SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
IdentifierInfo * getIdentifier() const
Defines the clang::LangOptions interface.
StringRef getKindName() const
unsigned getIndex() const
const T * castAs() const
Member-template castAs<specific type>.
unsigned getLine() const
Return the presumed line number of this location.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
bool isObjCClassType() const
DeclContext * getDeclContext()
const IdentifierInfo * getIdentifier() const
Retrieve the type named by the typename specifier as an identifier.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents the type decltype(expr) (C++11).
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
bool isFunctionOrMethod() const
Qualifiers Quals
The local qualifiers.
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Represents an unpacked "presumed" location which can be presented to the user.
Represents a GCC generic vector type.
ArraySizeModifier getSizeModifier() const
An lvalue reference type, per C++11 [dcl.ref].
unsigned SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Expr * getUnderlyingExpr() const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
bool hasQualifiers() const
Return true if the set contains any qualifiers.
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
RecordDecl * getDecl() const
const char * getFilename() const
Return the presumed filename of this location.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
is AltiVec 'vector Pixel'
QualType getCanonicalType() const
not a target-specific vector type
ExtParameterInfo getExtParameterInfo(unsigned I) const
ElaboratedTypeKeyword getKeyword() const
unsigned getColumn() const
Return the presumed column number of this location.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
Sugar for parentheses used when specifying types.
QualType getAdjustedType() const
QualType getReturnType() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Represents typeof(type), a GCC extension.
Interfaces are the core concept in Objective-C for object oriented design.
unsigned SuppressScope
Suppresses printing of scope specifiers.
ParameterABI getABI() const
Return the ABI treatment of this parameter.
Represents the declaration of a struct/union/class/enum.
ASTContext & getASTContext() const LLVM_READONLY
CallingConv getCC() const
QualType getElementType() const
Represents a vector type where either the type or size is dependent.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
No ref-qualifier was provided.
Qualifiers getMethodQuals() const
const TemplateTypeParmType * getReplacedParameter() const
Gets the template parameter that was substituted for.
QualType getEquivalentType() const
QualType getInnerType() const
is AltiVec 'vector bool ...'
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
AutoTypeKeyword getKeyword() const
Qualifiers getIndexTypeQualifiers() const
TypeClass getTypeClass() const
ArrayRef< TemplateArgument > template_arguments() const
EnumDecl * getDecl() const
An rvalue ref-qualifier was provided (&&).
ParameterABI
Kinds of parameter ABI.
std::string getAsString() const
Represents a pointer type decayed from an array or function type.
The injected class name of a C++ class template or class template partial specialization.
QualType getPointeeType() const
Represents a pack expansion of types.
Defines various enumerations that describe declaration and type specifiers.
StringRef getName() const
Return the actual identifier string.
Base class for declarations which introduce a typedef-name.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons...
Dataflow Directional Tag Classes.
ExtInfo getExtInfo() const
NestedNameSpecifier * getQualifier() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
VectorKind getVectorKind() const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A pointer to member type per C++ 8.3.3 - Pointers to members.
QualType getModifiedType() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
unsigned getIndexTypeCVRQualifiers() const
const llvm::APInt & getSize() const
bool isFunctionType() const
bool isObjCQualifiedIdType() const
ExtVectorType - Extended vector type.
Base for LValueReferenceType and RValueReferenceType.
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
QualType getUnderlyingType() const
SourceManager & getSourceManager()
A template argument list.
VectorType::VectorKind getVectorKind() const
TypedefNameDecl * getDecl() const
unsigned getDepth() const
An attributed type is a type to which a type attribute has been applied.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
QualType getParamType(unsigned i) const
Represents a type parameter type in Objective C.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
Defines the clang::SourceLocation class and associated facilities.
TypedefNameDecl * getTypedefNameForAnonDecl() const
Represents a template specialization type whose template cannot be resolved, e.g. ...
ArrayRef< TemplateArgument > template_arguments() const
Represents a C array with an unspecified size.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNamedType() const
Retrieve the type named by the qualified-id.
QualType getReplacementType() const
Gets the type that was substituted for the template parameter.
This class is used for builtin types like 'int'.
static QualType skipTopLevelReferences(QualType T)
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
unsigned getNumElements() const
Microsoft __declspec(nothrow) extension.
Represents an extended address space qualifier where the input address space value is dependent...
Represents a type template specialization; the template must be a class template, a type alias templa...
This represents a decl that may have a name.
bool isTranslationUnit() const
Represents a C array with a specified size that is not an integer-constant-expression.
No keyword precedes the qualified type name.
QualType getElementType() const
llvm::Optional< NullabilityKind > getImmediateNullability() const
Represents the canonical version of C arrays with a specified constant size.
A class which abstracts out some details necessary for making a call.
SourceLocation getLocation() const
QualType getPointeeType() const
This parameter (which must have pointer type) is a Swift indirect result parameter.
const IdentifierInfo * getIdentifier() const
Expr * getSizeExpr() const