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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111455 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index b549415..f53a50e 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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;
   }
 
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index 994d45c..3ca7d4d 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -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"
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index b340c04..82a81ec 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -43,4 +43,4 @@
   )
 
 add_dependencies(clangAST ClangARMNeon ClangAttrClasses ClangAttrList 
-                 ClangDiagnosticAST ClangDeclNodes ClangStmtNodes)
+                 ClangAttrImpl ClangDiagnosticAST ClangDeclNodes ClangStmtNodes)
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index e4ff679..74cc1c2 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -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);
 }
 
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index ad15917..f42ba5a 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -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)