]> granicus.if.org Git - clang/commitdiff
Switching the WeakRef attribute to using the new checkStringLiteralArgument helper...
authorAaron Ballman <aaron@aaronballman.com>
Fri, 13 Sep 2013 19:35:18 +0000 (19:35 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Fri, 13 Sep 2013 19:35:18 +0000 (19:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190719 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclAttr.cpp
test/SemaCXX/attr-weakref.cpp

index ceb4a3649beba909946d269a52414fd9c4cd70da..9d2b269d30696893838afa2ad7f8728e38e23c88 100644 (file)
@@ -282,6 +282,43 @@ static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
   return true;
 }
 
+/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
+/// If not emit an error and return false. If the argument is an identifier it
+/// will emit an error with a fixit hint and treat it as if it was a string
+/// literal.
+static bool checkStringLiteralArgument(Sema &S, StringRef &Str,
+                                       const AttributeList &Attr,
+                                       unsigned ArgNum,
+                                       SourceLocation *ArgLocation = 0) {
+  // Look for identifiers. If we have one emit a hint to fix it to a literal.
+  if (Attr.isArgIdent(ArgNum)) {
+    IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum);
+    S.Diag(Loc->Loc, diag::err_attribute_argument_type)
+        << Attr.getName() << AANT_ArgumentString
+        << FixItHint::CreateInsertion(Loc->Loc, "\"")
+        << FixItHint::CreateInsertion(S.PP.getLocForEndOfToken(Loc->Loc), "\"");
+    Str = Loc->Ident->getName();
+    if (ArgLocation)
+      *ArgLocation = Loc->Loc;
+    return true;
+  }
+
+  // Now check for an actual string literal.
+  Expr *ArgExpr = Attr.getArgAsExpr(ArgNum);
+  StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
+  if (ArgLocation)
+    *ArgLocation = ArgExpr->getLocStart();
+
+  if (!Literal || !Literal->isAscii()) {
+    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
+        << Attr.getName() << AANT_ArgumentString;
+    return false;
+  }
+
+  Str = Literal->getString();
+  return true;
+}
+
 ///
 /// \brief Check if passed in Decl is a field or potentially shared global var
 /// \return true if the Decl is a field or potentially shared global variable
@@ -1541,64 +1578,18 @@ static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
   // of transforming it into an AliasAttr.  The WeakRefAttr never uses the
   // StringRef parameter it was given anyway.
-  if (Attr.isArgExpr(0)) {
-    Expr *Arg = Attr.getArgAsExpr(0);
-    Arg = Arg->IgnoreParenCasts();
-    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-
-    if (!Str || !Str->isAscii()) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-        << Attr.getName() << 1 << AANT_ArgumentString;
-      return;
-    }
+  StringRef Str;
+  if (Attr.getNumArgs() && checkStringLiteralArgument(S, Str, Attr, 0))
     // GCC will accept anything as the argument of weakref. Should we
     // check for an existing decl?
-    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
-                                           Str->getString()));
-  }
+    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
+                                        Attr.getAttributeSpellingListIndex()));
 
   D->addAttr(::new (S.Context)
              WeakRefAttr(Attr.getRange(), S.Context,
                          Attr.getAttributeSpellingListIndex()));
 }
 
-/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
-/// If not emit an error and return false. If the argument is an identifier it
-/// will emit an error with a fixit hint and treat it as if it was a string
-/// literal.
-static bool checkStringLiteralArgument(Sema &S, StringRef &Str,
-                                       const AttributeList &Attr,
-                                       unsigned ArgNum,
-                                       SourceLocation *ArgLocation = 0) {
-  // Look for identifiers. If we have one emit a hint to fix it to a literal.
-  if (Attr.isArgIdent(ArgNum)) {
-    IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum);
-    S.Diag(Loc->Loc, diag::err_attribute_argument_type)
-        << Attr.getName() << AANT_ArgumentString
-        << FixItHint::CreateInsertion(Loc->Loc, "\"")
-        << FixItHint::CreateInsertion(S.PP.getLocForEndOfToken(Loc->Loc), "\"");
-    Str = Loc->Ident->getName();
-    if (ArgLocation)
-      *ArgLocation = Loc->Loc;
-    return true;
-  }
-
-  // Now check for an actual string literal.
-  Expr *ArgExpr = Attr.getArgAsExpr(ArgNum);
-  StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
-  if (ArgLocation)
-    *ArgLocation = ArgExpr->getLocStart();
-
-  if (!Literal || !Literal->isAscii()) {
-    S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
-        << Attr.getName() << AANT_ArgumentString;
-    return false;
-  }
-
-  Str = Literal->getString();
-  return true;
-}
-
 static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   StringRef Str;
   if (!checkStringLiteralArgument(S, Str, Attr, 0))
index f3d7a6241c91d6fcf2eab6c3e394f88f8719d918..0c3f1d20e7f79b0e7cc3a88e420ad700c25b6c03 100644 (file)
@@ -32,3 +32,5 @@ int a9 __attribute__((weakref));  // expected-error {{weakref declaration of 'a9
 
 static int a10();
 int a10() __attribute__((weakref ("foo")));
+
+static int v __attribute__((weakref(a1), alias("foo"))); // expected-error {{'weakref' attribute requires a string}}