[cfe-commits] r78019 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h lib/Parse/ParsePragma.cpp lib/Sema/Sema.h lib/Sema/SemaAttr.cpp test/Sema/pragma-unused.c

Ted Kremenek kremenek at apple.com
Mon Aug 3 16:24:58 PDT 2009


Author: kremenek
Date: Mon Aug  3 18:24:57 2009
New Revision: 78019

URL: http://llvm.org/viewvc/llvm-project?rev=78019&view=rev
Log:
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)


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/Parse/ParsePragma.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/test/Sema/pragma-unused.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=78019&r1=78018&r2=78019&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Aug  3 18:24:57 2009
@@ -167,6 +167,8 @@
   "specifying both a name and alignment to 'pop' is undefined">;
 def warn_pragma_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">;
 
+def warn_pragma_unused_undeclared_var : Warning<
+  "undeclared variable %0 used as an argument for '#pragma unused'">;
 def warn_pragma_unused_expected_localvar : Warning<
   "only local variables can be arguments to '#pragma unused'">;
 def err_unsupported_pragma_weak : Error<

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=78019&r1=78018&r2=78019&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Aug  3 18:24:57 2009
@@ -1904,7 +1904,8 @@
   }
   
   /// ActOnPragmaUnused - Called on well formed #pragma unused(...).
-  virtual void ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs,
+  virtual void ActOnPragmaUnused(const Token *Identifiers,
+                                 unsigned NumIdentifiers, Scope *CurScope,
                                  SourceLocation PragmaLoc, 
                                  SourceLocation LParenLoc,
                                  SourceLocation RParenLoc) {

Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=78019&r1=78018&r2=78019&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Mon Aug  3 18:24:57 2009
@@ -126,7 +126,7 @@
   SourceLocation LParenLoc = Tok.getLocation();
   
   // Lex the declaration reference(s).
-  llvm::SmallVector<Action::ExprTy*, 5> Ex;
+  llvm::SmallVector<Token, 5> Identifiers;
   SourceLocation RParenLoc;
   bool LexID = true;
   
@@ -134,27 +134,13 @@
     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());        
+      if (Tok.is(tok::identifier)) {  
+        Identifiers.push_back(Tok);
         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());
-      
+      // Illegal token!
       PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
       return;
     }
@@ -170,11 +156,7 @@
       break;
     }
     
-    // Illegal token! Release the parsed expressions (if any) and emit
-    // a warning.
-    if (!Ex.empty())
-      Action::MultiExprArg Release(Actions, &Ex[0], Ex.size());
-    
+    // Illegal token!
     PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
     return;
   }
@@ -188,10 +170,11 @@
 
   // 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");
+  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
 
   // Perform the action to handle the pragma.    
-  Actions.ActOnPragmaUnused(&Ex[0], Ex.size(), UnusedLoc, LParenLoc, RParenLoc);
+  Actions.ActOnPragmaUnused(Identifiers.data(), Identifiers.size(),
+                            parser.CurScope, UnusedLoc, LParenLoc, RParenLoc);
 }
 
 // #pragma weak identifier

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=78019&r1=78018&r2=78019&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Aug  3 18:24:57 2009
@@ -2953,7 +2953,8 @@
                                SourceLocation RParenLoc);
   
   /// ActOnPragmaUnused - Called on well-formed '#pragma unused'.
-  virtual void ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs,
+  virtual void ActOnPragmaUnused(const Token *Identifiers,
+                                 unsigned NumIdentifiers, Scope *curScope,
                                  SourceLocation PragmaLoc, 
                                  SourceLocation LParenLoc,
                                  SourceLocation RParenLoc);

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=78019&r1=78018&r2=78019&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Mon Aug  3 18:24:57 2009
@@ -170,42 +170,35 @@
   }
 }
 
-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();;
+  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 (!isa<VarDecl>(d) || !cast<VarDecl>(d)->hasLocalStorage()) {
-      ErrorExpr = Ex;
-      break;
+    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());
   }
 }

Modified: cfe/trunk/test/Sema/pragma-unused.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/pragma-unused.c?rev=78019&r1=78018&r2=78019&view=diff

==============================================================================
--- cfe/trunk/test/Sema/pragma-unused.c (original)
+++ cfe/trunk/test/Sema/pragma-unused.c Mon Aug  3 18:24:57 2009
@@ -16,7 +16,7 @@
 }
 
 void f3(void) {
-  #pragma unused(x) // expected-error{{use of undeclared identifier 'x'}}
+  #pragma unused(x) // expected-warning{{undeclared variable 'x' used as an argument for '#pragma unused'}}
 }
 
 void f4(void) {
@@ -26,7 +26,7 @@
 
 int k;
 void f5(void) {
-  #pragma unused(k) // expected-warning{{only local variables can be arguments to '#pragma unused' - ignored}}
+  #pragma unused(k) // expected-warning{{only local variables can be arguments to '#pragma unused'}}
 }
 
 void f6(void) {
@@ -36,3 +36,8 @@
   }
 }
 
+void f7() {
+  int y;
+  #pragma unused(undeclared, undefined, y) // expected-warning{{undeclared variable 'undeclared' used as an argument for '#pragma unused'}} expected-warning{{undeclared variable 'undefined' used as an argument for '#pragma unused'}}
+}
+





More information about the cfe-commits mailing list