@@ -93,13 +93,25 @@ class VariantMatcher {
93
93
// / \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
94
94
class MatcherOps {
95
95
public:
96
- virtual ~MatcherOps ();
97
- virtual bool canConstructFrom (const DynTypedMatcher &Matcher,
98
- bool &IsExactMatch) const = 0;
99
- virtual void constructFrom (const DynTypedMatcher &Matcher) = 0;
100
- virtual void constructVariadicOperator (
96
+ MatcherOps (ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
97
+
98
+ bool canConstructFrom (const DynTypedMatcher &Matcher,
99
+ bool &IsExactMatch) const ;
100
+
101
+ // / \brief Convert \p Matcher the destination type and return it as a new
102
+ // / DynTypedMatcher.
103
+ virtual DynTypedMatcher
104
+ convertMatcher (const DynTypedMatcher &Matcher) const = 0 ;
105
+
106
+ // / \brief Constructs a variadic typed matcher from \p InnerMatchers.
107
+ // / Will try to convert each inner matcher to the destination type and
108
+ // / return llvm::None if it fails to do so.
109
+ llvm::Optional<DynTypedMatcher> constructVariadicOperator (
101
110
ast_matchers::internal::VariadicOperatorFunction Func,
102
- ArrayRef<VariantMatcher> InnerMatchers) = 0;
111
+ ArrayRef<VariantMatcher> InnerMatchers) const ;
112
+
113
+ private:
114
+ ast_type_traits::ASTNodeKind NodeKind;
103
115
};
104
116
105
117
// / \brief Payload interface to be specialized by each matcher type.
@@ -110,7 +122,8 @@ class VariantMatcher {
110
122
virtual ~Payload ();
111
123
virtual llvm::Optional<DynTypedMatcher> getSingleMatcher () const = 0;
112
124
virtual std::string getTypeAsString () const = 0;
113
- virtual void makeTypedMatcher (MatcherOps &Ops) const = 0;
125
+ virtual llvm::Optional<DynTypedMatcher>
126
+ getTypedMatcher (const MatcherOps &Ops) const = 0 ;
114
127
virtual bool isConvertibleTo (ast_type_traits::ASTNodeKind Kind,
115
128
unsigned *Specificity) const = 0;
116
129
};
@@ -158,9 +171,8 @@ class VariantMatcher {
158
171
// / that can, the result would be ambiguous and false is returned.
159
172
template <class T >
160
173
bool hasTypedMatcher () const {
161
- TypedMatcherOps<T> Ops;
162
- if (Value) Value->makeTypedMatcher (Ops);
163
- return Ops.hasMatcher ();
174
+ if (!Value) return false ;
175
+ return Value->getTypedMatcher (TypedMatcherOps<T>()).hasValue ();
164
176
}
165
177
166
178
// / \brief Determines if the contained matcher can be converted to \p Kind.
@@ -182,10 +194,9 @@ class VariantMatcher {
182
194
// / Asserts that \c hasTypedMatcher<T>() is true.
183
195
template <class T >
184
196
ast_matchers::internal::Matcher<T> getTypedMatcher () const {
185
- TypedMatcherOps<T> Ops;
186
- Value->makeTypedMatcher (Ops);
187
- assert (Ops.hasMatcher () && " hasTypedMatcher<T>() == false" );
188
- return Ops.matcher ();
197
+ assert (hasTypedMatcher<T>() && " hasTypedMatcher<T>() == false" );
198
+ return Value->getTypedMatcher (TypedMatcherOps<T>())
199
+ ->template convertTo <T>();
189
200
}
190
201
191
202
// / \brief String representation of the type of the value.
@@ -197,51 +208,25 @@ class VariantMatcher {
197
208
private:
198
209
explicit VariantMatcher (Payload *Value) : Value(Value) {}
199
210
211
+ template <typename T> struct TypedMatcherOps ;
212
+
200
213
class SinglePayload ;
201
214
class PolymorphicPayload ;
202
215
class VariadicOpPayload ;
203
216
204
- template <typename T>
205
- class TypedMatcherOps : public MatcherOps {
206
- public:
207
- typedef ast_matchers::internal::Matcher<T> MatcherT;
208
-
209
- virtual bool canConstructFrom (const DynTypedMatcher &Matcher,
210
- bool &IsExactMatch) const {
211
- IsExactMatch = Matcher.getSupportedKind ().isSame (
212
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
213
- return Matcher.canConvertTo <T>();
214
- }
215
-
216
- virtual void constructFrom (const DynTypedMatcher& Matcher) {
217
- Out.reset (new MatcherT (Matcher.convertTo <T>()));
218
- }
219
-
220
- virtual void constructVariadicOperator (
221
- ast_matchers::internal::VariadicOperatorFunction Func,
222
- ArrayRef<VariantMatcher> InnerMatchers) {
223
- std::vector<DynTypedMatcher> DynMatchers;
224
- for (size_t i = 0 , e = InnerMatchers.size (); i != e; ++i) {
225
- // Abort if any of the inner matchers can't be converted to
226
- // Matcher<T>.
227
- if (!InnerMatchers[i].hasTypedMatcher <T>()) {
228
- return ;
229
- }
230
- DynMatchers.push_back (InnerMatchers[i].getTypedMatcher <T>());
231
- }
232
- Out.reset (new MatcherT (
233
- new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
234
- Func, DynMatchers)));
235
- }
236
-
237
- bool hasMatcher () const { return Out.get () != nullptr ; }
238
- const MatcherT &matcher () const { return *Out; }
217
+ IntrusiveRefCntPtr<const Payload> Value;
218
+ };
239
219
240
- private:
241
- std::unique_ptr<MatcherT> Out;
242
- };
220
+ template <typename T>
221
+ struct VariantMatcher ::TypedMatcherOps : VariantMatcher::MatcherOps {
222
+ TypedMatcherOps ()
223
+ : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
224
+ typedef ast_matchers::internal::Matcher<T> MatcherT;
243
225
244
- IntrusiveRefCntPtr<const Payload> Value;
226
+ DynTypedMatcher
227
+ convertMatcher (const DynTypedMatcher &Matcher) const override {
228
+ return DynTypedMatcher (Matcher.convertTo <T>());
229
+ }
245
230
};
246
231
247
232
// / \brief Variant value class.
0 commit comments