Fixed #4952 (SymbolDatabase: unknown types in log file)

This commit is contained in:
Robert Reif 2013-08-12 06:21:03 +02:00 committed by Daniel Marjamäki
parent 5ca00b2ed2
commit cd3044c808
3 changed files with 65 additions and 5 deletions

View File

@ -830,23 +830,35 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
scope = &(*it);
// add all variables
std::list<Variable>::const_iterator var;
std::list<Variable>::iterator var;
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) {
unsigned int varId = var->declarationId();
if (varId)
_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
std::list<Function>::const_iterator func;
std::list<Function>::iterator 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) {
// check for named parameters
if (arg->nameToken() && arg->declarationId()) {
const unsigned int declarationId = arg->declarationId();
if (declarationId > 0U)
_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());
}
// not a valid path
return 0;
}
//---------------------------------------------------------------------------
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
if (startTok->str() == "::") {
startTok = startTok->next();
@ -2687,7 +2708,6 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
return scope->findType(tok->str());
}
// not a valid path
return 0;
}

View File

@ -399,6 +399,17 @@ public:
}
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 */
const Token *_name;

View File

@ -197,6 +197,7 @@ private:
TEST_CASE(symboldatabase34); // ticket #4694 (segmentation fault)
TEST_CASE(symboldatabase35); // ticket #4806 (segmentation fault)
TEST_CASE(symboldatabase36); // ticket #4892 (segmentation fault)
TEST_CASE(symboldatabase37);
TEST_CASE(isImplicitlyVirtual);
@ -1582,6 +1583,34 @@ private:
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() {
{
GET_SYMBOL_DB("class Base {\n"