1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "clang/ASTMatchers/Dynamic/VariantValue.h" |
15 | #include "clang/Basic/LLVM.h" |
16 | #include "llvm/ADT/STLExtras.h" |
17 | |
18 | namespace clang { |
19 | namespace ast_matchers { |
20 | namespace dynamic { |
21 | |
22 | std::string ArgKind::asString() const { |
23 | switch (getArgKind()) { |
24 | case AK_Matcher: |
25 | return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str(); |
26 | case AK_Boolean: |
27 | return "boolean"; |
28 | case AK_Double: |
29 | return "double"; |
30 | case AK_Unsigned: |
31 | return "unsigned"; |
32 | case AK_String: |
33 | return "string"; |
34 | } |
35 | llvm_unreachable("unhandled ArgKind"); |
36 | } |
37 | |
38 | bool ArgKind::isConvertibleTo(ArgKind To, unsigned *Specificity) const { |
39 | if (K != To.K) |
40 | return false; |
41 | if (K != AK_Matcher) { |
42 | if (Specificity) |
43 | *Specificity = 1; |
44 | return true; |
45 | } |
46 | unsigned Distance; |
47 | if (!MatcherKind.isBaseOf(To.MatcherKind, &Distance)) |
48 | return false; |
49 | |
50 | if (Specificity) |
51 | *Specificity = 100 - Distance; |
52 | return true; |
53 | } |
54 | |
55 | bool |
56 | VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher, |
57 | bool &IsExactMatch) const { |
58 | IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind); |
59 | return Matcher.canConvertTo(NodeKind); |
60 | } |
61 | |
62 | llvm::Optional<DynTypedMatcher> |
63 | VariantMatcher::MatcherOps::constructVariadicOperator( |
64 | DynTypedMatcher::VariadicOperator Op, |
65 | ArrayRef<VariantMatcher> InnerMatchers) const { |
66 | std::vector<DynTypedMatcher> DynMatchers; |
67 | for (const auto &InnerMatcher : InnerMatchers) { |
68 | |
69 | |
70 | if (!InnerMatcher.Value) |
71 | return llvm::None; |
72 | llvm::Optional<DynTypedMatcher> Inner = |
73 | InnerMatcher.Value->getTypedMatcher(*this); |
74 | if (!Inner) |
75 | return llvm::None; |
76 | DynMatchers.push_back(*Inner); |
77 | } |
78 | return DynTypedMatcher::constructVariadic(Op, NodeKind, DynMatchers); |
79 | } |
80 | |
81 | VariantMatcher::Payload::~Payload() {} |
82 | |
83 | class VariantMatcher::SinglePayload : public VariantMatcher::Payload { |
84 | public: |
85 | SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {} |
86 | |
87 | llvm::Optional<DynTypedMatcher> getSingleMatcher() const override { |
88 | return Matcher; |
89 | } |
90 | |
91 | std::string getTypeAsString() const override { |
92 | return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">") |
93 | .str(); |
94 | } |
95 | |
96 | llvm::Optional<DynTypedMatcher> |
97 | getTypedMatcher(const MatcherOps &Ops) const override { |
98 | bool Ignore; |
99 | if (Ops.canConstructFrom(Matcher, Ignore)) |
100 | return Matcher; |
101 | return llvm::None; |
102 | } |
103 | |
104 | bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, |
105 | unsigned *Specificity) const override { |
106 | return ArgKind(Matcher.getSupportedKind()) |
107 | .isConvertibleTo(Kind, Specificity); |
108 | } |
109 | |
110 | private: |
111 | const DynTypedMatcher Matcher; |
112 | }; |
113 | |
114 | class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload { |
115 | public: |
116 | PolymorphicPayload(std::vector<DynTypedMatcher> MatchersIn) |
117 | : Matchers(std::move(MatchersIn)) {} |
118 | |
119 | ~PolymorphicPayload() override {} |
120 | |
121 | llvm::Optional<DynTypedMatcher> getSingleMatcher() const override { |
122 | if (Matchers.size() != 1) |
123 | return llvm::Optional<DynTypedMatcher>(); |
124 | return Matchers[0]; |
125 | } |
126 | |
127 | std::string getTypeAsString() const override { |
128 | std::string Inner; |
129 | for (size_t i = 0, e = Matchers.size(); i != e; ++i) { |
130 | if (i != 0) |
131 | Inner += "|"; |
132 | Inner += Matchers[i].getSupportedKind().asStringRef(); |
133 | } |
134 | return (Twine("Matcher<") + Inner + ">").str(); |
135 | } |
136 | |
137 | llvm::Optional<DynTypedMatcher> |
138 | getTypedMatcher(const MatcherOps &Ops) const override { |
139 | bool FoundIsExact = false; |
140 | const DynTypedMatcher *Found = nullptr; |
141 | int NumFound = 0; |
142 | for (size_t i = 0, e = Matchers.size(); i != e; ++i) { |
143 | bool IsExactMatch; |
144 | if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) { |
145 | if (Found) { |
146 | if (FoundIsExact) { |
147 | (0) . __assert_fail ("!IsExactMatch && \"We should not have two exact matches.\"", "/home/seafit/code_projects/clang_source/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp", 147, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!IsExactMatch && "We should not have two exact matches."); |
148 | continue; |
149 | } |
150 | } |
151 | Found = &Matchers[i]; |
152 | FoundIsExact = IsExactMatch; |
153 | ++NumFound; |
154 | } |
155 | } |
156 | |
157 | if (Found && (FoundIsExact || NumFound == 1)) |
158 | return *Found; |
159 | return llvm::None; |
160 | } |
161 | |
162 | bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, |
163 | unsigned *Specificity) const override { |
164 | unsigned MaxSpecificity = 0; |
165 | for (const DynTypedMatcher &Matcher : Matchers) { |
166 | unsigned ThisSpecificity; |
167 | if (ArgKind(Matcher.getSupportedKind()) |
168 | .isConvertibleTo(Kind, &ThisSpecificity)) { |
169 | MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity); |
170 | } |
171 | } |
172 | if (Specificity) |
173 | *Specificity = MaxSpecificity; |
174 | return MaxSpecificity > 0; |
175 | } |
176 | |
177 | const std::vector<DynTypedMatcher> Matchers; |
178 | }; |
179 | |
180 | class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload { |
181 | public: |
182 | VariadicOpPayload(DynTypedMatcher::VariadicOperator Op, |
183 | std::vector<VariantMatcher> Args) |
184 | : Op(Op), Args(std::move(Args)) {} |
185 | |
186 | llvm::Optional<DynTypedMatcher> getSingleMatcher() const override { |
187 | return llvm::Optional<DynTypedMatcher>(); |
188 | } |
189 | |
190 | std::string getTypeAsString() const override { |
191 | std::string Inner; |
192 | for (size_t i = 0, e = Args.size(); i != e; ++i) { |
193 | if (i != 0) |
194 | Inner += "&"; |
195 | Inner += Args[i].getTypeAsString(); |
196 | } |
197 | return Inner; |
198 | } |
199 | |
200 | llvm::Optional<DynTypedMatcher> |
201 | getTypedMatcher(const MatcherOps &Ops) const override { |
202 | return Ops.constructVariadicOperator(Op, Args); |
203 | } |
204 | |
205 | bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, |
206 | unsigned *Specificity) const override { |
207 | for (const VariantMatcher &Matcher : Args) { |
208 | if (!Matcher.isConvertibleTo(Kind, Specificity)) |
209 | return false; |
210 | } |
211 | return true; |
212 | } |
213 | |
214 | private: |
215 | const DynTypedMatcher::VariadicOperator Op; |
216 | const std::vector<VariantMatcher> Args; |
217 | }; |
218 | |
219 | VariantMatcher::VariantMatcher() {} |
220 | |
221 | VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) { |
222 | return VariantMatcher(std::make_shared<SinglePayload>(Matcher)); |
223 | } |
224 | |
225 | VariantMatcher |
226 | VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) { |
227 | return VariantMatcher( |
228 | std::make_shared<PolymorphicPayload>(std::move(Matchers))); |
229 | } |
230 | |
231 | VariantMatcher VariantMatcher::VariadicOperatorMatcher( |
232 | DynTypedMatcher::VariadicOperator Op, |
233 | std::vector<VariantMatcher> Args) { |
234 | return VariantMatcher( |
235 | std::make_shared<VariadicOpPayload>(Op, std::move(Args))); |
236 | } |
237 | |
238 | llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const { |
239 | return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>(); |
240 | } |
241 | |
242 | void VariantMatcher::reset() { Value.reset(); } |
243 | |
244 | std::string VariantMatcher::getTypeAsString() const { |
245 | if (Value) return Value->getTypeAsString(); |
246 | return "<Nothing>"; |
247 | } |
248 | |
249 | VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) { |
250 | *this = Other; |
251 | } |
252 | |
253 | VariantValue::VariantValue(bool Boolean) : Type(VT_Nothing) { |
254 | setBoolean(Boolean); |
255 | } |
256 | |
257 | VariantValue::VariantValue(double Double) : Type(VT_Nothing) { |
258 | setDouble(Double); |
259 | } |
260 | |
261 | VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) { |
262 | setUnsigned(Unsigned); |
263 | } |
264 | |
265 | VariantValue::VariantValue(StringRef String) : Type(VT_Nothing) { |
266 | setString(String); |
267 | } |
268 | |
269 | VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) { |
270 | setMatcher(Matcher); |
271 | } |
272 | |
273 | VariantValue::~VariantValue() { reset(); } |
274 | |
275 | VariantValue &VariantValue::operator=(const VariantValue &Other) { |
276 | if (this == &Other) return *this; |
277 | reset(); |
278 | switch (Other.Type) { |
279 | case VT_Boolean: |
280 | setBoolean(Other.getBoolean()); |
281 | break; |
282 | case VT_Double: |
283 | setDouble(Other.getDouble()); |
284 | break; |
285 | case VT_Unsigned: |
286 | setUnsigned(Other.getUnsigned()); |
287 | break; |
288 | case VT_String: |
289 | setString(Other.getString()); |
290 | break; |
291 | case VT_Matcher: |
292 | setMatcher(Other.getMatcher()); |
293 | break; |
294 | case VT_Nothing: |
295 | Type = VT_Nothing; |
296 | break; |
297 | } |
298 | return *this; |
299 | } |
300 | |
301 | void VariantValue::reset() { |
302 | switch (Type) { |
303 | case VT_String: |
304 | delete Value.String; |
305 | break; |
306 | case VT_Matcher: |
307 | delete Value.Matcher; |
308 | break; |
309 | |
310 | case VT_Boolean: |
311 | case VT_Double: |
312 | case VT_Unsigned: |
313 | case VT_Nothing: |
314 | break; |
315 | } |
316 | Type = VT_Nothing; |
317 | } |
318 | |
319 | bool VariantValue::isBoolean() const { |
320 | return Type == VT_Boolean; |
321 | } |
322 | |
323 | bool VariantValue::getBoolean() const { |
324 | assert(isBoolean()); |
325 | return Value.Boolean; |
326 | } |
327 | |
328 | void VariantValue::setBoolean(bool NewValue) { |
329 | reset(); |
330 | Type = VT_Boolean; |
331 | Value.Boolean = NewValue; |
332 | } |
333 | |
334 | bool VariantValue::isDouble() const { |
335 | return Type == VT_Double; |
336 | } |
337 | |
338 | double VariantValue::getDouble() const { |
339 | assert(isDouble()); |
340 | return Value.Double; |
341 | } |
342 | |
343 | void VariantValue::setDouble(double NewValue) { |
344 | reset(); |
345 | Type = VT_Double; |
346 | Value.Double = NewValue; |
347 | } |
348 | |
349 | bool VariantValue::isUnsigned() const { |
350 | return Type == VT_Unsigned; |
351 | } |
352 | |
353 | unsigned VariantValue::getUnsigned() const { |
354 | assert(isUnsigned()); |
355 | return Value.Unsigned; |
356 | } |
357 | |
358 | void VariantValue::setUnsigned(unsigned NewValue) { |
359 | reset(); |
360 | Type = VT_Unsigned; |
361 | Value.Unsigned = NewValue; |
362 | } |
363 | |
364 | bool VariantValue::isString() const { |
365 | return Type == VT_String; |
366 | } |
367 | |
368 | const std::string &VariantValue::getString() const { |
369 | assert(isString()); |
370 | return *Value.String; |
371 | } |
372 | |
373 | void VariantValue::setString(StringRef NewValue) { |
374 | reset(); |
375 | Type = VT_String; |
376 | Value.String = new std::string(NewValue); |
377 | } |
378 | |
379 | bool VariantValue::isMatcher() const { |
380 | return Type == VT_Matcher; |
381 | } |
382 | |
383 | const VariantMatcher &VariantValue::getMatcher() const { |
384 | assert(isMatcher()); |
385 | return *Value.Matcher; |
386 | } |
387 | |
388 | void VariantValue::setMatcher(const VariantMatcher &NewValue) { |
389 | reset(); |
390 | Type = VT_Matcher; |
391 | Value.Matcher = new VariantMatcher(NewValue); |
392 | } |
393 | |
394 | bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const { |
395 | switch (Kind.getArgKind()) { |
396 | case ArgKind::AK_Boolean: |
397 | if (!isBoolean()) |
398 | return false; |
399 | *Specificity = 1; |
400 | return true; |
401 | |
402 | case ArgKind::AK_Double: |
403 | if (!isDouble()) |
404 | return false; |
405 | *Specificity = 1; |
406 | return true; |
407 | |
408 | case ArgKind::AK_Unsigned: |
409 | if (!isUnsigned()) |
410 | return false; |
411 | *Specificity = 1; |
412 | return true; |
413 | |
414 | case ArgKind::AK_String: |
415 | if (!isString()) |
416 | return false; |
417 | *Specificity = 1; |
418 | return true; |
419 | |
420 | case ArgKind::AK_Matcher: |
421 | if (!isMatcher()) |
422 | return false; |
423 | return getMatcher().isConvertibleTo(Kind.getMatcherKind(), Specificity); |
424 | } |
425 | llvm_unreachable("Invalid Type"); |
426 | } |
427 | |
428 | bool VariantValue::isConvertibleTo(ArrayRef<ArgKind> Kinds, |
429 | unsigned *Specificity) const { |
430 | unsigned MaxSpecificity = 0; |
431 | for (const ArgKind& Kind : Kinds) { |
432 | unsigned ThisSpecificity; |
433 | if (!isConvertibleTo(Kind, &ThisSpecificity)) |
434 | continue; |
435 | MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity); |
436 | } |
437 | if (Specificity && MaxSpecificity > 0) { |
438 | *Specificity = MaxSpecificity; |
439 | } |
440 | return MaxSpecificity > 0; |
441 | } |
442 | |
443 | std::string VariantValue::getTypeAsString() const { |
444 | switch (Type) { |
445 | case VT_String: return "String"; |
446 | case VT_Matcher: return getMatcher().getTypeAsString(); |
447 | case VT_Boolean: return "Boolean"; |
448 | case VT_Double: return "Double"; |
449 | case VT_Unsigned: return "Unsigned"; |
450 | case VT_Nothing: return "Nothing"; |
451 | } |
452 | llvm_unreachable("Invalid Type"); |
453 | } |
454 | |
455 | } |
456 | } |
457 | } |
458 | |