diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 15f0e0b98..ba3b23f8b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -7934,13 +7934,13 @@ void Tokenizer::simplifyComma() for (Token *tok = list.front(); tok; tok = tok->next()) { // skip enums - if (Token::Match(tok, "enum class| %name%| :| %name%| {")) { - while (tok && tok->str() != "{") - tok = tok->next(); - if (tok) - tok = tok->link()->next(); + if (Token::Match(tok, "enum class|struct| %name%| :|{")) { + Token *defStart = tok->next(); + while (Token::Match(defStart, "%name%|::|:")) + defStart = defStart->next(); + if (defStart && defStart->str() == "{") + tok = defStart->link()->next(); } - if (!tok) syntaxError(nullptr); // invalid code like in #4195 @@ -9112,6 +9112,13 @@ void Tokenizer::simplifyNamespaceStd() for (const Token* tok = Token::findsimplematch(list.front(), "using namespace std ;"); tok; tok = tok->next()) { bool insert = false; + if (Token::Match(tok, "enum class|struct| %name%| :|{")) { // Don't replace within enum definitions + Token *defStart = tok->next(); + while (Token::Match(defStart, "%name%|::|:")) + defStart = defStart->next(); + if (defStart && defStart->str() == "{") + tok = defStart->link(); + } if (!Token::Match(tok->previous(), ".|::")) { if (Token::Match(tok, "%name% (") && !Token::Match(tok->linkAt(1)->next(), "%name%|{") && stdFunctions.find(tok->str()) != stdFunctions.end()) insert = true; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0291a3285..69214acc8 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -5568,6 +5568,33 @@ private: "void search ( ) { }\n" "} ;"; ASSERT_EQUALS(expected14, tokenizeAndStringify(code14, false)); + + // Ticket #8091 + ASSERT_EQUALS("enum Anonymous0 { string } ;", + tokenizeAndStringify("using namespace std; " + "enum { string };")); + ASSERT_EQUALS("enum Type { string } ;", + tokenizeAndStringify("using namespace std; " + "enum Type { string } ;")); + ASSERT_EQUALS("enum class Type { string } ;", + tokenizeAndStringify("using namespace std; " + "enum class Type { string } ;")); + ASSERT_EQUALS("enum struct Type { string } ;", + tokenizeAndStringify("using namespace std; " + "enum struct Type { string } ;")); + ASSERT_EQUALS("enum struct Type : int { f = 0 , string } ;", + tokenizeAndStringify("using namespace std; " + "enum struct Type : int { f = 0 , string } ;")); + ASSERT_EQUALS("enum Type { a , b } ; void foo ( enum Type , std :: string ) { }", + tokenizeAndStringify("using namespace std; " + "enum Type { a , b } ; void foo ( enum Type , string) {}")); + ASSERT_EQUALS("struct T { } ; enum struct Type : int { f = 0 , string } ;", + tokenizeAndStringify("using namespace std; " + "struct T { typedef int type; } ; " + "enum struct Type : T :: type { f = 0 , string } ;")); + // Handle garbage enum code "well" + ASSERT_EQUALS("enum E : int ; void foo ( ) { std :: string s ; }", + tokenizeAndStringify("using namespace std; enum E : int ; void foo ( ) { string s ; }")); } void microsoftMemory() {