Skip to content

Commit 072e822

Browse files
Set ValueType for free function returning iterator (#4837)
1 parent 514e605 commit 072e822

2 files changed

Lines changed: 54 additions & 10 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7045,7 +7045,8 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
70457045
}
70467046
}
70477047

7048-
if (typestr.empty() || typestr == "iterator") {
7048+
const bool isReturnIter = typestr == "iterator";
7049+
if (typestr.empty() || isReturnIter) {
70497050
if (Token::simpleMatch(tok->astOperand1(), ".") &&
70507051
tok->astOperand1()->astOperand1() &&
70517052
tok->astOperand1()->astOperand2() &&
@@ -7063,6 +7064,25 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
70637064
vt.containerTypeToken =
70647065
tok->astOperand1()->astOperand1()->valueType()->containerTypeToken;
70657066
setValueType(tok, vt);
7067+
continue;
7068+
}
7069+
}
7070+
}
7071+
if (isReturnIter) {
7072+
const std::vector<const Token*> args = getArguments(tok);
7073+
if (!args.empty()) {
7074+
const Library::ArgumentChecks::IteratorInfo* info = mSettings->library.getArgIteratorInfo(tok->previous(), 1);
7075+
if (info && info->it) {
7076+
const Token* contTok = args[0];
7077+
if (Token::simpleMatch(args[0]->astOperand1(), ".") && args[0]->astOperand1()->astOperand1())
7078+
contTok = args[0]->astOperand1()->astOperand1();
7079+
if (contTok && contTok->variable() && contTok->variable()->valueType() && contTok->variable()->valueType()->container) {
7080+
ValueType vt;
7081+
vt.type = ValueType::Type::ITERATOR;
7082+
vt.container = contTok->variable()->valueType()->container;
7083+
vt.containerTypeToken = contTok->variable()->valueType()->containerTypeToken;
7084+
setValueType(tok, vt);
7085+
}
70667086
}
70677087
}
70687088
}

test/testsymboldatabase.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8111,16 +8111,40 @@ class TestSymbolDatabase : public TestFixture {
81118111
}
81128112

81138113
void valueType3() {
8114-
GET_SYMBOL_DB("void f(std::vector<std::unordered_map<int, std::unordered_set<int>>>& v, int i, int j) {\n"
8115-
" auto& s = v[i][j];\n"
8116-
" s.insert(0);\n"
8117-
"}\n");
8118-
ASSERT_EQUALS("", errout.str());
8114+
{
8115+
GET_SYMBOL_DB("void f(std::vector<std::unordered_map<int, std::unordered_set<int>>>& v, int i, int j) {\n"
8116+
" auto& s = v[i][j];\n"
8117+
" s.insert(0);\n"
8118+
"}\n");
8119+
ASSERT_EQUALS("", errout.str());
81198120

8120-
const Token* tok = tokenizer.tokens();
8121-
tok = Token::findsimplematch(tok, "s .");
8122-
ASSERT(tok && tok->valueType());
8123-
ASSERT_EQUALS("container(std :: set|unordered_set <)", tok->valueType()->str());
8121+
const Token* tok = tokenizer.tokens();
8122+
tok = Token::findsimplematch(tok, "s .");
8123+
ASSERT(tok && tok->valueType());
8124+
ASSERT_EQUALS("container(std :: set|unordered_set <)", tok->valueType()->str());
8125+
}
8126+
{
8127+
GET_SYMBOL_DB("void f(std::vector<int> v) {\n"
8128+
" auto it = std::find(v.begin(), v.end(), 0);\n"
8129+
"}\n");
8130+
ASSERT_EQUALS("", errout.str());
8131+
8132+
const Token* tok = tokenizer.tokens();
8133+
tok = Token::findsimplematch(tok, "auto");
8134+
ASSERT(tok && tok->valueType());
8135+
ASSERT_EQUALS("iterator(std :: vector <)", tok->valueType()->str());
8136+
}
8137+
{
8138+
GET_SYMBOL_DB("void f(std::vector<int>::iterator beg, std::vector<int>::iterator end) {\n"
8139+
" auto it = std::find(beg, end, 0);\n"
8140+
"}\n");
8141+
ASSERT_EQUALS("", errout.str());
8142+
8143+
const Token* tok = tokenizer.tokens();
8144+
tok = Token::findsimplematch(tok, "auto");
8145+
ASSERT(tok && tok->valueType());
8146+
ASSERT_EQUALS("iterator(std :: vector <)", tok->valueType()->str());
8147+
}
81248148
}
81258149

81268150
void valueTypeThis() {

0 commit comments

Comments
 (0)