1//===--- ASTMatchersInternal.cpp - Structural query framework -------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  Implements the base layer of the matcher framework.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/ASTMatchers/ASTMatchers.h"
15#include "clang/ASTMatchers/ASTMatchersInternal.h"
16
17namespace clang {
18namespace ast_matchers {
19namespace internal {
20
21void BoundNodesMap::copyTo(BoundNodesTreeBuilder *Builder) const {
22  for (IDToNodeMap::const_iterator It = NodeMap.begin();
23       It != NodeMap.end();
24       ++It) {
25    Builder->setBinding(It->first, It->second);
26  }
27}
28
29void BoundNodesMap::copyTo(BoundNodesMap *Other) const {
30  for (IDToNodeMap::const_iterator I = NodeMap.begin(),
31                                   E = NodeMap.end();
32       I != E; ++I) {
33    Other->NodeMap[I->first] = I->second;
34  }
35}
36
37BoundNodesTree::BoundNodesTree() {}
38
39BoundNodesTree::BoundNodesTree(
40  const BoundNodesMap& Bindings,
41  const std::vector<BoundNodesTree> RecursiveBindings)
42  : Bindings(Bindings),
43    RecursiveBindings(RecursiveBindings) {}
44
45void BoundNodesTree::copyTo(BoundNodesTreeBuilder* Builder) const {
46  Bindings.copyTo(Builder);
47  for (std::vector<BoundNodesTree>::const_iterator
48         I = RecursiveBindings.begin(),
49         E = RecursiveBindings.end();
50       I != E; ++I) {
51    Builder->addMatch(*I);
52  }
53}
54
55void BoundNodesTree::visitMatches(Visitor* ResultVisitor) {
56  BoundNodesMap AggregatedBindings;
57  visitMatchesRecursively(ResultVisitor, AggregatedBindings);
58}
59
60void BoundNodesTree::
61visitMatchesRecursively(Visitor* ResultVisitor,
62                        const BoundNodesMap& AggregatedBindings) {
63  BoundNodesMap CombinedBindings(AggregatedBindings);
64  Bindings.copyTo(&CombinedBindings);
65  if (RecursiveBindings.empty()) {
66    ResultVisitor->visitMatch(BoundNodes(CombinedBindings));
67  } else {
68    for (unsigned I = 0; I < RecursiveBindings.size(); ++I) {
69      RecursiveBindings[I].visitMatchesRecursively(ResultVisitor,
70                                                   CombinedBindings);
71    }
72  }
73}
74
75BoundNodesTreeBuilder::BoundNodesTreeBuilder() {}
76
77void BoundNodesTreeBuilder::addMatch(const BoundNodesTree& Bindings) {
78  RecursiveBindings.push_back(Bindings);
79}
80
81BoundNodesTree BoundNodesTreeBuilder::build() const {
82  return BoundNodesTree(Bindings, RecursiveBindings);
83}
84
85} // end namespace internal
86} // end namespace ast_matchers
87} // end namespace clang
88