Skip to content

Commit a4e224b

Browse files
Handle auto as first token, set varid (#4991)
* Handle auto as first token * Set varid when initialized by function * Fix TODO from #11444 * Fix function parsing * Add parentheses * Format
1 parent 2364ff9 commit a4e224b

File tree

4 files changed

+61
-22
lines changed

4 files changed

+61
-22
lines changed

lib/symboldatabase.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6198,9 +6198,9 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
61986198
Token::Match(parent->tokAt(-1), "%var% ="))) {
61996199
Token *var1Tok = parent->strAt(-2) == ";" ? parent->tokAt(-3) : parent->tokAt(-1);
62006200
Token *autoTok = nullptr;
6201-
if (Token::Match(var1Tok->tokAt(-2), ";|{|}|(|const|constexpr auto"))
6201+
if (Token::simpleMatch(var1Tok->tokAt(-1), "auto"))
62026202
autoTok = var1Tok->previous();
6203-
else if (Token::Match(var1Tok->tokAt(-3), ";|{|}|(|const|constexpr auto *|&|&&"))
6203+
else if (Token::Match(var1Tok->tokAt(-2), "auto *|&|&&"))
62046204
autoTok = var1Tok->tokAt(-2);
62056205
if (autoTok) {
62066206
ValueType vt(*vt2);

lib/tokenize.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4574,7 +4574,7 @@ void Tokenizer::setVarIdPass1()
45744574
continue;
45754575

45764576
if (tok3->isLiteral() ||
4577-
(tok3->isName() && variableMap.hasVariable(tok3->str())) ||
4577+
(tok3->isName() && (variableMap.hasVariable(tok3->str()) || (tok3->strAt(-1) == "(" && Token::simpleMatch(tok3->next(), "(")))) ||
45784578
tok3->isOp() ||
45794579
tok3->str() == "(" ||
45804580
notstart.find(tok3->str()) != notstart.end()) {
@@ -4786,7 +4786,11 @@ static Token * matchMemberName(const Member &member, const std::list<ScopeInfo2>
47864786
static Token * matchMemberVarName(const Member &var, const std::list<ScopeInfo2> &scopeInfo)
47874787
{
47884788
Token *tok = matchMemberName(var, scopeInfo);
4789-
return Token::Match(tok, "%name% !!(") ? tok : nullptr;
4789+
if (Token::Match(tok, "%name%")) {
4790+
if (!tok->next() || tok->strAt(1) != "(" || (tok->tokAt(2) && tok->tokAt(2)->isLiteral()))
4791+
return tok;
4792+
}
4793+
return nullptr;
47904794
}
47914795

47924796
static Token * matchMemberFunctionName(const Member &func, const std::list<ScopeInfo2> &scopeInfo)
@@ -4854,7 +4858,7 @@ void Tokenizer::setVarIdPass2()
48544858
}
48554859
if (!tok->next())
48564860
syntaxError(tok);
4857-
if (Token::Match(tok, "%name% ("))
4861+
if (Token::Match(tok, "%name% (") && !(tok->tokAt(2) && tok->tokAt(2)->isLiteral()))
48584862
allMemberFunctions.emplace_back(scope, usingnamespaces, tok1);
48594863
else
48604864
allMemberVars.emplace_back(scope, usingnamespaces, tok1);

test/testsymboldatabase.cpp

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,7 +5262,7 @@ class TestSymbolDatabase : public TestFixture {
52625262

52635263
void createSymbolDatabaseFindAllScopes5()
52645264
{
5265-
GET_SYMBOL_DB("class C {\n"
5265+
GET_SYMBOL_DB("class C {\n" // #11444
52665266
"public:\n"
52675267
" template<typename T>\n"
52685268
" class D;\n"
@@ -5282,7 +5282,12 @@ class TestSymbolDatabase : public TestFixture {
52825282
ASSERT(db);
52835283
ASSERT_EQUALS(6, db->scopeList.size());
52845284
const Token* const var = Token::findsimplematch(tokenizer.tokens(), "IN (");
5285-
TODO_ASSERT(var && var->variable());
5285+
ASSERT(var && var->variable());
5286+
ASSERT_EQUALS(var->variable()->name(), "IN");
5287+
auto it = db->scopeList.begin();
5288+
std::advance(it, 4);
5289+
ASSERT_EQUALS(it->className, "S");
5290+
ASSERT_EQUALS(var->variable()->scope(), &*it);
52865291
}
52875292

52885293
void createSymbolDatabaseFindAllScopes6()
@@ -7686,23 +7691,35 @@ class TestSymbolDatabase : public TestFixture {
76867691
}
76877692

76887693
void executableScopeWithUnknownFunction() {
7689-
GET_SYMBOL_DB("class Fred {\n"
7690-
" void foo(const std::string & a = \"\");\n"
7691-
"};\n"
7692-
"Fred::foo(const std::string & b) { }");
7694+
{
7695+
GET_SYMBOL_DB("class Fred {\n"
7696+
" void foo(const std::string & a = \"\");\n"
7697+
"};\n"
7698+
"Fred::foo(const std::string & b) { }");
76937699

7694-
ASSERT(db && db->scopeList.size() == 3);
7695-
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
7696-
ASSERT_EQUALS(Scope::eGlobal, scope->type);
7697-
++scope;
7698-
ASSERT_EQUALS(Scope::eClass, scope->type);
7699-
const Scope * class_scope = &*scope;
7700-
++scope;
7701-
ASSERT(class_scope->functionList.size() == 1);
7702-
ASSERT(class_scope->functionList.cbegin()->hasBody());
7703-
ASSERT(class_scope->functionList.cbegin()->functionScope == &*scope);
7704-
}
7700+
ASSERT(db && db->scopeList.size() == 3);
7701+
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
7702+
ASSERT_EQUALS(Scope::eGlobal, scope->type);
7703+
++scope;
7704+
ASSERT_EQUALS(Scope::eClass, scope->type);
7705+
const Scope* class_scope = &*scope;
7706+
++scope;
7707+
ASSERT(class_scope->functionList.size() == 1);
7708+
ASSERT(class_scope->functionList.cbegin()->hasBody());
7709+
ASSERT(class_scope->functionList.cbegin()->functionScope == &*scope);
7710+
}
7711+
{
7712+
GET_SYMBOL_DB("bool f(bool (*g)(int));\n"
7713+
"bool f(bool (*g)(int)) { return g(0); }\n");
77057714

7715+
ASSERT(db && db->scopeList.size() == 2);
7716+
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
7717+
ASSERT_EQUALS(Scope::eGlobal, scope->type);
7718+
ASSERT(scope->functionList.size() == 1);
7719+
++scope;
7720+
ASSERT_EQUALS(Scope::eFunction, scope->type);
7721+
}
7722+
}
77067723
#define typeOf(...) typeOf_(__FILE__, __LINE__, __VA_ARGS__)
77077724
std::string typeOf_(const char* file, int line, const char code[], const char pattern[], const char filename[] = "test.cpp", const Settings *settings = nullptr) {
77087725
Tokenizer tokenizer(settings ? settings : &settings2, this);
@@ -8375,6 +8392,15 @@ class TestSymbolDatabase : public TestFixture {
83758392
ASSERT(tok->variable() && tok->variable()->valueType());
83768393
ASSERT_EQUALS("signed int * const &", tok->variable()->valueType()->str());
83778394
}
8395+
{
8396+
GET_SYMBOL_DB("auto a = 1;\n");
8397+
ASSERT_EQUALS("", errout.str());
8398+
8399+
const Token* tok = tokenizer.tokens();
8400+
tok = Token::findsimplematch(tok, "auto");
8401+
ASSERT(tok && tok->valueType());
8402+
ASSERT_EQUALS("signed int", tok->valueType()->str());
8403+
}
83788404
}
83798405

83808406
void valueTypeThis() {

test/testvarid.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class TestVarID : public TestFixture {
102102
TEST_CASE(varid63);
103103
TEST_CASE(varid64); // #9928 - extern const char (*x[256])
104104
TEST_CASE(varid65); // #10936
105+
TEST_CASE(varid66);
105106
TEST_CASE(varid_for_1);
106107
TEST_CASE(varid_for_2);
107108
TEST_CASE(varid_cpp_keywords_in_c_code);
@@ -1195,6 +1196,14 @@ class TestVarID : public TestFixture {
11951196
}
11961197
}
11971198

1199+
void varid66() {
1200+
const char code[] = "std::string g();\n"
1201+
"const std::string s(g() + \"abc\");\n";
1202+
const char expected[] = "1: std :: string g ( ) ;\n"
1203+
"2: const std :: string s@1 ( g ( ) + \"abc\" ) ;\n";
1204+
ASSERT_EQUALS(expected, tokenize(code));
1205+
}
1206+
11981207
void varid_for_1() {
11991208
const char code[] = "void foo(int a, int b) {\n"
12001209
" for (int a=1,b=2;;) {}\n"

0 commit comments

Comments
 (0)