Add variable and type information to tokens for C array range based for loops.
This commit is contained in:
parent
f8dd6ee014
commit
7adfb6e0e4
|
@ -4566,20 +4566,27 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype)
|
||||||
// range for loop, auto
|
// range for loop, auto
|
||||||
if (vt2 &&
|
if (vt2 &&
|
||||||
parent->str() == ":" &&
|
parent->str() == ":" &&
|
||||||
Token::Match(parent->astParent(), "( const| auto *| %var% :") &&
|
Token::Match(parent->astParent(), "( const| auto *|&| %var% :") &&
|
||||||
!parent->previous()->valueType() &&
|
!parent->previous()->valueType() &&
|
||||||
Token::simpleMatch(parent->astParent()->astOperand1(), "for")) {
|
Token::simpleMatch(parent->astParent()->astOperand1(), "for")) {
|
||||||
bool isconst = Token::simpleMatch(parent->astParent()->next(), "const");
|
const bool isconst = Token::simpleMatch(parent->astParent()->next(), "const");
|
||||||
Token * const autoToken = const_cast<Token *>(parent->astParent()->tokAt(isconst ? 2 : 1));
|
Token * const autoToken = const_cast<Token *>(parent->astParent()->tokAt(isconst ? 2 : 1));
|
||||||
if (vt2->pointer) {
|
if (vt2->pointer) {
|
||||||
ValueType vt(*vt2);
|
ValueType autovt(*vt2);
|
||||||
vt.pointer--;
|
autovt.pointer--;
|
||||||
if (isconst)
|
autovt.constness = 0;
|
||||||
vt.constness |= 1;
|
setValueType(autoToken, autovt);
|
||||||
setValueType(autoToken, vt);
|
|
||||||
setAutoTokenProperties(autoToken);
|
setAutoTokenProperties(autoToken);
|
||||||
setValueType(parent->previous(), vt);
|
ValueType varvt(*vt2);
|
||||||
const_cast<Variable *>(parent->previous()->variable())->setFlags(vt);
|
varvt.pointer--;
|
||||||
|
if (isconst)
|
||||||
|
varvt.constness |= 1;
|
||||||
|
setValueType(parent->previous(), varvt);
|
||||||
|
const_cast<Variable *>(parent->previous()->variable())->setFlags(varvt);
|
||||||
|
if (vt2->typeScope && vt2->typeScope->definedType) {
|
||||||
|
const_cast<Variable *>(parent->previous()->variable())->type(vt2->typeScope->definedType);
|
||||||
|
autoToken->type(vt2->typeScope->definedType);
|
||||||
|
}
|
||||||
} else if (vt2->container) {
|
} else if (vt2->container) {
|
||||||
// TODO: Determine exact type of RHS
|
// TODO: Determine exact type of RHS
|
||||||
const Token *typeStart = parent->astOperand2();
|
const Token *typeStart = parent->astOperand2();
|
||||||
|
|
|
@ -4614,6 +4614,64 @@ private:
|
||||||
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && vartok->variable()->type() && vartok->variable()->type()->name() == "E");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void auto4() {
|
||||||
|
GET_SYMBOL_DB("struct S { int i; };\n"
|
||||||
|
"int foo() {\n"
|
||||||
|
" S array[10];\n"
|
||||||
|
" for (auto a : array)\n"
|
||||||
|
" a.i = 0;\n"
|
||||||
|
" for (auto & b : array)\n"
|
||||||
|
" b.i = 1;\n"
|
||||||
|
" for (const auto & c : array)\n"
|
||||||
|
" auto ci = c.i;\n"
|
||||||
|
" for (auto * d : array)\n"
|
||||||
|
" d->i = 0;\n"
|
||||||
|
" for (const auto * e : array)\n"
|
||||||
|
" auto ei = e->i;\n"
|
||||||
|
" return array[0].i;\n"
|
||||||
|
"}");
|
||||||
|
const Token *autotok = Token::findsimplematch(tokenizer.tokens(), "auto a");
|
||||||
|
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->constness == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && autotok && autotok->type() && autotok->type()->name() == "S");
|
||||||
|
|
||||||
|
autotok = Token::findsimplematch(autotok->next(), "auto & b");
|
||||||
|
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->constness == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && autotok && autotok->type() && autotok->type()->name() == "S");
|
||||||
|
|
||||||
|
autotok = Token::findsimplematch(autotok->next(), "auto & c");
|
||||||
|
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->constness == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && autotok && autotok->type() && autotok->type()->name() == "S");
|
||||||
|
|
||||||
|
autotok = Token::findsimplematch(autotok->next(), "auto * d");
|
||||||
|
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->constness == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && autotok && autotok->type() && autotok->type()->name() == "S");
|
||||||
|
|
||||||
|
autotok = Token::findsimplematch(autotok->next(), "auto * e");
|
||||||
|
ASSERT(db && autotok && autotok->valueType() && autotok->valueType()->pointer == 0 && autotok->valueType()->constness == 0 && autotok->valueType()->typeScope && autotok->valueType()->typeScope->definedType && autotok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && autotok && autotok->type() && autotok->type()->name() == "S");
|
||||||
|
|
||||||
|
vartok = Token::findsimplematch(tokenizer.tokens(), "a :");
|
||||||
|
ASSERT(db && vartok && vartok->valueType() && vartok->valueType()->typeScope && vartok->valueType()->typeScope->definedType && vartok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isReference() && !vartok->variable()->isPointer());
|
||||||
|
ASSERT(db && vartok && vartok->variable() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
|
||||||
|
|
||||||
|
vartok = Token::findsimplematch(vartok->next(), "b :");
|
||||||
|
ASSERT(db && vartok && vartok->valueType() && vartok->valueType()->typeScope && vartok->valueType()->typeScope->definedType && vartok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isReference() && !vartok->variable()->isPointer() && !vartok->variable()->isConst());
|
||||||
|
|
||||||
|
vartok = Token::findsimplematch(vartok->next(), "c :");
|
||||||
|
ASSERT(db && vartok && vartok->valueType() && vartok->valueType()->typeScope && vartok->valueType()->typeScope->definedType && vartok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isReference() && !vartok->variable()->isPointer() && vartok->variable()->isConst());
|
||||||
|
|
||||||
|
vartok = Token::findsimplematch(vartok->next(), "d :");
|
||||||
|
ASSERT(db && vartok && vartok->valueType() && vartok->valueType()->typeScope && vartok->valueType()->typeScope->definedType && vartok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isReference() && vartok->variable()->isPointer() && !vartok->variable()->isConst());
|
||||||
|
|
||||||
|
vartok = Token::findsimplematch(vartok->next(), "e :");
|
||||||
|
ASSERT(db && vartok && vartok->valueType() && vartok->valueType()->typeScope && vartok->valueType()->typeScope->definedType && vartok->valueType()->typeScope->definedType->name() == "S");
|
||||||
|
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isReference() && vartok->variable()->isPointer() && vartok->variable()->isConst());
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestSymbolDatabase)
|
REGISTER_TEST(TestSymbolDatabase)
|
||||||
|
|
Loading…
Reference in New Issue