Skip to content

Commit c703be9

Browse files
committed
refs #13532 - reworked --debug* output [skip ci]
1 parent de53599 commit c703be9

8 files changed

Lines changed: 181 additions & 32 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
614614
mSettings.cppHeaderProbe = true;
615615
}
616616

617+
else if (std::strcmp(argv[i], "--debug-ast") == 0)
618+
mSettings.debugsymdb = true;
619+
617620
// Show debug warnings for lookup for configuration files
618621
else if (std::strcmp(argv[i], "--debug-clang-output") == 0)
619622
mSettings.debugClangOutput = true;
@@ -650,6 +653,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
650653
else if (std::strcmp(argv[i], "--debug-simplified") == 0)
651654
mSettings.debugSimplified = true;
652655

656+
else if (std::strcmp(argv[i], "--debug-symdb") == 0)
657+
mSettings.debugsymdb = true;
658+
653659
// Show template information
654660
else if (std::strcmp(argv[i], "--debug-template") == 0)
655661
mSettings.debugtemplate = true;

lib/cppcheck.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,7 @@ unsigned int CppCheck::checkClang(const FileWithDetails &file)
722722
mErrorLogger,
723723
mSettings,
724724
&s_timerResults);
725-
if (mSettings.debugnormal)
726-
tokenizer.printDebugOutput(1, std::cout);
725+
tokenizer.printDebugOutput(1, std::cout);
727726
checkNormalTokens(tokenizer, nullptr); // TODO: provide analyzer information
728727

729728
// create dumpfile

lib/settings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ class CPPCHECKLIB WARN_UNUSED Settings {
182182
/** @brief Are we running from DACA script? */
183183
bool daca{};
184184

185+
/** @brief Is --debug-ast given? */
186+
bool debugast{};
187+
185188
/** @brief Is --debug-clang-output given? */
186189
bool debugClangOutput{};
187190

@@ -206,6 +209,9 @@ class CPPCHECKLIB WARN_UNUSED Settings {
206209
/** @brief Is --debug-simplified given? */
207210
bool debugSimplified{};
208211

212+
/** @brief Is --debug-symdb given? */
213+
bool debugsymdb{};
214+
209215
/** @brief Is --debug-template given? */
210216
bool debugtemplate{};
211217

lib/tokenize.cpp

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3490,6 +3490,8 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration)
34903490
mSymbolDatabase->setArrayDimensionsUsingValueFlow();
34913491
}
34923492

3493+
validateTypes();
3494+
34933495
printDebugOutput(1, std::cout);
34943496

34953497
return true;
@@ -5924,52 +5926,58 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
59245926
}
59255927
//---------------------------------------------------------------------------
59265928

