Fixed #4952 (SymbolDatabase: unknown types in log file)
This commit is contained in:
parent
5ca00b2ed2
commit
cd3044c808
|
@ -830,23 +830,35 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
scope = &(*it);
|
scope = &(*it);
|
||||||
|
|
||||||
// add all variables
|
// add all variables
|
||||||
std::list<Variable>::const_iterator var;
|
std::list<Variable>::iterator var;
|
||||||
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) {
|
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) {
|
||||||
unsigned int varId = var->declarationId();
|
unsigned int varId = var->declarationId();
|
||||||
if (varId)
|
if (varId)
|
||||||
_variableList[varId] = &(*var);
|
_variableList[varId] = &(*var);
|
||||||
|
// fix up variables without type
|
||||||
|
if (var->isClass() && !var->type()) {
|
||||||
|
const Type *type = findType(var->typeStartToken(), scope);
|
||||||
|
if (type)
|
||||||
|
var->type(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all function parameters
|
// add all function parameters
|
||||||
std::list<Function>::const_iterator func;
|
std::list<Function>::iterator func;
|
||||||
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
|
||||||
std::list<Variable>::const_iterator arg;
|
std::list<Variable>::iterator arg;
|
||||||
for (arg = func->argumentList.begin(); arg != func->argumentList.end(); ++arg) {
|
for (arg = func->argumentList.begin(); arg != func->argumentList.end(); ++arg) {
|
||||||
// check for named parameters
|
// check for named parameters
|
||||||
if (arg->nameToken() && arg->declarationId()) {
|
if (arg->nameToken() && arg->declarationId()) {
|
||||||
const unsigned int declarationId = arg->declarationId();
|
const unsigned int declarationId = arg->declarationId();
|
||||||
if (declarationId > 0U)
|
if (declarationId > 0U)
|
||||||
_variableList[declarationId] = &(*arg);
|
_variableList[declarationId] = &(*arg);
|
||||||
|
// fix up parameters without type
|
||||||
|
if (!arg->type()) {
|
||||||
|
const Type *type = findType(arg->typeStartToken(), scope);
|
||||||
|
if (type)
|
||||||
|
arg->type(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2655,13 +2667,22 @@ const Scope *SymbolDatabase::findScope(const Token *tok, const Scope *startScope
|
||||||
return scope->findRecordInNestedList(tok->str());
|
return scope->findRecordInNestedList(tok->str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// not a valid path
|
// not a valid path
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startScope) const
|
const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startScope) const
|
||||||
{
|
{
|
||||||
|
// skip over struct or union
|
||||||
|
if (Token::Match(startTok, "struct|union"))
|
||||||
|
startTok = startTok->next();
|
||||||
|
|
||||||
|
// type same as scope
|
||||||
|
if (startTok->str() == startScope->className && startScope->isClassOrStruct())
|
||||||
|
return startScope->definedType;
|
||||||
|
|
||||||
// absolute path - directly start in global scope
|
// absolute path - directly start in global scope
|
||||||
if (startTok->str() == "::") {
|
if (startTok->str() == "::") {
|
||||||
startTok = startTok->next();
|
startTok = startTok->next();
|
||||||
|
@ -2687,7 +2708,6 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
|
||||||
return scope->findType(tok->str());
|
return scope->findType(tok->str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// not a valid path
|
// not a valid path
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,6 +399,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// only symbol database can change the type
|
||||||
|
friend class SymbolDatabase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Type pointer to known type.
|
||||||
|
* @param t type
|
||||||
|
*/
|
||||||
|
void type(const Type * t) {
|
||||||
|
_type = t;
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief variable name token */
|
/** @brief variable name token */
|
||||||
const Token *_name;
|
const Token *_name;
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,7 @@ private:
|
||||||
TEST_CASE(symboldatabase34); // ticket #4694 (segmentation fault)
|
TEST_CASE(symboldatabase34); // ticket #4694 (segmentation fault)
|
||||||
TEST_CASE(symboldatabase35); // ticket #4806 (segmentation fault)
|
TEST_CASE(symboldatabase35); // ticket #4806 (segmentation fault)
|
||||||
TEST_CASE(symboldatabase36); // ticket #4892 (segmentation fault)
|
TEST_CASE(symboldatabase36); // ticket #4892 (segmentation fault)
|
||||||
|
TEST_CASE(symboldatabase37);
|
||||||
|
|
||||||
TEST_CASE(isImplicitlyVirtual);
|
TEST_CASE(isImplicitlyVirtual);
|
||||||
|
|
||||||
|
@ -1582,6 +1583,34 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void symboldatabase37() {
|
||||||
|
GET_SYMBOL_DB("class Fred {\n"
|
||||||
|
"public:\n"
|
||||||
|
" struct Barney {\n"
|
||||||
|
" bool operator == (const struct Barney & b) const { return true; }\n"
|
||||||
|
" };\n"
|
||||||
|
" Fred(const struct Barney & b) { barney = b; }\n"
|
||||||
|
"private:\n"
|
||||||
|
" struct Barney barney;\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT(db && db->typeList.size() == 2);
|
||||||
|
ASSERT(db && db->isClassOrStruct("Fred"));
|
||||||
|
ASSERT(db && db->isClassOrStruct("Barney"));
|
||||||
|
if (!db || db->typeList.size() == 2)
|
||||||
|
return;
|
||||||
|
std::list<Type>::const_iterator i = db->typeList.begin();
|
||||||
|
const Type* Fred = &(*i++);
|
||||||
|
const Type* Barney = &(*i++);
|
||||||
|
ASSERT(Fred && Fred->classDef && Fred->classScope && Fred->enclosingScope && Fred->name() == "Fred");
|
||||||
|
ASSERT(Barney && Barney->classDef && Barney->classScope && Barney->enclosingScope && Barney->name() == "Barney");
|
||||||
|
|
||||||
|
ASSERT(db && db->getVariableListSize() == 4);
|
||||||
|
if (!db || db->getVariableListSize() == 4)
|
||||||
|
return;
|
||||||
|
ASSERT(db && db->getVariableFromVarId(1) && db->getVariableFromVarId(1)->type() && db->getVariableFromVarId(1)->type()->name() == "Barney");
|
||||||
|
ASSERT(db && db->getVariableFromVarId(2) && db->getVariableFromVarId(2)->type() && db->getVariableFromVarId(2)->type()->name() == "Barney");
|
||||||
|
}
|
||||||
|
|
||||||
void isImplicitlyVirtual() {
|
void isImplicitlyVirtual() {
|
||||||
{
|
{
|
||||||
GET_SYMBOL_DB("class Base {\n"
|
GET_SYMBOL_DB("class Base {\n"
|
||||||
|
|
Loading…
Reference in New Issue