diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2013-09-13 19:35:18 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2013-09-13 19:35:18 +0000 |
commit | 3b1dde63a2ae520b6969d4f16e87e7b3476a5ce6 (patch) | |
tree | a81c707504502a8fde01ecade5ef24482f4ba892 /clang/lib | |
parent | a3c58c02f160bf77ba57f587779b7ac20e126e97 (diff) | |
download | bcm5719-llvm-3b1dde63a2ae520b6969d4f16e87e7b3476a5ce6.tar.gz bcm5719-llvm-3b1dde63a2ae520b6969d4f16e87e7b3476a5ce6.zip |
Switching the WeakRef attribute to using the new checkStringLiteralArgument helper function.
llvm-svn: 190719
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 91 |
1 files changed, 41 insertions, 50 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ceb4a3649be..9d2b269d306 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -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)) |