Fixed #7788 (Varid missing for member variable in ctor of template class)
This commit is contained in:
parent
7ec0e41196
commit
6b1a2dcc5d
|
@ -2970,47 +2970,51 @@ void Tokenizer::setVarIdPass2()
|
||||||
std::map<const Token *, std::string> endOfScope;
|
std::map<const Token *, std::string> endOfScope;
|
||||||
std::list<std::string> scope;
|
std::list<std::string> scope;
|
||||||
std::list<const Token *> usingnamespaces;
|
std::list<const Token *> usingnamespaces;
|
||||||
for (Token *tok2 = list.front(); tok2; tok2 = tok2->next()) {
|
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (!tok2->previous() || Token::Match(tok2->previous(), "[;{}]")) {
|
if (!tok->previous() || Token::Match(tok->previous(), "[;{}]")) {
|
||||||
if (Token::Match(tok2, "using namespace %name% ::|;")) {
|
if (Token::Match(tok, "using namespace %name% ::|;")) {
|
||||||
const Token *endtok = tok2->tokAt(2);
|
const Token *endtok = tok->tokAt(2);
|
||||||
while (Token::Match(endtok, "%name% ::"))
|
while (Token::Match(endtok, "%name% ::"))
|
||||||
endtok = endtok->tokAt(2);
|
endtok = endtok->tokAt(2);
|
||||||
if (Token::Match(endtok, "%name% ;"))
|
if (Token::Match(endtok, "%name% ;"))
|
||||||
usingnamespaces.push_back(tok2->tokAt(2));
|
usingnamespaces.push_back(tok->tokAt(2));
|
||||||
} else if (Token::Match(tok2, "namespace %name% {")) {
|
} else if (Token::Match(tok, "namespace %name% {")) {
|
||||||
scope.push_back(tok2->strAt(1));
|
scope.push_back(tok->strAt(1));
|
||||||
endOfScope[tok2->linkAt(2)] = tok2->strAt(1);
|
endOfScope[tok->linkAt(2)] = tok->strAt(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok2->str() == "}") {
|
if (tok->str() == "}") {
|
||||||
std::map<const Token *, std::string>::iterator it = endOfScope.find(tok2);
|
std::map<const Token *, std::string>::iterator it = endOfScope.find(tok);
|
||||||
if (it != endOfScope.end())
|
if (it != endOfScope.end())
|
||||||
scope.remove(it->second);
|
scope.remove(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token* tok3 = nullptr;
|
Token* const tok1 = tok;
|
||||||
if (Token::Match(tok2, "%name% :: ~| %name%"))
|
if (Token::Match(tok->previous(), "!!:: %name% :: ~| %name%"))
|
||||||
tok3 = tok2->next();
|
tok = tok->next();
|
||||||
else if (Token::Match(tok2, "%name% <") && Token::Match(tok2->next()->findClosingBracket(),"> :: ~| %name%"))
|
else if (Token::Match(tok->previous(), "!!:: %name% <") && Token::Match(tok->next()->findClosingBracket(),"> :: ~| %name%"))
|
||||||
tok3 = tok2->next()->findClosingBracket()->next();
|
tok = tok->next()->findClosingBracket()->next();
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
while (Token::Match(tok3, ":: ~| %name%")) {
|
while (Token::Match(tok, ":: ~| %name%")) {
|
||||||
tok3 = tok3->next();
|
tok = tok->next();
|
||||||
if (tok3->str() == "~")
|
if (tok->str() == "~")
|
||||||
tok3 = tok3->next();
|
tok = tok->next();
|
||||||
tok3 = tok3->next();
|
else if (Token::Match(tok, "%name% <") && Token::Match(tok->next()->findClosingBracket(),"> :: ~| %name%"))
|
||||||
|
tok = tok->next()->findClosingBracket()->next();
|
||||||
|
else if (Token::Match(tok, "%name% ::"))
|
||||||
|
tok = tok->next();
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!tok3)
|
if (!tok)
|
||||||
syntaxError(tok2);
|
syntaxError(tok1);
|
||||||
const std::string& str3 = tok3->str();
|
if (Token::Match(tok, "%name% ("))
|
||||||
if (str3 == "(")
|
allMemberFunctions.push_back(Member(scope, usingnamespaces, tok1));
|
||||||
allMemberFunctions.push_back(Member(scope, usingnamespaces, tok2));
|
else
|
||||||
else if (str3 != "::" && tok2->strAt(-1) != "::") // Support only one depth
|
allMemberVars.push_back(Member(scope, usingnamespaces, tok1));
|
||||||
allMemberVars.push_back(Member(scope, usingnamespaces, tok2));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ private:
|
||||||
TEST_CASE(varid_in_class18); // #7127
|
TEST_CASE(varid_in_class18); // #7127
|
||||||
TEST_CASE(varid_in_class19);
|
TEST_CASE(varid_in_class19);
|
||||||
TEST_CASE(varid_in_class20); // #7267
|
TEST_CASE(varid_in_class20); // #7267
|
||||||
|
TEST_CASE(varid_in_class21); // #7788
|
||||||
TEST_CASE(varid_namespace_1); // #7272
|
TEST_CASE(varid_namespace_1); // #7272
|
||||||
TEST_CASE(varid_namespace_2); // #7000
|
TEST_CASE(varid_namespace_2); // #7000
|
||||||
TEST_CASE(varid_initList);
|
TEST_CASE(varid_initList);
|
||||||
|
@ -1769,6 +1770,28 @@ private:
|
||||||
"8: template < class C > cacheEntry < C > :: cacheEntry ( ) : m_key@1 ( ) { }\n", tokenize(code, false, "test.cpp"));
|
"8: template < class C > cacheEntry < C > :: cacheEntry ( ) : m_key@1 ( ) { }\n", tokenize(code, false, "test.cpp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void varid_in_class21() {
|
||||||
|
const char code[] = "template <typename t1,typename t2>\n"
|
||||||
|
"class A::B {\n"
|
||||||
|
" B();\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"template <typename t1,typename t2>\n"
|
||||||
|
"A::B<t1,t2>::B() : x(9) {}";
|
||||||
|
|
||||||
|
const char expected[] = "1: template < typename t1 , typename t2 >\n"
|
||||||
|
"2: class A :: B {\n"
|
||||||
|
"3: B ( ) ;\n"
|
||||||
|
"4: int x@1 ;\n"
|
||||||
|
"5: } ;\n"
|
||||||
|
"6:\n"
|
||||||
|
"7: template < typename t1 , typename t2 >\n"
|
||||||
|
"8: A :: B < t1 , t2 > :: B ( ) : x@1 ( 9 ) { }\n";
|
||||||
|
|
||||||
|
ASSERT_EQUALS(expected, tokenize(code, false, "test.cpp"));
|
||||||
|
}
|
||||||
|
|
||||||
void varid_namespace_1() { // #7272
|
void varid_namespace_1() { // #7272
|
||||||
const char code[] = "namespace Blah {\n"
|
const char code[] = "namespace Blah {\n"
|
||||||
" struct foo { int x;};\n"
|
" struct foo { int x;};\n"
|
||||||
|
|
Loading…
Reference in New Issue