diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index de3597a00..76fa236b2 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1830,7 +1830,6 @@ namespace { tok2 = tok2->tokAt(-2); } - // todo: check using namespace std::string fullScope1 = scope1; if (!scope1.empty() && !qualification.empty()) fullScope1 += " :: "; @@ -1839,6 +1838,19 @@ namespace { if (scope == fullScope1) return true; + // check using namespace + if (!scopeList1.back().usingNamespaces.empty()) { + if (qualification.empty()) { + if (scopeList1.back().usingNamespaces.find(scope) != scopeList1.back().usingNamespaces.end()) + return true; + } else { + for (auto ns : scopeList1.back().usingNamespaces) { + if (scope == ns + " :: " + qualification) + return true; + } + } + } + std::string newScope1 = scope1; // scopes didn't match so try higher scopes @@ -2024,9 +2036,25 @@ bool Tokenizer::simplifyUsing() continue; // remove the qualification - while (tok1->strAt(-1) == "::" && tok1->strAt(-2) == scope) { - tok1->deletePrevious(); - tok1->deletePrevious(); + std::string fullScope = scope; + while (tok1->strAt(-1) == "::") { + if (fullScope == tok1->strAt(-2)) { + tok1->deletePrevious(); + tok1->deletePrevious(); + break; + } else { + const std::string::size_type idx = fullScope.rfind(" "); + + if (idx == std::string::npos) + break; + + if (tok1->strAt(-2) == fullScope.substr(idx + 1)) { + tok1->deletePrevious(); + tok1->deletePrevious(); + fullScope.resize(idx - 3); + } else + break; + } } Token * arrayStart = nullptr; diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 83e081208..2372959bc 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -64,6 +64,7 @@ private: TEST_CASE(simplifyUsing8976); TEST_CASE(simplifyUsing9040); TEST_CASE(simplifyUsing9042); + TEST_CASE(simplifyUsing9191); } std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) { @@ -494,6 +495,35 @@ private: ASSERT_EQUALS(exp, tok(code, true, Settings::Win64)); } + void simplifyUsing9191() { + const char code[] = "namespace NS1 {\n" + " namespace NS2 {\n" + " using _LONG = signed long long;\n" + " }\n" + "}\n" + "void f1() {\n" + " using namespace NS1;\n" + " NS2::_LONG A;\n" + "}\n" + "void f2() {\n" + " using namespace NS1::NS2;\n" + " _LONG A;\n" + "}"; + + const char exp[] = "namespace NS1 { " + "} " + "void f1 ( ) { " + "using namespace NS1 ; " + "signed long long A ; " + "} " + "void f2 ( ) { " + "using namespace NS1 :: NS2 ; " + "signed long long A ; " + "}"; + + ASSERT_EQUALS(exp, tok(code, false)); + } + }; REGISTER_TEST(TestSimplifyUsing)