r301449 - PPCallbacks::MacroUndefined, change signature and add test.

Frederich Munch via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 26 12:47:31 PDT 2017


Author: marsupial
Date: Wed Apr 26 14:47:31 2017
New Revision: 301449

URL: http://llvm.org/viewvc/llvm-project?rev=301449&view=rev
Log:
PPCallbacks::MacroUndefined, change signature and add test.

Summary:
The PPCallbacks::MacroUndefined callback is currently insufficient for clients that need to track the MacroDirectives.
This patch adds an additional argument to PPCallbacks::MacroUndefined that is the undef MacroDirective.

Reviewers: bruno, manmanren

Reviewed By: bruno

Subscribers: nemanjai, cfe-commits

Differential Revision: https://reviews.llvm.org/D29923

Modified:
    cfe/trunk/include/clang/Lex/PPCallbacks.h
    cfe/trunk/include/clang/Lex/PreprocessingRecord.h
    cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/PreprocessingRecord.cpp
    cfe/trunk/tools/libclang/Indexing.cpp
    cfe/trunk/unittests/Basic/SourceManagerTest.cpp

Modified: cfe/trunk/include/clang/Lex/PPCallbacks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PPCallbacks.h?rev=301449&r1=301448&r2=301449&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PPCallbacks.h (original)
+++ cfe/trunk/include/clang/Lex/PPCallbacks.h Wed Apr 26 14:47:31 2017
@@ -247,10 +247,14 @@ public:
   }
 
   /// \brief Hook called whenever a macro \#undef is seen.
+  /// \param Token The active Token
+  /// \param MD A MacroDefinition for the named macro.
+  /// \param Undef New MacroDirective if the macro was defined, null otherwise.
   ///
   /// MD is released immediately following this callback.
   virtual void MacroUndefined(const Token &MacroNameTok,
-                              const MacroDefinition &MD) {
+                              const MacroDefinition &MD,
+                              const MacroDirective *Undef) {
   }
   
   /// \brief Hook called whenever the 'defined' operator is seen.
@@ -439,15 +443,17 @@ public:
     Second->MacroExpands(MacroNameTok, MD, Range, Args);
   }
 
-  void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override {
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override {
     First->MacroDefined(MacroNameTok, MD);
     Second->MacroDefined(MacroNameTok, MD);
   }
 
   void MacroUndefined(const Token &MacroNameTok,
-                      const MacroDefinition &MD) override {
-    First->MacroUndefined(MacroNameTok, MD);
-    Second->MacroUndefined(MacroNameTok, MD);
+                      const MacroDefinition &MD,
+                      const MacroDirective *Undef) override {
+    First->MacroUndefined(MacroNameTok, MD, Undef);
+    Second->MacroUndefined(MacroNameTok, MD, Undef);
   }
 
   void Defined(const Token &MacroNameTok, const MacroDefinition &MD,

Modified: cfe/trunk/include/clang/Lex/PreprocessingRecord.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessingRecord.h?rev=301449&r1=301448&r2=301449&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PreprocessingRecord.h (original)
+++ cfe/trunk/include/clang/Lex/PreprocessingRecord.h Wed Apr 26 14:47:31 2017
@@ -488,7 +488,8 @@ namespace clang {
     void MacroExpands(const Token &Id, const MacroDefinition &MD,
                       SourceRange Range, const MacroArgs *Args) override;
     void MacroDefined(const Token &Id, const MacroDirective *MD) override;
-    void MacroUndefined(const Token &Id, const MacroDefinition &MD) override;
+    void MacroUndefined(const Token &Id, const MacroDefinition &MD,
+                        const MacroDirective *Undef) override;
     void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                             StringRef FileName, bool IsAngled,
                             CharSourceRange FilenameRange,

Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=301449&r1=301448&r2=301449&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Wed Apr 26 14:47:31 2017
@@ -172,7 +172,8 @@ public:
 
   /// MacroUndefined - This hook is called whenever a macro #undef is seen.
   void MacroUndefined(const Token &MacroNameTok,
-                      const MacroDefinition &MD) override;
+                      const MacroDefinition &MD,
+                      const MacroDirective *Undef) override;
 };
 }  // end anonymous namespace
 
@@ -389,7 +390,8 @@ void PrintPPOutputPPCallbacks::MacroDefi
 }
 
 void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
