Create a subject list for the `used` attribute rather than use custom checking logic.

This changes the diagnostic wording somewhat, but otherwise intends no functional change to the attribute.

llvm-svn: 326665
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index fee61e1..a58726f 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2086,23 +2086,6 @@
       AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
 }
 
-static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &AL) {
-  if (const auto *VD = dyn_cast<VarDecl>(D)) {
-    if (VD->hasLocalStorage()) {
-      S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL.getName();
-      return;
-    }
-  } else if (!isFunctionOrMethod(D)) {
-    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << AL.getName() << ExpectedVariableOrFunction;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             UsedAttr(AL.getRange(), S.Context,
-                      AL.getAttributeSpellingListIndex()));
-}
-
 static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &AL) {
   bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
 
@@ -6248,7 +6231,7 @@
     handleDisableTailCallsAttr(S, D, AL);
     break;
   case AttributeList::AT_Used:
-    handleUsedAttr(S, D, AL);
+    handleSimpleAttribute<UsedAttr>(S, D, AL);
     break;
   case AttributeList::AT_Visibility:
     handleVisibilityAttr(S, D, AL, false);