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