blob: f1a9ff2e09cb87c67b42b70f2bcdbdfd999d9e33 [file] [log] [blame]
Manuel Klimek04616e42012-07-06 05:48:52 +00001//===--- 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
Manuel Klimek021d56f2012-08-28 23:26:39 +000021void BoundNodesMap::copyTo(BoundNodesTreeBuilder *Builder) const {
22 for (IDToNodeMap::const_iterator It = NodeMap.begin();
23 It != NodeMap.end();
24 ++It) {
Manuel Klimekfdf98762012-08-30 19:41:06 +000025 Builder->setBinding(It->first, It->second);
Manuel Klimek021d56f2012-08-28 23:26:39 +000026 }
27}
28
29void BoundNodesMap::copyTo(BoundNodesMap *Other) const {
Daniel Jasper94a56852012-11-16 18:39:22 +000030 for (IDToNodeMap::const_iterator I = NodeMap.begin(),
31 E = NodeMap.end();
32 I != E; ++I) {
33 Other->NodeMap[I->first] = I->second;
34 }
Manuel Klimek021d56f2012-08-28 23:26:39 +000035}
36
Manuel Klimek04616e42012-07-06 05:48:52 +000037BoundNodesTree::BoundNodesTree() {}
38
39BoundNodesTree::BoundNodesTree(
Manuel Klimek021d56f2012-08-28 23:26:39 +000040 const BoundNodesMap& Bindings,
Manuel Klimek04616e42012-07-06 05:48:52 +000041 const std::vector<BoundNodesTree> RecursiveBindings)
Manuel Klimek021d56f2012-08-28 23:26:39 +000042 : Bindings(Bindings),
Manuel Klimek04616e42012-07-06 05:48:52 +000043 RecursiveBindings(RecursiveBindings) {}
44
45void BoundNodesTree::copyTo(BoundNodesTreeBuilder* Builder) const {
Manuel Klimek021d56f2012-08-28 23:26:39 +000046 Bindings.copyTo(Builder);
Manuel Klimek04616e42012-07-06 05:48:52 +000047 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
Manuel Klimek04616e42012-07-06 05:48:52 +000055void BoundNodesTree::visitMatches(Visitor* ResultVisitor) {
Manuel Klimek021d56f2012-08-28 23:26:39 +000056 BoundNodesMap AggregatedBindings;
Daniel Jasper33806cd2012-11-11 22:14:55 +000057 visitMatchesRecursively(ResultVisitor, AggregatedBindings);
Manuel Klimek04616e42012-07-06 05:48:52 +000058}
59
60void BoundNodesTree::
61visitMatchesRecursively(Visitor* ResultVisitor,
Daniel Jasper33806cd2012-11-11 22:14:55 +000062 const BoundNodesMap& AggregatedBindings) {
63 BoundNodesMap CombinedBindings(AggregatedBindings);
64 Bindings.copyTo(&CombinedBindings);
Manuel Klimek04616e42012-07-06 05:48:52 +000065 if (RecursiveBindings.empty()) {
Daniel Jasper33806cd2012-11-11 22:14:55 +000066 ResultVisitor->visitMatch(BoundNodes(CombinedBindings));
Manuel Klimek04616e42012-07-06 05:48:52 +000067 } else {
68 for (unsigned I = 0; I < RecursiveBindings.size(); ++I) {
69 RecursiveBindings[I].visitMatchesRecursively(ResultVisitor,
Daniel Jasper33806cd2012-11-11 22:14:55 +000070 CombinedBindings);
Manuel Klimek04616e42012-07-06 05:48:52 +000071 }
72 }
73}
74
75BoundNodesTreeBuilder::BoundNodesTreeBuilder() {}
76
Manuel Klimek04616e42012-07-06 05:48:52 +000077void BoundNodesTreeBuilder::addMatch(const BoundNodesTree& Bindings) {
78 RecursiveBindings.push_back(Bindings);
79}
80
81BoundNodesTree BoundNodesTreeBuilder::build() const {
Manuel Klimek021d56f2012-08-28 23:26:39 +000082 return BoundNodesTree(Bindings, RecursiveBindings);
Manuel Klimek04616e42012-07-06 05:48:52 +000083}
84
85} // end namespace internal
86} // end namespace ast_matchers
87} // end namespace clang