Skip to content

Commit 7568f18

Browse files
committed
fix #13967
1 parent 7ceb7a8 commit 7568f18

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

lib/symboldatabase.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,30 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
173173

174174
const bool doProgress = (mSettings.reportProgress != -1);
175175

176+
std::map<Scope *, std::set<std::string>> forwardDecls;
177+
178+
const std::function<Scope *(const Token *, Scope *)> findForwardDeclScope = [&](const Token *tok, Scope *startScope) {
179+
if (tok->str() == "::")
180+
return findForwardDeclScope(tok->next(), &scopeList.front());
181+
182+
if (Token::Match(tok, "%name% :: %name%")) {
183+
auto it = std::find_if(startScope->nestedList.cbegin(), startScope->nestedList.cend(), [&](const Scope *scope) {
184+
return scope->className == tok->str();
185+
});
186+
187+
if (it == startScope->nestedList.cend())
188+
return static_cast<Scope *>(nullptr);
189+
190+
return findForwardDeclScope(tok->tokAt(2), *it);
191+
}
192+
193+
auto it = forwardDecls.find(startScope);
194+
if (it == forwardDecls.cend())
195+
return static_cast<Scope *>(nullptr);
196+
197+
return it->second.count(tok->str()) > 0 ? startScope : nullptr;
198+
};
199+
176200
// find all scopes
177201
for (const Token *tok = mTokenizer.tokens(); tok; tok = tok ? tok->next() : nullptr) {
178202
// #5593 suggested to add here:
@@ -291,7 +315,11 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
291315
scope = new_scope;
292316
tok = tok2;
293317
} else {
294-
scopeList.emplace_back(*this, tok, scope);
318+
319+
const Scope *forwardDeclScope = findForwardDeclScope(tok->next(), scope);
320+
const Scope *nestedIn = forwardDeclScope ? forwardDeclScope : scope;
321+
322+
scopeList.emplace_back(*this, tok, nestedIn);
295323
new_scope = &scopeList.back();
296324

297325
if (tok->str() == "class")
@@ -303,7 +331,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
303331
if (new_scope->isClassOrStructOrUnion() || new_scope->type == ScopeType::eEnum) {
304332
Type* new_type = findType(name, scope);
305333
if (!new_type) {
306-
typeList.emplace_back(new_scope->classDef, new_scope, scope);
334+
typeList.emplace_back(new_scope->classDef, new_scope, nestedIn);
307335
new_type = &typeList.back();
308336
scope->definedTypesMap[new_type->name()] = new_type;
309337
} else
@@ -386,6 +414,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
386414
typeList.emplace_back(tok, nullptr, scope);
387415
Type* new_type = &typeList.back();
388416
scope->definedTypesMap[new_type->name()] = new_type;
417+
forwardDecls[scope].insert(tok->strAt(1));
389418
}
390419
tok = tok->tokAt(2);
391420
}

0 commit comments

Comments
 (0)