diff --git a/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.cpp b/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.cpp index 0eed421a..0c0ae41d 100644 --- a/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.cpp +++ b/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.cpp @@ -92,10 +92,38 @@ void PreprocessorCallbacks::MacroDefined(const clang::Token& macroNameToken, con } } +void PreprocessorCallbacks::MacroUndefined( + const clang::Token& macroNameToken, const clang::MacroDefinition& macroDefinition) +{ + onMacroUsage(macroNameToken); +} + +void PreprocessorCallbacks::Defined( + const clang::Token& macroNameToken, const clang::MacroDefinition& macroDefinition, clang::SourceRange range) +{ + onMacroUsage(macroNameToken); +} + +void PreprocessorCallbacks::Ifdef(clang::SourceLocation location, const clang::Token& macroNameToken, + const clang::MacroDefinition& macroDefinition) +{ + onMacroUsage(macroNameToken); +} +void PreprocessorCallbacks::Ifndef(clang::SourceLocation location, const clang::Token& macroNameToken, + const clang::MacroDefinition& macroDefinition) +{ + onMacroUsage(macroNameToken); +} + void PreprocessorCallbacks::MacroExpands( const clang::Token& macroNameToken, const clang::MacroDefinition& macroDirective, clang::SourceRange range, const clang::MacroArgs* args ){ + onMacroUsage(macroNameToken); +} + +void PreprocessorCallbacks::onMacroUsage(const clang::Token& macroNameToken) +{ const std::string& fileStr = m_sourceManager.getFilename(m_sourceManager.getFileLoc(macroNameToken.getLocation())); if (!fileStr.size()) { diff --git a/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.h b/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.h index 7f93c18e..43a47702 100644 --- a/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.h +++ b/src/lib_parser/data/parser/cxx/PreprocessorCallbacks.h @@ -17,7 +17,8 @@ class PreprocessorCallbacks public: explicit PreprocessorCallbacks(clang::SourceManager& sourceManager, ParserClient* client, FileRegister* fileRegister); - virtual void FileChanged(clang::SourceLocation location, FileChangeReason reason, clang::SrcMgr::CharacteristicKind, clang::FileID); + virtual void FileChanged( + clang::SourceLocation location, FileChangeReason reason, clang::SrcMgr::CharacteristicKind, clang::FileID); virtual void InclusionDirective( clang::SourceLocation hashLocation, const clang::Token& includeToken, llvm::StringRef fileName, bool isAngled, @@ -25,6 +26,14 @@ public: llvm::StringRef relativePath, const clang::Module* imported); virtual void MacroDefined(const clang::Token& macroNameToken, const clang::MacroDirective* macroDirective); + virtual void MacroUndefined(const clang::Token& macroNameToken, const clang::MacroDefinition& macroDefinition); + + virtual void Defined( + const clang::Token& macroNameToken, const clang::MacroDefinition& macroDefinition, clang::SourceRange range); + virtual void Ifdef(clang::SourceLocation location, const clang::Token& macroNameToken, + const clang::MacroDefinition& macroDefinition); + virtual void Ifndef(clang::SourceLocation location, const clang::Token& macroNameToken, + const clang::MacroDefinition& macroDefinition); virtual void MacroExpands( const clang::Token& macroNameToken, const clang::MacroDefinition& macroDirective, @@ -32,6 +41,8 @@ public: ); private: + void onMacroUsage(const clang::Token& macroNameToken); + ParseLocation getParseLocation(const clang::Token& macroNameToc) const; ParseLocation getParseLocation(const clang::MacroInfo* macroNameToc) const; ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const; diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index e145b293..a5315a2f 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -280,6 +280,105 @@ public: TS_ASSERT_EQUALS(client->macros[0], "PI <1:9 <1:9 1:10> 1:8>"); } + void test_cxx_parser_finds_macro_undefine() + { + std::shared_ptr client = parseCode( + "#undef PI\n" + "void test()\n" + "{\n" + "};\n" + ); + + TS_ASSERT_EQUALS(client->macroUses.size(), 1); + TS_ASSERT_EQUALS(client->macroUses[0], "PI <1:8 1:9>"); + } + + void test_cxx_parser_finds_macro_in_ifdef() + { + std::shared_ptr client = parseCode( + "#define PI\n" + "#ifdef PI\n" + "void test()\n" + "{\n" + "};\n" + "#endif\n" + ); + + TS_ASSERT_EQUALS(client->macroUses.size(), 1); + TS_ASSERT_EQUALS(client->macroUses[0], "PI <2:8 2:9>"); + } + + void test_cxx_parser_finds_macro_in_ifndef() + { + std::shared_ptr client = parseCode( + "#define PI\n" + "#ifndef PI\n" + "void test()\n" + "{\n" + "};\n" + "#endif\n" + ); + + TS_ASSERT_EQUALS(client->macroUses.size(), 1); + TS_ASSERT_EQUALS(client->macroUses[0], "PI <2:9 2:10>"); + } + + void test_cxx_parser_finds_macro_in_ifdefined() + { + std::shared_ptr client = parseCode( + "#define PI\n" + "#if defined(PI)\n" + "void test()\n" + "{\n" + "};\n" + "#endif\n" + ); + + TS_ASSERT_EQUALS(client->macroUses.size(), 1); + TS_ASSERT_EQUALS(client->macroUses[0], "PI <2:13 2:14>"); + } + + void test_cxx_parser_finds_macro_expand() + { + std::shared_ptr client = parseCode( + "#define PI 3.14159265359\n" + "void test()\n" + "{\n" + "double i = PI;" + "};\n" + ); + + TS_ASSERT_EQUALS(client->macroUses.size(), 1); + TS_ASSERT_EQUALS(client->macroUses[0], "PI <4:12 4:13>"); + } + + void test_cxx_parser_finds_macro_expand_within_macro() + { + std::shared_ptr client = parseCode( + "#define PI 3.14159265359\n" + "#define TAU (2 * PI)\n" + "void test()\n" + "{\n" + "double i = TAU;" + "};\n" + ); + + TS_ASSERT_EQUALS(client->macroUses.size(), 2); + TS_ASSERT_EQUALS(client->macroUses[0], "TAU <5:12 5:14>"); + TS_ASSERT_EQUALS(client->macroUses[1], "PI <2:18 2:19>"); + } + + void test_cxx_parser_finds_macro_define_scope() + { + std::shared_ptr client = parseCode( + "#define MAX(a,b) \\\n" + " ((a)>(b)?(a):(b))" + ); + + TS_ASSERT_EQUALS(client->macros.size(), 1); + TS_ASSERT_EQUALS(client->macros[0], "MAX <1:9 <1:9 1:11> 2:17>"); + } + void test_cxx_parser_finds_type_template_parameter_type_of_template_class() { std::shared_ptr client = parseCode( @@ -1767,36 +1866,6 @@ public: TS_ASSERT_EQUALS(client->typeUses[3], "int main() -> A <9:16 9:16>"); } - void test_cxx_parser_finds_macro_expand() - { - std::shared_ptr client = parseCode( - "#define PI 3.14159265359\n" - "void test()\n" - "{\n" - "double i = PI;" - "};\n" - ); - - TS_ASSERT_EQUALS(client->macroUses.size(), 1); - TS_ASSERT_EQUALS(client->macroUses[0], "PI <4:12 4:13>"); - } - - void test_cxx_parser_finds_macro_expand_within_macro() - { - std::shared_ptr client = parseCode( - "#define PI 3.14159265359\n" - "#define TAU (2 * PI)\n" - "void test()\n" - "{\n" - "double i = TAU;" - "};\n" - ); - - TS_ASSERT_EQUALS(client->macroUses.size(), 2); - TS_ASSERT_EQUALS(client->macroUses[0], "TAU <5:12 5:14>"); - TS_ASSERT_EQUALS(client->macroUses[1], "PI <2:18 2:19>"); - } - void test_cxx_parser_finds_usage_of_template_template_parameter_of_template_class_specialized_with_concrete_type() { std::shared_ptr client = parseCode( @@ -2751,17 +2820,6 @@ public: TS_ASSERT_EQUALS(client->calls[1], "int main() -> void n::App::App(int) <11:16 11:18>"); } - void test_cxx_parser_finds_macro_define_scope() - { - std::shared_ptr client = parseCode( - "#define MAX(a,b) \\\n" - " ((a)>(b)?(a):(b))" - ); - - TS_ASSERT_EQUALS(client->macros.size(), 1); - TS_ASSERT_EQUALS(client->macros[0], "MAX <1:9 <1:9 1:11> 2:17>"); - } - //void __test_cxx_parser_finds_type_template_argument_of_static_cast_expression() //{ // std::shared_ptr client = parseCode(