Commit 33806cde authored by Daniel Jasper's avatar Daniel Jasper
Browse files

Fix binding of nodes in case of forEach..() matchers.

When recursively visiting the generated matches, the aggregated bindings need
to be copied during the recursion. Otherwise, we they might not be properly
overwritten (which is shown by the test), or there might be bound nodes present
that were bound on a different matching branch.

Review: http://llvm-reviews.chandlerc.com/D112
llvm-svn: 167695
parent 07351f8e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ public:
private:
  void visitMatchesRecursively(
      Visitor* ResultVistior,
      BoundNodesMap *AggregatedBindings);
      const BoundNodesMap& AggregatedBindings);

  // FIXME: Find out whether we want to use different data structures here -
  // first benchmarks indicate that it doesn't matter though.
+6 −5
Original line number Diff line number Diff line
@@ -51,19 +51,20 @@ void BoundNodesTree::copyTo(BoundNodesTreeBuilder* Builder) const {

void BoundNodesTree::visitMatches(Visitor* ResultVisitor) {
  BoundNodesMap AggregatedBindings;
  visitMatchesRecursively(ResultVisitor, &AggregatedBindings);
  visitMatchesRecursively(ResultVisitor, AggregatedBindings);
}

void BoundNodesTree::
visitMatchesRecursively(Visitor* ResultVisitor,
                        BoundNodesMap* AggregatedBindings) {
  Bindings.copyTo(AggregatedBindings);
                        const BoundNodesMap& AggregatedBindings) {
  BoundNodesMap CombinedBindings(AggregatedBindings);
  Bindings.copyTo(&CombinedBindings);
  if (RecursiveBindings.empty()) {
    ResultVisitor->visitMatch(BoundNodes(*AggregatedBindings));
    ResultVisitor->visitMatch(BoundNodes(CombinedBindings));
  } else {
    for (unsigned I = 0; I < RecursiveBindings.size(); ++I) {
      RecursiveBindings[I].visitMatchesRecursively(ResultVisitor,
                                                   AggregatedBindings);
                                                   CombinedBindings);
    }
  }
}
+11 −0
Original line number Diff line number Diff line
@@ -2775,6 +2775,17 @@ TEST(ForEachDescendant, BindsRecursiveCombinations) {
      new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
}

TEST(ForEachDescendant, BindsCorrectNodes) {
  EXPECT_TRUE(matchAndVerifyResultTrue(
      "class C { void f(); int i; };",
      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
      new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
  EXPECT_TRUE(matchAndVerifyResultTrue(
      "class C { void f() {} int i; };",
      recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
      new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
}


TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
  // Make sure that we can both match the class by name (::X) and by the type
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ public:

  virtual void run(const MatchFinder::MatchResult &Result) {
    if (FindResultReviewer != NULL) {
      *Verified = FindResultReviewer->run(&Result.Nodes, Result.Context);
      *Verified |= FindResultReviewer->run(&Result.Nodes, Result.Context);
    } else {
      *Verified = true;
    }