[cfe-commits] r67569 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/Parse/ParsePragma.cpp lib/Parse/ParsePragma.h lib/Parse/Parser.cpp lib/Sema/Sema.h lib/Sema/SemaAttr.cpp test/Sema/pragma-unused.c
Ted Kremenek
kremenek at apple.com
Mon Mar 23 16:00:16 PDT 2009
Thanks Doug. Your suggested fixes would definitely improve the code.
I'll go ahead and implement them.
On Mar 23, 2009, at 3:42 PM, Douglas Gregor wrote:
>
> On Mar 23, 2009, at 3:28 PM, Ted Kremenek wrote:
>
>> Author: kremenek
>> Date: Mon Mar 23 17:28:25 2009
>> New Revision: 67569
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=67569&view=rev
>> Log:
>> Implement '#pragma unused'.
>
> Cool. Some comments below.
>
>> Modified: cfe/trunk/include/clang/Parse/Action.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=67569&r1=67568&r2=67569&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- cfe/trunk/include/clang/Parse/Action.h (original)
>> +++ cfe/trunk/include/clang/Parse/Action.h Mon Mar 23 17:28:25 2009
>> @@ -1483,6 +1483,14 @@
>> SourceLocation RParenLoc) {
>> return;
>> }
>> +
>> + /// ActOnPragmaPack - Called on well formed #pragma pack(...).
>> + virtual void ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs,
>> + SourceLocation PragmaLoc,
>> + SourceLocation LParenLoc,
>> + SourceLocation RParenLoc) {
>> + return;
>> + }
>
> The comment here refers to #pragma pack, not #pragma unused.
>
>
>> +// #pragma unused(identifier)
>> +void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token
>> &UnusedTok) {
>> + // FIXME: Should we be expanding macros here? My guess is no.
>> + SourceLocation UnusedLoc = UnusedTok.getLocation();
>> +
>> + // Lex the left '('.
>> + Token Tok;
>> + PP.Lex(Tok);
>> + if (Tok.isNot(tok::l_paren)) {
>> + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
>> << "unused";
>> + return;
>> + }
>> + SourceLocation LParenLoc = Tok.getLocation();
>> +
>> + // Lex the declaration reference(s).
>> + llvm::SmallVector<Action::ExprTy*, 5> Ex;
>> + SourceLocation RParenLoc;
>> + bool LexID = true;
>> +
>> + while (true) {
>> + PP.Lex(Tok);
>> +
>> + if (LexID) {
>> + if (Tok.is(tok::identifier)) {
>> + Action::OwningExprResult Name =
>> + Actions.ActOnIdentifierExpr(parser.CurScope,
>> Tok.getLocation(),
>> + *Tok.getIdentifierInfo(),
>> false);
>> +
>> + if (Name.isInvalid()) {
>> + if (!Ex.empty())
>> + Action::MultiExprArg Release(Actions, &Ex[0],
>> Ex.size());
>> + return;
>> + }
>> +
>> + Ex.push_back(Name.release());
>> + LexID = false;
>> + continue;
>> + }
>> +
>> + // Illegal token! Release the parsed expressions (if any)
>> and emit
>> + // a warning.
>> + if (!Ex.empty())
>> + Action::MultiExprArg Release(Actions, &Ex[0], Ex.size());
>> +
>> + PP.Diag(Tok.getLocation(),
>> diag::warn_pragma_unused_expected_var);
>> + return;
>> + }
>> +
>> + // We are execting a ')' or a ','.
>> + if (Tok.is(tok::comma)) {
>> + LexID = true;
>> + continue;
>> + }
>> +
>> + if (Tok.is(tok::r_paren)) {
>> + RParenLoc = Tok.getLocation();
>> + break;
>> + }
>> +
>> + // Illegal token! Release the parsed expressions (if any) and
>> emit
>> + // a warning.
>> + if (!Ex.empty())
>> + Action::MultiExprArg Release(Actions, &Ex[0], Ex.size());
>> +
>> + PP.Diag(Tok.getLocation(),
>> diag::warn_pragma_unused_expected_punc);
>> + return;
>> + }
>> +
>> + // Verify that we have a location for the right parenthesis.
>> + assert(RParenLoc.isValid() && "Valid '#pragma unused' must have
>> ')'");
>> + assert(!Ex.empty() && "Valid '#pragma unused' must have
>> arguments");
>> +
>> + // Perform the action to handle the pragma.
>> + Actions.ActOnPragmaUnused(&Ex[0], Ex.size(), UnusedLoc,
>> LParenLoc, RParenLoc);
>> +}
>
> We're going through some extra work here. For each name, we call
> ActOnIdentifierExpr to build a DeclRefExpr, then we have to reverse-
> engineer the DeclRefExpr in ActOnPragmaUnused. Perhaps it would be
> easier to pass arrays of identifiers and locations into
> ActOnPragmaUnused, and skip the interim representation as a
> DeclRefExpr? ActOnPragmaUnused will, of course, need to receive the
> scope so that it can perform lookup for those identifiers.
>
>
>> Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=67569&r1=67568&r2=67569&view=diff
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaAttr.cpp Mon Mar 23 17:28:25 2009
>> @@ -170,3 +170,41 @@
>> }
>> }
>>
>> +void Sema::ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs,
>> + 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;
>> + }
>> + }
>> +
>> + // 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());
>> + }
>> +}
>
> Much of this code could be simplified if we just performed the
> lookup of these variables here. Also, aren't we leaking the
> DeclRefExprs in the case where the #pragma unused is well-formed?
>
> - Doug
More information about the cfe-commits
mailing list