Skip to content

Commit 64fa7bf

Browse files
committed
symbol database: add support for anonymous struct and union
1 parent a39444a commit 64fa7bf

1 file changed

Lines changed: 44 additions & 6 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,36 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
139139
tok = tok2;
140140
}
141141

142+
// anonymous struct and union
143+
else if (Token::Match(tok, "struct|union {") &&
144+
Token::simpleMatch(tok->next()->link(), "} ;"))
145+
{
146+
scopeList.push_back(Scope(this, tok, scope));
147+
148+
Scope *new_scope = &scopeList.back();
149+
150+
const Token *tok2 = tok->next();
151+
152+
new_scope->classStart = tok2;
153+
new_scope->classEnd = tok2->link();
154+
155+
// make sure we have valid code
156+
if (!new_scope->classEnd)
157+
{
158+
scopeList.pop_back();
159+
break;
160+
}
161+
162+
// make the new scope the current scope
163+
scope = &scopeList.back();
164+
scope->nestedIn->nestedList.push_back(scope);
165+
166+
tok = tok2;
167+
}
168+
142169
else
143170
{
144-
// check for end of space
171+
// check for end of scope
145172
if (tok == scope->classEnd)
146173
{
147174
scope = scope->nestedIn;
@@ -925,7 +952,7 @@ void SymbolDatabase::addFunction(Scope **scope, const Token **tok, const Token *
925952
bool match = false;
926953
if (scope1->className == tok1->str() && (scope1->type != Scope::eFunction))
927954
{
928-
// do the spaces match (same space) or do their names match (multiple namespaces)
955+
// do the scopes match (same scope) or do their names match (multiple namespaces)
929956
if ((*scope == scope1->nestedIn) || (*scope && scope1 &&
930957
(*scope)->className == scope1->nestedIn->className &&
931958
!(*scope)->className.empty() &&
@@ -1331,15 +1358,15 @@ Scope::Scope(SymbolDatabase *check_, const Token *classDef_, Scope *nestedIn_) :
13311358
else if (classDef->str() == "struct")
13321359
{
13331360
type = Scope::eStruct;
1334-
// unnamed structs don't have a name
1361+
// anonymous and unnamed structs don't have a name
13351362
if (classDef->next()->str() != "{")
13361363
className = classDef->next()->str();
13371364
access = Public;
13381365
}
13391366
else if (classDef->str() == "union")
13401367
{
13411368
type = Scope::eUnion;
1342-
// unnamed unions don't have a name
1369+
// anonymous and unnamed unions don't have a name
13431370
if (classDef->next()->str() != "{")
13441371
className = classDef->next()->str();
13451372
access = Public;
@@ -1400,6 +1427,7 @@ void Scope::getVariableList()
14001427
{
14011428
AccessControl varaccess = defaultAccess();
14021429
const Token *start;
1430+
int level = 1;
14031431

14041432
if (classStart)
14051433
start = classStart->next();
@@ -1408,9 +1436,13 @@ void Scope::getVariableList()
14081436

14091437
for (const Token *tok = start; tok; tok = tok->next())
14101438
{
1411-
// end of space?
1439+
// end of scope?
14121440
if (tok->str() == "}")
1413-
break;
1441+
{
1442+
level--;
1443+
if (level == 0)
1444+
break;
1445+
}
14141446

14151447
// syntax error?
14161448
else if (tok->next() == NULL)
@@ -1446,6 +1478,12 @@ void Scope::getVariableList()
14461478
tok = tok->next()->link()->next()->next();
14471479
continue;
14481480
}
1481+
else if (Token::Match(tok, "struct|union {") && Token::Match(tok->next()->link(), "} ;"))
1482+
{
1483+
level++;
1484+
tok = tok->next();
1485+
continue;
1486+
}
14491487

14501488
// Borland C++: Skip all variables in the __published section.
14511489
// These are automatically initialized.

0 commit comments

Comments
 (0)