[cfe-commits] r128209 - in /cfe/trunk: include/clang/Parse/Parser.h include/clang/Sema/AttributeList.h include/clang/Sema/DeclSpec.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseObjc.cpp lib/Parse/ParseStmt.cpp lib/Parse/ParseTemplate.cpp lib/Parse/ParseTentative.cpp lib/Parse/Parser.cpp lib/Sema/AttributeList.cpp lib/Sema/DeclSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaType.cpp

John McCall rjmccall at apple.com
Thu Mar 24 04:26:52 PDT 2011


Author: rjmccall
Date: Thu Mar 24 06:26:52 2011
New Revision: 128209

URL: http://llvm.org/viewvc/llvm-project?rev=128209&view=rev
Log:
Insomniac refactoring:  change how the parser allocates attributes so that
AttributeLists do not accumulate over the lifetime of parsing, but are
instead reused.  Also make the arguments array not require a separate
allocation, and make availability attributes store their stuff in
augmented memory, too.


Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Parse/ParseTentative.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/AttributeList.cpp
    cfe/trunk/lib/Sema/DeclSpec.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Mar 24 06:26:52 2011
@@ -157,7 +157,7 @@
   unsigned TemplateParameterDepth;
   
   /// Factory object for creating AttributeList objects.
-  AttributeList::Factory AttrFactory;
+  AttributeFactory AttrFactory;
 
 public:
   Parser(Preprocessor &PP, Sema &Actions);
@@ -801,10 +801,9 @@
     ParsingDeclRAIIObject ParsingRAII;
 
   public:
-    ParsingDeclSpec(Parser &P) : ParsingRAII(P) {}
-    ParsingDeclSpec(ParsingDeclRAIIObject &RAII) : ParsingRAII(RAII) {}
+    ParsingDeclSpec(Parser &P) : DeclSpec(P.AttrFactory), ParsingRAII(P) {}
     ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
-      : ParsingRAII(P, RAII) {}
+      : DeclSpec(P.AttrFactory), ParsingRAII(P, RAII) {}
 
     void complete(Decl *D) {
       ParsingRAII.complete(D);
@@ -943,6 +942,9 @@
   //===--------------------------------------------------------------------===//
   // C99 6.9: External Definitions.
   struct ParsedAttributesWithRange : ParsedAttributes {
+    ParsedAttributesWithRange(AttributeFactory &factory)
+      : ParsedAttributes(factory) {}
+
     SourceRange Range;
   };
 
@@ -1506,10 +1508,10 @@
 
   void MaybeParseGNUAttributes(Declarator &D) {
     if (Tok.is(tok::kw___attribute)) {
-      ParsedAttributes attrs;
+      ParsedAttributes attrs(AttrFactory);
       SourceLocation endLoc;
       ParseGNUAttributes(attrs, &endLoc);
-      D.addAttributes(attrs.getList(), endLoc);
+      D.takeAttributes(attrs, endLoc);
     }
   }
   void MaybeParseGNUAttributes(ParsedAttributes &attrs,
@@ -1522,18 +1524,18 @@
 
   void MaybeParseCXX0XAttributes(Declarator &D) {
     if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
-      ParsedAttributesWithRange attrs;
+      ParsedAttributesWithRange attrs(AttrFactory);
       SourceLocation endLoc;
       ParseCXX0XAttributes(attrs, &endLoc);
-      D.addAttributes(attrs.getList(), endLoc);
+      D.takeAttributes(attrs, endLoc);
     }
   }
   void MaybeParseCXX0XAttributes(ParsedAttributes &attrs,
                                  SourceLocation *endLoc = 0) {
     if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
-      ParsedAttributesWithRange attrsWithRange;
+      ParsedAttributesWithRange attrsWithRange(AttrFactory);
       ParseCXX0XAttributes(attrsWithRange, endLoc);
-      attrs.append(attrsWithRange.getList());
+      attrs.takeAllFrom(attrsWithRange);
     }
   }
   void MaybeParseCXX0XAttributes(ParsedAttributesWithRange &attrs,

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Thu Mar 24 06:26:52 2011
@@ -16,13 +16,13 @@
 #define LLVM_CLANG_SEMA_ATTRLIST_H
 
 #include "llvm/Support/Allocator.h"
-#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/SmallVector.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/VersionTuple.h"
-#include "clang/AST/Expr.h"
 #include <cassert>
 
 namespace clang {
+  class ASTContext;
   class IdentifierInfo;
   class Expr;
 
@@ -51,87 +51,96 @@
 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
 ///
-class AttributeList {
-public:
-  class Factory;
+class AttributeList { // TODO: This should really be called ParsedAttribute
 private:
   IdentifierInfo *AttrName;
-  SourceLocation AttrLoc;
   IdentifierInfo *ScopeName;
-  SourceLocation ScopeLoc;
   IdentifierInfo *ParmName;
+  SourceLocation AttrLoc;
+  SourceLocation ScopeLoc;
   SourceLocation ParmLoc;
-  Expr **Args;
+
+  /// The number of expression arguments this attribute has.
+  /// The expressions themselves are stored after the object.
   unsigned NumArgs;
-  AttributeList *Next;
-  bool DeclspecAttribute, CXX0XAttribute;
 
-  // For the 'availability' attribute.
-  AvailabilityChange AvailabilityIntroduced;
-  AvailabilityChange AvailabilityDeprecated;
-  AvailabilityChange AvailabilityObsoleted;
+  /// True if Microsoft style: declspec(foo).
+  bool DeclspecAttribute;
+
+  /// True if C++0x-style: [[foo]].
+  bool CXX0XAttribute;
 
   /// True if already diagnosed as invalid.
   mutable bool Invalid;
 
+  /// True if this has the extra information associated with an
+  /// availability attribute.
+  bool IsAvailability;
+
+  /// The next attribute in the current position.
+  AttributeList *NextInPosition;
+
+  /// The next attribute allocated in the current Pool.
+  AttributeList *NextInPool;
+
+  Expr **getArgsBuffer() {
+    return reinterpret_cast<Expr**>(this+1);
+  }
+  Expr * const *getArgsBuffer() const {
+    return reinterpret_cast<Expr* const *>(this+1);
+  }
+
+  enum AvailabilitySlot {
+    IntroducedSlot, DeprecatedSlot, ObsoletedSlot
+  };
+
+  AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
+    return reinterpret_cast<AvailabilityChange*>(this+1)[index];
+  }
+  const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
+    return reinterpret_cast<const AvailabilityChange*>(this+1)[index];
+  }
+
   AttributeList(const AttributeList &); // DO NOT IMPLEMENT
   void operator=(const AttributeList &); // DO NOT IMPLEMENT
   void operator delete(void *); // DO NOT IMPLEMENT
   ~AttributeList(); // DO NOT IMPLEMENT
-  AttributeList(llvm::BumpPtrAllocator &Alloc,
-                IdentifierInfo *AttrName, SourceLocation AttrLoc,
-                IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-                IdentifierInfo *ParmName, SourceLocation ParmLoc,
-                Expr **args, unsigned numargs,
-                bool declspec, bool cxx0x);
-
-  AttributeList(llvm::BumpPtrAllocator &Alloc,
-                IdentifierInfo *AttrName, SourceLocation AttrLoc,
-                IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-                IdentifierInfo *ParmName, SourceLocation ParmLoc,
-                const AvailabilityChange &Introduced,
-                const AvailabilityChange &Deprecated,
-                const AvailabilityChange &Obsoleted,
-                bool declspec, bool cxx0x);
+
+  size_t allocated_size() const;
+
+  AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierInfo *parmName, SourceLocation parmLoc,
+                Expr **args, unsigned numArgs,
+                bool declspec, bool cxx0x)
+    : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
+      AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
+      NumArgs(numArgs),
+      DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false),
+      IsAvailability(false), NextInPosition(0), NextInPool(0) {
+    if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
+  }
+
+  AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierInfo *parmName, SourceLocation parmLoc,
+                const AvailabilityChange &introduced,
+                const AvailabilityChange &deprecated,
+                const AvailabilityChange &obsoleted,
+                bool declspec, bool cxx0x)
+    : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
+      AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
+      NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x),
+      Invalid(false), IsAvailability(true), NextInPosition(0), NextInPool(0) {
+    new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
+    new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
+    new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
+  }
+
+  friend class AttributePool;
+  friend class AttributeFactory;
+
 public:
