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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits