Move the static DeclAttrs map into ASTContext. Fixes <rdar://problem/6983177>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73702 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index ae863f2..425d804 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -77,11 +77,11 @@
   
 /// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
 /// diagnostic that should be emitted if control goes over it. If not, return 0.
-static unsigned GetDiagForGotoScopeDecl(const Decl *D) {
+static unsigned GetDiagForGotoScopeDecl(ASTContext &Context, const Decl *D) {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
     if (VD->getType()->isVariablyModifiedType())
       return diag::note_protected_by_vla;
-    if (VD->hasAttr<CleanupAttr>())
+    if (VD->hasAttr<CleanupAttr>(Context))
       return diag::note_protected_by_cleanup;
   } else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
     if (TD->getUnderlyingType()->isVariablyModifiedType())
@@ -125,7 +125,7 @@
       for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
            I != E; ++I) {
         // If this decl causes a new scope, push and switch to it.
-        if (unsigned Diag = GetDiagForGotoScopeDecl(*I)) {
+        if (unsigned Diag = GetDiagForGotoScopeDecl(this->S.Context, *I)) {
           Scopes.push_back(GotoScope(ParentScope, Diag, (*I)->getLocation()));
           ParentScope = Scopes.size()-1;
         }
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 1bf8444..cbfa56a 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -205,7 +205,7 @@
   // Otherwise, add the 'unused' attribute to each referenced declaration.
   for (unsigned i = 0; i < NumExprs; ++i) {
     DeclRefExpr *DR = (DeclRefExpr*) Exprs[i];
-    DR->getDecl()->addAttr(::new (Context) UnusedAttr());
+    DR->getDecl()->addAttr(Context, ::new (Context) UnusedAttr());
     DR->Destroy(Context);
   }
 }
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 4856e7f..a2ceafa 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -166,7 +166,7 @@
   // handlers.
 
   // Printf checking.
-  if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
+  if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>(Context)) {
     if (Format->getType() == "printf") {
       bool HasVAListArg = Format->getFirstArg() == 0;
       if (!HasVAListArg) {
@@ -178,7 +178,8 @@
                            HasVAListArg ? 0 : Format->getFirstArg() - 1);
     }
   }
-  for (const Attr *attr = FDecl->getAttrs(); attr; attr = attr->getNext()) {
+  for (const Attr *attr = FDecl->getAttrs(Context); 
+       attr; attr = attr->getNext()) {
     if (const NonNullAttr *NonNull = dyn_cast<NonNullAttr>(attr))
       CheckNonNullArguments(NonNull, TheCall);
   }
@@ -191,7 +192,7 @@
 
   OwningExprResult TheCallResult(Owned(TheCall));
   // Printf checking.
-  const FormatAttr *Format = NDecl->getAttr<FormatAttr>();
+  const FormatAttr *Format = NDecl->getAttr<FormatAttr>(Context);
   if (!Format)
     return move(TheCallResult);
   const VarDecl *V = dyn_cast<VarDecl>(NDecl);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7746035..9e31bae 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -256,7 +256,7 @@
   if (isa<OverloadedFunctionDecl>(PrevDecl))
     return true;
 
-  return PrevDecl->getAttr<OverloadableAttr>() != 0;
+  return PrevDecl->getAttr<OverloadableAttr>(Context) != 0;
 }
 
 /// Add this decl to the scope shadowed decl chains.
@@ -611,8 +611,9 @@
 
 /// 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())
+static bool 
+DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) {
+  for (const Attr *attr = decl->getAttrs(Context); attr; attr = attr->getNext())
     if (attr->getKind() == target->getKind())
       return true;
 
@@ -621,11 +622,11 @@
 
 /// 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()) {
+  for (const Attr *attr = Old->getAttrs(C); attr; attr = attr->getNext()) {
+    if (!DeclHasAttr(C, New, attr) && attr->isMerged()) {
       Attr *NewAttr = attr->clone(C);
       NewAttr->setInherited(true);
-      New->addAttr(NewAttr);
+      New->addAttr(C, NewAttr);
     }
   }
 }
@@ -1828,7 +1829,8 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);  
-    NewVD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+    NewVD->addAttr(Context, 
+                   ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
                                                         SE->getByteLength())));
   }
 
@@ -1907,11 +1909,11 @@
   }
 
   if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
-      && !NewVD->hasAttr<BlocksAttr>())
+      && !NewVD->hasAttr<BlocksAttr>(Context))
     Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
 
   bool isVM = T->isVariablyModifiedType();
-  if (isVM || NewVD->hasAttr<CleanupAttr>())
+  if (isVM || NewVD->hasAttr<CleanupAttr>(Context))
     CurFunctionNeedsScopeChecking = true;
   
   if ((isVM && NewVD->hasLinkage()) ||
@@ -1966,12 +1968,12 @@
     return NewVD->setInvalidDecl();
   }
 
-  if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
+  if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>(Context)) {
     Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
     return NewVD->setInvalidDecl();
   }
     
-  if (isVM && NewVD->hasAttr<BlocksAttr>()) {
+  if (isVM && NewVD->hasAttr<BlocksAttr>(Context)) {
     Diag(NewVD->getLocation(), diag::err_block_on_vm);
     return NewVD->setInvalidDecl();
   }
@@ -2201,7 +2203,8 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);  
-    NewFD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+    NewFD->addAttr(Context,
+                   ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
                                                         SE->getByteLength())));
   }
 
@@ -2322,7 +2325,7 @@
   ProcessDeclAttributes(S, NewFD, D);
   AddKnownFunctionAttributes(NewFD);
 
-  if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+  if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>(Context)) {
     // 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)
@@ -2330,7 +2333,7 @@
     if (PrevDecl)
       Diag(PrevDecl->getLocation(), 
            diag::note_attribute_overloadable_prev_overload);
-    NewFD->addAttr(::new (Context) OverloadableAttr());
+    NewFD->addAttr(Context, ::new (Context) OverloadableAttr());
   }
 
   // If this is a locally-scoped extern C function, update the
@@ -2930,7 +2933,7 @@
 
   ProcessDeclAttributes(S, New, D);
 
