VariantValue.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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. /// \brief Polymorphic value type.
  12. ///
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/ASTMatchers/Dynamic/VariantValue.h"
  15. #include "clang/Basic/LLVM.h"
  16. #include "llvm/ADT/STLExtras.h"
  17. namespace clang {
  18. namespace ast_matchers {
  19. namespace dynamic {
  20. std::string ArgKind::asString() const {
  21. switch (getArgKind()) {
  22. case AK_Matcher:
  23. return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str();
  24. case AK_Unsigned:
  25. return "unsigned";
  26. case AK_String:
  27. return "string";
  28. }
  29. llvm_unreachable("unhandled ArgKind");
  30. }
  31. bool ArgKind::isConvertibleTo(ArgKind To, unsigned *Specificity) const {
  32. if (K != To.K)
  33. return false;
  34. if (K != AK_Matcher) {
  35. if (Specificity)
  36. *Specificity = 1;
  37. return true;
  38. }
  39. unsigned Distance;
  40. if (!MatcherKind.isBaseOf(To.MatcherKind, &Distance))
  41. return false;
  42. if (Specificity)
  43. *Specificity = 100 - Distance;
  44. return true;
  45. }
  46. bool
  47. VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
  48. bool &IsExactMatch) const {
  49. IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
  50. return Matcher.canConvertTo(NodeKind);
  51. }
  52. llvm::Optional<DynTypedMatcher>
  53. VariantMatcher::MatcherOps::constructVariadicOperator(
  54. DynTypedMatcher::VariadicOperator Op,
  55. ArrayRef<VariantMatcher> InnerMatchers) const {
  56. std::vector<DynTypedMatcher> DynMatchers;
  57. for (const auto &InnerMatcher : InnerMatchers) {
  58. // Abort if any of the inner matchers can't be converted to
  59. // Matcher<T>.
  60. if (!InnerMatcher.Value)
  61. return llvm::None;
  62. llvm::Optional<DynTypedMatcher> Inner =
  63. InnerMatcher.Value->getTypedMatcher(*this);
  64. if (!Inner)
  65. return llvm::None;
  66. DynMatchers.push_back(*Inner);
  67. }
  68. return DynTypedMatcher::constructVariadic(Op, NodeKind, DynMatchers);
  69. }
  70. VariantMatcher::Payload::~Payload() {}
  71. class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
  72. public:
  73. SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
  74. llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
  75. return Matcher;
  76. }
  77. std::string getTypeAsString() const override {
  78. return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
  79. .str();
  80. }
  81. llvm::Optional<DynTypedMatcher>
  82. getTypedMatcher(const MatcherOps &Ops) const override {
  83. bool Ignore;
  84. if (Ops.canConstructFrom(Matcher, Ignore))
  85. return Matcher;
  86. return llvm::None;
  87. }
  88. bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
  89. unsigned *Specificity) const override {
  90. return ArgKind(Matcher.getSupportedKind())
  91. .isConvertibleTo(Kind, Specificity);
  92. }
  93. private:
  94. const DynTypedMatcher Matcher;
  95. };
  96. class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
  97. public:
  98. PolymorphicPayload(std::vector<DynTypedMatcher> MatchersIn)
  99. : Matchers(std::move(MatchersIn)) {}
  100. ~PolymorphicPayload() override {}
  101. llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
  102. if (Matchers.size() != 1)
  103. return llvm::Optional<DynTypedMatcher>();
  104. return Matchers[0];
  105. }
  106. std::string getTypeAsString() const override {
  107. std::string Inner;
  108. for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
  109. if (i != 0)
  110. Inner += "|";
  111. Inner += Matchers[i].getSupportedKind().asStringRef();
  112. }
  113. return (Twine("Matcher<") + Inner + ">").str();
  114. }
  115. llvm::Optional<DynTypedMatcher>
  116. getTypedMatcher(const MatcherOps &Ops) const override {
  117. bool FoundIsExact = false;
  118. const DynTypedMatcher *Found = nullptr;
  119. int NumFound = 0;
  120. for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
  121. bool IsExactMatch;
  122. if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) {
  123. if (Found) {
  124. if (FoundIsExact) {
  125. assert(!IsExactMatch && "We should not have two exact matches.");
  126. continue;
  127. }
  128. }
  129. Found = &Matchers[i];
  130. FoundIsExact = IsExactMatch;
  131. ++NumFound;
  132. }
  133. }
  134. // We only succeed if we found exactly one, or if we found an exact match.
  135. if (Found && (FoundIsExact || NumFound == 1))
  136. return *Found;
  137. return llvm::None;
  138. }
  139. bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
  140. unsigned *Specificity) const override {
  141. unsigned MaxSpecificity = 0;
  142. for (const DynTypedMatcher &Matcher : Matchers) {
  143. unsigned ThisSpecificity;
  144. if (ArgKind(Matcher.getSupportedKind())
  145. .isConvertibleTo(Kind, &ThisSpecificity)) {
  146. MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
  147. }
  148. }
  149. if (Specificity)
  150. *Specificity = MaxSpecificity;
  151. return MaxSpecificity > 0;
  152. }
  153. const std::vector<DynTypedMatcher> Matchers;
  154. };
  155. class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
  156. public:
  157. VariadicOpPayload(DynTypedMatcher::VariadicOperator Op,
  158. std::vector<VariantMatcher> Args)
  159. : Op(Op), Args(std::move(Args)) {}
  160. llvm::Optional<DynTypedMatcher> getSingleMatcher() const override {
  161. return llvm::Optional<DynTypedMatcher>();
  162. }
  163. std::string getTypeAsString() const override {
  164. std::string Inner;
  165. for (size_t i = 0, e = Args.size(); i != e; ++i) {
  166. if (i != 0)
  167. Inner += "&";
  168. Inner += Args[i].getTypeAsString();
  169. }
  170. return Inner;
  171. }
  172. llvm::Optional<DynTypedMatcher>
  173. getTypedMatcher(const MatcherOps &Ops) const override {
  174. return Ops.constructVariadicOperator(Op, Args);
  175. }
  176. bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
  177. unsigned *Specificity) const override {
  178. for (const VariantMatcher &Matcher : Args) {
  179. if (!Matcher.isConvertibleTo(Kind, Specificity))
  180. return false;
  181. }
  182. return true;
  183. }
  184. private:
  185. const DynTypedMatcher::VariadicOperator Op;
  186. const std::vector<VariantMatcher> Args;
  187. };
  188. VariantMatcher::VariantMatcher() {}
  189. VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
  190. return VariantMatcher(new SinglePayload(Matcher));
  191. }
  192. VariantMatcher
  193. VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) {
  194. return VariantMatcher(new PolymorphicPayload(std::move(Matchers)));
  195. }
  196. VariantMatcher VariantMatcher::VariadicOperatorMatcher(
  197. DynTypedMatcher::VariadicOperator Op,
  198. std::vector<VariantMatcher> Args) {
  199. return VariantMatcher(new VariadicOpPayload(Op, std::move(Args)));
  200. }
  201. llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
  202. return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
  203. }
  204. void VariantMatcher::reset() { Value.reset(); }
  205. std::string VariantMatcher::getTypeAsString() const {
  206. if (Value) return Value->getTypeAsString();
  207. return "<Nothing>";
  208. }
  209. VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
  210. *this = Other;
  211. }
  212. VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
  213. setUnsigned(Unsigned);
  214. }
  215. VariantValue::VariantValue(StringRef String) : Type(VT_Nothing) {
  216. setString(String);
  217. }
  218. VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
  219. setMatcher(Matcher);
  220. }
  221. VariantValue::~VariantValue() { reset(); }
  222. VariantValue &VariantValue::operator=(const VariantValue &Other) {
  223. if (this == &Other) return *this;
  224. reset();
  225. switch (Other.Type) {
  226. case VT_Unsigned:
  227. setUnsigned(Other.getUnsigned());
  228. break;
  229. case VT_String:
  230. setString(Other.getString());
  231. break;
  232. case VT_Matcher:
  233. setMatcher(Other.getMatcher());
  234. break;
  235. case VT_Nothing:
  236. Type = VT_Nothing;
  237. break;
  238. }
  239. return *this;
  240. }
  241. void VariantValue::reset() {
  242. switch (Type) {
  243. case VT_String:
  244. delete Value.String;
  245. break;
  246. case VT_Matcher:
  247. delete Value.Matcher;
  248. break;
  249. // Cases that do nothing.
  250. case VT_Unsigned:
  251. case VT_Nothing:
  252. break;
  253. }
  254. Type = VT_Nothing;
  255. }
  256. bool VariantValue::isUnsigned() const {
  257. return Type == VT_Unsigned;
  258. }
  259. unsigned VariantValue::getUnsigned() const {
  260. assert(isUnsigned());
  261. return Value.Unsigned;
  262. }
  263. void VariantValue::setUnsigned(unsigned NewValue) {
  264. reset();
  265. Type = VT_Unsigned;
  266. Value.Unsigned = NewValue;
  267. }
  268. bool VariantValue::isString() const {
  269. return Type == VT_String;
  270. }
  271. const std::string &VariantValue::getString() const {
  272. assert(isString());
  273. return *Value.String;
  274. }
  275. void VariantValue::setString(StringRef NewValue) {
  276. reset();
  277. Type = VT_String;
  278. Value.String = new std::string(NewValue);
  279. }
  280. bool VariantValue::isMatcher() const {
  281. return Type == VT_Matcher;
  282. }
  283. const VariantMatcher &VariantValue::getMatcher() const {
  284. assert(isMatcher());
  285. return *Value.Matcher;
  286. }
  287. void VariantValue::setMatcher(const VariantMatcher &NewValue) {
  288. reset();
  289. Type = VT_Matcher;
  290. Value.Matcher = new VariantMatcher(NewValue);
  291. }
  292. bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const {
  293. switch (Kind.getArgKind()) {
  294. case ArgKind::AK_Unsigned:
  295. if (!isUnsigned())
  296. return false;
  297. *Specificity = 1;
  298. return true;
  299. case ArgKind::AK_String:
  300. if (!isString())
  301. return false;
  302. *Specificity = 1;
  303. return true;
  304. case ArgKind::AK_Matcher:
  305. if (!isMatcher())
  306. return false;
  307. return getMatcher().isConvertibleTo(Kind.getMatcherKind(), Specificity);
  308. }
  309. llvm_unreachable("Invalid Type");
  310. }
  311. bool VariantValue::isConvertibleTo(ArrayRef<ArgKind> Kinds,
  312. unsigned *Specificity) const {
  313. unsigned MaxSpecificity = 0;
  314. for (const ArgKind& Kind : Kinds) {
  315. unsigned ThisSpecificity;
  316. if (!isConvertibleTo(Kind, &ThisSpecificity))
  317. continue;
  318. MaxSpecificity = std::max(MaxSpecificity, ThisSpecificity);
  319. }
  320. if (Specificity && MaxSpecificity > 0) {
  321. *Specificity = MaxSpecificity;
  322. }
  323. return MaxSpecificity > 0;
  324. }
  325. std::string VariantValue::getTypeAsString() const {
  326. switch (Type) {
  327. case VT_String: return "String";
  328. case VT_Matcher: return getMatcher().getTypeAsString();
  329. case VT_Unsigned: return "Unsigned";
  330. case VT_Nothing: return "Nothing";
  331. }
  332. llvm_unreachable("Invalid Type");
  333. }
  334. } // end namespace dynamic
  335. } // end namespace ast_matchers
  336. } // end namespace clang