Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 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 | |
| 17 | namespace clang { |
| 18 | namespace ast_matchers { |
| 19 | namespace internal { |
| 20 | |
| 21 | BoundNodesTree::BoundNodesTree() {} |
| 22 | |
| 23 | BoundNodesTree::BoundNodesTree( |
Daniel Jasper | e0e6b9e | 2012-07-10 20:20:19 +0000 | [diff] [blame] | 24 | const std::map<std::string, const Decl*>& DeclBindings, |
| 25 | const std::map<std::string, const Stmt*>& StmtBindings, |
Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 26 | const std::vector<BoundNodesTree> RecursiveBindings) |
| 27 | : DeclBindings(DeclBindings), StmtBindings(StmtBindings), |
| 28 | RecursiveBindings(RecursiveBindings) {} |
| 29 | |
| 30 | void BoundNodesTree::copyTo(BoundNodesTreeBuilder* Builder) const { |
| 31 | copyBindingsTo(DeclBindings, Builder); |
| 32 | copyBindingsTo(StmtBindings, Builder); |
| 33 | for (std::vector<BoundNodesTree>::const_iterator |
| 34 | I = RecursiveBindings.begin(), |
| 35 | E = RecursiveBindings.end(); |
| 36 | I != E; ++I) { |
| 37 | Builder->addMatch(*I); |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | template <typename T> |
| 42 | void BoundNodesTree::copyBindingsTo( |
| 43 | const T& Bindings, BoundNodesTreeBuilder* Builder) const { |
| 44 | for (typename T::const_iterator I = Bindings.begin(), |
| 45 | E = Bindings.end(); |
| 46 | I != E; ++I) { |
Daniel Jasper | e0e6b9e | 2012-07-10 20:20:19 +0000 | [diff] [blame] | 47 | Builder->setBinding(I->first, I->second); |
Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 48 | } |
| 49 | } |
| 50 | |
| 51 | void BoundNodesTree::visitMatches(Visitor* ResultVisitor) { |
Daniel Jasper | e0e6b9e | 2012-07-10 20:20:19 +0000 | [diff] [blame] | 52 | std::map<std::string, const Decl*> AggregatedDeclBindings; |
| 53 | std::map<std::string, const Stmt*> AggregatedStmtBindings; |
Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 54 | visitMatchesRecursively(ResultVisitor, AggregatedDeclBindings, |
| 55 | AggregatedStmtBindings); |
| 56 | } |
| 57 | |
| 58 | void BoundNodesTree:: |
| 59 | visitMatchesRecursively(Visitor* ResultVisitor, |
Daniel Jasper | e0e6b9e | 2012-07-10 20:20:19 +0000 | [diff] [blame] | 60 | std::map<std::string, const Decl*> |
Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 61 | AggregatedDeclBindings, |
Daniel Jasper | e0e6b9e | 2012-07-10 20:20:19 +0000 | [diff] [blame] | 62 | std::map<std::string, const Stmt*> |
Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 63 | AggregatedStmtBindings) { |
| 64 | copy(DeclBindings.begin(), DeclBindings.end(), |
| 65 | inserter(AggregatedDeclBindings, AggregatedDeclBindings.begin())); |
| 66 | copy(StmtBindings.begin(), StmtBindings.end(), |
| 67 | inserter(AggregatedStmtBindings, AggregatedStmtBindings.begin())); |
| 68 | if (RecursiveBindings.empty()) { |
| 69 | ResultVisitor->visitMatch(BoundNodes(AggregatedDeclBindings, |
| 70 | AggregatedStmtBindings)); |
| 71 | } else { |
| 72 | for (unsigned I = 0; I < RecursiveBindings.size(); ++I) { |
| 73 | RecursiveBindings[I].visitMatchesRecursively(ResultVisitor, |
| 74 | AggregatedDeclBindings, |
| 75 | AggregatedStmtBindings); |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | BoundNodesTreeBuilder::BoundNodesTreeBuilder() {} |
| 81 | |
Daniel Jasper | e0e6b9e | 2012-07-10 20:20:19 +0000 | [diff] [blame] | 82 | void BoundNodesTreeBuilder::setBinding(const std::string &Id, |
| 83 | const Decl *Node) { |
| 84 | DeclBindings[Id] = Node; |
Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 85 | } |
| 86 | |
Daniel Jasper | e0e6b9e | 2012-07-10 20:20:19 +0000 | [diff] [blame] | 87 | void BoundNodesTreeBuilder::setBinding(const std::string &Id, |
| 88 | const Stmt *Node) { |
| 89 | StmtBindings[Id] = Node; |
Manuel Klimek | 4da2166 | 2012-07-06 05:48:52 +0000 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | void BoundNodesTreeBuilder::addMatch(const BoundNodesTree& Bindings) { |
| 93 | RecursiveBindings.push_back(Bindings); |
| 94 | } |
| 95 | |
| 96 | BoundNodesTree BoundNodesTreeBuilder::build() const { |
| 97 | return BoundNodesTree(DeclBindings, StmtBindings, RecursiveBindings); |
| 98 | } |
| 99 | |
| 100 | } // end namespace internal |
| 101 | } // end namespace ast_matchers |
| 102 | } // end namespace clang |