[cfe-commits] r111455 - in /cfe/trunk: include/clang/ include/clang/AST/ include/clang/Basic/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/Checker/ lib/CodeGen/ lib/Sema/ lib/Serialization/ tools/libclang/

Sean Hunt rideau3 at gmail.com
Wed Aug 18 16:23:40 PDT 2010


Author: coppro
Date: Wed Aug 18 18:23:40 2010
New Revision: 111455

URL: http://llvm.org/viewvc/llvm-project?rev=111455&view=rev
Log:
Generate Attr subclasses with TableGen.

Now all classes derived from Attr are generated from TableGen.
Additionally, Attr* is no longer its own linked list; SmallVectors or
Attr* are used. The accompanying LLVM commit contains the updates to
TableGen necessary for this.

Some other notes about newly-generated attribute classes:

 - The constructor arguments are a SourceLocation and a Context&,
   followed by the attributes arguments in the order that they were
   defined in Attr.td

 - Every argument in Attr.td has an appropriate accessor named getFoo,
   and there are sometimes a few extra ones (such as to get the length
   of a variadic argument).

Additionally, specific_attr_iterator has been introduced, which will
iterate over an AttrVec, but only over attributes of a certain type. It
can be accessed through either Decl::specific_attr_begin/end or
the global functions of the same name.

Added:
    cfe/trunk/include/clang/Serialization/CMakeLists.txt
    cfe/trunk/include/clang/Serialization/Makefile
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/include/clang/AST/CMakeLists.txt
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/AST/Makefile
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/CMakeLists.txt
    cfe/trunk/include/clang/Makefile
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/PCHReader.h
    cfe/trunk/include/clang/Serialization/PCHWriter.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/AttrImpl.cpp
    cfe/trunk/lib/AST/CMakeLists.txt
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/Checker/MallocChecker.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/TargetAttributesSema.cpp
    cfe/trunk/lib/Serialization/CMakeLists.txt
    cfe/trunk/lib/Serialization/PCHReaderDecl.cpp
    cfe/trunk/lib/Serialization/PCHWriter.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Aug 18 18:23:40 2010
@@ -18,7 +18,6 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/PartialDiagnostic.h"
-#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/PrettyPrinter.h"
@@ -199,7 +198,7 @@
   ///
   /// Since so few decls have attrs, we keep them in a hash map instead of
   /// wasting space in the Decl class.
-  llvm::DenseMap<const Decl*, Attr*> DeclAttrs;
+  llvm::DenseMap<const Decl*, AttrVec> DeclAttrs;
 
   /// \brief Keeps track of the static data member templates from which
   /// static data members of class template specializations were instantiated.
@@ -322,7 +321,7 @@
   }
 
   /// \brief Retrieve the attributes for the given declaration.
-  Attr*& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
+  AttrVec& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
 
   /// \brief Erase the attributes corresponding to the given declaration.
   void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); }

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Wed Aug 18 18:23:40 2010
@@ -15,9 +15,11 @@
 #define LLVM_CLANG_AST_ATTR_H
 
 #include "llvm/Support/Casting.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "clang/Basic/AttrKinds.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
 #include <cassert>
 #include <cstring>
 #include <algorithm>
@@ -29,25 +31,33 @@
   class ObjCInterfaceDecl;
   class Expr;
   class QualType;
+  class FunctionDecl;
+  class TypeSourceInfo;
 }
 
 // Defined in ASTContext.h
 void *operator new(size_t Bytes, clang::ASTContext &C,
                    size_t Alignment = 16) throw ();
+// FIXME: Being forced to not have a default argument here due to redeclaration
+//        rules on default arguments sucks
+void *operator new[](size_t Bytes, clang::ASTContext &C,
+                     size_t Alignment) throw ();
 
 // It is good practice to pair new/delete operators.  Also, MSVC gives many
 // warnings if a matching delete overload is not declared, even though the
 // throw() spec guarantees it will not be implicitly called.
 void operator delete(void *Ptr, clang::ASTContext &C, size_t)
               throw ();