-                                              const MacroDefinition &MD) {
+                                              const MacroDefinition &MD,
+                                              const MacroDirective *Undef) {
   // Only print out macro definitions in -dD mode.
   if (!DumpDefines) return;
 

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=301449&r1=301448&r2=301449&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Wed Apr 26 14:47:31 2017
@@ -2592,25 +2592,26 @@ void Preprocessor::HandleUndefDirective(
   // Okay, we have a valid identifier to undef.
   auto *II = MacroNameTok.getIdentifierInfo();
   auto MD = getMacroDefinition(II);
+  UndefMacroDirective *Undef = nullptr;
+  
+  // If the macro is not defined, this is a noop undef.
+  if (const MacroInfo *MI = MD.getMacroInfo()) {
+    if (!MI->isUsed() && MI->isWarnIfUnused())
+      Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
+
+    if (MI->isWarnIfUnused())
+      WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
+
+    Undef = AllocateUndefMacroDirective(MacroNameTok.getLocation());
+  }
 
   // If the callbacks want to know, tell them about the macro #undef.
   // Note: no matter if the macro was defined or not.
   if (Callbacks)
-    Callbacks->MacroUndefined(MacroNameTok, MD);
-
-  // If the macro is not defined, this is a noop undef, just return.
-  const MacroInfo *MI = MD.getMacroInfo();
-  if (!MI)
-    return;
-
-  if (!MI->isUsed() && MI->isWarnIfUnused())
-    Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
-
-  if (MI->isWarnIfUnused())
-    WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
+    Callbacks->MacroUndefined(MacroNameTok, MD, Undef);
 
-  appendMacroDirective(MacroNameTok.getIdentifierInfo(),
-                       AllocateUndefMacroDirective(MacroNameTok.getLocation()));
+  if (Undef)
+    appendMacroDirective(II, Undef);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Lex/PreprocessingRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PreprocessingRecord.cpp?rev=301449&r1=301448&r2=301449&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PreprocessingRecord.cpp (original)
+++ cfe/trunk/lib/Lex/PreprocessingRecord.cpp Wed Apr 26 14:47:31 2017
@@ -422,7 +422,8 @@ void PreprocessingRecord::MacroDefined(c
 }
 
 void PreprocessingRecord::MacroUndefined(const Token &Id,
-                                         const MacroDefinition &MD) {
+                                         const MacroDefinition &MD,
+                                         const MacroDirective *Undef) {
   MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); });
 }
 

Modified: cfe/trunk/tools/libclang/Indexing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=301449&r1=301448&r2=301449&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/Indexing.cpp (original)
+++ cfe/trunk/tools/libclang/Indexing.cpp Wed Apr 26 14:47:31 2017
@@ -262,7 +262,8 @@ public:
   /// MacroUndefined - This hook is called whenever a macro #undef is seen.
   /// MI is released immediately following this callback.
   void MacroUndefined(const Token &MacroNameTok,
-                      const MacroDefinition &MD) override {}
+                      const MacroDefinition &MD,
+                      const MacroDirective *UD) override {}
 
   /// MacroExpands - This is called by when a macro invocation is found.
   void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,

Modified: cfe/trunk/unittests/Basic/SourceManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/SourceManagerTest.cpp?rev=301449&r1=301448&r2=301449&view=diff
==============================================================================
--- cfe/trunk/unittests/Basic/SourceManagerTest.cpp (original)
+++ cfe/trunk/unittests/Basic/SourceManagerTest.cpp Wed Apr 26 14:47:31 2017
@@ -249,12 +249,18 @@ TEST_F(SourceManagerTest, getMacroArgExp
 namespace {
 
 struct MacroAction {
+  enum Kind { kExpansion, kDefinition, kUnDefinition};
+
   SourceLocation Loc;
   std::string Name;
-  bool isDefinition; // if false, it is expansion.
-  
-  MacroAction(SourceLocation Loc, StringRef Name, bool isDefinition)
-    : Loc(Loc), Name(Name), isDefinition(isDefinition) { }
+  unsigned MAKind : 3;
+
+  MacroAction(SourceLocation Loc, StringRef Name, unsigned K)
+    : Loc(Loc), Name(Name), MAKind(K) { }
+
+  bool isExpansion() const { return MAKind == kExpansion; }
+  bool isDefinition() const { return MAKind & kDefinition; }
+  bool isUnDefinition() const { return MAKind & kUnDefinition; }
 };
 
 class MacroTracker : public PPCallbacks {
@@ -267,13 +273,22 @@ public:
                     const MacroDirective *MD) override {
     Macros.push_back(MacroAction(MD->getLocation(),
                                  MacroNameTok.getIdentifierInfo()->getName(),
-                                 true));
+                                 MacroAction::kDefinition));
+  }
+  void MacroUndefined(const Token &MacroNameTok,
+                      const MacroDefinition &MD,
+                      const MacroDirective  *UD) override {
+    Macros.push_back(
+        MacroAction(UD ? UD->getLocation() : SourceLocation(),
+                    MacroNameTok.getIdentifierInfo()->getName(),
+                    UD ? MacroAction::kDefinition | MacroAction::kUnDefinition
+                       : MacroAction::kUnDefinition));
   }
   void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
                     SourceRange Range, const MacroArgs *Args) override {
     Macros.push_back(MacroAction(MacroNameTok.getLocation(),
                                  MacroNameTok.getIdentifierInfo()->getName(),
-                                 false));
+                                 MacroAction::kExpansion));
   }
 };
 
