[cfe-commits] r123666 - in /cfe/trunk: include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h include/clang/Sema/Sema.h lib/Parse/ParsePragma.cpp lib/Parse/ParseStmt.cpp lib/Parse/Parser.cpp lib/Sema/SemaAttr.cpp test/SemaCXX/pragma-unused.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Mon Jan 17 10:58:44 PST 2011


Author: akirtzidis
Date: Mon Jan 17 12:58:44 2011
New Revision: 123666

URL: http://llvm.org/viewvc/llvm-project?rev=123666&view=rev
Log:
Convert "#pragma unused(...)" into tokens for the parser.
This allows us to cache a "#pragma unused" that occurs inside an inline C++ member function.
Fixes rdar://8829590&8770988.

Added:
    cfe/trunk/test/SemaCXX/pragma-unused.cpp
Modified:
    cfe/trunk/include/clang/Basic/TokenKinds.def
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParsePragma.cpp
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/SemaAttr.cpp

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=123666&r1=123665&r2=123666&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Mon Jan 17 12:58:44 2011
@@ -433,6 +433,12 @@
 ANNOTATION(template_id)  // annotation for a C++ template-id that names a
                          // function template specialization (not a type),
                          // e.g., "std::swap<int>"
+
+// Annotation for #pragma unused(...)
+// For each argument inside the parentheses the pragma handler will produce
+// one 'pragma_unused' annotation token followed by the argument token.
+ANNOTATION(pragma_unused)
+
 #undef ANNOTATION
 #undef OBJC2_AT_KEYWORD
 #undef OBJC1_AT_KEYWORD

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=123666&r1=123665&r2=123666&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jan 17 12:58:44 2011
@@ -349,6 +349,9 @@
   /// based on context.
   void CodeCompletionRecovery();
 
+  /// \brief Handle the annotation token produced for #pragma unused(...)
+  void HandlePragmaUnused();
+
   /// GetLookAheadToken - This peeks ahead N tokens and returns that token
   /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
   /// returns the token after Tok, etc.

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=123666&r1=123665&r2=123666&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jan 17 12:58:44 2011
@@ -4299,11 +4299,9 @@
                        SourceLocation RParenLoc);
 
   /// ActOnPragmaUnused - Called on well-formed '#pragma unused'.
-  void ActOnPragmaUnused(const Token *Identifiers,
-                         unsigned NumIdentifiers, Scope *curScope,
-                         SourceLocation PragmaLoc,
-                         SourceLocation LParenLoc,
-                         SourceLocation RParenLoc);
+  void ActOnPragmaUnused(const Token &Identifier,
+                         Scope *curScope,
+                         SourceLocation PragmaLoc);
 
   /// ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... .
   void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,

Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=123666&r1=123665&r2=123666&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Mon Jan 17 12:58:44 2011
@@ -17,6 +17,17 @@
 #include "clang/Lex/Preprocessor.h"
 using namespace clang;
 
+/// \brief Handle the annotation token produced for #pragma unused(...)
+///
+/// Each annot_pragma_unused is followed by the argument token so e.g.
+/// "#pragma unused(x,y)" becomes:
+/// annot_pragma_unused 'x' annot_pragma_unused 'y'
+void Parser::HandlePragmaUnused() {
+  assert(Tok.is(tok::annot_pragma_unused));
+  SourceLocation UnusedLoc = ConsumeToken();
+  Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
+  ConsumeToken(); // The argument token.
+}
 
 // #pragma GCC visibility comes in two variants:
 //   'push' '(' [visibility] ')'
@@ -301,9 +312,20 @@
   assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
   assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
 
-  // Perform the action to handle the pragma.
-  Actions.ActOnPragmaUnused(Identifiers.data(), Identifiers.size(),
-                            parser.getCurScope(), UnusedLoc, LParenLoc, RParenLoc);
+  // For each identifier token, insert into the token stream a
+  // annot_pragma_unused token followed by the identifier token.
+  // This allows us to cache a "#pragma unused" that occurs inside an inline
+  // C++ member function.
+
+  Token *Toks = new Token[2*Identifiers.size()];
+  for (unsigned i=0; i != Identifiers.size(); i++) {
+    Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
+    pragmaUnusedTok.startToken();
+    pragmaUnusedTok.setKind(tok::annot_pragma_unused);
+    pragmaUnusedTok.setLocation(UnusedLoc);
+    idTok = Identifiers[i];
+  }
+  PP.EnterTokenStream(Toks, 2*Identifiers.size(), /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
 }
 
 // #pragma weak identifier

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=123666&r1=123665&r2=123666&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Mon Jan 17 12:58:44 2011
@@ -465,6 +465,12 @@
 
   StmtVector Stmts(Actions);
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+
+    if (Tok.is(tok::annot_pragma_unused)) {
+      HandlePragmaUnused();
+      continue;
+    }
+
     StmtResult R;
     if (Tok.isNot(tok::kw___extension__)) {
       R = ParseStatementOrDeclaration(Stmts, false);

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=123666&r1=123665&r2=123666&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Jan 17 12:58:44 2011
@@ -404,6 +404,10 @@
 /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
 /// action tells us to.  This returns true if the EOF was encountered.
 bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
+
+  while (Tok.is(tok::annot_pragma_unused))
+    HandlePragmaUnused();
+
   Result = DeclGroupPtrTy();
   if (Tok.is(tok::eof)) {
     Actions.ActOnEndOfTranslationUnit();

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=123666&r1=123665&r2=123666&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Mon Jan 17 12:58:44 2011
@@ -263,37 +263,31 @@
   }
 }
 
-void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
-                             Scope *curScope,
-                             SourceLocation PragmaLoc,
-                             SourceLocation LParenLoc,
-                             SourceLocation RParenLoc) {
-
-  for (unsigned i = 0; i < NumIdentifiers; ++i) {
-    const Token &Tok = Identifiers[i];
-    IdentifierInfo *Name = Tok.getIdentifierInfo();
-    LookupResult Lookup(*this, Name, Tok.getLocation(), LookupOrdinaryName);
-    LookupParsedName(Lookup, curScope, NULL, true);
-
-    if (Lookup.empty()) {
-      Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
-        << Name << SourceRange(Tok.getLocation());
-      continue;
-    }
-
-    VarDecl *VD = Lookup.getAsSingle<VarDecl>();
-    if (!VD || !(VD->hasLocalStorage() || VD->isStaticLocal())) {
-      Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar)
-        << Name << SourceRange(Tok.getLocation());
-      continue;
-    }
+void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
+                             SourceLocation PragmaLoc) {
 
-    // Warn if this was used before being marked unused.
-    if (VD->isUsed())
-      Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
+  IdentifierInfo *Name = IdTok.getIdentifierInfo();
+  LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
+  LookupParsedName(Lookup, curScope, NULL, true);
+
+  if (Lookup.empty()) {
+    Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
+      << Name << SourceRange(IdTok.getLocation());
+    return;
+  }
 
-    VD->addAttr(::new (Context) UnusedAttr(Tok.getLocation(), Context));
+  VarDecl *VD = Lookup.getAsSingle<VarDecl>();
+  if (!VD || !(VD->hasLocalStorage() || VD->isStaticLocal())) {
+    Diag(PragmaLoc, diag::warn_pragma_unused_expected_localvar)
+      << Name << SourceRange(IdTok.getLocation());
+    return;
   }
+
+  // Warn if this was used before being marked unused.
+  if (VD->isUsed())
+    Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
+
+  VD->addAttr(::new (Context) UnusedAttr(IdTok.getLocation(), Context));
 }
 
 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;

Added: cfe/trunk/test/SemaCXX/pragma-unused.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pragma-unused.cpp?rev=123666&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/pragma-unused.cpp (added)
+++ cfe/trunk/test/SemaCXX/pragma-unused.cpp Mon Jan 17 12:58:44 2011
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-parameter -Wunused -verify %s
+
+struct S {
+  void m(int x, int y) {
+    int z;
+    #pragma unused(x,y,z)
+  }
+};





More information about the cfe-commits mailing list