-  if (New->hasAttr<BlocksAttr>()) {
+  if (New->hasAttr<BlocksAttr>(Context)) {
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
   }
   return DeclPtrTy::make(New);
@@ -3056,9 +3059,10 @@
 
   // Checking attributes of current function definition
   // dllimport attribute.
-  if (FD->getAttr<DLLImportAttr>() && (!FD->getAttr<DLLExportAttr>())) {
+  if (FD->getAttr<DLLImportAttr>(Context) && 
+      (!FD->getAttr<DLLExportAttr>(Context))) {
     // dllimport attribute cannot be applied to definition.
-    if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+    if (!(FD->getAttr<DLLImportAttr>(Context))->isInherited()) {
       Diag(FD->getLocation(),
            diag::err_attribute_can_be_applied_only_to_symbol_declaration)
         << "dllimport";
@@ -3227,8 +3231,9 @@
     unsigned FormatIdx;
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
-      if (!FD->getAttr<FormatAttr>())
-        FD->addAttr(::new (Context) FormatAttr("printf", FormatIdx + 1,
+      if (!FD->getAttr<FormatAttr>(Context))
+        FD->addAttr(Context,
+                    ::new (Context) FormatAttr("printf", FormatIdx + 1,
                                              HasVAListArg ? 0 : FormatIdx + 2));
     }
 
@@ -3237,8 +3242,8 @@
     // IRgen to use LLVM intrinsics for such functions.
     if (!getLangOptions().MathErrno &&
         Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
-      if (!FD->getAttr<ConstAttr>())
-        FD->addAttr(::new (Context) ConstAttr());
+      if (!FD->getAttr<ConstAttr>(Context))
+        FD->addAttr(Context, ::new (Context) ConstAttr());
     }
   }
 
@@ -3256,15 +3261,17 @@
     return;
 
   if (Name->isStr("NSLog") || Name->isStr("NSLogv")) {
-    if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
+    if (const FormatAttr *Format = FD->getAttr<FormatAttr>(Context)) {
       // FIXME: We known better than our headers.
       const_cast<FormatAttr *>(Format)->setType("printf");
     } else 
-      FD->addAttr(::new (Context) FormatAttr("printf", 1,
+      FD->addAttr(Context,
+                  ::new (Context) FormatAttr("printf", 1,
                                              Name->isStr("NSLogv") ? 0 : 2));
   } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
-    if (!FD->getAttr<FormatAttr>())
-      FD->addAttr(::new (Context) FormatAttr("printf", 2,
+    if (!FD->getAttr<FormatAttr>(Context))
+      FD->addAttr(Context,
+                  ::new (Context) FormatAttr("printf", 2,
                                              Name->isStr("vasprintf") ? 0 : 3));
   }
 }
@@ -3620,7 +3627,7 @@
     // the #pragma tokens are effectively skipped over during the
     // parsing of the struct).
     if (unsigned Alignment = getPragmaPackAlignment())
-      New->addAttr(::new (Context) PackedAttr(Alignment * 8));
+      New->addAttr(Context, ::new (Context) PackedAttr(Alignment * 8));
   }
 
   if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) {
@@ -4471,7 +4478,7 @@
 
   // FIXME: This implementation is an ugly hack!
   if (PrevDecl) {
-    PrevDecl->addAttr(::new (Context) WeakAttr());
+    PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
     return;
   }
   Diag(PragmaLoc, diag::err_unsupported_pragma_weak);
@@ -4487,8 +4494,8 @@
 
   // FIXME: This implementation is an ugly hack!
   if (PrevDecl) {
-    PrevDecl->addAttr(::new (Context) AliasAttr(AliasName->getName()));
-    PrevDecl->addAttr(::new (Context) WeakAttr());
+    PrevDecl->addAttr(Context, ::new (Context) AliasAttr(AliasName->getName()));
+    PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
     return;
   }
   Diag(PragmaLoc, diag::err_unsupported_pragma_weak);
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index b309b3b..d57630e 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -284,7 +284,7 @@
   }
   
   if (TagDecl *TD = dyn_cast<TagDecl>(d))
-    TD->addAttr(::new (S.Context) PackedAttr(1));
+    TD->addAttr(S.Context, ::new (S.Context) PackedAttr(1));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
     // If the alignment is less than or equal to 8 bits, the packed attribute
     // has no effect.
@@ -293,7 +293,7 @@
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
         << Attr.getName() << FD->getType();
     else
-      FD->addAttr(::new (S.Context) PackedAttr(1));
+      FD->addAttr(S.Context, ::new (S.Context) PackedAttr(1));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
@@ -308,7 +308,7 @@
   // The IBOutlet attribute only applies to instance variables of Objective-C
   // classes.
   if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
-    d->addAttr(::new (S.Context) IBOutletAttr());
+    d->addAttr(S.Context, ::new (S.Context) IBOutletAttr());
   else
     S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
 }
@@ -380,7 +380,7 @@
   unsigned* start = &NonNullArgs[0];
   unsigned size = NonNullArgs.size();
   std::sort(start, start + size);
-  d->addAttr(::new (S.Context) NonNullAttr(start, size));
+  d->addAttr(S.Context, ::new (S.Context) NonNullAttr(start, size));
 }
 
 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -405,7 +405,7 @@
   
   // FIXME: check if target symbol exists in current file
   
-  d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
+  d->addAttr(S.Context, ::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
 }
 
 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 
@@ -422,7 +422,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) AlwaysInlineAttr());
+  d->addAttr(S.Context, ::new (S.Context) AlwaysInlineAttr());
 }
 
 static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
@@ -447,13 +447,13 @@
 
 static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   if (HandleCommonNoReturnAttr(d, Attr, S))  
-    d->addAttr(::new (S.Context) NoReturnAttr());
+    d->addAttr(S.Context, ::new (S.Context) NoReturnAttr());
 }
 
 static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
                                        Sema &S) {
   if (HandleCommonNoReturnAttr(d, Attr, S))  
-    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+    d->addAttr(S.Context, ::new (S.Context) AnalyzerNoReturnAttr());
 }
 
 static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -469,7 +469,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) UnusedAttr());
+  d->addAttr(S.Context, ::new (S.Context) UnusedAttr());
 }
 
 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -490,7 +490,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) UsedAttr());
+  d->addAttr(S.Context, ::new (S.Context) UsedAttr());
 }
 
 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -519,7 +519,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) ConstructorAttr(priority));
+  d->addAttr(S.Context, ::new (S.Context) ConstructorAttr(priority));
 }
 
 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -548,7 +548,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) DestructorAttr(priority));
+  d->addAttr(S.Context, ::new (S.Context) DestructorAttr(priority));
 }
 
 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -558,7 +558,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) DeprecatedAttr());