+void operator delete[](void *Ptr, clang::ASTContext &C, size_t)
+              throw ();
 
 namespace clang {
 
 /// Attr - This represents one attribute.
 class Attr {
 private:
-  Attr *Next;
-  attr::Kind AttrKind;
+  SourceLocation Loc;
+  unsigned AttrKind : 16;
   bool Inherited : 1;
 
 protected:
@@ -61,38 +71,36 @@
     assert(0 && "Attrs cannot be released with regular 'delete'.");
   }
 
+public:
+  // Forward so that the regular new and delete do not hide global ones.
+  void* operator new(size_t Bytes, ASTContext &C,
+                     size_t Alignment = 16) throw() {
+    return ::operator new(Bytes, C, Alignment);
+  }
+  void operator delete(void *Ptr, ASTContext &C,
+                       size_t Alignment = 16) throw() {
+    return ::operator delete(Ptr, C, Alignment);
+  }
+
 protected:
-  Attr(attr::Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
-  
+  Attr(attr::Kind AK, SourceLocation L)
+    : Loc(L), AttrKind(AK) {}
+
 public:
 
   /// \brief Whether this attribute should be merged to new
   /// declarations.
   virtual bool isMerged() const { return true; }
 
-  attr::Kind getKind() const { return AttrKind; }
-
-  Attr *getNext() { return Next; }
-  const Attr *getNext() const { return Next; }
-  void setNext(Attr *next) { Next = next; }
-
-  template<typename T> const T *getNext() const {
-    for (const Attr *attr = getNext(); attr; attr = attr->getNext())
-      if (const T *V = dyn_cast<T>(attr))
-        return V;
-    return 0;
+  attr::Kind getKind() const {
+    return static_cast<attr::Kind>(AttrKind);
   }
 
-  bool isInherited() const { return Inherited; }
-  void setInherited(bool value) { Inherited = value; }
-
-  void addAttr(Attr *attr) {
-    assert((attr != 0) && "addAttr(): attr is null");
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
 
-    // FIXME: This doesn't preserve the order in any way.
-    attr->Next = Next;
-    Next = attr;
-  }
+  bool isInherited() const { return Inherited; }
+  void setInherited(bool I) { Inherited = I; }
 
   // Clone this attribute.
   virtual Attr* clone(ASTContext &C) const = 0;
@@ -102,591 +110,112 @@
 };
 
 #include "clang/AST/Attrs.inc"
-  
-class AttrWithString : public Attr {
-private:
-  const char *Str;
-  unsigned StrLen;
-protected:
-  AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s);
-  llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
-  void ReplaceString(ASTContext &C, llvm::StringRef newS);
-};
-
-#define DEF_SIMPLE_ATTR(ATTR)                                           \
-class ATTR##Attr : public Attr {                                        \
-public:                                                                 \
-  ATTR##Attr() : Attr(attr::ATTR) {}                                          \
-  virtual Attr *clone(ASTContext &C) const;                             \
-  static bool classof(const Attr *A) { return A->getKind() == attr::ATTR; }   \
-  static bool classof(const ATTR##Attr *A) { return true; }             \
-}
-
-DEF_SIMPLE_ATTR(Packed);
 
-/// \brief Attribute for specifying a maximum field alignment; this is only
-/// valid on record decls.
-class MaxFieldAlignmentAttr : public Attr {
-  unsigned Alignment;
+/// AttrVec - A vector of Attr, which is how they are stored on the AST.
+typedef llvm::SmallVector<Attr*, 2> AttrVec;
+typedef llvm::SmallVector<const Attr*, 2> ConstAttrVec;
 
-public:
-  MaxFieldAlignmentAttr(unsigned alignment)
-    : Attr(attr::MaxFieldAlignment), Alignment(alignment) {}
-
-  /// getAlignment - The specified alignment in bits.
-  unsigned getAlignment() const { return Alignment; }
-
-  virtual Attr* clone(ASTContext &C) const;
+/// DestroyAttrs - Destroy the contents of an AttrVec.
+inline void DestroyAttrs (AttrVec& V, ASTContext &C) {
+}
 
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::MaxFieldAlignment;
+/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
+/// providing attributes that are of a specifc type.
+template <typename SpecificAttr>
+class specific_attr_iterator {
+  /// Current - The current, underlying iterator.
+  /// In order to ensure we don't dereference an invalid iterator unless
+  /// specifically requested, we don't necessarily advance this all the
+  /// way. Instead, we advance it when an operation is requested; if the
+  /// operation is acting on what should be a past-the-end iterator,
+  /// then we offer no guarantees, but this way we do not dererence a
+  /// past-the-end iterator when we move to a past-the-end position.
+  mutable AttrVec::const_iterator Current;
+
+  void AdvanceToNext() const {
+    while (!llvm::isa<SpecificAttr>(*Current))
+      ++Current;
+  }
+
+  void AdvanceToNext(AttrVec::const_iterator I) const {
+    while (Current != I && !llvm::isa<SpecificAttr>(*Current))
+      ++Current;
   }
-  static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
-};
 
-DEF_SIMPLE_ATTR(AlignMac68k);
-
-/// \brief Atribute for specifying the alignment of a variable or type.
-///
-/// This node will either contain the precise Alignment (in bits, not bytes!)
-/// or will contain the expression for the alignment attribute in the case of
-/// a dependent expression within a class or function template. At template
-/// instantiation time these are transformed into concrete attributes.
-class AlignedAttr : public Attr {
-  unsigned Alignment;
-  Expr *AlignmentExpr;
 public:
-  AlignedAttr(unsigned alignment)
-    : Attr(attr::Aligned), Alignment(alignment), AlignmentExpr(0) {}
-  AlignedAttr(Expr *E)
-    : Attr(attr::Aligned), Alignment(0), AlignmentExpr(E) {}
-
-  /// getAlignmentExpr - Get a dependent alignment expression if one is present.
-  Expr *getAlignmentExpr() const {
-    return AlignmentExpr;
-  }
-
-  /// isDependent - Is the alignment a dependent expression
-  bool isDependent() const {
-    return getAlignmentExpr();
-  }
-
-  /// getAlignment - The specified alignment in bits. Requires !isDependent().
-  unsigned getAlignment() const {
-    assert(!isDependent() && "Cannot get a value dependent alignment");
-    return Alignment;
-  }
-
-  /// getMaxAlignment - Get the maximum alignment of attributes on this list.
-  unsigned getMaxAlignment() const {
-    const AlignedAttr *Next = getNext<AlignedAttr>();
-    if (Next)
-      return std::max(Next->getMaxAlignment(), getAlignment());
+  typedef SpecificAttr*             value_type;
+  typedef SpecificAttr*             reference;
+  typedef SpecificAttr*             pointer;
+  typedef std::forward_iterator_tag iterator_category;
+  typedef std::ptrdiff_t            difference_type;
+
+  specific_attr_iterator() : Current() { }
+  explicit specific_attr_iterator(AttrVec::const_iterator i) : Current(i) { }
+
+  reference operator*() const {
+    AdvanceToNext();
+    return llvm::cast<SpecificAttr>(*Current);
+  }
+  pointer operator->() const {
+    AdvanceToNext();
+    return llvm::cast<SpecificAttr>(*Current);
+  }
+
+  specific_attr_iterator& operator++() {
+    ++Current;
+    return *this;
+  }
+  specific_attr_iterator operator++(int) {
+    specific_attr_iterator Tmp(*this);
+    ++(*this);
+    return Tmp;
+  }
+
+  friend bool operator==(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    if (Left.Current < Right.Current)
+      Left.AdvanceToNext(Right.Current); 
     else
-      return getAlignment();
-  }
-
-  virtual Attr* clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::Aligned;
-  }
-  static bool classof(const AlignedAttr *A) { return true; }
-};
-
-class AnnotateAttr : public AttrWithString {
-public:
-  AnnotateAttr(ASTContext &C, llvm::StringRef ann)
-    : AttrWithString(attr::Annotate, C, ann) {}
-
-  llvm::StringRef getAnnotation() const { return getString(); }
-
-  virtual Attr* clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::Annotate;
-  }
-  static bool classof(const AnnotateAttr *A) { return true; }
-};
-
-class AsmLabelAttr : public AttrWithString {
-public:
-  AsmLabelAttr(ASTContext &C, llvm::StringRef L)
-    : AttrWithString(attr::AsmLabel, C, L) {}
-
-  llvm::StringRef getLabel() const { return getString(); }
-
-  virtual Attr* clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::AsmLabel;
-  }
-  static bool classof(const AsmLabelAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AlwaysInline);
-
-class AliasAttr : public AttrWithString {
-public:
-  AliasAttr(ASTContext &C, llvm::StringRef aliasee)
-    : AttrWithString(attr::Alias, C, aliasee) {}
-
-  llvm::StringRef getAliasee() const { return getString(); }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
-  static bool classof(const AliasAttr *A) { return true; }
-};
-
-class ConstructorAttr : public Attr {
-  int priority;
-public:
-  ConstructorAttr(int p) : Attr(attr::Constructor), priority(p) {}
-
-  int getPriority() const { return priority; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Constructor; }
-  static bool classof(const ConstructorAttr *A) { return true; }
-};
-
-class DestructorAttr : public Attr {
-  int priority;
-public:
-  DestructorAttr(int p) : Attr(attr::Destructor), priority(p) {}
-
-  int getPriority() const { return priority; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Destructor; }
-  static bool classof(const DestructorAttr *A) { return true; }
-};
-
-class IBOutletAttr : public Attr {
-public:
-  IBOutletAttr() : Attr(attr::IBOutlet) {}
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::IBOutlet;
-  }
-  static bool classof(const IBOutletAttr *A) { return true; }
-};
-
-class IBOutletCollectionAttr : public Attr {
-  QualType QT;
-public:
-  IBOutletCollectionAttr(QualType qt = QualType())
-    : Attr(attr::IBOutletCollection), QT(qt) {}
-
-  QualType getType() const { return QT; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::IBOutletCollection;
+      Right.AdvanceToNext(Left.Current);
+    return Left.Current == Right.Current;
   }
-  static bool classof(const IBOutletCollectionAttr *A) { return true; }
-};
-
-class IBActionAttr : public Attr {
-public:
-  IBActionAttr() : Attr(attr::IBAction) {}
-
-  virtual Attr *clone(ASTContext &C) const;
-
-    // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::IBAction;
-  }
-  static bool classof(const IBActionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AnalyzerNoReturn);
-DEF_SIMPLE_ATTR(Deprecated);
-DEF_SIMPLE_ATTR(GNUInline);
-DEF_SIMPLE_ATTR(Malloc);
-DEF_SIMPLE_ATTR(NoReturn);
-DEF_SIMPLE_ATTR(NoInstrumentFunction);
-
-class SectionAttr : public AttrWithString {
-public:
-  SectionAttr(ASTContext &C, llvm::StringRef N)
-    : AttrWithString(attr::Section, C, N) {}
-
-  llvm::StringRef getName() const { return getString(); }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::Section;
-  }
-  static bool classof(const SectionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(Unavailable);
-DEF_SIMPLE_ATTR(Unused);
-DEF_SIMPLE_ATTR(Used);
-DEF_SIMPLE_ATTR(Weak);
-DEF_SIMPLE_ATTR(WeakImport);
-DEF_SIMPLE_ATTR(WeakRef);
-DEF_SIMPLE_ATTR(NoThrow);
-DEF_SIMPLE_ATTR(Const);
-DEF_SIMPLE_ATTR(Pure);
-
-class NonNullAttr : public Attr {
-  unsigned* ArgNums;
-  unsigned Size;
-public:
-  NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
-
-  typedef const unsigned *iterator;
-  iterator begin() const { return ArgNums; }
-  iterator end() const { return ArgNums + Size; }
-  unsigned size() const { return Size; }
-
-  bool isNonNull(unsigned arg) const {
-    return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
+  friend bool operator!=(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    return !(Left == Right);
   }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
-  static bool classof(const NonNullAttr *A) { return true; }
 };
 
-/// OwnershipAttr
-/// Ownership attributes are used to annotate pointers that own a resource
-/// in order for the analyzer to check correct allocation and deallocation.
-/// There are three attributes, ownership_returns, ownership_holds and
-/// ownership_takes, represented by subclasses of OwnershipAttr
-class OwnershipAttr: public AttrWithString {
- protected:
-  unsigned* ArgNums;
-  unsigned Size;
-public:
-  attr::Kind AKind;
-public:
-  OwnershipAttr(attr::Kind AK, ASTContext &C, unsigned* arg_nums, unsigned size,
-                llvm::StringRef module);
-
-
-  virtual void Destroy(ASTContext &C);
-
-  /// Ownership attributes have a 'module', which is the name of a kind of
-  /// resource that can be checked.
-  /// The Malloc checker uses the module 'malloc'.
-  llvm::StringRef getModule() const {
-    return getString();
-  }
-  void setModule(ASTContext &C, llvm::StringRef module) {
-    ReplaceString(C, module);
-  }
-  bool isModule(const char *m) const {
-    return getModule().equals(m);
-  }
-
-  typedef const unsigned *iterator;
-  iterator begin() const {
-    return ArgNums;
-  }
-  iterator end() const {
-    return ArgNums + Size;
-  }
-  unsigned size() const {
-    return Size;
-  }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A) {
-    switch (A->getKind()) {
-    case attr::OwnershipTakes:
-    case attr::OwnershipHolds:
-    case attr::OwnershipReturns:
-      return true;
-    default:
-      return false;
-    }
-  }
-  static bool classof(const OwnershipAttr *A) {
-    return true;
-  }
-};
-
-class OwnershipTakesAttr: public OwnershipAttr {
-public:
-  OwnershipTakesAttr(ASTContext &C, unsigned* arg_nums, unsigned size,
-                     llvm::StringRef module);
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::OwnershipTakes;
-  }
-  static bool classof(const OwnershipTakesAttr *A) {
-    return true;
-  }
-};
-
-class OwnershipHoldsAttr: public OwnershipAttr {
-public:
-  OwnershipHoldsAttr(ASTContext &C, unsigned* arg_nums, unsigned size,
-                     llvm::StringRef module);
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::OwnershipHolds;
-  }
-  static bool classof(const OwnershipHoldsAttr *A) {
-    return true;
-  }
-};
-
-class OwnershipReturnsAttr: public OwnershipAttr {
-public:
-  OwnershipReturnsAttr(ASTContext &C, unsigned* arg_nums, unsigned size,
-                     llvm::StringRef module);
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::OwnershipReturns;
-  }
-  static bool classof(const OwnershipReturnsAttr *A) {
-    return true;
-  }
-};
-
-class FormatAttr : public AttrWithString {
-  int formatIdx, firstArg;
-public:
-  FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
-    : AttrWithString(attr::Format, C, type), formatIdx(idx), firstArg(first) {}
-
-  llvm::StringRef getType() const { return getString(); }
-  void setType(ASTContext &C, llvm::StringRef type);
-  int getFormatIdx() const { return formatIdx; }
-  int getFirstArg() const { return firstArg; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
-  static bool classof(const FormatAttr *A) { return true; }
-};
-
-class FormatArgAttr : public Attr {
-  int formatIdx;
-public:
-  FormatArgAttr(int idx) : Attr(attr::FormatArg), formatIdx(idx) {}
-  int getFormatIdx() const { return formatIdx; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
-  static bool classof(const FormatArgAttr *A) { return true; }
-};
-
-class SentinelAttr : public Attr {
-  int sentinel, NullPos;
-public:
-  SentinelAttr(int sentinel_val, int nullPos) : Attr(attr::Sentinel),
-               sentinel(sentinel_val), NullPos(nullPos) {}
-  int getSentinel() const { return sentinel; }
-  int getNullPos() const { return NullPos; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
-  static bool classof(const SentinelAttr *A) { return true; }
-};
-
-class VisibilityAttr : public Attr {
-public:
-  /// @brief An enumeration for the kinds of visibility of symbols.
-  enum VisibilityTypes {
-    DefaultVisibility = 0,
-    HiddenVisibility,
-    ProtectedVisibility
-  };
-private:
-  VisibilityTypes VisibilityType;
-  bool FromPragma;
-public:
-  VisibilityAttr(VisibilityTypes v, bool fp) : Attr(attr::Visibility),
-                 VisibilityType(v), FromPragma(fp) {}
-
-  VisibilityTypes getVisibility() const { return VisibilityType; }
-
-  bool isFromPragma() const { return FromPragma; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Visibility; }
-  static bool classof(const VisibilityAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(FastCall);
-DEF_SIMPLE_ATTR(StdCall);
-DEF_SIMPLE_ATTR(ThisCall);
-DEF_SIMPLE_ATTR(CDecl);
-DEF_SIMPLE_ATTR(TransparentUnion);
-DEF_SIMPLE_ATTR(ObjCNSObject);
-DEF_SIMPLE_ATTR(ObjCException);
-
-class OverloadableAttr : public Attr {
-public:
-  OverloadableAttr() : Attr(attr::Overloadable) { }
-
-  virtual bool isMerged() const { return false; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::Overloadable; }
-  static bool classof(const OverloadableAttr *) { return true; }
-};
-
-class BlocksAttr : public Attr {
-public:
-  enum BlocksAttrTypes {
-    ByRef = 0
-  };
-private:
-  BlocksAttrTypes BlocksAttrType;
-public:
-  BlocksAttr(BlocksAttrTypes t) : Attr(attr::Blocks), BlocksAttrType(t) {}
-
-  BlocksAttrTypes getType() const { return BlocksAttrType; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
-  static bool classof(const BlocksAttr *A) { return true; }
-};
-
-class FunctionDecl;
-
-class CleanupAttr : public Attr {
-  FunctionDecl *FD;
-
-public:
-  CleanupAttr(FunctionDecl *fd) : Attr(attr::Cleanup), FD(fd) {}
-
-  const FunctionDecl *getFunctionDecl() const { return FD; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
-  static bool classof(const CleanupAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(NoDebug);
-DEF_SIMPLE_ATTR(WarnUnusedResult);
-DEF_SIMPLE_ATTR(NoInline);
-
-class RegparmAttr : public Attr {
-  unsigned NumParams;
-
-public:
-  RegparmAttr(unsigned np) : Attr(attr::Regparm), NumParams(np) {}
-
-  unsigned getNumParams() const { return NumParams; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) { return A->getKind() == attr::Regparm; }
-  static bool classof(const RegparmAttr *A) { return true; }
-};
-
-class ReqdWorkGroupSizeAttr : public Attr {
-  unsigned X, Y, Z;
-public:
-  ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
-  : Attr(attr::ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
-
-  unsigned getXDim() const { return X; }
-  unsigned getYDim() const { return Y; }
-  unsigned getZDim() const { return Z; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    return A->getKind() == attr::ReqdWorkGroupSize;
-  }
-  static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
-};
-
-class InitPriorityAttr : public Attr {
-  unsigned Priority;
-public:
-  InitPriorityAttr(unsigned priority) 
-    : Attr(attr::InitPriority),  Priority(priority) {}
-    
-  unsigned getPriority() const { return Priority; }
-    
-  virtual Attr *clone(ASTContext &C) const;
-    
-  static bool classof(const Attr *A) 
-    { return A->getKind() == attr::InitPriority; }
-  static bool classof(const InitPriorityAttr *A) { return true; }
-};
-  
-// Checker-specific attributes.
-DEF_SIMPLE_ATTR(CFReturnsNotRetained);
-DEF_SIMPLE_ATTR(CFReturnsRetained);
-DEF_SIMPLE_ATTR(NSReturnsNotRetained);
-DEF_SIMPLE_ATTR(NSReturnsRetained);
-
-// Target-specific attributes
-DEF_SIMPLE_ATTR(DLLImport);
-DEF_SIMPLE_ATTR(DLLExport);
-
-class MSP430InterruptAttr : public Attr {
-  unsigned Number;
-
-public:
-  MSP430InterruptAttr(unsigned n) : Attr(attr::MSP430Interrupt), Number(n) {}
-
-  unsigned getNumber() const { return Number; }
-
-  virtual Attr *clone(ASTContext &C) const;
-
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A)
-    { return A->getKind() == attr::MSP430Interrupt; }
-  static bool classof(const MSP430InterruptAttr *A) { return true; }
-};
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) {
+  return specific_attr_iterator<T>(vec.begin());
+}
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) {
+  return specific_attr_iterator<T>(vec.end());
+}
 
-DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+template <typename T>
+inline bool hasSpecificAttr(const AttrVec& vec) {
+  return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec);
+}
+template <typename T>
+inline T *getSpecificAttr(const AttrVec& vec) {
+  specific_attr_iterator<T> i = specific_attr_begin<T>(vec);
+  if (i != specific_attr_end<T>(vec))
+    return *i;
+  else
+    return 0;
+}
 
-#undef DEF_SIMPLE_ATTR
+/// getMaxAlignment - Returns the highest alignment value found among
+/// AlignedAttrs in an AttrVec, or 0 if there are none.
+inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) {
+  unsigned Align = 0;
+  specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end());
+  for(; i != e; ++i)
+    Align = std::max(Align, i->getAlignment(Ctx));
+  return Align;
+}
 
 }  // end namespace clang
 

Modified: cfe/trunk/include/clang/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/AST/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -5,6 +5,12 @@
 add_custom_target(ClangAttrClasses
   DEPENDS Attrs.inc)
 
+tablegen(AttrImpl.inc
+         -gen-clang-attr-impl
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrImpl
+  DEPENDS AttrImpl.inc)
+
 set(LLVM_TARGET_DEFINITIONS ../Basic/StmtNodes.td)
 tablegen(StmtNodes.inc
          -gen-clang-stmt-nodes)

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Aug 18 18:23:40 2010
@@ -308,24 +308,52 @@
   }
 
   bool hasAttrs() const { return HasAttrs; }
-  void initAttrs(Attr *attrs);
-  void addAttr(Attr *attr);
-  const Attr *getAttrs() const {
-    if (!HasAttrs) return 0;  // common case, no attributes.
-    return getAttrsImpl();    // Uncommon case, out of line hash lookup.
+  void setAttrs(const AttrVec& Attrs);
+  AttrVec& getAttrs() {
+    return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
   }
+  const AttrVec &getAttrs() const;
   void swapAttrs(Decl *D);
-  void invalidateAttrs();
+  void dropAttrs();
 
-  template<typename T> const T *getAttr() const {
-    for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
-      if (const T *V = dyn_cast<T>(attr))
-        return V;
-    return 0;
+  void addAttr(Attr *A) {
+    if (hasAttrs())
+      getAttrs().push_back(A);
+    else
+      setAttrs(AttrVec(1, A));
   }
 
+  typedef AttrVec::const_iterator attr_iterator;
+
+  // FIXME: Do not rely on iterators having comparable singular values.
+  //        Note that this should error out if they do not.
+  attr_iterator attr_begin() const {
+    return hasAttrs() ? getAttrs().begin() : 0;
+  }
+  attr_iterator attr_end() const {
+    return hasAttrs() ? getAttrs().end() : 0;
+  }
+
+  template <typename T>
+  specific_attr_iterator<T> specific_attr_begin() const {
+    return specific_attr_iterator<T>(attr_begin());
+  }
+  template <typename T>
+  specific_attr_iterator<T> specific_attr_end() const {
+    return specific_attr_iterator<T>(attr_end());
+  }
+
+  template<typename T> T *getAttr() const {
+    return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : 0;
+  }
   template<typename T> bool hasAttr() const {
-    return getAttr<T>() != 0;
+    return hasAttrs() && hasSpecificAttr<T>(getAttrs());
+  }
+
+  /// getMaxAlignment - return the maximum alignment specified by attributes
+  /// on this decl, 0 if there are none.
+  unsigned getMaxAlignment() const {
+    return hasAttrs() ? getMaxAttrAlignment(getAttrs(), getASTContext()) : 0;
   }
 
   /// setInvalidDecl - Indicates the Decl had a semantic error. This
@@ -346,16 +374,16 @@
   /// (in addition to the "used" bit set by \c setUsed()) when determining
   /// whether the function is used.
   bool isUsed(bool CheckUsedAttr = true) const;
-  
+
   void setUsed(bool U = true) { Used = U; }
 
   /// \brief Retrieve the level of precompiled header from which this
   /// declaration was generated.
   ///
   /// The PCH level of a declaration describes where the declaration originated
-  /// from. A PCH level of 0 indicates that the declaration was not from a 
+  /// from. A PCH level of 0 indicates that the declaration was not from a
   /// precompiled header. A PCH level of 1 indicates that the declaration was
-  /// from a top-level precompiled header; 2 indicates that the declaration 
+  /// from a top-level precompiled header; 2 indicates that the declaration
   /// comes from a precompiled header on which the top-level precompiled header
   /// depends, and so on. 
   unsigned getPCHLevel() const { return PCHLevel; }

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Aug 18 18:23:40 2010
@@ -21,7 +21,6 @@
 class Expr;
 class Stmt;
 class FunctionDecl;
-class AttributeList;
 class RecordDecl;
 class ObjCIvarDecl;
 class ObjCMethodDecl;

Modified: cfe/trunk/include/clang/AST/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Makefile?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Makefile (original)
+++ cfe/trunk/include/clang/AST/Makefile Wed Aug 18 18:23:40 2010
@@ -1,6 +1,6 @@
 CLANG_LEVEL := ../../..
 TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc StmtNodes.inc DeclNodes.inc
+BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
@@ -12,6 +12,12 @@
 	$(Verb) $(TableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
 		-I $(PROJ_SRC_DIR)/../../ $<
 
+$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang attribute implementations with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
 $(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(TBLGEN) \
                               $(ObjDir)/.dir
 	$(Echo) "Building Clang statement node tables with tblgen"

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Aug 18 18:23:40 2010
@@ -33,8 +33,8 @@
 // a possible subject.
 def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
                               [{S->getStorageClass() != VarDecl::Register &&
-                                S->getKind() != Decl::ImplicitParam
-                                S->getKind() != Decl::ParmVar
+                                S->getKind() != Decl::ImplicitParam &&
+                                S->getKind() != Decl::ParmVar &&
                                 S->getKind() != Decl::NonTypeTemplateParm}]>;
 def CXXVirtualMethod : SubsetSubject<CXXRecord, "virtual member function",
                                      [{S->isVirtual()}]>;
@@ -51,18 +51,27 @@
 class StringArgument<string name> : Argument<name>;
 class ExprArgument<string name> : Argument<name>;
 class FunctionArgument<string name> : Argument<name>;
-class ObjCInterfaceArgument<string name> : Argument<name>;
-class UnsignedIntArgument<string name> : Argument<name>;
-class UnsignedIntOrTypeArgument<string name> : Argument<name>;
+class TypeArgument<string name> : Argument<name>;
+class UnsignedArgument<string name> : Argument<name>;
+class VariadicUnsignedArgument<string name> : Argument<name>;
+
+// This one's a doozy, so it gets its own special type
+// It can be an unsigned integer, or a type. Either can
+// be dependent.
+class AlignedArgument<string name> : Argument<name>;
 
 // An integer argument with a default value
 class DefaultIntArgument<string name, int default> : IntArgument<name> {
   int Default = default;
 }
 
-// Zero or more arguments of a type
-class VariadicArgument<Argument arg> : Argument<arg.Name> {
-  Argument VariadicArg = arg;
+// This argument is more complex, it includes the enumerator type name,
+// a list of strings to accept, and a list of enumerators to map them to.
+class EnumArgument<string name, string type, list<string> values,
+                         list<string> enums> : Argument<name> {
+  string Type = type;
+  list<string> Values = values;
+  list<string> Enums = enums;
 }
 
 class Attr {
@@ -76,9 +85,8 @@
   // The attribute will not be permitted in C++0x attribute-specifiers if
   // this is empty; the empty string can be used as a namespace.
   list<string> Namespaces = [];
-  // A temporary development bit to tell TableGen not to emit certain
-  // information about the attribute.
-  bit DoNotEmit = 1;
+  // Any additional text that should be included verbatim in the class.
+  code AdditionalMembers = [{}];
 }
 
 //
@@ -87,13 +95,13 @@
 
 def Alias : Attr {
   let Spellings = ["alias"];
-  let Args = [StringArgument<"AliasName">];
+  let Args = [StringArgument<"Aliasee">];
 }
 
 def Aligned : Attr {
   let Spellings = ["align", "aligned"];
   let Subjects = [NonBitField, NormalVar, Tag];
-  let Args = [UnsignedIntOrTypeArgument<"Alignment">];
+  let Args = [AlignedArgument<"Alignment">];
   let Namespaces = ["", "std"];
 }
 
@@ -123,19 +131,17 @@
   let Spellings = ["base_check"];
   let Subjects = [CXXRecord];
   let Namespaces = ["", "std"];
-  let DoNotEmit = 0;
 }
 
 def Blocks : Attr {
   let Spellings = ["blocks"];
-  let Args = [IdentifierArgument<"Type">];
+  let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
 }
 
 def CarriesDependency : Attr {
   let Spellings = ["carries_dependency"];
   let Subjects = [ParmVar, Function];
   let Namespaces = ["", "std"];
-  let DoNotEmit = 0;
 }
 
 def CDecl : Attr {
@@ -189,7 +195,6 @@
   let Spellings = ["final"];
   let Subjects = [CXXRecord, CXXVirtualMethod];
   let Namespaces = ["", "std"];
-  let DoNotEmit = 0;
 }
 
 def Format : Attr {
@@ -211,7 +216,6 @@
   let Spellings = ["hiding"];
   let Subjects = [Field, CXXMethod];
   let Namespaces = ["", "std"];
-  let DoNotEmit = 0;
 }
 
 def IBAction : Attr {
@@ -224,7 +228,7 @@
 
 def IBOutletCollection : Attr {
   let Spellings = ["iboutletcollection"];
-  let Args = [ObjCInterfaceArgument<"Class">];
+  let Args = [TypeArgument<"Interface">];
 }
 
 def Malloc : Attr {
@@ -233,12 +237,12 @@
 
 def MaxFieldAlignment : Attr {
   let Spellings = [];
-  let Args = [UnsignedIntArgument<"Alignment">];
+  let Args = [UnsignedArgument<"Alignment">];
 }
 
 def MSP430Interrupt : Attr {
   let Spellings = [];
-  let Args = [UnsignedIntArgument<"Number">];
+  let Args = [UnsignedArgument<"Number">];
 }
 
 def NoDebug : Attr {
@@ -251,7 +255,15 @@
 
 def NonNull : Attr {
   let Spellings = ["nonnull"];
-  let Args = [VariadicArgument<UnsignedIntArgument<"Args">>];
+  let Args = [VariadicUnsignedArgument<"Args">];
+  let AdditionalMembers =
+[{bool isNonNull(unsigned idx) const {
+    for (args_iterator i = args_begin(), e = args_end();
+         i != e; ++i)
+      if (*i == idx)
+        return true;
+    return false;
+  } }];
 }
 
 def NoReturn : Attr {
@@ -290,26 +302,18 @@
   let Spellings = ["override"];
   let Subjects = [CXXVirtualMethod];
   let Namespaces = ["", "std"];
-  let DoNotEmit = 0;
 }
 
 def Overloadable : Attr {
   let Spellings = ["overloadable"];
 }
 
-def OwnershipReturns : Attr {
-  let Spellings = ["ownership_returns"];
-  let Args = [StringArgument<"Module">, IntArgument<"SizeIdx">];
-}
-
-def OwnershipTakes : Attr {
-  let Spellings = ["ownership_takes"];
-  let Args = [StringArgument<"Module">, IntArgument<"PtrIdx">];
-}
-
-def OwnershipHolds : Attr {
-  let Spellings = ["ownership_holds"];
-  let Args = [StringArgument<"Module">, IntArgument<"PtrIdx">];
+def Ownership : Attr {
+  let Spellings = ["ownership_holds", "ownership_returns", "ownership_takes"];
+  let Args = [EnumArgument<"OwnKind", "OwnershipKind",
+                    ["ownership_holds", "ownership_returns", "ownership_takes"],
+                    ["Holds", "Returns", "Takes"]>,
+              StringArgument<"Module">, VariadicUnsignedArgument<"Args">];
 }
 
 def Packed : Attr {
@@ -322,18 +326,18 @@
 
 def Regparm : Attr {
   let Spellings = ["regparm"];
-  let Args = [UnsignedIntArgument<"NumParams">];
+  let Args = [UnsignedArgument<"NumParams">];
 }
 
 def ReqdWorkGroupSize : Attr {
   let Spellings = ["reqd_work_group_size"];
-  let Args = [UnsignedIntArgument<"XDim">, UnsignedIntArgument<"YDim">,
-              UnsignedIntArgument<"ZDim">];
+  let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
+              UnsignedArgument<"ZDim">];
 }
 
 def InitPriority : Attr {
   let Spellings = ["init_priority"];
-  let Args = [UnsignedIntArgument<"Priority">];
+  let Args = [UnsignedArgument<"Priority">];
 }
 
 def Section : Attr {
@@ -343,8 +347,8 @@
 
 def Sentinel : Attr {
   let Spellings = ["sentinel"];
-  let Args = [DefaultIntArgument<"NulPos", 0>,
-              DefaultIntArgument<"Sentinel", 0>];
+  let Args = [DefaultIntArgument<"Sentinel", 0>,
+              DefaultIntArgument<"NullPos", 0>];
 }
 
 def StdCall : Attr {
@@ -373,13 +377,14 @@
 
 def Visibility : Attr {
   let Spellings = ["visibility"];
-  let Args = [StringArgument<"Visibility">];
+  let Args = [EnumArgument<"Visibility", "VisibilityType",
+                           ["default", "hidden", "internal", "protected"],
+                           ["Default", "Hidden", "Hidden", "Protected"]>];
 }
 
 def VecReturn : Attr {
   let Spellings = ["vecreturn"];
   let Subjects = [CXXRecord];
-  let DoNotEmit = 0;
 }
 
 def WarnUnusedResult : Attr {

Modified: cfe/trunk/include/clang/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -1,3 +1,4 @@
 add_subdirectory(AST)
 add_subdirectory(Basic)
 add_subdirectory(Driver)
+add_subdirectory(Serialization)

Modified: cfe/trunk/include/clang/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Makefile?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Makefile (original)
+++ cfe/trunk/include/clang/Makefile Wed Aug 18 18:23:40 2010
@@ -1,5 +1,5 @@
 CLANG_LEVEL := ../..
-DIRS := AST Basic Driver
+DIRS := AST Basic Driver Serialization
 
 include $(CLANG_LEVEL)/Makefile
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Aug 18 18:23:40 2010
@@ -4265,7 +4265,8 @@
 
   /// PushPragmaVisibility - Push the top element of the visibility stack; used
   ///  for '#pragma GCC visibility' and visibility attributes on namespaces.
-  void PushPragmaVisibility(VisibilityAttr::VisibilityTypes type);
+  void PushPragmaVisibility(VisibilityAttr::VisibilityType type,
+                            SourceLocation loc);
 
   /// PopPragmaVisibility - Pop the top element of the visibility stack; used
   /// for '#pragma GCC visibility' and visibility attributes on namespaces.
@@ -4276,6 +4277,7 @@
 
   /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
   void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E);
+  void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *T);
 
   /// CastCategory - Get the correct forwarded implicit cast result category
   /// from the inner expression.

Added: cfe/trunk/include/clang/Serialization/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/CMakeLists.txt?rev=111455&view=auto
==============================================================================
--- cfe/trunk/include/clang/Serialization/CMakeLists.txt (added)
+++ cfe/trunk/include/clang/Serialization/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -0,0 +1,12 @@
+set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td)
+tablegen(AttrPCHRead.inc
+         -gen-clang-attr-pch-read
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrPCHRead
+  DEPENDS AttrPCHRead.inc)
+
+tablegen(AttrPCHWrite.inc
+         -gen-clang-attr-pch-write
+         -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrPCHWrite
+  DEPENDS AttrPCHWrite.inc)

Added: cfe/trunk/include/clang/Serialization/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Makefile?rev=111455&view=auto
==============================================================================
--- cfe/trunk/include/clang/Serialization/Makefile (added)
+++ cfe/trunk/include/clang/Serialization/Makefile Wed Aug 18 18:23:40 2010
@@ -0,0 +1,19 @@
+CLANG_LEVEL := ../../..
+TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
+BUILT_SOURCES = AttrPCHRead.inc AttrPCHWrite.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(CLANG_LEVEL)/Makefile
+
+$(ObjDir)/AttrPCHRead.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang PCH reader with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-pch-read -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
+$(ObjDir)/AttrPCHWrite.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+                              $(ObjDir)/.dir
+	$(Echo) "Building Clang PCH writer with tblgen"
+	$(Verb) $(TableGen) -gen-clang-attr-pch-write -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<

Modified: cfe/trunk/include/clang/Serialization/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/PCHReader.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/PCHReader.h (original)
+++ cfe/trunk/include/clang/Serialization/PCHReader.h Wed Aug 18 18:23:40 2010
@@ -908,7 +908,7 @@
   CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx);
       
   /// \brief Reads attributes from the current stream position.
-  Attr *ReadAttributes(llvm::BitstreamCursor &DeclsCursor);
+  void ReadAttributes(llvm::BitstreamCursor &DeclsCursor, AttrVec &Attrs);
 
   /// \brief Reads a statement.
   Stmt *ReadStmt(llvm::BitstreamCursor &Cursor);

Modified: cfe/trunk/include/clang/Serialization/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/PCHWriter.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/PCHWriter.h Wed Aug 18 18:23:40 2010
@@ -281,7 +281,7 @@
   void WriteSelectors(Sema &SemaRef);
   void WriteReferencedSelectorsPool(Sema &SemaRef);
   void WriteIdentifierTable(Preprocessor &PP);
-  void WriteAttributeRecord(const Attr *Attr);
+  void WriteAttributeRecord(const AttrVec &Attrs);
   void WriteDeclUpdateBlock();
 
   unsigned ParmVarDeclAbbrev;

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug 18 18:23:40 2010
@@ -497,8 +497,7 @@
 CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) {
   unsigned Align = Target.getCharWidth();
 
-  if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
-    Align = std::max(Align, AA->getMaxAlignment());
+  Align = std::max(Align, D->getMaxAlignment());
 
   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
     QualType T = VD->getType();
@@ -760,12 +759,9 @@
 
   case Type::Typedef: {
     const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
-    if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
-      Align = std::max(Aligned->getMaxAlignment(),
-                       getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
-      Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
-    } else
-      return getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
+    Align = std::max(Typedef->getMaxAlignment(),
+                     getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
+    Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
     break;
   }
 

Modified: cfe/trunk/lib/AST/AttrImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/AttrImpl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/AttrImpl.cpp (original)
+++ cfe/trunk/lib/AST/AttrImpl.cpp Wed Aug 18 18:23:40 2010
@@ -13,231 +13,10 @@
 
 #include "clang/AST/Attr.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Expr.h"
 using namespace clang;
 
 Attr::~Attr() { }
 
-AttrWithString::AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s)
-  : Attr(AK) {
-  assert(!s.empty());
-  StrLen = s.size();
-  Str = new (C) char[StrLen];
-  memcpy(const_cast<char*>(Str), s.data(), StrLen);
-}
-
-void AttrWithString::ReplaceString(ASTContext &C, llvm::StringRef newS) {
-  if (newS.size() > StrLen) {
-    C.Deallocate(const_cast<char*>(Str));
-    Str = new (C) char[newS.size()];
-  }
-  StrLen = newS.size();
-  memcpy(const_cast<char*>(Str), newS.data(), StrLen);
-}
-
-void FormatAttr::setType(ASTContext &C, llvm::StringRef type) {
-  ReplaceString(C, type);
-}
-
-NonNullAttr::NonNullAttr(ASTContext &C, unsigned* arg_nums, unsigned size)
-  : Attr(attr::NonNull), ArgNums(0), Size(0) {
-  if (size == 0)
-    return;
-  assert(arg_nums);
-  ArgNums = new (C) unsigned[size];
-  Size = size;
-  memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
-}
-
-OwnershipAttr::OwnershipAttr(attr::Kind AK, ASTContext &C, unsigned* arg_nums,
-                             unsigned size, llvm::StringRef module)
-  : AttrWithString(AK, C, module), ArgNums(0), Size(0) {
-  if (size == 0)
-    return;
-  assert(arg_nums);
-  ArgNums = new (C) unsigned[size];
-  Size = size;
-  memcpy(ArgNums, arg_nums, sizeof(*ArgNums) * size);
-}
-
-
-void OwnershipAttr::Destroy(ASTContext &C) {
-  if (ArgNums)
-    C.Deallocate(ArgNums);
-}
-
-OwnershipTakesAttr::OwnershipTakesAttr(ASTContext &C, unsigned* arg_nums,
-                                       unsigned size, llvm::StringRef module)
-  : OwnershipAttr(attr::OwnershipTakes, C, arg_nums, size, module) {
-}
-
-OwnershipHoldsAttr::OwnershipHoldsAttr(ASTContext &C, unsigned* arg_nums,
-                                       unsigned size, llvm::StringRef module)
-  : OwnershipAttr(attr::OwnershipHolds, C, arg_nums, size, module) {
-}
-
-OwnershipReturnsAttr::OwnershipReturnsAttr(ASTContext &C, unsigned* arg_nums,
-                                           unsigned size,
-                                           llvm::StringRef module)
-  : OwnershipAttr(attr::OwnershipReturns, C, arg_nums, size, module) {
-}
-
-#define DEF_SIMPLE_ATTR_CLONE(ATTR)                                     \
-  Attr *ATTR##Attr::clone(ASTContext &C) const {                        \
-    return ::new (C) ATTR##Attr;                                        \
-  }
-
-// FIXME: Can we use variadic macro to define DEF_SIMPLE_ATTR_CLONE for
-// "non-simple" classes?
-
-DEF_SIMPLE_ATTR_CLONE(AlignMac68k)
-DEF_SIMPLE_ATTR_CLONE(AlwaysInline)
-DEF_SIMPLE_ATTR_CLONE(AnalyzerNoReturn)
-DEF_SIMPLE_ATTR_CLONE(BaseCheck)
-DEF_SIMPLE_ATTR_CLONE(CDecl)
-DEF_SIMPLE_ATTR_CLONE(CFReturnsNotRetained)
-DEF_SIMPLE_ATTR_CLONE(CFReturnsRetained)
-DEF_SIMPLE_ATTR_CLONE(Const)
-DEF_SIMPLE_ATTR_CLONE(DLLExport)
-DEF_SIMPLE_ATTR_CLONE(DLLImport)
-DEF_SIMPLE_ATTR_CLONE(Deprecated)
-DEF_SIMPLE_ATTR_CLONE(FastCall)
-DEF_SIMPLE_ATTR_CLONE(Final)
-DEF_SIMPLE_ATTR_CLONE(Hiding)
-DEF_SIMPLE_ATTR_CLONE(Malloc)
-DEF_SIMPLE_ATTR_CLONE(NSReturnsNotRetained)
-DEF_SIMPLE_ATTR_CLONE(NSReturnsRetained)
-DEF_SIMPLE_ATTR_CLONE(NoDebug)
-DEF_SIMPLE_ATTR_CLONE(NoInline)
-DEF_SIMPLE_ATTR_CLONE(NoInstrumentFunction)
-DEF_SIMPLE_ATTR_CLONE(NoReturn)
-DEF_SIMPLE_ATTR_CLONE(NoThrow)
-DEF_SIMPLE_ATTR_CLONE(ObjCException)
-DEF_SIMPLE_ATTR_CLONE(ObjCNSObject)
-DEF_SIMPLE_ATTR_CLONE(Override)
-DEF_SIMPLE_ATTR_CLONE(Packed)
-DEF_SIMPLE_ATTR_CLONE(Pure)
-DEF_SIMPLE_ATTR_CLONE(StdCall)
-DEF_SIMPLE_ATTR_CLONE(ThisCall)
-DEF_SIMPLE_ATTR_CLONE(TransparentUnion)
-DEF_SIMPLE_ATTR_CLONE(Unavailable)
-DEF_SIMPLE_ATTR_CLONE(Unused)
-DEF_SIMPLE_ATTR_CLONE(Used)
-DEF_SIMPLE_ATTR_CLONE(VecReturn)
-DEF_SIMPLE_ATTR_CLONE(WarnUnusedResult)
-DEF_SIMPLE_ATTR_CLONE(Weak)
-DEF_SIMPLE_ATTR_CLONE(WeakImport)
-
-DEF_SIMPLE_ATTR_CLONE(WeakRef)
-DEF_SIMPLE_ATTR_CLONE(X86ForceAlignArgPointer)
-
-Attr* MaxFieldAlignmentAttr::clone(ASTContext &C) const {
-  return ::new (C) MaxFieldAlignmentAttr(Alignment);
-}
-
-Attr* AlignedAttr::clone(ASTContext &C) const {
-  return ::new (C) AlignedAttr(Alignment);
-}
-
-Attr* AnnotateAttr::clone(ASTContext &C) const {
-  return ::new (C) AnnotateAttr(C, getAnnotation());
-}
-
-Attr *AsmLabelAttr::clone(ASTContext &C) const {
-  return ::new (C) AsmLabelAttr(C, getLabel());
-}
-
-Attr *AliasAttr::clone(ASTContext &C) const {
-  return ::new (C) AliasAttr(C, getAliasee());
-}
-
-Attr *ConstructorAttr::clone(ASTContext &C) const {
-  return ::new (C) ConstructorAttr(priority);
-}
-
-Attr *DestructorAttr::clone(ASTContext &C) const {
-  return ::new (C) DestructorAttr(priority);
-}
-
-Attr *IBOutletAttr::clone(ASTContext &C) const {
-  return ::new (C) IBOutletAttr;
-}
-
-Attr *IBOutletCollectionAttr::clone(ASTContext &C) const {
-  return ::new (C) IBOutletCollectionAttr(QT);
-}
-
-Attr *IBActionAttr::clone(ASTContext &C) const {
-  return ::new (C) IBActionAttr;
-}
-
-Attr *GNUInlineAttr::clone(ASTContext &C) const {
-  return ::new (C) GNUInlineAttr;
-}
-
-Attr *SectionAttr::clone(ASTContext &C) const {
-  return ::new (C) SectionAttr(C, getName());
-}
-
-Attr *NonNullAttr::clone(ASTContext &C) const {
-  return ::new (C) NonNullAttr(C, ArgNums, Size);
-}
-
-Attr *OwnershipAttr::clone(ASTContext &C) const {
-  return ::new (C) OwnershipAttr(AKind, C, ArgNums, Size, getModule());
-}
-
-Attr *OwnershipReturnsAttr::clone(ASTContext &C) const {
-  return ::new (C) OwnershipReturnsAttr(C, ArgNums, Size, getModule());
-}
-
-Attr *OwnershipTakesAttr::clone(ASTContext &C) const {
-  return ::new (C) OwnershipTakesAttr(C, ArgNums, Size, getModule());
-}
-
-Attr *OwnershipHoldsAttr::clone(ASTContext &C) const {
-  return ::new (C) OwnershipHoldsAttr(C, ArgNums, Size, getModule());
-}
-
-Attr *FormatAttr::clone(ASTContext &C) const {
-  return ::new (C) FormatAttr(C, getType(), formatIdx, firstArg);
-}
-
-Attr *FormatArgAttr::clone(ASTContext &C) const {
-  return ::new (C) FormatArgAttr(formatIdx);
-}
-
-Attr *SentinelAttr::clone(ASTContext &C) const {
-  return ::new (C) SentinelAttr(sentinel, NullPos);
-}
-
-Attr *VisibilityAttr::clone(ASTContext &C) const {
-  return ::new (C) VisibilityAttr(VisibilityType, FromPragma);
-}
-
-Attr *OverloadableAttr::clone(ASTContext &C) const {
-  return ::new (C) OverloadableAttr;
-}
-
-Attr *BlocksAttr::clone(ASTContext &C) const {
-  return ::new (C) BlocksAttr(BlocksAttrType);
-}
-
-Attr *CleanupAttr::clone(ASTContext &C) const {
-  return ::new (C) CleanupAttr(FD);
-}
-
-Attr *RegparmAttr::clone(ASTContext &C) const {
-  return ::new (C) RegparmAttr(NumParams);
-}
-
-Attr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const {
-  return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z);
-}
-
-Attr *InitPriorityAttr::clone(ASTContext &C) const {
-  return ::new (C) InitPriorityAttr(Priority);
-}
-
-Attr *MSP430InterruptAttr::clone(ASTContext &C) const {
-  return ::new (C) MSP430InterruptAttr(Number);
-}
+#include "clang/AST/AttrImpl.inc"

Modified: cfe/trunk/lib/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CMakeLists.txt (original)
+++ cfe/trunk/lib/AST/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -43,4 +43,4 @@
   )
 
 add_dependencies(clangAST ClangARMNeon ClangAttrClasses ClangAttrList 
-                 ClangDiagnosticAST ClangDeclNodes ClangStmtNodes)
+                 ClangAttrImpl ClangDiagnosticAST ClangDeclNodes ClangStmtNodes)

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Aug 18 18:23:40 2010
@@ -312,35 +312,25 @@
   return 0;
 }
 
-void Decl::initAttrs(Attr *attrs) {
+void Decl::setAttrs(const AttrVec &attrs) {
   assert(!HasAttrs && "Decl already contains attrs.");
 
-  Attr *&AttrBlank = getASTContext().getDeclAttrs(this);
-  assert(AttrBlank == 0 && "HasAttrs was wrong?");
+  AttrVec &AttrBlank = getASTContext().getDeclAttrs(this);
+  assert(AttrBlank.empty() && "HasAttrs was wrong?");
 
   AttrBlank = attrs;
   HasAttrs = true;
 }
 
-void Decl::addAttr(Attr *NewAttr) {
-  Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
-
-  assert(NewAttr->getNext() == 0 && "Chain of attributes will be truncated!");
-  NewAttr->setNext(ExistingAttr);
-  ExistingAttr = NewAttr;
-
-  HasAttrs = true;
-}
-
-void Decl::invalidateAttrs() {
+void Decl::dropAttrs() {
   if (!HasAttrs) return;
 
   HasAttrs = false;
   getASTContext().eraseDeclAttrs(this);
 }
 
-const Attr *Decl::getAttrsImpl() const {
-  assert(HasAttrs && "getAttrs() should verify this!");
+const AttrVec &Decl::getAttrs() const {
+  assert(HasAttrs && "No attrs to get!");
   return getASTContext().getDeclAttrs(this);
 }
 

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed Aug 18 18:23:40 2010
@@ -1123,8 +1123,8 @@
     if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
       MaxFieldAlignment = MFAA->getAlignment();
 
-    if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
-      UpdateAlignment(AA->getMaxAlignment());
+    if (unsigned MaxAlign = D->getMaxAlignment())
+      UpdateAlignment(MaxAlign);
   }
 }
 
@@ -1287,8 +1287,7 @@
 
   if (FieldPacked || !Context.Target.useBitFieldTypeAlignment())
     FieldAlign = 1;
-  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
-    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+  FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
 
   // The maximum field alignment overrides the aligned attribute.
   if (MaxFieldAlignment)
@@ -1357,8 +1356,7 @@
 
   if (FieldPacked)
     FieldAlign = 8;
-  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
-    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+  FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
 
   // The maximum field alignment overrides the aligned attribute.
   if (MaxFieldAlignment)

Modified: cfe/trunk/lib/Checker/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/MallocChecker.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/MallocChecker.cpp (original)
+++ cfe/trunk/lib/Checker/MallocChecker.cpp Wed Aug 18 18:23:40 2010
@@ -176,19 +176,23 @@
   // There can be multiple of these attributes.
   bool rv = false;
   if (FD->hasAttrs()) {
-    for (const Attr *attr = FD->getAttrs(); attr; attr = attr->getNext()) {
-      switch (attr->getKind()) {
-      case attr::OwnershipReturns:
-        MallocMemReturnsAttr(C, CE, cast<OwnershipAttr>(attr));
+    for (specific_attr_iterator<OwnershipAttr>
+                  i = FD->specific_attr_begin<OwnershipAttr>(),
+                  e = FD->specific_attr_end<OwnershipAttr>();
+         i != e; ++i) {
+      switch ((*i)->getOwnKind()) {
+      case OwnershipAttr::Returns: {
+        MallocMemReturnsAttr(C, CE, *i);
         rv = true;
         break;
-      case attr::OwnershipTakes:
-      case attr::OwnershipHolds:
-        FreeMemAttr(C, CE, cast<OwnershipAttr>(attr));
+      }
+      case OwnershipAttr::Takes:
+      case OwnershipAttr::Holds: {
+        FreeMemAttr(C, CE, *i);
         rv = true;
         break;
+      }
       default:
-        // Ignore non-ownership attributes.
         break;
       }
     }
@@ -204,10 +208,10 @@
 
 void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
                                          const OwnershipAttr* Att) {
-  if (!Att->isModule("malloc"))
+  if (Att->getModule() != "malloc")
     return;
 
-  const unsigned *I = Att->begin(), *E = Att->end();
+  OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
   if (I != E) {
     const GRState *state =
         MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
@@ -258,14 +262,15 @@
 
 void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
                                 const OwnershipAttr* Att) {
-  if (!Att->isModule("malloc"))
+  if (Att->getModule() != "malloc")
     return;
 
-  for (const unsigned *I = Att->begin(), *E = Att->end(); I != E; ++I) {
-    const GRState *state =
-        FreeMemAux(C, CE, C.getState(), *I, isa<OwnershipHoldsAttr>(Att));
-  if (state)
-    C.addTransition(state);
+  for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
+       I != E; ++I) {
+    const GRState *state = FreeMemAux(C, CE, C.getState(), *I,
+                                      Att->getOwnKind() == OwnershipAttr::Holds);
+    if (state)
+      C.addTransition(state);
   }
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Aug 18 18:23:40 2010
@@ -150,11 +150,11 @@
   if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
     switch (attr->getVisibility()) {
     default: assert(0 && "Unknown visibility!");
-    case VisibilityAttr::DefaultVisibility:
+    case VisibilityAttr::Default:
       return LangOptions::Default;
-    case VisibilityAttr::HiddenVisibility:
+    case VisibilityAttr::Hidden:
       return LangOptions::Hidden;
-    case VisibilityAttr::ProtectedVisibility:
+    case VisibilityAttr::Protected:
       return LangOptions::Protected;
     }
   }
@@ -461,12 +461,10 @@
   else if (Features.getStackProtectorMode() == LangOptions::SSPReq)
     F->addFnAttr(llvm::Attribute::StackProtectReq);
   
-  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
-    unsigned width = Context.Target.getCharWidth();
-    F->setAlignment(AA->getAlignment() / width);
-    while ((AA = AA->getNext<AlignedAttr>()))
-      F->setAlignment(std::max(F->getAlignment(), AA->getAlignment() / width));
-  }
+  unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
+  if (alignment)
+    F->setAlignment(alignment);
+
   // C++ ABI requires 2-byte alignment for member functions.
   if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
     F->setAlignment(2);

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Wed Aug 18 18:23:40 2010
@@ -14,6 +14,7 @@
 
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
@@ -120,9 +121,11 @@
   // Otherwise, check to see if we need a max field alignment attribute.
   if (unsigned Alignment = Stack->getAlignment()) {
     if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
-      RD->addAttr(::new (Context) AlignMac68kAttr());
+      RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
     else
-      RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
+      RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
+                                                        Context,
+                                                        Alignment * 8));
   }
 }
 
@@ -285,11 +288,12 @@
       continue;
     }
 
-    VD->addAttr(::new (Context) UnusedAttr());
+    VD->addAttr(::new (Context) UnusedAttr(Tok.getLocation(), Context));
   }
 }
 
-typedef std::vector<VisibilityAttr::VisibilityTypes> VisStack;
+typedef std::vector<std::pair<VisibilityAttr::VisibilityType,
+                              SourceLocation> > VisStack;
 
 void Sema::AddPushedVisibilityAttribute(Decl *D) {
   if (!VisContext)
@@ -299,9 +303,10 @@
     return;
 
   VisStack *Stack = static_cast<VisStack*>(VisContext);
-  VisibilityAttr::VisibilityTypes type = Stack->back();
+  VisibilityAttr::VisibilityType type = Stack->back().first;
+  SourceLocation loc = Stack->back().second;
 
-  D->addAttr(::new (Context) VisibilityAttr(type, true));
+  D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
 }
 
 /// FreeVisContext - Deallocate and null out VisContext.
@@ -314,33 +319,34 @@
                                  SourceLocation PragmaLoc) {
   if (IsPush) {
     // Compute visibility to use.
-    VisibilityAttr::VisibilityTypes type;
+    VisibilityAttr::VisibilityType type;
     if (VisType->isStr("default"))
-      type = VisibilityAttr::DefaultVisibility;
+      type = VisibilityAttr::Default;
     else if (VisType->isStr("hidden"))
-      type = VisibilityAttr::HiddenVisibility;
+      type = VisibilityAttr::Hidden;
     else if (VisType->isStr("internal"))
-      type = VisibilityAttr::HiddenVisibility; // FIXME
+      type = VisibilityAttr::Hidden; // FIXME
     else if (VisType->isStr("protected"))
-      type = VisibilityAttr::ProtectedVisibility;
+      type = VisibilityAttr::Protected;
     else {
       Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
         VisType->getName();
       return;
     }
-    PushPragmaVisibility(type);
+    PushPragmaVisibility(type, PragmaLoc);
   } else {
     PopPragmaVisibility();
   }
 }
 
