Switch attributes to be allocated from the declcontext bump pointer just like
decls.  This reduces the number of calls to malloc on cocoa.h with pth and
-disable-free from 15958 to 12444 times (down ~3500).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66023 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 89fe0f0..0d6ed01 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -69,16 +69,23 @@
   bool Inherited : 1;
 
 protected:
+  void* operator new(size_t bytes) throw() {
+    assert(0 && "Attrs cannot be allocated with regular 'new'.");
+    return 0;
+  }
+  void operator delete(void* data) throw() {
+    assert(0 && "Attrs cannot be released with regular 'delete'.");
+  }
+  
+protected:
   Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
   virtual ~Attr() {
-    delete Next;
+    assert(Next == 0 && "Destroy didn't work");
   }
 public:
   
-  void Destroy(ASTContext &C) {
-    delete this;
-  }
-
+  void Destroy(ASTContext &C);
+  
   /// \brief Whether this attribute should be merged to new
   /// declarations.
   virtual bool isMerged() const { return true; }
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1ebfbf7..eaf69f0 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -22,10 +22,21 @@
 
 using namespace clang;
 
+void Attr::Destroy(ASTContext &C) {
+  if (Next) {
+    Next->Destroy(C);
+    Next = 0;
+  }
+  this->~Attr();
+  C.Deallocate((void*)this);
+}
+
+
 //===----------------------------------------------------------------------===//
 // Decl Allocation/Deallocation Method Implementations
 //===----------------------------------------------------------------------===//
  
+
 TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
   return new (C) TranslationUnitDecl();
 }
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 609c872..10eec7a 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -231,18 +231,16 @@
   void *Ptr = Name.getFETokenInfo<void>();
   if (!Ptr) return end();
 
-  if (isDeclPtr(Ptr)) {
-    NamedDecl *D = static_cast<NamedDecl*>(Ptr);
-    return iterator(D);
-  }
+  if (isDeclPtr(Ptr))
+    return iterator(static_cast<NamedDecl*>(Ptr));
 
   IdDeclInfo *IDI = toIdDeclInfo(Ptr);
 
   IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
   if (I != IDI->decls_begin())
     return iterator(I-1);
-  else // No decls found.
-    return end();
+  // No decls found.
+  return end();
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 6a6628f..3880792 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1575,8 +1575,8 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);  
-    NewVD->addAttr(new AsmLabelAttr(std::string(SE->getStrData(),
-                                                SE->getByteLength())));
+    NewVD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+                                                        SE->getByteLength())));
   }
 
   // Emit an error if an address space was applied to decl with local storage.
@@ -1804,8 +1804,8 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);  
-    NewFD->addAttr(new AsmLabelAttr(std::string(SE->getStrData(),
-                                                SE->getByteLength())));
+    NewFD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+                                                        SE->getByteLength())));
   }
 
   // Copy the parameter declarations from the declarator D to
@@ -2016,7 +2016,7 @@
     if (PrevDecl)
       Diag(PrevDecl->getLocation(), 
            diag::note_attribute_overloadable_prev_overload);
-    NewFD->addAttr(new OverloadableAttr);
+    NewFD->addAttr(::new (Context) OverloadableAttr());
   }
 
   if (getLangOptions().CPlusPlus) {
@@ -2713,7 +2713,8 @@
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
       if (!FD->getAttr<FormatAttr>())
-        FD->addAttr(new FormatAttr("printf", FormatIdx + 1, FormatIdx + 2));
+        FD->addAttr(::new (Context) FormatAttr("printf", FormatIdx + 1,
+                                               FormatIdx + 2));
     }
 
     // Mark const if we don't care about errno and that is the only
@@ -2722,7 +2723,7 @@
     if (!getLangOptions().MathErrno &&
         Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
       if (!FD->getAttr<ConstAttr>())
-        FD->addAttr(new ConstAttr());
+        FD->addAttr(::new (Context) ConstAttr());
     }
   }
 
@@ -2751,13 +2752,13 @@
       // FIXME: We known better than our headers.
       const_cast<FormatAttr *>(Format)->setType("printf");
     } else 