+  d->addAttr(S.Context, ::new (S.Context) DeprecatedAttr());
 }
 
 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -568,7 +568,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) UnavailableAttr());
+  d->addAttr(S.Context, ::new (S.Context) UnavailableAttr());
 }
 
 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -605,7 +605,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) VisibilityAttr(type));
+  d->addAttr(S.Context, ::new (S.Context) VisibilityAttr(type));
 }
 
 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -621,7 +621,7 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) ObjCExceptionAttr());
+  D->addAttr(S.Context, ::new (S.Context) ObjCExceptionAttr());
 }
 
 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -637,7 +637,7 @@
       return;
     }
   }
-  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+  D->addAttr(S.Context, ::new (S.Context) ObjCNSObjectAttr());
 }
 
 static void 
@@ -652,7 +652,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) OverloadableAttr());
+  D->addAttr(S.Context, ::new (S.Context) OverloadableAttr());
 }
 
 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -676,7 +676,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) BlocksAttr(type));
+  d->addAttr(S.Context, ::new (S.Context) BlocksAttr(type));
 }
 
 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -768,7 +768,7 @@
       << Attr.getName() << 6 /*function, method or block */;
     return;
   }
-  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+  d->addAttr(S.Context, ::new (S.Context) SentinelAttr(sentinel, nullPos));
 }
 
 static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -786,7 +786,7 @@
     return;
   }
   
-  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
+  Fn->addAttr(S.Context, ::new (S.Context) WarnUnusedResultAttr());
 }
 
 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -803,7 +803,7 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) WeakAttr());
+  D->addAttr(S.Context, ::new (S.Context) WeakAttr());
 }
 
 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -836,7 +836,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakImportAttr());
+  D->addAttr(S.Context, ::new (S.Context) WeakImportAttr());
 }
 
 static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -848,7 +848,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLImportAttr());
+    D->addAttr(S.Context, ::new (S.Context) DLLImportAttr());
     return;
   }
 
@@ -876,12 +876,12 @@
     }
   }
 
-  if (D->getAttr<DLLExportAttr>()) {
+  if (D->getAttr<DLLExportAttr>(S.Context)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLImportAttr());
+  D->addAttr(S.Context, ::new (S.Context) DLLImportAttr());
 }
 
 static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -893,7 +893,7 @@
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLExportAttr());
+    D->addAttr(S.Context, ::new (S.Context) DLLExportAttr());
     return;
   }
 
@@ -912,7 +912,7 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLExportAttr());
+  D->addAttr(S.Context, ::new (S.Context) DLLExportAttr());
 }
 
 static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -931,7 +931,8 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
     return;
   }
-  D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
+  D->addAttr(S.Context, 
+             ::new (S.Context) SectionAttr(std::string(SE->getStrData(),
                                                      SE->getByteLength())));
 }
 
@@ -950,13 +951,13 @@
   }
 
   // stdcall and fastcall attributes are mutually incompatible.
-  if (d->getAttr<FastCallAttr>()) {
+  if (d->getAttr<FastCallAttr>(S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
       << "stdcall" << "fastcall";
     return;
   }
 
-  d->addAttr(::new (S.Context) StdCallAttr());
+  d->addAttr(S.Context, ::new (S.Context) StdCallAttr());
 }
 
 static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -973,13 +974,13 @@
   }
 
   // stdcall and fastcall attributes are mutually incompatible.
-  if (d->getAttr<StdCallAttr>()) {
+  if (d->getAttr<StdCallAttr>(S.Context)) {
     S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
       << "fastcall" << "stdcall";
     return;
   }
 
-  d->addAttr(::new (S.Context) FastCallAttr());
+  d->addAttr(S.Context, ::new (S.Context) FastCallAttr());
 }
 
 static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -989,7 +990,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) NoThrowAttr());
+  d->addAttr(S.Context, ::new (S.Context) NoThrowAttr());
 }
 
 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -999,7 +1000,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) ConstAttr());
+  d->addAttr(S.Context, ::new (S.Context) ConstAttr());
 }
 
 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1009,7 +1010,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) PureAttr());
+  d->addAttr(S.Context, ::new (S.Context) PureAttr());
 }
 
 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1067,7 +1068,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) CleanupAttr(FD));