-void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityTypes type) {
+void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityType type,
+                                SourceLocation loc) {
   // Put visibility on stack.
   if (!VisContext)
     VisContext = new VisStack;
 
   VisStack *Stack = static_cast<VisStack*>(VisContext);
-  Stack->push_back(type);
+  Stack->push_back(std::make_pair(type, loc));
 }
 
 void Sema::PopPragmaVisibility() {

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Aug 18 18:23:40 2010
@@ -347,9 +347,12 @@
     }
   }
 
-  for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull;
-       NonNull = NonNull->getNext<NonNullAttr>())
-    CheckNonNullArguments(NonNull, TheCall);
+  specific_attr_iterator<NonNullAttr>
+    i = FDecl->specific_attr_begin<NonNullAttr>(),
+    e = FDecl->specific_attr_end<NonNullAttr>();
+
+  for (; i != e; ++i)
+    CheckNonNullArguments(*i, TheCall);
 
   return false;
 }
@@ -1041,7 +1044,8 @@
 void
 Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
                             const CallExpr *TheCall) {
-  for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end();
+  for (NonNullAttr::args_iterator i = NonNull->args_begin(),
+                                  e = NonNull->args_end();
        i != e; ++i) {
     const Expr *ArgExpr = TheCall->getArg(*i);
     if (ArgExpr->isNullPointerConstant(Context,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Aug 18 18:23:40 2010
@@ -997,19 +997,32 @@
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool
-DeclHasAttr(const Decl *decl, const Attr *target) {
-  for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
-    if (attr->getKind() == target->getKind())
+DeclHasAttr(const Decl *D, const Attr *A) {
+  const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
+  for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
+    if ((*i)->getKind() == A->getKind()) {
+      // FIXME: Don't hardcode this check
+      if (OA && isa<OwnershipAttr>(*i))
+        return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
       return true;
+    }
 
   return false;
 }
 
-/// MergeAttributes - append attributes from the Old decl to the New one.
-static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
-  for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
-    if (!DeclHasAttr(New, attr) && attr->isMerged()) {
-      Attr *NewAttr = attr->clone(C);
+/// MergeDeclAttributes - append attributes from the Old decl to the New one.
+static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) {
+  if (!Old->hasAttrs())
+    return;
+  // Ensure that any moving of objects within the allocated map is done before
+  // we process them.
+  if (!New->hasAttrs())
+    New->setAttrs(AttrVec());
+  for (Decl::attr_iterator i = Old->attr_begin(), e = Old->attr_end(); i != e;
+       ++i) {
+    // FIXME: Make this more general than just checking for Overloadable.
+    if (!DeclHasAttr(New, *i) && (*i)->getKind() != attr::Overloadable) {
+      Attr *NewAttr = (*i)->clone(C);
       NewAttr->setInherited(true);
       New->addAttr(NewAttr);
     }
@@ -1402,7 +1415,7 @@
 /// \returns false
 bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
   // Merge the attributes
-  MergeAttributes(New, Old, Context);
+  MergeDeclAttributes(New, Old, Context);
 
   // Merge the storage class.
   if (Old->getStorageClass() != FunctionDecl::Extern &&
@@ -1447,7 +1460,7 @@
     return New->setInvalidDecl();
   }
 
-  MergeAttributes(New, Old, Context);
+  MergeDeclAttributes(New, Old, Context);
 
   // Merge the types
   QualType MergedT;
@@ -1611,9 +1624,7 @@
   }
          
   if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
-    // If there are attributes in the DeclSpec, apply them to the record.
-    if (const AttributeList *AL = DS.getAttributes())
-      ProcessDeclAttributeList(S, Record, AL);
+    ProcessDeclAttributeList(S, Record, DS.getAttributes());
     
     if (!Record->getDeclName() && Record->isDefinition() &&
         DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
@@ -2770,7 +2781,8 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
-    NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+    NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), 
+                                                Context, SE->getString()));
   }
 
   // Diagnose shadowed variables before filtering for scope.
@@ -2810,6 +2822,8 @@
     NewVD->setInvalidDecl();
 
   // attributes declared post-definition are currently ignored
+  // FIXME: This should be handled in attribute merging, not
+  // here.
   if (Previous.isSingleResult()) {
     VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
     if (Def && (Def = Def->getDefinition()) &&
@@ -3447,7 +3461,8 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
-    NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+    NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
+                                                SE->getString()));
   }
 
   // Copy the parameter declarations from the declarator D to the function
@@ -3673,6 +3688,7 @@
   ProcessDeclAttributes(S, NewFD, D);
 
   // attributes declared post-definition are currently ignored
+  // FIXME: This should happen during attribute merging
   if (Redeclaration && Previous.isSingleResult()) {
     const FunctionDecl *Def;
     FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
@@ -3684,7 +3700,7 @@
 
   AddKnownFunctionAttributes(NewFD);
 
-  if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+  if (OverloadableAttrRequired && !NewFD->hasAttr<OverloadableAttr>()) {
     // If a function name is overloadable in C, then every function
     // with that name must be marked "overloadable".
     Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -3692,7 +3708,7 @@
     if (!Previous.empty())
       Diag(Previous.getRepresentativeDecl()->getLocation(),
            diag::note_attribute_overloadable_prev_overload);
-    NewFD->addAttr(::new (Context) OverloadableAttr());
+    NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), Context));
   }
 
   if (NewFD->hasAttr<OverloadableAttr>() && 
@@ -4792,10 +4808,10 @@
 
   // Checking attributes of current function definition
   // dllimport attribute.
-  if (FD->getAttr<DLLImportAttr>() &&
-      (!FD->getAttr<DLLExportAttr>())) {
-    // dllimport attribute cannot be applied to definition.
-    if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+  DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
+  if (DA && (!FD->getAttr<DLLExportAttr>())) {
+    // dllimport attribute cannot be directly applied to definition.
+    if (!DA->isInherited()) {
       Diag(FD->getLocation(),
            diag::err_attribute_can_be_applied_only_to_symbol_declaration)
         << "dllimport";
@@ -5041,7 +5057,7 @@
   CurContext = Context.getTranslationUnitDecl();
 
   FunctionDecl *FD =
- dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
+      dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
   FD->setImplicit();
 
   CurContext = PrevDC;
@@ -5069,13 +5085,15 @@
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
       if (!FD->getAttr<FormatAttr>())
-        FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+        FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                                "printf", FormatIdx+1,
                                                HasVAListArg ? 0 : FormatIdx+2));
     }
     if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
                                              HasVAListArg)) {
      if (!FD->getAttr<FormatAttr>())
-       FD->addAttr(::new (Context) FormatAttr(Context, "scanf", FormatIdx+1,
+       FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                              "scanf", FormatIdx+1,
                                               HasVAListArg ? 0 : FormatIdx+2));
     }
 
