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

    <tr>
        <th>Summary</th>
        <td>
            [clang-tidy] `hasAncestor(cxxCtorInitializer)` never matches?
        </td>
    </tr>

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

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

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

<pre>
    Given this code:

```cpp
// foo.cpp
class Foo {
 public:
  Foo(int f): foo(f) {}
 private:
  int foo;
};
```

```
> ./clang-query foo.cpp
clang-query> match declRefExpr(hasAncestor(cxxCtorInitializer()))
```

This does not match anything, although replacing `cxxCtorInitializer` with `cxxConstructorDecl` matches `f`.

Dumping AST via `clang-check -ast-dump` shows this tree:

```
`-CXXRecordDecl 0x1a4d5f501a0 <foo.cpp:1:1, line:6:1> line:1:7 class Foo definition
  |-DefinitionData pass_in_registers standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
  | |-DefaultConstructor
  | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveConstructor exists simple trivial needs_implicit
  | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveAssignment exists simple trivial needs_implicit
  | `-Destructor simple irrelevant trivial needs_implicit
  |-CXXRecordDecl 0x1a4d5f502b8 <col:1, col:7> col:7 implicit referenced class Foo
  |-AccessSpecDecl 0x1a4d5f50348 <line:2:2, col:8> col:2 public
  |-CXXConstructorDecl 0x1a4d5f50498 <line:3:3, col:23> col:3 Foo 'void (int)' implicit-inline
  | |-ParmVarDecl 0x1a4d5f50390 <col:7, col:11> col:11 used f 'int'
  | |-CXXCtorInitializer Field 0x1a4d5f50598 'foo' 'int'
  | | `-ImplicitCastExpr 0x1a4d5f50648 <col:19> 'int' <LValueToRValue>
  | |   `-DeclRefExpr 0x1a4d5f50608 <col:19> 'int' lvalue ParmVar 0x1a4d5f50390 'f' 'int'
  | `-CompoundStmt 0x1a4d5f50688 <col:22, col:23>
  |-AccessSpecDecl 0x1a4d5f50550 <line:4:2, col:9> col:2 private
  `-FieldDecl 0x1a4d5f50598 <line:5:3, col:7> col:7 foo 'int'
```

Per the tree the declRefExpr should have ImplicitCastExpr, CXXCtorInitializer and CXXConstructorDecl, but the parent list just lacks the initializer per the following query:

```
clang-query> match declRefExpr(hasParent(implicitCastExpr(hasParent(cxxConstructorDecl().bind('grandparent'))).bind("parent"))) 

Match #1:

C:\Users\sasch\Documents\GitHub\gecko-dev\build\clang-plugin\foo.cpp:3:3: note: "grandparent" binds here
  Foo(int f): foo(f) {}
 ^~~~~~~~~~~~~~~~~~~~~
C:\Users\sasch\Documents\GitHub\gecko-dev\build\clang-plugin\foo.cpp:3:19: note: "parent" binds here
  Foo(int f): foo(f) {}
 ^
C:\Users\sasch\Documents\GitHub\gecko-dev\build\clang-plugin\foo.cpp:3:19: note: "root" binds here
  Foo(int f): foo(f) {}
 ^
1 match.
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV9-P26gT_2vIC0pkYztOHvKQOpt-K30rVW2v2reIwDimS8AHOLvpw_3tJ7CdON7d_pB6d6t4DQx8PjPDMIypteKgAFYoe4OyzYQ2rtJmZallFVX022Sv-Xn1VpxAYVcJi5nmgJI1ijYo6v_Po_bH6robIVtEtrjUenYZY5Jai7daY5S_aYdw3eylYBc47MWILIRyuERkiZK1x0Bk4XthXb7plxpxog4Ga8MqrVHSofu5l3av4ot6d93kDs8Q2TJJ1WH6ZwPm_MyCXuDnHqljFebA5Eco755qg8iionatGFinfY89PRVOm3dKOEGl-AZ-0NvV_l7X7LP3NNdgsdKuI6Lq7CqhDogUmEpX6eZQYQO1pEyoA_buf043j_CjcFUv1co60zCnzQaY9NKADdZPKNE8mg212DTH2kOvP33GJ0EDSHABq4A94Cm1bsqbY-1xbKUfbRshzsCrEXLpTov7-4_AtOFeExw9xTTlWZlFMY0wSore8ck6Dg8psBTK487bsbu-7-U5vkYXh1J4D2jVBwbKi-nmMrqhjuKaWrsTamfgIKwDY7F1VHFq-E7Ss24cdkacBJXyvGO6PtO9BFxRu2ssmJ3fc2qA77wnMaNqx7xndxxK2ki380wD8l4BLxtswXhGoevzQIytONYSekUCe0tTU0OPWAFwu_NzBBMO943daN6Y5b0-wZAFnoR1dkx2C_6SpuuQOI6g3D-o6IDkl_WcR9MNjJ0pjAEJJ6rcjyFeDVGyX_gQZVr2odk2cx-VXfNiJjZQggHFgF-DdMiyZgys_VQDG9EkaaDpwpyE58K1uHKRPo3eqj467APgdDkETsJzASbJFTlp0zXJT1pw3CbmkLuu5k2FCjijzftAzfELHRMny-jquPzKGcdXzjjGjQWOS88b-PJn4Xd_P8pzeCtA8gFT5k0kebg88leRQpC86ywpqHU-iw9Q5ulwo5deyQuUF_z_C5UNfNYfwxsld2N83IXh5YoYgkffAZcnj4g7N45dSPLydbN8btXHWjeKf3JHN2RcDBgJGe35T8VklkWD0ElvY3J5E5Pd_dyjzqNp2KQx4E0sZrexeHOgyjYUhxa_eHd-AINdBeEaCo3BDe2vqUZyXNET4PHGe94XQosqjp8fJz9576-JCnBNjc9QUliHvzbWYUnZgw0iMQCqO8VKLaV-9BdrV0p876r8uZrjQ9DAH9BnNt2IX6gBQkEy2wvFQzM_GKp43S3IL8XKdQbpheQixEMD3gcVEUnikWWF72fFHxaMRVkRSkyUFRvNGp_h_dhb4f7X7FFWHIA96CmHE8qKfSMkR1nRuqKWzUEolA0qhKR7fLHkowgjQm7MINhrb3EFBn690kTZ3V8v_P0LRsXLkVW_zaD_Qnmj9e9TPW6Pwmx0aCZ8lfBlsqQTWMXzxSJbxElOJtWK8D2HeZlGOY9LGrF0GVGY52lephlk-2QiViQiSZRHWbwgJCOziJEFWWRpHKcpi3mJ0giOVMiZlKfjTJvDRFjbwGqezJfJRNI9SBu-oghR8IiD0B-SbDMxK79mum8OFqWRzxP2iuKEk-Hzq_WmE_yMso1PmD_-mFj60lvBCUxfyKNkO2mMXFXO1dZvb_gSOwhXNfsZ00dEtp65e01ro78Cc4hsg74WkW2w5-8AAAD__6tfTQQ">