Add variable and type information for auto and auto variables in range based for loops of containers.

This commit is contained in:
Robert Reif 2017-03-23 20:14:49 -04:00
parent 7adfb6e0e4
commit bc87e874e9
2 changed files with 152 additions and 5 deletions

View File

@ -1219,7 +1219,7 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
// Set Token::variable pointer for array member variable
// Since it doesn't point at a fixed location it doesn't have varid
if (tok->variable() != nullptr &&
tok->variable()->typeScope() &&
(tok->variable()->typeScope() || (tok->valueType() && tok->valueType()->type == ValueType::CONTAINER)) &&
Token::Match(tok, "%name% [|.")) {
Token *tok2 = tok->next();
@ -1241,6 +1241,17 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
membertok->variable(membervar);
const_cast<Token *>(membertok)->varId(membervar->nameToken()->varId());
}
} else if (var && tok->valueType() && tok->valueType()->type == ValueType::CONTAINER) {
if (Token::Match(var->typeStartToken(), "std :: %type% < %type% *| *| >")) {
const Type * type = var->typeStartToken()->tokAt(4)->type();
if (type && type->classScope && type->classScope->definedType) {
const Variable *membervar = type->classScope->getVariable(membertok->str());
if (membervar) {
membertok->variable(membervar);
const_cast<Token *>(membertok)->varId(membervar->nameToken()->varId());
}
}
}
}
}
}
@ -4600,11 +4611,20 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype)
}
// TODO: Get type better
if (Token::Match(typeStart, "std :: %type% < %type% *| *| >")) {
ValueType vt;
if (parsedecl(typeStart->tokAt(4), &vt, defaultSignedness, _settings)) {
setValueType(autoToken, vt);
ValueType autovt;
if (parsedecl(typeStart->tokAt(4), &autovt, defaultSignedness, _settings)) {
setValueType(autoToken, autovt);
setAutoTokenProperties(autoToken);
setValueType(parent->previous(), vt);
ValueType varvt(autovt);
if (isconst)
varvt.constness |= 1;
setValueType(parent->previous(), varvt);
const_cast<Variable *>(parent->previous()->variable())->setFlags(varvt);
const Type * type = typeStart->tokAt(4)->type();
if (type && type->classScope && type->classScope->definedType) {
autoToken->type(type->classScope->definedType);
const_cast<Variable *>(parent->previous()->variable())->type(type->classScope->definedType);
}
}
}
}

View File

@ -322,6 +322,8 @@ private:
TEST_CASE(auto1);
TEST_CASE(auto2);
TEST_CASE(auto3);
TEST_CASE(auto4);
TEST_CASE(auto5);
}
void array() {
@ -4670,6 +4672,131 @@ private:
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());
vartok = Token::findsimplematch(tokenizer.tokens(), "a . i");
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok, "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "b . i");
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok->next(), "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "c . i");
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok->next(), "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "d . i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok->next(), "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "e . i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
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 auto5() {
GET_SYMBOL_DB("struct S { int i; };\n"
"int foo() {\n"
" std::vector<S> vec(10);\n"
" for (auto a : vec)\n"
" a.i = 0;\n"
" for (auto & b : vec)\n"
" b.i = 0;\n"
" for (const auto & c : vec)\n"
" auto ci = c.i;\n"
" for (auto * d : vec)\n"
" d.i = 0;\n"
" for (const auto * e : vec)\n"
" auto ei = e->i;\n"
" return vec[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());
vartok = Token::findsimplematch(tokenizer.tokens(), "a . i");
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok, "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "b . i");
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok->next(), "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "c . i");
ASSERT(db && vartok && vartok->variable() && !vartok->variable()->isPointer() && vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok->next(), "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "d . i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
vartok = Token::findsimplematch(vartok->next(), "i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->typeStartToken()->str() == "int");
vartok = Token::findsimplematch(vartok->next(), "e . i");
ASSERT(db && vartok && vartok->variable() && vartok->variable()->isPointer() && !vartok->variable()->isReference() && vartok->variable()->type() && vartok->variable()->type()->name() == "S");
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");
}
};