[cfe-commits] r120562 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp
John McCall
rjmccall at apple.com
Wed Dec 1 00:12:46 PST 2010
Author: rjmccall
Date: Wed Dec 1 02:12:46 2010
New Revision: 120562
URL: http://llvm.org/viewvc/llvm-project?rev=120562&view=rev
Log:
Eliminate vtables from the Type hierarchy.
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/Type.cpp
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=120562&r1=120561&r2=120562&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Dec 1 02:12:46 2010
@@ -789,6 +789,7 @@
/// Bitfields required by the Type class.
class TypeBitfields {
friend class Type;
+ template <class T> friend class TypePropertyCache;
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
unsigned TC : 8;
@@ -954,36 +955,9 @@
TypeBits.FromAST = V;
}
- void ensureCachedProperties() const;
+ template <class T> friend class TypePropertyCache;
protected:
- /// \brief Compute the cached properties of this type.
- class CachedProperties {
- char linkage;
- char visibility;
- bool local;
-
- public:
- CachedProperties(Linkage linkage, Visibility visibility, bool local)
- : linkage(linkage), visibility(visibility), local(local) {}
-
- Linkage getLinkage() const { return (Linkage) linkage; }
- Visibility getVisibility() const { return (Visibility) visibility; }
- bool hasLocalOrUnnamedType() const { return local; }
-
- friend CachedProperties merge(CachedProperties L, CachedProperties R) {
- return CachedProperties(minLinkage(L.getLinkage(), R.getLinkage()),
- minVisibility(L.getVisibility(), R.getVisibility()),
- L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType());
- }
- };
-
- virtual CachedProperties getCachedProperties() const;
- static CachedProperties getCachedProperties(QualType T) {
- return getCachedProperties(T.getTypePtr());
- }
- static CachedProperties getCachedProperties(const Type *T);
-
// silence VC++ warning C4355: 'this' : used in base member initializer list
Type *this_() { return this; }
Type(TypeClass tc, QualType Canonical, bool Dependent, bool VariablyModified)
@@ -996,7 +970,6 @@
TypeBits.CachedLinkage = NoLinkage;
TypeBits.FromAST = false;
}
- virtual ~Type();
friend class ASTContext;
void setDependent(bool D = true) { TypeBits.Dependent = D; }
@@ -1336,9 +1309,6 @@
ObjCSel // This represents the ObjC 'SEL' type.
};
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
BuiltinType(Kind K)
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
@@ -1392,9 +1362,6 @@
}
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
QualType getElementType() const { return ElementType; }
@@ -1424,9 +1391,6 @@
}
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
QualType getPointeeType() const { return PointeeType; }
@@ -1458,9 +1422,6 @@
}
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
// Get the pointee type. Pointee is required to always be a function type.
@@ -1496,8 +1457,6 @@
ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
}
- virtual CachedProperties getCachedProperties() const;
-
public:
bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
@@ -1579,9 +1538,6 @@
}
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
QualType getPointeeType() const { return PointeeType; }
@@ -1649,8 +1605,6 @@
friend class ASTContext; // ASTContext creates these.
- virtual CachedProperties getCachedProperties() const;
-
public:
QualType getElementType() const { return ElementType; }
ArraySizeModifier getSizeModifier() const {
@@ -1954,8 +1908,6 @@
}
friend class ASTContext; // ASTContext creates these.
- virtual CachedProperties getCachedProperties() const;
-
public:
QualType getElementType() const { return ElementType; }
@@ -2057,8 +2009,6 @@
/// class of FunctionNoProtoType and FunctionProtoType.
///
class FunctionType : public Type {
- virtual void ANCHOR(); // Key function for FunctionType.
-
// The type returned by the function.
QualType ResultType;
@@ -2183,9 +2133,6 @@
Info) {}
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
// No additional state past what FunctionType provides.
@@ -2239,9 +2186,6 @@
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
unsigned getNumArgs() const { return NumArgs; }
QualType getArgType(unsigned i) const {
@@ -2482,8 +2426,6 @@
protected:
TagType(TypeClass TC, const TagDecl *D, QualType can);
- virtual CachedProperties getCachedProperties() const;
-
public:
TagDecl *getDecl() const;
@@ -2857,8 +2799,6 @@
}
public:
- virtual ~TypeWithKeyword(); // pin vtable to Type.cpp
-
ElaboratedTypeKeyword getKeyword() const {
return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
}
@@ -2983,8 +2923,6 @@
friend class ASTContext; // ASTContext creates these
public:
- virtual ~DependentNameType();
-
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -3051,8 +2989,6 @@
friend class ASTContext; // ASTContext creates these
public:
- virtual ~DependentTemplateSpecializationType();
-
NestedNameSpecifier *getQualifier() const { return NNS; }
const IdentifierInfo *getIdentifier() const { return Name; }
@@ -3144,9 +3080,6 @@
ObjCObjectTypeBits.NumProtocols = 0;
}
-protected:
- CachedProperties getCachedProperties() const; // key function
-
public:
/// getBaseType - Gets the base type of this object type. This is
/// always (possibly sugar for) one of:
@@ -3254,9 +3187,6 @@
Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
/// getDecl - Get the declaration of this interface.
ObjCInterfaceDecl *getDecl() const { return Decl; }
@@ -3306,9 +3236,6 @@
PointeeType(Pointee) {}
friend class ASTContext; // ASTContext creates these.
-protected:
- virtual CachedProperties getCachedProperties() const;
-
public:
/// getPointeeType - Gets the type pointed to by this ObjC pointer.
/// The result will always be an ObjCObjectType or sugar thereof.
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=120562&r1=120561&r2=120562&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Dec 1 02:12:46 2010
@@ -19,6 +19,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
@@ -35,8 +36,6 @@
return false;
}
-Type::~Type() { }
-
unsigned ConstantArrayType::getNumAddressingBits(ASTContext &Context,
QualType ElementType,
const llvm::APInt &NumElements) {
@@ -827,9 +826,6 @@
}
}
-TypeWithKeyword::~TypeWithKeyword() {
-}
-
ElaboratedTypeKeyword
TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
switch (TypeSpec) {
@@ -910,10 +906,6 @@
return "";
}
-ElaboratedType::~ElaboratedType() {}
-DependentNameType::~DependentNameType() {}
-DependentTemplateSpecializationType::~DependentTemplateSpecializationType() {}
-
DependentTemplateSpecializationType::DependentTemplateSpecializationType(
ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, const IdentifierInfo *Name,
@@ -1006,8 +998,6 @@
return 0;
}
-void FunctionType::ANCHOR() {} // Key function for FunctionType.
-
QualType QualType::getNonLValueExprType(ASTContext &Context) const {
if (const ReferenceType *RefType = getTypePtr()->getAs<ReferenceType>())
return RefType->getPointeeType();
@@ -1318,154 +1308,194 @@
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();
- }
+namespace {
+
+/// \brief The cached properties of a type.
+class CachedProperties {
+ char linkage;
+ char visibility;
+ bool local;
+
+public:
+ CachedProperties(Linkage linkage, Visibility visibility, bool local)
+ : linkage(linkage), visibility(visibility), local(local) {}
+
+ Linkage getLinkage() const { return (Linkage) linkage; }
+ Visibility getVisibility() const { return (Visibility) visibility; }
+ bool hasLocalOrUnnamedType() const { return local; }
+
+ friend CachedProperties merge(CachedProperties L, CachedProperties R) {
+ return CachedProperties(minLinkage(L.getLinkage(), R.getLinkage()),
+ minVisibility(L.getVisibility(), R.getVisibility()),
+ L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType());
+ }
+};
+}
+
+static CachedProperties computeCachedProperties(const Type *T);
+
+namespace clang {
+/// The type-property cache. This is templated so as to be
+/// instantiated at an internal type to prevent unnecessary symbol
+/// leakage.
+template <class Private> class TypePropertyCache {
+public:
+ static CachedProperties get(QualType T) {
+ return get(T.getTypePtr());
+ }
+
+ static CachedProperties get(const Type *T) {
+ ensure(T);
+ return CachedProperties(T->TypeBits.getLinkage(),
+ T->TypeBits.getVisibility(),
+ T->TypeBits.hasLocalOrUnnamedType());
+ }
+
+ static void ensure(const Type *T) {
+ // If the cache is valid, we're okay.
+ if (T->TypeBits.isCacheValid()) return;
+
+ // If this type is non-canonical, ask its canonical type for the
+ // relevant information.
+ if (QualType(T, 0) != T->CanonicalType) {
+ const Type *CT = T->CanonicalType.getTypePtr();
+ ensure(CT);
+ T->TypeBits.CacheValidAndVisibility =
+ CT->TypeBits.CacheValidAndVisibility;
+ T->TypeBits.CachedLinkage = CT->TypeBits.CachedLinkage;
+ T->TypeBits.CachedLocalOrUnnamed = CT->TypeBits.CachedLocalOrUnnamed;
+ return;
+ }
+
+ // Compute the cached properties and then set the cache.
+ CachedProperties Result = computeCachedProperties(T);
+ T->TypeBits.CacheValidAndVisibility = Result.getVisibility() + 1U;
+ assert(T->TypeBits.isCacheValid() &&
+ T->TypeBits.getVisibility() == Result.getVisibility());
+ T->TypeBits.CachedLinkage = Result.getLinkage();
+ T->TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType();
+ }
+};
+}
+
+// Instantiate the friend template at a private class. In a
+// reasonable implementation, these symbols will be internal.
+// It is terrible that this is the best way to accomplish this.
+namespace { class Private {}; }
+typedef TypePropertyCache<Private> Cache;
+
+static CachedProperties computeCachedProperties(const Type *T) {
+ switch (T->getTypeClass()) {
+#define TYPE(Class,Base)
+#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+ llvm_unreachable("didn't expect a non-canonical type here");
+
+#define TYPE(Class,Base)
+#define DEPENDENT_TYPE(Class,Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+ // Treat dependent types as external.
+ assert(T->isDependentType());
+ return CachedProperties(ExternalLinkage, DefaultVisibility, false);
+
+ case Type::Builtin:
+ // 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 CachedProperties(ExternalLinkage, DefaultVisibility, false);
+
+ case Type::Record:
+ case Type::Enum: {
+ const TagDecl *Tag = cast<TagType>(T)->getDecl();
+
+ // 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
+ NamedDecl::LinkageInfo LV = Tag->getLinkageAndVisibility();
+ bool IsLocalOrUnnamed =
+ Tag->getDeclContext()->isFunctionOrMethod() ||
+ (!Tag->getIdentifier() && !Tag->getTypedefForAnonDecl());
+ return CachedProperties(LV.linkage(), LV.visibility(), 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
+ case Type::Complex:
+ return Cache::get(cast<ComplexType>(T)->getElementType());
+ case Type::Pointer:
+ return Cache::get(cast<PointerType>(T)->getPointeeType());
+ case Type::BlockPointer:
+ return Cache::get(cast<BlockPointerType>(T)->getPointeeType());
+ case Type::LValueReference:
+ case Type::RValueReference:
+ return Cache::get(cast<ReferenceType>(T)->getPointeeType());
+ case Type::MemberPointer: {
+ const MemberPointerType *MPT = cast<MemberPointerType>(T);
+ return merge(Cache::get(MPT->getClass()),
+ Cache::get(MPT->getPointeeType()));
+ }
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ case Type::VariableArray:
+ return Cache::get(cast<ArrayType>(T)->getElementType());
+ case Type::Vector:
+ case Type::ExtVector:
+ return Cache::get(cast<VectorType>(T)->getElementType());
+ case Type::FunctionNoProto:
+ return Cache::get(cast<FunctionType>(T)->getResultType());
+ case Type::FunctionProto: {
+ const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
+ CachedProperties result = Cache::get(FPT->getResultType());
+ for (FunctionProtoType::arg_type_iterator ai = FPT->arg_type_begin(),
+ ae = FPT->arg_type_end(); ai != ae; ++ai)
+ result = merge(result, Cache::get(*ai));
+ return result;
+ }
+ case Type::ObjCInterface: {
+ NamedDecl::LinkageInfo LV =
+ cast<ObjCInterfaceType>(T)->getDecl()->getLinkageAndVisibility();
+ return CachedProperties(LV.linkage(), LV.visibility(), false);
+ }
+ case Type::ObjCObject:
+ return Cache::get(cast<ObjCObjectType>(T)->getBaseType());
+ case Type::ObjCObjectPointer:
+ return Cache::get(cast<ObjCObjectPointerType>(T)->getPointeeType());
+ }
+
+ llvm_unreachable("unhandled type class");
+
+ // C++ [basic.link]p8:
+ // Names not covered by these rules have no linkage.
+ return CachedProperties(NoLinkage, DefaultVisibility, false);
}
/// \brief Determine the linkage of this type.
Linkage Type::getLinkage() const {
- if (this != CanonicalType.getTypePtr())
- return CanonicalType->getLinkage();
-
- ensureCachedProperties();
+ Cache::ensure(this);
return TypeBits.getLinkage();
}
/// \brief Determine the linkage of this type.
Visibility Type::getVisibility() const {
- if (this != CanonicalType.getTypePtr())
- return CanonicalType->getVisibility();
-
- ensureCachedProperties();
+ Cache::ensure(this);
return TypeBits.getVisibility();
}
bool Type::hasUnnamedOrLocalType() const {
- if (this != CanonicalType.getTypePtr())
- return CanonicalType->hasUnnamedOrLocalType();
-
- ensureCachedProperties();
+ Cache::ensure(this);
return TypeBits.hasLocalOrUnnamedType();
}
std::pair<Linkage,Visibility> Type::getLinkageAndVisibility() const {
- if (this != CanonicalType.getTypePtr())
- return CanonicalType->getLinkageAndVisibility();
-
- ensureCachedProperties();
+ Cache::ensure(this);
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.CacheValidAndVisibility = 0;
-}
-
-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 CachedProperties(ExternalLinkage, DefaultVisibility, false);
-}
-
-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
-
- NamedDecl::LinkageInfo LV = getDecl()->getLinkageAndVisibility();
- bool IsLocalOrUnnamed =
- getDecl()->getDeclContext()->isFunctionOrMethod() ||
- (!getDecl()->getIdentifier() &&
- !getDecl()->getTypedefForAnonDecl());
- return CachedProperties(LV.linkage(), LV.visibility(), 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
-Type::CachedProperties ComplexType::getCachedProperties() const {
- return Type::getCachedProperties(ElementType);
-}
-
-Type::CachedProperties PointerType::getCachedProperties() const {
- return Type::getCachedProperties(PointeeType);
-}
-
-Type::CachedProperties BlockPointerType::getCachedProperties() const {
- return Type::getCachedProperties(PointeeType);
-}
-
-Type::CachedProperties ReferenceType::getCachedProperties() const {
- return Type::getCachedProperties(PointeeType);
-}
-
-Type::CachedProperties MemberPointerType::getCachedProperties() const {
- return merge(Type::getCachedProperties(Class),
- Type::getCachedProperties(PointeeType));
-}
-
-Type::CachedProperties ArrayType::getCachedProperties() const {
- return Type::getCachedProperties(ElementType);
-}
-
-Type::CachedProperties VectorType::getCachedProperties() const {
- return Type::getCachedProperties(ElementType);
-}
-
-Type::CachedProperties FunctionNoProtoType::getCachedProperties() const {
- return Type::getCachedProperties(getResultType());
-}
-
-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) {
- Cached = merge(Cached, Type::getCachedProperties(*A));
- }
- return Cached;
-}
-
-Type::CachedProperties ObjCInterfaceType::getCachedProperties() const {
- NamedDecl::LinkageInfo LV = getDecl()->getLinkageAndVisibility();
- return CachedProperties(LV.linkage(), LV.visibility(), false);
-}
-
-Type::CachedProperties ObjCObjectType::getCachedProperties() const {
- if (const ObjCInterfaceType *T = getBaseType()->getAs<ObjCInterfaceType>())
- return Type::getCachedProperties(T);
- return CachedProperties(ExternalLinkage, DefaultVisibility, false);
-}
-
-Type::CachedProperties ObjCObjectPointerType::getCachedProperties() const {
- return Type::getCachedProperties(PointeeType);
+ TypeBits.CacheValidAndVisibility = 0;
+ if (QualType(this, 0) != CanonicalType)
+ CanonicalType->TypeBits.CacheValidAndVisibility = 0;
}
More information about the cfe-commits
mailing list