diff options
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/AST/Type.cpp | 177 | ||||
| -rw-r--r-- | clang/lib/AST/TypeLoc.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 159 |
4 files changed, 127 insertions, 221 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0a40ee5de9d..098abf20639 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3876,7 +3876,7 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const { return QualType(newType, 0); } -QualType ASTContext::getAttributedType(AttributedType::Kind attrKind, +QualType ASTContext::getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType) { llvm::FoldingSetNodeID id; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 7dc01b2f2f3..2e1aed26fd4 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -592,28 +592,6 @@ bool Type::isObjCClassOrClassKindOfType() const { return OPT->isObjCClassType() || OPT->isObjCQualifiedClassType(); } -/// Was this type written with the special inert-in-MRC __unsafe_unretained -/// qualifier? -/// -/// This approximates the answer to the following question: if this -/// translation unit were compiled in ARC, would this type be qualified -/// with __unsafe_unretained? -bool Type::isObjCInertUnsafeUnretainedType() const { - const Type *cur = this; - while (true) { - if (const auto attributed = dyn_cast<AttributedType>(cur)) { - if (attributed->getAttrKind() == - AttributedType::attr_objc_inert_unsafe_unretained) - return true; - } - - // Single-step desugar until we run out of sugar. - QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType(); - if (next.getTypePtr() == cur) return false; - cur = next.getTypePtr(); - } -} - ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D, QualType can, ArrayRef<ObjCProtocolDecl *> protocols) @@ -1641,6 +1619,16 @@ TagDecl *Type::getAsTagDecl() const { return nullptr; } +bool Type::hasAttr(attr::Kind AK) const { + const Type *Cur = this; + while (const auto *AT = Cur->getAs<AttributedType>()) { + if (AT->getAttrKind() == AK) + return true; + Cur = AT->getEquivalentType().getTypePtr(); + } + return false; +} + namespace { class GetContainedDeducedTypeVisitor : @@ -3168,105 +3156,58 @@ bool RecordType::hasConstFields() const { } bool AttributedType::isQualifier() const { + // FIXME: Generate this with TableGen. switch (getAttrKind()) { // These are type qualifiers in the traditional C sense: they annotate // something about a specific value/variable of a type. (They aren't // always part of the canonical type, though.) - case AttributedType::attr_address_space: - case AttributedType::attr_objc_gc: - case AttributedType::attr_objc_ownership: - case AttributedType::attr_objc_inert_unsafe_unretained: - case AttributedType::attr_nonnull: - case AttributedType::attr_nullable: - case AttributedType::attr_null_unspecified: - case AttributedType::attr_lifetimebound: + case attr::ObjCGC: + case attr::ObjCOwnership: + case attr::ObjCInertUnsafeUnretained: + case attr::TypeNonNull: + case attr::TypeNullable: + case attr::TypeNullUnspecified: + case attr::LifetimeBound: return true; - // These aren't qualifiers; they rewrite the modified type to be a - // semantically different type. - case AttributedType::attr_regparm: - case AttributedType::attr_vector_size: - case AttributedType::attr_neon_vector_type: - case AttributedType::attr_neon_polyvector_type: - case AttributedType::attr_pcs: - case AttributedType::attr_pcs_vfp: - case AttributedType::attr_noreturn: - case AttributedType::attr_cdecl: - case AttributedType::attr_fastcall: - case AttributedType::attr_stdcall: - case AttributedType::attr_thiscall: - case AttributedType::attr_regcall: - case AttributedType::attr_pascal: - case AttributedType::attr_swiftcall: - case AttributedType::attr_vectorcall: - case AttributedType::attr_inteloclbicc: - case AttributedType::attr_preserve_most: - case AttributedType::attr_preserve_all: - case AttributedType::attr_ms_abi: - case AttributedType::attr_sysv_abi: - case AttributedType::attr_ptr32: - case AttributedType::attr_ptr64: - case AttributedType::attr_sptr: - case AttributedType::attr_uptr: - case AttributedType::attr_objc_kindof: - case AttributedType::attr_ns_returns_retained: - case AttributedType::attr_nocf_check: + // All other type attributes aren't qualifiers; they rewrite the modified + // type to be a semantically different type. + default: return false; } - llvm_unreachable("bad attributed type kind"); } bool AttributedType::isMSTypeSpec() const { + // FIXME: Generate this with TableGen? switch (getAttrKind()) { - default: return false; - case attr_ptr32: - case attr_ptr64: - case attr_sptr: - case attr_uptr: + default: return false; + case attr::Ptr32: + case attr::Ptr64: + case attr::SPtr: + case attr::UPtr: return true; } llvm_unreachable("invalid attr kind"); } bool AttributedType::isCallingConv() const { + // FIXME: Generate this with TableGen. switch (getAttrKind()) { - case attr_ptr32: - case attr_ptr64: - case attr_sptr: - case attr_uptr: - case attr_address_space: - case attr_regparm: - case attr_vector_size: - case attr_neon_vector_type: - case attr_neon_polyvector_type: - case attr_objc_gc: - case attr_objc_ownership: - case attr_objc_inert_unsafe_unretained: - case attr_noreturn: - case attr_nonnull: - case attr_ns_returns_retained: - case attr_nullable: - case attr_null_unspecified: - case attr_objc_kindof: - case attr_nocf_check: - case attr_lifetimebound: - return false; - - case attr_pcs: - case attr_pcs_vfp: - case attr_cdecl: - case attr_fastcall: - case attr_stdcall: - case attr_thiscall: - case attr_regcall: - case attr_swiftcall: - case attr_vectorcall: - case attr_pascal: - case attr_ms_abi: - case attr_sysv_abi: - case attr_inteloclbicc: - case attr_preserve_most: - case attr_preserve_all: + default: return false; + case attr::Pcs: + case attr::CDecl: + case attr::FastCall: + case attr::StdCall: + case attr::ThisCall: + case attr::RegCall: + case attr::SwiftCall: + case attr::VectorCall: + case attr::Pascal: + case attr::MSABI: + case attr::SysVABI: + case attr::IntelOclBicc: + case attr::PreserveMost: + case attr::PreserveAll: return true; } llvm_unreachable("invalid attr kind"); @@ -3712,23 +3653,18 @@ LinkageInfo Type::getLinkageAndVisibility() const { return LinkageComputer{}.getTypeLinkageAndVisibility(this); } -Optional<NullabilityKind> Type::getNullability(const ASTContext &context) const { - QualType type(this, 0); - do { +Optional<NullabilityKind> +Type::getNullability(const ASTContext &Context) const { + QualType Type(this, 0); + while (const auto *AT = Type->getAs<AttributedType>()) { // Check whether this is an attributed type with nullability // information. - if (auto attributed = dyn_cast<AttributedType>(type.getTypePtr())) { - if (auto nullability = attributed->getImmediateNullability()) - return nullability; - } + if (auto Nullability = AT->getImmediateNullability()) + return Nullability; - // Desugar the type. If desugaring does nothing, we're done. - QualType desugared = type.getSingleStepDesugaredType(context); - if (desugared.getTypePtr() == type.getTypePtr()) - return None; - - type = desugared; - } while (true); + Type = AT->getEquivalentType(); + } + return None; } bool Type::canHaveNullability(bool ResultIfUnknown) const { @@ -3841,12 +3777,13 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { llvm_unreachable("bad type kind!"); } -llvm::Optional<NullabilityKind> AttributedType::getImmediateNullability() const { - if (getAttrKind() == AttributedType::attr_nonnull) +llvm::Optional<NullabilityKind> +AttributedType::getImmediateNullability() const { + if (getAttrKind() == attr::TypeNonNull) return NullabilityKind::NonNull; - if (getAttrKind() == AttributedType::attr_nullable) + if (getAttrKind() == attr::TypeNullable) return NullabilityKind::Nullable; - if (getAttrKind() == AttributedType::attr_null_unspecified) + if (getAttrKind() == attr::TypeNullUnspecified) return NullabilityKind::Unspecified; return None; } diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index e4fd6f106e3..b6dc679bbf7 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -404,11 +404,11 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { } SourceLocation TypeLoc::findNullabilityLoc() const { - if (auto attributedLoc = getAs<AttributedTypeLoc>()) { - if (attributedLoc.getAttrKind() == AttributedType::attr_nullable || - attributedLoc.getAttrKind() == AttributedType::attr_nonnull || - attributedLoc.getAttrKind() == AttributedType::attr_null_unspecified) - return attributedLoc.getAttrNameLoc(); + if (auto ATL = getAs<AttributedTypeLoc>()) { + const Attr *A = ATL.getAttr(); + if (A && (isa<TypeNullableAttr>(A) || isa<TypeNonNullAttr>(A) || + isa<TypeNullUnspecifiedAttr>(A))) + return A->getLocation(); } return {}; diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 1cb5ff46b55..d86849f64fa 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1354,12 +1354,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 +1369,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,9 +1393,11 @@ 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 this is a calling convention attribute, don't print the implicit CC from @@ -1406,107 +1408,74 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, // Some attributes are printed as qualifiers before the type, so we have // nothing left to do. - if (T->getAttrKind() == AttributedType::attr_objc_kindof || - T->isMSTypeSpec() || - T->getAttrKind() == AttributedType::attr_nonnull || - T->getAttrKind() == AttributedType::attr_nullable || - T->getAttrKind() == AttributedType::attr_null_unspecified) + 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; - if (T->getAttrKind() == AttributedType::attr_lifetimebound) { + if (T->getAttrKind() == attr::LifetimeBound) { OS << " [[clang::lifetimebound]]"; 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"); - - 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 << ')'; - 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 << ')'; +#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 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_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: + 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()) @@ -1517,12 +1486,12 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, break; } - case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; - case AttributedType::attr_preserve_most: + 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; } |

