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::list<std::string> scope;
|
||||
std::list<const Token *> usingnamespaces;
|
||||
for (Token *tok2 = list.front(); tok2; tok2 = tok2->next()) {
|
||||
if (!tok2->previous() || Token::Match(tok2->previous(), "[;{}]")) {
|
||||
if (Token::Match(tok2, "using namespace %name% ::|;")) {
|
||||
const Token *endtok = tok2->tokAt(2);
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (!tok->previous() || Token::Match(tok->previous(), "[;{}]")) {
|
||||
if (Token::Match(tok, "using namespace %name% ::|;")) {
|
||||
const Token *endtok = tok->tokAt(2);
|
||||
while (Token::Match(endtok, "%name% ::"))
|
||||
endtok = endtok->tokAt(2);
|
||||
if (Token::Match(endtok, "%name% ;"))
|
||||
usingnamespaces.push_back(tok2->tokAt(2));
|
||||
} else if (Token::Match(tok2, "namespace %name% {")) {
|
||||
scope.push_back(tok2->strAt(1));
|
||||
endOfScope[tok2->linkAt(2)] = tok2->strAt(1);
|
||||
usingnamespaces.push_back(tok->tokAt(2));
|
||||
} else if (Token::Match(tok, "namespace %name% {")) {
|
||||
scope.push_back(tok->strAt(1));
|
||||
endOfScope[tok->linkAt(2)] = tok->strAt(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (tok2->str() == "}") {
|
||||
std::map<const Token *, std::string>::iterator it = endOfScope.find(tok2);
|
||||
if (tok->str() == "}") {
|
||||
std::map<const Token *, std::string>::iterator it = endOfScope.find(tok);
|
||||
if (it != endOfScope.end())
|
||||
scope.remove(it->second);
|
||||
}
|
||||
|
||||
const Token* tok3 = nullptr;
|
||||
if (Token::Match(tok2, "%name% :: ~| %name%"))
|
||||
tok3 = tok2->next();
|
||||
else if (Token::Match(tok2, "%name% <") && Token::Match(tok2->next()->findClosingBracket(),"> :: ~| %name%"))
|
||||
tok3 = tok2->next()->findClosingBracket()->next();
|
||||
Token* const tok1 = tok;
|
||||
if (Token::Match(tok->previous(), "!!:: %name% :: ~| %name%"))
|
||||
tok = tok->next();
|
||||
else if (Token::Match(tok->previous(), "!!:: %name% <") && Token::Match(tok->next()->findClosingBracket(),"> :: ~| %name%"))
|
||||
tok = tok->next()->findClosingBracket()->next();
|
||||
else
|
||||
continue;
|
||||
|
||||
while (Token::Match(tok3, ":: ~| %name%")) {
|
||||
tok3 = tok3->next();
|
||||
if (tok3->str() == "~")
|
||||
tok3 = tok3->next();
|
||||
tok3 = tok3->next();
|
||||
while (Token::Match(tok, ":: ~| %name%")) {
|
||||
tok = tok->next();
|
||||
if (tok->str() == "~")
|
||||
tok = tok->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)
|
||||
syntaxError(tok2);
|
||||
const std::string& str3 = tok3->str();
|
||||
if (str3 == "(")
|
||||
allMemberFunctions.push_back(Member(scope, usingnamespaces, tok2));
|
||||
else if (str3 != "::" && tok2->strAt(-1) != "::") // Support only one depth
|
||||
allMemberVars.push_back(Member(scope, usingnamespaces, tok2));
|
||||
if (!tok)
|
||||
syntaxError(tok1);
|
||||
if (Token::Match(tok, "%name% ("))
|
||||
allMemberFunctions.push_back(Member(scope, usingnamespaces, tok1));
|
||||
else
|
||||
allMemberVars.push_back(Member(scope, usingnamespaces, tok1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ private:
|
|||
TEST_CASE(varid_in_class18); // #7127
|
||||
TEST_CASE(varid_in_class19);
|
||||
TEST_CASE(varid_in_class20); // #7267
|
||||
TEST_CASE(varid_in_class21); // #7788
|
||||
TEST_CASE(varid_namespace_1); // #7272
|
||||
TEST_CASE(varid_namespace_2); // #7000
|
||||
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"));
|
||||
}
|
||||
|
||||
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
|
||||
const char code[] = "namespace Blah {\n"
|
||||
" struct foo { int x;};\n"
|
||||
|
|
Loading…
Reference in New Issue