-      FD->addAttr(new FormatAttr("printf", 1, 2));
+      FD->addAttr(::new (Context) FormatAttr("printf", 1, 2));
     break;
 
   case id_asprintf:
   case id_vasprintf:
     if (!FD->getAttr<FormatAttr>())
-      FD->addAttr(new FormatAttr("printf", 2, 3));
+      FD->addAttr(::new (Context) FormatAttr("printf", 2, 3));
     break;
 
   default:
@@ -3036,7 +3037,7 @@
     // the #pragma tokens are effectively skipped over during the
     // parsing of the struct).
     if (unsigned Alignment = getPragmaPackAlignment())
-      New->addAttr(new PackedAttr(Alignment * 8));
+      New->addAttr(::new (Context) PackedAttr(Alignment * 8));
   }
 
   if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index f7ead5c..d97747c 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -259,7 +259,7 @@
   }
   
   if (TagDecl *TD = dyn_cast<TagDecl>(d))
-    TD->addAttr(new PackedAttr(1));
+    TD->addAttr(::new (S.Context) PackedAttr(1));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
     // If the alignment is less than or equal to 8 bits, the packed attribute
     // has no effect.
@@ -268,7 +268,7 @@
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
         << Attr.getName() << FD->getType();
     else
-      FD->addAttr(new PackedAttr(1));
+      FD->addAttr(::new (S.Context) PackedAttr(1));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
@@ -283,7 +283,7 @@
   // The IBOutlet attribute only applies to instance variables of Objective-C
   // classes.
   if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
-    d->addAttr(new IBOutletAttr());
+    d->addAttr(::new (S.Context) IBOutletAttr());
   else
     S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
 }
@@ -355,7 +355,7 @@
   unsigned* start = &NonNullArgs[0];
   unsigned size = NonNullArgs.size();
   std::sort(start, start + size);
-  d->addAttr(new NonNullAttr(start, size));
+  d->addAttr(::new (S.Context) NonNullAttr(start, size));
 }
 
 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -380,7 +380,7 @@
   
   // FIXME: check if target symbol exists in current file
   
-  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
+  d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
 }
 
 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 
@@ -397,7 +397,7 @@
     return;
   }
   
-  d->addAttr(new AlwaysInlineAttr());
+  d->addAttr(::new (S.Context) AlwaysInlineAttr());
 }
 
 static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -413,7 +413,7 @@
     return;
   }
   
-  d->addAttr(new NoReturnAttr());
+  d->addAttr(::new (S.Context) NoReturnAttr());
 }
 
 static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -429,7 +429,7 @@
     return;
   }
   
-  d->addAttr(new UnusedAttr());
+  d->addAttr(::new (S.Context) UnusedAttr());
 }
 
 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -450,7 +450,7 @@
     return;
   }
   
-  d->addAttr(new UsedAttr());
+  d->addAttr(::new (S.Context) UsedAttr());
 }
 
 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -480,7 +480,7 @@
     return;
   }
 
-  d->addAttr(new ConstructorAttr(priority));
+  d->addAttr(::new (S.Context) ConstructorAttr(priority));
 }
 
 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -509,7 +509,7 @@
     return;
   }
 
-  d->addAttr(new DestructorAttr(priority));
+  d->addAttr(::new (S.Context) DestructorAttr(priority));
 }
 
 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -519,7 +519,7 @@
     return;
   }
   
-  d->addAttr(new DeprecatedAttr());
+  d->addAttr(::new (S.Context) DeprecatedAttr());
 }
 
 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -529,7 +529,7 @@
     return;
   }
   
-  d->addAttr(new UnavailableAttr());
+  d->addAttr(::new (S.Context) UnavailableAttr());
 }
 
 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -566,7 +566,7 @@
     return;
   }
   
-  d->addAttr(new VisibilityAttr(type));
+  d->addAttr(::new (S.Context) VisibilityAttr(type));
 }
 
 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -582,7 +582,7 @@
     return;
   }
   
-  D->addAttr(new ObjCExceptionAttr());
+  D->addAttr(::new (S.Context) ObjCExceptionAttr());
 }
 
 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -598,7 +598,7 @@
       return;
     }
   }
-  D->addAttr(new ObjCNSObjectAttr);
+  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
 }
 
 static void 
