<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/58965>58965</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang] `LambdaExpr` expected children not reachable via `has` or `forEach` in matcher
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          Febbe
      </td>
    </tr>
</table>

<pre>
    Having a test code with a lambda:

```cpp
void lambdaCaptureValueTester() {
  Movable Mov{};
  auto Lambda = [Mov]() mutable {
      Mov.memberUse();
    };
  Lambda();
}
```

And the matcher:

```cpp
match(lambdaExpr(forEach(stmt().bind("first"))), Context);
```

Will result in: 

```AST
DeclRefExpr 0x56550acfd968 <tmp.cpp:193:18> 'Movable':'Movable' lvalue Var 0x56550acfd368 'Mov' 'Movable':'Movable'
CompoundStmt 0x56550acfd838 <tmp.cpp:193:33, line:198:5>
`-CXXMemberCallExpr 0x56550acfd818 <line:197:5, col:19> 'void'
  `-MemberExpr 0x56550acfd7e8 <col:5, col:9> '<bound member function type>' .memberUse 0x56550acd38d0
    `-DeclRefExpr 0x56550acfd7c8 <col:5> 'Movable':'Movable' lvalue Var 0x56550acfd368 'Mov' 'Movable':'Movable'
```

With the AST:

```AST
LambdaExpr 0x56550acffc30 <tmp.cpp:193:17, line:198:5> '(lambda at tmp.cpp:193:17)'
|-CXXRecordDecl 0x56550acfd5c8 <line:193:17> col:17 implicit class definition
| |-DefinitionData lambda standard_layout can_const_default_init
| | |-DefaultConstructor defaulted_is_constexpr
| | |-CopyConstructor simple trivial has_const_param needs_overload_resolution implicit_has_const_param
| | |-MoveConstructor exists simple trivial needs_overload_resolution
| | |-CopyAssignment trivial has_const_param needs_overload_resolution implicit_has_const_param
| | |-MoveAssignment needs_overload_resolution
| | `-Destructor simple non_trivial needs_overload_resolution
| |-CXXMethodDecl 0x56550acfd710 <col:25, line:198:5> line:193:17 used constexpr operator() 'void ()' inline
| | `-CompoundStmt 0x56550acfd838 <col:33, line:198:5>
| |   `-CXXMemberCallExpr 0x56550acfd818 <line:197:5, col:19> 'void'
| |     `-MemberExpr 0x56550acfd7e8 <col:5, col:9> '<bound member function type>' .memberUse 0x56550acd38d0
| |       `-DeclRefExpr 0x56550acfd7c8 <col:5> 'Movable':'Movable' lvalue Var 0x56550acfd368 'Mov' 'Movable':'Movable'
| |-FieldDecl 0x56550acff580 <line:193:18> col:18 implicit 'Movable':'Movable'
| |-CXXConstructorDecl 0x56550acff620 <col:17> col:17 implicit constexpr (lambda at tmp.cpp:193:17) 'void (const (lambda at tmp.cpp:193:17) &)' inline default trivial noexcept-unevaluated 0x56550acff620
| | `-ParmVarDecl 0x56550acff738 <col:17> col:17 'const (lambda at tmp.cpp:193:17) &'
| |-CXXConstructorDecl 0x56550acff7d8 <col:17> col:17 implicit constexpr (lambda at tmp.cpp:193:17) 'void ((lambda at tmp.cpp:193:17) &&)' inline default trivial noexcept-unevaluated 0x56550acff7d8
| | `-ParmVarDecl 0x56550acff8f8 <col:17> col:17 '(lambda at tmp.cpp:193:17) &&'
| |-CXXMethodDecl 0x56550acff9a8 <col:17> col:17 implicit operator= '(lambda at tmp.cpp:193:17) &(const (lambda at tmp.cpp:193:17) &)' inline default_delete trivial noexcept-unevaluated 0x56550acff9a8
| | `-ParmVarDecl 0x56550acffab8 <col:17> col:17 'const (lambda at tmp.cpp:193:17) &'
| `-CXXDestructorDecl 0x56550acffb40 <col:17> col:17 implicit used ~(lambda at tmp.cpp:193:17) 'void () noexcept' inline default
|   `-CompoundStmt 0x56550acffc60 <col:17>
|-CXXConstructExpr 0x56550acff540 <col:18> 'Movable':'Movable' 'void (const Movable &) noexcept'
| `-ImplicitCastExpr 0x56550acfd988 <col:18> 'const Movable':'const Movable' lvalue <NoOp>
|   `-DeclRefExpr 0x56550acfd968 <col:18> 'Movable':'Movable' lvalue Var 0x56550acfd368 'Mov' 'Movable':'Movable'
`-CompoundStmt 0x56550acfd838 <col:33, line:198:5>
  `-CXXMemberCallExpr 0x56550acfd818 <line:197:5, col:19> 'void'
    `-MemberExpr 0x56550acfd7e8 <col:5, col:9> '<bound member function type>' .memberUse 0x56550acd38d0
      `-DeclRefExpr 0x56550acfd7c8 <col:5> 'Movable':'Movable' lvalue Var 0x56550acfd368 'Mov' 'Movable':'Movable'
