diff options
Diffstat (limited to 'lib/AST/TypePrinter.cpp')
| -rw-r--r-- | lib/AST/TypePrinter.cpp | 245 |
1 files changed, 115 insertions, 130 deletions
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index e032c312aa12..32c75afb4381 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -117,9 +117,7 @@ namespace { void spaceBeforePlaceHolder(raw_ostream &OS); void printTypeSpec(NamedDecl *D, raw_ostream &OS); - void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS); void printBefore(QualType T, raw_ostream &OS); - void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS); void printAfter(QualType T, raw_ostream &OS); void AppendScope(DeclContext *DC, raw_ostream &OS); void printTag(TagDecl *T, raw_ostream &OS); @@ -129,6 +127,10 @@ namespace { void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \ void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS); #include "clang/AST/TypeNodes.def" + + private: + void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS); + void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS); }; } // namespace @@ -160,8 +162,15 @@ void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) { OS << ' '; } +static SplitQualType splitAccordingToPolicy(QualType QT, + const PrintingPolicy &Policy) { + if (Policy.PrintCanonicalTypes) + QT = QT.getCanonicalType(); + return QT.split(); +} + void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) { - SplitQualType split = t.split(); + SplitQualType split = splitAccordingToPolicy(t, Policy); print(split.Ty, split.Quals, OS, PlaceHolder); } @@ -260,7 +269,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T, } void TypePrinter::printBefore(QualType T, raw_ostream &OS) { - SplitQualType Split = T.split(); + SplitQualType Split = splitAccordingToPolicy(T, Policy); // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2 // at this level. @@ -320,7 +329,7 @@ void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) { } void TypePrinter::printAfter(QualType t, raw_ostream &OS) { - SplitQualType split = t.split(); + SplitQualType split = splitAccordingToPolicy(t, Policy); printAfter(split.Ty, split.Quals, OS); } @@ -801,10 +810,8 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, printFunctionAfter(Info, OS); - if (unsigned quals = T->getTypeQuals()) { - OS << ' '; - AppendTypeQualList(OS, quals, Policy.Restrict); - } + if (!T->getTypeQuals().empty()) + OS << " " << T->getTypeQuals().getAsString(); switch (T->getRefQualifier()) { case RQ_None: @@ -861,6 +868,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info, case CC_AAPCS_VFP: OS << " __attribute__((pcs(\"aapcs-vfp\")))"; break; + case CC_AArch64VectorCall: + OS << "__attribute__((aarch64_vector_pcs))"; + break; case CC_IntelOclBicc: OS << " __attribute__((intel_ocl_bicc))"; break; @@ -1154,9 +1164,13 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc( D->getLocation()); if (PLoc.isValid()) { - OS << " at " << PLoc.getFilename() - << ':' << PLoc.getLine() - << ':' << PLoc.getColumn(); + OS << " at "; + StringRef File = PLoc.getFilename(); + if (Policy.RemapFilePaths) + OS << Policy.remapPath(File); + else + OS << File; + OS << ':' << PLoc.getLine() << ':' << PLoc.getColumn(); } } @@ -1354,12 +1368,14 @@ void TypePrinter::printPackExpansionAfter(const PackExpansionType *T, void TypePrinter::printAttributedBefore(const AttributedType *T, raw_ostream &OS) { + // FIXME: Generate this with TableGen. + // Prefer the macro forms of the GC and ownership qualifiers. - if (T->getAttrKind() == AttributedType::attr_objc_gc || - T->getAttrKind() == AttributedType::attr_objc_ownership) + if (T->getAttrKind() == attr::ObjCGC || + T->getAttrKind() == attr::ObjCOwnership) return printBefore(T->getEquivalentType(), OS); - if (T->getAttrKind() == AttributedType::attr_objc_kindof) + if (T->getAttrKind() == attr::ObjCKindOf) OS << "__kindof "; printBefore(T->getModifiedType(), OS); @@ -1367,23 +1383,21 @@ void TypePrinter::printAttributedBefore(const AttributedType *T, if (T->isMSTypeSpec()) { switch (T->getAttrKind()) { default: return; - case AttributedType::attr_ptr32: OS << " __ptr32"; break; - case AttributedType::attr_ptr64: OS << " __ptr64"; break; - case AttributedType::attr_sptr: OS << " __sptr"; break; - case AttributedType::attr_uptr: OS << " __uptr"; break; + case attr::Ptr32: OS << " __ptr32"; break; + case attr::Ptr64: OS << " __ptr64"; break; + case attr::SPtr: OS << " __sptr"; break; + case attr::UPtr: OS << " __uptr"; break; } spaceBeforePlaceHolder(OS); } // Print nullability type specifiers. - if (T->getAttrKind() == AttributedType::attr_nonnull || - T->getAttrKind() == AttributedType::attr_nullable || - T->getAttrKind() == AttributedType::attr_null_unspecified) { - if (T->getAttrKind() == AttributedType::attr_nonnull) + if (T->getImmediateNullability()) { + if (T->getAttrKind() == attr::TypeNonNull) OS << " _Nonnull"; - else if (T->getAttrKind() == AttributedType::attr_nullable) + else if (T->getAttrKind() == attr::TypeNullable) OS << " _Nullable"; - else if (T->getAttrKind() == AttributedType::attr_null_unspecified) + else if (T->getAttrKind() == attr::TypeNullUnspecified) OS << " _Null_unspecified"; else llvm_unreachable("unhandled nullability"); @@ -1393,140 +1407,96 @@ void TypePrinter::printAttributedBefore(const AttributedType *T, void TypePrinter::printAttributedAfter(const AttributedType *T, raw_ostream &OS) { + // FIXME: Generate this with TableGen. + // Prefer the macro forms of the GC and ownership qualifiers. - if (T->getAttrKind() == AttributedType::attr_objc_gc || - T->getAttrKind() == AttributedType::attr_objc_ownership) + if (T->getAttrKind() == attr::ObjCGC || + T->getAttrKind() == attr::ObjCOwnership) return printAfter(T->getEquivalentType(), OS); - if (T->getAttrKind() == AttributedType::attr_objc_kindof) - return; - - // TODO: not all attributes are GCC-style attributes. - if (T->isMSTypeSpec()) - return; - - // Nothing to print after. - if (T->getAttrKind() == AttributedType::attr_nonnull || - T->getAttrKind() == AttributedType::attr_nullable || - T->getAttrKind() == AttributedType::attr_null_unspecified) - return printAfter(T->getModifiedType(), OS); - // If this is a calling convention attribute, don't print the implicit CC from // the modified type. SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv()); printAfter(T->getModifiedType(), OS); + // Some attributes are printed as qualifiers before the type, so we have + // nothing left to do. + if (T->getAttrKind() == attr::ObjCKindOf || + T->isMSTypeSpec() || T->getImmediateNullability()) + return; + // Don't print the inert __unsafe_unretained attribute at all. - if (T->getAttrKind() == AttributedType::attr_objc_inert_unsafe_unretained) + if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained) return; // Don't print ns_returns_retained unless it had an effect. - if (T->getAttrKind() == AttributedType::attr_ns_returns_retained && + if (T->getAttrKind() == attr::NSReturnsRetained && !T->getEquivalentType()->castAs<FunctionType>() ->getExtInfo().getProducesResult()) return; - // Print nullability type specifiers that occur after - if (T->getAttrKind() == AttributedType::attr_nonnull || - T->getAttrKind() == AttributedType::attr_nullable || - T->getAttrKind() == AttributedType::attr_null_unspecified) { - if (T->getAttrKind() == AttributedType::attr_nonnull) - OS << " _Nonnull"; - else if (T->getAttrKind() == AttributedType::attr_nullable) - OS << " _Nullable"; - else if (T->getAttrKind() == AttributedType::attr_null_unspecified) - OS << " _Null_unspecified"; - else - llvm_unreachable("unhandled nullability"); - + if (T->getAttrKind() == attr::LifetimeBound) { + OS << " [[clang::lifetimebound]]"; return; } - if (T->getAttrKind() == AttributedType::attr_lifetimebound) { - OS << " [[clang::lifetimebound]]"; + // The printing of the address_space attribute is handled by the qualifier + // since it is still stored in the qualifier. Return early to prevent printing + // this twice. + if (T->getAttrKind() == attr::AddressSpace) return; - } OS << " __attribute__(("; switch (T->getAttrKind()) { - case AttributedType::attr_lifetimebound: - case AttributedType::attr_nonnull: - case AttributedType::attr_nullable: - case AttributedType::attr_null_unspecified: - case AttributedType::attr_objc_gc: - case AttributedType::attr_objc_inert_unsafe_unretained: - case AttributedType::attr_objc_kindof: - case AttributedType::attr_objc_ownership: - case AttributedType::attr_ptr32: - case AttributedType::attr_ptr64: - case AttributedType::attr_sptr: - case AttributedType::attr_uptr: - llvm_unreachable("This attribute should have been handled already"); +#define TYPE_ATTR(NAME) +#define DECL_OR_TYPE_ATTR(NAME) +#define ATTR(NAME) case attr::NAME: +#include "clang/Basic/AttrList.inc" + llvm_unreachable("non-type attribute attached to type"); - case AttributedType::attr_address_space: - OS << "address_space("; - // FIXME: printing the raw LangAS value is wrong. This should probably - // use the same code as Qualifiers::print() - OS << (unsigned)T->getEquivalentType().getAddressSpace(); - OS << ')'; + case attr::OpenCLPrivateAddressSpace: + case attr::OpenCLGlobalAddressSpace: + case attr::OpenCLLocalAddressSpace: + case attr::OpenCLConstantAddressSpace: + case attr::OpenCLGenericAddressSpace: + // FIXME: Update printAttributedBefore to print these once we generate + // AttributedType nodes for them. break; - case AttributedType::attr_vector_size: - OS << "__vector_size__("; - if (const auto *vector = T->getEquivalentType()->getAs<VectorType>()) { - OS << vector->getNumElements(); - OS << " * sizeof("; - print(vector->getElementType(), OS, StringRef()); - OS << ')'; - } - OS << ')'; - break; - - case AttributedType::attr_neon_vector_type: - case AttributedType::attr_neon_polyvector_type: { - if (T->getAttrKind() == AttributedType::attr_neon_vector_type) - OS << "neon_vector_type("; - else - OS << "neon_polyvector_type("; - const auto *vector = T->getEquivalentType()->getAs<VectorType>(); - OS << vector->getNumElements(); - OS << ')'; - break; - } - - case AttributedType::attr_regparm: { - // FIXME: When Sema learns to form this AttributedType, avoid printing the - // attribute again in printFunctionProtoAfter. - OS << "regparm("; - QualType t = T->getEquivalentType(); - while (!t->isFunctionType()) - t = t->getPointeeType(); - OS << t->getAs<FunctionType>()->getRegParmType(); - OS << ')'; - break; - } + case attr::LifetimeBound: + case attr::TypeNonNull: + case attr::TypeNullable: + case attr::TypeNullUnspecified: + case attr::ObjCGC: + case attr::ObjCInertUnsafeUnretained: + case attr::ObjCKindOf: + case attr::ObjCOwnership: + case attr::Ptr32: + case attr::Ptr64: + case attr::SPtr: + case attr::UPtr: + case attr::AddressSpace: + llvm_unreachable("This attribute should have been handled already"); - case AttributedType::attr_ns_returns_retained: + case attr::NSReturnsRetained: OS << "ns_returns_retained"; break; // FIXME: When Sema learns to form this AttributedType, avoid printing the // attribute again in printFunctionProtoAfter. - case AttributedType::attr_noreturn: OS << "noreturn"; break; - case AttributedType::attr_nocf_check: OS << "nocf_check"; break; - case AttributedType::attr_cdecl: OS << "cdecl"; break; - case AttributedType::attr_fastcall: OS << "fastcall"; break; - case AttributedType::attr_stdcall: OS << "stdcall"; break; - case AttributedType::attr_thiscall: OS << "thiscall"; break; - case AttributedType::attr_swiftcall: OS << "swiftcall"; break; - case AttributedType::attr_vectorcall: OS << "vectorcall"; break; - case AttributedType::attr_pascal: OS << "pascal"; break; - case AttributedType::attr_ms_abi: OS << "ms_abi"; break; - case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break; - case AttributedType::attr_regcall: OS << "regcall"; break; - case AttributedType::attr_pcs: - case AttributedType::attr_pcs_vfp: { + case attr::AnyX86NoCfCheck: OS << "nocf_check"; break; + case attr::CDecl: OS << "cdecl"; break; + case attr::FastCall: OS << "fastcall"; break; + case attr::StdCall: OS << "stdcall"; break; + case attr::ThisCall: OS << "thiscall"; break; + case attr::SwiftCall: OS << "swiftcall"; break; + case attr::VectorCall: OS << "vectorcall"; break; + case attr::Pascal: OS << "pascal"; break; + case attr::MSABI: OS << "ms_abi"; break; + case attr::SysVABI: OS << "sysv_abi"; break; + case attr::RegCall: OS << "regcall"; break; + case attr::Pcs: { OS << "pcs("; QualType t = T->getEquivalentType(); while (!t->isFunctionType()) @@ -1536,15 +1506,18 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, OS << ')'; break; } - - case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; - case AttributedType::attr_preserve_most: + case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break; + case attr::IntelOclBicc: OS << "inteloclbicc"; break; + case attr::PreserveMost: OS << "preserve_most"; break; - case AttributedType::attr_preserve_all: + case attr::PreserveAll: OS << "preserve_all"; break; + case attr::NoDeref: + OS << "noderef"; + break; } OS << "))"; } @@ -1851,6 +1824,12 @@ std::string QualType::getAsString(const Type *ty, Qualifiers qs, return buffer; } +void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy, + const Twine &PlaceHolder, unsigned Indentation) const { + print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder, + Indentation); +} + void QualType::print(const Type *ty, Qualifiers qs, raw_ostream &OS, const PrintingPolicy &policy, const Twine &PlaceHolder, unsigned Indentation) { @@ -1860,6 +1839,12 @@ void QualType::print(const Type *ty, Qualifiers qs, TypePrinter(policy, Indentation).print(ty, qs, OS, PH); } +void QualType::getAsStringInternal(std::string &Str, + const PrintingPolicy &Policy) const { + return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str, + Policy); +} + void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, std::string &buffer, const PrintingPolicy &policy) { |