-  class Factory {
-    llvm::BumpPtrAllocator Alloc;
-  public:
-    Factory() {}
-    ~Factory() {}
-    AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
-      IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-      IdentifierInfo *ParmName, SourceLocation ParmLoc,
-      Expr **args, unsigned numargs, bool declspec = false, bool cxx0x = false) {
-        AttributeList *Mem = Alloc.Allocate<AttributeList>();
-        new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
-                                ParmName, ParmLoc, args, numargs,
-                                declspec, cxx0x);
-        return Mem;
-      }
-
-    AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
-      IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-      IdentifierInfo *ParmName, SourceLocation ParmLoc,
-      const AvailabilityChange &Introduced,
-      const AvailabilityChange &Deprecated,
-      const AvailabilityChange &Obsoleted,
-      bool declspec = false, bool cxx0x = false) {
-        AttributeList *Mem = Alloc.Allocate<AttributeList>();
-        new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
-                                ParmName, ParmLoc, Introduced, Deprecated,
-                                Obsoleted, declspec, cxx0x);
-        return Mem;
-      }
-
-    AttributeList* CreateIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
-                                          SourceLocation TokLoc, int Arg) {
-      Expr* IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t)Arg),
-                                          C.IntTy, TokLoc);
-      return Create( Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
-    }
-  };
-  
   enum Kind {             // Please keep this list alphabetized.
     AT_IBAction,          // Clang-specific.
     AT_IBOutlet,          // Clang-specific.
@@ -242,8 +251,8 @@
   Kind getKind() const { return getKind(getName()); }
   static Kind getKind(const IdentifierInfo *Name);
 
-  AttributeList *getNext() const { return Next; }
-  void setNext(AttributeList *N) { Next = N; }
+  AttributeList *getNext() const { return NextInPosition; }
+  void setNext(AttributeList *N) { NextInPosition = N; }
 
   /// getNumArgs - Return the number of actual arguments to this attribute.
   unsigned getNumArgs() const { return NumArgs; }
@@ -251,14 +260,14 @@
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) const {
     assert(Arg < NumArgs && "Arg access out of range!");
-    return Args[Arg];
+    return getArgsBuffer()[Arg];
   }
 
   class arg_iterator {
-    Expr** X;
+    Expr * const *X;
     unsigned Idx;
   public:
-    arg_iterator(Expr** x, unsigned idx) : X(x), Idx(idx) {}
+    arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {}
 
     arg_iterator& operator++() {
       ++Idx;
@@ -285,27 +294,158 @@
   };
 
   arg_iterator arg_begin() const {
-    return arg_iterator(Args, 0);
+    return arg_iterator(getArgsBuffer(), 0);
   }
 
   arg_iterator arg_end() const {
-    return arg_iterator(Args, NumArgs);
+    return arg_iterator(getArgsBuffer(), NumArgs);
   }
 
   const AvailabilityChange &getAvailabilityIntroduced() const {
     assert(getKind() == AT_availability && "Not an availability attribute");
-    return AvailabilityIntroduced;
+    return getAvailabilitySlot(IntroducedSlot);
   }
 
   const AvailabilityChange &getAvailabilityDeprecated() const {
     assert(getKind() == AT_availability && "Not an availability attribute");
-    return AvailabilityDeprecated;
+    return getAvailabilitySlot(DeprecatedSlot);
   }
 
   const AvailabilityChange &getAvailabilityObsoleted() const {
     assert(getKind() == AT_availability && "Not an availability attribute");
-    return AvailabilityObsoleted;
+    return getAvailabilitySlot(ObsoletedSlot);
+  }
+};
+
+/// A factory, from which one makes pools, from which one creates
+/// individual attributes which are deallocated with the pool.
+///
+/// Note that it's tolerably cheap to create and destroy one of
+/// these as long as you don't actually allocate anything in it.
+class AttributeFactory {
+public:
+  enum {
+    /// The required allocation size of an availability attribute,
+    /// which we want to ensure is a multiple of sizeof(void*).
+    AvailabilityAllocSize =
+      sizeof(AttributeList)
+      + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1)
+         / sizeof(void*) * sizeof(void*))
+  };
+
+private:
+  enum {
+    /// The number of free lists we want to be sure to support
+    /// inline.  This is just enough that availability attributes
+    /// don't surpass it.  It's actually very unlikely we'll see an
+    /// attribute that needs more than that; on x86-64 you'd need 10
+    /// expression arguments, and on i386 you'd need 19.
+    InlineFreeListsCapacity =
+      1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
+  };
+
+  llvm::BumpPtrAllocator Alloc;
+
+  /// Free lists.  The index is determined by the following formula:
+  ///   (size - sizeof(AttributeList)) / sizeof(void*)
+  llvm::SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
+
+  // The following are the private interface used by AttributePool.
+  friend class AttributePool;
+
+  /// Allocate an attribute of the given size.
+  void *allocate(size_t size);
+
+  /// Reclaim all the attributes in the given pool chain, which is
+  /// non-empty.  Note that the current implementation is safe
+  /// against reclaiming things which were not actually allocated
+  /// with the allocator, although of course it's important to make
+  /// sure that their allocator lives at least as long as this one.
+  void reclaimPool(AttributeList *head);
+
+public:
+  AttributeFactory();
+  ~AttributeFactory();
+};
+
+class AttributePool {
+  AttributeFactory &Factory;
+  AttributeList *Head;
+
+  void *allocate(size_t size) {
+    return Factory.allocate(size);
+  }
+
+  AttributeList *add(AttributeList *attr) {
+    // We don't care about the order of the pool.
+    attr->NextInPool = Head;
+    Head = attr;
+    return attr;
+  }
+
+  void takePool(AttributeList *pool);
+
+public:
+  /// Create a new pool for a factory.
+  AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {}
+
+  /// Move the given pool's allocations to this pool.
+  AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
+    pool.Head = 0;
+  }
+
+  AttributeFactory &getFactory() const { return Factory; }
+
+  void clear() {
+    if (Head) {
+      Factory.reclaimPool(Head);
+      Head = 0;
+    }
   }
+
+  /// Take the given pool's allocations and add them to this pool.
+  void takeAllFrom(AttributePool &pool) {
+    if (pool.Head) {
+      takePool(pool.Head);
+      pool.Head = 0;
+    }
+  }
+
+  ~AttributePool() {
+    if (Head) Factory.reclaimPool(Head);
+  }
+
+  AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierInfo *parmName, SourceLocation parmLoc,
+                        Expr **args, unsigned numArgs,
+                        bool declspec = false, bool cxx0x = false) {
+    void *memory = allocate(sizeof(AttributeList)
+                            + numArgs * sizeof(Expr*));
+    return add(new (memory) AttributeList(attrName, attrLoc,
+                                          scopeName, scopeLoc,
+                                          parmName, parmLoc,
+                                          args, numArgs,
+                                          declspec, cxx0x));
+  }
+
+  AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierInfo *parmName, SourceLocation parmLoc,
+                        const AvailabilityChange &introduced,
+                        const AvailabilityChange &deprecated,
+                        const AvailabilityChange &obsoleted,
+                        bool declspec = false, bool cxx0x = false) {
+    void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
+    return add(new (memory) AttributeList(attrName, attrLoc,
+                                          scopeName, scopeLoc,
+                                          parmName, parmLoc,
+                                          introduced, deprecated, obsoleted,
+                                          declspec, cxx0x));
+  }
+
+  AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
+                                        SourceLocation TokLoc, int Arg);
 };
 
 /// addAttributeLists - Add two AttributeLists together
@@ -350,7 +490,16 @@
 /// is that this will become significantly more serious.
 class ParsedAttributes {
 public:
-  ParsedAttributes() : list(0) {}
+  ParsedAttributes(AttributeFactory &factory)
+    : pool(factory), list(0) {
+  }
+
+  ParsedAttributes(ParsedAttributes &attrs)
+    : pool(attrs.pool), list(attrs.list) {
+    attrs.list = 0;
+  }
+
+  AttributePool &getPool() const { return pool; }
 
   bool empty() const { return list == 0; }
 
@@ -361,7 +510,7 @@
     list = newAttr;
   }
 
