23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/Support/SaveAndRestore.h"
26 #include "llvm/Support/raw_ostream.h"
27 using namespace clang;
32 class IncludeStrongLifetimeRAII {
38 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
43 ~IncludeStrongLifetimeRAII() {
48 class ParamPolicyRAII {
54 : Policy(Policy), Old(Policy.SuppressSpecifiers) {
59 Policy.SuppressSpecifiers = Old;
63 class ElaboratedTypePolicyRAII {
65 bool SuppressTagKeyword;
69 explicit ElaboratedTypePolicyRAII(
PrintingPolicy &Policy) : Policy(Policy) {
76 ~ElaboratedTypePolicyRAII() {
77 Policy.SuppressTagKeyword = SuppressTagKeyword;
78 Policy.SuppressScope = SuppressScope;
85 bool HasEmptyPlaceHolder;
86 bool InsideCCAttribute;
89 explicit TypePrinter(
const PrintingPolicy &Policy,
unsigned Indentation = 0)
90 : Policy(Policy), Indentation(Indentation),
91 HasEmptyPlaceHolder(
false), InsideCCAttribute(
false) { }
94 StringRef PlaceHolder);
95 void print(
QualType T, raw_ostream &OS, StringRef PlaceHolder);
97 static bool canPrefixQualifiers(
const Type *T,
bool &NeedARCStrongQualifier);
98 void spaceBeforePlaceHolder(raw_ostream &OS);
99 void printTypeSpec(
NamedDecl *D, raw_ostream &OS);
102 void printBefore(
QualType T, raw_ostream &OS);
104 void printAfter(
QualType T, raw_ostream &OS);
105 void AppendScope(
DeclContext *DC, raw_ostream &OS);
106 void printTag(
TagDecl *T, raw_ostream &OS);
108 #define ABSTRACT_TYPE(CLASS, PARENT)
109 #define TYPE(CLASS, PARENT) \
110 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
111 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
112 #include "clang/AST/TypeNodes.def"
117 bool HasRestrictKeyword) {
118 bool appendSpace =
false;
124 if (appendSpace) OS <<
' ';
129 if (appendSpace) OS <<
' ';
130 if (HasRestrictKeyword) {
138 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
139 if (!HasEmptyPlaceHolder)
143 void TypePrinter::print(
QualType t, raw_ostream &OS, StringRef PlaceHolder) {
145 print(split.
Ty, split.
Quals, OS, PlaceHolder);
148 void TypePrinter::print(
const Type *T,
Qualifiers Quals, raw_ostream &OS,
149 StringRef PlaceHolder) {
157 printBefore(T, Quals, OS);
159 printAfter(T, Quals, OS);
162 bool TypePrinter::canPrefixQualifiers(
const Type *T,
163 bool &NeedARCStrongQualifier) {
169 bool CanPrefixQualifiers =
false;
170 NeedARCStrongQualifier =
false;
172 if (
const AutoType *AT = dyn_cast<AutoType>(T))
173 TC = AT->desugar()->getTypeClass();
175 = dyn_cast<SubstTemplateTypeParmType>(T))
176 TC = Subst->getReplacementType()->getTypeClass();
182 case Type::UnresolvedUsing:
184 case Type::TypeOfExpr:
187 case Type::UnaryTransform:
190 case Type::Elaborated:
191 case Type::TemplateTypeParm:
192 case Type::SubstTemplateTypeParmPack:
193 case Type::DeducedTemplateSpecialization:
194 case Type::TemplateSpecialization:
195 case Type::InjectedClassName:
196 case Type::DependentName:
197 case Type::DependentTemplateSpecialization:
198 case Type::ObjCObject:
199 case Type::ObjCTypeParam:
200 case Type::ObjCInterface:
203 CanPrefixQualifiers =
true;
206 case Type::ObjCObjectPointer:
211 case Type::ConstantArray:
212 case Type::IncompleteArray:
213 case Type::VariableArray:
214 case Type::DependentSizedArray:
215 NeedARCStrongQualifier =
true;
221 case Type::BlockPointer:
222 case Type::LValueReference:
223 case Type::RValueReference:
224 case Type::MemberPointer:
225 case Type::DependentSizedExtVector:
227 case Type::ExtVector:
228 case Type::FunctionProto:
229 case Type::FunctionNoProto:
231 case Type::Attributed:
232 case Type::PackExpansion:
233 case Type::SubstTemplateTypeParm:
234 CanPrefixQualifiers =
false;
238 return CanPrefixQualifiers;
241 void TypePrinter::printBefore(
QualType T, raw_ostream &OS) {
248 dyn_cast<SubstTemplateTypeParmType>(Split.
Ty))
251 printBefore(Split.
Ty, Quals, OS);
256 void TypePrinter::printBefore(
const Type *T,
Qualifiers Quals, raw_ostream &OS) {
264 bool CanPrefixQualifiers =
false;
265 bool NeedARCStrongQualifier =
false;
266 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
268 if (CanPrefixQualifiers && !Quals.
empty()) {
269 if (NeedARCStrongQualifier) {
270 IncludeStrongLifetimeRAII Strong(Policy);
271 Quals.
print(OS, Policy,
true);
273 Quals.
print(OS, Policy,
true);
277 bool hasAfterQuals =
false;
278 if (!CanPrefixQualifiers && !Quals.
empty()) {
281 HasEmptyPlaceHolder =
false;
285 #define ABSTRACT_TYPE(CLASS, PARENT)
286 #define TYPE(CLASS, PARENT) case Type::CLASS: \
287 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
289 #include "clang/AST/TypeNodes.def"
293 if (NeedARCStrongQualifier) {
294 IncludeStrongLifetimeRAII Strong(Policy);
295 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
297 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
302 void TypePrinter::printAfter(
QualType t, raw_ostream &OS) {
304 printAfter(split.
Ty, split.
Quals, OS);
309 void TypePrinter::printAfter(
const Type *T,
Qualifiers Quals, raw_ostream &OS) {
311 #define ABSTRACT_TYPE(CLASS, PARENT)
312 #define TYPE(CLASS, PARENT) case Type::CLASS: \
313 print##CLASS##After(cast<CLASS##Type>(T), OS); \
315 #include "clang/AST/TypeNodes.def"
319 void TypePrinter::printBuiltinBefore(
const BuiltinType *T, raw_ostream &OS) {
321 spaceBeforePlaceHolder(OS);
323 void TypePrinter::printBuiltinAfter(
const BuiltinType *T, raw_ostream &OS) { }
325 void TypePrinter::printComplexBefore(
const ComplexType *T, raw_ostream &OS) {
329 void TypePrinter::printComplexAfter(
const ComplexType *T, raw_ostream &OS) {
333 void TypePrinter::printPointerBefore(
const PointerType *T, raw_ostream &OS) {
334 IncludeStrongLifetimeRAII Strong(Policy);
343 void TypePrinter::printPointerAfter(
const PointerType *T, raw_ostream &OS) {
344 IncludeStrongLifetimeRAII Strong(Policy);
367 IncludeStrongLifetimeRAII Strong(Policy);
378 IncludeStrongLifetimeRAII Strong(Policy);
389 IncludeStrongLifetimeRAII Strong(Policy);
400 IncludeStrongLifetimeRAII Strong(Policy);
411 IncludeStrongLifetimeRAII Strong(Policy);
420 InnerPolicy.IncludeTagDefinition =
false;
421 TypePrinter(InnerPolicy).print(
QualType(T->
getClass(), 0), OS, StringRef());
427 IncludeStrongLifetimeRAII Strong(Policy);
438 IncludeStrongLifetimeRAII Strong(Policy);
454 OS << T->
getSize().getZExtValue() <<
']';
460 IncludeStrongLifetimeRAII Strong(Policy);
472 IncludeStrongLifetimeRAII Strong(Policy);
496 void TypePrinter::printAdjustedBefore(
const AdjustedType *T, raw_ostream &OS) {
501 void TypePrinter::printAdjustedAfter(
const AdjustedType *T, raw_ostream &OS) {
505 void TypePrinter::printDecayedBefore(
const DecayedType *T, raw_ostream &OS) {
507 printAdjustedBefore(T, OS);
509 void TypePrinter::printDecayedAfter(
const DecayedType *T, raw_ostream &OS) {
510 printAdjustedAfter(T, OS);
513 void TypePrinter::printDependentSizedArrayBefore(
516 IncludeStrongLifetimeRAII Strong(Policy);
520 void TypePrinter::printDependentSizedArrayAfter(
530 void TypePrinter::printDependentSizedExtVectorBefore(
535 void TypePrinter::printDependentSizedExtVectorAfter(
538 OS <<
" __attribute__((ext_vector_type(";
545 void TypePrinter::printVectorBefore(
const VectorType *T, raw_ostream &OS) {
548 OS <<
"__vector __pixel ";
551 OS <<
"__vector __bool ";
559 OS <<
"__attribute__((neon_vector_type("
564 OS <<
"__attribute__((neon_polyvector_type(" <<
571 OS <<
"__attribute__((__vector_size__("
581 void TypePrinter::printVectorAfter(
const VectorType *T, raw_ostream &OS) {
585 void TypePrinter::printExtVectorBefore(
const ExtVectorType *T,
589 void TypePrinter::printExtVectorAfter(
const ExtVectorType *T, raw_ostream &OS) {
591 OS <<
" __attribute__((ext_vector_type(";
628 if (!HasEmptyPlaceHolder)
634 if (!PrevPHIsEmpty.get())
642 llvm_unreachable(
"asking for spelling of ordinary parameter ABI");
644 return "swift_context";
646 return "swift_error_result";
648 return "swift_indirect_result";
650 llvm_unreachable(
"bad parameter ABI kind");
656 if (!HasEmptyPlaceHolder)
662 ParamPolicyRAII ParamPolicy(Policy);
663 for (
unsigned i = 0, e = T->
getNumParams(); i != e; ++i) {
667 if (EPI.isConsumed()) OS <<
"__attribute__((ns_consumed)) ";
680 }
else if (T->
getNumParams() == 0 && Policy.UseVoidForZeroParams) {
689 printFunctionAfter(Info, OS);
719 if (!InsideCCAttribute) {
720 switch (Info.
getCC()) {
731 OS <<
" __attribute__((stdcall))";
734 OS <<
" __attribute__((fastcall))";
737 OS <<
" __attribute__((thiscall))";
740 OS <<
" __attribute__((vectorcall))";
743 OS <<
" __attribute__((pascal))";
746 OS <<
" __attribute__((pcs(\"aapcs\")))";
749 OS <<
" __attribute__((pcs(\"aapcs-vfp\")))";
752 OS <<
" __attribute__((intel_ocl_bicc))";
755 OS <<
" __attribute__((ms_abi))";
758 OS <<
" __attribute__((sysv_abi))";
761 OS <<
" __attribute__((regcall))";
768 OS <<
" __attribute__((swiftcall))";
771 OS <<
" __attribute__((preserve_most))";
774 OS <<
" __attribute__((preserve_all))";
780 OS <<
" __attribute__((noreturn))";
782 OS <<
" __attribute__((ns_returns_retained))";
784 OS <<
" __attribute__((regparm ("
787 OS <<
" __attribute__((no_caller_saved_registers))";
795 if (!PrevPHIsEmpty.get())
801 if (!HasEmptyPlaceHolder)
810 void TypePrinter::printTypeSpec(
NamedDecl *D, raw_ostream &OS) {
815 if (!Policy.SuppressScope)
820 spaceBeforePlaceHolder(OS);
825 printTypeSpec(T->
getDecl(), OS);
830 void TypePrinter::printTypedefBefore(
const TypedefType *T, raw_ostream &OS) {
831 printTypeSpec(T->
getDecl(), OS);
833 void TypePrinter::printTypedefAfter(
const TypedefType *T, raw_ostream &OS) { }
840 spaceBeforePlaceHolder(OS);
845 void TypePrinter::printTypeOfBefore(
const TypeOfType *T, raw_ostream &OS) {
849 spaceBeforePlaceHolder(OS);
851 void TypePrinter::printTypeOfAfter(
const TypeOfType *T, raw_ostream &OS) { }
853 void TypePrinter::printDecltypeBefore(
const DecltypeType *T, raw_ostream &OS) {
858 spaceBeforePlaceHolder(OS);
860 void TypePrinter::printDecltypeAfter(
const DecltypeType *T, raw_ostream &OS) { }
864 IncludeStrongLifetimeRAII Strong(Policy);
868 OS <<
"__underlying_type(";
871 spaceBeforePlaceHolder(OS);
879 IncludeStrongLifetimeRAII Strong(Policy);
889 void TypePrinter::printAutoBefore(
const AutoType *T, raw_ostream &OS) {
899 spaceBeforePlaceHolder(OS);
902 void TypePrinter::printAutoAfter(
const AutoType *T, raw_ostream &OS) {
908 void TypePrinter::printDeducedTemplateSpecializationBefore(
914 IncludeStrongLifetimeRAII Strong(Policy);
916 spaceBeforePlaceHolder(OS);
919 void TypePrinter::printDeducedTemplateSpecializationAfter(
926 void TypePrinter::printAtomicBefore(
const AtomicType *T, raw_ostream &OS) {
927 IncludeStrongLifetimeRAII Strong(Policy);
932 spaceBeforePlaceHolder(OS);
934 void TypePrinter::printAtomicAfter(
const AtomicType *T, raw_ostream &OS) { }
936 void TypePrinter::printPipeBefore(
const PipeType *T, raw_ostream &OS) {
937 IncludeStrongLifetimeRAII Strong(Policy);
945 spaceBeforePlaceHolder(OS);
948 void TypePrinter::printPipeAfter(
const PipeType *T, raw_ostream &OS) {
951 void TypePrinter::AppendScope(
DeclContext *DC, raw_ostream &OS) {
957 if (Policy.SuppressUnwrittenScope &&
958 (NS->isAnonymousNamespace() || NS->isInline()))
960 if (NS->getIdentifier())
961 OS << NS->getName() <<
"::";
963 OS <<
"(anonymous namespace)::";
965 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
966 IncludeStrongLifetimeRAII Strong(Policy);
967 OS << Spec->getIdentifier()->getName();
970 OS, TemplateArgs.
asArray(), Policy);
972 }
else if (
TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
974 OS << Typedef->getIdentifier()->getName() <<
"::";
975 else if (Tag->getIdentifier())
976 OS << Tag->getIdentifier()->getName() <<
"::";
982 void TypePrinter::printTag(
TagDecl *D, raw_ostream &OS) {
983 if (Policy.IncludeTagDefinition) {
986 D->
print(OS, SubPolicy, Indentation);
987 spaceBeforePlaceHolder(OS);
991 bool HasKindDecoration =
false;
996 HasKindDecoration =
true;
1004 if (!Policy.SuppressScope)
1008 OS << II->getName();
1010 assert(Typedef->getIdentifier() &&
"Typedef without identifier?");
1011 OS << Typedef->getIdentifier()->getName();
1015 OS << (Policy.MSVCFormatting ?
'`' :
'(');
1017 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
1019 HasKindDecoration =
true;
1024 if (Policy.AnonymousTagLocations) {
1028 if (!HasKindDecoration)
1040 OS << (Policy.MSVCFormatting ?
'\'' :
')');
1046 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1050 cast<TemplateSpecializationType>(TAW->getType());
1054 Args = TemplateArgs.
asArray();
1056 IncludeStrongLifetimeRAII Strong(Policy);
1060 spaceBeforePlaceHolder(OS);
1063 void TypePrinter::printRecordBefore(
const RecordType *T, raw_ostream &OS) {
1066 void TypePrinter::printRecordAfter(
const RecordType *T, raw_ostream &OS) { }
1068 void TypePrinter::printEnumBefore(
const EnumType *T, raw_ostream &OS) {
1071 void TypePrinter::printEnumAfter(
const EnumType *T, raw_ostream &OS) { }
1076 OS << Id->getName();
1079 spaceBeforePlaceHolder(OS);
1082 raw_ostream &OS) { }
1084 void TypePrinter::printSubstTemplateTypeParmBefore(
1087 IncludeStrongLifetimeRAII Strong(Policy);
1090 void TypePrinter::printSubstTemplateTypeParmAfter(
1093 IncludeStrongLifetimeRAII Strong(Policy);
1097 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1100 IncludeStrongLifetimeRAII Strong(Policy);
1103 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1106 IncludeStrongLifetimeRAII Strong(Policy);
1110 void TypePrinter::printTemplateSpecializationBefore(
1113 IncludeStrongLifetimeRAII Strong(Policy);
1118 spaceBeforePlaceHolder(OS);
1120 void TypePrinter::printTemplateSpecializationAfter(
1122 raw_ostream &OS) { }
1129 raw_ostream &OS) { }
1134 if (!Policy.IncludeTagDefinition)
1141 Qualifier->
print(OS, Policy);
1144 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1149 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1153 void TypePrinter::printParenBefore(
const ParenType *T, raw_ostream &OS) {
1154 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1160 void TypePrinter::printParenAfter(
const ParenType *T, raw_ostream &OS) {
1161 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1177 spaceBeforePlaceHolder(OS);
1180 raw_ostream &OS) { }
1182 void TypePrinter::printDependentTemplateSpecializationBefore(
1184 IncludeStrongLifetimeRAII Strong(Policy);
1196 spaceBeforePlaceHolder(OS);
1198 void TypePrinter::printDependentTemplateSpecializationAfter(
1231 spaceBeforePlaceHolder(OS);
1243 OS <<
" _Null_unspecified";
1245 llvm_unreachable(
"unhandled nullability");
1246 spaceBeforePlaceHolder(OS);
1283 ->getExtInfo().getProducesResult())
1295 OS <<
" _Null_unspecified";
1297 llvm_unreachable(
"unhandled nullability");
1302 OS <<
" __attribute__((";
1304 default: llvm_unreachable(
"This attribute should have been handled already");
1306 OS <<
"address_space(";
1312 OS <<
"__vector_size__(";
1314 OS << vector->getNumElements();
1316 print(vector->getElementType(), OS, StringRef());
1326 OS <<
"neon_vector_type(";
1328 OS <<
"neon_polyvector_type(";
1353 if (next == tmp)
break;
1366 OS <<
"objc_ownership(";
1378 OS <<
"ns_returns_retained";
1402 "\"aapcs\"" :
"\"aapcs-vfp\"");
1408 OS <<
"preserve_most";
1411 OS <<
"preserve_all";
1420 spaceBeforePlaceHolder(OS);
1423 raw_ostream &OS) { }
1429 bool isFirst =
true;
1431 for (
const auto *
I : T->
quals()) {
1441 spaceBeforePlaceHolder(OS);
1444 void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
1445 raw_ostream &OS) { }
1447 void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
1449 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1450 !T->isKindOfTypeAsWritten())
1451 return printBefore(T->getBaseType(), OS);
1453 if (T->isKindOfTypeAsWritten())
1456 print(T->getBaseType(), OS, StringRef());
1458 if (T->isSpecializedAsWritten()) {
1459 bool isFirst = true;
1461 for (auto typeArg : T->getTypeArgsAsWritten()) {
1467 print(typeArg, OS, StringRef());
1472 if (!T->qual_empty()) {
1473 bool isFirst = true;
1475 for (const auto *I : T->quals()) {
1485 spaceBeforePlaceHolder(OS);
1487 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1489 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1490 !T->isKindOfTypeAsWritten())
1491 return printAfter(T->getBaseType(), OS);
1494 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1496 printBefore(T->getPointeeType(), OS);
1498 // If we need to print the pointer, print it now.
1499 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
1500 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
1501 if (HasEmptyPlaceHolder)
1506 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1507 raw_ostream &OS) { }
1509 void TemplateSpecializationType::
1510 PrintTemplateArgumentList(raw_ostream &OS,
1511 const TemplateArgumentListInfo &Args,
1512 const PrintingPolicy &Policy) {
1513 return PrintTemplateArgumentList(OS,
1518 void TemplateSpecializationType::PrintTemplateArgumentList(
1519 raw_ostream &OS, ArrayRef<TemplateArgument> Args,
1520 const PrintingPolicy &Policy, bool SkipBrackets) {
1521 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
1525 bool needSpace = false;
1526 bool FirstArg = true;
1527 for (const TemplateArgument &Arg : Args) {
1528 // Print the argument into a string.
1529 SmallString<128> Buf;
1530 llvm::raw_svector_ostream ArgOS(Buf);
1531 if (Arg.getKind() == TemplateArgument::Pack) {
1532 if (Arg.pack_size() && !FirstArg)
1534 PrintTemplateArgumentList(ArgOS,
1535 Arg.getPackAsArray(),
1540 Arg.print(Policy, ArgOS);
1542 StringRef ArgString = ArgOS.str();
1544 // If this is the first argument and its string representation
1545 // begins with the global scope specifier ('::foo
'), add a space
1546 // to avoid printing the diagraph '<:
'.
1547 if (FirstArg && !ArgString.empty() && ArgString[0] == ':
')
1552 needSpace = (!ArgString.empty() && ArgString.back() == '>
');
1556 // If the last character of our string is '>
', add another space to
1557 // keep the two '>
''s separate tokens. We don
't *have* to do this in
1558 // C++0x, but it's still good hygiene.
1566 // Sadly, repeat all that with TemplateArgLoc.
1567 void TemplateSpecializationType::
1568 PrintTemplateArgumentList(raw_ostream &OS,
1569 ArrayRef<TemplateArgumentLoc> Args,
1570 const PrintingPolicy &Policy) {
1572 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
1574 bool needSpace = false;
1575 bool FirstArg = true;
1576 for (const TemplateArgumentLoc &Arg : Args) {
1580 // Print the argument into a string.
1581 SmallString<128> Buf;
1582 llvm::raw_svector_ostream ArgOS(Buf);
1583 if (Arg.getArgument().getKind() == TemplateArgument::Pack) {
1584 PrintTemplateArgumentList(ArgOS,
1585 Arg.getArgument().getPackAsArray(),
1588 Arg.getArgument().print(Policy, ArgOS);
1590 StringRef ArgString = ArgOS.str();
1592 // If this is the first argument and its string representation
1593 // begins with the global scope specifier ('::foo
'), add a space
1594 // to avoid printing the diagraph '<:
'.
1595 if (FirstArg && !ArgString.empty() && ArgString[0] == ':
')
1600 needSpace = (!ArgString.empty() && ArgString.back() == '>
');
1604 // If the last character of our string is '>
', add another space to
1605 // keep the two '>
''s separate tokens. We don
't *have* to do this in
1606 // C++0x, but it's still good hygiene.
1613 std::string Qualifiers::getAsString() const {
1615 return getAsString(PrintingPolicy(LO));
1618 // Appends qualifiers to the given string, separated by spaces. Will
1619 // prefix a space if the string is non-empty. Will not append a final
1621 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
1622 SmallString<64> Buf;
1623 llvm::raw_svector_ostream StrOS(Buf);
1624 print(StrOS, Policy);
1628 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
1629 if (getCVRQualifiers())
1632 if (getAddressSpace())
1635 if (getObjCGCAttr())
1638 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
1639 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
1645 // Appends qualifiers to the given string, separated by spaces. Will
1646 // prefix a space if the string is non-empty. Will not append a final
1648 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
1649 bool appendSpaceIfNonEmpty) const {
1650 bool addSpace = false;
1652 unsigned quals = getCVRQualifiers();
1654 AppendTypeQualList(OS, quals, Policy.Restrict);
1657 if (hasUnaligned()) {
1660 OS << "__unaligned";
1663 if (unsigned addrspace = getAddressSpace()) {
1667 switch (addrspace) {
1668 case LangAS::opencl_global:
1671 case LangAS::opencl_local:
1674 case LangAS::opencl_constant:
1675 case LangAS::cuda_constant:
1678 case LangAS::opencl_generic:
1681 case LangAS::cuda_device:
1684 case LangAS::cuda_shared:
1688 assert(addrspace >= LangAS::FirstTargetAddressSpace);
1689 OS << "__attribute__((address_space(";
1690 OS << addrspace - LangAS::FirstTargetAddressSpace;
1694 if (Qualifiers::GC gc = getObjCGCAttr()) {
1698 if (gc == Qualifiers::Weak)
1703 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
1704 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
1711 case Qualifiers::OCL_None: llvm_unreachable("none but true");
1712 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
1713 case Qualifiers::OCL_Strong:
1714 if (!Policy.SuppressStrongLifetime)
1718 case Qualifiers::OCL_Weak: OS << "__weak"; break;
1719 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
1723 if (appendSpaceIfNonEmpty && addSpace)
1727 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
1729 getAsStringInternal(S, Policy);
1733 std::string QualType::getAsString(const Type *ty, Qualifiers qs) {
1735 LangOptions options;
1736 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
1740 void QualType::print(const Type *ty, Qualifiers qs,
1741 raw_ostream &OS, const PrintingPolicy &policy,
1742 const Twine &PlaceHolder, unsigned Indentation) {
1743 SmallString<128> PHBuf;
1744 StringRef PH = PlaceHolder.toStringRef(PHBuf);
1746 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
1749 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
1750 std::string &buffer,
1751 const PrintingPolicy &policy) {
1752 SmallString<256> Buf;
1753 llvm::raw_svector_ostream StrOS(Buf);
1754 TypePrinter(policy).print(ty, qs, StrOS, buffer);
1755 std::string str = StrOS.str();
unsigned getNumElements() const
unsigned getAddressSpace() const
Return the address space of this type.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0) const
static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)
Defines the clang::ASTContext interface.
QualType getExceptionType(unsigned i) const
Represents a type that was referred to using an elaborated type keyword, e.g., struct S...
Expr * getSizeExpr() const
const Type * Ty
The locally-unqualified type.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS=false) const
Print the template name.
static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)
ExtParameterInfo getExtParameterInfo(unsigned I) const
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
unsigned getDepth() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
Represents the dependent type named by a dependently-scoped typename using declaration, e.g.
A (possibly-)qualified type.
unsigned getColumn() const
Return the presumed column number of this location.
__auto_type (GNU extension)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
FunctionType - C99 6.7.5.3 - Function Declarators.
C Language Family Type Representation.
Defines the SourceManager interface.
Qualifiers::GC getObjCGCAttr() const
Returns gc attribute of this type.
Represents a qualified type name for which the type name is dependent.
Defines the C++ template declaration subclasses.
Represents a C++11 auto or C++14 decltype(auto) type.
QualType getPointeeType() const
The base class of the type hierarchy.
bool isObjCQualifiedClassType() const
NamespaceDecl - Represent a C++ namespace.
static void PrintTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, bool SkipBrackets=false)
Print a template argument list, including the '<' and '>' enclosing the template arguments...
A container of type source information.
unsigned getIndex() const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
const llvm::APInt & getSize() const
AutoTypeKeyword getKeyword() const
Represents a C++17 deduced template specialization type.
Describes how types, statements, expressions, and declarations should be printed. ...
Qualifiers getIndexTypeQualifiers() const
Represents the result of substituting a type for a template type parameter.
The collection of all-type qualifiers we support.
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
unsigned getNumParams() const
const IdentifierInfo * getIdentifier() const
Retrieve the type named by the typename specifier as an identifier.
QualType getElementType() const
Represents a class template specialization, which refers to a class template with a given set of temp...
One of these records is kept for each identifier that is lexed.
unsigned getIndexTypeCVRQualifiers() const
ParameterABI getABI() const
Return the ABI treatment of this parameter.
unsigned SuppressLifetimeQualifiers
When true, suppress printing of lifetime qualifier in ARC.
Expr * getSizeExpr() const
IdentifierInfo * getIdentifier() const
bool isTranslationUnit() const
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
Represents the result of substituting a set of types for a template type parameter pack...
unsigned getRegParm() const
QualType getUnderlyingType() const
Expr * getUnderlyingExpr() const
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment...
An rvalue reference type, per C++11 [dcl.ref].
An lvalue ref-qualifier was provided (&).
Microsoft throw(...) extension.
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
QualType getReturnType() const
UnresolvedUsingTypenameDecl * getDecl() const
Represents a typeof (or typeof) expression (a GCC extension).
Expr * getNoexceptExpr() const
bool SuppressScope
Suppresses printing of scope specifiers.
RecordDecl * getDecl() const
NestedNameSpecifier * getQualifier() const
Retrieve the qualification on this type.
TypeClass getTypeClass() const
unsigned getLine() const
Return the presumed line number of this location.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const
const TemplateSpecializationType * getInjectedTST() const
detail::InMemoryDirectory::const_iterator I
is ARM Neon polynomial vector
This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...
Represents an extended vector type where either the type or size is dependent.
This object can be modified without requiring retains or releases.
const TemplateTypeParmType * getReplacedParameter() const
Gets the template parameter that was substituted for.
EnumDecl * getDecl() const
Represents a K&R-style 'int foo()' function, which has no information available about its arguments...
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
ExtInfo getExtInfo() const
QualType getParamType(unsigned i) const
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
bool getNoCallerSavedRegs() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Represents an array type in C++ whose size is a value-dependent expression.
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
QualType getPointeeType() const
Defines the clang::LangOptions interface.
StringRef getName() const
Return the actual identifier string.
bool isObjCClassType() const
bool IncludeTagDefinition
When true, include the body of a tag definition.
bool isObjCGCWeak() const
true when Type is objc's weak.
Expr * getUnderlyingExpr() const
QualType getNamedType() const
Retrieve the type named by the qualified-id.
DeclContext * getDeclContext()
Represents the type decltype(expr) (C++11).
bool isObjCIdType() const
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
bool hasTrailingReturn() const
bool isFunctionOrMethod() const
Qualifiers Quals
The local qualifiers.
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.
An lvalue reference type, per C++11 [dcl.ref].
QualType getElementType() const
QualType getReplacementType() const
Gets the type that was substituted for the template parameter.
TypedefNameDecl * getTypedefNameForAnonDecl() const
bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const
const IdentifierInfo * getIdentifier() const
There is no lifetime qualification on this type.
is AltiVec 'vector Pixel'
Assigning into this object requires the old value to be released and the new value to be retained...
not a target-specific vector type
const char * getFilename() const
Return the presumed filename of this location.
Sugar for parentheses used when specifying types.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
QualType getElementType() const
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Represents typeof(type), a GCC extension.
Interfaces are the core concept in Objective-C for object oriented design.
TemplateName getTemplateName() const
Retrieve the name of the template that we are deducing.
bool SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration...
TagDecl - Represents the declaration of a struct/union/class/enum.
ASTContext & getASTContext() const LLVM_READONLY
VectorKind getVectorKind() const
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
No ref-qualifier was provided.
is AltiVec 'vector bool ...'
TypedefNameDecl * getDecl() const
bool SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
const T * castAs() const
Member-template castAs<specific type>.
ArrayRef< TemplateArgument > template_arguments() const
An rvalue ref-qualifier was provided (&&).
Assigning into this object requires a lifetime extension.
ParameterABI
Kinds of parameter ABI.
ObjCTypeParamDecl * getDecl() 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.
Expr * getSizeExpr() const
Base class for declarations which introduce a typedef-name.
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons...
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
Print this nested name specifier to the given output stream.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool getProducesResult() const
QualType getEquivalentType() const
bool isCallingConv() const
CallingConv getCC() const
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.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
const T * getAs() const
Member-template getAs<specific type>'.
unsigned getTypeQuals() const
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
bool isObjCQualifiedIdType() const
bool isFunctionType() const
ExtVectorType - Extended vector type.
ArrayRef< TemplateArgument > template_arguments() const
QualType getInnerType() const
llvm::StringRef getParameterABISpelling(ParameterABI kind)
NestedNameSpecifier * getQualifier() const
bool isMSTypeSpec() const
SourceManager & getSourceManager()
void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const
A template argument list.
const Type * getClass() const
Reading or writing from this object requires a barrier call.
An attributed type is a type to which a type attribute has been applied.
Represents a type parameter type in Objective C.
Represents a template specialization type whose template cannot be resolved, e.g. ...
bool hasQualifiers() const
Return true if the set contains any qualifiers.
Represents a C array with an unspecified size.
ArraySizeModifier getSizeModifier() const
ElaboratedTypeKeyword getKeyword() const
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
This class is used for builtin types like 'int'.
QualType getAdjustedType() const
QualType getPattern() const
Retrieve the pattern of this pack expansion, which is the type that will be repeatedly instantiated w...
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it's either not been deduced or was deduce...
QualType getPointeeTypeAsWritten() const
Represents a type template specialization; the template must be a class template, a type alias templa...
QualType getElementType() const
QualType getElementType() const
StringRef getKindName() const
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
StringRef getName(const PrintingPolicy &Policy) const
Represents a C array with a specified size that is not an integer-constant-expression.
No keyword precedes the qualified type name.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Represents the canonical version of C arrays with a specified constant size.
A class which abstracts out some details necessary for making a call.
This parameter (which must have pointer type) is a Swift indirect result parameter.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
unsigned getNumExceptions() const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.