```
Note, that the `CXXConstructExpr` which I would expect is not even reachable from here. Instead, a descendant of it is.
Is that really the expected behavior?

In my opinion, either the AST itself is wrong, or the `has` + `forEach` traversal matcher.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNWNtu2zgQ_Rr5haghS9HFD35I7BQboO0u2m63bwYljiIuKFEQKSf5-x1SF0uykzpou60h2BbFOXNmODPkKJHsafMHPfDynlCiQWmSSgbkgescBwQtEkYd_9pxd47bf4due6VV1Y4cJGfd3C2tdFPDFyoa-IxwUDte7Hhr4kQ37WRC3ssDTQSYXzMa7Rx_eEYbLck7C0Ucf0ec4MZMC3YdTNFoKzuCMx-csyygSKD-W0E7dQRKyFRJiz-bZqZM7RsbfV0yonMgBdVpjkZ9yyV2HmpovXL7WBk_ZLK-pXZY6UK3-pcJL5n962W8VjjqGVbdtSVbWWp41BOm5wj-w4UgNahGaMJL5EfOErz-9Lkd2UEqPkJmmBH3MQiDwKVpxtZhjH7f6qJaGlv869XaN9-x498Sx4u6tcN_xgXjeyIOZtHJFzoB9A2gnWfmvIjQEtvKopJNyT6hi8ZAsX-Wme8bLwlegh1CntcBch3MfrP9-vW9jYwtFWJubryyoIN4ZMURMJXCDnRmmwgfGGI4IW4LOgeMwAK24iOkHgifJcY60kYryZoy1VyWRD9VYHijk46RfERmfszcUTwjgWdWMEonDP6vZXsmKLGMmLQxYfdMygwR-W5IlRGRLPXdswEZnV126-I-6wjV5Jzc-kg62pr4-AiprJnx59gFQTqNjU4clXTBERFeVIKnHIumoEoRBhkvuVnOAZ4YFbthfEd1X1WJ0rRktGZ7QZ9kgxi03KeyVHqPOBTzeG-EJkg9mnm6NVPrJtWyJp0AsD1XLQaYinMiupXV01hOGQOA6JofOBUkp530vqI1LUgJwNReHqAWkrI9VhcpGhutveH7mcipSowTGKuER660mmt-VtN5G66V4vdlAaX-6dxHqi4laXNz7uNSlvvXWdtWLp3Lk8iMVu4xxb3gfCbM4pY0ChgZYoPICmqK_Prtua1xpNsUMed5aRFOTPtGfW5JvVyVO7S2jP34-nzE_8WVekzkt6zZXaC95SDmQZYFsXta_uJR-YuP5e8VunC5R-VgrjT0RpH9bLEdgvjbpX4c2FbuMplwkgR9fT2WKwmPKVT6TVOCWQqKpXdmxmni_EXrAldsbnI0zpuZyUjhdaRf5eyIPa_5u519KePv9DTacLGn4-xFT7-C8ambzxbqbE0v8PBQiU27czmN7w9nPGcI0HCxr9Gai31Nk58U1e2Ocdxf54qTqwsqiN0Lnej2tSG9Hnx06s0jR_LSPpml4Zzg5Cw65Ov8IBxMDLugHzupfH3f3cbD2JSpf-86N22pmrNg6zg-w2KCP3CZj_bbFsp_kH9Wk_PAi9tj15RebvqP62l-wHHnZx1zfvnx5rc91kxb0Q9Sg7Ff5ybJsRnFJ_NEwyHykPM0J3fkQTaCYZ9SQaoJV5gnmsABSlIDTXObQVktC5JDDUtyZ7ZHyowCiqVApYBNHTYLMiPciC9bEneq1Y8YQjxZGq0GLEQJ5PTAzQbwdtwh35WkeMLdAbtA7AwQH7CbxpXq-mmEVyAyw_ChluW9mSHr3kDsbYxNjndj7voXTziia4p9h8Jy373K6gguYLMKQ4zq0AvcBdv4bO2v6UJzLWDjBDfY4aKOYGfgjp26QRzsSHMuWI2OMh47Ogv3lhEjpDglxMueyaKpxSbXulJ2Xd_idY8mN8kylQXeCHHof95UtfwXteItV6oBhX-CeB0Gi3wThUkQe-tolVKWrFaxF1-lbJVQyGDtMposBE1AKGOU43klPBALYV68BbsF33iu561WqyvX9SPfXSap5wZX4VUSel4Yesy5cqGgXCwNj6Ws7xf1xlJKmnuFD4Xpb48Pqe0fwfrQ4NMGDwr15i0kCSys4o0l_h9jmliv">