Skip to content

Commit 1705d09

Browse files
authored
Simplify empty anonymous namespaces. (cppcheck-opensource#2673)
1 parent a45c775 commit 1705d09

3 files changed

Lines changed: 22 additions & 8 deletions

File tree

lib/tokenize.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5375,20 +5375,26 @@ void Tokenizer::simplifyEmptyNamespaces()
53755375
tok = tok->link();
53765376
continue;
53775377
}
5378-
if (!Token::Match(tok, "namespace %name% {"))
5378+
if (!Token::Match(tok, "namespace %name%| {"))
53795379
continue;
5380-
if (tok->strAt(3) == "}") {
5381-
tok->deleteNext(3); // remove '%name% { }'
5380+
bool isAnonymousNS = tok->strAt(1) == "{";
5381+
if (tok->strAt(3 - isAnonymousNS) == "}") {
5382+
tok->deleteNext(3 - isAnonymousNS); // remove '%name%| { }'
53825383
if (!tok->previous()) {
53835384
// remove 'namespace' or replace it with ';' if isolated
53845385
tok->deleteThis();
53855386
goback = true;
53865387
} else { // '%any% namespace %any%'
53875388
tok = tok->previous(); // goto previous token
53885389
tok->deleteNext(); // remove next token: 'namespace'
5390+
if (tok->str() == "{") {
5391+
// Go back in case we were within a namespace that's empty now
5392+
tok = tok->tokAt(-2) ? tok->tokAt(-2) : tok->previous();
5393+
goback = true;
5394+
}
53895395
}
53905396
} else {
5391-
tok = tok->tokAt(2);
5397+
tok = tok->tokAt(2 - isAnonymousNS);
53925398
}
53935399
}
53945400
}

test/testsimplifyusing.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,7 @@ class TestSimplifyUsing : public TestFixture {
512512
" _LONG A;\n"
513513
"}";
514514

515-
const char exp[] = "namespace NS1 { "
516-
"} "
517-
"void f1 ( ) { "
515+
const char exp[] = "void f1 ( ) { "
518516
"using namespace NS1 ; "
519517
"signed long long A ; "
520518
"} "

test/testtokenize.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,8 @@ class TestTokenizer : public TestFixture {
443443

444444
TEST_CASE(simplifyCaseRange);
445445

446+
TEST_CASE(simplifyEmptyNamespaces);
447+
446448
TEST_CASE(compileLimits); // #5592 crash: gcc: testsuit: gcc.c-torture/compile/limits-declparen.c
447449

448450
TEST_CASE(prepareTernaryOpForAST);
@@ -6621,7 +6623,7 @@ class TestTokenizer : public TestFixture {
66216623
// remove some unhandled macros in the global scope.
66226624
ASSERT_EQUALS("void f ( ) { }", tokenizeAndStringify("void f() NOTHROW { }"));
66236625
ASSERT_EQUALS("struct Foo { } ;", tokenizeAndStringify("struct __declspec(dllexport) Foo {};"));
6624-
ASSERT_EQUALS("namespace { }", tokenizeAndStringify("ABA() namespace { }"));
6626+
ASSERT_EQUALS("namespace { int a ; }", tokenizeAndStringify("ABA() namespace { int a ; }"));
66256627

66266628
// #3750
66276629
ASSERT_THROW(tokenizeAndStringify("; AB(foo*) foo::foo() { }"), InternalError);
@@ -7365,6 +7367,14 @@ class TestTokenizer : public TestFixture {
73657367
ASSERT_EQUALS("void f ( ) { switch ( x ) { case '[' : case '\\\\' : case ']' : ; } }", tokenizeAndStringify("void f() { switch(x) { case '[' ... ']': } }"));
73667368
}
73677369

7370+
void simplifyEmptyNamespaces() {
7371+
ASSERT_EQUALS("", tokenizeAndStringify("namespace { }"));
7372+
ASSERT_EQUALS("", tokenizeAndStringify("namespace foo { }"));
7373+
ASSERT_EQUALS("", tokenizeAndStringify("namespace foo { namespace { } }"));
7374+
ASSERT_EQUALS("", tokenizeAndStringify("namespace { namespace { } }")); // Ticket #9512
7375+
ASSERT_EQUALS("", tokenizeAndStringify("namespace foo { namespace bar { } }"));
7376+
}
7377+
73687378
void prepareTernaryOpForAST() {
73697379
ASSERT_EQUALS("a ? b : c ;", tokenizeAndStringify("a ? b : c;"));
73707380

0 commit comments

Comments
 (0)