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.inc" 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)
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.inc" 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.inc" 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);
791 for (
unsigned i = 0, e = T->
getNumParams(); i != e; ++i) {
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) {
1061 spaceBeforePlaceHolder(OS);
1065 void TypePrinter::printAutoAfter(
const AutoType *T, raw_ostream &OS) {
1071 void TypePrinter::printDeducedTemplateSpecializationBefore(
1077 IncludeStrongLifetimeRAII Strong(Policy);
1079 spaceBeforePlaceHolder(OS);
1083 void TypePrinter::printDeducedTemplateSpecializationAfter(
1090 void TypePrinter::printAtomicBefore(
const AtomicType *T, raw_ostream &OS) {
1091 IncludeStrongLifetimeRAII Strong(Policy);
1096 spaceBeforePlaceHolder(OS);
1099 void TypePrinter::printAtomicAfter(
const AtomicType *T, raw_ostream &OS) {}
1101 void TypePrinter::printPipeBefore(
const PipeType *T, raw_ostream &OS) {
1102 IncludeStrongLifetimeRAII Strong(Policy);
1107 OS <<
"write_only ";
1110 spaceBeforePlaceHolder(OS);
1113 void TypePrinter::printPipeAfter(
const PipeType *T, raw_ostream &OS) {}
1116 void TypePrinter::AppendScope(
DeclContext *DC, raw_ostream &OS) {
1121 if (
const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1122 if (Policy.SuppressUnwrittenScope &&
1123 (NS->isAnonymousNamespace() || NS->isInline()))
1125 if (NS->getIdentifier())
1126 OS << NS->getName() <<
"::";
1128 OS <<
"(anonymous namespace)::";
1129 }
else if (
const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1130 IncludeStrongLifetimeRAII Strong(Policy);
1131 OS << Spec->getIdentifier()->getName();
1135 }
else if (
const auto *Tag = dyn_cast<TagDecl>(DC)) {
1137 OS << Typedef->getIdentifier()->getName() <<
"::";
1138 else if (Tag->getIdentifier())
1139 OS << Tag->getIdentifier()->getName() <<
"::";
1145 void TypePrinter::printTag(
TagDecl *D, raw_ostream &OS) {
1146 if (Policy.IncludeTagDefinition) {
1149 D->
print(OS, SubPolicy, Indentation);
1150 spaceBeforePlaceHolder(OS);
1154 bool HasKindDecoration =
false;
1159 HasKindDecoration =
true;
1167 if (!Policy.SuppressScope)
1171 OS << II->getName();
1173 assert(Typedef->getIdentifier() &&
"Typedef without identifier?");
1174 OS << Typedef->getIdentifier()->getName();
1178 OS << (Policy.MSVCFormatting ?
'`' :
'(');
1180 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1182 HasKindDecoration =
true;
1187 if (Policy.AnonymousTagLocations) {
1191 if (!HasKindDecoration)
1199 if (
auto *Callbacks = Policy.Callbacks)
1200 OS << Callbacks->remapPath(File);
1207 OS << (Policy.MSVCFormatting ?
'\'' :
')');
1212 if (
const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1215 if (!Policy.PrintCanonicalTypes && TAW) {
1217 cast<TemplateSpecializationType>(TAW->
getType());
1221 Args = TemplateArgs.
asArray();
1223 IncludeStrongLifetimeRAII Strong(Policy);
1227 spaceBeforePlaceHolder(OS);
1230 void TypePrinter::printRecordBefore(
const RecordType *T, raw_ostream &OS) {
1234 void TypePrinter::printRecordAfter(
const RecordType *T, raw_ostream &OS) {}
1236 void TypePrinter::printEnumBefore(
const EnumType *T, raw_ostream &OS) {
1240 void TypePrinter::printEnumAfter(
const EnumType *T, raw_ostream &OS) {}
1247 TC->
print(OS, Policy);
1252 OS <<
Id->getName();
1256 spaceBeforePlaceHolder(OS);
1262 void TypePrinter::printSubstTemplateTypeParmBefore(
1265 IncludeStrongLifetimeRAII Strong(Policy);
1269 void TypePrinter::printSubstTemplateTypeParmAfter(
1272 IncludeStrongLifetimeRAII Strong(Policy);
1276 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1279 IncludeStrongLifetimeRAII Strong(Policy);
1283 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1286 IncludeStrongLifetimeRAII Strong(Policy);
1290 void TypePrinter::printTemplateSpecializationBefore(
1293 IncludeStrongLifetimeRAII Strong(Policy);
1297 spaceBeforePlaceHolder(OS);
1300 void TypePrinter::printTemplateSpecializationAfter(
1317 "OwnedTagDecl expected to be a declaration for the type");
1320 OwnedTagDecl->
print(OS, SubPolicy, Indentation);
1321 spaceBeforePlaceHolder(OS);
1326 if (!Policy.IncludeTagDefinition)
1333 Qualifier->
print(OS, Policy);
1336 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1344 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1348 void TypePrinter::printParenBefore(
const ParenType *T, raw_ostream &OS) {
1349 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1356 void TypePrinter::printParenAfter(
const ParenType *T, raw_ostream &OS) {
1357 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1373 spaceBeforePlaceHolder(OS);
1379 void TypePrinter::printDependentTemplateSpecializationBefore(
1381 IncludeStrongLifetimeRAII Strong(Policy);
1391 spaceBeforePlaceHolder(OS);
1394 void TypePrinter::printDependentTemplateSpecializationAfter(
1428 case attr::Ptr32: OS <<
" __ptr32";
break;
1429 case attr::Ptr64: OS <<
" __ptr64";
break;
1430 case attr::SPtr: OS <<
" __sptr";
break;
1431 case attr::UPtr: OS <<
" __uptr";
break;
1433 spaceBeforePlaceHolder(OS);
1442 else if (T->
getAttrKind() == attr::TypeNullUnspecified)
1443 OS <<
" _Null_unspecified";
1445 llvm_unreachable(
"unhandled nullability");
1446 spaceBeforePlaceHolder(OS);
1472 if (T->
getAttrKind() == attr::ObjCInertUnsafeUnretained)
1476 if (T->
getAttrKind() == attr::NSReturnsRetained &&
1478 ->getExtInfo().getProducesResult())
1482 OS <<
" [[clang::lifetimebound]]";
1492 OS <<
" __attribute__((";
1494 #define TYPE_ATTR(NAME) 1495 #define DECL_OR_TYPE_ATTR(NAME) 1496 #define ATTR(NAME) case attr::NAME: 1497 #include "clang/Basic/AttrList.inc" 1498 llvm_unreachable(
"non-type attribute attached to type");
1500 case attr::OpenCLPrivateAddressSpace:
1501 case attr::OpenCLGlobalAddressSpace:
1502 case attr::OpenCLLocalAddressSpace:
1503 case attr::OpenCLConstantAddressSpace:
1504 case attr::OpenCLGenericAddressSpace:
1509 case attr::LifetimeBound:
1510 case attr::TypeNonNull:
1511 case attr::TypeNullable:
1512 case attr::TypeNullUnspecified:
1514 case attr::ObjCInertUnsafeUnretained:
1515 case attr::ObjCKindOf:
1516 case attr::ObjCOwnership:
1521 case attr::AddressSpace:
1522 llvm_unreachable(
"This attribute should have been handled already");
1524 case attr::NSReturnsRetained:
1525 OS <<
"ns_returns_retained";
1530 case attr::AnyX86NoCfCheck: OS <<
"nocf_check";
break;
1531 case attr::CDecl: OS <<
"cdecl";
break;
1532 case attr::FastCall: OS <<
"fastcall";
break;
1533 case attr::StdCall: OS <<
"stdcall";
break;
1534 case attr::ThisCall: OS <<
"thiscall";
break;
1535 case attr::SwiftCall: OS <<
"swiftcall";
break;
1536 case attr::VectorCall: OS <<
"vectorcall";
break;
1537 case attr::Pascal: OS <<
"pascal";
break;
1538 case attr::MSABI: OS <<
"ms_abi";
break;
1539 case attr::SysVABI: OS <<
"sysv_abi";
break;
1540 case attr::RegCall: OS <<
"regcall";
break;
1547 "\"aapcs\"" :
"\"aapcs-vfp\"");
1551 case attr::AArch64VectorPcs: OS <<
"aarch64_vector_pcs";
break;
1552 case attr::IntelOclBicc: OS <<
"inteloclbicc";
break;
1553 case attr::PreserveMost:
1554 OS <<
"preserve_most";
1557 case attr::PreserveAll:
1558 OS <<
"preserve_all";
1563 case attr::AcquireHandle:
1564 OS <<
"acquire_handle";
1573 spaceBeforePlaceHolder(OS);
1583 bool isFirst =
true;
1585 for (
const auto *I : T->
quals()) {
1595 spaceBeforePlaceHolder(OS); 1598 void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T, 1601 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T, 1603 if (T->qual_empty() && T->isUnspecializedAsWritten() && 1604 !T->isKindOfTypeAsWritten()) 1605 return printBefore(T->getBaseType(), OS); 1607 if (T->isKindOfTypeAsWritten()) 1610 print(T->getBaseType(), OS, StringRef()); 1612 if (T->isSpecializedAsWritten()) { 1613 bool isFirst = true; 1615 for (auto typeArg : T->getTypeArgsAsWritten()) { 1621 print(typeArg, OS, StringRef()); 1626 if (!T->qual_empty()) { 1627 bool isFirst = true; 1629 for (const auto *I : T->quals()) { 1639 spaceBeforePlaceHolder(OS); 1642 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T, 1644 if (T->qual_empty() && T->isUnspecializedAsWritten() && 1645 !T->isKindOfTypeAsWritten()) 1646 return printAfter(T->getBaseType(), OS); 1649 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T, 1651 printBefore(T->getPointeeType(), OS); 1653 // If we need to print the pointer, print it now. 1654 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() && 1655 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) { 1656 if (HasEmptyPlaceHolder) 1662 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T, 1666 const TemplateArgument &getArgument(const TemplateArgument &A) { return A; } 1668 static const TemplateArgument &getArgument(const TemplateArgumentLoc &A) { 1669 return A.getArgument(); 1672 static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, 1673 llvm::raw_ostream &OS) { 1677 static void printArgument(const TemplateArgumentLoc &A, 1678 const PrintingPolicy &PP, llvm::raw_ostream &OS) { 1679 const TemplateArgument::ArgKind &Kind = A.getArgument().getKind(); 1680 if (Kind == TemplateArgument::ArgKind::Type) 1681 return A.getTypeSourceInfo()->getType().print(OS, PP); 1682 return A.getArgument().print(PP, OS); 1685 template<typename TA> 1686 static void printTo(raw_ostream &OS, ArrayRef<TA> Args, 1687 const PrintingPolicy &Policy, bool SkipBrackets) { 1688 const char *Comma = Policy.MSVCFormatting ? "," : ", "; 1692 bool NeedSpace = false; 1693 bool FirstArg = true; 1694 for (const auto &Arg : Args) { 1695 // Print the argument into a string. 1696 SmallString<128> Buf; 1697 llvm::raw_svector_ostream ArgOS(Buf); 1698 const TemplateArgument &Argument = getArgument(Arg); 1699 if (Argument.getKind() == TemplateArgument::Pack) { 1700 if (Argument.pack_size() && !FirstArg) 1702 printTo(ArgOS, Argument.getPackAsArray(), Policy, true); 1706 // Tries to print the argument with location info if exists. 1707 printArgument(Arg, Policy, ArgOS); 1709 StringRef ArgString = ArgOS.str(); 1711 // If this is the first argument and its string representation 1712 // begins with the global scope specifier ('::foo
'), add a space 1713 // to avoid printing the diagraph '<:
'. 1714 if (FirstArg && !ArgString.empty() && ArgString[0] == ':
') 1719 NeedSpace = (!ArgString.empty() && ArgString.back() == '>
'); 1723 // If the last character of our string is '>
', add another space to 1724 // keep the two '>
''s separate tokens. We don
't *have* to do this in 1725 // C++0x, but it's still good hygiene.
1733 void clang::printTemplateArgumentList(raw_ostream &OS, 1734 const TemplateArgumentListInfo &Args, 1735 const PrintingPolicy &Policy) { 1736 return printTo(OS, Args.arguments(), Policy, false); 1739 void clang::printTemplateArgumentList(raw_ostream &OS, 1740 ArrayRef<TemplateArgument> Args, 1741 const PrintingPolicy &Policy) { 1742 printTo(OS, Args, Policy, false); 1745 void clang::printTemplateArgumentList(raw_ostream &OS, 1746 ArrayRef<TemplateArgumentLoc> Args, 1747 const PrintingPolicy &Policy) { 1748 printTo(OS, Args, Policy, false); 1751 std::string Qualifiers::getAsString() const { 1753 return getAsString(PrintingPolicy(LO)); 1756 // Appends qualifiers to the given string, separated by spaces. Will 1757 // prefix a space if the string is non-empty. Will not append a final 1759 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const { 1760 SmallString<64> Buf; 1761 llvm::raw_svector_ostream StrOS(Buf); 1762 print(StrOS, Policy); 1766 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const { 1767 if (getCVRQualifiers()) 1770 if (getAddressSpace() != LangAS::Default) 1773 if (getObjCGCAttr()) 1776 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) 1777 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)) 1783 std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { 1785 case LangAS::Default: 1787 case LangAS::opencl_global: 1789 case LangAS::opencl_local: 1791 case LangAS::opencl_private: 1793 case LangAS::opencl_constant: 1794 return "__constant"; 1795 case LangAS::opencl_generic: 1797 case LangAS::cuda_device: 1798 return "__device__"; 1799 case LangAS::cuda_constant: 1800 return "__constant__"; 1801 case LangAS::cuda_shared: 1802 return "__shared__"; 1803 case LangAS::ptr32_sptr: 1804 return "__sptr __ptr32"; 1805 case LangAS::ptr32_uptr: 1806 return "__uptr __ptr32"; 1810 return std::to_string(toTargetAddressSpace(AS)); 1814 // Appends qualifiers to the given string, separated by spaces. Will 1815 // prefix a space if the string is non-empty. Will not append a final 1817 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, 1818 bool appendSpaceIfNonEmpty) const { 1819 bool addSpace = false; 1821 unsigned quals = getCVRQualifiers(); 1823 AppendTypeQualList(OS, quals, Policy.Restrict); 1826 if (hasUnaligned()) { 1829 OS << "__unaligned"; 1832 auto ASStr = getAddrSpaceAsString(getAddressSpace()); 1833 if (!ASStr.empty()) { 1837 // Wrap target address space into an attribute syntax 1838 if (isTargetAddressSpace(getAddressSpace())) 1839 OS << "__attribute__((address_space(" << ASStr << ")))"; 1844 if (Qualifiers::GC gc = getObjCGCAttr()) { 1848 if (gc == Qualifiers::Weak) 1853 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) { 1854 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){ 1861 case Qualifiers::OCL_None: llvm_unreachable("none but true"); 1862 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break; 1863 case Qualifiers::OCL_Strong: 1864 if (!Policy.SuppressStrongLifetime) 1868 case Qualifiers::OCL_Weak: OS << "__weak"; break; 1869 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break; 1873 if (appendSpaceIfNonEmpty && addSpace) 1877 std::string QualType::getAsString() const { 1878 return getAsString(split(), LangOptions()); 1881 std::string QualType::getAsString(const PrintingPolicy &Policy) const { 1883 getAsStringInternal(S, Policy); 1887 std::string QualType::getAsString(const Type *ty, Qualifiers qs, 1888 const PrintingPolicy &Policy) { 1890 getAsStringInternal(ty, qs, buffer, Policy); 1894 void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy, 1895 const Twine &PlaceHolder, unsigned Indentation) const { 1896 print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder, 1900 void QualType::print(const Type *ty, Qualifiers qs, 1901 raw_ostream &OS, const PrintingPolicy &policy, 1902 const Twine &PlaceHolder, unsigned Indentation) { 1903 SmallString<128> PHBuf; 1904 StringRef PH = PlaceHolder.toStringRef(PHBuf); 1906 TypePrinter(policy, Indentation).print(ty, qs, OS, PH); 1909 void QualType::getAsStringInternal(std::string &Str, 1910 const PrintingPolicy &Policy) const { 1911 return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str, 1915 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, 1916 std::string &buffer, 1917 const PrintingPolicy &policy) { 1918 SmallString<256> Buf; 1919 llvm::raw_svector_ostream StrOS(Buf); 1920 TypePrinter(policy).print(ty, qs, StrOS, buffer); 1921 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)
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
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, possibly constrained by a type-constraint.
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. ...
void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, QualType Ty)
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...
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
bool isConstrained() const
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
Declaration of a template type parameter.
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
ConceptDecl * getTypeConstraintConcept() 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
QualType getType() const
Return the type wrapped by this type source info.
This parameter (which must have pointer type) is a Swift indirect result parameter.
const IdentifierInfo * getIdentifier() const
Expr * getSizeExpr() const