diff options
author | Anders Carlsson <andersca@mac.com> | 2008-02-15 23:30:50 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-02-15 23:30:50 +0000 |
commit | b0dd26825e58a5f2982fd6d4ffa4c4ae6e24ff17 (patch) | |
tree | 8c7c0833830f160eae6bd89f68cafbec79a31ced | |
parent | c6fbdcdb3b84d8a6bffa59b0848a8f53cf0bd11a (diff) |
Store attributes in a global hash map instead.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47191 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | AST/Decl.cpp | 47 | ||||
-rw-r--r-- | include/clang/AST/Attr.h | 4 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 14 |
3 files changed, 50 insertions, 15 deletions
diff --git a/AST/Decl.cpp b/AST/Decl.cpp index 0ed028ca54..04d0d3cac2 100644 --- a/AST/Decl.cpp +++ b/AST/Decl.cpp @@ -15,6 +15,8 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/Attr.h" #include "clang/Basic/IdentifierTable.h" +#include "llvm/ADT/DenseMap.h" + using namespace clang; // temporary statistics gathering @@ -43,6 +45,12 @@ static unsigned nFileScopeAsmDecl = 0; static bool StatSwitch = false; +// This keeps track of all decl attributes. Since so few decls have attrs, we +// keep them in a hash map instead of wasting space in the Decl class. +typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy; + +static DeclAttrMapTy *DeclAttrs = 0; + const char *Decl::getDeclKindName() const { switch (DeclKind) { default: assert(0 && "Unknown decl kind!"); @@ -251,6 +259,39 @@ void Decl::addDeclKind(const Kind k) { // Out-of-line virtual method providing a home for Decl. Decl::~Decl() { + if (!DeclAttrs) + return; + + DeclAttrMapTy::iterator it = DeclAttrs->find(this); + if (it != DeclAttrs->end()) { + delete it->second; + DeclAttrs->erase(it); + if (DeclAttrs->empty()) { + delete DeclAttrs; + DeclAttrs = 0; + } + } +} + +void Decl::addAttr(Attr *newattr) +{ + if (!DeclAttrs) + DeclAttrs = new llvm::DenseMap<const Decl*, Attr*>; + + Attr *&attr = DeclAttrs->FindAndConstruct(this).second; + + newattr->setNext(attr); + attr = newattr; + + HasAttrs = true; +} + +const Attr *Decl::getAttrs() const +{ + if (!HasAttrs || !DeclAttrs) + return 0; + + return DeclAttrs->find(this)->second; } const char *NamedDecl::getName() const { @@ -259,12 +300,6 @@ const char *NamedDecl::getName() const { return ""; } -void ValueDecl::addAttr(Attr *attr) -{ - attr->setNext(Attrs); - Attrs = attr; -} - FunctionDecl::~FunctionDecl() { delete[] ParamInfo; } diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 82ba6b63fb..82da65a89b 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -30,11 +30,11 @@ private: protected: Attr(Kind AK) : Next(0), AttrKind(AK) {} +public: virtual ~Attr() { delete Next; } - -public: + Kind getKind() const { return AttrKind; } Attr *getNext() { return Next; } diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 0640222ea9..32127bb3a9 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -118,8 +118,11 @@ private: /// InvalidDecl - This indicates a semantic error occurred. unsigned int InvalidDecl : 1; + /// HasAttrs - This indicates whether the decl has attributes or not. + unsigned int HasAttrs : 1; protected: - Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0) { + Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0), + HasAttrs(false) { if (Decl::CollectingStats()) addDeclKind(DK); } @@ -132,6 +135,9 @@ public: Kind getKind() const { return DeclKind; } const char *getDeclKindName() const; + void addAttr(Attr *attr); + const Attr *getAttrs() const; + /// setInvalidDecl - Indicates the Decl had a semantic error. This /// allows for graceful error recovery. void setInvalidDecl() { InvalidDecl = 1; } @@ -253,9 +259,6 @@ protected: class ValueDecl : public ScopedDecl { QualType DeclType; - /// Attrs - Linked list of attributes that are attached to this - /// function. - Attr *Attrs; protected: ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl) @@ -265,9 +268,6 @@ public: void setType(QualType newType) { DeclType = newType; } QualType getCanonicalType() const { return DeclType.getCanonicalType(); } - void addAttr(Attr *attr); - const Attr *getAttrs() const { return Attrs; } - // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= ValueFirst && D->getKind() <= ValueLast; |