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 BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) { 22 if (Bindings.empty()) 23 Bindings.push_back(BoundNodesMap()); 24 for (unsigned i = 0, e = Bindings.size(); i != e; ++i) { 25 ResultVisitor->visitMatch(BoundNodes(Bindings[i])); 26 } 27 } 28 29 DynTypedMatcher::MatcherStorage::~MatcherStorage() {} 30 31 void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) { 32 for (unsigned i = 0, e = Other.Bindings.size(); i != e; ++i) { 33 Bindings.push_back(Other.Bindings[i]); 34 } 35 } 36 37 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 38 ASTMatchFinder *Finder, 39 BoundNodesTreeBuilder *Builder, 40 ArrayRef<DynTypedMatcher> InnerMatchers) { 41 // allOf leads to one matcher for each alternative in the first 42 // matcher combined with each alternative in the second matcher. 43 // Thus, we can reuse the same Builder. 44 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) { 45 if (!InnerMatchers[i].matches(DynNode, Finder, Builder)) 46 return false; 47 } 48 return true; 49 } 50 51 bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 52 ASTMatchFinder *Finder, 53 BoundNodesTreeBuilder *Builder, 54 ArrayRef<DynTypedMatcher> InnerMatchers) { 55 BoundNodesTreeBuilder Result; 56 bool Matched = false; 57 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) { 58 BoundNodesTreeBuilder BuilderInner(*Builder); 59 if (InnerMatchers[i].matches(DynNode, Finder, &BuilderInner)) { 60 Matched = true; 61 Result.addMatch(BuilderInner); 62 } 63 } 64 *Builder = Result; 65 return Matched; 66 } 67 68 bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 69 ASTMatchFinder *Finder, 70 BoundNodesTreeBuilder *Builder, 71 ArrayRef<DynTypedMatcher> InnerMatchers) { 72 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) { 73 BoundNodesTreeBuilder Result = *Builder; 74 if (InnerMatchers[i].matches(DynNode, Finder, &Result)) { 75 *Builder = Result; 76 return true; 77 } 78 } 79 return false; 80 } 81 82 } // end namespace internal 83 } // end namespace ast_matchers 84 } // end namespace clang 85