From 751bcd7cf9f538c9f1a77baa59a3075698ff4b7c Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 13 Jan 2025 14:25:17 +0100 Subject: [PATCH] added CLI option `--debug-clang-ast` to print Clang AST --- cli/cmdlineparser.cpp | 4 ++++ lib/cppcheck.cpp | 4 ++++ lib/settings.h | 3 +++ test/cli/clang-import_test.py | 22 ++++++++++++++++++++++ test/testcmdlineparser.cpp | 8 ++++++++ 5 files changed, 41 insertions(+) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 20b39179e8e..1bbfc5afa1b 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -614,6 +614,10 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a mSettings.cppHeaderProbe = true; } + // Show debug warnings for lookup for configuration files + else if (std::strcmp(argv[i], "--debug-clang-ast") == 0) + mSettings.debugClangAst = true; + // Show --debug output after the first simplifications else if (std::strcmp(argv[i], "--debug") == 0 || std::strcmp(argv[i], "--debug-normal") == 0) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index e7ae9b14399..3eb4b96af6e 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -684,6 +684,10 @@ unsigned int CppCheck::checkClang(const FileWithDetails &file) return 0; // TODO: report as failure? } + if (mSettings.debugClangAst) { + std::cout << output2 << std::endl; + } + if (output2.find("TranslationUnitDecl") == std::string::npos) { // TODO: report as proper error std::cerr << "Failed to execute '" << exe << " " << args2 << " " << redirect2 << "' - (no TranslationUnitDecl in output)" << std::endl; diff --git a/lib/settings.h b/lib/settings.h index 9afb9431a6f..21c8f9acdaf 100644 --- a/lib/settings.h +++ b/lib/settings.h @@ -178,6 +178,9 @@ class CPPCHECKLIB WARN_UNUSED Settings { /** @brief Are we running from DACA script? */ bool daca{}; + /** @brief Is --debug-clang-ast given? */ + bool debugClangAst{}; + /** @brief Internal: Is --debug-lookup or --debug-lookup=all given? */ bool debuglookup{}; diff --git a/test/cli/clang-import_test.py b/test/cli/clang-import_test.py index 4e0b7e09e48..c4f2fb7d113 100644 --- a/test/cli/clang-import_test.py +++ b/test/cli/clang-import_test.py @@ -239,3 +239,25 @@ def test_cmd_std_c_enforce_alias_2(tmp_path): # #13128/#13129/#13130 def test_cmd_std_cpp_enforce_alias(tmp_path): # #13128/#13129/#13130 __test_cmd(tmp_path, 'test.c',['--language=c++', '--std=gnu99', '--std=gnu++11'], '-x c++ -std=gnu++11') + + +def test_debug_ast(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, 'wt') as f: + f.write( +""" +void f() {} +""") + + args = [ + '-q', + '--clang', + '--debug-clang-ast', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0, stderr if not stdout else stdout + assert stderr == '' + assert stdout.startswith('TranslationUnitDecl'), stdout + assert stdout.find(str(test_file)) != -1, stdout \ No newline at end of file diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp index e854400c946..ce863a96a41 100644 --- a/test/testcmdlineparser.cpp +++ b/test/testcmdlineparser.cpp @@ -422,6 +422,7 @@ class TestCmdlineParser : public TestFixture { TEST_CASE(maxTemplateRecursion); TEST_CASE(maxTemplateRecursionMissingCount); TEST_CASE(emitDuplicates); + TEST_CASE(debugClangAst); TEST_CASE(ignorepaths1); TEST_CASE(ignorepaths2); @@ -2907,6 +2908,13 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS(true, settings->emitDuplicates); } + void debugClangAst() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--debug-clang-ast", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv)); + ASSERT_EQUALS(true, settings->debugClangAst); + } + void ignorepaths1() { REDIRECT; const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"};