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