================
@@ -467,6 +468,58 @@ hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef 
*> NameRefs) {
   return HasOverloadOpNameMatcher(vectorFromRefs(NameRefs));
 }
 
+static std::vector<Matcher<Stmt>>
+vectorFromMatcherRefs(ArrayRef<const Matcher<Stmt> *> MatcherRefs) {
+  std::vector<Matcher<Stmt>> Matchers;
+  Matchers.reserve(MatcherRefs.size());
+  for (auto *Matcher : MatcherRefs)
+    Matchers.push_back(*Matcher);
+  return Matchers;
+}
+
+HasAdjSubstatementsMatcherType
+hasAdjSubstatementsFunc(ArrayRef<const Matcher<Stmt> *> MatcherRefs) {
+  return HasAdjSubstatementsMatcherType(vectorFromMatcherRefs(MatcherRefs));
+}
+
+template <typename T, typename ArgT>
+bool HasAdjSubstatementsMatcher<T, ArgT>::matches(
+    const T &Node, ASTMatchFinder *Finder,
+    BoundNodesTreeBuilder *Builder) const {
+  const CompoundStmt *CS = CompoundStmtMatcher<T>::get(Node);
+  if (!CS)
+    return false;
+
+  // Use llvm::search with lambda predicate that matches statements against
+  // matchers and accumulates BoundNodesTreeBuilder state
+  BoundNodesTreeBuilder CurrentBuilder;
+  const auto Found = llvm::search(
+      CS->body(), Matchers,
+      [&](const Stmt *StmtPtr, const Matcher<Stmt> &Matcher) mutable {
+        BoundNodesTreeBuilder StepBuilder;
+        StepBuilder.addMatch(CurrentBuilder);
+        if (!Matcher.matches(*StmtPtr, Finder, &StepBuilder)) {
----------------
denzor200 wrote:

Given the sample of code:
```
  struct ExtProtoInfo {
    int AArch64SMEAttributes = 0;
    int FunctionEffects = 0;
  };

  ExtProtoInfo getExtProtoInfo(ExtProtoInfo EPI) {
    EPI.AArch64SMEAttributes = 0;
    EPI.FunctionEffects = 0;
    return EPI;
  }
```

And having posted this code to clang-query, our matcher provides invalid output:
```
Match #1:

/home/d-mikhailov/ext-disk/repos/llvm-project/clang-tools-extra/clang-tidy/llvm/TwineLocalCheck.cpp:8:5:
 note: "first" binds here
    8 |     EPI.AArch64SMEAttributes = 0;
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/d-mikhailov/ext-disk/repos/llvm-project/clang-tools-extra/clang-tidy/llvm/TwineLocalCheck.cpp:7:50:
 note: "root" binds here
    7 |   ExtProtoInfo getExtProtoInfo(ExtProtoInfo EPI) {
      |                                                  ^
    8 |     EPI.AArch64SMEAttributes = 0;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    9 |     EPI.FunctionEffects = 0;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~
   10 |     return EPI;
      |     ~~~~~~~~~~~
   11 |   }
      |   ~
/home/d-mikhailov/ext-disk/repos/llvm-project/clang-tools-extra/clang-tidy/llvm/TwineLocalCheck.cpp:10:5:
 note: "second" binds here
   10 |     return EPI;
      |     ^~~~~~~~~~
1 match.
clang-query> 
```

It found `EPI.AArch64SMEAttributes = 0;` line as "first" binding, while correct 
statement for the "first" is `EPI.FunctionEffects = 0;`

https://github.com/llvm/llvm-project/pull/169965
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to