-  void append(AttributeList *newList) {
+  void addAll(AttributeList *newList) {
     if (!newList) return;
 
     AttributeList *lastInNewList = newList;
@@ -376,14 +525,57 @@
     list = newList;
   }
 
-  void clear() { list = 0; }
+  void takeAllFrom(ParsedAttributes &attrs) {
+    addAll(attrs.list);
+    attrs.list = 0;
+    pool.takeAllFrom(attrs.pool);
+  }
+
+  void clear() { list = 0; pool.clear(); }
   AttributeList *getList() const { return list; }
 
   /// Returns a reference to the attribute list.  Try not to introduce
   /// dependencies on this method, it may not be long-lived.
   AttributeList *&getListRef() { return list; }
 
+
+  AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierInfo *parmName, SourceLocation parmLoc,
+                        Expr **args, unsigned numArgs,
+                        bool declspec = false, bool cxx0x = false) {
+    AttributeList *attr =
+      pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc,
+                  args, numArgs, declspec, cxx0x);
+    add(attr);
+    return attr;
+  }
+
+  AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierInfo *parmName, SourceLocation parmLoc,
+                        const AvailabilityChange &introduced,
+                        const AvailabilityChange &deprecated,
+                        const AvailabilityChange &obsoleted,
+                        bool declspec = false, bool cxx0x = false) {
+    AttributeList *attr =
+      pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc,
+                  introduced, deprecated, obsoleted, declspec, cxx0x);
+    add(attr);
+    return attr;
+  }
+
+  AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
+                               SourceLocation loc, int arg) {
+    AttributeList *attr =
+      pool.createIntegerAttribute(C, name, loc, arg);
+    add(attr);
+    return attr;
+  }
+
+
 private:
+  mutable AttributePool pool;
   AttributeList *list;
 };
 

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu Mar 24 06:26:52 2011
@@ -271,7 +271,6 @@
   };
 
 private:
-
   // storage-class-specifier
   /*SCS*/unsigned StorageClassSpec : 3;
   unsigned SCS_thread_specified : 1;
@@ -358,7 +357,7 @@
   void operator=(const DeclSpec&); // DO NOT IMPLEMENT
 public:
 
-  DeclSpec()
+  DeclSpec(AttributeFactory &attrFactory)
     : StorageClassSpec(SCS_unspecified),
       SCS_thread_specified(false),
       SCS_extern_in_linkage_spec(false),
@@ -377,6 +376,7 @@
       Friend_specified(false),
       Constexpr_specified(false),
       StorageClassSpecAsWritten(SCS_unspecified),
+      Attrs(attrFactory),
       ProtocolQualifiers(0),
       NumProtocolQualifiers(0),
       ProtocolLocs(0),
@@ -581,6 +581,10 @@
   bool isConstexprSpecified() const { return Constexpr_specified; }
   SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
 
+  AttributePool &getAttributePool() const {
+    return Attrs.getPool();
+  }
+
   /// AddAttributes - contatenates two attribute lists.
   /// The GCC attribute syntax allows for the following:
   ///
@@ -594,9 +598,9 @@
   /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
   ///
   void addAttributes(AttributeList *AL) {
-    Attrs.append(AL);
+    Attrs.addAll(AL);
   }
-  void aetAttributes(AttributeList *AL) {
+  void setAttributes(AttributeList *AL) {
     Attrs.set(AL);
   }
 
@@ -608,14 +612,12 @@
   /// TakeAttributes - Return the current attribute list and remove them from
   /// the DeclSpec so that it doesn't own them.
   ParsedAttributes takeAttributes() {
-    ParsedAttributes saved = Attrs;
-    Attrs.clear();
-    return saved;
+    // The non-const "copy" constructor clears the operand automatically.
+    return Attrs;
   }
 
   void takeAttributesFrom(ParsedAttributes &attrs) {
-    Attrs.append(attrs.getList());
-    attrs.clear();
+    Attrs.takeAllFrom(attrs);
   }
 
   typedef Decl * const *ProtocolQualifierListTy;
@@ -1197,8 +1199,7 @@
   static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
                                     SourceLocation ConstQualLoc,
                                     SourceLocation VolatileQualLoc,
-                                    SourceLocation RestrictQualLoc,
-                                    const ParsedAttributes &attrs) {
+                                    SourceLocation RestrictQualLoc) {
     DeclaratorChunk I;
     I.Kind                = Pointer;
     I.Loc                 = Loc;
@@ -1206,35 +1207,33 @@
     I.Ptr.ConstQualLoc    = ConstQualLoc.getRawEncoding();
     I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding();
     I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
-    I.Ptr.AttrList        = attrs.getList();
+    I.Ptr.AttrList        = 0;
     return I;
   }
 
   /// getReference - Return a DeclaratorChunk for a reference.
   ///
   static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
-                                      const ParsedAttributes &attrs,
                                       bool lvalue) {
     DeclaratorChunk I;
     I.Kind            = Reference;
     I.Loc             = Loc;
     I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
     I.Ref.LValueRef   = lvalue;
-    I.Ref.AttrList    = attrs.getList();
+    I.Ref.AttrList    = 0;
     return I;
   }
 
   /// getArray - Return a DeclaratorChunk for an array.
   ///
   static DeclaratorChunk getArray(unsigned TypeQuals,
-                                  const ParsedAttributes &attrs,
                                   bool isStatic, bool isStar, Expr *NumElts,
                                   SourceLocation LBLoc, SourceLocation RBLoc) {
     DeclaratorChunk I;
     I.Kind          = Array;
     I.Loc           = LBLoc;
     I.EndLoc        = RBLoc;
-    I.Arr.AttrList  = attrs.getList();
+    I.Arr.AttrList  = 0;
     I.Arr.TypeQuals = TypeQuals;
     I.Arr.hasStatic = isStatic;
     I.Arr.isStar    = isStar;
@@ -1244,8 +1243,7 @@
 
   /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
   /// "TheDeclarator" is the declarator that this will be added to.
-  static DeclaratorChunk getFunction(const ParsedAttributes &attrs,
-                                     bool hasProto, bool isVariadic,
+  static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
                                      SourceLocation EllipsisLoc,
                                      ParamInfo *ArgInfo, unsigned NumArgs,
                                      unsigned TypeQuals, 
@@ -1265,25 +1263,24 @@
 
   /// getBlockPointer - Return a DeclaratorChunk for a block.
   ///
-  static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc,
-                                         const ParsedAttributes &attrs) {
+  static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
+                                         SourceLocation Loc) {
     DeclaratorChunk I;
     I.Kind          = BlockPointer;
     I.Loc           = Loc;
     I.Cls.TypeQuals = TypeQuals;
-    I.Cls.AttrList  = attrs.getList();
+    I.Cls.AttrList  = 0;
     return I;
   }
 
   static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
                                           unsigned TypeQuals,
-                                          SourceLocation Loc,
-                                          const ParsedAttributes &attrs) {
+                                          SourceLocation Loc) {
     DeclaratorChunk I;
     I.Kind          = MemberPointer;
     I.Loc           = Loc;
     I.Mem.TypeQuals = TypeQuals;
-    I.Mem.AttrList  = attrs.getList();
+    I.Mem.AttrList  = 0;
     new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
     return I;
   }
@@ -1352,8 +1349,8 @@
   /// GroupingParens - Set by Parser::ParseParenDeclarator().
   bool GroupingParens : 1;
 
-  /// AttrList - Attributes.
-  AttributeList *AttrList;
+  /// Attrs - Attributes.
+  ParsedAttributes Attrs;
 
   /// AsmLabel - The asm label, if specified.
   Expr *AsmLabel;
@@ -1377,8 +1374,8 @@
   Declarator(const DeclSpec &ds, TheContext C)
     : DS(ds), Range(ds.getSourceRange()), Context(C),
       InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
-      GroupingParens(false), AttrList(0), AsmLabel(0),
-      InlineParamsUsed(false), Extension(false) {
+      GroupingParens(false), Attrs(ds.getAttributePool().getFactory()),
+      AsmLabel(0), InlineParamsUsed(false), Extension(false) {
   }
 
   ~Declarator() {
@@ -1396,6 +1393,10 @@
   /// be shared or when in error recovery etc.
   DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); }
 
+  AttributePool &getAttributePool() const {
+    return Attrs.getPool();
+  }
+
   /// getCXXScopeSpec - Return the C++ scope specifier (global scope or
   /// nested-name-specifier) that is part of the declarator-id.
   const CXXScopeSpec &getCXXScopeSpec() const { return SS; }
