clang API Documentation

VariantValue.cpp
Go to the documentation of this file.
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