Home | History | Annotate | Download | only in ASTMatchers
      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