fix #10183 (performance regression (hang) - ScopeInfo3::findInChildren()) (#3147)

This commit is contained in:
IOBYTE 2021-02-24 00:36:53 -05:00 committed by GitHub
parent 22727ee3ab
commit 9bb57a7b6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 35 additions and 10 deletions

View File

@ -2149,6 +2149,21 @@ namespace {
} }
return qualification; return qualification;
} }
const Token * memberFunctionEnd(const Token *tok)
{
if (tok->str() != "(")
return nullptr;
const Token *end = tok->link()->next();
while (end) {
if (end->str() == "{" && !Token::Match(end->tokAt(-2), ":|, %name%"))
return end;
else if (end->str() == ";")
break;
end = end->next();
}
return nullptr;
}
} // namespace } // namespace
bool Tokenizer::isMemberFunction(const Token *openParen) const bool Tokenizer::isMemberFunction(const Token *openParen) const
@ -2317,6 +2332,9 @@ bool Tokenizer::simplifyUsing()
ScopeInfo3 *currentScope1 = &scopeInfo1; ScopeInfo3 *currentScope1 = &scopeInfo1;
Token *startToken = list.front(); Token *startToken = list.front();
Token *endToken = nullptr; Token *endToken = nullptr;
bool inMemberFunc = false;
const ScopeInfo3 * memberFuncScope = nullptr;
const Token * memberFuncEnd = nullptr;
// We can limit the search to the current function when the type alias // We can limit the search to the current function when the type alias
// is defined in that function. // is defined in that function.
@ -2328,12 +2346,17 @@ bool Tokenizer::simplifyUsing()
return substitute; // something bad happened return substitute; // something bad happened
startToken = usingEnd; startToken = usingEnd;
endToken = currentScope->bodyEnd->next(); endToken = currentScope->bodyEnd->next();
if (currentScope->type == ScopeInfo3::MemberFunction) {
const ScopeInfo3 * temp = currentScope->findScope(currentScope->fullName);
if (temp) {
inMemberFunc = true;
memberFuncScope = temp;
memberFuncEnd = endToken;
}
}
} }
std::string scope1; std::string scope1;
bool inMemberFunc = false;
const ScopeInfo3 * memberFuncScope = nullptr;
const Token * memberFuncEnd = nullptr;
bool skip = false; // don't erase type aliases we can't parse bool skip = false; // don't erase type aliases we can't parse
for (Token* tok1 = startToken; !skip && tok1 && tok1 != endToken; tok1 = tok1->next()) { for (Token* tok1 = startToken; !skip && tok1 && tok1 != endToken; tok1 = tok1->next()) {
if ((Token::Match(tok1, "{|}|namespace|class|struct|union") && tok1->strAt(-1) != "using") || if ((Token::Match(tok1, "{|}|namespace|class|struct|union") && tok1->strAt(-1) != "using") ||
@ -2368,13 +2391,15 @@ bool Tokenizer::simplifyUsing()
if (!scope1.empty()) if (!scope1.empty())
scope1 += " :: "; scope1 += " :: ";
scope1 += memberFunctionScope(tok1); scope1 += memberFunctionScope(tok1);
memberFuncScope = currentScope1->findScope(scope1); const ScopeInfo3 * temp = currentScope1->findScope(scope1);
if (temp) {
if (!memberFuncScope) const Token *end = memberFunctionEnd(tok1);
continue; if (end) {
inMemberFunc = true;
inMemberFunc = true; memberFuncScope = temp;
memberFuncEnd = currentScope1->bodyEnd; memberFuncEnd = end;
}
}
continue; continue;
} else if (inMemberFunc && memberFuncScope) { } else if (inMemberFunc && memberFuncScope) {
if (!usingMatch(nameToken, scope, &tok1, scope1, memberFuncScope)) if (!usingMatch(nameToken, scope, &tok1, scope1, memberFuncScope))