Symbol Database: improved type handling. Ticket: #4952

This commit is contained in:
Robert Reif 2013-08-17 18:43:15 +02:00 committed by Daniel Marjamäki
parent 7b0af1172b
commit 914893013e
3 changed files with 55 additions and 2 deletions

View File

@ -855,7 +855,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
_variableList[declarationId] = &(*arg); _variableList[declarationId] = &(*arg);
// fix up parameters without type // fix up parameters without type
if (!arg->type() && !arg->typeStartToken()->isStandardType()) { if (!arg->type() && !arg->typeStartToken()->isStandardType()) {
const Type *type = findType(arg->typeStartToken(), scope); const Type *type = findTypeInNested(arg->typeStartToken(), scope);
if (type) if (type)
arg->type(type); arg->type(type);
} }
@ -2711,3 +2711,55 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
// not a valid path // not a valid path
return 0; return 0;
} }
//---------------------------------------------------------------------------
const Type* SymbolDatabase::findTypeInNested(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;
bool hasPath = false;
// absolute path - directly start in global scope
if (startTok->str() == "::") {
hasPath = true;
startTok = startTok->next();
startScope = &scopeList.front();
}
const Token* tok = startTok;
const Scope* scope = startScope;
while (scope && tok && tok->isName()) {
if (tok->strAt(1) == "::") {
hasPath = true;
scope = scope->findRecordInNestedList(tok->str());
if (scope) {
tok = tok->tokAt(2);
} else {
startScope = startScope->nestedIn;
if (!startScope)
break;
scope = startScope;
tok = startTok;
}
} else {
const Type * type = scope->findType(tok->str());
if (hasPath || type)
return type;
else {
scope = scope->nestedIn;
if (!scope)
break;
}
}
}
// not a valid path
return 0;
}

View File

@ -734,6 +734,7 @@ private:
Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart); Function *addGlobalFunction(Scope*& scope, const Token*& tok, const Token *argStart, const Token* funcStart);
void addNewFunction(Scope **info, const Token **tok); void addNewFunction(Scope **info, const Token **tok);
static bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart); static bool isFunction(const Token *tok, const Scope* outerScope, const Token **funcStart, const Token **argStart);
const Type *findTypeInNested(const Token *tok, const Scope *startScope) const;
const Tokenizer *_tokenizer; const Tokenizer *_tokenizer;
const Settings *_settings; const Settings *_settings;

View File

@ -1612,7 +1612,7 @@ private:
if (!db || db->getVariableListSize() != 5) if (!db || db->getVariableListSize() != 5)
return; return;
ASSERT(db && db->getVariableFromVarId(1) && db->getVariableFromVarId(1)->type() && db->getVariableFromVarId(1)->type()->name() == "Barney"); ASSERT(db && db->getVariableFromVarId(1) && db->getVariableFromVarId(1)->type() && db->getVariableFromVarId(1)->type()->name() == "Barney");
TODO_ASSERT(db && db->getVariableFromVarId(2) && db->getVariableFromVarId(2)->type() && db->getVariableFromVarId(2)->type()->name() == "Wilma"); ASSERT(db && db->getVariableFromVarId(2) && db->getVariableFromVarId(2)->type() && db->getVariableFromVarId(2)->type()->name() == "Wilma");
ASSERT(db && db->getVariableFromVarId(3) && db->getVariableFromVarId(3)->type() && db->getVariableFromVarId(3)->type()->name() == "Barney"); ASSERT(db && db->getVariableFromVarId(3) && db->getVariableFromVarId(3)->type() && db->getVariableFromVarId(3)->type()->name() == "Barney");
} }