From 349a624ab98ea25abc46f2587b28787a570a6552 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Wed, 26 Apr 2017 21:05:44 +0000 Subject: [PATCH] Revert "Revert "PPCallbacks::MacroUndefined, change signature and add test."" This reverts commit r301469. It isn't needed with r301470, which fixes the API break introduced in the original commit. llvm-svn: 301472 --- clang/include/clang/Lex/PPCallbacks.h | 16 ++-- clang/include/clang/Lex/PreprocessingRecord.h | 3 +- .../lib/Frontend/PrintPreprocessedOutput.cpp | 6 +- clang/lib/Lex/PPDirectives.cpp | 29 ++++---- clang/lib/Lex/PreprocessingRecord.cpp | 3 +- clang/tools/libclang/Indexing.cpp | 3 +- clang/unittests/Basic/SourceManagerTest.cpp | 74 +++++++++++++------ 7 files changed, 88 insertions(+), 46 deletions(-) diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h index 2d027f314b5f..57fe1bb12250 100644 --- a/clang/include/clang/Lex/PPCallbacks.h +++ b/clang/include/clang/Lex/PPCallbacks.h @@ -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, diff --git a/clang/include/clang/Lex/PreprocessingRecord.h b/clang/include/clang/Lex/PreprocessingRecord.h index 826ba33fbb72..fc2c50700400 100644 --- a/clang/include/clang/Lex/PreprocessingRecord.h +++ b/clang/include/clang/Lex/PreprocessingRecord.h @@ -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, diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index d48b952ef203..3168b3da70a5 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -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::MacroDefined(const Token &MacroNameTok, } 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; diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 8a56ddf23699..fd4e6d30def9 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -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); + Callbacks->MacroUndefined(MacroNameTok, MD, Undef); - // 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()); - - appendMacroDirective(MacroNameTok.getIdentifierInfo(), - AllocateUndefMacroDirective(MacroNameTok.getLocation())); + if (Undef) + appendMacroDirective(II, Undef); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp index 13e15f3c943b..03c4cbe589d5 100644 --- a/clang/lib/Lex/PreprocessingRecord.cpp +++ b/clang/lib/Lex/PreprocessingRecord.cpp @@ -422,7 +422,8 @@ void PreprocessingRecord::MacroDefined(const Token &Id, } void PreprocessingRecord::MacroUndefined(const Token &Id, - const MacroDefinition &MD) { + const MacroDefinition &MD, + const MacroDirective *Undef) { MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); }); } diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp index f98b25887973..5312b7c0169c 100644 --- a/clang/tools/libclang/Indexing.cpp +++ b/clang/tools/libclang/Indexing.cpp @@ -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, diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp index dddc3f98662d..aa15e16b851f 100644 --- a/clang/unittests/Basic/SourceManagerTest.cpp +++ b/clang/unittests/Basic/SourceManagerTest.cpp @@ -249,12 +249,18 @@ TEST_F(SourceManagerTest, getMacroArgExpandedLocation) { 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, isBeforeInTranslationUnitWithMacroInInclude) { // 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 - 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, isBeforeInTranslationUnitWithMacroInInclude) { // 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