@@ -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