This commit is contained in:
parent
c860de8565
commit
a4953575f1
|
@ -1996,6 +1996,36 @@ bool Tokenizer::isMemberFunction(const Token *openParen) const
|
||||||
isFunctionHead(openParen, "{|:");
|
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 Tokenizer::simplifyUsing()
|
||||||
{
|
{
|
||||||
bool substitute = false;
|
bool substitute = false;
|
||||||
|
@ -2159,7 +2189,7 @@ bool Tokenizer::simplifyUsing()
|
||||||
// remove the qualification
|
// remove the qualification
|
||||||
std::string fullScope = scope;
|
std::string fullScope = scope;
|
||||||
std::string removed;
|
std::string removed;
|
||||||
while (tok1->strAt(-1) == "::") {
|
while (Token::Match(tok1->tokAt(-2), "%name% ::") && !tok1->tokAt(-2)->isKeyword()) {
|
||||||
removed = (tok1->strAt(-2) + " :: ") + removed;
|
removed = (tok1->strAt(-2) + " :: ") + removed;
|
||||||
if (fullScope == tok1->strAt(-2)) {
|
if (fullScope == tok1->strAt(-2)) {
|
||||||
tok1->deletePrevious();
|
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;
|
Token * arrayStart = nullptr;
|
||||||
|
|
||||||
// parse the type
|
// parse the type
|
||||||
|
@ -2297,7 +2333,7 @@ bool Tokenizer::simplifyUsing()
|
||||||
std::string::size_type idx = removed1.rfind(" ::");
|
std::string::size_type idx = removed1.rfind(" ::");
|
||||||
if (idx != std::string::npos)
|
if (idx != std::string::npos)
|
||||||
removed1.resize(idx);
|
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) {
|
for (std::list<ScopeInfo3>::const_reverse_iterator it = scopeList.crbegin(); it != scopeList.crend(); ++it) {
|
||||||
if (it->recordTypes.find(start->str()) != it->recordTypes.end()) {
|
if (it->recordTypes.find(start->str()) != it->recordTypes.end()) {
|
||||||
std::string::size_type spaceIdx = 0;
|
std::string::size_type spaceIdx = 0;
|
||||||
|
|
|
@ -402,7 +402,8 @@ private:
|
||||||
TEST_CASE(findFunction35);
|
TEST_CASE(findFunction35);
|
||||||
TEST_CASE(findFunction36); // #10122
|
TEST_CASE(findFunction36); // #10122
|
||||||
TEST_CASE(findFunction37); // #10124
|
TEST_CASE(findFunction37); // #10124
|
||||||
TEST_CASE(findFunction38); // #10152
|
TEST_CASE(findFunction38); // #10125
|
||||||
|
TEST_CASE(findFunction39); // #10127
|
||||||
TEST_CASE(findFunctionContainer);
|
TEST_CASE(findFunctionContainer);
|
||||||
TEST_CASE(findFunctionExternC);
|
TEST_CASE(findFunctionExternC);
|
||||||
TEST_CASE(findFunctionGlobalScope); // ::foo
|
TEST_CASE(findFunctionGlobalScope); // ::foo
|
||||||
|
@ -6322,6 +6323,26 @@ private:
|
||||||
ASSERT_EQUALS(6, functok->function()->tokenDef->linenr());
|
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() {
|
void findFunctionContainer() {
|
||||||
{
|
{
|
||||||
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"
|
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"
|
||||||
|
|
Loading…
Reference in New Issue