aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-02-15 23:30:50 +0000
committerAnders Carlsson <andersca@mac.com>2008-02-15 23:30:50 +0000
commitb0dd26825e58a5f2982fd6d4ffa4c4ae6e24ff17 (patch)
tree8c7c0833830f160eae6bd89f68cafbec79a31ced
parentc6fbdcdb3b84d8a6bffa59b0848a8f53cf0bd11a (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.cpp47
-rw-r--r--include/clang/AST/Attr.h4
-rw-r--r--include/clang/AST/Decl.h14
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;