@@ -1445,7 +1446,7 @@
     for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
       DeclTypeInfo[i].destroy();
     DeclTypeInfo.clear();
-    AttrList = 0;
+    Attrs.clear();
     AsmLabel = 0;
     InlineParamsUsed = false;
   }
@@ -1552,8 +1553,13 @@
   
   /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
   /// EndLoc, which should be the last token of the chunk.
-  void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) {
+  void AddTypeInfo(const DeclaratorChunk &TI,
+                   ParsedAttributes &attrs,
+                   SourceLocation EndLoc) {
     DeclTypeInfo.push_back(TI);
+    DeclTypeInfo.back().getAttrListRef() = attrs.getList();
+    getAttributePool().takeAllFrom(attrs.getPool());
+
     if (!EndLoc.isInvalid())
       SetRangeEnd(EndLoc);
   }
@@ -1633,28 +1639,26 @@
     return const_cast<Declarator*>(this)->getFunctionTypeInfo();
   }
 
-  /// AddAttributes - simply adds the attribute list to the Declarator.
+  /// takeAttributes - Takes attributes from the given parsed-attributes
+  /// set and add them to this declarator.
+  ///
   /// These examples both add 3 attributes to "var":
   ///  short int var __attribute__((aligned(16),common,deprecated));
   ///  short int x, __attribute__((aligned(16)) var
   ///                                 __attribute__((common,deprecated));
   ///
   /// Also extends the range of the declarator.
-  void addAttributes(AttributeList *alist, SourceLocation LastLoc) {
-    AttrList = addAttributeLists(AttrList, alist);
-
-    if (!LastLoc.isInvalid())
-      SetRangeEnd(LastLoc);
-  }
+  void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) {
+    Attrs.takeAllFrom(attrs);
 
-  void addAttributes(const ParsedAttributes &attrs) {
-    addAttributes(attrs.getList(), SourceLocation());
+    if (!lastLoc.isInvalid())
+      SetRangeEnd(lastLoc);
   }
 
-  const AttributeList *getAttributes() const { return AttrList; }
-  AttributeList *getAttributes() { return AttrList; }
+  const AttributeList *getAttributes() const { return Attrs.getList(); }
+  AttributeList *getAttributes() { return Attrs.getList(); }
 
-  AttributeList *&getAttrListRef() { return AttrList; }
+  AttributeList *&getAttrListRef() { return Attrs.getListRef(); }
 
   /// hasAttributes - do we contain any attributes?
   bool hasAttributes() const {

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Mar 24 06:26:52 2011
@@ -33,7 +33,7 @@
 TypeResult Parser::ParseTypeName(SourceRange *Range,
                                  Declarator::TheContext Context) {
   // Parse the common declaration-specifiers piece.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseSpecifierQualifierList(DS);
 
   // Parse the abstract-declarator, if present.
@@ -126,8 +126,8 @@
           if (Tok.is(tok::r_paren)) {
             // __attribute__(( mode(byte) ))
             ConsumeParen(); // ignore the right paren loc for now
-            attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                         ParmName, ParmLoc, 0, 0));
+            attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                         ParmName, ParmLoc, 0, 0);
           } else if (Tok.is(tok::comma)) {
             ConsumeToken();
             // __attribute__(( format(printf, 1, 2) ))
@@ -150,9 +150,8 @@
             }
             if (ArgExprsOk && Tok.is(tok::r_paren)) {
               ConsumeParen(); // ignore the right paren loc for now
-              attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
-                                           AttrNameLoc, ParmName, ParmLoc,
-                                           ArgExprs.take(), ArgExprs.size()));
+              attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                           ParmName, ParmLoc, ArgExprs.take(), ArgExprs.size());
             }
           }
         } else { // not an identifier
@@ -161,8 +160,8 @@
           // parse a possibly empty comma separated list of expressions
             // __attribute__(( nonnull() ))
             ConsumeParen(); // ignore the right paren loc for now
-            attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                         0, SourceLocation(), 0, 0));
+            attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                         0, SourceLocation(), 0, 0);
             break;
           case tok::kw_char:
           case tok::kw_wchar_t:
@@ -179,9 +178,8 @@
           case tok::kw_void:
           case tok::kw_typeof: {
             AttributeList *attr
-                     = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                          0, SourceLocation(), 0, 0);
-            attrs.add(attr);
+              = attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                             0, SourceLocation(), 0, 0);
             if (attr->getKind() == AttributeList::AT_IBOutletCollection)
               Diag(Tok, diag::err_iboutletcollection_builtintype);
             // If it's a builtin type name, eat it and expect a rparen
@@ -213,16 +211,16 @@
             // Match the ')'.
             if (ArgExprsOk && Tok.is(tok::r_paren)) {
               ConsumeParen(); // ignore the right paren loc for now
-              attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
-                                           AttrNameLoc, 0, SourceLocation(),
-                                           ArgExprs.take(), ArgExprs.size()));
+              attrs.addNew(AttrName, AttrNameLoc, 0,
+                           AttrNameLoc, 0, SourceLocation(),
+                           ArgExprs.take(), ArgExprs.size());
             }
             break;
           }
         }
       } else {
-        attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                     0, SourceLocation(), 0, 0));
+        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                     0, SourceLocation(), 0, 0);
       }
     }
     if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -264,14 +262,14 @@
       ExprResult ArgExpr(ParseAssignmentExpression());
       if (!ArgExpr.isInvalid()) {
         Expr *ExprList = ArgExpr.take();
-        attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                     SourceLocation(), &ExprList, 1, true));
+        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                     SourceLocation(), &ExprList, 1, true);
       }
       if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
         SkipUntil(tok::r_paren, false);
     } else {
-      attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                   0, SourceLocation(), 0, 0, true));
+      attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
+                   0, SourceLocation(), 0, 0, true);
     }
   }
   if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -290,8 +288,8 @@
     if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
       // FIXME: Support these properly!
       continue;
-    attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                 SourceLocation(), 0, 0, true));
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                 SourceLocation(), 0, 0, true);
   }
 }
 
@@ -300,8 +298,8 @@
   while (Tok.is(tok::kw___pascal)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
-                                 SourceLocation(), 0, 0, true));
+    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+                 SourceLocation(), 0, 0, true);
   }
 }
 
@@ -309,9 +307,9 @@
   // Treat these like attributes
   while (Tok.is(tok::kw___kernel)) {
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.add(AttrFactory.Create(PP.getIdentifierInfo("opencl_kernel_function"),
-                                 AttrNameLoc, 0, AttrNameLoc, 0,
-                                 SourceLocation(), 0, 0, false));
+    attrs.addNew(PP.getIdentifierInfo("opencl_kernel_function"),
+                 AttrNameLoc, 0, AttrNameLoc, 0,
+                 SourceLocation(), 0, 0, false);
   }
 }
 
@@ -321,45 +319,45 @@
     // OpenCL qualifiers:
     case tok::kw___private:
     case tok::kw_private: 
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute( 
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(), 
-          PP.getIdentifierInfo("address_space"), Loc, 0));
+          PP.getIdentifierInfo("address_space"), Loc, 0);
       break;
       
     case tok::kw___global:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global));
+          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
       break;
       
     case tok::kw___local:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local));
+          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
       break;
       
     case tok::kw___constant:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant));
+          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
       break;
       
     case tok::kw___read_only:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(), 
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only));
+          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
       break;
       
     case tok::kw___write_only:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(), 
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only));
+          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
       break;
       
     case tok::kw___read_write:
-      DS.addAttributes(AttrFactory.CreateIntegerAttribute(
+      DS.getAttributes().addNewInteger(
           Actions.getASTContext(),
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write));
+          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
       break;
     default: break;
   }
@@ -592,12 +590,12 @@
     *endLoc = RParenLoc;
 
   // Record this attribute
-  attrs.add(AttrFactory.Create(&Availability, AvailabilityLoc,
-                               0, SourceLocation(),
-                               Platform, PlatformLoc,
-                               Changes[Introduced],
-                               Changes[Deprecated],
-                               Changes[Obsoleted], false, false));
+  attrs.addNew(&Availability, AvailabilityLoc,
+               0, SourceLocation(),
+               Platform, PlatformLoc,
+               Changes[Introduced],
+               Changes[Deprecated],
+               Changes[Obsoleted], false, false);
 }
 
 void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
