]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
Merge OpenSSL 1.0.1k.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / ASTMatchers / ASTMatchersInternal.cpp
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 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
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))
66       return false;
67   }
68   return true;
69 }
70
71 bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
72                             ASTMatchFinder *Finder,
73                             BoundNodesTreeBuilder *Builder,
74                             ArrayRef<DynTypedMatcher> InnerMatchers) {
75   BoundNodesTreeBuilder Result;
76   bool Matched = false;
77   for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
78     BoundNodesTreeBuilder BuilderInner(*Builder);
79     if (InnerMatchers[i].matches(DynNode, Finder, &BuilderInner)) {
80       Matched = true;
81       Result.addMatch(BuilderInner);
82     }
83   }
84   *Builder = Result;
85   return Matched;
86 }
87
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)) {
95       *Builder = Result;
96       return true;
97     }
98   }
99   return false;
100 }
101
102 } // end namespace internal
103 } // end namespace ast_matchers
104 } // end namespace clang