@@ -173,13 +173,38 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
173
173
174
174
const bool doProgress = (mSettings .reportProgress != -1 );
175
175
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
+
176
200
// find all scopes
177
201
for (const Token *tok = mTokenizer .tokens (); tok; tok = tok ? tok->next () : nullptr ) {
178
202
// #5593 suggested to add here:
179
203
if (doProgress)
180
204
mErrorLogger .reportProgress (mTokenizer .list .getSourceFilePath (),
181
205
" SymbolDatabase" ,
182
206
tok->progressValue ());
207
+
183
208
// Locate next class
184
209
if ((tok->isCpp () && tok->isKeyword () &&
185
210
((Token::Match (tok, " class|struct|union|namespace ::| %name% final| {|:|::|<" ) &&
@@ -291,7 +316,11 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
291
316
scope = new_scope;
292
317
tok = tok2;
293
318
} 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);
295
324
new_scope = &scopeList.back ();
296
325
297
326
if (tok->str () == " class" )
@@ -303,7 +332,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
303
332
if (new_scope->isClassOrStructOrUnion () || new_scope->type == ScopeType::eEnum) {
304
333
Type* new_type = findType (name, scope);
305
334
if (!new_type) {
306
- typeList.emplace_back (new_scope->classDef , new_scope, scope );
335
+ typeList.emplace_back (new_scope->classDef , new_scope, nestedIn );
307
336
new_type = &typeList.back ();
308
337
scope->definedTypesMap [new_type->name ()] = new_type;
309
338
} else
@@ -386,6 +415,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
386
415
typeList.emplace_back (tok, nullptr , scope);
387
416
Type* new_type = &typeList.back ();
388
417
scope->definedTypesMap [new_type->name ()] = new_type;
418
+ forwardDecls[scope].insert (tok->strAt (1 ));
389
419
}
390
420
tok = tok->tokAt (2 );
391
421
}
0 commit comments