This commit is contained in:
parent
c860de8565
commit
a4953575f1
|
@ -1996,6 +1996,36 @@ bool Tokenizer::isMemberFunction(const Token *openParen) const
|
|||
isFunctionHead(openParen, "{|:");
|
||||
}
|
||||
|
||||
static bool scopesMatch(const std::string &scope1, const std::string &scope2, const std::list<ScopeInfo3> &scopeList)
|
||||
{
|
||||
if (scope1.empty() || scope2.empty())
|
||||
return false;
|
||||
|
||||
// check if scopes match
|
||||
if (scope1 == scope2)
|
||||
return true;
|
||||
|
||||
if (scopeList.size() < 2)
|
||||
return false;
|
||||
|
||||
// check if scopes only differ by global qualification
|
||||
if (scope1 == (":: " + scope2)) {
|
||||
std::string::size_type end = scope2.find_first_of(' ');
|
||||
if (end == std::string::npos)
|
||||
end = scope2.size();
|
||||
if ((++scopeList.begin())->name == scope2.substr(0, end))
|
||||
return true;
|
||||
} else if (scope2 == (":: " + scope1)) {
|
||||
std::string::size_type end = scope1.find_first_of(' ');
|
||||
if (end == std::string::npos)
|
||||
end = scope1.size();
|
||||
if ((++scopeList.begin())->name == scope1.substr(0, end))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tokenizer::simplifyUsing()
|
||||
{
|
||||
bool substitute = false;
|
||||
|
@ -2159,7 +2189,7 @@ bool Tokenizer::simplifyUsing()
|
|||
// remove the qualification
|
||||
std::string fullScope = scope;
|
||||
std::string removed;
|
||||
while (tok1->strAt(-1) == "::") {
|
||||
while (Token::Match(tok1->tokAt(-2), "%name% ::") && !tok1->tokAt(-2)->isKeyword()) {
|
||||
removed = (tok1->strAt(-2) + " :: ") + removed;
|
||||
if (fullScope == tok1->strAt(-2)) {
|
||||
tok1->deletePrevious();
|
||||
|
@ -2180,6 +2210,12 @@ bool Tokenizer::simplifyUsing()
|
|||
}
|
||||
}
|
||||
|
||||
// remove global namespace if present
|
||||
if (tok1->strAt(-1) == "::") {
|
||||
removed.insert(0, ":: ");
|
||||
tok1->deletePrevious();
|
||||
}
|
||||
|
||||
Token * arrayStart = nullptr;
|
||||
|
||||
// parse the type
|
||||
|
@ -2297,7 +2333,7 @@ bool Tokenizer::simplifyUsing()
|
|||
std::string::size_type idx = removed1.rfind(" ::");
|
||||
if (idx != std::string::npos)
|
||||
removed1.resize(idx);
|
||||
if (removed1 == scope && !removed1.empty()) {
|
||||
if (scopesMatch(removed1, scope, scopeList)) {
|
||||
for (std::list<ScopeInfo3>::const_reverse_iterator it = scopeList.crbegin(); it != scopeList.crend(); ++it) {
|
||||
if (it->recordTypes.find(start->str()) != it->recordTypes.end()) {
|
||||
std::string::size_type spaceIdx = 0;
|
||||
|
|
|
@ -402,7 +402,8 @@ private:
|
|||
TEST_CASE(findFunction35);
|
||||
TEST_CASE(findFunction36); // #10122
|
||||
TEST_CASE(findFunction37); // #10124
|
||||
TEST_CASE(findFunction38); // #10152
|
||||
TEST_CASE(findFunction38); // #10125
|
||||
TEST_CASE(findFunction39); // #10127
|
||||
TEST_CASE(findFunctionContainer);
|
||||
TEST_CASE(findFunctionExternC);
|
||||
TEST_CASE(findFunctionGlobalScope); // ::foo
|
||||
|
@ -6322,6 +6323,26 @@ private:
|
|||
ASSERT_EQUALS(6, functok->function()->tokenDef->linenr());
|
||||
}
|
||||
|
||||
void findFunction39() { // #10127
|
||||
GET_SYMBOL_DB("namespace external {\n"
|
||||
" class V {\n"
|
||||
" public:\n"
|
||||
" using I = int;\n"
|
||||
" };\n"
|
||||
"}\n"
|
||||
"class A {\n"
|
||||
" void f(external::V::I);\n"
|
||||
"};\n"
|
||||
"using ::external::V;\n"
|
||||
"void A::f(V::I) {}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
const Token *functok = Token::findsimplematch(tokenizer.tokens(), "f ( int )");
|
||||
ASSERT(functok);
|
||||
ASSERT(functok->function());
|
||||
ASSERT(functok->function()->name() == "f");
|
||||
ASSERT_EQUALS(8, functok->function()->tokenDef->linenr());
|
||||
}
|
||||
|
||||
void findFunctionContainer() {
|
||||
{
|
||||
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"
|
||||
|
|
Loading…
Reference in New Issue