1 //===--- ASTMatchersInternal.cpp - Structural query framework -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Implements the base layer of the matcher framework.
12 //===----------------------------------------------------------------------===//
14 #include "clang/ASTMatchers/ASTMatchers.h"
15 #include "clang/ASTMatchers/ASTMatchersInternal.h"
18 namespace ast_matchers {
21 void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
23 Bindings.push_back(BoundNodesMap());
24 for (unsigned i = 0, e = Bindings.size(); i != e; ++i) {
25 ResultVisitor->visitMatch(BoundNodes(Bindings[i]));
29 DynTypedMatcher::MatcherStorage::~MatcherStorage() {}
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]);
37 bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
38 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
39 ArrayRef<DynTypedMatcher> InnerMatchers) {
40 if (InnerMatchers.size() != 1)
43 // The 'unless' matcher will always discard the result:
44 // If the inner matcher doesn't match, unless returns true,
45 // but the inner matcher cannot have bound anything.
46 // If the inner matcher matches, the result is false, and
47 // any possible binding will be discarded.
48 // We still need to hand in all the bound nodes up to this
49 // point so the inner matcher can depend on bound nodes,
50 // and we need to actively discard the bound nodes, otherwise
51 // the inner matcher will reset the bound nodes if it doesn't
52 // match, but this would be inversed by 'unless'.
53 BoundNodesTreeBuilder Discard(*Builder);
54 return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
57 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
58 ASTMatchFinder *Finder,
59 BoundNodesTreeBuilder *Builder,
60 ArrayRef<DynTypedMatcher> InnerMatchers) {
61 // allOf leads to one matcher for each alternative in the first
62 // matcher combined with each alternative in the second matcher.
63 // Thus, we can reuse the same Builder.
64 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
65 if (!InnerMatchers[i].matches(DynNode, Finder, Builder))
71 bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
72 ASTMatchFinder *Finder,
73 BoundNodesTreeBuilder *Builder,
74 ArrayRef<DynTypedMatcher> InnerMatchers) {
75 BoundNodesTreeBuilder Result;
77 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
78 BoundNodesTreeBuilder BuilderInner(*Builder);
79 if (InnerMatchers[i].matches(DynNode, Finder, &BuilderInner)) {
81 Result.addMatch(BuilderInner);
88 bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
89 ASTMatchFinder *Finder,
90 BoundNodesTreeBuilder *Builder,
91 ArrayRef<DynTypedMatcher> InnerMatchers) {
92 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
93 BoundNodesTreeBuilder Result = *Builder;
94 if (InnerMatchers[i].matches(DynNode, Finder, &Result)) {
102 } // end namespace internal
103 } // end namespace ast_matchers
104 } // end namespace clang