@@ -2175,7 +2173,7 @@
     }
 
     // Parse all the comma separated declarators.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 
     if (!Tok.is(tok::at)) {
       struct CFieldCallback : FieldCallback {
@@ -2236,7 +2234,7 @@
 
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
 
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   // If attributes exist after struct contents, parse them.
   MaybeParseGNUAttributes(attrs);
 
@@ -2286,7 +2284,7 @@
   }
   
   // If attributes exist after tag, parse them.
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseGNUAttributes(attrs);
 
   CXXScopeSpec &SS = DS.getTypeSpecScope();
@@ -2526,7 +2524,7 @@
     SourceLocation IdentLoc = ConsumeToken();
 
     // If attributes exist after the enumerator, parse them.
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     MaybeParseGNUAttributes(attrs);
 
     SourceLocation EqualLoc;
@@ -2570,7 +2568,7 @@
   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
 
   // If attributes exist after the identifier list, parse them.
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseGNUAttributes(attrs);
 
   Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
@@ -2918,7 +2916,7 @@
     DeclScopeObj.EnterDeclaratorScope();
 
   // Optionally skip Microsoft attributes.
-  ParsedAttributes Attrs;
+  ParsedAttributes Attrs(AttrFactory);
   MaybeParseMicrosoftAttributes(Attrs);
 
   // Check whether the next token(s) are part of a declaration
@@ -2946,7 +2944,7 @@
                                        bool CXX0XAttributesAllowed) {
   if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
     SourceLocation Loc = Tok.getLocation();
-    ParsedAttributesWithRange attrs;
+    ParsedAttributesWithRange attrs(AttrFactory);
     ParseCXX0XAttributes(attrs);
     if (CXX0XAttributesAllowed)
       DS.takeAttributesFrom(attrs);
@@ -3092,7 +3090,7 @@
 
       SourceLocation Loc = ConsumeToken();
       D.SetRangeEnd(Loc);
-      DeclSpec DS;
+      DeclSpec DS(AttrFactory);
       ParseTypeQualifierListOpt(DS);
       D.ExtendWithDeclSpec(DS);
 
@@ -3102,7 +3100,8 @@
       // Sema will have to catch (syntactically invalid) pointers into global
       // scope. It has to catch pointers into namespace scope anyway.
       D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
-                                                      Loc, DS.takeAttributes()),
+                                                      Loc),
+                    DS.getAttributes(),
                     /* Don't replace range end. */SourceLocation());
       return;
     }
@@ -3126,7 +3125,7 @@
 
   if (Kind == tok::star || Kind == tok::caret) {
     // Is a pointer.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 
     ParseTypeQualifierListOpt(DS);
     D.ExtendWithDeclSpec(DS);
@@ -3138,17 +3137,18 @@
       D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
                                                 DS.getConstSpecLoc(),
                                                 DS.getVolatileSpecLoc(),
-                                                DS.getRestrictSpecLoc(),
-                                                DS.takeAttributes()),
+                                                DS.getRestrictSpecLoc()),
+                    DS.getAttributes(),
                     SourceLocation());
     else
       // Remember that we parsed a Block type, and remember the type-quals.
       D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
-                                                     Loc, DS.takeAttributes()),
+                                                     Loc),
+                    DS.getAttributes(),
                     SourceLocation());
   } else {
     // Is a reference
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 
     // Complain about rvalue references in C++03, but then go on and build
     // the declarator.
@@ -3196,8 +3196,8 @@
 
     // Remember that we parsed a reference type. It doesn't have type-quals.
     D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
-                                                DS.takeAttributes(),
                                                 Kind == tok::amp),
+                  DS.getAttributes(),
                   SourceLocation());
   }
 }
@@ -3362,7 +3362,7 @@
         if (!isCXXFunctionDeclarator(warnIfAmbiguous))
           break;
       }
-      ParsedAttributes attrs;
+      ParsedAttributes attrs(AttrFactory);
       ParseFunctionDeclarator(ConsumeParen(), D, attrs);
     } else if (Tok.is(tok::l_square)) {
       ParseBracketDeclarator(D);
@@ -3399,7 +3399,7 @@
   // In either case, we need to eat any attributes to be able to determine what
   // sort of paren this is.
   //
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   bool RequiresArg = false;
   if (Tok.is(tok::kw___attribute)) {
     ParseGNUAttributes(attrs);
@@ -3445,13 +3445,12 @@
   if (isGrouping) {
     bool hadGroupingParens = D.hasGroupingParens();
     D.setGroupingParens(true);
-    if (!attrs.empty())
-      D.addAttributes(attrs.getList(), SourceLocation());
 
     ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
     // Match the ')'.
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_paren, StartLoc);
-    D.AddTypeInfo(DeclaratorChunk::getParen(StartLoc, EndLoc), EndLoc);
+    D.AddTypeInfo(DeclaratorChunk::getParen(StartLoc, EndLoc),
+                  attrs, EndLoc);
 
     D.setGroupingParens(hadGroupingParens);
     return;
@@ -3518,7 +3517,7 @@
     SourceLocation EndLoc = ConsumeParen();  // Eat the closing ')'.
 
     // cv-qualifier-seq[opt].
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     SourceLocation RefQualifierLoc;
     bool RefQualifierIsLValueRef = true;
     ExceptionSpecificationType ESpecType = EST_None;
@@ -3559,8 +3558,7 @@
 
     // Remember that we parsed a function type, and remember the attributes.
     // int() -> no prototype, no '...'.
-    D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
-                                               /*prototype*/getLang().CPlusPlus,
+    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
                                                /*variadic*/ false,
                                                SourceLocation(),
                                                /*arglist*/ 0, 0,
@@ -3575,7 +3573,7 @@
                                                  NoexceptExpr.get() : 0,
                                                LParenLoc, EndLoc, D,
                                                TrailingReturnType),
-                  EndLoc);
+                  attrs, EndLoc);
     return;
   }
 
@@ -3639,7 +3637,7 @@
 
     // Parse the declaration-specifiers.
     // Just use the ParsingDeclaration "scope" of the declarator.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
 	
     // Skip any Microsoft attributes before a param.
     if (getLang().Microsoft && Tok.is(tok::l_square))
@@ -3765,7 +3763,7 @@
   // If we have the closing ')', eat it.
   SourceLocation EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
 
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   SourceLocation RefQualifierLoc;
   bool RefQualifierIsLValueRef = true;
   ExceptionSpecificationType ESpecType = EST_None;
@@ -3814,8 +3812,7 @@
   PrototypeScope.Exit();
 
   // Remember that we parsed a function type, and remember the attributes.
-  D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
-                                             /*proto*/true, IsVariadic,
+  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
                                              EllipsisLoc,
                                              ParamInfo.data(), ParamInfo.size(),
                                              DS.getTypeQualifiers(),
@@ -3829,7 +3826,7 @@
                                                NoexceptExpr.get() : 0,
                                              LParenLoc, EndLoc, D,
                                              TrailingReturnType),
-                EndLoc);
+                attrs, EndLoc);
 }
 
 /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
@@ -3898,15 +3895,15 @@
   // Remember that we parsed a function type, and remember the attributes.  This
   // function type is always a K&R style function type, which is not varargs and
   // has no prototype.
-  D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
-                                             /*proto*/false, /*varargs*/false,
+  ParsedAttributes attrs(AttrFactory);
+  D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
                                              SourceLocation(),
                                              &ParamInfo[0], ParamInfo.size(),
                                              /*TypeQuals*/0,
                                              true, SourceLocation(),
                                              EST_None, SourceLocation(), 0, 0,
                                              0, 0, LParenLoc, RLoc, D),
-                RLoc);
+                attrs, RLoc);
 }
 
 /// [C90]   direct-declarator '[' constant-expression[opt] ']'
@@ -3921,14 +3918,14 @@
   // This code does a fast path to handle some of the most obvious cases.
   if (Tok.getKind() == tok::r_square) {
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     MaybeParseCXX0XAttributes(attrs);
     
     // Remember that we parsed the empty array type.
     ExprResult NumElements;
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, false, 0,
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
                                             StartLoc, EndLoc),
