Issue 138782
Summary ASTMatcher `unless(hasAncestor(classTemplatePartialSpecializationDecl()))` has no effect
Labels new issue
Assignees
Reporter isVoid
    ## Reproducer:

Given the following `example.cpp`:
```c++
#include <type_traits>

template <typename A, typename B>
struct Tensor {};

template <class T>
struct is_tensor : std::false_type {};

template <class A, class B>
struct is_tensor<Tensor<A, B>> : std::true_type {};
```

The second `is_tensor` yields the following tree
```
`-ClassTemplatePartialSpecializationDecl 0x5e81939cb9e8 <line:9:1, line:10:50> col:8 struct is_tensor definition explicit_specialization
  |-DefinitionData empty aggregate standard_layout trivially_copyable trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
  | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
  | |-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
  |-public 'std::true_type':'std::integral_constant<bool, true>'
  |-TemplateArgument type 'Tensor<type-parameter-0-0, type-parameter-0-1>'
  | `-TemplateSpecializationType 0x5e81939cb000 'Tensor<type-parameter-0-0, type-parameter-0-1>' dependent
  |   |-name: 'Tensor'
  |   | `-ClassTemplateDecl 0x5e81939cae88 <line:3:1, line:4:16> col:8 Tensor
  | |-TemplateArgument type 'type-parameter-0-0'
  |   | `-TemplateTypeParmType 0x5e8193817f40 'type-parameter-0-0' dependent depth 0 index 0
  | `-TemplateArgument type 'type-parameter-0-1'
  |     `-TemplateTypeParmType 0x5e8193877fb0 'type-parameter-0-1' dependent depth 0 index 1
 |-TemplateTypeParmDecl 0x5e81939cb720 <line:9:11, col:17> col:17 referenced class depth 0 index 0 A
  |-TemplateTypeParmDecl 0x5e81939cb7a0 <col:20, col:26> col:26 referenced class depth 0 index 1 B
  `-CXXRecordDecl 0x5e81939cbc88 <line:10:1, col:8> col:8 implicit struct is_tensor
```

It's obvious that the `CXXRecordDecl is_tensor` is a child of `ClassTemplatePartialSpecializationDecl`.

Given ASTMatcher setup:

```c++
class RecordCallback : public MatchFinder::MatchCallback {
public:
  RecordCallback() = default;
  void run(const MatchFinder::MatchResult & Result) {
    const CXXRecordDecl *RD =
 Result.Nodes.getNodeAs<clang::CXXRecordDecl>("record");

    std::string name = RD->getNameAsString();

    if (name == "is_tensor")
    {
 std::string source_range =
 RD->getSourceRange().printToString(*Result.SourceManager);
        std::cout << source_range << std::endl;
    }
  }
};

void parse(std::vector<std::string> options) {

  auto ast = default_ast_unit_from_command_line(options);

  MatchFinder finder;

 RecordCallback record_callback;

  finder.addMatcher(
 recordDecl(allOf(
 unless(hasAncestor(classTemplatePartialSpecializationDecl())),
 unless(hasAncestor(classTemplateDecl())))).bind("record"),
 &record_callback);

 finder.matchAST(ast->getASTContext());
}
```

prints

```
<example.cpp:9:1, line:10:50>
```

## Expected:

Nothing should be printed because `unless(hasAncestor(classTemplatePartialSpecializationDecl()))` exclude all `recorddecl`s with CTPSD in ancestors. Noticably, `unless(hasAncestor(classTemplateDecl()))` works as expected.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to