Skip to content

Commit e1f4230

Browse files
committed
fix #13967
1 parent 7ceb7a8 commit e1f4230

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

lib/symboldatabase.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,38 @@ 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 (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 (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:
179203
if (doProgress)
180204
mErrorLogger.reportProgress(mTokenizer.list.getSourceFilePath(),
181205
"SymbolDatabase",
182206
tok->progressValue());
207+
183208
// Locate next class
184209
if ((tok->isCpp() && tok->isKeyword() &&
185210
((Token::Match(tok, "class|struct|union|namespace ::| %name% final| {|:|::|<") &&
@@ -291,7 +316,11 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
291316
scope = new_scope;
292317
tok = tok2;
293318
} else {
294-
scopeList.emplace_back(*this, tok, scope);
319+
320+
const Scope *forwardDeclScope = findForwardDeclScope(tok->next(), scope);
321+
const Scope *nestedIn = forwardDeclScope ? forwardDeclScope : scope;
322+
323+
scopeList.emplace_back(*this, tok, nestedIn);
295324
new_scope = &scopeList.back();
296325

297326
if (tok->str() == "class")
@@ -303,7 +332,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
303332
if (new_scope->isClassOrStructOrUnion() || new_scope->type == ScopeType::eEnum) {
304333
Type* new_type = findType(name, scope);
305334
if (!new_type) {
306-
typeList.emplace_back(new_scope->classDef, new_scope, scope);
335+
typeList.emplace_back(new_scope->classDef, new_scope, nestedIn);
307336
new_type = &typeList.back();
308337
scope->definedTypesMap[new_type->name()] = new_type;
309338
} else
@@ -386,6 +415,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
386415
typeList.emplace_back(tok, nullptr, scope);
387416
Type* new_type = &typeList.back();
388417
scope->definedTypesMap[new_type->name()] = new_type;
418+
forwardDecls[scope].insert(tok->strAt(1));
389419
}
390420
tok = tok->tokAt(2);
391421
}

0 commit comments

Comments
 (0)