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
This commit is contained in:
parent
2364ff9765
commit
a4e224b65c
|
@ -6198,9 +6198,9 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
|
|||
Token::Match(parent->tokAt(-1), "%var% ="))) {
|
||||
Token *var1Tok = parent->strAt(-2) == ";" ? parent->tokAt(-3) : parent->tokAt(-1);
|
||||
Token *autoTok = nullptr;
|
||||
if (Token::Match(var1Tok->tokAt(-2), ";|{|}|(|const|constexpr auto"))
|
||||
if (Token::simpleMatch(var1Tok->tokAt(-1), "auto"))
|
||||
autoTok = var1Tok->previous();
|
||||
else if (Token::Match(var1Tok->tokAt(-3), ";|{|}|(|const|constexpr auto *|&|&&"))
|
||||
else if (Token::Match(var1Tok->tokAt(-2), "auto *|&|&&"))
|
||||
autoTok = var1Tok->tokAt(-2);
|
||||
if (autoTok) {
|
||||
ValueType vt(*vt2);
|
||||
|
|
|
@ -4574,7 +4574,7 @@ void Tokenizer::setVarIdPass1()
|
|||
continue;
|
||||
|
||||
if (tok3->isLiteral() ||
|
||||
(tok3->isName() && variableMap.hasVariable(tok3->str())) ||
|
||||
(tok3->isName() && (variableMap.hasVariable(tok3->str()) || (tok3->strAt(-1) == "(" && Token::simpleMatch(tok3->next(), "(")))) ||
|
||||
tok3->isOp() ||
|
||||
tok3->str() == "(" ||
|
||||
notstart.find(tok3->str()) != notstart.end()) {
|
||||
|
@ -4786,7 +4786,11 @@ static Token * matchMemberName(const Member &member, const std::list<ScopeInfo2>
|
|||
static Token * matchMemberVarName(const Member &var, const std::list<ScopeInfo2> &scopeInfo)
|
||||
{
|
||||
Token *tok = matchMemberName(var, scopeInfo);
|
||||
return Token::Match(tok, "%name% !!(") ? tok : nullptr;
|
||||
if (Token::Match(tok, "%name%")) {
|
||||
if (!tok->next() || tok->strAt(1) != "(" || (tok->tokAt(2) && tok->tokAt(2)->isLiteral()))
|
||||
return tok;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Token * matchMemberFunctionName(const Member &func, const std::list<ScopeInfo2> &scopeInfo)
|
||||
|
@ -4854,7 +4858,7 @@ void Tokenizer::setVarIdPass2()
|
|||
}
|
||||
if (!tok->next())
|
||||
syntaxError(tok);
|
||||
if (Token::Match(tok, "%name% ("))
|
||||
if (Token::Match(tok, "%name% (") && !(tok->tokAt(2) && tok->tokAt(2)->isLiteral()))
|
||||
allMemberFunctions.emplace_back(scope, usingnamespaces, tok1);
|
||||
else
|
||||
allMemberVars.emplace_back(scope, usingnamespaces, tok1);
|
||||
|
|
|
@ -5262,7 +5262,7 @@ private:
|
|||
|
||||
void createSymbolDatabaseFindAllScopes5()
|
||||
{
|
||||
GET_SYMBOL_DB("class C {\n"
|
||||
GET_SYMBOL_DB("class C {\n" // #11444
|
||||
"public:\n"
|
||||
" template<typename T>\n"
|
||||
" class D;\n"
|
||||
|
@ -5282,7 +5282,12 @@ private:
|
|||
ASSERT(db);
|
||||
ASSERT_EQUALS(6, db->scopeList.size());
|
||||
const Token* const var = Token::findsimplematch(tokenizer.tokens(), "IN (");
|
||||
TODO_ASSERT(var && var->variable());
|
||||
ASSERT(var && var->variable());
|
||||
ASSERT_EQUALS(var->variable()->name(), "IN");
|
||||
auto it = db->scopeList.begin();
|
||||
std::advance(it, 4);
|
||||
ASSERT_EQUALS(it->className, "S");
|
||||
ASSERT_EQUALS(var->variable()->scope(), &*it);
|
||||
}
|
||||
|
||||
void createSymbolDatabaseFindAllScopes6()
|
||||
|
@ -7686,23 +7691,35 @@ private:
|
|||
}
|
||||
|
||||
void executableScopeWithUnknownFunction() {
|
||||
GET_SYMBOL_DB("class Fred {\n"
|
||||
" void foo(const std::string & a = \"\");\n"
|
||||
"};\n"
|
||||
"Fred::foo(const std::string & b) { }");
|
||||
{
|
||||
GET_SYMBOL_DB("class Fred {\n"
|
||||
" void foo(const std::string & a = \"\");\n"
|
||||
"};\n"
|
||||
"Fred::foo(const std::string & b) { }");
|
||||
|
||||
ASSERT(db && db->scopeList.size() == 3);
|
||||
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
|
||||
ASSERT_EQUALS(Scope::eGlobal, scope->type);
|
||||
++scope;
|
||||
ASSERT_EQUALS(Scope::eClass, scope->type);
|
||||
const Scope * class_scope = &*scope;
|
||||
++scope;
|
||||
ASSERT(class_scope->functionList.size() == 1);
|
||||
ASSERT(class_scope->functionList.cbegin()->hasBody());
|
||||
ASSERT(class_scope->functionList.cbegin()->functionScope == &*scope);
|
||||
ASSERT(db && db->scopeList.size() == 3);
|
||||
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
|
||||
ASSERT_EQUALS(Scope::eGlobal, scope->type);
|
||||
++scope;
|
||||
ASSERT_EQUALS(Scope::eClass, scope->type);
|
||||
const Scope* class_scope = &*scope;
|
||||
++scope;
|
||||
ASSERT(class_scope->functionList.size() == 1);
|
||||
ASSERT(class_scope->functionList.cbegin()->hasBody());
|
||||
ASSERT(class_scope->functionList.cbegin()->functionScope == &*scope);
|
||||
}
|
||||
{
|
||||
GET_SYMBOL_DB("bool f(bool (*g)(int));\n"
|
||||
"bool f(bool (*g)(int)) { return g(0); }\n");
|
||||
|
||||
ASSERT(db && db->scopeList.size() == 2);
|
||||
std::list<Scope>::const_iterator scope = db->scopeList.cbegin();
|
||||
ASSERT_EQUALS(Scope::eGlobal, scope->type);
|
||||
ASSERT(scope->functionList.size() == 1);
|
||||
++scope;
|
||||
ASSERT_EQUALS(Scope::eFunction, scope->type);
|
||||
}
|
||||
}
|
||||
|
||||
#define typeOf(...) typeOf_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
std::string typeOf_(const char* file, int line, const char code[], const char pattern[], const char filename[] = "test.cpp", const Settings *settings = nullptr) {
|
||||
Tokenizer tokenizer(settings ? settings : &settings2, this);
|
||||
|
@ -8375,6 +8392,15 @@ private:
|
|||
ASSERT(tok->variable() && tok->variable()->valueType());
|
||||
ASSERT_EQUALS("signed int * const &", tok->variable()->valueType()->str());
|
||||
}
|
||||
{
|
||||
GET_SYMBOL_DB("auto a = 1;\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
const Token* tok = tokenizer.tokens();
|
||||
tok = Token::findsimplematch(tok, "auto");
|
||||
ASSERT(tok && tok->valueType());
|
||||
ASSERT_EQUALS("signed int", tok->valueType()->str());
|
||||
}
|
||||
}
|
||||
|
||||
void valueTypeThis() {
|
||||
|
|
|
@ -102,6 +102,7 @@ private:
|
|||
TEST_CASE(varid63);
|
||||
TEST_CASE(varid64); // #9928 - extern const char (*x[256])
|
||||
TEST_CASE(varid65); // #10936
|
||||
TEST_CASE(varid66);
|
||||
TEST_CASE(varid_for_1);
|
||||
TEST_CASE(varid_for_2);
|
||||
TEST_CASE(varid_cpp_keywords_in_c_code);
|
||||
|
@ -1195,6 +1196,14 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void varid66() {
|
||||
const char code[] = "std::string g();\n"
|
||||
"const std::string s(g() + \"abc\");\n";
|
||||
const char expected[] = "1: std :: string g ( ) ;\n"
|
||||
"2: const std :: string s@1 ( g ( ) + \"abc\" ) ;\n";
|
||||
ASSERT_EQUALS(expected, tokenize(code));
|
||||
}
|
||||
|
||||
void varid_for_1() {
|
||||
const char code[] = "void foo(int a, int b) {\n"
|
||||
" for (int a=1,b=2;;) {}\n"
|
||||
|
|
Loading…
Reference in New Issue