diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index bd69a3f43..beb569871 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2008,6 +2008,8 @@ bool Tokenizer::tokenize(std::istream &code, simplifyRedundantConsecutiveBraces(); + simplifyEmptyNamespaces(); + bool valid = validate(); if (valid) createSymbolDatabase(); @@ -3427,6 +3429,8 @@ bool Tokenizer::simplifyTokenList() simplifyRedundantConsecutiveBraces(); + simplifyEmptyNamespaces(); + if (!validate()) return false; @@ -3608,6 +3612,41 @@ void Tokenizer::simplifyRealloc() } } +void Tokenizer::simplifyEmptyNamespaces() +{ + if (isC()) + return; + + bool goback = false; + for (Token *tok = list.front(); tok; tok = tok->next()) { + if (goback) { + tok = tok->previous(); + goback = false; + } + if (tok->str() == "(" || tok->str() == "[" || tok->str() == "{") { + tok = tok->link(); + continue; + } + if (!Token::Match(tok, "namespace %var% {")) + continue; + if (tok->strAt(3) == "}") { + tok->deleteNext(3); // remove '%var% { }' + if (tok->next()) { // '%empty% namespace %anytoken%'? + if (!tok->previous()) { + tok->deleteThis(); // remove 'namespace' + goback = true; + } else { // '%any% namespace %any%' + tok = tok->previous(); // goto previous token + tok->deleteNext(); // remove next token: 'namespace' + } + } else // '%empty% namespace %empty%'? + tok->str(";"); // change 'namespace' to ';' + } else { + tok = tok->tokAt(2); + } + } +} + void Tokenizer::simplifyFlowControl() { diff --git a/lib/tokenize.h b/lib/tokenize.h index 03c1903b4..f4f07a334 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -341,6 +341,9 @@ public: /** Replace a "goto" with the statements */ void simplifyGoto(); + /** Simplify useless C++ empty namespaces, like: 'namespace %var% { }'*/ + void simplifyEmptyNamespaces(); + /** Simplify redundant code placed after control flow statements : * 'return', 'throw', 'goto', 'break' and 'continue' */ diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 80e1e703b..c644390c7 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2379,6 +2379,12 @@ private: void namespaces() { + { + const char code[] = "namespace std { }"; + + ASSERT_EQUALS(";", tok(code)); + } + { const char code[] = "using namespace std; namespace a{ namespace b{ void f(){} } }"; @@ -2395,14 +2401,6 @@ private: ASSERT_EQUALS(expected, tok(code)); } - { - const char code[] = "int a; namespace b{ }"; - - const std::string expected("int a ; namespace b { }"); - - ASSERT_EQUALS(expected, tok(code)); - } - { const char code[] = "void f(int namespace) { }"; @@ -5629,11 +5627,9 @@ private: const char code[] = "typedef long Long;\n" "namespace NS {\n" "}\n"; - const char expected[] = "namespace NS { " - "}"; checkSimplifyTypedef(code); - ASSERT_EQUALS(expected, tok(code)); + ASSERT_EQUALS(";", tok(code)); ASSERT_EQUALS("", errout.str()); }