@@ -281,7 +296,10 @@ public:
 
 TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) {
   const char *header =
-    "#define MACRO_IN_INCLUDE 0\n";
+    "#define MACRO_IN_INCLUDE 0\n"
+    "#define MACRO_DEFINED\n"
+    "#undef MACRO_DEFINED\n"
+    "#undef MACRO_UNDEFINED\n";
 
   const char *main =
     "#define M(x) x\n"
@@ -327,34 +345,46 @@ TEST_F(SourceManagerTest, isBeforeInTran
   // Make sure we got the tokens that we expected.
   ASSERT_EQ(0U, toks.size());
 
-  ASSERT_EQ(9U, Macros.size());
+  ASSERT_EQ(15U, Macros.size());
   // #define M(x) x
-  ASSERT_TRUE(Macros[0].isDefinition);
+  ASSERT_TRUE(Macros[0].isDefinition());
   ASSERT_EQ("M", Macros[0].Name);
   // #define INC "/test-header.h"
-  ASSERT_TRUE(Macros[1].isDefinition);
+  ASSERT_TRUE(Macros[1].isDefinition());
   ASSERT_EQ("INC", Macros[1].Name);
   // M expansion in #include M(INC)
-  ASSERT_FALSE(Macros[2].isDefinition);
+  ASSERT_FALSE(Macros[2].isDefinition());
   ASSERT_EQ("M", Macros[2].Name);
   // INC expansion in #include M(INC)
-  ASSERT_FALSE(Macros[3].isDefinition);
+  ASSERT_TRUE(Macros[3].isExpansion());
   ASSERT_EQ("INC", Macros[3].Name);
   // #define MACRO_IN_INCLUDE 0
-  ASSERT_TRUE(Macros[4].isDefinition);
+  ASSERT_TRUE(Macros[4].isDefinition());
   ASSERT_EQ("MACRO_IN_INCLUDE", Macros[4].Name);
+  // #define MACRO_DEFINED
+  ASSERT_TRUE(Macros[5].isDefinition());
+  ASSERT_FALSE(Macros[5].isUnDefinition());
+  ASSERT_EQ("MACRO_DEFINED", Macros[5].Name);
+  // #undef MACRO_DEFINED
+  ASSERT_TRUE(Macros[6].isDefinition());
+  ASSERT_TRUE(Macros[6].isUnDefinition());
+  ASSERT_EQ("MACRO_DEFINED", Macros[6].Name);
+  // #undef MACRO_UNDEFINED
+  ASSERT_FALSE(Macros[7].isDefinition());
+  ASSERT_TRUE(Macros[7].isUnDefinition());
+  ASSERT_EQ("MACRO_UNDEFINED", Macros[7].Name);
   // #define INC2 </test-header.h>
-  ASSERT_TRUE(Macros[5].isDefinition);
-  ASSERT_EQ("INC2", Macros[5].Name);
+  ASSERT_TRUE(Macros[8].isDefinition());
+  ASSERT_EQ("INC2", Macros[8].Name);
   // M expansion in #include M(INC2)
-  ASSERT_FALSE(Macros[6].isDefinition);
-  ASSERT_EQ("M", Macros[6].Name);
+  ASSERT_FALSE(Macros[9].isDefinition());
+  ASSERT_EQ("M", Macros[9].Name);
   // INC2 expansion in #include M(INC2)
-  ASSERT_FALSE(Macros[7].isDefinition);
-  ASSERT_EQ("INC2", Macros[7].Name);
+  ASSERT_TRUE(Macros[10].isExpansion());
+  ASSERT_EQ("INC2", Macros[10].Name);
   // #define MACRO_IN_INCLUDE 0
-  ASSERT_TRUE(Macros[8].isDefinition);
-  ASSERT_EQ("MACRO_IN_INCLUDE", Macros[8].Name);
+  ASSERT_TRUE(Macros[11].isDefinition());
+  ASSERT_EQ("MACRO_IN_INCLUDE", Macros[11].Name);
 
   // The INC expansion in #include M(INC) comes before the first
   // MACRO_IN_INCLUDE definition of the included file.
@@ -362,7 +392,7 @@ TEST_F(SourceManagerTest, isBeforeInTran
 
   // The INC2 expansion in #include M(INC2) comes before the second
   // MACRO_IN_INCLUDE definition of the included file.
-  EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[7].Loc, Macros[8].Loc));
+  EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[10].Loc, Macros[11].Loc));
 }
 
 #endif




More information about the cfe-commits mailing list