diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index acc5fc91f..906722bcb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3378,6 +3378,11 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // remove some unhandled macros in global scope removeMacrosInGlobalScope(); + // remove undefined macro in class definition: + // class DLLEXPORT Fred { }; + // class Fred FINAL : Base { }; + removeMacroInClassDef(); + // remove __attribute__((?)) simplifyAttribute(); @@ -4061,6 +4066,22 @@ void Tokenizer::removeMacrosInGlobalScope() tok = tok->link(); } } + +//--------------------------------------------------------------------------- + +void Tokenizer::removeMacroInClassDef() +{ + for (Token *tok = list.front(); tok; tok = tok->next()) { + if (Token::Match(tok, "class|struct %var% %var% {|:") && + (tok->next()->isUpperCaseName() || tok->tokAt(2)->isUpperCaseName())) { + if (tok->next()->isUpperCaseName() && !tok->tokAt(2)->isUpperCaseName()) + tok->deleteNext(); + else if (!tok->next()->isUpperCaseName() && tok->tokAt(2)->isUpperCaseName()) + tok->next()->deleteNext(); + } + } +} + //--------------------------------------------------------------------------- void Tokenizer::removeMacroInVarDecl() diff --git a/lib/tokenize.h b/lib/tokenize.h index 9c02998be..3a912dc6c 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -195,6 +195,12 @@ public: /** Remove macros in global scope */ void removeMacrosInGlobalScope(); + /** Remove undefined macro in class definition: + * class DLLEXPORT Fred { }; + * class Fred FINAL : Base { }; + */ + void removeMacroInClassDef(); + /** Remove unknown macro in variable declarations: PROGMEM char x; */ void removeMacroInVarDecl(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 8618c1c77..1562e25e1 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -472,6 +472,8 @@ private: TEST_CASE(astlambda); TEST_CASE(startOfExecutableScope); + + TEST_CASE(removeMacroInClassDef); // #6058 } std::string tokenizeAndStringify(const char code[], bool simplify = false, bool expand = true, Settings::PlatformType platform = Settings::Unspecified, const char* filename = "test.cpp", bool cpp11 = true) { @@ -8712,6 +8714,11 @@ private: ASSERT(isStartOfExecutableScope(2, "foo() : a{1}, b{2} { }")); } + void removeMacroInClassDef() { // #6058 + ASSERT_EQUALS("class Fred { } ;", tokenizeAndStringify("class DLLEXPORT Fred { } ;")); + ASSERT_EQUALS("class Fred : Base { } ;", tokenizeAndStringify("class Fred FINAL : Base { } ;")); + } + }; REGISTER_TEST(TestTokenizer) diff --git a/test/testvarid.cpp b/test/testvarid.cpp index f6b0662d0..bd51dbedb 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -1889,7 +1889,7 @@ private: // #6058 ASSERT_EQUALS("\n\n##file 0\n" - "1: class CPPCHECKLIB Scope { } ;\n", + "1: class Scope { } ;\n", tokenize("class CPPCHECKLIB Scope { };")); // #6073