@@ -613,7 +613,7 @@
     return;
   }
 
-  D->addAttr(new OverloadableAttr);
+  D->addAttr(::new (S.Context) OverloadableAttr());
 }
 
 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -637,7 +637,7 @@
     return;
   }
   
-  d->addAttr(new BlocksAttr(type));
+  d->addAttr(::new (S.Context) BlocksAttr(type));
 }
 
 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -721,7 +721,7 @@
     return;
   }
   
-  Fn->addAttr(new WarnUnusedResultAttr());
+  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
 }
 
 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -731,7 +731,7 @@
     return;
   }
   
-  D->addAttr(new WeakAttr());
+  D->addAttr(::new (S.Context) WeakAttr());
 }
 
 static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -743,7 +743,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(new DLLImportAttr());
+    D->addAttr(::new (S.Context) DLLImportAttr());
     return;
   }
 
@@ -776,7 +776,7 @@
     return;
   }
 
-  D->addAttr(new DLLImportAttr());
+  D->addAttr(::new (S.Context) DLLImportAttr());
 }
 
 static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -788,7 +788,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(new DLLExportAttr());
+    D->addAttr(::new (S.Context) DLLExportAttr());
     return;
   }
 
@@ -807,7 +807,7 @@
     return;
   }
 
-  D->addAttr(new DLLExportAttr());
+  D->addAttr(::new (S.Context) DLLExportAttr());
 }
 
 static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -826,8 +826,8 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
     return;
   }
-  D->addAttr(new SectionAttr(std::string(SE->getStrData(),
-                                         SE->getByteLength())));
+  D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
+                                                     SE->getByteLength())));
 }
 
 static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -851,7 +851,7 @@
     return;
   }
 
-  d->addAttr(new StdCallAttr());
+  d->addAttr(::new (S.Context) StdCallAttr());
 }
 
 static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -874,7 +874,7 @@
     return;
   }
 
-  d->addAttr(new FastCallAttr());
+  d->addAttr(::new (S.Context) FastCallAttr());
 }
 
 static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -884,7 +884,7 @@
     return;
   }
   
-  d->addAttr(new NoThrowAttr());
+  d->addAttr(::new (S.Context) NoThrowAttr());
 }
 
 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -894,7 +894,7 @@
     return;
   }
   
-  d->addAttr(new ConstAttr());
+  d->addAttr(::new (S.Context) ConstAttr());
 }
 
 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -904,7 +904,7 @@
     return;
   }
   
-  d->addAttr(new PureAttr());
+  d->addAttr(::new (S.Context) PureAttr());
 }
 
 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -962,7 +962,7 @@
     return;
   }
   
-  d->addAttr(new CleanupAttr(FD));
+  d->addAttr(::new (S.Context) CleanupAttr(FD));
 }
 
 /// Handle __attribute__((format(type,idx,firstarg))) attributes
@@ -1105,7 +1105,7 @@
     return;
   }
 
-  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
+  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
                             Idx.getZExtValue(), FirstArg.getZExtValue()));
 }
 
@@ -1164,8 +1164,8 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
     return;
   }
-  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
-                                          SE->getByteLength())));
+  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
+                                                        SE->getByteLength())));
 }
 
 static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1180,7 +1180,7 @@
     // FIXME: This should be the target specific maximum alignment.
     // (For now we just use 128 bits which is the maximum on X86).
     Align = 128;
-    d->addAttr(new AlignedAttr(Align));
+    d->addAttr(::new (S.Context) AlignedAttr(Align));
     return;
   }
   
@@ -1197,7 +1197,7 @@
     return;
   }
 
-  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
+  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
 }
 
 /// HandleModeAttr - This attribute modifies the width of a decl with
@@ -1378,7 +1378,7 @@
     return;
   }
   
-  d->addAttr(new NodebugAttr());
+  d->addAttr(::new (S.Context) NodebugAttr());
 }
 
 static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1394,7 +1394,7 @@
     return;
   }
   
-  d->addAttr(new NoinlineAttr());
+  d->addAttr(::new (S.Context) NoinlineAttr());
 }
 
 //===----------------------------------------------------------------------===//