xref: /aosp_15_r20/external/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- VariantValue.cpp - Polymorphic value type -*- C++ -*-===/
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li ///
10*67e74705SXin Li /// \file
11*67e74705SXin Li /// \brief Polymorphic value type.
12*67e74705SXin Li ///
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "clang/ASTMatchers/Dynamic/VariantValue.h"
16*67e74705SXin Li #include "clang/Basic/LLVM.h"
17*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
18*67e74705SXin Li 
19*67e74705SXin Li namespace clang {
20*67e74705SXin Li namespace ast_matchers {
21*67e74705SXin Li namespace dynamic {
22*67e74705SXin Li 
asString() const23*67e74705SXin Li std::string ArgKind::asString() const {
24*67e74705SXin Li   switch (getArgKind()) {
25*67e74705SXin Li   case AK_Matcher:
26*67e74705SXin Li     return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str();
27*67e74705SXin Li   case AK_Unsigned:
28*67e74705SXin Li     return "unsigned";
29*67e74705SXin Li   case AK_String:
30*67e74705SXin Li     return "string";
31*67e74705SXin Li   }
32*67e74705SXin Li   llvm_unreachable("unhandled ArgKind");
33*67e74705SXin Li }
34*67e74705SXin Li 
isConvertibleTo(ArgKind To,unsigned * Specificity) const35*67e74705SXin Li bool ArgKind::isConvertibleTo(ArgKind To, unsigned *Specificity) const {
36*67e74705SXin Li   if (K != To.K)
37*67e74705SXin Li     return false;
38*67e74705SXin Li   if (K != AK_Matcher) {
39*67e74705SXin Li     if (Specificity)
40*67e74705SXin Li       *Specificity = 1;
41*67e74705SXin Li     return true;
42*67e74705SXin Li   }
43*67e74705SXin Li   unsigned Distance;
44*67e74705SXin Li   if (!MatcherKind.isBaseOf(To.MatcherKind, &Distance))
45*67e74705SXin Li     return false;
46*67e74705SXin Li 
47*67e74705SXin Li   if (Specificity)
48*67e74705SXin Li     *Specificity = 100 - Distance;
49*67e74705SXin Li   return true;
50*67e74705SXin Li }
51*67e74705SXin Li 
52*67e74705SXin Li bool
canConstructFrom(const DynTypedMatcher & Matcher,bool & IsExactMatch) const53*67e74705SXin Li VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
54*67e74705SXin Li                                              bool &IsExactMatch) const {
55*67e74705SXin Li   IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
56*67e74705SXin Li   return Matcher.canConvertTo(NodeKind);
57*67e74705SXin Li }
58*67e74705SXin Li 
59*67e74705SXin Li llvm::Optional<DynTypedMatcher>
constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,ArrayRef<VariantMatcher> InnerMatchers) const60*67e74705SXin Li VariantMatcher::MatcherOps::constructVariadicOperator(
61*67e74705SXin Li     DynTypedMatcher::VariadicOperator Op,
62*67e74705SXin Li     ArrayRef<VariantMatcher> InnerMatchers) const {
63*67e74705SXin Li   std::vector<DynTypedMatcher> DynMatchers;
64*67e74705SXin Li   for (const auto &InnerMatcher : InnerMatchers) {
65*67e74705SXin Li     // Abort if any of the inner matchers can't be converted to
66*67e74705SXin Li     // Matcher<T>.
67*67e74705SXin Li     if (!InnerMatcher.Value)
68*67e74705SXin Li       return llvm::None;
69*67e74705SXin Li     llvm::Optional<DynTypedMatcher> Inner =
70*67e74705SXin Li         InnerMatcher.Value->getTypedMatcher(*this);
71*67e74705SXin Li     if (!Inner)
72*67e74705SXin Li       return llvm::None;
73*67e74705SXin Li     DynMatchers.push_back(*Inner);
74*67e74705SXin Li   }
75*67e74705SXin Li   return DynTypedMatcher::constructVariadic(Op, NodeKind, DynMatchers);
76*67e74705SXin Li }
77*67e74705SXin Li 
~Payload()78*67e74705SXin Li VariantMatcher::Payload::~Payload() {}
79*67e74705SXin Li 
80*67e74705SXin Li class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
81*67e74705SXin Li public:
SinglePayload(const DynTypedMatcher & Matcher)82*67e74705SXin Li   SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
83*67e74705SXin Li 
getSingleMatcher() const84*67e74705SXin Li   llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
85*67e74705SXin Li     return Matcher;
86*67e74705SXin Li   }
87*67e74705SXin Li 
getTypeAsString() const88*67e74705SXin Li   std::string getTypeAsString() const override {
89*67e74705SXin Li     return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
90*67e74705SXin Li         .str();
91*67e74705SXin Li   }
92*67e74705SXin Li 
93*67e74705SXin Li   llvm::Optional<DynTypedMatcher>
getTypedMatcher(const MatcherOps & Ops) const94*67e74705SXin Li   getTypedMatcher(const MatcherOps &Ops) const override {
95*67e74705SXin Li     bool Ignore;
96*67e74705SXin Li     if (Ops.canConstructFrom(Matcher, Ignore))
97*67e74705SXin Li       return Matcher;
98*67e74705SXin Li     return llvm::None;
99*67e74705SXin Li   }
100*67e74705SXin Li 
isConvertibleTo(ast_type_traits::ASTNodeKind Kind,unsigned * Specificity) const101*67e74705SXin Li   bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
102*67e74705SXin Li                        unsigned *Specificity) const override {
103*67e74705SXin Li     return ArgKind(Matcher.getSupportedKind())
104*67e74705SXin Li         .isConvertibleTo(Kind, Specificity);
105*67e74705SXin Li   }
106*67e74705SXin Li 
107*67e74705SXin Li private:
108*67e74705SXin Li   const DynTypedMatcher Matcher;
109*67e74705SXin Li };
110*67e74705SXin Li 
111*67e74705SXin Li class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
112*67e74705SXin Li public:
PolymorphicPayload(std::vector<DynTypedMatcher> MatchersIn)113*67e74705SXin Li   PolymorphicPayload(std::vector<DynTypedMatcher> MatchersIn)
114*67e74705SXin Li       : Matchers(std::move(MatchersIn)) {}
115*67e74705SXin Li 
~PolymorphicPayload()116*67e74705SXin Li   ~PolymorphicPayload() override {}
117*67e74705SXin Li 
getSingleMatcher() const118*67e74705SXin Li   llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
119*67e74705SXin Li     if (Matchers.size() != 1)
120*67e74705SXin Li       return llvm::Optional<DynTypedMatcher>();
121*67e74705SXin Li     return Matchers[0];
122*67e74705SXin Li   }
123*67e74705SXin Li 
getTypeAsString() const124*67e74705SXin Li   std::string getTypeAsString() const override {
125*67e74705SXin Li     std::string Inner;
126*67e74705SXin Li     for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
127*67e74705SXin Li       if (i != 0)
128*67e74705SXin Li         Inner += "|";
129*67e74705SXin Li       Inner += Matchers[i].getSupportedKind().asStringRef();
130*67e74705SXin Li     }
131*67e74705SXin Li     return (Twine("Matcher<") + Inner + ">").str();
132*67e74705SXin Li   }
133*67e74705SXin Li 
134*67e74705SXin Li   llvm::Optional<DynTypedMatcher>
getTypedMatcher(const MatcherOps & Ops) const135*67e74705SXin Li   getTypedMatcher(const MatcherOps &Ops) const override {
136*67e74705SXin Li     bool FoundIsExact = false;
137*67e74705SXin Li     const DynTypedMatcher *Found = nullptr;
138*67e74705SXin Li     int NumFound = 0;
139*67e74705SXin Li     for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
140*67e74705SXin Li       bool IsExactMatch;
141*67e74705SXin Li       if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) {
142*67e74705SXin Li         if (Found) {
143*67e74705SXin Li           if (FoundIsExact) {
144*67e74705SXin Li             assert(!IsExactMatch && "We should not have two exact matches.");
145*67e74705SXin Li             continue;
146*67e74705SXin Li           }
147*67e74705SXin Li         }
148*67e74705SXin Li         Found = &Matchers[i];
149*67e74705SXin Li         FoundIsExact = IsExactMatch;
150*67e74705SXin Li         ++NumFound;
151*67e74705SXin Li       }
152*67e74705SXin Li     }
153*67e74705SXin Li     // We only succeed if we found exactly one, or if we found an exact match.
154*67e74705SXin Li     if (Found && (FoundIsExact || NumFound == 1))
155*67e74705SXin Li       return *Found;
156*67e74705SXin Li     return llvm::None;
157*67e74705SXin Li   }
158*67e74705SXin Li 
isConvertibleTo(ast_type_traits::ASTNodeKind Kind,unsigned * Specificity) const159*67e74705SXin Li   bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
160*67e74705SXin Li                        unsigned *Specificity) const override {
161*67e74705SXin Li     unsigned MaxSpecificity = 0;
162*67e74705SXin Li     for (const DynTypedMatcher &Matcher : Matchers) {
163*67e74705SXin Li       unsigned ThisSpecificity;
164*67e74705SXin Li       if (ArgKind(Matcher.getSupportedKind())
165*67e74705SXin Li               .isConvertibleTo(Kind, &ThisSpecificity)) {
166*67e74705SXin Li         MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
167*67e74705SXin Li       }
168*67e74705SXin Li     }
169*67e74705SXin Li     if (Specificity)
170*67e74705SXin Li       *Specificity = MaxSpecificity;
171*67e74705SXin Li     return MaxSpecificity > 0;
172*67e74705SXin Li   }
173*67e74705SXin Li 
174*67e74705SXin Li   const std::vector<DynTypedMatcher> Matchers;
175*67e74705SXin Li };
176*67e74705SXin Li 
177*67e74705SXin Li class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
178*67e74705SXin Li public:
VariadicOpPayload(DynTypedMatcher::VariadicOperator Op,std::vector<VariantMatcher> Args)179*67e74705SXin Li   VariadicOpPayload(DynTypedMatcher::VariadicOperator Op,
180*67e74705SXin Li                     std::vector<VariantMatcher> Args)
181*67e74705SXin Li       : Op(Op), Args(std::move(Args)) {}
182*67e74705SXin Li 
getSingleMatcher() const183*67e74705SXin Li   llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
184*67e74705SXin Li     return llvm::Optional<DynTypedMatcher>();
185*67e74705SXin Li   }
186*67e74705SXin Li 
getTypeAsString() const187*67e74705SXin Li   std::string getTypeAsString() const override {
188*67e74705SXin Li     std::string Inner;
189*67e74705SXin Li     for (size_t i = 0, e = Args.size(); i != e; ++i) {
190*67e74705SXin Li       if (i != 0)
191*67e74705SXin Li         Inner += "&";
192*67e74705SXin Li       Inner += Args[i].getTypeAsString();
193*67e74705SXin Li     }
194*67e74705SXin Li     return Inner;
195*67e74705SXin Li   }
196*67e74705SXin Li 
197*67e74705SXin Li   llvm::Optional<DynTypedMatcher>
getTypedMatcher(const MatcherOps & Ops) const198*67e74705SXin Li   getTypedMatcher(const MatcherOps &Ops) const override {
199*67e74705SXin Li     return Ops.constructVariadicOperator(Op, Args);
200*67e74705SXin Li   }
201*67e74705SXin Li 
isConvertibleTo(ast_type_traits::ASTNodeKind Kind,unsigned * Specificity) const202*67e74705SXin Li   bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
203*67e74705SXin Li                        unsigned *Specificity) const override {
204*67e74705SXin Li     for (const VariantMatcher &Matcher : Args) {
205*67e74705SXin Li       if (!Matcher.isConvertibleTo(Kind, Specificity))
206*67e74705SXin Li         return false;
207*67e74705SXin Li     }
208*67e74705SXin Li     return true;
209*67e74705SXin Li   }
210*67e74705SXin Li 
211*67e74705SXin Li private:
212*67e74705SXin Li   const DynTypedMatcher::VariadicOperator Op;
213*67e74705SXin Li   const std::vector<VariantMatcher> Args;
214*67e74705SXin Li };
215*67e74705SXin Li 
VariantMatcher()216*67e74705SXin Li VariantMatcher::VariantMatcher() {}
217*67e74705SXin Li 
SingleMatcher(const DynTypedMatcher & Matcher)218*67e74705SXin Li VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
219*67e74705SXin Li   return VariantMatcher(new SinglePayload(Matcher));
220*67e74705SXin Li }
221*67e74705SXin Li 
222*67e74705SXin Li VariantMatcher
PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers)223*67e74705SXin Li VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) {
224*67e74705SXin Li   return VariantMatcher(new PolymorphicPayload(std::move(Matchers)));
225*67e74705SXin Li }
226*67e74705SXin Li 
VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,std::vector<VariantMatcher> Args)227*67e74705SXin Li VariantMatcher VariantMatcher::VariadicOperatorMatcher(
228*67e74705SXin Li     DynTypedMatcher::VariadicOperator Op,
229*67e74705SXin Li     std::vector<VariantMatcher> Args) {
230*67e74705SXin Li   return VariantMatcher(new VariadicOpPayload(Op, std::move(Args)));
231*67e74705SXin Li }
232*67e74705SXin Li 
getSingleMatcher() const233*67e74705SXin Li llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
234*67e74705SXin Li   return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
235*67e74705SXin Li }
236*67e74705SXin Li 
reset()237*67e74705SXin Li void VariantMatcher::reset() { Value.reset(); }
238*67e74705SXin Li 
getTypeAsString() const239*67e74705SXin Li std::string VariantMatcher::getTypeAsString() const {
240*67e74705SXin Li   if (Value) return Value->getTypeAsString();
241*67e74705SXin Li   return "<Nothing>";
242*67e74705SXin Li }
243*67e74705SXin Li 
VariantValue(const VariantValue & Other)244*67e74705SXin Li VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
245*67e74705SXin Li   *this = Other;
246*67e74705SXin Li }
247*67e74705SXin Li 
VariantValue(unsigned Unsigned)248*67e74705SXin Li VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
249*67e74705SXin Li   setUnsigned(Unsigned);
250*67e74705SXin Li }
251*67e74705SXin Li 
VariantValue(StringRef String)252*67e74705SXin Li VariantValue::VariantValue(StringRef String) : Type(VT_Nothing) {
253*67e74705SXin Li   setString(String);
254*67e74705SXin Li }
255*67e74705SXin Li 
VariantValue(const VariantMatcher & Matcher)256*67e74705SXin Li VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
257*67e74705SXin Li   setMatcher(Matcher);
258*67e74705SXin Li }
259*67e74705SXin Li 
~VariantValue()260*67e74705SXin Li VariantValue::~VariantValue() { reset(); }
261*67e74705SXin Li 
operator =(const VariantValue & Other)262*67e74705SXin Li VariantValue &VariantValue::operator=(const VariantValue &Other) {
263*67e74705SXin Li   if (this == &Other) return *this;
264*67e74705SXin Li   reset();
265*67e74705SXin Li   switch (Other.Type) {
266*67e74705SXin Li   case VT_Unsigned:
267*67e74705SXin Li     setUnsigned(Other.getUnsigned());
268*67e74705SXin Li     break;
269*67e74705SXin Li   case VT_String:
270*67e74705SXin Li     setString(Other.getString());
271*67e74705SXin Li     break;
272*67e74705SXin Li   case VT_Matcher:
273*67e74705SXin Li     setMatcher(Other.getMatcher());
274*67e74705SXin Li     break;
275*67e74705SXin Li   case VT_Nothing:
276*67e74705SXin Li     Type = VT_Nothing;
277*67e74705SXin Li     break;
278*67e74705SXin Li   }
279*67e74705SXin Li   return *this;
280*67e74705SXin Li }
281*67e74705SXin Li 
reset()282*67e74705SXin Li void VariantValue::reset() {
283*67e74705SXin Li   switch (Type) {
284*67e74705SXin Li   case VT_String:
285*67e74705SXin Li     delete Value.String;
286*67e74705SXin Li     break;
287*67e74705SXin Li   case VT_Matcher:
288*67e74705SXin Li     delete Value.Matcher;
289*67e74705SXin Li     break;
290*67e74705SXin Li   // Cases that do nothing.
291*67e74705SXin Li   case VT_Unsigned:
292*67e74705SXin Li   case VT_Nothing:
293*67e74705SXin Li     break;
294*67e74705SXin Li   }
295*67e74705SXin Li   Type = VT_Nothing;
296*67e74705SXin Li }
297*67e74705SXin Li 
isUnsigned() const298*67e74705SXin Li bool VariantValue::isUnsigned() const {
299*67e74705SXin Li   return Type == VT_Unsigned;
300*67e74705SXin Li }
301*67e74705SXin Li 
getUnsigned() const302*67e74705SXin Li unsigned VariantValue::getUnsigned() const {
303*67e74705SXin Li   assert(isUnsigned());
304*67e74705SXin Li   return Value.Unsigned;
305*67e74705SXin Li }
306*67e74705SXin Li 
setUnsigned(unsigned NewValue)307*67e74705SXin Li void VariantValue::setUnsigned(unsigned NewValue) {
308*67e74705SXin Li   reset();
309*67e74705SXin Li   Type = VT_Unsigned;
310*67e74705SXin Li   Value.Unsigned = NewValue;
311*67e74705SXin Li }
312*67e74705SXin Li 
isString() const313*67e74705SXin Li bool VariantValue::isString() const {
314*67e74705SXin Li   return Type == VT_String;
315*67e74705SXin Li }
316*67e74705SXin Li 
getString() const317*67e74705SXin Li const std::string &VariantValue::getString() const {
318*67e74705SXin Li   assert(isString());
319*67e74705SXin Li   return *Value.String;
320*67e74705SXin Li }
321*67e74705SXin Li 
setString(StringRef NewValue)322*67e74705SXin Li void VariantValue::setString(StringRef NewValue) {
323*67e74705SXin Li   reset();
324*67e74705SXin Li   Type = VT_String;
325*67e74705SXin Li   Value.String = new std::string(NewValue);
326*67e74705SXin Li }
327*67e74705SXin Li 
isMatcher() const328*67e74705SXin Li bool VariantValue::isMatcher() const {
329*67e74705SXin Li   return Type == VT_Matcher;
330*67e74705SXin Li }
331*67e74705SXin Li 
getMatcher() const332*67e74705SXin Li const VariantMatcher &VariantValue::getMatcher() const {
333*67e74705SXin Li   assert(isMatcher());
334*67e74705SXin Li   return *Value.Matcher;
335*67e74705SXin Li }
336*67e74705SXin Li 
setMatcher(const VariantMatcher & NewValue)337*67e74705SXin Li void VariantValue::setMatcher(const VariantMatcher &NewValue) {
338*67e74705SXin Li   reset();
339*67e74705SXin Li   Type = VT_Matcher;
340*67e74705SXin Li   Value.Matcher = new VariantMatcher(NewValue);
341*67e74705SXin Li }
342*67e74705SXin Li 
isConvertibleTo(ArgKind Kind,unsigned * Specificity) const343*67e74705SXin Li bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const {
344*67e74705SXin Li   switch (Kind.getArgKind()) {
345*67e74705SXin Li   case ArgKind::AK_Unsigned:
346*67e74705SXin Li     if (!isUnsigned())
347*67e74705SXin Li       return false;
348*67e74705SXin Li     *Specificity = 1;
349*67e74705SXin Li     return true;
350*67e74705SXin Li 
351*67e74705SXin Li   case ArgKind::AK_String:
352*67e74705SXin Li     if (!isString())
353*67e74705SXin Li       return false;
354*67e74705SXin Li     *Specificity = 1;
355*67e74705SXin Li     return true;
356*67e74705SXin Li 
357*67e74705SXin Li   case ArgKind::AK_Matcher:
358*67e74705SXin Li     if (!isMatcher())
359*67e74705SXin Li       return false;
360*67e74705SXin Li     return getMatcher().isConvertibleTo(Kind.getMatcherKind(), Specificity);
361*67e74705SXin Li   }
362*67e74705SXin Li   llvm_unreachable("Invalid Type");
363*67e74705SXin Li }
364*67e74705SXin Li 
isConvertibleTo(ArrayRef<ArgKind> Kinds,unsigned * Specificity) const365*67e74705SXin Li bool VariantValue::isConvertibleTo(ArrayRef<ArgKind> Kinds,
366*67e74705SXin Li                                    unsigned *Specificity) const {
367*67e74705SXin Li   unsigned MaxSpecificity = 0;
368*67e74705SXin Li   for (const ArgKind& Kind : Kinds) {
369*67e74705SXin Li     unsigned ThisSpecificity;
370*67e74705SXin Li     if (!isConvertibleTo(Kind, &ThisSpecificity))
371*67e74705SXin Li       continue;
372*67e74705SXin Li     MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
373*67e74705SXin Li   }
374*67e74705SXin Li   if (Specificity && MaxSpecificity > 0) {
375*67e74705SXin Li     *Specificity = MaxSpecificity;
376*67e74705SXin Li   }
377*67e74705SXin Li   return MaxSpecificity > 0;
378*67e74705SXin Li }
379*67e74705SXin Li 
getTypeAsString() const380*67e74705SXin Li std::string VariantValue::getTypeAsString() const {
381*67e74705SXin Li   switch (Type) {
382*67e74705SXin Li   case VT_String: return "String";
383*67e74705SXin Li   case VT_Matcher: return getMatcher().getTypeAsString();
384*67e74705SXin Li   case VT_Unsigned: return "Unsigned";
385*67e74705SXin Li   case VT_Nothing: return "Nothing";
386*67e74705SXin Li   }
387*67e74705SXin Li   llvm_unreachable("Invalid Type");
388*67e74705SXin Li }
389*67e74705SXin Li 
390*67e74705SXin Li } // end namespace dynamic
391*67e74705SXin Li } // end namespace ast_matchers
392*67e74705SXin Li } // end namespace clang
393