@@ -5085,15 +5103,15 @@
     if (!getLangOptions().MathErrno &&
         Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
       if (!FD->getAttr<ConstAttr>())
-        FD->addAttr(::new (Context) ConstAttr());
+        FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
     }
 
     if (Context.BuiltinInfo.isNoReturn(BuiltinID))
       FD->setType(Context.getNoReturnType(FD->getType()));
     if (Context.BuiltinInfo.isNoThrow(BuiltinID))
-      FD->addAttr(::new (Context) NoThrowAttr());
+      FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
     if (Context.BuiltinInfo.isConst(BuiltinID))
-      FD->addAttr(::new (Context) ConstAttr());
+      FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
   }
 
   IdentifierInfo *Name = FD->getIdentifier();
@@ -5115,13 +5133,15 @@
       // FIXME: We known better than our headers.
       const_cast<FormatAttr *>(Format)->setType(Context, "printf");
     } else
-      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
+      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                             "printf", 1,
                                              Name->isStr("NSLogv") ? 0 : 2));
   } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
     // FIXME: asprintf and vasprintf aren't C99 functions. Should they be
     // target-specific builtins, perhaps?
     if (!FD->getAttr<FormatAttr>())
-      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2,
+      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                             "printf", 2,
                                              Name->isStr("vasprintf") ? 0 : 3));
   }
 }
