diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 5cd1834f9ef..b81269a5dfd 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8807,6 +8807,20 @@ void Tokenizer::simplifyFunctionTryCatch() } } +static bool isAnonymousEnum(const Token* tok) +{ + if (!Token::Match(tok, "enum {|:")) + return false; + if (tok->index() > 2 && Token::Match(tok->tokAt(-3), "using %name% =")) + return false; + const Token* end = tok->next(); + if (end->str() == ":") { + end = end->next(); + while (Token::Match(end, "%name%|::")) + end = end->next(); + } + return end && Token::Match(end->link(), "} (| %type%| )| [,;[({=]"); +} void Tokenizer::simplifyStructDecl() { @@ -8833,10 +8847,7 @@ void Tokenizer::simplifyStructDecl() } } // check for anonymous enum - else if ((Token::simpleMatch(tok, "enum {") && - !Token::Match(tok->tokAt(-3), "using %name% =") && - Token::Match(tok->next()->link(), "} (| %type%| )| ,|;|[|(|{")) || - (Token::Match(tok, "enum : %type% {") && Token::Match(tok->linkAt(3), "} (| %type%| )| ,|;|[|(|{"))) { + else if (isAnonymousEnum(tok)) { Token *start = tok->strAt(1) == ":" ? tok->linkAt(3) : tok->linkAt(1); if (start && Token::Match(start->next(), "( %type% )")) { start->next()->link()->deleteThis(); diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 0f46f1e3998..209f53f3a48 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -1252,24 +1252,53 @@ class TestSimplifyTokens : public TestFixture { } void simplifyStructDecl9() { - const char* code = "enum E : int;\n" // #12588 - "void f() {}\n" - "namespace {\n" - " struct S {\n" - " explicit S(int i) : m(i) {}\n" - " int m;\n" - " };\n" - "}\n" - "void g() { S s(0); }\n"; - const char* exp = "enum E : int ; " - "void f ( ) { } " - "namespace { " - "struct S { " - "explicit S ( int i ) : m ( i ) { } " - "int m ; " - "} ; " - "} " - "void g ( ) { S s ( 0 ) ; }"; + const char *code{}, *exp{}; + code = "enum E : int;\n" // #12588 + "void f() {}\n" + "namespace {\n" + " struct S {\n" + " explicit S(int i) : m(i) {}\n" + " int m;\n" + " };\n" + "}\n" + "void g() { S s(0); }\n"; + exp = "enum E : int ; " + "void f ( ) { } " + "namespace { " + "struct S { " + "explicit S ( int i ) : m ( i ) { } " + "int m ; " + "} ; " + "} " + "void g ( ) { S s ( 0 ) ; }"; + ASSERT_EQUALS(exp, tok(code)); + + code = "struct S {\n" // 12595 + " explicit S() {\n" + " e = E1;\n" + " }\n" + " enum { E1 } e = E1;\n" + "};\n"; + exp = "struct S { " + "explicit S ( ) { e = E1 ; } " + "enum Anonymous0 { E1 } ; " + "enum Anonymous0 e ; " + "e = E1 ; " + "} ;"; + ASSERT_EQUALS(exp, tok(code)); + + code = "struct S {\n" + " explicit S() {\n" + " e = E1;\n" + " }\n" + " enum : std::uint8_t { E1 } e = E1;\n" + "};\n"; + exp = "struct S { " + "explicit S ( ) { e = E1 ; } " + "enum Anonymous0 : std :: uint8_t { E1 } ; " + "enum Anonymous0 e ; " + "e = E1 ; " + "} ;"; ASSERT_EQUALS(exp, tok(code)); }