Switching the WeakRef attribute to using the new checkStringLiteralArgument helper function.

llvm-svn: 190719
This commit is contained in:
Aaron Ballman 2013-09-13 19:35:18 +00:00
parent a3c58c02f1
commit 3b1dde63a2
2 changed files with 43 additions and 50 deletions

View 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))

View 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}}