SymbolDatabase; Add variables when structured binding is used

This commit is contained in:
Daniel Marjamäki 2021-04-26 18:21:07 +02:00
parent 8aa9e448f5
commit bd97b8eb8a
2 changed files with 18 additions and 0 deletions

View File

@ -4139,6 +4139,16 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con
// the start of the type tokens does not include the above modifiers
const Token *typestart = tok;
// C++17 structured bindings
if (settings->standards.cpp >= Standards::CPP17 && Token::Match(tok, "auto &|&&| [")) {
const Token *typeend = Token::findsimplematch(typestart, "[")->previous();
for (tok = typeend->tokAt(2); Token::Match(tok, "%name%|,"); tok = tok->next()) {
if (tok->varId())
addVariable(tok, typestart, typeend, varaccess, nullptr, this, settings);
}
return typeend->linkAt(1);
}
if (tok->isKeyword() && Token::Match(tok, "class|struct|union|enum")) {
tok = tok->next();
}

View File

@ -346,6 +346,7 @@ private:
TEST_CASE(symboldatabase91);
TEST_CASE(symboldatabase92); // daca crash
TEST_CASE(symboldatabase93); // alignas attribute
TEST_CASE(symboldatabase94); // structured bindings
TEST_CASE(createSymbolDatabaseFindAllScopes1);
@ -4712,6 +4713,13 @@ private:
ASSERT(scope);
}
void symboldatabase94() { // structured bindings
GET_SYMBOL_DB("int foo() { auto [x,y] = xy(); return x+y; }");
ASSERT(db != nullptr);
ASSERT(db->getVariableFromVarId(1) != nullptr);
ASSERT(db->getVariableFromVarId(2) != nullptr);
}
void createSymbolDatabaseFindAllScopes1() {
GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }");
ASSERT(db->scopeList.size() == 3);