-                  EndLoc);
+                  attrs, EndLoc);
     return;
   } else if (Tok.getKind() == tok::numeric_constant &&
              GetLookAheadToken(1).is(tok::r_square)) {
@@ -3937,14 +3934,14 @@
     ConsumeToken();
 
     SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     MaybeParseCXX0XAttributes(attrs);
 
     // Remember that we parsed a array type, and remember its features.
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, 0,
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
                                             ExprRes.release(),
                                             StartLoc, EndLoc),
-                  EndLoc);
+                  attrs, EndLoc);
     return;
   }
 
@@ -3955,7 +3952,7 @@
 
   // If there is a type-qualifier-list, read it now.
   // Type qualifiers in an array subscript are a C99 feature.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseTypeQualifierListOpt(DS, false /*no attributes*/);
 
   // If we haven't already read 'static', check to see if there is one after the
@@ -4003,15 +4000,15 @@
 
   SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
 
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseCXX0XAttributes(attrs);
 
   // Remember that we parsed a array type, and remember its features.
-  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), attrs,
+  D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
                                           StaticLoc.isValid(), isStar,
                                           NumElements.release(),
                                           StartLoc, EndLoc),
-                EndLoc);
+                attrs, EndLoc);
 }
 
 /// [GNU]   typeof-specifier:

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Mar 24 06:26:52 2011
@@ -69,11 +69,9 @@
   }
 
   // Read label attributes, if present.
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   if (Tok.is(tok::kw___attribute)) {
     attrTok = Tok;
-
-    // FIXME: save these somewhere.
     ParseGNUAttributes(attrs);
   }
 
@@ -118,7 +116,7 @@
                                       "parsing namespace");
 
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    ParsedAttributesWithRange attrs;
+    ParsedAttributesWithRange attrs(AttrFactory);
     MaybeParseCXX0XAttributes(attrs);
     MaybeParseMicrosoftAttributes(attrs);
     ParseExternalDeclaration(attrs);
@@ -138,9 +136,9 @@
 /// alias definition.
 ///
 Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
-                                              SourceLocation AliasLoc,
-                                              IdentifierInfo *Alias,
-                                              SourceLocation &DeclEnd) {
+                                  SourceLocation AliasLoc,
+                                  IdentifierInfo *Alias,
+                                  SourceLocation &DeclEnd) {
   assert(Tok.is(tok::equal) && "Not equal token");
 
   ConsumeToken(); // eat the '='.
@@ -199,7 +197,7 @@
                                       Tok.is(tok::l_brace) ? Tok.getLocation()
                                                            : SourceLocation());
 
-  ParsedAttributesWithRange attrs;
+  ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX0XAttributes(attrs);
   MaybeParseMicrosoftAttributes(attrs);
 
@@ -216,7 +214,7 @@
 
   SourceLocation LBrace = ConsumeBrace();
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    ParsedAttributesWithRange attrs;
+    ParsedAttributesWithRange attrs(AttrFactory);
     MaybeParseCXX0XAttributes(attrs);
     MaybeParseMicrosoftAttributes(attrs);
     ParseExternalDeclaration(attrs);
@@ -380,7 +378,7 @@
   }
 
   // Parse (optional) attributes (most likely GNU strong-using extension).
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseGNUAttributes(attrs);
 
   // Eat ';'.
@@ -590,7 +588,7 @@
   EndLocation = IdLoc;
 
   // Fake up a Declarator to use with ActOnTypeName.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   DS.SetRangeStart(IdLoc);
   DS.SetRangeEnd(EndLocation);
   DS.getTypeSpecScope() = SS;
@@ -677,7 +675,7 @@
     SuppressingAccessChecks = true;
   }
 
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   // If attributes exist after tag, parse them.
   if (Tok.is(tok::kw___attribute))
     ParseGNUAttributes(attrs);
@@ -1488,7 +1486,7 @@
   // is a bitfield.
   ColonProtectionRAIIObject X(*this);
 
-  ParsedAttributesWithRange attrs;
+  ParsedAttributesWithRange attrs(AttrFactory);
   // Optional C++0x attribute-specifier
   MaybeParseCXX0XAttributes(attrs);
   MaybeParseMicrosoftAttributes(attrs);
@@ -1837,7 +1835,7 @@
   }
 
   // If attributes exist after class contents, parse them.
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   MaybeParseGNUAttributes(attrs);
 
   if (TagDecl)
@@ -2309,8 +2307,8 @@
           break;
         }
 
-        attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
-                                     SourceLocation(), 0, 0, false, true));
+        attrs.addNew(AttrName, AttrLoc, 0, AttrLoc, 0,
+                     SourceLocation(), 0, 0, false, true);
         AttrParsed = true;
         break;
       }
@@ -2330,9 +2328,9 @@
 
         ExprVector ArgExprs(Actions);
         ArgExprs.push_back(ArgExpr.release());
-        attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
-                                     0, ParamLoc, ArgExprs.take(), 1,
-                                     false, true));
+        attrs.addNew(AttrName, AttrLoc, 0, AttrLoc,
+                     0, ParamLoc, ArgExprs.take(), 1,
+                     false, true);
 
         AttrParsed = true;
         break;

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Thu Mar 24 06:26:52 2011
@@ -683,7 +683,7 @@
         if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
           if (Typ.get()->isObjCObjectOrInterfaceType()) {
             // Fake up a Declarator to use with ActOnTypeName.
-            DeclSpec DS;
+            DeclSpec DS(AttrFactory);
             DS.SetRangeStart(ILoc);
             DS.SetRangeEnd(ILoc);
             const char *PrevSpec = 0;
@@ -826,7 +826,7 @@
       ParsedType Type = getTypeAnnotation(Tok);
       
       // Fake up a Declarator to use with ActOnTypeName.
-      DeclSpec DS;
+      DeclSpec DS(AttrFactory);
       DS.SetRangeStart(Tok.getLocation());
       DS.SetRangeEnd(Tok.getLastLoc());
 
@@ -876,7 +876,7 @@
 
     // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
     //
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     ParseCXXSimpleTypeSpecifier(DS);
     if (Tok.isNot(tok::l_paren))
       return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
@@ -1634,7 +1634,7 @@
   
   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::ext_gnu_statement_expr);
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     StmtResult Stmt(ParseCompoundStatement(attrs, true));
     ExprType = CompoundStmt;
 
@@ -1850,7 +1850,7 @@
   }
   
   // Parse the specifier-qualifier-list piece.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseSpecifierQualifierList(DS);
 
   // Parse the block-declarator.
@@ -1858,7 +1858,7 @@
   ParseDeclarator(DeclaratorInfo);
 
   // We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
-  DeclaratorInfo.addAttributes(DS.takeAttributes());
+  DeclaratorInfo.takeAttributes(DS.getAttributes(), SourceLocation());
 
   MaybeParseGNUAttributes(DeclaratorInfo);
 
@@ -1894,7 +1894,7 @@
   Actions.ActOnBlockStart(CaretLoc, getCurScope());
 
   // Parse the return type if present.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
   // FIXME: Since the return type isn't actually parsed, it can't be used to
   // fill ParamInfo with an initial valid range, so do it manually.
@@ -1926,8 +1926,8 @@
     ParseBlockId();
   } else {
     // Otherwise, pretend we saw (void).
-    ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
-                                                       true, false,
+    ParsedAttributes attrs(AttrFactory);
+    ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
                                                        SourceLocation(),
                                                        0, 0, 0,
                                                        true, SourceLocation(),
@@ -1936,7 +1936,7 @@
                                                        0, 0, 0, 0,
                                                        CaretLoc, CaretLoc,
                                                        ParamInfo),
-                          CaretLoc);
+                          attrs, CaretLoc);
 
     MaybeParseGNUAttributes(ParamInfo);
 

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Mar 24 06:26:52 2011
@@ -800,7 +800,7 @@
   }
 
   // type-specifier-seq
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseSpecifierQualifierList(DS);
 
   // declarator
@@ -1391,7 +1391,7 @@
   //     ptr-operator conversion-declarator[opt]
   
   // Parse the type-specifier-seq.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
     return true;
   
