ASTMatchersInternal.cpp revision 263508
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
17namespace clang {
18namespace ast_matchers {
19namespace internal {
20
21void 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
29DynTypedMatcher::MatcherStorage::~MatcherStorage() {}
30
31void 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
37bool 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
51bool 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
68bool 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