@@ -7009,7 +7029,7 @@
   Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
 
   if (PrevDecl) {
-    PrevDecl->addAttr(::new (Context) WeakAttr());
+    PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
   } else {
     (void)WeakUndeclaredIdentifiers.insert(
       std::pair<IdentifierInfo*,WeakInfo>

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Aug 18 18:23:40 2010
@@ -211,7 +211,7 @@
   }
 
   if (TagDecl *TD = dyn_cast<TagDecl>(d))
-    TD->addAttr(::new (S.Context) PackedAttr);
+    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
   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.
@@ -220,7 +220,7 @@
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
         << Attr.getName() << FD->getType();
     else
-      FD->addAttr(::new (S.Context) PackedAttr);
+      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
@@ -235,7 +235,7 @@
   // The IBAction attributes only apply to instance methods.
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
     if (MD->isInstanceMethod()) {
-      d->addAttr(::new (S.Context) IBActionAttr());
+      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
       return;
     }
 
@@ -252,7 +252,7 @@
   // The IBOutlet attributes only apply to instance variables of
   // Objective-C classes.
   if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
-    d->addAttr(::new (S.Context) IBOutletAttr());
+    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -307,7 +307,8 @@
     S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
     return;
   }
-  d->addAttr(::new (S.Context) IBOutletCollectionAttr(QT));
+  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
+                                                      QT));
 }
 
 static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -378,7 +379,8 @@
   unsigned* start = &NonNullArgs[0];
   unsigned size = NonNullArgs.size();
   llvm::array_pod_sort(start, start + size);