@@ -1644,7 +1644,7 @@
   SourceLocation PlacementLParen, PlacementRParen;
 
   SourceRange TypeIdParens;
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
   if (Tok.is(tok::l_paren)) {
     // If it turns out to be a placement, we change the type location.
@@ -1746,10 +1746,12 @@
     first = false;
 
     SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, ParsedAttributes(),
+
+    ParsedAttributes attrs(AttrFactory);
+    D.AddTypeInfo(DeclaratorChunk::getArray(0,
                                             /*static=*/false, /*star=*/false,
                                             Size.release(), LLoc, RLoc),
-                  RLoc);
+                  attrs, RLoc);
 
     if (RLoc.isInvalid())
       return;

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Thu Mar 24 06:26:52 2011
@@ -41,11 +41,11 @@
   case tok::objc_class:
     return ParseObjCAtClassDeclaration(AtLoc);
   case tok::objc_interface: {
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     return ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
   }
   case tok::objc_protocol: {
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
   }
   case tok::objc_implementation:
@@ -371,7 +371,7 @@
 
       // FIXME: as the name implies, this rule allows function definitions.
       // We could pass a flag or check for functions during semantic analysis.
-      ParsedAttributes attrs;
+      ParsedAttributes attrs(AttrFactory);
       allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
       continue;
     }
@@ -439,7 +439,7 @@
                                     OCDS, AtLoc, MethodImplKind);
 
       // Parse all the comma separated declarators.
-      DeclSpec DS;
+      DeclSpec DS(AttrFactory);
       ParseStructDeclaration(DS, Callback);
 
       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
@@ -843,9 +843,9 @@
     ReturnType = ParseObjCTypeName(DSRet, OTN_ResultType);
 
   // If attributes exist before the method, parse them.
-  ParsedAttributes attrs;
+  ParsedAttributes methodAttrs(AttrFactory);
   if (getLang().ObjC2)
-    MaybeParseGNUAttributes(attrs);
+    MaybeParseGNUAttributes(methodAttrs);
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
@@ -870,7 +870,7 @@
   if (Tok.isNot(tok::colon)) {
     // If attributes exist after the method, parse them.
     if (getLang().ObjC2)
-      MaybeParseGNUAttributes(attrs);
+      MaybeParseGNUAttributes(methodAttrs);
 
     Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
     Decl *Result
@@ -878,8 +878,8 @@
                                           mType, IDecl, DSRet, ReturnType, Sel,
                                           0, 
                                           CParamInfo.data(), CParamInfo.size(),
-                                          attrs.getList(), MethodImplKind, false, 
-                                          MethodDefinition);
+                                          methodAttrs.getList(), MethodImplKind,
+                                          false, MethodDefinition);
     PD.complete(Result);
     return Result;
   }
@@ -888,8 +888,11 @@
   llvm::SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
   ParseScope PrototypeScope(this,
                             Scope::FunctionPrototypeScope|Scope::DeclScope);
+
+  AttributePool allParamAttrs(AttrFactory);
   
   while (1) {
+    ParsedAttributes paramAttrs(AttrFactory);
     Sema::ObjCArgInfo ArgInfo;
 
     // Each iteration parses a single keyword argument.
@@ -906,9 +909,8 @@
     // If attributes exist before the argument name, parse them.
     ArgInfo.ArgAttrs = 0;
     if (getLang().ObjC2) {
-      ParsedAttributes attrs;
-      MaybeParseGNUAttributes(attrs);
-      ArgInfo.ArgAttrs = attrs.getList();
+      MaybeParseGNUAttributes(paramAttrs);
+      ArgInfo.ArgAttrs = paramAttrs.getList();
     }
 
     // Code completion for the next piece of the selector.
@@ -937,6 +939,9 @@
     ArgInfos.push_back(ArgInfo);
     KeyIdents.push_back(SelIdent);
 
+    // Make sure the attributes persist.
+    allParamAttrs.takeAllFrom(paramAttrs.getPool());
+
     // Code completion for the next piece of the selector.
     if (Tok.is(tok::code_completion)) {
       ConsumeCodeCompletionToken();
@@ -967,7 +972,7 @@
       ConsumeToken();
       break;
     }
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     ParseDeclarationSpecifiers(DS);
     // Parse the declarator.
     Declarator ParmDecl(DS, Declarator::PrototypeContext);
@@ -984,7 +989,7 @@
   // FIXME: Add support for optional parameter list...
   // If attributes exist after the method, parse them.
   if (getLang().ObjC2)
-    MaybeParseGNUAttributes(attrs);
+    MaybeParseGNUAttributes(methodAttrs);
   
   if (KeyIdents.size() == 0) {
     // Leave prototype scope.
@@ -999,7 +1004,7 @@
                                         mType, IDecl, DSRet, ReturnType, Sel,
                                         &ArgInfos[0], 
                                         CParamInfo.data(), CParamInfo.size(),
-                                        attrs.getList(),
+                                        methodAttrs.getList(),
                                         MethodImplKind, isVariadic, MethodDefinition);
   // Leave prototype scope.
   PrototypeScope.Exit();
@@ -1172,7 +1177,7 @@
     } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
     
     // Parse all the comma separated declarators.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     ParseStructDeclaration(DS, Callback);
 
     if (Tok.is(tok::semi)) {
@@ -1616,7 +1621,7 @@
         ConsumeParen();
         ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
         if (Tok.isNot(tok::ellipsis)) {
-          DeclSpec DS;
+          DeclSpec DS(AttrFactory);
           ParseDeclarationSpecifiers(DS);
           // For some odd reason, the name of the exception variable is
           // optional. As a result, we need to use "PrototypeContext", because
@@ -1848,7 +1853,7 @@
   //   typename-specifier
   //   simple-type-specifier
   //   expression (that starts with one of the above)
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseCXXSimpleTypeSpecifier(DS);
   
   if (Tok.is(tok::l_paren)) {

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Mar 24 06:26:52 2011
@@ -81,7 +81,7 @@
   
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
 
-  ParsedAttributesWithRange attrs;
+  ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX0XAttributes(attrs);
 
   // Cases in this switch statement should fall through if the parser expects
@@ -500,7 +500,7 @@
       ConsumeToken();
     }
     
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     DeclGroupPtrTy Res = Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
                                       DeclsInGroup.data(), DeclsInGroup.size());
     StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
@@ -528,7 +528,7 @@
       while (Tok.is(tok::kw___extension__))
         ConsumeToken();
 
-      ParsedAttributesWithRange attrs;
+      ParsedAttributesWithRange attrs(AttrFactory);
       MaybeParseCXX0XAttributes(attrs);
 
       // If this is the start of a declaration, parse it as such.
@@ -1049,7 +1049,7 @@
     if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
       Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
 
-    ParsedAttributesWithRange attrs;
+    ParsedAttributesWithRange attrs(AttrFactory);
     MaybeParseCXX0XAttributes(attrs);
 
     SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
@@ -1359,7 +1359,7 @@
     msAsm = true;
     return FuzzyParseMicrosoftAsmStatement(AsmLoc);
   }
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   SourceLocation Loc = Tok.getLocation();
   ParseTypeQualifierListOpt(DS, true, false);
 
@@ -1643,7 +1643,7 @@
   if (Tok.isNot(tok::l_brace))
     return StmtError(Diag(Tok, diag::err_expected_lbrace));
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
-  ParsedAttributesWithRange attrs;
+  ParsedAttributesWithRange attrs(AttrFactory);
   StmtResult TryBlock(ParseCompoundStatement(attrs));
   if (TryBlock.isInvalid())
     return move(TryBlock);
@@ -1696,7 +1696,7 @@
   // without default arguments.
   Decl *ExceptionDecl = 0;
   if (Tok.isNot(tok::ellipsis)) {
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     if (ParseCXXTypeSpecifierSeq(DS))
       return StmtError();
     Declarator ExDecl(DS, Declarator::CXXCatchContext);
@@ -1712,7 +1712,7 @@
     return StmtError(Diag(Tok, diag::err_expected_lbrace));
 
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
-  ParsedAttributes attrs;
+  ParsedAttributes attrs(AttrFactory);
   StmtResult Block(ParseCompoundStatement(attrs));
   if (Block.isInvalid())
     return move(Block);

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Thu Mar 24 06:26:52 2011
@@ -196,7 +196,7 @@
     return 0;
   }
 
-  ParsedAttributesWithRange prefixAttrs;
+  ParsedAttributesWithRange prefixAttrs(AttrFactory);
   MaybeParseCXX0XAttributes(prefixAttrs);
 
   if (Tok.is(tok::kw_using))
