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 void 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 29 void 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 37 BoundNodesTree::BoundNodesTree() {} 38 39 BoundNodesTree::BoundNodesTree( 40 const BoundNodesMap& Bindings, 41 const std::vector<BoundNodesTree> RecursiveBindings) 42 : Bindings(Bindings), 43 RecursiveBindings(RecursiveBindings) {} 44 45 void 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 55 void BoundNodesTree::visitMatches(Visitor* ResultVisitor) { 56 BoundNodesMap AggregatedBindings; 57 visitMatchesRecursively(ResultVisitor, AggregatedBindings); 58 } 59 60 void BoundNodesTree:: 61 visitMatchesRecursively(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 75 BoundNodesTreeBuilder::BoundNodesTreeBuilder() {} 76 77 void BoundNodesTreeBuilder::addMatch(const BoundNodesTree& Bindings) { 78 RecursiveBindings.push_back(Bindings); 79 } 80 81 BoundNodesTree BoundNodesTreeBuilder::build() const { 82 return BoundNodesTree(Bindings, RecursiveBindings); 83 } 84 85 } // end namespace internal 86 } // end namespace ast_matchers 87 } // end namespace clang 88