From 9569fa1374efc0a1cd478d6ba075b4b8f115f7b8 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Sat, 6 Jul 2019 14:22:13 -0400 Subject: [PATCH] Partial fix for #9191 (simplifyTypedef: Problem when namespace is used) (#1952) * Partial fix for #9191 (simplifyTypedef: Problem when namespace is used) This fixes simplifyUsing which has the same problem as simplifyTypedef. simplifyUsing was designed to support using namespace but it was never implemented. The changes are minor to add it. simplifyTypedef requires much more work to support using namespace. * reduce scope of variable * make idx const --- lib/tokenize.cpp | 36 ++++++++++++++++++++++++++++++++---- test/testsimplifyusing.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) 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)