diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-08-03 23:24:57 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-08-03 23:24:57 +0000 |
commit | 7a02a3733cdd2ca672902d869fda4ef2e3f05052 (patch) | |
tree | 818f89d2f2c93249173392518c282bf95e36d034 /lib/Sema/SemaAttr.cpp | |
parent | 48775d5bf05120adb2a953bbcd626405bf666b22 (diff) |
Per advice that Doug Gregor gave me several months ago, clean up the
implementation of '#pragma unused' by not constructing intermediate
DeclRefExprs, but instead do the name lookup directly. The
implementation is greatly simplified.
Along the way, degrade '#pragma unused(undeclaredvariable)' to a
warning instead of being a hard error. This implements:
<rdar://problem/6761874> [sema] allow #pragma unused to reference undefined variable (with warning)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78019 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaAttr.cpp')
-rw-r--r-- | lib/Sema/SemaAttr.cpp | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index 1bf8444c42..6622d53659 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -170,42 +170,35 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, } } -void Sema::ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs, +void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers, + Scope *curScope, SourceLocation PragmaLoc, SourceLocation LParenLoc, SourceLocation RParenLoc) { - - // Verify that all of the expressions are valid before - // modifying the attributes of any referenced decl. - Expr *ErrorExpr = 0; - - for (unsigned i = 0; i < NumExprs; ++i) { - Expr *Ex = (Expr*) Exprs[i]; - if (!isa<DeclRefExpr>(Ex)) { - ErrorExpr = Ex; - break; - } - Decl *d = cast<DeclRefExpr>(Ex)->getDecl();; - - if (!isa<VarDecl>(d) || !cast<VarDecl>(d)->hasLocalStorage()) { - ErrorExpr = Ex; - break; + for (unsigned i = 0; i < NumIdentifiers; ++i) { + const Token &Tok = Identifiers[i]; + IdentifierInfo *Name = Tok.getIdentifierInfo(); + const LookupResult &Lookup = LookupParsedName(curScope, NULL, Name, + LookupOrdinaryName, + false, true, + Tok.getLocation()); + // FIXME: Handle Lookup.isAmbiguous? + + NamedDecl *ND = Lookup.getAsDecl(); + + if (!ND) { + Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) + << Name << SourceRange(Tok.getLocation()); + continue; } - } - - // Delete the expressions if we encountered any error. - if (ErrorExpr) { - Diag(ErrorExpr->getLocStart(), diag::warn_pragma_unused_expected_localvar); - for (unsigned i = 0; i < NumExprs; ++i) - ((Expr*) Exprs[i])->Destroy(Context); - return; - } - // Otherwise, add the 'unused' attribute to each referenced declaration. - for (unsigned i = 0; i < NumExprs; ++i) { - DeclRefExpr *DR = (DeclRefExpr*) Exprs[i]; - DR->getDecl()->addAttr(::new (Context) UnusedAttr()); - DR->Destroy(Context); + if (!isa<VarDecl>(ND) || !cast<VarDecl>(ND)->hasLocalStorage()) { + Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar) + << Name << SourceRange(Tok.getLocation()); + continue; + } + + ND->addAttr(::new (Context) UnusedAttr()); } } |