SymbolDatabase: Better handling of function call using smart pointer

This commit is contained in:
Daniel Marjamäki 2019-10-15 19:33:11 +02:00
parent e3fe559f0d
commit 7d6d561c84
2 changed files with 31 additions and 2 deletions

View File

@ -1151,7 +1151,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->valueType() && tok->valueType()->type == ValueType::CONTAINER)) &&
(tok->variable()->typeScope() || tok->variable()->isSmartPointer() || (tok->valueType() && tok->valueType()->type == ValueType::CONTAINER)) &&
Token::Match(tok, "%name% [|.")) {
Token *tok2 = tok->next();
@ -1174,6 +1174,13 @@ void SymbolDatabase::createSymbolDatabaseSetVariablePointers()
if (membertok->varId() == 0 || mVariableList[membertok->varId()] == nullptr)
fixVarId(varIds, tok, const_cast<Token *>(membertok), membervar);
}
} else if (const ::Type *type = var ? var->smartPointerType() : nullptr) {
const Variable *membervar = type->classScope->getVariable(membertok->str());
if (membervar) {
membertok->variable(membervar);
if (membertok->varId() == 0 || mVariableList[membertok->varId()] == nullptr)
fixVarId(varIds, tok, const_cast<Token *>(membertok), membervar);
}
} 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();
@ -1845,7 +1852,7 @@ const Type *Variable::smartPointerType() const
while (Token::Match(ptrType, "%name%|::"))
ptrType = ptrType->next();
if (Token::Match(ptrType, "< %name% >"))
return ptrType->next()->type();
return ptrType->scope()->findType(ptrType->next()->str());
return nullptr;
}

View File

@ -351,6 +351,7 @@ private:
TEST_CASE(findFunction26); // #8668 - pointer parameter in function call, const pointer function argument
TEST_CASE(findFunction27);
TEST_CASE(findFunction28);
TEST_CASE(findFunction29);
TEST_CASE(findFunctionContainer);
TEST_CASE(findFunctionExternC);
TEST_CASE(findFunctionGlobalScope); // ::foo
@ -5737,6 +5738,27 @@ private:
ASSERT_EQUALS(4, a->function()->token->linenr());
}
void findFunction29() {
GET_SYMBOL_DB("struct A {\n"
" int foo() const;\n"
"};\n"
"\n"
"struct B {\n"
" A a;\n"
"};\n"
"\n"
"typedef std::shared_ptr<B> BPtr;\n"
"\n"
"void bar(BPtr b) {\n"
" int x = b->a.foo();\n"
"}");
const Token *foo = Token::findsimplematch(tokenizer.tokens(), "foo ( ) ;");
ASSERT(foo);
ASSERT(foo->function());
ASSERT(foo->function()->token);
ASSERT_EQUALS(2, foo->function()->token->linenr());
}
void findFunctionContainer() {
{
GET_SYMBOL_DB("void dostuff(std::vector<int> v);\n"