-  d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
+  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
+                                           size));
 }
 
 static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
@@ -397,24 +399,24 @@
     return;
   }
   // Figure out our Kind, and check arguments while we're at it.
-  attr::Kind K;
+  OwnershipAttr::OwnershipKind K;
   switch (AL.getKind()) {
   case AttributeList::AT_ownership_takes:
-    K = attr::OwnershipTakes;
+    K = OwnershipAttr::Takes;
     if (AL.getNumArgs() < 1) {
       S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
       return;
     }
     break;
   case AttributeList::AT_ownership_holds:
-    K = attr::OwnershipHolds;
+    K = OwnershipAttr::Holds;
     if (AL.getNumArgs() < 1) {
       S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
       return;
     }
     break;
   case AttributeList::AT_ownership_returns:
-    K = attr::OwnershipReturns;
+    K = OwnershipAttr::Returns;
     if (AL.getNumArgs() > 1) {
       S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
           << AL.getNumArgs() + 1;
@@ -463,21 +465,21 @@
     }
     --x;
     switch (K) {
-    case attr::OwnershipTakes:
-    case attr::OwnershipHolds: {
+    case OwnershipAttr::Takes:
+    case OwnershipAttr::Holds: {
       // Is the function argument a pointer type?
       QualType T = getFunctionOrMethodArgType(d, x);
       if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
         // FIXME: Should also highlight argument in decl.
         S.Diag(AL.getLoc(), diag::err_ownership_type)
-            << ((K==attr::OwnershipTakes)?"ownership_takes":"ownership_holds")
+            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
             << "pointer"
             << IdxExpr->getSourceRange();
         continue;
       }
       break;
     }
-    case attr::OwnershipReturns: {
+    case OwnershipAttr::Returns: {
       if (AL.getNumArgs() > 1) {
           // Is the function argument an integer type?
           Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
@@ -497,18 +499,16 @@
     } // switch
 
     // Check we don't have a conflict with another ownership attribute.
-    if (K != attr::OwnershipReturns && d->hasAttrs()) {
-      for (const Attr *attr = d->getAttrs(); attr; attr = attr->getNext()) {
-        if (const OwnershipAttr* Att = dyn_cast<OwnershipAttr>(attr)) {
-          // Two ownership attributes of the same kind can't conflict,
-          // except returns attributes.
-          if (Att->getKind() != K) {
-            for (const unsigned *I = Att->begin(), *E = Att->end(); I!=E; ++I) {
-              if (x == *I) {
-                S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
-                    << AL.getName()->getName() << "ownership_*";
-              }
-            }
+    for (specific_attr_iterator<OwnershipAttr>
+          i = d->specific_attr_begin<OwnershipAttr>(),
+          e = d->specific_attr_end<OwnershipAttr>();
+        i != e; ++i) {
+      if ((*i)->getOwnKind() != K) {
+        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
+             I!=E; ++I) {
+          if (x == *I) {
+            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+                << AL.getName()->getName() << "ownership_*";
           }
         }
       }
@@ -519,33 +519,14 @@
   unsigned* start = OwnershipArgs.data();
   unsigned size = OwnershipArgs.size();
   llvm::array_pod_sort(start, start + size);
-  switch (K) {
-  case attr::OwnershipTakes: {
-    if (OwnershipArgs.empty()) {
-      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
-      return;
-    }
-    d->addAttr(::new (S.Context) OwnershipTakesAttr(S.Context, start, size,
-                                                    Module));
-    break;
-  }
-  case attr::OwnershipHolds: {
-    if (OwnershipArgs.empty()) {
-      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
-      return;
-    }
-    d->addAttr(::new (S.Context) OwnershipHoldsAttr(S.Context, start, size,
-                                                    Module));
-    break;
-  }
-  case attr::OwnershipReturns: {
-    d->addAttr(::new (S.Context) OwnershipReturnsAttr(S.Context, start, size,
-                                                      Module));
-    break;
-  }
-  default:
-    llvm_unreachable("Unknown ownership attribute");
+
+  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
+    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+    return;
   }
+
+  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
+                                             start, size));
 }
 
 static bool isStaticVarOrStaticFunciton(Decl *D) {
@@ -622,10 +603,10 @@
     }
     // GCC will accept anything as the argument of weakref. Should we
     // check for an existing decl?
-    d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
   }
 
-  d->addAttr(::new (S.Context) WeakRefAttr());
+  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -647,7 +628,7 @@
 
   // FIXME: check if target symbol exists in current file
 
-  d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
 }
 
 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -664,7 +645,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) AlwaysInlineAttr());
+  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -677,7 +658,7 @@
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
     QualType RetTy = FD->getResultType();
     if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
-      d->addAttr(::new (S.Context) MallocAttr());
+      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
       return;
     }
   }
@@ -711,13 +692,13 @@
 static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
   assert(Attr.isInvalid() == false);
-  d->addAttr(::new (S.Context) NoReturnAttr());
+  d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
                                        Sema &S) {
   if (HandleCommonNoReturnAttr(d, Attr, S))
-    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
 }
 
 // PS3 PPU-specific.
@@ -756,7 +737,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) VecReturnAttr());
+  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -782,7 +763,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) UnusedAttr());
+  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -803,7 +784,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) UsedAttr());
+  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -833,7 +814,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) ConstructorAttr(priority));
+  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
 }
 
 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -863,7 +844,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) DestructorAttr(priority));
