Commit 2e8dc859 authored by Stephen Kelly's avatar Stephen Kelly
Browse files

Add matchDynamic convenience functions

Summary: These correspond to the existing match() free functions.

Reviewers: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D54406
parent 31312492
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -309,6 +309,33 @@ match(MatcherT Matcher, ASTContext &Context) {
  return std::move(Callback.Nodes);
}

inline SmallVector<BoundNodes, 1>
matchDynamic(internal::DynTypedMatcher Matcher,
             const ast_type_traits::DynTypedNode &Node, ASTContext &Context) {
  internal::CollectMatchesCallback Callback;
  MatchFinder Finder;
  Finder.addDynamicMatcher(Matcher, &Callback);
  Finder.match(Node, Context);
  return std::move(Callback.Nodes);
}

template <typename NodeT>
SmallVector<BoundNodes, 1> matchDynamic(internal::DynTypedMatcher Matcher,
                                        const NodeT &Node,
                                        ASTContext &Context) {
  return matchDynamic(Matcher, ast_type_traits::DynTypedNode::create(Node),
                      Context);
}

inline SmallVector<BoundNodes, 1>
matchDynamic(internal::DynTypedMatcher Matcher, ASTContext &Context) {
  internal::CollectMatchesCallback Callback;
  MatchFinder Finder;
  Finder.addDynamicMatcher(Matcher, &Callback);
  Finder.matchAST(Context);
  return std::move(Callback.Nodes);
}

} // end namespace ast_matchers
} // end namespace clang

+24 −0
Original line number Diff line number Diff line
@@ -1827,5 +1827,29 @@ void x(int x) {
  EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher));
}

TEST(MatchFinderAPI, matchesDynamic) {

  std::string SourceCode = "struct A { void f() {} };";
  auto Matcher = functionDecl(isDefinition()).bind("method");

  auto astUnit = tooling::buildASTFromCode(SourceCode);

  auto GlobalBoundNodes = matchDynamic(Matcher, astUnit->getASTContext());

  EXPECT_EQ(GlobalBoundNodes.size(), 1u);
  EXPECT_EQ(GlobalBoundNodes[0].getMap().size(), 1u);

  auto GlobalMethodNode = GlobalBoundNodes[0].getNodeAs<FunctionDecl>("method");
  EXPECT_TRUE(GlobalMethodNode != nullptr);

  auto MethodBoundNodes =
      matchDynamic(Matcher, *GlobalMethodNode, astUnit->getASTContext());
  EXPECT_EQ(MethodBoundNodes.size(), 1u);
  EXPECT_EQ(MethodBoundNodes[0].getMap().size(), 1u);

  auto MethodNode = MethodBoundNodes[0].getNodeAs<FunctionDecl>("method");
  EXPECT_EQ(MethodNode, GlobalMethodNode);
}

} // namespace ast_matchers
} // namespace clang