Skip to content

Commit b20b47c

Browse files
autoantwortclaude
andcommitted
Handle lambda in constructor initializer list in setVarIdPass1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent fdc7691 commit b20b47c

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

‎lib/tokenize.cpp‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4771,6 +4771,7 @@ void Tokenizer::setVarIdPass1()
47714771
std::stack<const Token *> functionDeclEndStack;
47724772
const Token *functionDeclEndToken = nullptr;
47734773
bool initlist = false;
4774+
std::stack<const Token *> initlistLambdaEnds; // ends of lambda bodies in an initializer list
47744775
bool inlineFunction = false;
47754776
for (Token *tok = list.front(); tok; tok = tok->next()) {
47764777
if (tok->isOp())
@@ -4843,6 +4844,7 @@ void Tokenizer::setVarIdPass1()
48434844
while (Token::Match(prev, "%name%|."))
48444845
prev = prev->previous();
48454846
const bool isLambda = prev && prev->str() == ")" && Token::simpleMatch(prev->link()->previous(), "] (");
4847+
const bool isInitlistLambda = initlist && (isLambda || Token::simpleMatch(prev, "]"));
48464848
if ((!isLambda && (tok->strAt(-1) == ")" || Token::Match(tok->tokAt(-2), ") %type%"))) ||
48474849
(initlist && tok->strAt(-1) == "}")) {
48484850
isExecutable = true;
@@ -4852,8 +4854,10 @@ void Tokenizer::setVarIdPass1()
48524854
if (!(scopeStack.top().isStructInit || tok->strAt(-1) == "="))
48534855
variableMap.enterScope();
48544856
}
4855-
const bool isStructInit = scopeStack.top().isStructInit || tok->strAt(-1) == "=" || (initlist && !Token::Match(tok->tokAt(-1), ")|}|..."));
4857+
const bool isStructInit = scopeStack.top().isStructInit || tok->strAt(-1) == "=" || (initlist && !isInitlistLambda && !Token::Match(tok->tokAt(-1), ")|}|..."));
48564858
scopeStack.emplace(isExecutable, isStructInit, isEnumStart(tok), variableMap.getVarId());
4859+
if (isInitlistLambda)
4860+
initlistLambdaEnds.push(tok->link());
48574861
initlist = false;
48584862
} else { /* if (tok->str() == "}") */
48594863
bool isNamespace = false;
@@ -4894,6 +4898,11 @@ void Tokenizer::setVarIdPass1()
48944898
if (scopeStack.empty()) { // should be impossible
48954899
scopeStack.emplace(/*VarIdScopeInfo()*/);
48964900
}
4901+
if (!initlistLambdaEnds.empty() && initlistLambdaEnds.top() == tok) {
4902+
// continue with the initializer list after the lambda
4903+
initlistLambdaEnds.pop();
4904+
initlist = true;
4905+
}
48974906
}
48984907
}
48994908
}

‎test/testvarid.cpp‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2739,6 +2739,30 @@ class TestVarID : public TestFixture {
27392739
"10: } ;\n"
27402740
"11: int T :: g ( ) { return * p@5 ; }\n",
27412741
tokenize(code14));
2742+
2743+
const char code15[] = "struct S {\n" // lambda in initializer list
2744+
" int x;\n"
2745+
" int* p;\n"
2746+
" S(int* p) : x([p] { return *p; }()), p(p) {}\n"
2747+
" S(int* p, int) : x([](int* q) { int y = *q; return y; }(p)), p(p) {}\n"
2748+
"};\n"
2749+
"struct T {\n"
2750+
" int* p;\n"
2751+
" int g();\n"
2752+
"};\n"
2753+
"int T::g() { return *p; }\n";
2754+
ASSERT_EQUALS("1: struct S {\n"
2755+
"2: int x@1 ;\n"
2756+
"3: int * p@2 ;\n"
2757+
"4: S ( int * p@3 ) : x@1 ( [ p@3 ] { return * p@3 ; } ( ) ) , p@2 ( p@3 ) { }\n"
2758+
"5: S ( int * p@4 , int ) : x@1 ( [ ] ( int * q@5 ) { int y@6 ; y@6 = * q@5 ; return y@6 ; } ( p@4 ) ) , p@2 ( p@4 ) { }\n"
2759+
"6: } ;\n"
2760+
"7: struct T {\n"
2761+
"8: int * p@7 ;\n"
2762+
"9: int g ( ) ;\n"
2763+
"10: } ;\n"
2764+
"11: int T :: g ( ) { return * p@7 ; }\n",
2765+
tokenize(code15));
27422766
}
27432767

27442768
void varid_initListWithBaseTemplate() {

0 commit comments

Comments
 (0)