diff options
author | John McCall <rjmccall@apple.com> | 2010-10-22 21:05:15 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-10-22 21:05:15 +0000 |
commit | 1fb0caaa7bef765b85972274e3b434af2572c141 (patch) | |
tree | 39b9f78902f8581d6749d0d0dc99fc1f2ae1d8d5 /lib/AST/Type.cpp | |
parent | 07ed93f378a8868c9a7c04ca7ae685b85c55e5ea (diff) |
Substantially revise how clang computes the visibility of a declaration to
more closely parallel the computation of linkage. This gets us to a state
much closer to what gcc emits, modulo bugs, which will undoubtedly arise in
abundance.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117147 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 161 |
1 files changed, 93 insertions, 68 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 145250793f..33aac123c2 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1268,129 +1268,154 @@ void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getBaseType(), qual_begin(), getNumProtocols()); } +void Type::ensureCachedProperties() const { + if (!TypeBits.isCacheValid()) { + CachedProperties Result = getCachedProperties(); + TypeBits.CacheValidAndVisibility = Result.getVisibility() + 1U; + assert(TypeBits.isCacheValid() && + TypeBits.getVisibility() == Result.getVisibility()); + TypeBits.CachedLinkage = Result.getLinkage(); + TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType(); + } +} + /// \brief Determine the linkage of this type. Linkage Type::getLinkage() const { if (this != CanonicalType.getTypePtr()) return CanonicalType->getLinkage(); - - if (!TypeBits.LinkageKnown) { - std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl(); - TypeBits.CachedLinkage = Result.first; - TypeBits.CachedLocalOrUnnamed = Result.second; - TypeBits.LinkageKnown = true; - } - - return static_cast<clang::Linkage>(TypeBits.CachedLinkage); + + ensureCachedProperties(); + return TypeBits.getLinkage(); +} + +/// \brief Determine the linkage of this type. +Visibility Type::getVisibility() const { + if (this != CanonicalType.getTypePtr()) + return CanonicalType->getVisibility(); + + ensureCachedProperties(); + return TypeBits.getVisibility(); } bool Type::hasUnnamedOrLocalType() const { if (this != CanonicalType.getTypePtr()) return CanonicalType->hasUnnamedOrLocalType(); - - if (!TypeBits.LinkageKnown) { - std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl(); - TypeBits.CachedLinkage = Result.first; - TypeBits.CachedLocalOrUnnamed = Result.second; - TypeBits.LinkageKnown = true; - } - - return TypeBits.CachedLocalOrUnnamed; + + ensureCachedProperties(); + return TypeBits.hasLocalOrUnnamedType(); } -std::pair<Linkage, bool> Type::getLinkageUnnamedLocalImpl() const { - // C++ [basic.link]p8: - // Names not covered by these rules have no linkage. - return std::make_pair(NoLinkage, false); +std::pair<Linkage,Visibility> Type::getLinkageAndVisibility() const { + if (this != CanonicalType.getTypePtr()) + return CanonicalType->getLinkageAndVisibility(); + + ensureCachedProperties(); + return std::make_pair(TypeBits.getLinkage(), TypeBits.getVisibility()); +} + + +Type::CachedProperties Type::getCachedProperties(const Type *T) { + T = T->CanonicalType.getTypePtr(); + T->ensureCachedProperties(); + return CachedProperties(T->TypeBits.getLinkage(), + T->TypeBits.getVisibility(), + T->TypeBits.hasLocalOrUnnamedType()); } void Type::ClearLinkageCache() { if (this != CanonicalType.getTypePtr()) CanonicalType->ClearLinkageCache(); else - TypeBits.LinkageKnown = false; + TypeBits.CacheValidAndVisibility = 0; } -std::pair<Linkage, bool> BuiltinType::getLinkageUnnamedLocalImpl() const { +Type::CachedProperties Type::getCachedProperties() const { + // Treat dependent types as external. + if (isDependentType()) + return CachedProperties(ExternalLinkage, DefaultVisibility, false); + + // C++ [basic.link]p8: + // Names not covered by these rules have no linkage. + return CachedProperties(NoLinkage, DefaultVisibility, false); +} + +Type::CachedProperties BuiltinType::getCachedProperties() const { // C++ [basic.link]p8: // A type is said to have linkage if and only if: // - it is a fundamental type (3.9.1); or - return std::make_pair(ExternalLinkage, false); + return CachedProperties(ExternalLinkage, DefaultVisibility, false); } -std::pair<Linkage, bool> TagType::getLinkageUnnamedLocalImpl() const { +Type::CachedProperties TagType::getCachedProperties() const { // C++ [basic.link]p8: // - it is a class or enumeration type that is named (or has a name for // linkage purposes (7.1.3)) and the name has linkage; or // - it is a specialization of a class template (14); or - return std::make_pair(getDecl()->getLinkage(), - getDecl()->getDeclContext()->isFunctionOrMethod() || + + std::pair<Linkage,Visibility> LV = getDecl()->getLinkageAndVisibility(); + bool IsLocalOrUnnamed = + getDecl()->getDeclContext()->isFunctionOrMethod() || (!getDecl()->getIdentifier() && - !getDecl()->getTypedefForAnonDecl())); + !getDecl()->getTypedefForAnonDecl()); + return CachedProperties(LV.first, LV.second, IsLocalOrUnnamed); } // C++ [basic.link]p8: // - it is a compound type (3.9.2) other than a class or enumeration, // compounded exclusively from types that have linkage; or -std::pair<Linkage, bool> ComplexType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ElementType->getLinkage(), - ElementType->hasUnnamedOrLocalType()); +Type::CachedProperties ComplexType::getCachedProperties() const { + return Type::getCachedProperties(ElementType); } -std::pair<Linkage, bool> PointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(PointeeType->getLinkage(), - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties PointerType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } -std::pair<Linkage, bool> BlockPointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(PointeeType->getLinkage(), - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties BlockPointerType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } -std::pair<Linkage, bool> ReferenceType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(PointeeType->getLinkage(), - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties ReferenceType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } -std::pair<Linkage, bool> MemberPointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(minLinkage(Class->getLinkage(), - PointeeType->getLinkage()), - Class->hasUnnamedOrLocalType() || - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties MemberPointerType::getCachedProperties() const { + return merge(Type::getCachedProperties(Class), + Type::getCachedProperties(PointeeType)); } -std::pair<Linkage, bool> ArrayType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ElementType->getLinkage(), - ElementType->hasUnnamedOrLocalType()); +Type::CachedProperties ArrayType::getCachedProperties() const { + return Type::getCachedProperties(ElementType); } -std::pair<Linkage, bool> VectorType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ElementType->getLinkage(), - ElementType->hasUnnamedOrLocalType()); +Type::CachedProperties VectorType::getCachedProperties() const { + return Type::getCachedProperties(ElementType); } -std::pair<Linkage, bool> -FunctionNoProtoType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(getResultType()->getLinkage(), - getResultType()->hasUnnamedOrLocalType()); +Type::CachedProperties FunctionNoProtoType::getCachedProperties() const { + return Type::getCachedProperties(getResultType()); } -std::pair<Linkage, bool> FunctionProtoType::getLinkageUnnamedLocalImpl() const { - Linkage L = getResultType()->getLinkage(); - bool UnnamedOrLocal = getResultType()->hasUnnamedOrLocalType(); +Type::CachedProperties FunctionProtoType::getCachedProperties() const { + CachedProperties Cached = Type::getCachedProperties(getResultType()); for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end(); A != AEnd; ++A) { - L = minLinkage(L, (*A)->getLinkage()); - UnnamedOrLocal = UnnamedOrLocal || (*A)->hasUnnamedOrLocalType(); + Cached = merge(Cached, Type::getCachedProperties(*A)); } - - return std::make_pair(L, UnnamedOrLocal); + return Cached; +} + +Type::CachedProperties ObjCInterfaceType::getCachedProperties() const { + std::pair<Linkage,Visibility> LV = getDecl()->getLinkageAndVisibility(); + return CachedProperties(LV.first, LV.second, false); } -std::pair<Linkage, bool> ObjCObjectType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ExternalLinkage, false); +Type::CachedProperties ObjCObjectType::getCachedProperties() const { + if (const ObjCInterfaceType *T = getBaseType()->getAs<ObjCInterfaceType>()) + return Type::getCachedProperties(T); + return CachedProperties(ExternalLinkage, DefaultVisibility, false); } -std::pair<Linkage, bool> -ObjCObjectPointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ExternalLinkage, false); +Type::CachedProperties ObjCObjectPointerType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } |