[cfe-commits] r38632 - in /cfe/cfe/trunk: Lex/Preprocessor.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Lex/MacroInfo.h include/clang/Lex/Preprocessor.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:23:22 PDT 2007


Author: sabre
Date: Wed Jul 11 11:23:22 2007
New Revision: 38632

URL: http://llvm.org/viewvc/llvm-project?rev=38632&view=rev
Log:
Implement -Wunused-macros functionality.

Modified:
    cfe/cfe/trunk/Lex/Preprocessor.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Lex/MacroInfo.h
    cfe/cfe/trunk/include/clang/Lex/Preprocessor.h

Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=38632&r1=38631&r2=38632&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:23:22 2007
@@ -352,16 +352,14 @@
 bool Preprocessor::isInPrimaryFile() const {
   unsigned NumLexersFound = 0;
   if (CurLexer && !CurLexer->Is_PragmaLexer)
-    ++NumLexersFound;
+    return CurLexer->isMainFile();
   
-  /// If there are any stacked lexers, we're in a #include.
+  // If there are any stacked lexers, we're in a #include.
   for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i)
-    if (IncludeMacroStack[i].TheLexer) {
-      if (!IncludeMacroStack[i].TheLexer->Is_PragmaLexer)
-        if (++NumLexersFound > 1)
-          return false;
-    }
-  return NumLexersFound < 2;
+    if (IncludeMacroStack[i].TheLexer &&
+        !IncludeMacroStack[i].TheLexer->Is_PragmaLexer)
+      return IncludeMacroStack[i].TheLexer->isMainFile();
+  return false;
 }
 
 /// getCurrentLexer - Return the current file lexer being lexed from.  Note
@@ -384,7 +382,8 @@
 /// start lexing tokens from it instead of the current buffer.  Return true
 /// on failure.
 void Preprocessor::EnterSourceFile(unsigned FileID,
-                                   const DirectoryLookup *CurDir) {
+                                   const DirectoryLookup *CurDir,
+                                   bool isMainFile) {
   assert(CurMacroExpander == 0 && "Cannot #include a file inside a macro!");
   ++NumEnteredSourceFiles;
   
@@ -393,6 +392,7 @@
 
   const SourceBuffer *Buffer = SourceMgr.getBuffer(FileID);
   Lexer *TheLexer = new Lexer(Buffer, FileID, *this);
+  if (isMainFile) TheLexer->setIsMainFile();
   EnterSourceFileWithLexer(TheLexer, CurDir);
 }  
   
@@ -490,6 +490,9 @@
 void Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier, 
                                                  MacroInfo *MI) {
   ++NumMacroExpanded;
+  
+  // Notice that this macro has been used.
+  MI->setIsUsed(true);
 
   // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
   if (MI->isBuiltinMacro())
@@ -689,6 +692,18 @@
   }  
 }
 
+namespace {
+struct UnusedIdentifierReporter : public IdentifierVisitor {
+  Preprocessor &PP;
+  UnusedIdentifierReporter(Preprocessor &pp) : PP(pp) {}
+
+  void VisitIdentifier(IdentifierTokenInfo &ITI) const {
+    if (ITI.getMacroInfo() && !ITI.getMacroInfo()->isUsed())
+      PP.Diag(ITI.getMacroInfo()->getDefinitionLoc(), diag::pp_macro_not_used);
+  }
+};
+}
+
 //===----------------------------------------------------------------------===//
 // Lexer Event Handling.
 //===----------------------------------------------------------------------===//
@@ -775,6 +790,9 @@
   // We're done with the #included file.
   delete CurLexer;
   CurLexer = 0;
+
+  // This is the end of the top-level file.
+  IdentifierInfo.VisitIdentifiers(UnusedIdentifierReporter(*this));
 }
 
 /// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
@@ -1302,10 +1320,17 @@
     LexUnexpandedToken(Tok);
   }
   
+  // If this is the primary source file, remember that this macro hasn't been
+  // used yet.
+  if (isInPrimaryFile())
+    MI->setIsUsed(false);
+  
   // Finally, if this identifier already had a macro defined for it, verify that
   // the macro bodies are identical and free the old definition.
   if (MacroInfo *OtherMI = MacroNameTok.getIdentifierInfo()->getMacroInfo()) {
-    
+    if (!OtherMI->isUsed())
+      Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
+
     // FIXME: Verify the definition is the same.
     // Macros must be identical.  This means all tokes and whitespace separation
     // must be the same.
@@ -1336,10 +1361,8 @@
   // If the macro is not defined, this is a noop undef, just return.
   if (MI == 0) return;
 
-#if 0 // FIXME: implement warn_unused_macros.
-  if (CPP_OPTION (pfile, warn_unused_macros))
-    _cpp_warn_if_unused_macro (pfile, node, NULL);
-#endif
+  if (!MI->isUsed())
+    Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
   
   // Free macro definition.
   delete MI;

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38632&r1=38631&r2=38632&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:23:22 2007
@@ -98,6 +98,8 @@
      "undefining builtin macro")
 DIAG(pp_redef_builtin_macro, WARNING,
      "redefining builtin macro")
+DIAG(pp_macro_not_used, WARNING,    // -Wunused-macros
+     "macro is not used")
 
 DIAG(ext_pp_import_directive, EXTENSION,
      "#import is a language extension")

Modified: cfe/cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=38632&r1=38631&r2=38632&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/MacroInfo.h Wed Jul 11 11:23:22 2007
@@ -33,30 +33,50 @@
   /// to.
   std::vector<LexerToken> ReplacementTokens;
   
-  /// isDisabled - True if we have started an expansion of this macro already.
+  /// IsDisabled - True if we have started an expansion of this macro already.
   /// This disbles recursive expansion, which would be quite bad for things like
   /// #define A A.
   bool IsDisabled : 1;
   
-  /// isBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
+  /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
   /// it has not yet been redefined or undefined.
   bool IsBuiltinMacro : 1;
+  
+  /// IsUsed - True if this macro is either defined in the main file and has
+  /// been used, or if it is not defined in the main file.  This is used to 
+  /// emit -Wunused-macros diagnostics.
+  bool IsUsed : 1;
 public:
   MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
     IsDisabled = false;
     IsBuiltinMacro = false;
+    IsUsed = true;
   }
   
+  /// getDefinitionLoc - Return the location that the macro was defined at.
+  ///
+  SourceLocation getDefinitionLoc() const { return Location; }
+  
   /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
   ///
   void setIsBuiltinMacro(bool Val = true) {
     IsBuiltinMacro = Val;
   }
   
+  /// setIsUsed - Set the value of the IsUsed flag.
+  ///
+  void setIsUsed(bool Val) {
+    IsUsed = Val;
+  }
+  
   /// isBuiltinMacro - Return true if this macro is a builtin macro, such as
   /// __LINE__, which requires processing before expansion.
   bool isBuiltinMacro() const { return IsBuiltinMacro; }
 
+  /// isUsed - Return false if this macro is defined in the main file and has
+  /// not yet been used.
+  bool isUsed() const { return IsUsed; }
+  
   /// getNumTokens - Return the number of tokens that this macro expands to.
   ///
   unsigned getNumTokens() const {

Modified: cfe/cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=38632&r1=38631&r2=38632&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jul 11 11:23:22 2007
@@ -297,8 +297,10 @@
                               const DirectoryLookup *&CurDir);
   
   /// EnterSourceFile - Add a source file to the top of the include stack and
-  /// start lexing tokens from it instead of the current buffer.
-  void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir);
+  /// start lexing tokens from it instead of the current buffer.  If isMainFile
+  /// is true, this is the main file for the translation unit.
+  void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir,
+                       bool isMainFile = false);
 
   /// EnterMacro - Add a Macro to the top of the include stack and start lexing
   /// tokens from it instead of the current buffer.
@@ -440,7 +442,7 @@
   void Handle_Pragma(LexerToken &Tok);
   
   
-  /// EnterSourceFile - Add a source file to the top of the include stack and
+  /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
   /// start lexing tokens from it instead of the current buffer.
   void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
   





More information about the cfe-commits mailing list