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(
const 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);
107 #define ABSTRACT_TYPE(CLASS, PARENT)
108 #define TYPE(CLASS, PARENT) \
109 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
110 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
111 #include "clang/AST/TypeNodes.def"
116 bool HasRestrictKeyword) {
117 bool appendSpace =
false;
123 if (appendSpace) OS <<
' ';
128 if (appendSpace) OS <<
' ';
129 if (HasRestrictKeyword) {
137 void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
138 if (!HasEmptyPlaceHolder)
142 void TypePrinter::print(
QualType t, raw_ostream &OS, StringRef PlaceHolder) {
144 print(split.
Ty, split.
Quals, OS, PlaceHolder);
147 void TypePrinter::print(
const Type *T,
Qualifiers Quals, raw_ostream &OS,
148 StringRef PlaceHolder) {
156 printBefore(T, Quals, OS);
158 printAfter(T, Quals, OS);
161 bool TypePrinter::canPrefixQualifiers(
const Type *T,
162 bool &NeedARCStrongQualifier) {
168 bool CanPrefixQualifiers =
false;
169 NeedARCStrongQualifier =
false;
171 if (
const AutoType *AT = dyn_cast<AutoType>(T))
172 TC = AT->desugar()->getTypeClass();
174 = dyn_cast<SubstTemplateTypeParmType>(T))
175 TC = Subst->getReplacementType()->getTypeClass();
181 case Type::UnresolvedUsing:
183 case Type::TypeOfExpr:
186 case Type::UnaryTransform:
189 case Type::Elaborated:
190 case Type::TemplateTypeParm:
191 case Type::SubstTemplateTypeParmPack:
192 case Type::TemplateSpecialization:
193 case Type::InjectedClassName:
194 case Type::DependentName:
195 case Type::DependentTemplateSpecialization:
196 case Type::ObjCObject:
197 case Type::ObjCInterface:
200 CanPrefixQualifiers =
true;
203 case Type::ObjCObjectPointer:
208 case Type::ConstantArray:
209 case Type::IncompleteArray:
210 case Type::VariableArray:
211 case Type::DependentSizedArray:
212 NeedARCStrongQualifier =
true;
218 case Type::BlockPointer:
219 case Type::LValueReference:
220 case Type::RValueReference:
221 case Type::MemberPointer:
222 case Type::DependentSizedExtVector:
224 case Type::ExtVector:
225 case Type::FunctionProto:
226 case Type::FunctionNoProto:
228 case Type::Attributed:
229 case Type::PackExpansion:
230 case Type::SubstTemplateTypeParm:
231 CanPrefixQualifiers =
false;
235 return CanPrefixQualifiers;
238 void TypePrinter::printBefore(
QualType T, raw_ostream &OS) {
245 dyn_cast<SubstTemplateTypeParmType>(Split.
Ty))
248 printBefore(Split.
Ty, Quals, OS);
253 void TypePrinter::printBefore(
const Type *T,
Qualifiers Quals, raw_ostream &OS) {
261 bool CanPrefixQualifiers =
false;
262 bool NeedARCStrongQualifier =
false;
263 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
265 if (CanPrefixQualifiers && !Quals.
empty()) {
266 if (NeedARCStrongQualifier) {
267 IncludeStrongLifetimeRAII Strong(Policy);
268 Quals.
print(OS, Policy,
true);
270 Quals.
print(OS, Policy,
true);
274 bool hasAfterQuals =
false;
275 if (!CanPrefixQualifiers && !Quals.
empty()) {
278 HasEmptyPlaceHolder =
false;
282 #define ABSTRACT_TYPE(CLASS, PARENT)
283 #define TYPE(CLASS, PARENT) case Type::CLASS: \
284 print##CLASS##Before(cast<CLASS##Type>(T), OS); \
286 #include "clang/AST/TypeNodes.def"
290 if (NeedARCStrongQualifier) {
291 IncludeStrongLifetimeRAII Strong(Policy);
292 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
294 Quals.
print(OS, Policy, !PrevPHIsEmpty.get());
299 void TypePrinter::printAfter(
QualType t, raw_ostream &OS) {
301 printAfter(split.
Ty, split.
Quals, OS);
306 void TypePrinter::printAfter(
const Type *T,
Qualifiers Quals, raw_ostream &OS) {
308 #define ABSTRACT_TYPE(CLASS, PARENT)
309 #define TYPE(CLASS, PARENT) case Type::CLASS: \
310 print##CLASS##After(cast<CLASS##Type>(T), OS); \
312 #include "clang/AST/TypeNodes.def"
316 void TypePrinter::printBuiltinBefore(
const BuiltinType *T, raw_ostream &OS) {
318 spaceBeforePlaceHolder(OS);
320 void TypePrinter::printBuiltinAfter(
const BuiltinType *T, raw_ostream &OS) { }
322 void TypePrinter::printComplexBefore(
const ComplexType *T, raw_ostream &OS) {
326 void TypePrinter::printComplexAfter(
const ComplexType *T, raw_ostream &OS) {
330 void TypePrinter::printPointerBefore(
const PointerType *T, raw_ostream &OS) {
331 IncludeStrongLifetimeRAII Strong(Policy);
340 void TypePrinter::printPointerAfter(
const PointerType *T, raw_ostream &OS) {
341 IncludeStrongLifetimeRAII Strong(Policy);
364 IncludeStrongLifetimeRAII Strong(Policy);
375 IncludeStrongLifetimeRAII Strong(Policy);
386 IncludeStrongLifetimeRAII Strong(Policy);
397 IncludeStrongLifetimeRAII Strong(Policy);
408 IncludeStrongLifetimeRAII Strong(Policy);
417 InnerPolicy.IncludeTagDefinition =
false;
418 TypePrinter(InnerPolicy).print(
QualType(T->
getClass(), 0), OS, StringRef());
424 IncludeStrongLifetimeRAII Strong(Policy);
435 IncludeStrongLifetimeRAII Strong(Policy);
451 OS << T->
getSize().getZExtValue() <<
']';
457 IncludeStrongLifetimeRAII Strong(Policy);
469 IncludeStrongLifetimeRAII Strong(Policy);
487 T->
getSizeExpr()->printPretty(OS,
nullptr, Policy);
493 void TypePrinter::printAdjustedBefore(
const AdjustedType *T, raw_ostream &OS) {
498 void TypePrinter::printAdjustedAfter(
const AdjustedType *T, raw_ostream &OS) {
502 void TypePrinter::printDecayedBefore(
const DecayedType *T, raw_ostream &OS) {
504 printAdjustedBefore(T, OS);
506 void TypePrinter::printDecayedAfter(
const DecayedType *T, raw_ostream &OS) {
507 printAdjustedAfter(T, OS);
510 void TypePrinter::printDependentSizedArrayBefore(
513 IncludeStrongLifetimeRAII Strong(Policy);
517 void TypePrinter::printDependentSizedArrayAfter(
522 T->
getSizeExpr()->printPretty(OS,
nullptr, Policy);
527 void TypePrinter::printDependentSizedExtVectorBefore(
532 void TypePrinter::printDependentSizedExtVectorAfter(
535 OS <<
" __attribute__((ext_vector_type(";
537 T->
getSizeExpr()->printPretty(OS,
nullptr, Policy);
542 void TypePrinter::printVectorBefore(
const VectorType *T, raw_ostream &OS) {
545 OS <<
"__vector __pixel ";
548 OS <<
"__vector __bool ";
556 OS <<
"__attribute__((neon_vector_type("
561 OS <<
"__attribute__((neon_polyvector_type(" <<
568 OS <<
"__attribute__((__vector_size__("
578 void TypePrinter::printVectorAfter(
const VectorType *T, raw_ostream &OS) {
582 void TypePrinter::printExtVectorBefore(
const ExtVectorType *T,
586 void TypePrinter::printExtVectorAfter(
const ExtVectorType *T, raw_ostream &OS) {
588 OS <<
" __attribute__((ext_vector_type(";
625 if (!HasEmptyPlaceHolder)
631 if (!PrevPHIsEmpty.get())
639 llvm_unreachable(
"asking for spelling of ordinary parameter ABI");
641 return "swift_context";
643 return "swift_error_result";
645 return "swift_indirect_result";
647 llvm_unreachable(
"bad parameter ABI kind");
653 if (!HasEmptyPlaceHolder)
659 ParamPolicyRAII ParamPolicy(Policy);
660 for (
unsigned i = 0, e = T->
getNumParams(); i != e; ++i) {
664 if (EPI.isConsumed()) OS <<
"__attribute__((ns_consumed)) ";
677 }
else if (T->
getNumParams() == 0 && Policy.UseVoidForZeroParams) {
686 if (!InsideCCAttribute) {
687 switch (Info.
getCC()) {
698 OS <<
" __attribute__((stdcall))";
701 OS <<
" __attribute__((fastcall))";
704 OS <<
" __attribute__((thiscall))";
707 OS <<
" __attribute__((vectorcall))";
710 OS <<
" __attribute__((pascal))";
713 OS <<
" __attribute__((pcs(\"aapcs\")))";
716 OS <<
" __attribute__((pcs(\"aapcs-vfp\")))";
719 OS <<
" __attribute__((intel_ocl_bicc))";
722 OS <<
" __attribute__((ms_abi))";
725 OS <<
" __attribute__((sysv_abi))";
732 OS <<
" __attribute__((swiftcall))";
735 OS <<
" __attribute__((preserve_most))";
738 OS <<
" __attribute__((preserve_all))";
744 OS <<
" __attribute__((noreturn))";
746 OS <<
" __attribute__((regparm ("
780 if (!PrevPHIsEmpty.get())
786 if (!HasEmptyPlaceHolder)
792 OS <<
" __attribute__((noreturn))";
796 void TypePrinter::printTypeSpec(
const NamedDecl *D, raw_ostream &OS) {
799 spaceBeforePlaceHolder(OS);
804 printTypeSpec(T->
getDecl(), OS);
809 void TypePrinter::printTypedefBefore(
const TypedefType *T, raw_ostream &OS) {
810 printTypeSpec(T->
getDecl(), OS);
812 void TypePrinter::printTypedefAfter(
const TypedefType *T, raw_ostream &OS) { }
819 spaceBeforePlaceHolder(OS);
824 void TypePrinter::printTypeOfBefore(
const TypeOfType *T, raw_ostream &OS) {
828 spaceBeforePlaceHolder(OS);
830 void TypePrinter::printTypeOfAfter(
const TypeOfType *T, raw_ostream &OS) { }
832 void TypePrinter::printDecltypeBefore(
const DecltypeType *T, raw_ostream &OS) {
837 spaceBeforePlaceHolder(OS);
839 void TypePrinter::printDecltypeAfter(
const DecltypeType *T, raw_ostream &OS) { }
843 IncludeStrongLifetimeRAII Strong(Policy);
847 OS <<
"__underlying_type(";
850 spaceBeforePlaceHolder(OS);
858 IncludeStrongLifetimeRAII Strong(Policy);
868 void TypePrinter::printAutoBefore(
const AutoType *T, raw_ostream &OS) {
878 spaceBeforePlaceHolder(OS);
881 void TypePrinter::printAutoAfter(
const AutoType *T, raw_ostream &OS) {
887 void TypePrinter::printAtomicBefore(
const AtomicType *T, raw_ostream &OS) {
888 IncludeStrongLifetimeRAII Strong(Policy);
893 spaceBeforePlaceHolder(OS);
895 void TypePrinter::printAtomicAfter(
const AtomicType *T, raw_ostream &OS) { }
897 void TypePrinter::printPipeBefore(
const PipeType *T, raw_ostream &OS) {
898 IncludeStrongLifetimeRAII Strong(Policy);
902 spaceBeforePlaceHolder(OS);
905 void TypePrinter::printPipeAfter(
const PipeType *T, raw_ostream &OS) {
908 void TypePrinter::AppendScope(
DeclContext *DC, raw_ostream &OS) {
914 if (Policy.SuppressUnwrittenScope &&
915 (NS->isAnonymousNamespace() || NS->isInline()))
917 if (NS->getIdentifier())
918 OS << NS->getName() <<
"::";
920 OS <<
"(anonymous namespace)::";
922 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
923 IncludeStrongLifetimeRAII Strong(Policy);
924 OS << Spec->getIdentifier()->getName();
927 OS, TemplateArgs.
asArray(), Policy);
929 }
else if (
TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
931 OS << Typedef->getIdentifier()->getName() <<
"::";
932 else if (Tag->getIdentifier())
933 OS << Tag->getIdentifier()->getName() <<
"::";
939 void TypePrinter::printTag(
TagDecl *D, raw_ostream &OS) {
940 if (Policy.IncludeTagDefinition) {
943 D->print(OS, SubPolicy, Indentation);
944 spaceBeforePlaceHolder(OS);
948 bool HasKindDecoration =
false;
953 HasKindDecoration =
true;
961 if (!Policy.SuppressScope)
962 AppendScope(D->getDeclContext(), OS);
967 assert(Typedef->getIdentifier() &&
"Typedef without identifier?");
968 OS << Typedef->getIdentifier()->getName();
972 OS << (Policy.MSVCFormatting ?
'`' :
'(');
974 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
976 HasKindDecoration =
true;
981 if (Policy.AnonymousTagLocations) {
985 if (!HasKindDecoration)
988 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
997 OS << (Policy.MSVCFormatting ?
'\'' :
')');
1003 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1004 ArrayRef<TemplateArgument> Args;
1007 cast<TemplateSpecializationType>(TAW->getType());
1008 Args = TST->template_arguments();
1011 Args = TemplateArgs.
asArray();
1013 IncludeStrongLifetimeRAII Strong(Policy);
1017 spaceBeforePlaceHolder(OS);
1020 void TypePrinter::printRecordBefore(
const RecordType *T, raw_ostream &OS) {
1023 void TypePrinter::printRecordAfter(
const RecordType *T, raw_ostream &OS) { }
1025 void TypePrinter::printEnumBefore(
const EnumType *T, raw_ostream &OS) {
1028 void TypePrinter::printEnumAfter(
const EnumType *T, raw_ostream &OS) { }
1033 OS << Id->getName();
1036 spaceBeforePlaceHolder(OS);
1039 raw_ostream &OS) { }
1041 void TypePrinter::printSubstTemplateTypeParmBefore(
1044 IncludeStrongLifetimeRAII Strong(Policy);
1047 void TypePrinter::printSubstTemplateTypeParmAfter(
1050 IncludeStrongLifetimeRAII Strong(Policy);
1054 void TypePrinter::printSubstTemplateTypeParmPackBefore(
1057 IncludeStrongLifetimeRAII Strong(Policy);
1060 void TypePrinter::printSubstTemplateTypeParmPackAfter(
1063 IncludeStrongLifetimeRAII Strong(Policy);
1067 void TypePrinter::printTemplateSpecializationBefore(
1070 IncludeStrongLifetimeRAII Strong(Policy);
1071 T->getTemplateName().print(OS, Policy);
1074 OS, T->template_arguments(), Policy);
1075 spaceBeforePlaceHolder(OS);
1077 void TypePrinter::printTemplateSpecializationAfter(
1079 raw_ostream &OS) { }
1086 raw_ostream &OS) { }
1091 if (!Policy.IncludeTagDefinition)
1098 Qualifier->
print(OS, Policy);
1101 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1106 ElaboratedTypePolicyRAII PolicyRAII(Policy);
1110 void TypePrinter::printParenBefore(
const ParenType *T, raw_ostream &OS) {
1111 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1117 void TypePrinter::printParenAfter(
const ParenType *T, raw_ostream &OS) {
1118 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->
getInnerType())) {
1134 spaceBeforePlaceHolder(OS);
1137 raw_ostream &OS) { }
1139 void TypePrinter::printDependentTemplateSpecializationBefore(
1141 IncludeStrongLifetimeRAII Strong(Policy);
1147 if (T->getQualifier())
1148 T->getQualifier()->print(OS, Policy);
1149 OS << T->getIdentifier()->getName();
1151 T->template_arguments(),
1153 spaceBeforePlaceHolder(OS);
1155 void TypePrinter::printDependentTemplateSpecializationAfter(
1188 spaceBeforePlaceHolder(OS);
1200 OS <<
" _Null_unspecified";
1202 llvm_unreachable(
"unhandled nullability");
1203 spaceBeforePlaceHolder(OS);
1246 OS <<
" _Null_unspecified";
1248 llvm_unreachable(
"unhandled nullability");
1253 OS <<
" __attribute__((";
1255 default: llvm_unreachable(
"This attribute should have been handled already");
1257 OS <<
"address_space(";
1263 OS <<
"__vector_size__(";
1265 OS << vector->getNumElements();
1267 print(vector->getElementType(), OS, StringRef());
1277 OS <<
"neon_vector_type(";
1279 OS <<
"neon_polyvector_type(";
1304 if (next == tmp)
break;
1317 OS <<
"objc_ownership(";
1348 "\"aapcs\"" :
"\"aapcs-vfp\"");
1354 OS <<
"preserve_most";
1357 OS <<
"preserve_all";
1366 spaceBeforePlaceHolder(OS);
1369 raw_ostream &OS) { }
1383 bool isFirst =
true;
1391 print(typeArg, OS, StringRef());
1396 if (!T->qual_empty()) {
1397 bool isFirst = true;
1399 for (const auto *I : T->quals()) {
1409 spaceBeforePlaceHolder(OS);
1411 void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
1413 if (T->qual_empty() && T->isUnspecializedAsWritten() &&
1414 !T->isKindOfTypeAsWritten())
1415 return printAfter(T->getBaseType(), OS);
1418 void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
1420 printBefore(T->getPointeeType(), OS);
1422 // If we need to print the pointer, print it now.
1423 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
1424 !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
1425 if (HasEmptyPlaceHolder)
1430 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
1431 raw_ostream &OS) { }
1433 void TemplateSpecializationType::
1434 PrintTemplateArgumentList(raw_ostream &OS,
1435 const TemplateArgumentListInfo &Args,
1436 const PrintingPolicy &Policy) {
1437 return PrintTemplateArgumentList(OS,
1442 void TemplateSpecializationType::PrintTemplateArgumentList(
1443 raw_ostream &OS, ArrayRef<TemplateArgument> Args,
1444 const PrintingPolicy &Policy, bool SkipBrackets) {
1445 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
1449 bool needSpace = false;
1450 bool FirstArg = true;
1451 for (const TemplateArgument &Arg : Args) {
1452 // Print the argument into a string.
1453 SmallString<128> Buf;
1454 llvm::raw_svector_ostream ArgOS(Buf);
1455 if (Arg.getKind() == TemplateArgument::Pack) {
1456 if (Arg.pack_size() && !FirstArg)
1458 PrintTemplateArgumentList(ArgOS,
1459 Arg.getPackAsArray(),
1464 Arg.print(Policy, ArgOS);
1466 StringRef ArgString = ArgOS.str();
1468 // If this is the first argument and its string representation
1469 // begins with the global scope specifier ('::foo
'), add a space
1470 // to avoid printing the diagraph '<:
'.
1471 if (FirstArg && !ArgString.empty() && ArgString[0] == ':
')
1476 needSpace = (!ArgString.empty() && ArgString.back() == '>
');
1480 // If the last character of our string is '>
', add another space to
1481 // keep the two '>
''s separate tokens. We don
't *have* to do this in
1482 // C++0x, but it's still good hygiene.
1490 // Sadly, repeat all that with TemplateArgLoc.
1491 void TemplateSpecializationType::
1492 PrintTemplateArgumentList(raw_ostream &OS,
1493 ArrayRef<TemplateArgumentLoc> Args,
1494 const PrintingPolicy &Policy) {
1496 const char *Comma = Policy.MSVCFormatting ? "," : ", ";
1498 bool needSpace = false;
1499 bool FirstArg = true;
1500 for (const TemplateArgumentLoc &Arg : Args) {
1504 // Print the argument into a string.
1505 SmallString<128> Buf;
1506 llvm::raw_svector_ostream ArgOS(Buf);
1507 if (Arg.getArgument().getKind() == TemplateArgument::Pack) {
1508 PrintTemplateArgumentList(ArgOS,
1509 Arg.getArgument().getPackAsArray(),
1512 Arg.getArgument().print(Policy, ArgOS);
1514 StringRef ArgString = ArgOS.str();
1516 // If this is the first argument and its string representation
1517 // begins with the global scope specifier ('::foo
'), add a space
1518 // to avoid printing the diagraph '<:
'.
1519 if (FirstArg && !ArgString.empty() && ArgString[0] == ':
')
1524 needSpace = (!ArgString.empty() && ArgString.back() == '>
');
1528 // If the last character of our string is '>
', add another space to
1529 // keep the two '>
''s separate tokens. We don
't *have* to do this in
1530 // C++0x, but it's still good hygiene.
1537 std::string Qualifiers::getAsString() const {
1539 return getAsString(PrintingPolicy(LO));
1542 // Appends qualifiers to the given string, separated by spaces. Will
1543 // prefix a space if the string is non-empty. Will not append a final
1545 std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
1546 SmallString<64> Buf;
1547 llvm::raw_svector_ostream StrOS(Buf);
1548 print(StrOS, Policy);
1552 bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
1553 if (getCVRQualifiers())
1556 if (getAddressSpace())
1559 if (getObjCGCAttr())
1562 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
1563 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
1569 // Appends qualifiers to the given string, separated by spaces. Will
1570 // prefix a space if the string is non-empty. Will not append a final
1572 void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
1573 bool appendSpaceIfNonEmpty) const {
1574 bool addSpace = false;
1576 unsigned quals = getCVRQualifiers();
1578 AppendTypeQualList(OS, quals, Policy.Restrict);
1581 if (hasUnaligned()) {
1584 OS << "__unaligned";
1587 if (unsigned addrspace = getAddressSpace()) {
1591 switch (addrspace) {
1592 case LangAS::opencl_global:
1595 case LangAS::opencl_local:
1598 case LangAS::opencl_constant:
1601 case LangAS::opencl_generic:
1605 OS << "__attribute__((address_space(";
1610 if (Qualifiers::GC gc = getObjCGCAttr()) {
1614 if (gc == Qualifiers::Weak)
1619 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
1620 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
1627 case Qualifiers::OCL_None: llvm_unreachable("none but true");
1628 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
1629 case Qualifiers::OCL_Strong:
1630 if (!Policy.SuppressStrongLifetime)
1634 case Qualifiers::OCL_Weak: OS << "__weak"; break;
1635 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
1639 if (appendSpaceIfNonEmpty && addSpace)
1643 std::string QualType::getAsString(const PrintingPolicy &Policy) const {
1645 getAsStringInternal(S, Policy);
1649 std::string QualType::getAsString(const Type *ty, Qualifiers qs) {
1651 LangOptions options;
1652 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
1656 void QualType::print(const Type *ty, Qualifiers qs,
1657 raw_ostream &OS, const PrintingPolicy &policy,
1658 const Twine &PlaceHolder, unsigned Indentation) {
1659 SmallString<128> PHBuf;
1660 StringRef PH = PlaceHolder.toStringRef(PHBuf);
1662 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
1665 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
1666 std::string &buffer,
1667 const PrintingPolicy &policy) {
1668 SmallString<256> Buf;
1669 llvm::raw_svector_ostream StrOS(Buf);
1670 TypePrinter(policy).print(ty, qs, StrOS, buffer);
1671 std::string str = StrOS.str();
unsigned getNumElements() const
unsigned getAddressSpace() const
Return the address space of this type.
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.
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.
bool isKindOfTypeAsWritten() const
Whether this is a "__kindof" type as written.
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
DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, ArrayRef< TemplateArgument > Args, QualType Canon)
NamespaceDecl - Represent a C++ namespace.
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
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.
Represents a class type in Objective C.
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.
QualType getBaseType() const
Gets the base type of this object type.
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.
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.
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
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
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.
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.
VectorKind getVectorKind() const
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
No ref-qualifier was provided.
is AltiVec 'vector bool ...'
bool isSpecializedAsWritten() const
Determine whether this object type was written with type arguments.
TypedefNameDecl * getDecl() const
bool SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
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...
An rvalue ref-qualifier was provided (&&).
Assigning into this object requires a lifetime extension.
ParameterABI
Kinds of parameter ABI.
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.
ArrayRef< QualType > getTypeArgsAsWritten() const
Retrieve the type arguments of this object type as they were written.
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...
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.
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.
QualType getInnerType() const
llvm::StringRef getParameterABISpelling(ParameterABI kind)
bool isMSTypeSpec() const
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.
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 getPointeeTypeAsWritten() const
QualType getElementType() const
QualType getElementType() const
StringRef getKindName() 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 isUnspecializedAsWritten() const
Determine whether this object type is "unspecialized" as written, meaning that it has no type argumen...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
TemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon, QualType Aliased)
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
QualType getDeducedType() const
Get the type deduced for this auto type, or null if it's either not been deduced or was deduced to a ...