SymbolDatabase: Improved findFunction

This commit is contained in:
Daniel Marjamäki 2019-05-30 20:26:45 +02:00
parent 36b6fb9f4d
commit 66a61fe5e8
2 changed files with 53 additions and 3 deletions

View File

@ -58,8 +58,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
createSymbolDatabaseNeedInitialization();
createSymbolDatabaseVariableSymbolTable();
createSymbolDatabaseSetScopePointers();
createSymbolDatabaseSetFunctionPointers(true);
createSymbolDatabaseSetVariablePointers();
createSymbolDatabaseSetFunctionPointers(true);
createSymbolDatabaseSetTypePointers();
createSymbolDatabaseEnums();
}
@ -4057,6 +4057,9 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
const Function * func = matches[i];
size_t same = 0;
if (requireConst && !func->isConst())
continue;
if (!requireConst || !func->isConst()) {
// get the function this call is in
const Scope * scope = tok->scope();
@ -4419,7 +4422,14 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const
if (Token::Match(tok1, "%var% .")) {
const Variable *var = getVariableFromVarId(tok1->varId());
if (var && var->typeScope())
return var->typeScope()->findFunction(tok, var->isConst());
return var->typeScope()->findFunction(tok, var->valueType()->constness == 1);
} else if (Token::simpleMatch(tok->previous()->astOperand1(), "(")) {
const Token *castTok = tok->previous()->astOperand1();
if (castTok->isCast()) {
ValueType vt = ValueType::parseDecl(castTok->next(),mSettings);
if (vt.typeScope)
return vt.typeScope->findFunction(tok, vt.constness == 1);
}
}
}

View File

@ -337,6 +337,8 @@ private:
TEST_CASE(findFunction19);
TEST_CASE(findFunction20); // #8280
TEST_CASE(findFunction21);
TEST_CASE(findFunction22);
TEST_CASE(findFunction23);
TEST_CASE(noexceptFunction1);
TEST_CASE(noexceptFunction2);
@ -5425,7 +5427,45 @@ private:
const Function *f = tok1 && tok1->tokAt(2) ? tok1->tokAt(2)->function() : nullptr;
ASSERT(f != nullptr);
ASSERT_EQUALS(true, f && f->tokenDef->linenr() == 3);
ASSERT_EQUALS(true, f && !f->isConst());
}
void findFunction22() { // # 8558
GET_SYMBOL_DB("struct foo {\n"
" int GetThing( ) const { return m_thing; }\n"
" int* GetThing( ) { return &m_thing; }\n"
"};\n"
"\n"
"void f(const foo *myFoo) {\n"
" int* myThing = myFoo->GetThing();\n"
"}");
ASSERT(db != nullptr);
const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), ". GetThing ( ) ;")->next();
const Function *f = tok1 ? tok1->function() : nullptr;
ASSERT(f != nullptr);
ASSERT_EQUALS(true, f && f->isConst());
}
void findFunction23() { // # 8558
GET_SYMBOL_DB("struct foo {\n"
" int GetThing( ) const { return m_thing; }\n"
" int* GetThing( ) { return &m_thing; }\n"
"};\n"
"\n"
"void f(foo *myFoo) {\n"
" int* myThing = ((const foo *)myFoo)->GetThing();\n"
"}");
ASSERT(db != nullptr);
const Token *tok1 = Token::findsimplematch(tokenizer.tokens(), ". GetThing ( ) ;")->next();
const Function *f = tok1 ? tok1->function() : nullptr;
ASSERT(f != nullptr);
ASSERT_EQUALS(true, f && f->isConst());
}
#define FUNC(x) const Function *x = findFunctionByName(#x, &db->scopeList.front()); \