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