+  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
 }
 
 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -873,7 +854,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) DeprecatedAttr());
+  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -883,7 +864,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) UnavailableAttr());
+  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -904,22 +885,22 @@
   }
 
   llvm::StringRef TypeStr = Str->getString();
-  VisibilityAttr::VisibilityTypes type;
+  VisibilityAttr::VisibilityType type;
 
   if (TypeStr == "default")
-    type = VisibilityAttr::DefaultVisibility;
+    type = VisibilityAttr::Default;
   else if (TypeStr == "hidden")
-    type = VisibilityAttr::HiddenVisibility;
+    type = VisibilityAttr::Hidden;
   else if (TypeStr == "internal")
-    type = VisibilityAttr::HiddenVisibility; // FIXME
+    type = VisibilityAttr::Hidden; // FIXME
   else if (TypeStr == "protected")
-    type = VisibilityAttr::ProtectedVisibility;
+    type = VisibilityAttr::Protected;
   else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
     return;
   }
 
-  d->addAttr(::new (S.Context) VisibilityAttr(type, false));
+  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
 }
 
 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -935,7 +916,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ObjCExceptionAttr());
+  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -951,7 +932,7 @@
       return;
     }
   }
-  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
 }
 
 static void
@@ -966,7 +947,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) OverloadableAttr());
+  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -981,7 +962,7 @@
     return;
   }
 
-  BlocksAttr::BlocksAttrTypes type;
+  BlocksAttr::BlockType type;
   if (Attr.getParameterName()->isStr("byref"))
     type = BlocksAttr::ByRef;
   else {
@@ -990,7 +971,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) BlocksAttr(type));
+  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
 }
 
 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1083,7 +1064,7 @@
       << Attr.getName() << 6 /*function, method or block */;
     return;
   }
-  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
 }
 
 static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1111,7 +1092,7 @@
       return;
     }
   
-  D->addAttr(::new (S.Context) WarnUnusedResultAttr());
+  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1135,7 +1116,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakAttr());
+  D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1171,7 +1152,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakImportAttr());
+  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -1194,7 +1175,8 @@
     }
     WGSize[i] = (unsigned) ArgNum.getZExtValue();
   }
-  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
+                                                     WGSize[0], WGSize[1],
                                                      WGSize[2]));
 }
 
@@ -1228,7 +1210,7 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
+  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
 }
 
 
@@ -1239,7 +1221,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) NoThrowAttr());
+  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1249,7 +1231,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) ConstAttr());
+  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1259,7 +1241,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) PureAttr());
+  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1317,7 +1299,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) CleanupAttr(FD));
+  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -1380,7 +1362,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue()));
 }
 
 enum FormatAttrKind {
@@ -1462,7 +1444,7 @@
     Attr.setInvalid();
     return;
   }
-  d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum));
+  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
 }
 
 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -1606,7 +1588,8 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
+  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
+                                          Idx.getZExtValue(),
                                           FirstArg.getZExtValue()));
 }
 
@@ -1675,7 +1658,7 @@
     }
   }
 
-  RD->addAttr(::new (S.Context) TransparentUnionAttr());
+  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1693,7 +1676,7 @@
     S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
     return;
   }
-  d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
+  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
 }
 
 static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1708,9 +1691,7 @@
   //       weaker alignment, rather than being silently ignored.
 
   if (Attr.getNumArgs() == 0) {
-    // FIXME: This should be the target specific maximum alignment.
-    // (For now we just use 128 bits which is the maximum on X86).
-    D->addAttr(::new (S.Context) AlignedAttr(128));
+    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
     return;
   }
 
@@ -1720,10 +1701,11 @@
 void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
   if (E->isTypeDependent() || E->isValueDependent()) {
     // Save dependent expressions in the AST to be instantiated.
-    D->addAttr(::new (Context) AlignedAttr(E));
+    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
     return;
   }
 
+  // FIXME: Cache the number on the Attr object?
   llvm::APSInt Alignment(32);
   if (!E->isIntegerConstantExpr(Alignment, Context)) {
     Diag(AttrLoc, diag::err_attribute_argument_not_int)
@@ -1736,7 +1718,14 @@
     return;
   }
 
-  D->addAttr(::new (Context) AlignedAttr(Alignment.getZExtValue() * 8));
+  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
+}
+
+void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
+  // FIXME: Cache the number on the Attr object if non-dependent?
+  // FIXME: Perform checking of type validity
+  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
+  return;
 }
 
 /// HandleModeAttr - This attribute modifies the width of a decl with primitive
@@ -1923,7 +1912,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) NoDebugAttr());
+  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1939,7 +1928,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) NoInlineAttr());
+  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
@@ -1956,7 +1945,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr());
+  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1978,7 +1967,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) GNUInlineAttr());
+  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1988,15 +1977,15 @@
 
   switch (Attr.getKind()) {
   case AttributeList::AT_fastcall:
-    d->addAttr(::new (S.Context) FastCallAttr());
+    d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
     return;
   case AttributeList::AT_stdcall:
-    d->addAttr(::new (S.Context) StdCallAttr());
+    d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
     return;
   case AttributeList::AT_thiscall:
-    d->addAttr(::new (S.Context) ThisCallAttr());
+    d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
   case AttributeList::AT_cdecl:
-    d->addAttr(::new (S.Context) CDeclAttr());
+    d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
     return;
   default:
     llvm_unreachable("unexpected attribute kind");
@@ -2038,7 +2027,8 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+  d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
+                                           NumParams.getZExtValue()));
 }
 
 static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2064,7 +2054,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FinalAttr());
+  d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
 }
 
 //===----------------------------------------------------------------------===//
@@ -2090,7 +2080,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) BaseCheckAttr());
+  d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2115,7 +2105,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) HidingAttr());
+  d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2140,7 +2130,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) OverrideAttr());
+  d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
 }
 
 //===----------------------------------------------------------------------===//
@@ -2176,16 +2166,16 @@
       assert(0 && "invalid ownership attribute");
       return;
     case AttributeList::AT_cf_returns_not_retained:
-      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
+      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_ns_returns_not_retained:
-      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
+      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_cf_returns_retained:
-      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_ns_returns_retained:
-      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
       return;
   };
 }
@@ -2369,8 +2359,9 @@
   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
     IdentifierInfo *NDId = ND->getIdentifier();
     NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
-    NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
-    NewD->addAttr(::new (Context) WeakAttr());
+    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
+                                            NDId->getName()));
+    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
     WeakTopLevelDecl.push_back(NewD);
     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
     // to insert Decl at TU scope, sorry.
@@ -2379,7 +2370,7 @@
     PushOnScopeChains(NewD, S);
     CurContext = SavedContext;
   } else { // just add weak to existing
-    ND->addAttr(::new (Context) WeakAttr());
+    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
   }
 }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Aug 18 18:23:40 2010
@@ -3292,7 +3292,7 @@
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
 
   if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
-    PushPragmaVisibility(attr->getVisibility());
+    PushPragmaVisibility(attr->getVisibility(), attr->getLocation());
 
   if (II) {
     // C++ [namespace.def]p2:

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Aug 18 18:23:40 2010
@@ -1454,13 +1454,14 @@
 }
 
 static inline
-bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+bool containsInvalidMethodImplAttribute(const AttrVec &A) {
   // The 'ibaction' attribute is allowed on method definitions because of
   // how the IBAction macro is used on both method declarations and definitions.
   // If the method definitions contains any other attributes, return true.
-  while (A && A->getKind() == AttributeList::AT_IBAction)
-    A = A->getNext();
-  return A != NULL;
+  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+    if ((*i)->getKind() != attr::IBAction)
+      return true;
+  return false;
 }
 
 Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
@@ -1590,7 +1591,8 @@
     }
     InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
                                                    MethodType == tok::minus);
-    if (containsInvalidMethodImplAttribute(AttrList))
+    if (ObjCMethod->hasAttrs() &&
+        containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
       Diag(EndLoc, diag::warn_attribute_method_def);
   } else if (ObjCCategoryImplDecl *CatImpDecl =
              dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1601,7 +1603,8 @@
       PrevMethod = CatImpDecl->getClassMethod(Sel);
       CatImpDecl->addClassMethod(ObjCMethod);
     }
-    if (containsInvalidMethodImplAttribute(AttrList))
+    if (ObjCMethod->hasAttrs() &&
+        containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
       Diag(EndLoc, diag::warn_attribute_method_def);
   }
   if (PrevMethod) {
@@ -1613,8 +1616,10 @@
 
   // If the interface declared this method, and it was deprecated there,
   // mark it deprecated here.
-  if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
-    ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
+  if (InterfaceMD)
+   if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
+    ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
+                                                       Context));
 
   return DeclPtrTy::make(ObjCMethod);
 }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Aug 18 18:23:40 2010
@@ -1259,7 +1259,7 @@
         // FIXME: Do we need to check for default arguments here?
         if (Func->getNumParams() == 1 && InitialParamType == Argument) {
           if(AddMallocAttr && !Func->hasAttr<MallocAttr>())
-            Func->addAttr(::new (Context) MallocAttr());
+            Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
           return;
         }
       }
@@ -1287,7 +1287,7 @@
   Alloc->setImplicit();
   
   if (AddMallocAttr)
-    Alloc->addAttr(::new (Context) MallocAttr());
+    Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
   
   ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
                                            0, Argument, /*TInfo=*/0,

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Aug 18 18:23:40 2010
@@ -4031,7 +4031,7 @@
 /// \brief Strips various properties off an implicit instantiation
 /// that has just been explicitly specialized.
 static void StripImplicitInstantiation(NamedDecl *D) {
-  D->invalidateAttrs();
+  D->dropAttrs();
 
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     FD->setInlineSpecified(false);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Aug 18 18:23:40 2010
@@ -140,21 +140,30 @@
 // FIXME: Is this still too simple?
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                             Decl *Tmpl, Decl *New) {
-  for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
-       TmplAttr = TmplAttr->getNext()) {
+  for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
+       i != e; ++i) {
+    const Attr *TmplAttr = *i;
     // FIXME: This should be generalized to more than just the AlignedAttr.
     if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
-      if (Aligned->isDependent()) {
+      if (Aligned->isAlignmentDependent()) {
         // The alignment expression is not potentially evaluated.
         EnterExpressionEvaluationContext Unevaluated(*this,
                                                      Action::Unevaluated);
 
-        OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
-                                            TemplateArgs);
-        if (!Result.isInvalid())
-          // FIXME: Is this the correct source location?
-          AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
-                         New, Result.takeAs<Expr>());
+        if (Aligned->isAlignmentExpr()) {
+          OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+                                              TemplateArgs);
+          if (!Result.isInvalid())
+            AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>());
+        }
+        else {
+          TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
+                                              TemplateArgs,
+                                              Aligned->getLocation(), 
+                                              DeclarationName());
+          if (Result)
+            AddAlignedAttr(Aligned->getLocation(), New, Result);
+        }
         continue;
       }
     }

Modified: cfe/trunk/lib/Sema/TargetAttributesSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (original)
+++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Wed Aug 18 18:23:40 2010
@@ -51,8 +51,8 @@
       return;
     }
 
