This revision was automatically updated to reflect the committed changes.
Closed by commit rG69bb99914f35: Implement additional traverse() overloads 
(authored by stephenkelly).

Changed prior to commit:
  https://reviews.llvm.org/D71977?vs=235520&id=235719#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71977

Files:
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1612,6 +1612,92 @@
       matches(VarDeclCode,
               traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
                        Matcher)));
+
+  EXPECT_TRUE(
+      matches(VarDeclCode, decl(traverse(ast_type_traits::TK_AsIs,
+                                         anyOf(cxxRecordDecl(), varDecl())))));
+
+  EXPECT_TRUE(matches(VarDeclCode,
+                      floatLiteral(traverse(ast_type_traits::TK_AsIs,
+                                            hasParent(implicitCastExpr())))));
+
+  EXPECT_TRUE(matches(
+      VarDeclCode,
+      floatLiteral(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                            hasParent(varDecl())))));
+
+  EXPECT_TRUE(
+      matches(VarDeclCode,
+              varDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                               unless(parmVarDecl())))));
+
+  EXPECT_TRUE(notMatches(
+      VarDeclCode,
+      varDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                       has(implicitCastExpr())))));
+
+  EXPECT_TRUE(matches(VarDeclCode, varDecl(traverse(ast_type_traits::TK_AsIs,
+                                                    has(implicitCastExpr())))));
+
+  EXPECT_TRUE(notMatches(
+      VarDeclCode,
+      varDecl(has(traverse(ast_type_traits::TK_AsIs, floatLiteral())))));
+
+  EXPECT_TRUE(matches(
+      VarDeclCode,
+      functionDecl(traverse(ast_type_traits::TK_AsIs, hasName("foo")))));
+
+  EXPECT_TRUE(matches(
+      VarDeclCode,
+      functionDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                            hasName("foo")))));
+
+  EXPECT_TRUE(
+      matches(VarDeclCode, functionDecl(traverse(ast_type_traits::TK_AsIs,
+                                                 hasAnyName("foo", "bar")))));
+
+  EXPECT_TRUE(matches(
+      VarDeclCode,
+      functionDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                            hasAnyName("foo", "bar")))));
+
+  EXPECT_TRUE(
+      matches(R"cpp(
+void foo(int a)
+{
+  int i = 3.0 + a;
+}
+void bar()
+{
+  foo(7.0);
+}
+)cpp",
+              callExpr(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                                hasArgument(0, floatLiteral())))));
+
+  EXPECT_TRUE(
+      matches(R"cpp(
+void foo(int a)
+{
+  int i = 3.0 + a;
+}
+void bar()
+{
+  foo(7.0);
+}
+)cpp",
+              callExpr(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                                hasAnyArgument(floatLiteral())))));
+
+  EXPECT_TRUE(
+      matches(VarDeclCode,
+              varDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                               hasType(builtinType())))));
+
+  EXPECT_TRUE(matches(
+      VarDeclCode,
+      functionDecl(hasName("foo"), traverse(ast_type_traits::TK_AsIs,
+                                            hasDescendant(floatLiteral())))));
 }
 
 TEST(Traversal, traverseMatcherNesting) {
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1199,6 +1199,24 @@
   }
 };
 
+template <typename MatcherType> class TraversalWrapper {
+public:
+  TraversalWrapper(ast_type_traits::TraversalKind TK,
+                   const MatcherType &InnerMatcher)
+      : TK(TK), InnerMatcher(InnerMatcher) {}
+
+  template <typename T> operator Matcher<T>() const {
+    return internal::DynTypedMatcher::constructRestrictedWrapper(
+               new internal::TraversalMatcher<T>(TK, InnerMatcher),
+               ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
+        .template unconditionalConvertTo<T>();
+  }
+
+private:
+  ast_type_traits::TraversalKind TK;
+  MatcherType InnerMatcher;
+};
+
 /// A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
 /// created from N parameters p1, ..., pN (of type P1, ..., PN) and
 /// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -714,6 +714,52 @@
       .template unconditionalConvertTo<T>();
 }
 
+template <typename... T>
+internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>
+traverse(ast_type_traits::TraversalKind TK,
+         const internal::VariadicOperatorMatcher<T...> &InnerMatcher) {
+  return internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>(
+      TK, InnerMatcher);
+}
+
+template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
+          typename T, typename ToTypes>
+internal::TraversalWrapper<
+    internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>>
+traverse(ast_type_traits::TraversalKind TK,
+         const internal::ArgumentAdaptingMatcherFuncAdaptor<
+             ArgumentAdapterT, T, ToTypes> &InnerMatcher) {
+  return internal::TraversalWrapper<
+      internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T,
+                                                   ToTypes>>(TK, InnerMatcher);
+}
+
+template <template <typename T, typename P1> class MatcherT, typename P1,
+          typename ReturnTypesF>
+internal::TraversalWrapper<
+    internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>
+traverse(
+    ast_type_traits::TraversalKind TK,
+    const internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>
+        &InnerMatcher) {
+  return internal::TraversalWrapper<
+      internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>(
+      TK, InnerMatcher);
+}
+
+template <template <typename T, typename P1, typename P2> class MatcherT,
+          typename P1, typename P2, typename ReturnTypesF>
+internal::TraversalWrapper<
+    internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>
+traverse(
+    ast_type_traits::TraversalKind TK,
+    const internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>
+        &InnerMatcher) {
+  return internal::TraversalWrapper<
+      internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>(
+      TK, InnerMatcher);
+}
+
 /// Matches expressions that match InnerMatcher after any implicit AST
 /// nodes are stripped off.
 ///
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to