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/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 96793d5..66d31dd 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -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() {
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 9a48493..4e8c82f 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -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,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index dfbc7e1..f6d6e6b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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>
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 7125c36..1776d46 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -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;
+
+  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
+    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+    return;
   }
-  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");
-  }
+
+  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));
   }
 }
 
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 7791b68..fff37d9 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -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:
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 8bcb616..0fd3d6e 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -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);
 }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 8599a14..2267e0c 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -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,
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 24ecb47..5cfacf7 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -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);
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 1cb5077..6fc9563 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -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;
       }
     }
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
index 4d9e486..dc08a73 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -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 {