+  d->addAttr(S.Context, ::new (S.Context) CleanupAttr(FD));
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute
@@ -1130,7 +1131,7 @@
     return;
   }    
   
-  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+  d->addAttr(S.Context, ::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
 }
 
 /// Handle __attribute__((format(type,idx,firstarg))) attributes
@@ -1271,7 +1272,8 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
+  d->addAttr(S.Context, 
+             ::new (S.Context) FormatAttr(std::string(Format, FormatLen),
                             Idx.getZExtValue(), FirstArg.getZExtValue()));
 }
 
@@ -1339,7 +1341,7 @@
     }
   }
 
-  RD->addAttr(::new (S.Context) TransparentUnionAttr());
+  RD->addAttr(S.Context, ::new (S.Context) TransparentUnionAttr());
 }
 
 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1357,7 +1359,8 @@
     S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
     return;
   }
-  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
+  d->addAttr(S.Context, 
+             ::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
                                                         SE->getByteLength())));
 }
 
@@ -1373,7 +1376,7 @@
     // FIXME: This should be the target specific maximum alignment.
     // (For now we just use 128 bits which is the maximum on X86).
     Align = 128;
-    d->addAttr(::new (S.Context) AlignedAttr(Align));
+    d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Align));
     return;
   }
   
@@ -1390,7 +1393,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
+  d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
 }
 
 /// HandleModeAttr - This attribute modifies the width of a decl with
@@ -1571,7 +1574,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) NodebugAttr());
+  d->addAttr(S.Context, ::new (S.Context) NodebugAttr());
 }
 
 static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1587,7 +1590,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) NoinlineAttr());
+  d->addAttr(S.Context, ::new (S.Context) NoinlineAttr());
 }
 
 static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1609,7 +1612,7 @@
     return;
   }
   
-  d->addAttr(::new (S.Context) GNUInlineAttr());
+  d->addAttr(S.Context, ::new (S.Context) GNUInlineAttr());
 }
 
 static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1645,7 +1648,8 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+  d->addAttr(S.Context, 
+             ::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1678,10 +1682,10 @@
       assert(0 && "invalid ownership attribute");
       return;
     case AttributeList::AT_cf_returns_retained:
-      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+      d->addAttr(S.Context, ::new (S.Context) CFReturnsRetainedAttr());
       return;
     case AttributeList::AT_ns_returns_retained:
-      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+      d->addAttr(S.Context, ::new (S.Context) NSReturnsRetainedAttr());
       return;
   };
 }
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 672e487..7e82783 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -39,7 +39,7 @@
 /// referenced), false otherwise.
 bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
   // See if the decl is deprecated.
-  if (D->getAttr<DeprecatedAttr>()) {
+  if (D->getAttr<DeprecatedAttr>(Context)) {
     // Implementing deprecated stuff requires referencing deprecated
     // stuff. Don't warn if we are implementing a deprecated
     // construct.
@@ -48,7 +48,7 @@
     if (NamedDecl *ND = getCurFunctionOrMethodDecl()) {
       // If this reference happens *in* a deprecated function or method, don't
       // warn.
-      isSilenced = ND->getAttr<DeprecatedAttr>();
+      isSilenced = ND->getAttr<DeprecatedAttr>(Context);
       
       // If this is an Objective-C method implementation, check to see if the
       // method was deprecated on the declaration, not the definition.
@@ -61,7 +61,7 @@
           MD = Impl->getClassInterface()->getMethod(Context, 
                                                     MD->getSelector(),
                                                     MD->isInstanceMethod());
-          isSilenced |= MD && MD->getAttr<DeprecatedAttr>();
+          isSilenced |= MD && MD->getAttr<DeprecatedAttr>(Context);
         }
       }
     }
@@ -80,7 +80,7 @@
   }
 
   // See if the decl is unavailable
-  if (D->getAttr<UnavailableAttr>()) {
+  if (D->getAttr<UnavailableAttr>(Context)) {
     Diag(Loc, diag::warn_unavailable) << D->getDeclName();
     Diag(D->getLocation(), diag::note_unavailable_here) << 0;
   }
@@ -95,7 +95,7 @@
 void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
                                  Expr **Args, unsigned NumArgs)
 {
-  const SentinelAttr *attr = D->getAttr<SentinelAttr>();
+  const SentinelAttr *attr = D->getAttr<SentinelAttr>(Context);
   if (!attr) 
     return;
   int sentinelPos = attr->getSentinel();
@@ -1127,7 +1127,7 @@
   if (CurBlock && ShouldSnapshotBlockValueReference(CurBlock, VD)) {
     QualType ExprTy = VD->getType().getNonReferenceType();
     // The BlocksAttr indicates the variable is bound by-reference.
-    if (VD->getAttr<BlocksAttr>())
+    if (VD->getAttr<BlocksAttr>(Context))
       return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true));
 
     // Variable will be bound by-copy, make it const within the closure.
