llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.24k stars 11.66k forks source link

[AST-Matchers] `hasAncestor(cxxCtorInitializer)` never matches? #63693

Open saschanaz opened 1 year ago

saschanaz commented 1 year ago

Given this code:

// 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.
llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-tidy