Add variable or type information to auto and auto variable tokens. Changing the auto variable type requires rerunning the variable pointer pass to correct the symbol database for the new type.
This commit is contained in:
parent
fda1f02dab
commit
662bc6f846
|
@ -1237,8 +1237,10 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
|
|||
const Variable *var = tok->variable();
|
||||
if (var && var->typeScope()) {
|
||||
const Variable *membervar = var->typeScope()->getVariable(membertok->str());
|
||||
if (membervar)
|
||||
if (membervar) {
|
||||
membertok->variable(membervar);
|
||||
const_cast<Token *>(membertok)->varId(membervar->nameToken()->varId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4493,13 +4495,24 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype)
|
|||
else if (Token::Match(var1Tok->tokAt(-3), "[;{}] auto *"))
|
||||
autoTok = var1Tok->tokAt(-2);
|
||||
if (autoTok) {
|
||||
setValueType(autoTok, *vt2);
|
||||
ValueType vt(*vt2);
|
||||
if (autoTok->strAt(1) == "*" && vt.pointer)
|
||||
vt.pointer--;
|
||||
if (autoTok->strAt(-1) == "const")
|
||||
vt.constness |= 1;
|
||||
setValueType(autoTok, vt);
|
||||
setAutoTokenProperties(autoTok);
|
||||
setValueType(var1Tok, *vt2);
|
||||
setValueType(parent->previous(), *vt2);
|
||||
const Variable *var = parent->previous()->variable();
|
||||
if (var)
|
||||
if (var) {
|
||||
const_cast<Variable *>(var)->setFlags(*vt2);
|
||||
if (vt2->typeScope && vt2->typeScope->definedType) {
|
||||
const_cast<Variable *>(var)->type(vt2->typeScope->definedType);
|
||||
if (autoTok->valueType()->pointer == 0)
|
||||
autoTok->type(vt2->typeScope->definedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -4957,6 +4970,9 @@ void SymbolDatabase::setValueTypeInTokenList()
|
|||
setValueType(tok, vt);
|
||||
}
|
||||
}
|
||||
|
||||
// Update auto variables with new type information.
|
||||
createSymbolDatabaseSetVariablePointers();
|
||||
}
|
||||
|
||||
ValueType ValueType::parseDecl(const Token *type, const Settings *settings)
|
||||
|
|
|
@ -320,6 +320,8 @@ private:
|
|||
TEST_CASE(noReturnType);
|
||||
|
||||
TEST_CASE(auto1);
|
||||
TEST_CASE(auto2);
|
||||
TEST_CASE(auto3);
|
||||
}
|
||||
|
||||
void array() {
|
||||
|
@ -812,7 +814,7 @@ private:
|
|||
tok = tok ? tok->next() : nullptr;
|
||||
ASSERT(db != nullptr);
|
||||
ASSERT(tok && tok->variable() && Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;"));
|
||||
ASSERT(tok && tok->varId() == 0U); // It's possible to set a varId
|
||||
ASSERT(tok && tok->varId() == 1U); // It's possible to set a varId
|
||||
}
|
||||
|
||||
void arrayMemberVar2() {
|
||||
|
@ -828,7 +830,7 @@ private:
|
|||
tok = tok ? tok->next() : nullptr;
|
||||
ASSERT(db != nullptr);
|
||||
ASSERT(tok && tok->variable() && Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;"));
|
||||
ASSERT(tok && tok->varId() == 0U); // It's possible to set a varId
|
||||
ASSERT(tok && tok->varId() == 1U); // It's possible to set a varId
|
||||
}
|
||||
|
||||
void arrayMemberVar3() {
|
||||
|
@ -844,7 +846,7 @@ private:
|
|||
tok = tok ? tok->next() : nullptr;
|
||||
ASSERT(db != nullptr);
|
||||
ASSERT(tok && tok->variable() && Token::simpleMatch(tok->variable()->typeStartToken(), "int x ;"));
|
||||
ASSERT(tok && tok->varId() == 0U); // It's possible to set a varId
|
||||
ASSERT(tok && tok->varId() == 1U); // It's possible to set a varId
|
||||
}
|
||||
|
||||
void staticMemberVar() {
|
||||
|
@ -4501,6 +4503,117 @@ private:
|
|||
const Variable *var = db ? db->getVariableFromVarId(1) : nullptr;
|
||||
ASSERT(var && var->isPointer() && var->isConst());
|
||||
}
|
||||
|
||||
void auto2() {
|
||||
GET_SYMBOL_DB("struct S { int i; };\n"
|
||||
"int foo() {\n"
|
||||
" auto a = new S;\n"
|
||||
" auto * b = new S;\n"
|
||||
" auto c = new S[10];\n"
|
||||
" auto * d = new S[10];\n"
|
||||
" return a->i + b->i + c[0]->i + d[0]->i;\n"
|
||||
"}");
|
||||
const Token *autotok = Token::findsimplematch(tokenizer.tokens(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 1 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S" && autotok->type() == nullptr);
|
||||
|
||||
autotok = Token::findsimplematch(autotok->next(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S" && autotok->type() && autotok->type()->name() == "S");
|
||||
|
||||
autotok = Token::findsimplematch(autotok->next(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 1 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S" && autotok->type() == nullptr);
|
||||
|
||||
autotok = Token::findsimplematch(autotok->next(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S" && autotok->type() && autotok->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(tokenizer.tokens(), "a =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "b =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "c =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "d =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(tokenizer.tokens(), "return");
|
||||
|
||||
vartok = Token::findsimplematch(vartok, "a");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "b");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "c");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "d");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||
|
||||
vartok = Token::findsimplematch(tokenizer.tokens(), "return");
|
||||
|
||||
vartok = Token::findsimplematch(vartok, "i");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "i");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "i");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "i");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
|
||||
}
|
||||
|
||||
void auto3() {
|
||||
GET_SYMBOL_DB("enum class E : unsigned short { A, B, C };\n"
|
||||
"int foo() {\n"
|
||||
" auto a = new E;\n"
|
||||
" auto * b = new E;\n"
|
||||
" auto c = new E[10];\n"
|
||||
" auto * d = new E[10];\n"
|
||||
" return a + b + c + d;\n"
|
||||
"}");
|
||||
const Token *autotok = Token::findsimplematch(tokenizer.tokens(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 1 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "E" && autotok->type() == nullptr);
|
||||
|
||||
autotok = Token::findsimplematch(autotok->next(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "E" && autotok->type() && autotok->type()->name() == "E");
|
||||
|
||||
autotok = Token::findsimplematch(autotok->next(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 1 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "E" && autotok->type() == nullptr);
|
||||
|
||||
autotok = Token::findsimplematch(autotok->next(), "auto");
|
||||
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "E" && autotok->type() && autotok->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(tokenizer.tokens(), "a =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "b =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "c =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "d =");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(tokenizer.tokens(), "return");
|
||||
|
||||
vartok = Token::findsimplematch(vartok, "a");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "b");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "c");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
|
||||
vartok = Token::findsimplematch(vartok->next(), "d");
|
||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestSymbolDatabase)
|
||||
|
|
|
@ -1344,7 +1344,7 @@ private:
|
|||
"10:\n"
|
||||
"11: void Bar :: f ( )\n"
|
||||
"12: {\n"
|
||||
"13: foo@2 . x@4 = x@3 ;\n"
|
||||
"13: foo@2 . x@1 = x@3 ;\n"
|
||||
"14: }\n";
|
||||
ASSERT_EQUALS(expected, actual);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue