Tokenizer::simplifyUsing; Fixed bug when enum class is used
This commit is contained in:
parent
e62cdbb664
commit
d73ab0ad96
|
@ -1901,14 +1901,25 @@ namespace {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void setScopeInfo(Token *tok, ScopeInfo3 **scopeInfo)
|
void setScopeInfo(Token *tok, ScopeInfo3 **scopeInfo, bool debug=false)
|
||||||
{
|
{
|
||||||
if (!tok)
|
if (!tok)
|
||||||
return;
|
return;
|
||||||
if (tok->str() == "{" && (*scopeInfo)->parent && tok == (*scopeInfo)->bodyStart)
|
if (tok->str() == "{" && (*scopeInfo)->parent && tok == (*scopeInfo)->bodyStart)
|
||||||
return;
|
return;
|
||||||
if (tok->str() == "}" && (*scopeInfo)->parent && tok == (*scopeInfo)->bodyEnd) {
|
if (tok->str() == "}") {
|
||||||
*scopeInfo = (*scopeInfo)->parent;
|
if ((*scopeInfo)->parent && tok == (*scopeInfo)->bodyEnd)
|
||||||
|
*scopeInfo = (*scopeInfo)->parent;
|
||||||
|
else {
|
||||||
|
// Try to find parent scope
|
||||||
|
ScopeInfo3 *parent = (*scopeInfo)->parent;
|
||||||
|
while (parent && parent->bodyEnd != tok)
|
||||||
|
parent = parent->parent;
|
||||||
|
if (parent)
|
||||||
|
*scopeInfo = parent;
|
||||||
|
if (debug)
|
||||||
|
throw std::runtime_error("Internal error: unmatched }");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Token::Match(tok, "namespace|class|struct|union %name% {|:|::|<")) {
|
if (!Token::Match(tok, "namespace|class|struct|union %name% {|:|::|<")) {
|
||||||
|
@ -2235,9 +2246,26 @@ bool Tokenizer::simplifyUsing()
|
||||||
if (Settings::terminated())
|
if (Settings::terminated())
|
||||||
return substitute;
|
return substitute;
|
||||||
|
|
||||||
|
if (Token::simpleMatch(tok, "enum class")) {
|
||||||
|
Token *bodyStart = tok;
|
||||||
|
while (Token::Match(bodyStart, "%name%|:|::|<")) {
|
||||||
|
if (bodyStart->str() == "<")
|
||||||
|
bodyStart = bodyStart->findClosingBracket();
|
||||||
|
bodyStart = bodyStart ? bodyStart->next() : nullptr;
|
||||||
|
}
|
||||||
|
if (Token::simpleMatch(bodyStart, "{"))
|
||||||
|
tok = bodyStart->link();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (Token::Match(tok, "{|}|namespace|class|struct|union") ||
|
if (Token::Match(tok, "{|}|namespace|class|struct|union") ||
|
||||||
Token::Match(tok, "using namespace %name% ;|::")) {
|
Token::Match(tok, "using namespace %name% ;|::")) {
|
||||||
setScopeInfo(tok, ¤tScope);
|
try {
|
||||||
|
setScopeInfo(tok, ¤tScope, mSettings->debugwarnings);
|
||||||
|
} catch (const std::runtime_error &e) {
|
||||||
|
reportError(tok, Severity::debug, "simplifyUsingUnmatchedBodyEnd",
|
||||||
|
"simplifyUsing: unmatched body end");
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2386,7 +2414,12 @@ bool Tokenizer::simplifyUsing()
|
||||||
|
|
||||||
if ((Token::Match(tok1, "{|}|namespace|class|struct|union") && tok1->strAt(-1) != "using") ||
|
if ((Token::Match(tok1, "{|}|namespace|class|struct|union") && tok1->strAt(-1) != "using") ||
|
||||||
Token::Match(tok1, "using namespace %name% ;|::")) {
|
Token::Match(tok1, "using namespace %name% ;|::")) {
|
||||||
setScopeInfo(tok1, ¤tScope1);
|
try {
|
||||||
|
setScopeInfo(tok1, ¤tScope1, mSettings->debugwarnings);
|
||||||
|
} catch (const std::runtime_error &e) {
|
||||||
|
reportError(tok1, Severity::debug, "simplifyUsingUnmatchedBodyEnd",
|
||||||
|
"simplifyUsing: unmatched body end");
|
||||||
|
}
|
||||||
scope1 = currentScope1->fullName;
|
scope1 = currentScope1->fullName;
|
||||||
if (inMemberFunc && memberFuncEnd && tok1 == memberFuncEnd) {
|
if (inMemberFunc && memberFuncEnd && tok1 == memberFuncEnd) {
|
||||||
inMemberFunc = false;
|
inMemberFunc = false;
|
||||||
|
@ -2406,6 +2439,8 @@ bool Tokenizer::simplifyUsing()
|
||||||
|
|
||||||
// check for enum with body
|
// check for enum with body
|
||||||
if (tok1->str() == "enum") {
|
if (tok1->str() == "enum") {
|
||||||
|
if (Token::simpleMatch(tok1, "enum class"))
|
||||||
|
tok1 = tok1->next();
|
||||||
Token *defStart = tok1;
|
Token *defStart = tok1;
|
||||||
while (Token::Match(defStart, "%name%|::|:"))
|
while (Token::Match(defStart, "%name%|::|:"))
|
||||||
defStart = defStart->next();
|
defStart = defStart->next();
|
||||||
|
|
|
@ -90,6 +90,8 @@ private:
|
||||||
TEST_CASE(simplifyUsing10172);
|
TEST_CASE(simplifyUsing10172);
|
||||||
TEST_CASE(simplifyUsing10173);
|
TEST_CASE(simplifyUsing10173);
|
||||||
TEST_CASE(simplifyUsing10335);
|
TEST_CASE(simplifyUsing10335);
|
||||||
|
|
||||||
|
TEST_CASE(scopeInfo1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) {
|
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) {
|
||||||
|
@ -1311,6 +1313,17 @@ private:
|
||||||
const char exp[] = "enum E : unsigned char { E0 } ;";
|
const char exp[] = "enum E : unsigned char { E0 } ;";
|
||||||
ASSERT_EQUALS(exp, tok(code, false));
|
ASSERT_EQUALS(exp, tok(code, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scopeInfo1() {
|
||||||
|
const char code[] = "struct A {\n"
|
||||||
|
" enum class Mode { UNKNOWN, ENABLED, NONE, };\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"namespace spdlog { class logger; }\n"
|
||||||
|
"using LoggerPtr = std::shared_ptr<spdlog::logger>;";
|
||||||
|
tok(code, true);
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestSimplifyUsing)
|
REGISTER_TEST(TestSimplifyUsing)
|
||||||
|
|
Loading…
Reference in New Issue