]> granicus.if.org Git - clang/commitdiff
Store attributes in a global hash map instead.
authorAnders Carlsson <andersca@mac.com>
Fri, 15 Feb 2008 23:30:50 +0000 (23:30 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 15 Feb 2008 23:30:50 +0000 (23:30 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47191 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Decl.cpp
include/clang/AST/Attr.h
include/clang/AST/Decl.h

index 0ed028ca540101169e00a47cf46ca75c286f2255..04d0d3cac2b2536932b7dfd6e870e9e12acaaca7 100644 (file)
@@ -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;
 }
index 82ba6b63fbb6cf366b558ad357f551f3df249f79..82da65a89bdc83201b2a42386626437d2a90ee7d 100644 (file)
@@ -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; }
index 0640222ea9fcae12ea19ecaa698751a85b74b6fc..32127bb3a9ab62d872a2b0618e57e60682c205f2 100644 (file)
@@ -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;