5927-
void Tokenizer::printDebugOutput(int simplification, std::ostream &out) const
5929+
void Tokenizer::printDebugOutput(bool simplified, std::ostream &out) const
59285930
{
5929-
const bool debug = (simplification != 1U && mSettings.debugSimplified) ||
5930-
(simplification != 2U && mSettings.debugnormal);
5931+
const bool debug = (simplified && (mSettings.debugSimplified||mSettings.debugast||mSettings.debugsymdb)) ||
5932+
(!simplified && (mSettings.debugnormal||mSettings.debugast||mSettings.debugsymdb));
59315933

59325934
if (debug && list.front()) {
5933-
list.front()->printOut(out, nullptr, list.getFiles());
5935+
if (mSettings.debugSimplified || mSettings.debugnormal)
5936+
list.front()->printOut(out, nullptr, list.getFiles());
59345937

59355938
if (mSettings.xml)
59365939
out << "<debug>" << std::endl;
59375940

59385941
if (mSymbolDatabase) {
59395942
if (mSettings.xml)
59405943
mSymbolDatabase->printXml(out);
5941-
else if (mSettings.verbose) {
5944+
else if (mSettings.debugsymdb) {
59425945
mSymbolDatabase->printOut("Symbol database");
59435946
}
59445947
}
59455948

5946-
if (mSettings.verbose)
5947-
list.front()->printAst(mSettings.verbose, mSettings.xml, list.getFiles(), out);
5949+
if (mSettings.xml || mSettings.debugast)
5950+
list.front()->printAst(mSettings.verbose, mSettings.xml, list.getFiles(), out); // TODO: do not depend on --verbose
59485951

5952+
// TODO: add option
59495953
list.front()->printValueFlow(mSettings.xml, out);
59505954

59515955
if (mSettings.xml)
59525956
out << "</debug>" << std::endl;
59535957
}
5958+
}
59545959

5955-
if (mSymbolDatabase && simplification == 2U && mSettings.debugwarnings) {
5956-
printUnknownTypes();
5960+
void Tokenizer::validateTypes() const
5961+
{
5962+
if (!mSymbolDatabase || !mSettings.debugwarnings)
5963+
return;
59575964

5958-
// the typeStartToken() should come before typeEndToken()
5959-
for (const Variable *var : mSymbolDatabase->variableList()) {
5960-
if (!var)
5961-
continue;
5965+
printUnknownTypes();
59625966

5963-
const Token * typetok = var->typeStartToken();
5964-
while (typetok && typetok != var->typeEndToken())
5965-
typetok = typetok->next();
5967+
// the typeStartToken() should come before typeEndToken()
5968+
for (const Variable *var : mSymbolDatabase->variableList()) {
5969+
if (!var)
5970+
continue;
59665971

5967-
if (typetok != var->typeEndToken()) {
5968-
reportError(var->typeStartToken(),
5969-
Severity::debug,
5970-
"debug",
5971-
"Variable::typeStartToken() of variable '" + var->name() + "' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + "' at line " + std::to_string(var->typeStartToken()->linenr()));
5972-
}
5972+
const Token * typetok = var->typeStartToken();
5973+
while (typetok && typetok != var->typeEndToken())
5974+
typetok = typetok->next();
5975+
5976+
if (typetok != var->typeEndToken()) {
5977+
reportError(var->typeStartToken(),
5978+
Severity::debug,
5979+
"debug",
5980+
"Variable::typeStartToken() of variable '" + var->name() + "' is not located before Variable::typeEndToken(). The location of the typeStartToken() is '" + var->typeStartToken()->str() + "' at line " + std::to_string(var->typeStartToken()->linenr()));
59735981
}
59745982
}
59755983
}

lib/tokenize.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -564,18 +564,17 @@ class CPPCHECKLIB Tokenizer {
564564

565565
static bool operatorEnd(const Token * tok);
566566

567+
void validateTypes() const;
568+
567569
public:
568570
const SymbolDatabase *getSymbolDatabase() const {
569571
return mSymbolDatabase;
570572
}
571573
void createSymbolDatabase();
572574

573575
/** print --debug output if debug flags match the simplification:
574-
* 0=unknown/both simplifications
575-
* 1=1st simplifications
576-
* 2=2nd simplifications
577576
*/
578-
void printDebugOutput(int simplification, std::ostream &out) const;
577+
void printDebugOutput(int simplified, std::ostream &out) const;
579578

580579
void dump(std::ostream &out) const;
581580

test/cli/clang-import_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ def __check_symbol_database(tmpdir, code):
4747
testfile = os.path.join(tmpdir, 'test.cpp')
4848
with open(testfile, 'w+t') as f:
4949
f.write(code)
50-
ret1, stdout1, _ = cppcheck(['--clang', '--debug', '-v', testfile])
51-
ret2, stdout2, _ = cppcheck(['--debug', '-v', testfile])
50+
ret1, stdout1, _ = cppcheck(['--clang', '--debug-symdb', testfile])
51+
ret2, stdout2, _ = cppcheck(['--debug-symdb', testfile])
5252
assert 0 == ret1, stdout1
5353
assert 0 == ret2, stdout2
5454
assert __get_debug_section('### Symbol database', stdout1) == __get_debug_section('### Symbol database', stdout2)
@@ -58,8 +58,8 @@ def __check_ast(tmpdir, code):
5858
testfile = os.path.join(tmpdir, 'test.cpp')
5959
with open(testfile, 'w+t') as f:
6060
f.write(code)
61-
ret1, stdout1, _ = cppcheck(['--clang', '--debug', '-v', testfile])
62-
ret2, stdout2, _ = cppcheck(['--debug', '-v', testfile])
61+
ret1, stdout1, _ = cppcheck(['--clang', '--debug-ast', testfile])
62+
ret2, stdout2, _ = cppcheck(['--debug-ast', testfile])
6363
assert 0 == ret1, stdout1
6464
assert 0 == ret2, stdout1
6565
assert __get_debug_section('##AST', stdout1) == __get_debug_section('##AST', stdout2)

test/cli/other_test.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2869,3 +2869,118 @@ def test_ctu_builddir(tmp_path): # #11883
28692869
assert stderr.splitlines() == [
28702870
'{}:2:19: error: Null pointer dereference: p [ctunullpointer]'.format(test_file)
28712871
]
2872+
2873+
2874+
# TODO: test with --xml
2875+
2876+
def test_debug_normal(tmp_path):
2877+
test_file = tmp_path / 'test.c'
2878+
with open(test_file, "w") as f:
2879+
f.write(
2880+
"""
2881+
void f
2882+
{
2883+
(void)*((int*)0);
2884+
}
2885+
""")
2886+
2887+
args = [
2888+
'--debug-normal',
2889+
str(test_file)
2890+
]
2891+
2892+
exitcode, stdout, stderr = cppcheck(args)
2893+
assert exitcode == 0, stdout
2894+
assert stdout.find('##file ') != -1
2895+
assert stdout.find('##Value flow') != -1
2896+
assert stderr.splitlines() == []
2897+
2898+
2899+
# TODO: simplification = 2
2900+
def test_debug_simplified(tmp_path):
2901+
test_file = tmp_path / 'test.c'
2902+
with open(test_file, "w") as f:
2903+
f.write(
2904+
"""
2905+
void f
2906+
{
2907+
(void)*((int*)0);
2908+
}
2909+
""")
2910+
2911+
args = [
2912+
'--debug-simplified',
2913+
str(test_file)
2914+
]
2915+
2916+
exitcode, stdout, stderr = cppcheck(args)
2917+
assert exitcode == 0, stdout
2918+
assert stdout.find('##file ') != -1
2919+
assert stderr.splitlines() == []
2920+
2921+
2922+
def test_debug_symdb(tmp_path):
2923+
test_file = tmp_path / 'test.c'
2924+
with open(test_file, "w") as f:
2925+
f.write(
2926+
"""
2927+
void f
2928+
{
2929+
(void)*((int*)0);
2930+
}
2931+
""")
2932+
2933+
args = [
2934+
'--debug-simplified',
2935+
str(test_file)
2936+
]
2937+
2938+
exitcode, stdout, stderr = cppcheck(args)
2939+
assert exitcode == 0, stdout
2940+
assert stdout.find('### Symbol database ###') != -1
2941+
assert stderr.splitlines() == []
2942+
2943+
2944+
def test_debug_ast(tmp_path):
2945+
test_file = tmp_path / 'test.c'
2946+
with open(test_file, "w") as f:
2947+
f.write(
2948+
"""
2949+
void f
2950+
{
2951+
(void)*((int*)0);
2952+
}
2953+
""")
2954+
2955+
args = [
2956+
'--debug-ast',
2957+
str(test_file)
2958+
]
2959+
2960+
exitcode, stdout, stderr = cppcheck(args)
2961+
assert exitcode == 0, stdout
2962+
assert stdout == ''
2963+
assert stderr.splitlines() == []
2964+
2965+
2966+
@pytest.mark.skip
2967+
def test_debug_valueflow(tmp_path):
2968+
test_file = tmp_path / 'test.c'
2969+
with open(test_file, "w") as f:
2970+
f.write(
2971+
"""
2972+
void f
2973+
{
2974+
(void)*((int*)0);
2975+
}
2976+
""")
2977+
2978+
args = [
2979+
'--debug-valueflow',
2980+
str(test_file)
2981+
]
2982+
2983+
exitcode, stdout, stderr = cppcheck(args)
2984+
assert exitcode == 0, stdout
2985+
assert stdout.find('##Value flow') != -1
2986+
assert stderr.splitlines() == []

test/testcmdlineparser.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ class TestCmdlineParser : public TestFixture {
423423
TEST_CASE(maxTemplateRecursionMissingCount);
424424
TEST_CASE(emitDuplicates);
425425
TEST_CASE(debugClangOutput);
426+
TEST_CASE(debugSymdb);
427+
TEST_CASE(debugAst);
426428

427429
TEST_CASE(ignorepaths1);
428430
TEST_CASE(ignorepaths2);
@@ -2925,6 +2927,20 @@ class TestCmdlineParser : public TestFixture {
29252927
ASSERT_EQUALS(true, settings->debugClangOutput);
29262928
}
29272929

2930+
void debugSymdb() {
2931+
REDIRECT;
2932+
const char * const argv[] = {"cppcheck", "--debug-symdb", "file.cpp"};
2933+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
2934+
ASSERT_EQUALS(true, settings->debugsymdb);
2935+
}
2936+
2937+
void debugAst() {
2938+
REDIRECT;
2939+
const char * const argv[] = {"cppcheck", "--debug-ast", "file.cpp"};
2940+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
2941+
ASSERT_EQUALS(true, settings->debugast);
2942+
}
2943+
29282944
void ignorepaths1() {
29292945
REDIRECT;
29302946
const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"};

0 commit comments

Comments
 (0)