[PATCH] D80654: WIP: Make it possible to use the traverse() matcher in clang-query

2020-05-27 Thread Stephen Kelly via Phabricator via cfe-commits
steveire marked an inline comment as done.
steveire added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:383
+  static DynTypedMatcher
+  constructTraversalWrapper(const DynTypedMatcher ,
+ast_type_traits::TraversalKind TK);

ymandel wrote:
> I need this for my fix to Transformer. In fact, this is the only thing I 
> need, rather than an overload of `traverse` for `DynTypedMatcher`.  Do you 
> want me to split this into its own patch and send to you? Or, vice versa?
> 
> Also, whay `const DynTypedMatcher `? Given that it is 
> immediately copied, why not just `DynTypedMatcher InnerMatcher`, which at 
> least allows the caller to move-construct the argument and avoid the copy?
Yes, if you could split what ever you need out and incorporate it into your 
work I think that would be useful. 

I can rebase the rest of this once your fix is in.



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80654/new/

https://reviews.llvm.org/D80654



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80654: WIP: Make it possible to use the traverse() matcher in clang-query

2020-05-27 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel added a comment.

Thanks, this looks quite useful. I should be able to look it over in full 
tomorrow.




Comment at: clang/include/clang/ASTMatchers/ASTMatchersInternal.h:383
+  static DynTypedMatcher
+  constructTraversalWrapper(const DynTypedMatcher ,
+ast_type_traits::TraversalKind TK);

I need this for my fix to Transformer. In fact, this is the only thing I need, 
rather than an overload of `traverse` for `DynTypedMatcher`.  Do you want me to 
split this into its own patch and send to you? Or, vice versa?

Also, whay `const DynTypedMatcher `? Given that it is immediately 
copied, why not just `DynTypedMatcher InnerMatcher`, which at least allows the 
caller to move-construct the argument and avoid the copy?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80654/new/

https://reviews.llvm.org/D80654



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80654: WIP: Make it possible to use the traverse() matcher in clang-query

2020-05-27 Thread Stephen Kelly via Phabricator via cfe-commits
steveire added a comment.

This is not ready for review, but is it a direction we want to go, given that 
we can already use

  set traversal 

in clang-query?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80654/new/

https://reviews.llvm.org/D80654



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80654: WIP: Make it possible to use the traverse() matcher in clang-query

2020-05-27 Thread Stephen Kelly via Phabricator via cfe-commits
steveire created this revision.
steveire added a reviewer: ymandel.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D80654

Files:
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
  clang/lib/ASTMatchers/ASTMatchersInternal.cpp
  clang/lib/ASTMatchers/Dynamic/Marshallers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
  clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp

Index: clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===
--- clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -505,6 +505,25 @@
   EXPECT_FALSE(matches("struct X {};", Value));
 }
 
+TEST_F(RegistryTest, Traverse) {
+  EXPECT_TRUE(
+  matches(R"cpp(
+int foo()
+{
+double d = 0;
+return d;
+}
+)cpp",
+  constructMatcher(
+  "returnStmt",
+  constructMatcher(
+  "hasReturnValue",
+  constructMatcher("traverse",
+   StringRef("IgnoreUnlessSpelledInSource"),
+   constructMatcher("declRefExpr"
+  .getTypedMatcher()));
+}
+
 TEST_F(RegistryTest, ParenExpr) {
   Matcher Value = constructMatcher("parenExpr").getTypedMatcher();
   EXPECT_TRUE(
Index: clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
===
--- clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -80,6 +80,44 @@
 
 VariantMatcher::Payload::~Payload() {}
 
+class VariantMatcher::TraversalPayload : public VariantMatcher::Payload {
+public:
+  TraversalPayload(ast_type_traits::TraversalKind TK,
+   const DynTypedMatcher )
+  : TK(TK), Matcher(Matcher) {}
+
+  llvm::Optional getSingleMatcher() const override {
+return Matcher;
+  }
+
+  std::string getTypeAsString() const override {
+return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
+.str();
+  }
+
+  llvm::Optional
+  getTypedMatcher(const MatcherOps ) const override {
+// llvm::errs() << "TraversalCode" << "\n";
+// std::terminate();
+
+bool Ignore;
+if (Ops.canConstructFrom(Matcher, Ignore)) {
+  return DynTypedMatcher::constructTraversalWrapper(Matcher, TK);
+}
+return llvm::None;
+  }
+
+  bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
+   unsigned *Specificity) const override {
+return ArgKind(Matcher.getSupportedKind())
+.isConvertibleTo(Kind, Specificity);
+  }
+
+private:
+  ast_type_traits::TraversalKind TK;
+  const DynTypedMatcher Matcher;
+};
+
 class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
 public:
   SinglePayload(const DynTypedMatcher ) : Matcher(Matcher) {}
@@ -219,6 +257,12 @@
   return VariantMatcher(std::make_shared(Matcher));
 }
 
+VariantMatcher
+VariantMatcher::TraversalMatcher(ast_type_traits::TraversalKind TK,
+ const DynTypedMatcher ) {
+  return VariantMatcher(std::make_shared(TK, Matcher));
+}
+
 VariantMatcher
 VariantMatcher::PolymorphicMatcher(std::vector Matchers) {
   return VariantMatcher(
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -101,6 +101,9 @@
   // Other:
   // equalsNode
 
+  registerMatcher("traverse",
+  std::make_unique());
+
   REGISTER_OVERLOADED_2(callee);
   REGISTER_OVERLOADED_2(hasAnyCapture);
   REGISTER_OVERLOADED_2(hasPrefix);
Index: clang/lib/ASTMatchers/Dynamic/Marshallers.h
===
--- clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -244,6 +244,31 @@
   static llvm::Optional getBestGuess(const VariantValue );
 };
 
+template <> struct ArgTypeTraits {
+private:
+  static Optional
+  getTraversalKind(llvm::StringRef TK) {
+return llvm::StringSwitch>(TK)
+.Case("TK::AsIs", ast_type_traits::TK_AsIs)
+.Case("TK::IgnoreUnlessSpelledInSource",
+  ast_type_traits::TK_IgnoreUnlessSpelledInSource)
+.Case("TK::IgnoreImplicitCastsAndParentheses",
+  ast_type_traits::TK_IgnoreImplicitCastsAndParentheses)
+.Default(llvm::None);
+  }
+
+public:
+  static bool is(const VariantValue ) {
+return Value.isString() && getTraversalKind(Value.getString());
+  }
+
+  static ast_type_traits::TraversalKind get(const VariantValue ) {
+return *getTraversalKind(Value.getString());
+  }
+
+  static ArgKind getKind() { return