@@ -205,7 +205,7 @@
 
   // Parse the declaration specifiers, stealing the accumulated
   // diagnostics from the template parameters.
-  ParsingDeclSpec DS(DiagsFromTParams);
+  ParsingDeclSpec DS(*this, &DiagsFromTParams);
 
   DS.takeAttributesFrom(prefixAttrs);
 
@@ -598,7 +598,7 @@
   // Parse the declaration-specifiers (i.e., the type).
   // FIXME: The type should probably be restricted in some way... Not all
   // declarators (parts of declarators?) are accepted for parameters.
-  DeclSpec DS;
+  DeclSpec DS(AttrFactory);
   ParseDeclarationSpecifiers(DS);
 
   // Parse this as a typename.

Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Thu Mar 24 06:26:52 2011
@@ -1151,7 +1151,7 @@
       return TPResult::True(); // '...' is a sign of a function declarator.
     }
 
-    ParsedAttributes attrs;
+    ParsedAttributes attrs(AttrFactory);
     MaybeParseMicrosoftAttributes(attrs);
 
     // decl-specifier-seq

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Mar 24 06:26:52 2011
@@ -441,7 +441,7 @@
     return true;
   }
 
-  ParsedAttributesWithRange attrs;
+  ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX0XAttributes(attrs);
   MaybeParseMicrosoftAttributes(attrs);
   
@@ -839,7 +839,7 @@
     SourceLocation DSStart = Tok.getLocation();
 
     // Parse the common declaration-specifiers piece.
-    DeclSpec DS;
+    DeclSpec DS(AttrFactory);
     ParseDeclarationSpecifiers(DS);
 
     // C99 6.9.1p6: 'each declaration in the declaration list shall have at

Modified: cfe/trunk/lib/Sema/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AttributeList.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AttributeList.cpp (original)
+++ cfe/trunk/lib/Sema/AttributeList.cpp Thu Mar 24 06:26:52 2011
@@ -12,46 +12,89 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/AttributeList.h"
+#include "clang/AST/Expr.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/StringSwitch.h"
 using namespace clang;
 
-AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
-                             IdentifierInfo *aName, SourceLocation aLoc,
-                             IdentifierInfo *sName, SourceLocation sLoc,
-                             IdentifierInfo *pName, SourceLocation pLoc,
-                             Expr **ExprList, unsigned numArgs,
-                             bool declspec, bool cxx0x)
-  : AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
-    ScopeLoc(sLoc),
-    ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(0),
-    DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
-
-  if (numArgs == 0)
-    Args = 0;
-  else {
-    // Allocate the Args array using the BumpPtrAllocator.
-    Args = Alloc.Allocate<Expr*>(numArgs);
-    memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
+size_t AttributeList::allocated_size() const {
+  if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
+  return (sizeof(AttributeList) + NumArgs * sizeof(Expr*));
+}
+
+AttributeFactory::AttributeFactory() {
+  // Go ahead and configure all the inline capacity.  This is just a memset.
+  FreeLists.resize(InlineFreeListsCapacity);
+}
+AttributeFactory::~AttributeFactory() {}
+
+static size_t getFreeListIndexForSize(size_t size) {
+  assert(size >= sizeof(AttributeList));
+  assert((size % sizeof(void*)) == 0);
+  return ((size - sizeof(AttributeList)) / sizeof(void*));
+}
+
+void *AttributeFactory::allocate(size_t size) {
+  // Check for a previously reclaimed attribute.
+  size_t index = getFreeListIndexForSize(size);
+  if (index < FreeLists.size()) {
+    if (AttributeList *attr = FreeLists[index]) {
+      FreeLists[index] = attr->NextInPool;
+      return attr;
+    }
+  }
+
+  // Otherwise, allocate something new.
+  return Alloc.Allocate(size, llvm::AlignOf<AttributeFactory>::Alignment);
+}
+
+void AttributeFactory::reclaimPool(AttributeList *cur) {
+  assert(cur && "reclaiming empty pool!");
+  do {
+    // Read this here, because we're going to overwrite NextInPool
+    // when we toss 'cur' into the appropriate queue.
+    AttributeList *next = cur->NextInPool;
+
+    size_t size = cur->allocated_size();
+    size_t freeListIndex = getFreeListIndexForSize(size);
+
+    // Expand FreeLists to the appropriate size, if required.
+    if (freeListIndex >= FreeLists.size())
+      FreeLists.resize(freeListIndex+1);
+
+    // Add 'cur' to the appropriate free-list.
+    cur->NextInPool = FreeLists[freeListIndex];
+    FreeLists[freeListIndex] = cur;
+    
+    cur = next;
+  } while (cur);
+}
+
+void AttributePool::takePool(AttributeList *pool) {
+  assert(pool);
+
+  // Fast path:  this pool is empty.
+  if (!Head) {
+    Head = pool;
+    return;
   }
+
+  // Reverse the pool onto the current head.  This optimizes for the
+  // pattern of pulling a lot of pools into a single pool.
+  do {
+    AttributeList *next = pool->NextInPool;
+    pool->NextInPool = Head;
+    Head = pool;
+    pool = next;
+  } while (pool);
 }
 
-AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
-                             IdentifierInfo *AttrName, SourceLocation AttrLoc,
-                             IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
-                             IdentifierInfo *ParmName, SourceLocation ParmLoc,
-                             const AvailabilityChange &Introduced,
-                             const AvailabilityChange &Deprecated,
-                             const AvailabilityChange &Obsoleted,
-                             bool declspec, bool cxx0x)
-  : AttrName(AttrName), AttrLoc(AttrLoc), ScopeName(ScopeName), 
-    ScopeLoc(ScopeLoc), ParmName(ParmName), ParmLoc(ParmLoc), 
-    Args(0), NumArgs(0), Next(0),
-    DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), 
-    AvailabilityIntroduced(Introduced),
-    AvailabilityDeprecated(Deprecated),
-    AvailabilityObsoleted(Obsoleted),
-    Invalid(false) {
+AttributeList *
+AttributePool::createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
+                                      SourceLocation TokLoc, int Arg) {
+  Expr *IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
+                                      C.IntTy, TokLoc);
+  return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
 }
 
 AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {

Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Thu Mar 24 06:26:52 2011
@@ -134,8 +134,7 @@
 
 /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
 /// "TheDeclarator" is the declarator that this will be added to.
-DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
-                                             bool hasProto, bool isVariadic,
+DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
                                              SourceLocation EllipsisLoc,
                                              ParamInfo *ArgInfo,
                                              unsigned NumArgs,
@@ -157,7 +156,7 @@
   I.Kind                        = Function;
   I.Loc                         = LocalRangeBegin;
   I.EndLoc                      = LocalRangeEnd;
-  I.Fun.AttrList                = attrs.getList();
+  I.Fun.AttrList                = 0;
   I.Fun.hasPrototype            = hasProto;
   I.Fun.isVariadic              = isVariadic;
   I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar 24 06:26:52 2011
@@ -5502,7 +5502,8 @@
 
         // Implicitly declare the argument as type 'int' for lack of a better
         // type.
-        DeclSpec DS;
+        AttributeFactory attrs;
+        DeclSpec DS(attrs);
         const char* PrevSpec; // unused
         unsigned DiagID; // unused
         DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
@@ -5838,17 +5839,18 @@
 
   // Set a Declarator for the implicit definition: int foo();
   const char *Dummy;
-  DeclSpec DS;
+  AttributeFactory attrFactory;
+  DeclSpec DS(attrFactory);
   unsigned DiagID;
   bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
   (void)Error; // Silence warning.
   assert(!Error && "Error setting up implicit decl!");
   Declarator D(DS, Declarator::BlockContext);
-  D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
-                                             false, false, SourceLocation(), 0,
+  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
                                              0, 0, true, SourceLocation(),
                                              EST_None, SourceLocation(),
                                              0, 0, 0, 0, Loc, Loc, D),
+                DS.getAttributes(),
                 SourceLocation());
   D.SetIdentifier(&II, Loc);
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=128209&r1=128208&r2=128209&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Mar 24 06:26:52 2011
@@ -536,7 +536,6 @@
 
   // ...and *prepend* it to the declarator.
   declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction(
-                             ParsedAttributes(),
                              /*proto*/ true,
                              /*variadic*/ false, SourceLocation(),
                              /*args*/ 0, 0,





More information about the cfe-commits mailing list