-    d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
-    d->addAttr(::new (S.Context) UsedAttr());
+    d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
+    d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
   }
 
 namespace {
@@ -97,7 +97,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
+  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -109,7 +109,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLImportAttr());
+    D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -146,7 +146,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLImportAttr());
+  D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -158,7 +158,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLExportAttr());
+    D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -177,7 +177,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLExportAttr());
+  D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
 }
 
 namespace {

Modified: cfe/trunk/lib/Serialization/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/CMakeLists.txt (original)
+++ cfe/trunk/lib/Serialization/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -13,6 +13,8 @@
 add_dependencies(clangSerialization
   ClangAttrClasses
   ClangAttrList
+  ClangAttrPCHRead
+  ClangAttrPCHWrite
   ClangDiagnosticFrontend
   ClangDiagnosticLex
   ClangDiagnosticSema

Modified: cfe/trunk/lib/Serialization/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/PCHReaderDecl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/PCHReaderDecl.cpp Wed Aug 18 18:23:40 2010
@@ -148,8 +148,11 @@
                      cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
   D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
   D->setInvalidDecl(Record[Idx++]);
-  if (Record[Idx++])
-    D->initAttrs(Reader.ReadAttributes(Cursor));
+  if (Record[Idx++]) {
+    AttrVec Attrs;
+    Reader.ReadAttributes(Cursor, Attrs);
+    D->setAttrs(Attrs);
+  }
   D->setImplicit(Record[Idx++]);
   D->setUsed(Record[Idx++]);
   D->setAccess((AccessSpecifier)Record[Idx++]);
@@ -1091,7 +1094,8 @@
 //===----------------------------------------------------------------------===//
 
 /// \brief Reads attributes from the current stream position.
-Attr *PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor) {
+void PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor,
+                               AttrVec &Attrs) {
   unsigned Code = DeclsCursor.ReadCode();
   assert(Code == llvm::bitc::UNABBREV_RECORD &&
          "Expected unabbreviated record"); (void)Code;
@@ -1102,174 +1106,18 @@
   assert(RecCode == pch::DECL_ATTR && "Expected attribute record");
   (void)RecCode;
 
-#define SIMPLE_ATTR(Name)                       \
- case attr::Name:                               \
-   New = ::new (*Context) Name##Attr();         \
-   break
-
-#define STRING_ATTR(Name)                                       \
- case attr::Name:                                               \
-   New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx));  \
-   break
-
-#define UNSIGNED_ATTR(Name)                             \
- case attr::Name:                                       \
-   New = ::new (*Context) Name##Attr(Record[Idx++]);    \
-   break
-
-  Attr *Attrs = 0;
   while (Idx < Record.size()) {
     Attr *New = 0;
     attr::Kind Kind = (attr::Kind)Record[Idx++];
-    bool IsInherited = Record[Idx++];
-
-    switch (Kind) {
-    default:
-      assert(0 && "Unknown attribute!");
-      break;
-    STRING_ATTR(Alias);
-    SIMPLE_ATTR(AlignMac68k);
-    UNSIGNED_ATTR(Aligned);
-    SIMPLE_ATTR(AlwaysInline);
-    SIMPLE_ATTR(AnalyzerNoReturn);
-    STRING_ATTR(Annotate);
-    STRING_ATTR(AsmLabel);
-    SIMPLE_ATTR(BaseCheck);
-
-    case attr::Blocks:
-      New = ::new (*Context) BlocksAttr(
-                                  (BlocksAttr::BlocksAttrTypes)Record[Idx++]);
-      break;
-
-    SIMPLE_ATTR(CDecl);
-
-    case attr::Cleanup:
-      New = ::new (*Context) CleanupAttr(
-                                  cast<FunctionDecl>(GetDecl(Record[Idx++])));
-      break;
-
-    SIMPLE_ATTR(Const);
-    UNSIGNED_ATTR(Constructor);
-    SIMPLE_ATTR(DLLExport);
-    SIMPLE_ATTR(DLLImport);
-    SIMPLE_ATTR(Deprecated);
-    UNSIGNED_ATTR(Destructor);
-    SIMPLE_ATTR(FastCall);
-    SIMPLE_ATTR(Final);
-
-    case attr::Format: {
-      std::string Type = ReadString(Record, Idx);
-      unsigned FormatIdx = Record[Idx++];
-      unsigned FirstArg = Record[Idx++];
-      New = ::new (*Context) FormatAttr(*Context, Type, FormatIdx, FirstArg);
-      break;
-    }
-
-    case attr::FormatArg: {
-      unsigned FormatIdx = Record[Idx++];
-      New = ::new (*Context) FormatArgAttr(FormatIdx);
-      break;
-    }
-
-    case attr::Sentinel: {
-      int sentinel = Record[Idx++];
-      int nullPos = Record[Idx++];
-      New = ::new (*Context) SentinelAttr(sentinel, nullPos);
-      break;
-    }
+    SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
+    bool isInherited = Record[Idx++];
 
-    SIMPLE_ATTR(GNUInline);
-    SIMPLE_ATTR(Hiding);
-
-    case attr::IBAction:
-      New = ::new (*Context) IBActionAttr();
-      break;
-
-    case attr::IBOutlet:
-      New = ::new (*Context) IBOutletAttr();
-      break;
-
-    case attr::IBOutletCollection: {
-      QualType QT = GetType(Record[Idx++]);
-      New = ::new (*Context) IBOutletCollectionAttr(QT);
-      break;
-    }
-
-    SIMPLE_ATTR(Malloc);
-    SIMPLE_ATTR(NoDebug);
-    SIMPLE_ATTR(NoInline);
-    SIMPLE_ATTR(NoReturn);
-    SIMPLE_ATTR(NoThrow);
-
-    case attr::NonNull: {
-      unsigned Size = Record[Idx++];
-      llvm::SmallVector<unsigned, 16> ArgNums;
-      ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size);
-      Idx += Size;
-      New = ::new (*Context) NonNullAttr(*Context, ArgNums.data(), Size);
-      break;
-    }
-
-    case attr::ReqdWorkGroupSize: {
-      unsigned X = Record[Idx++];
-      unsigned Y = Record[Idx++];
-      unsigned Z = Record[Idx++];
-      New = ::new (*Context) ReqdWorkGroupSizeAttr(X, Y, Z);
-      break;
-    }
-
-    SIMPLE_ATTR(ObjCException);
-    SIMPLE_ATTR(ObjCNSObject);
-    SIMPLE_ATTR(CFReturnsNotRetained);
-    SIMPLE_ATTR(CFReturnsRetained);
-    SIMPLE_ATTR(NSReturnsNotRetained);
-    SIMPLE_ATTR(NSReturnsRetained);
-    SIMPLE_ATTR(Overloadable);
-    SIMPLE_ATTR(Override);
-    SIMPLE_ATTR(Packed);
-    UNSIGNED_ATTR(MaxFieldAlignment);
-    SIMPLE_ATTR(Pure);
-    UNSIGNED_ATTR(Regparm);
-    STRING_ATTR(Section);
-    SIMPLE_ATTR(StdCall);
-    SIMPLE_ATTR(ThisCall);
-    SIMPLE_ATTR(TransparentUnion);
-    SIMPLE_ATTR(Unavailable);
-    SIMPLE_ATTR(Unused);
-    SIMPLE_ATTR(Used);
-
-    case attr::Visibility:
-      New = ::new (*Context) VisibilityAttr(
-                              (VisibilityAttr::VisibilityTypes)Record[Idx++],
-                              (bool)Record[Idx++]);
-      break;
-
-    SIMPLE_ATTR(WarnUnusedResult);
-    SIMPLE_ATTR(Weak);
-    SIMPLE_ATTR(WeakRef);
-    SIMPLE_ATTR(WeakImport);
-    }
+#include "clang/Serialization/AttrPCHRead.inc"
 
     assert(New && "Unable to decode attribute?");
-    New->setInherited(IsInherited);
-    New->setNext(Attrs);
-    Attrs = New;
-  }
-#undef UNSIGNED_ATTR
-#undef STRING_ATTR
-#undef SIMPLE_ATTR
-
-  // The list of attributes was built backwards. Reverse the list
-  // before returning it.
-  Attr *PrevAttr = 0, *NextAttr = 0;
-  while (Attrs) {
-    NextAttr = Attrs->getNext();
-    Attrs->setNext(PrevAttr);
-    PrevAttr = Attrs;
-    Attrs = NextAttr;
+    New->setInherited(isInherited);
+    Attrs.push_back(New);
   }
-
-  return PrevAttr;
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Serialization/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/PCHWriter.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/PCHWriter.cpp Wed Aug 18 18:23:40 2010
@@ -1949,172 +1949,16 @@
 //===----------------------------------------------------------------------===//
 
 /// \brief Write a record containing the given attributes.
-void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
+void PCHWriter::WriteAttributeRecord(const AttrVec &Attrs) {
   RecordData Record;
-  for (; Attr; Attr = Attr->getNext()) {
-    Record.push_back(Attr->getKind()); // FIXME: stable encoding, target attrs
-    Record.push_back(Attr->isInherited());
-    switch (Attr->getKind()) {
-    default:
-      assert(0 && "Does not support PCH writing for this attribute yet!");
-      break;
-    case attr::Alias:
-      AddString(cast<AliasAttr>(Attr)->getAliasee(), Record);
-      break;
-
-    case attr::AlignMac68k:
-      break;
-
-    case attr::Aligned:
-      Record.push_back(cast<AlignedAttr>(Attr)->getAlignment());
-      break;
-
-    case attr::AlwaysInline:
-      break;
-
-    case attr::AnalyzerNoReturn:
-      break;
-
-    case attr::Annotate:
-      AddString(cast<AnnotateAttr>(Attr)->getAnnotation(), Record);
-      break;
-
-    case attr::AsmLabel:
-      AddString(cast<AsmLabelAttr>(Attr)->getLabel(), Record);
-      break;
-
-    case attr::BaseCheck:
-      break;
-
-    case attr::Blocks:
-      Record.push_back(cast<BlocksAttr>(Attr)->getType()); // FIXME: stable
-      break;
-
-    case attr::CDecl:
-      break;
-
-    case attr::Cleanup:
-      AddDeclRef(cast<CleanupAttr>(Attr)->getFunctionDecl(), Record);
-      break;
-
-    case attr::Const:
-      break;
-
-    case attr::Constructor:
-      Record.push_back(cast<ConstructorAttr>(Attr)->getPriority());
-      break;
-
-    case attr::DLLExport:
-    case attr::DLLImport:
-    case attr::Deprecated:
-      break;
-
-    case attr::Destructor:
-      Record.push_back(cast<DestructorAttr>(Attr)->getPriority());
-      break;
-
-    case attr::FastCall:
-    case attr::Final:
-      break;
-
-    case attr::Format: {
-      const FormatAttr *Format = cast<FormatAttr>(Attr);
-      AddString(Format->getType(), Record);
-      Record.push_back(Format->getFormatIdx());
-      Record.push_back(Format->getFirstArg());
-      break;
-    }
-
-    case attr::FormatArg: {
-      const FormatArgAttr *Format = cast<FormatArgAttr>(Attr);
-      Record.push_back(Format->getFormatIdx());
-      break;
-    }
-
-    case attr::Sentinel : {
-      const SentinelAttr *Sentinel = cast<SentinelAttr>(Attr);
-      Record.push_back(Sentinel->getSentinel());
-      Record.push_back(Sentinel->getNullPos());
-      break;
-    }
-
-    case attr::GNUInline:
-    case attr::Hiding:
-    case attr::IBAction:
-    case attr::IBOutlet:
-    case attr::Malloc:
-    case attr::NoDebug:
-    case attr::NoInline:
-    case attr::NoReturn:
-    case attr::NoThrow:
-      break;
-
-    case attr::IBOutletCollection: {
-      const IBOutletCollectionAttr *ICA = cast<IBOutletCollectionAttr>(Attr);
-      AddTypeRef(ICA->getType(), Record);
-      break;
-    }
-
-    case attr::NonNull: {
-      const NonNullAttr *NonNull = cast<NonNullAttr>(Attr);
-      Record.push_back(NonNull->size());
-      Record.insert(Record.end(), NonNull->begin(), NonNull->end());
-      break;
-    }
-
-    case attr::CFReturnsNotRetained:
-    case attr::CFReturnsRetained:
-    case attr::NSReturnsNotRetained:
-    case attr::NSReturnsRetained:
-    case attr::ObjCException:
-    case attr::ObjCNSObject:
-    case attr::Overloadable:
-    case attr::Override:
-      break;
+  for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){
+    const Attr * A = *i;
+    Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs
+    AddSourceLocation(A->getLocation(), Record);
+    Record.push_back(A->isInherited());
 
-    case attr::MaxFieldAlignment:
-      Record.push_back(cast<MaxFieldAlignmentAttr>(Attr)->getAlignment());
-      break;
-
-    case attr::Packed:
-      break;
-
-    case attr::Pure:
-      break;
-
-    case attr::Regparm:
-      Record.push_back(cast<RegparmAttr>(Attr)->getNumParams());
-      break;
-
-    case attr::ReqdWorkGroupSize:
-      Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim());
-      Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim());
-      Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim());
-      break;
+#include "clang/Serialization/AttrPCHWrite.inc"
 
-    case attr::Section:
-      AddString(cast<SectionAttr>(Attr)->getName(), Record);
-      break;
-
-    case attr::StdCall:
-    case attr::TransparentUnion:
-    case attr::Unavailable:
-    case attr::Unused:
-    case attr::Used:
-      break;
-
-    case attr::Visibility:
-      // FIXME: stable encoding
-      Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility());
-      Record.push_back(cast<VisibilityAttr>(Attr)->isFromPragma());
-      break;
-
-    case attr::WarnUnusedResult:
-    case attr::Weak:
-    case attr::WeakRef:
-    case attr::WeakImport:
-      break;
-    }
   }
 
   Stream.EmitRecord(pch::DECL_ATTR, Record);

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Aug 18 18:23:40 2010
@@ -1144,8 +1144,9 @@
 
 
 bool CursorVisitor::VisitAttributes(Decl *D) {
-  for (const Attr *A = D->getAttrs(); A; A = A->getNext())
-    if (Visit(MakeCXCursor(A, D, TU)))
+  for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
+       i != e; ++i)
+    if (Visit(MakeCXCursor(*i, D, TU)))
         return true;
 
   return false;





More information about the cfe-commits mailing list