@@ -3408,7 +3408,7 @@
   // If the ArgType is a Union type, we want to handle a potential 
   // transparent_union GCC extension.
   const RecordType *UT = ArgType->getAsUnionType();
-  if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
+  if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>(Context))
     return Incompatible;
 
   // The field to initialize within the transparent union.
@@ -5142,7 +5142,7 @@
     CurBlock->hasPrototype = true;
     CurBlock->isVariadic = false;
     // Check for a valid sentinel attribute on this block.
-    if (CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+    if (CurBlock->TheDecl->getAttr<SentinelAttr>(Context)) {
       Diag(ParamInfo.getAttributes()->getLoc(), 
            diag::warn_attribute_sentinel_not_variadic) << 1;
       // FIXME: remove the attribute.
@@ -5190,7 +5190,8 @@
       PushOnScopeChains(*AI, CurBlock->TheScope);
 
   // Check for a valid sentinel attribute on this block.
-  if (!CurBlock->isVariadic && CurBlock->TheDecl->getAttr<SentinelAttr>()) {
+  if (!CurBlock->isVariadic && 
+      CurBlock->TheDecl->getAttr<SentinelAttr>(Context)) {
     Diag(ParamInfo.getAttributes()->getLoc(), 
          diag::warn_attribute_sentinel_not_variadic) << 1;
     // FIXME: remove the attribute.
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index f29cd17..52de4e6 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -894,7 +894,7 @@
             continue;
         }
 
-        if ((*I)->getAttr<OverloadableAttr>()) {
+        if ((*I)->getAttr<OverloadableAttr>(Context)) {
           // If this declaration has the "overloadable" attribute, we
           // might have a set of overloaded functions.
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 98ee13a..e81985b 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -3484,7 +3484,7 @@
   // Best is the best viable function.
   if (Best->Function &&
       (Best->Function->isDeleted() || 
-       Best->Function->getAttr<UnavailableAttr>()))
+       Best->Function->getAttr<UnavailableAttr>(Context)))
     return OR_Deleted;
 
   // If Best refers to a function that is either deleted (C++0x) or
@@ -3506,7 +3506,7 @@
     if (Cand->Viable || !OnlyViable) {
       if (Cand->Function) {
         if (Cand->Function->isDeleted() ||
-            Cand->Function->getAttr<UnavailableAttr>()) {
+            Cand->Function->getAttr<UnavailableAttr>(Context)) {
           // Deleted or "unavailable" function.
           Diag(Cand->Function->getLocation(), diag::err_ovl_candidate_deleted)
             << Cand->Function->isDeleted();
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index aa9b8db..7797e27 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -84,7 +84,7 @@
     
     SourceLocation Loc;
     SourceRange R1, R2;
-    if (!E->isUnusedResultAWarning(Loc, R1, R2))
+    if (!E->isUnusedResultAWarning(Loc, R1, R2, Context))
       continue;
 
     Diag(Loc, diag::warn_unused_expr) << R1 << R2;
@@ -759,7 +759,7 @@
   }
   QualType FnRetType = QualType(CurBlock->ReturnType, 0);
 
-  if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
+  if (CurBlock->TheDecl->hasAttr<NoReturnAttr>(Context)) {
     Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
       << getCurFunctionOrMethodDecl()->getDeclName();
     return StmtError();
@@ -835,7 +835,7 @@
   QualType FnRetType;
   if (const FunctionDecl *FD = getCurFunctionDecl()) {
     FnRetType = FD->getResultType();
-    if (FD->hasAttr<NoReturnAttr>())
+    if (FD->hasAttr<NoReturnAttr>(Context))
       Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
         << getCurFunctionOrMethodDecl()->getDeclName();
   } else if (ObjCMethodDecl *MD = getCurMethodDecl())