blob: 47b8b6d2f27a61b689e48d9000763965ae58f8f8 [file] [log] [blame]
Manuel Klimek04616e42012-07-06 05:48:52 +00001//===--- 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
Manuel Klimeka0c025f2013-06-19 15:42:45 +000021void 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]));
Manuel Klimek021d56f2012-08-28 23:26:39 +000026 }
27}
28
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000029DynTypedMatcher::MatcherStorage::~MatcherStorage() {}
30
Manuel Klimeka0c025f2013-06-19 15:42:45 +000031void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
32 for (unsigned i = 0, e = Other.Bindings.size(); i != e; ++i) {
33 Bindings.push_back(Other.Bindings[i]);
Daniel Jasper94a56852012-11-16 18:39:22 +000034 }
Manuel Klimek021d56f2012-08-28 23:26:39 +000035}
36
Samuel Benzaquen4d058742013-11-22 14:41:48 +000037bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
38 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
39 ArrayRef<DynTypedMatcher> InnerMatchers) {
40 if (InnerMatchers.size() != 1)
41 return false;
42
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);
55}
56
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +000057bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
58 ASTMatchFinder *Finder,
59 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000060 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +000061 // 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) {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000065 if (!InnerMatchers[i].matches(DynNode, Finder, Builder))
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +000066 return false;
67 }
68 return true;
69}
70
71bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
72 ASTMatchFinder *Finder,
73 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000074 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +000075 BoundNodesTreeBuilder Result;
76 bool Matched = false;
77 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
78 BoundNodesTreeBuilder BuilderInner(*Builder);
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000079 if (InnerMatchers[i].matches(DynNode, Finder, &BuilderInner)) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +000080 Matched = true;
81 Result.addMatch(BuilderInner);
82 }
83 }
84 *Builder = Result;
85 return Matched;
86}
87
88bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
89 ASTMatchFinder *Finder,
90 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000091 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +000092 for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
93 BoundNodesTreeBuilder Result = *Builder;
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +000094 if (InnerMatchers[i].matches(DynNode, Finder, &Result)) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +000095 *Builder = Result;
96 return true;
97 }
98 }
99 return false;
100}
101
Manuel Klimek04616e42012-07-06 05:48:52 +0000102} // end namespace internal
103} // end namespace ast_matchers
104} // end namespace clang