clang API Documentation
00001 //===--- VariantValue.cpp - Polymorphic value type -*- C++ -*-===/ 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief Polymorphic value type. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/ASTMatchers/Dynamic/VariantValue.h" 00016 #include "clang/Basic/LLVM.h" 00017 #include "llvm/ADT/STLExtras.h" 00018 00019 namespace clang { 00020 namespace ast_matchers { 00021 namespace dynamic { 00022 00023 std::string ArgKind::asString() const { 00024 switch (getArgKind()) { 00025 case AK_Matcher: 00026 return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str(); 00027 case AK_Unsigned: 00028 return "unsigned"; 00029 case AK_String: 00030 return "string"; 00031 } 00032 llvm_unreachable("unhandled ArgKind"); 00033 } 00034 00035 bool ArgKind::isConvertibleTo(ArgKind To, unsigned *Specificity) const { 00036 if (K != To.K) 00037 return false; 00038 if (K != AK_Matcher) { 00039 if (Specificity) 00040 *Specificity = 1; 00041 return true; 00042 } 00043 unsigned Distance; 00044 if (!MatcherKind.isBaseOf(To.MatcherKind, &Distance)) 00045 return false; 00046 00047 if (Specificity) 00048 *Specificity = 100 - Distance; 00049 return true; 00050 } 00051 00052 bool 00053 VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher, 00054 bool &IsExactMatch) const { 00055 IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind); 00056 return Matcher.canConvertTo(NodeKind); 00057 } 00058 00059 llvm::Optional<DynTypedMatcher> 00060 VariantMatcher::MatcherOps::constructVariadicOperator( 00061 DynTypedMatcher::VariadicOperatorFunction Func, 00062 ArrayRef<VariantMatcher> InnerMatchers) const { 00063 std::vector<DynTypedMatcher> DynMatchers; 00064 for (const auto &InnerMatcher : InnerMatchers) { 00065 // Abort if any of the inner matchers can't be converted to 00066 // Matcher<T>. 00067 if (!InnerMatcher.Value) 00068 return llvm::None; 00069 llvm::Optional<DynTypedMatcher> Inner = 00070 InnerMatcher.Value->getTypedMatcher(*this); 00071 if (!Inner) 00072 return llvm::None; 00073 DynMatchers.push_back(*Inner); 00074 } 00075 return DynTypedMatcher::constructVariadic(Func, DynMatchers); 00076 } 00077 00078 VariantMatcher::Payload::~Payload() {} 00079 00080 class VariantMatcher::SinglePayload : public VariantMatcher::Payload { 00081 public: 00082 SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {} 00083 00084 llvm::Optional<DynTypedMatcher> getSingleMatcher() const override { 00085 return Matcher; 00086 } 00087 00088 std::string getTypeAsString() const override { 00089 return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">") 00090 .str(); 00091 } 00092 00093 llvm::Optional<DynTypedMatcher> 00094 getTypedMatcher(const MatcherOps &Ops) const override { 00095 bool Ignore; 00096 if (Ops.canConstructFrom(Matcher, Ignore)) 00097 return Matcher; 00098 return llvm::None; 00099 } 00100 00101 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, 00102 unsigned *Specificity) const override { 00103 return ArgKind(Matcher.getSupportedKind()) 00104 .isConvertibleTo(Kind, Specificity); 00105 } 00106 00107 private: 00108 const DynTypedMatcher Matcher; 00109 }; 00110 00111 class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload { 00112 public: 00113 PolymorphicPayload(std::vector<DynTypedMatcher> MatchersIn) 00114 : Matchers(std::move(MatchersIn)) {} 00115 00116 ~PolymorphicPayload() override {} 00117 00118 llvm::Optional<DynTypedMatcher> getSingleMatcher() const override { 00119 if (Matchers.size() != 1) 00120 return llvm::Optional<DynTypedMatcher>(); 00121 return Matchers[0]; 00122 } 00123 00124 std::string getTypeAsString() const override { 00125 std::string Inner; 00126 for (size_t i = 0, e = Matchers.size(); i != e; ++i) { 00127 if (i != 0) 00128 Inner += "|"; 00129 Inner += Matchers[i].getSupportedKind().asStringRef(); 00130 } 00131 return (Twine("Matcher<") + Inner + ">").str(); 00132 } 00133 00134 llvm::Optional<DynTypedMatcher> 00135 getTypedMatcher(const MatcherOps &Ops) const override { 00136 bool FoundIsExact = false; 00137 const DynTypedMatcher *Found = nullptr; 00138 int NumFound = 0; 00139 for (size_t i = 0, e = Matchers.size(); i != e; ++i) { 00140 bool IsExactMatch; 00141 if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) { 00142 if (Found) { 00143 if (FoundIsExact) { 00144 assert(!IsExactMatch && "We should not have two exact matches."); 00145 continue; 00146 } 00147 } 00148 Found = &Matchers[i]; 00149 FoundIsExact = IsExactMatch; 00150 ++NumFound; 00151 } 00152 } 00153 // We only succeed if we found exactly one, or if we found an exact match. 00154 if (Found && (FoundIsExact || NumFound == 1)) 00155 return *Found; 00156 return llvm::None; 00157 } 00158 00159 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, 00160 unsigned *Specificity) const override { 00161 unsigned MaxSpecificity = 0; 00162 for (const DynTypedMatcher &Matcher : Matchers) { 00163 unsigned ThisSpecificity; 00164 if (ArgKind(Matcher.getSupportedKind()) 00165 .isConvertibleTo(Kind, &ThisSpecificity)) { 00166 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity); 00167 } 00168 } 00169 if (Specificity) 00170 *Specificity = MaxSpecificity; 00171 return MaxSpecificity > 0; 00172 } 00173 00174 const std::vector<DynTypedMatcher> Matchers; 00175 }; 00176 00177 class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload { 00178 public: 00179 VariadicOpPayload(DynTypedMatcher::VariadicOperatorFunction Func, 00180 std::vector<VariantMatcher> Args) 00181 : Func(Func), Args(std::move(Args)) {} 00182 00183 llvm::Optional<DynTypedMatcher> getSingleMatcher() const override { 00184 return llvm::Optional<DynTypedMatcher>(); 00185 } 00186 00187 std::string getTypeAsString() const override { 00188 std::string Inner; 00189 for (size_t i = 0, e = Args.size(); i != e; ++i) { 00190 if (i != 0) 00191 Inner += "&"; 00192 Inner += Args[i].getTypeAsString(); 00193 } 00194 return Inner; 00195 } 00196 00197 llvm::Optional<DynTypedMatcher> 00198 getTypedMatcher(const MatcherOps &Ops) const override { 00199 return Ops.constructVariadicOperator(Func, Args); 00200 } 00201 00202 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, 00203 unsigned *Specificity) const override { 00204 for (const VariantMatcher &Matcher : Args) { 00205 if (!Matcher.isConvertibleTo(Kind, Specificity)) 00206 return false; 00207 } 00208 return true; 00209 } 00210 00211 private: 00212 const DynTypedMatcher::VariadicOperatorFunction Func; 00213 const std::vector<VariantMatcher> Args; 00214 }; 00215 00216 VariantMatcher::VariantMatcher() {} 00217 00218 VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) { 00219 return VariantMatcher(new SinglePayload(Matcher)); 00220 } 00221 00222 VariantMatcher 00223 VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) { 00224 return VariantMatcher(new PolymorphicPayload(std::move(Matchers))); 00225 } 00226 00227 VariantMatcher VariantMatcher::VariadicOperatorMatcher( 00228 DynTypedMatcher::VariadicOperatorFunction Func, 00229 std::vector<VariantMatcher> Args) { 00230 return VariantMatcher(new VariadicOpPayload(Func, std::move(Args))); 00231 } 00232 00233 llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const { 00234 return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>(); 00235 } 00236 00237 void VariantMatcher::reset() { Value.reset(); } 00238 00239 std::string VariantMatcher::getTypeAsString() const { 00240 if (Value) return Value->getTypeAsString(); 00241 return "<Nothing>"; 00242 } 00243 00244 VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) { 00245 *this = Other; 00246 } 00247 00248 VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) { 00249 setUnsigned(Unsigned); 00250 } 00251 00252 VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) { 00253 setString(String); 00254 } 00255 00256 VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) { 00257 setMatcher(Matcher); 00258 } 00259 00260 VariantValue::~VariantValue() { reset(); } 00261 00262 VariantValue &VariantValue::operator=(const VariantValue &Other) { 00263 if (this == &Other) return *this; 00264 reset(); 00265 switch (Other.Type) { 00266 case VT_Unsigned: 00267 setUnsigned(Other.getUnsigned()); 00268 break; 00269 case VT_String: 00270 setString(Other.getString()); 00271 break; 00272 case VT_Matcher: 00273 setMatcher(Other.getMatcher()); 00274 break; 00275 case VT_Nothing: 00276 Type = VT_Nothing; 00277 break; 00278 } 00279 return *this; 00280 } 00281 00282 void VariantValue::reset() { 00283 switch (Type) { 00284 case VT_String: 00285 delete Value.String; 00286 break; 00287 case VT_Matcher: 00288 delete Value.Matcher; 00289 break; 00290 // Cases that do nothing. 00291 case VT_Unsigned: 00292 case VT_Nothing: 00293 break; 00294 } 00295 Type = VT_Nothing; 00296 } 00297 00298 bool VariantValue::isUnsigned() const { 00299 return Type == VT_Unsigned; 00300 } 00301 00302 unsigned VariantValue::getUnsigned() const { 00303 assert(isUnsigned()); 00304 return Value.Unsigned; 00305 } 00306 00307 void VariantValue::setUnsigned(unsigned NewValue) { 00308 reset(); 00309 Type = VT_Unsigned; 00310 Value.Unsigned = NewValue; 00311 } 00312 00313 bool VariantValue::isString() const { 00314 return Type == VT_String; 00315 } 00316 00317 const std::string &VariantValue::getString() const { 00318 assert(isString()); 00319 return *Value.String; 00320 } 00321 00322 void VariantValue::setString(const std::string &NewValue) { 00323 reset(); 00324 Type = VT_String; 00325 Value.String = new std::string(NewValue); 00326 } 00327 00328 bool VariantValue::isMatcher() const { 00329 return Type == VT_Matcher; 00330 } 00331 00332 const VariantMatcher &VariantValue::getMatcher() const { 00333 assert(isMatcher()); 00334 return *Value.Matcher; 00335 } 00336 00337 void VariantValue::setMatcher(const VariantMatcher &NewValue) { 00338 reset(); 00339 Type = VT_Matcher; 00340 Value.Matcher = new VariantMatcher(NewValue); 00341 } 00342 00343 bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const { 00344 switch (Kind.getArgKind()) { 00345 case ArgKind::AK_Unsigned: 00346 if (!isUnsigned()) 00347 return false; 00348 *Specificity = 1; 00349 return true; 00350 00351 case ArgKind::AK_String: 00352 if (!isString()) 00353 return false; 00354 *Specificity = 1; 00355 return true; 00356 00357 case ArgKind::AK_Matcher: 00358 if (!isMatcher()) 00359 return false; 00360 return getMatcher().isConvertibleTo(Kind.getMatcherKind(), Specificity); 00361 } 00362 llvm_unreachable("Invalid Type"); 00363 } 00364 00365 bool VariantValue::isConvertibleTo(ArrayRef<ArgKind> Kinds, 00366 unsigned *Specificity) const { 00367 unsigned MaxSpecificity = 0; 00368 for (const ArgKind& Kind : Kinds) { 00369 unsigned ThisSpecificity; 00370 if (!isConvertibleTo(Kind, &ThisSpecificity)) 00371 continue; 00372 MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity); 00373 } 00374 if (Specificity && MaxSpecificity > 0) { 00375 *Specificity = MaxSpecificity; 00376 } 00377 return MaxSpecificity > 0; 00378 } 00379 00380 std::string VariantValue::getTypeAsString() const { 00381 switch (Type) { 00382 case VT_String: return "String"; 00383 case VT_Matcher: return getMatcher().getTypeAsString(); 00384 case VT_Unsigned: return "Unsigned"; 00385 case VT_Nothing: return "Nothing"; 00386 } 00387 llvm_unreachable("Invalid Type"); 00388 } 00389 00390 } // end namespace dynamic 00391 } // end namespace ast_matchers 00392 } // end namespace clang