Tokenizer::setVarId: better handling of initializer lists
This commit is contained in:
parent
5086ae7c31
commit
6ae135124e
|
@ -2885,6 +2885,26 @@ static void setVarIdStructMembers(Token **tok1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update the variable ids..
|
||||||
|
// Parse each function..
|
||||||
|
static void setVarIdClassFunction(Token * const startToken,
|
||||||
|
const Token * const endToken,
|
||||||
|
const std::map<std::string, unsigned int> &varlist,
|
||||||
|
std::map<unsigned int, std::map<std::string,unsigned int> > *structMembers,
|
||||||
|
unsigned int *_varId)
|
||||||
|
{
|
||||||
|
for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) {
|
||||||
|
if (tok2->varId() == 0 && tok2->previous()->str() != ".") {
|
||||||
|
const std::map<std::string,unsigned int>::const_iterator it = varlist.find(tok2->str());
|
||||||
|
if (it != varlist.end()) {
|
||||||
|
tok2->varId(it->second);
|
||||||
|
setVarIdStructMembers(&tok2, structMembers, _varId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Tokenizer::setVarId()
|
void Tokenizer::setVarId()
|
||||||
{
|
{
|
||||||
// Clear all variable ids
|
// Clear all variable ids
|
||||||
|
@ -3084,27 +3104,24 @@ void Tokenizer::setVarId()
|
||||||
|
|
||||||
// If this is a function implementation.. add it to funclist
|
// If this is a function implementation.. add it to funclist
|
||||||
if (Token::Match(tok2, ") const|volatile| {")) {
|
if (Token::Match(tok2, ") const|volatile| {")) {
|
||||||
if (tok2->next()->str() != "{")
|
while (tok2->str() != "{")
|
||||||
tok2 = tok2->next();
|
tok2 = tok2->next();
|
||||||
funclist.push_back(tok2->next());
|
setVarIdClassFunction(tok2, tok2->link(), varlist, &structMembers, &_varId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructor with initializer list
|
||||||
|
if (Token::Match(tok2, ") : %var% (")) {
|
||||||
|
const Token *tok3 = tok2;
|
||||||
|
while (Token::Match(tok3, ") [:,] %var% (")) {
|
||||||
|
tok3 = tok3->linkAt(3);
|
||||||
|
}
|
||||||
|
if (Token::simpleMatch(tok3, ") {")) {
|
||||||
|
setVarIdClassFunction(tok2, tok3->next()->link(), varlist, &structMembers, &_varId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the variable ids..
|
|
||||||
// Parse each function..
|
|
||||||
for (std::list<Token *>::iterator func = funclist.begin(); func != funclist.end(); ++func) {
|
|
||||||
for (Token *tok2 = (*func)->next(); tok2 != (*func)->link(); tok2 = tok2->next()) {
|
|
||||||
if (tok2->varId() == 0 &&
|
|
||||||
tok2->strAt(-1) != "." &&
|
|
||||||
varlist.find(tok2->str()) != varlist.end()) {
|
|
||||||
tok2->varId(varlist[tok2->str()]);
|
|
||||||
setVarIdStructMembers(&tok2, &structMembers, &_varId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1916,9 +1916,8 @@ private:
|
||||||
" Foo();\n"
|
" Foo();\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"Foo::Foo() : s(0) {}");
|
"Foo::Foo() : s(0) {}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference\n"
|
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference\n"
|
||||||
"[test.cpp:9]: (error) Null pointer dereference\n",
|
"[test.cpp:9]: (error) Null pointer dereference\n", errout.str());
|
||||||
"[test.cpp:3]: (error) Null pointer dereference\n", errout.str());
|
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" std::string s = 0 == x ? \"a\" : \"b\";\n"
|
" std::string s = 0 == x ? \"a\" : \"b\";\n"
|
||||||
|
|
|
@ -241,6 +241,7 @@ private:
|
||||||
TEST_CASE(varidclass12);
|
TEST_CASE(varidclass12);
|
||||||
TEST_CASE(varidclass13);
|
TEST_CASE(varidclass13);
|
||||||
TEST_CASE(varidclass14);
|
TEST_CASE(varidclass14);
|
||||||
|
TEST_CASE(varidclass15); // initializer list
|
||||||
|
|
||||||
TEST_CASE(file1);
|
TEST_CASE(file1);
|
||||||
TEST_CASE(file2);
|
TEST_CASE(file2);
|
||||||
|
@ -3942,6 +3943,23 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void varidclass15() {
|
||||||
|
const char code[] = "class A {\n"
|
||||||
|
" int a;\n"
|
||||||
|
" int b;\n"
|
||||||
|
" A();\n"
|
||||||
|
"};\n"
|
||||||
|
"A::A() : a(0) { b = 1; }";
|
||||||
|
const char expected[] = "\n\n##file 0\n"
|
||||||
|
"1: class A {\n"
|
||||||
|
"2: int a@1 ;\n"
|
||||||
|
"3: int b@2 ;\n"
|
||||||
|
"4: A ( ) ;\n"
|
||||||
|
"5: } ;\n"
|
||||||
|
"6: A :: A ( ) : a@1 ( 0 ) { b@2 = 1 ; }\n";
|
||||||
|
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
|
||||||
|
}
|
||||||
|
|
||||||
void file1() {
|
void file1() {
|
||||||
const char code[] = "a1\n"
|
const char code[] = "a1\n"
|
||||||
"#file \"b\"\n"
|
"#file \"b\"\n"
|
||||||
|
|
Loading…
Reference in New Issue