This revision was automatically updated to reflect the committed changes. ymandel marked an inline comment as done. Closed by commit rG04a96aa3e430: [ASTMatchers] Add traversal-kind support to `DynTypedMatcher` (authored by ymandel).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D80685/new/ https://reviews.llvm.org/D80685 Files: clang/include/clang/ASTMatchers/ASTMatchersInternal.h clang/lib/ASTMatchers/ASTMatchersInternal.cpp clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp clang/unittests/ASTMatchers/CMakeLists.txt
Index: clang/unittests/ASTMatchers/CMakeLists.txt =================================================================== --- clang/unittests/ASTMatchers/CMakeLists.txt +++ clang/unittests/ASTMatchers/CMakeLists.txt @@ -30,4 +30,9 @@ clangTooling ) +target_link_libraries(ASTMatchersTests + PRIVATE + LLVMTestingSupport +) + add_subdirectory(Dynamic) Index: clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp @@ -13,10 +13,12 @@ #include "clang/Tooling/Tooling.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Host.h" +#include "llvm/Testing/Support/SupportHelpers.h" #include "gtest/gtest.h" namespace clang { namespace ast_matchers { +using internal::DynTypedMatcher; #if GTEST_HAS_DEATH_TEST TEST(HasNameDeathTest, DiesOnEmptyName) { @@ -171,6 +173,26 @@ EXPECT_NE(nullptr, PT); } +TEST(DynTypedMatcherTest, TraversalKindForwardsToImpl) { + auto M = DynTypedMatcher(decl()); + EXPECT_FALSE(M.getTraversalKind().hasValue()); + + M = DynTypedMatcher(traverse(TK_AsIs, decl())); + EXPECT_THAT(M.getTraversalKind(), llvm::ValueIs(TK_AsIs)); +} + +TEST(DynTypedMatcherTest, ConstructWithTraversalKindSetsTK) { + auto M = DynTypedMatcher(decl()).withTraversalKind(TK_AsIs); + EXPECT_THAT(M.getTraversalKind(), llvm::ValueIs(TK_AsIs)); +} + +TEST(DynTypedMatcherTest, ConstructWithTraversalKindOverridesNestedTK) { + auto M = DynTypedMatcher(decl()).withTraversalKind(TK_AsIs).withTraversalKind( + TK_IgnoreUnlessSpelledInSource); + EXPECT_THAT(M.getTraversalKind(), + llvm::ValueIs(TK_IgnoreUnlessSpelledInSource)); +} + TEST(IsInlineMatcher, IsInline) { EXPECT_TRUE(matches("void g(); inline void f();", functionDecl(isInline(), hasName("f")))); Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp =================================================================== --- clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -136,6 +136,31 @@ } }; +/// A matcher that specifies a particular \c TraversalKind. +/// +/// The kind provided to the constructor overrides any kind that may be +/// specified by the `InnerMatcher`. +class DynTraversalMatcherImpl : public DynMatcherInterface { +public: + explicit DynTraversalMatcherImpl( + clang::TraversalKind TK, + IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher) + : TK(TK), InnerMatcher(std::move(InnerMatcher)) {} + + bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const override { + return this->InnerMatcher->dynMatches(DynNode, Finder, Builder); + } + + llvm::Optional<clang::TraversalKind> TraversalKind() const override { + return TK; + } + +private: + clang::TraversalKind TK; + IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher; +}; + } // namespace static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance; @@ -204,6 +229,14 @@ return Copy; } +DynTypedMatcher +DynTypedMatcher::withTraversalKind(ast_type_traits::TraversalKind TK) { + auto Copy = *this; + Copy.Implementation = + new DynTraversalMatcherImpl(TK, std::move(Copy.Implementation)); + return Copy; +} + DynTypedMatcher DynTypedMatcher::trueMatcher(ASTNodeKind NodeKind) { return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance); } Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -395,6 +395,12 @@ /// restricts the node types for \p Kind. DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const; + /// Return a matcher that that points to the same implementation, but sets the + /// traversal kind. + /// + /// If the traversal kind is already set, then \c TK overrides it. + DynTypedMatcher withTraversalKind(TraversalKind TK); + /// Returns true if the matcher matches the given \c DynNode. bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const; @@ -458,6 +464,14 @@ /// If it is not compatible, then this matcher will never match anything. template <typename T> Matcher<T> unconditionalConvertTo() const; + /// Returns the \c TraversalKind respected by calls to `match()`, if any. + /// + /// Most matchers will not have a traversal kind set, instead relying on the + /// surrounding context. For those, \c llvm::None is returned. + llvm::Optional<clang::TraversalKind> getTraversalKind() const { + return Implementation->TraversalKind(); + } + private: DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind, IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits