Skip to content

Commit cddaa6d

Browse files
authored
10221: Fix setVarId in template code (#3187)
The computation of the classname was not expecting templates. Simply skipping the template part seems to fix the issue.
1 parent e23a967 commit cddaa6d

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

lib/tokenize.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4175,7 +4175,7 @@ void Tokenizer::setVarIdPass2()
41754175
while (tok->str() == "}" && !scopeInfo.empty() && tok == scopeInfo.back().bodyEnd)
41764176
scopeInfo.pop_back();
41774177

4178-
if (!Token::Match(tok, "namespace|class|struct %name% {|:|::"))
4178+
if (!Token::Match(tok, "namespace|class|struct %name% {|:|::|<"))
41794179
continue;
41804180

41814181
const std::string &scopeName(getScopeName(scopeInfo));
@@ -4184,9 +4184,14 @@ void Tokenizer::setVarIdPass2()
41844184
std::list<const Token *> classnameTokens;
41854185
classnameTokens.push_back(tok->next());
41864186
const Token* tokStart = tok->tokAt(2);
4187-
while (Token::Match(tokStart, ":: %name%")) {
4188-
classnameTokens.push_back(tokStart->next());
4189-
tokStart = tokStart->tokAt(2);
4187+
while (Token::Match(tokStart, ":: %name%") || tokStart->str() == "<") {
4188+
if (tokStart->str() == "<") {
4189+
// skip the template part
4190+
tokStart = tokStart->findClosingBracket()->next();
4191+
} else {
4192+
classnameTokens.push_back(tokStart->next());
4193+
tokStart = tokStart->tokAt(2);
4194+
}
41904195
}
41914196

41924197
std::string classname;

test/testvarid.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ class TestVarID : public TestFixture {
195195
TEST_CASE(varidclass19); // initializer list
196196
TEST_CASE(varidclass20); // #7578: int (*p)[2]
197197
TEST_CASE(varid_classnameshaddowsvariablename); // #3990
198+
TEST_CASE(varid_classnametemplate); // #10221
198199

199200
TEST_CASE(varidenum1);
200201
TEST_CASE(varidenum2);
@@ -3211,6 +3212,37 @@ class TestVarID : public TestFixture {
32113212

32123213
}
32133214

3215+
void varid_classnametemplate() {
3216+
const char code[] = "template <typename T>\n"
3217+
"struct BBB {\n"
3218+
" struct inner;\n"
3219+
"};\n"
3220+
"\n"
3221+
"template <typename T>\n"
3222+
"struct BBB<T>::inner {\n"
3223+
" inner(int x);\n"
3224+
" int x;\n"
3225+
"};\n"
3226+
"\n"
3227+
"template <typename T>\n"
3228+
"BBB<T>::inner::inner(int x): x(x) {}\n";
3229+
const char expected[] = "1: template < typename T >\n"
3230+
"2: struct BBB {\n"
3231+
"3: struct inner ;\n"
3232+
"4: } ;\n"
3233+
"5:\n"
3234+
"6: template < typename T >\n"
3235+
"7: struct BBB < T > :: inner {\n"
3236+
"8: inner ( int x@1 ) ;\n"
3237+
"9: int x@2 ;\n"
3238+
"10: } ;\n"
3239+
"11:\n"
3240+
"12: template < typename T >\n"
3241+
"13: BBB < T > :: inner :: inner ( int x@3 ) : x@2 ( x@3 ) { }\n";
3242+
ASSERT_EQUALS(expected, tokenize(code));
3243+
3244+
}
3245+
32143246
void varidnamespace1() {
32153247
const char code[] = "namespace A {\n"
32163248
" char buf[20];\n"

0 commit comments

Comments
 (0)