Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- VariantValue.h - Polymorphic value type ----------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// Polymorphic value type.
  11. ///
  12. /// Supports all the types required for dynamic Matcher construction.
  13. ///  Used by the registry to construct matchers in a generic way.
  14. ///
  15. //===----------------------------------------------------------------------===//
  16.  
  17. #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
  18. #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
  19.  
  20. #include "clang/ASTMatchers/ASTMatchers.h"
  21. #include "clang/ASTMatchers/ASTMatchersInternal.h"
  22. #include "llvm/ADT/IntrusiveRefCntPtr.h"
  23. #include <memory>
  24. #include <optional>
  25. #include <vector>
  26.  
  27. namespace clang {
  28. namespace ast_matchers {
  29. namespace dynamic {
  30.  
  31. /// Kind identifier.
  32. ///
  33. /// It supports all types that VariantValue can contain.
  34. class ArgKind {
  35.  public:
  36.   enum Kind {
  37.     AK_Matcher,
  38.     AK_Node,
  39.     AK_Boolean,
  40.     AK_Double,
  41.     AK_Unsigned,
  42.     AK_String
  43.   };
  44.   /// Constructor for non-matcher types.
  45.   ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
  46.  
  47.   /// Constructor for matcher types.
  48.   static ArgKind MakeMatcherArg(ASTNodeKind MatcherKind) {
  49.     return ArgKind{AK_Matcher, MatcherKind};
  50.   }
  51.  
  52.   static ArgKind MakeNodeArg(ASTNodeKind MatcherKind) {
  53.     return ArgKind{AK_Node, MatcherKind};
  54.   }
  55.  
  56.   Kind getArgKind() const { return K; }
  57.   ASTNodeKind getMatcherKind() const {
  58.     assert(K == AK_Matcher);
  59.     return NodeKind;
  60.   }
  61.   ASTNodeKind getNodeKind() const {
  62.     assert(K == AK_Node);
  63.     return NodeKind;
  64.   }
  65.  
  66.   /// Determines if this type can be converted to \p To.
  67.   ///
  68.   /// \param To the requested destination type.
  69.   ///
  70.   /// \param Specificity value corresponding to the "specificity" of the
  71.   ///   conversion.
  72.   bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
  73.  
  74.   bool operator<(const ArgKind &Other) const {
  75.     if ((K == AK_Matcher && Other.K == AK_Matcher) ||
  76.         (K == AK_Node && Other.K == AK_Node))
  77.       return NodeKind < Other.NodeKind;
  78.     return K < Other.K;
  79.   }
  80.  
  81.   /// String representation of the type.
  82.   std::string asString() const;
  83.  
  84. private:
  85.   ArgKind(Kind K, ASTNodeKind NK) : K(K), NodeKind(NK) {}
  86.   Kind K;
  87.   ASTNodeKind NodeKind;
  88. };
  89.  
  90. using ast_matchers::internal::DynTypedMatcher;
  91.  
  92. /// A variant matcher object.
  93. ///
  94. /// The purpose of this object is to abstract simple and polymorphic matchers
  95. /// into a single object type.
  96. /// Polymorphic matchers might be implemented as a list of all the possible
  97. /// overloads of the matcher. \c VariantMatcher knows how to select the
  98. /// appropriate overload when needed.
  99. /// To get a real matcher object out of a \c VariantMatcher you can do:
  100. ///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
  101. ///    to decide which matcher to return. Eg. it contains only a single
  102. ///    matcher, or a polymorphic one with only one overload.
  103. ///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
  104. ///    the underlying matcher(s) can unambiguously return a Matcher<T>.
  105. class VariantMatcher {
  106.   /// Methods that depend on T from hasTypedMatcher/getTypedMatcher.
  107.   class MatcherOps {
  108.   public:
  109.     MatcherOps(ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
  110.  
  111.     bool canConstructFrom(const DynTypedMatcher &Matcher,
  112.                           bool &IsExactMatch) const;
  113.  
  114.     /// Convert \p Matcher the destination type and return it as a new
  115.     /// DynTypedMatcher.
  116.     DynTypedMatcher convertMatcher(const DynTypedMatcher &Matcher) const;
  117.  
  118.     /// Constructs a variadic typed matcher from \p InnerMatchers.
  119.     /// Will try to convert each inner matcher to the destination type and
  120.     /// return std::nullopt if it fails to do so.
  121.     std::optional<DynTypedMatcher>
  122.     constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
  123.                               ArrayRef<VariantMatcher> InnerMatchers) const;
  124.  
  125.   private:
  126.     ASTNodeKind NodeKind;
  127.   };
  128.  
  129.   /// Payload interface to be specialized by each matcher type.
  130.   ///
  131.   /// It follows a similar interface as VariantMatcher itself.
  132.   class Payload {
  133.   public:
  134.     virtual ~Payload();
  135.     virtual std::optional<DynTypedMatcher> getSingleMatcher() const = 0;
  136.     virtual std::string getTypeAsString() const = 0;
  137.     virtual std::optional<DynTypedMatcher>
  138.     getTypedMatcher(const MatcherOps &Ops) const = 0;
  139.     virtual bool isConvertibleTo(ASTNodeKind Kind,
  140.                                  unsigned *Specificity) const = 0;
  141.   };
  142.  
  143. public:
  144.   /// A null matcher.
  145.   VariantMatcher();
  146.  
  147.   /// Clones the provided matcher.
  148.   static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
  149.  
  150.   /// Clones the provided matchers.
  151.   ///
  152.   /// They should be the result of a polymorphic matcher.
  153.   static VariantMatcher
  154.   PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
  155.  
  156.   /// Creates a 'variadic' operator matcher.
  157.   ///
  158.   /// It will bind to the appropriate type on getTypedMatcher<T>().
  159.   static VariantMatcher
  160.   VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
  161.                           std::vector<VariantMatcher> Args);
  162.  
  163.   /// Makes the matcher the "null" matcher.
  164.   void reset();
  165.  
  166.   /// Whether the matcher is null.
  167.   bool isNull() const { return !Value; }
  168.  
  169.   /// Return a single matcher, if there is no ambiguity.
  170.   ///
  171.   /// \returns the matcher, if there is only one matcher. An empty Optional, if
  172.   /// the underlying matcher is a polymorphic matcher with more than one
  173.   /// representation.
  174.   std::optional<DynTypedMatcher> getSingleMatcher() const;
  175.  
  176.   /// Determines if the contained matcher can be converted to
  177.   ///   \c Matcher<T>.
  178.   ///
  179.   /// For the Single case, it returns true if it can be converted to
  180.   /// \c Matcher<T>.
  181.   /// For the Polymorphic case, it returns true if one, and only one, of the
  182.   /// overloads can be converted to \c Matcher<T>. If there are more than one
  183.   /// that can, the result would be ambiguous and false is returned.
  184.   template <class T>
  185.   bool hasTypedMatcher() const {
  186.     return hasTypedMatcher(ASTNodeKind::getFromNodeKind<T>());
  187.   }
  188.  
  189.   bool hasTypedMatcher(ASTNodeKind NK) const {
  190.     if (!Value) return false;
  191.     return Value->getTypedMatcher(MatcherOps(NK)).has_value();
  192.   }
  193.  
  194.   /// Determines if the contained matcher can be converted to \p Kind.
  195.   ///
  196.   /// \param Kind the requested destination type.
  197.   ///
  198.   /// \param Specificity value corresponding to the "specificity" of the
  199.   ///   conversion.
  200.   bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const {
  201.     if (Value)
  202.       return Value->isConvertibleTo(Kind, Specificity);
  203.     return false;
  204.   }
  205.  
  206.   /// Return this matcher as a \c Matcher<T>.
  207.   ///
  208.   /// Handles the different types (Single, Polymorphic) accordingly.
  209.   /// Asserts that \c hasTypedMatcher<T>() is true.
  210.   template <class T>
  211.   ast_matchers::internal::Matcher<T> getTypedMatcher() const {
  212.     assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
  213.     return Value->getTypedMatcher(MatcherOps(ASTNodeKind::getFromNodeKind<T>()))
  214.         ->template convertTo<T>();
  215.   }
  216.  
  217.   DynTypedMatcher getTypedMatcher(ASTNodeKind NK) const {
  218.     assert(hasTypedMatcher(NK) && "hasTypedMatcher(NK) == false");
  219.     return *Value->getTypedMatcher(MatcherOps(NK));
  220.   }
  221.  
  222.   /// String representation of the type of the value.
  223.   ///
  224.   /// If the underlying matcher is a polymorphic one, the string will show all
  225.   /// the types.
  226.   std::string getTypeAsString() const;
  227.  
  228. private:
  229.   explicit VariantMatcher(std::shared_ptr<Payload> Value)
  230.       : Value(std::move(Value)) {}
  231.  
  232.  
  233.   class SinglePayload;
  234.   class PolymorphicPayload;
  235.   class VariadicOpPayload;
  236.  
  237.   std::shared_ptr<const Payload> Value;
  238. };
  239.  
  240. /// Variant value class.
  241. ///
  242. /// Basically, a tagged union with value type semantics.
  243. /// It is used by the registry as the return value and argument type for the
  244. /// matcher factory methods.
  245. /// It can be constructed from any of the supported types. It supports
  246. /// copy/assignment.
  247. ///
  248. /// Supported types:
  249. ///  - \c bool
  250. //   - \c double
  251. ///  - \c unsigned
  252. ///  - \c llvm::StringRef
  253. ///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
  254. class VariantValue {
  255. public:
  256.   VariantValue() : Type(VT_Nothing) {}
  257.  
  258.   VariantValue(const VariantValue &Other);
  259.   ~VariantValue();
  260.   VariantValue &operator=(const VariantValue &Other);
  261.  
  262.   /// Specific constructors for each supported type.
  263.   VariantValue(bool Boolean);
  264.   VariantValue(double Double);
  265.   VariantValue(unsigned Unsigned);
  266.   VariantValue(StringRef String);
  267.   VariantValue(ASTNodeKind NodeKind);
  268.   VariantValue(const VariantMatcher &Matchers);
  269.  
  270.   /// Constructs an \c unsigned value (disambiguation from bool).
  271.   VariantValue(int Signed) : VariantValue(static_cast<unsigned>(Signed)) {}
  272.  
  273.   /// Returns true iff this is not an empty value.
  274.   explicit operator bool() const { return hasValue(); }
  275.   bool hasValue() const { return Type != VT_Nothing; }
  276.  
  277.   /// Boolean value functions.
  278.   bool isBoolean() const;
  279.   bool getBoolean() const;
  280.   void setBoolean(bool Boolean);
  281.  
  282.   /// Double value functions.
  283.   bool isDouble() const;
  284.   double getDouble() const;
  285.   void setDouble(double Double);
  286.  
  287.   /// Unsigned value functions.
  288.   bool isUnsigned() const;
  289.   unsigned getUnsigned() const;
  290.   void setUnsigned(unsigned Unsigned);
  291.  
  292.   /// String value functions.
  293.   bool isString() const;
  294.   const std::string &getString() const;
  295.   void setString(StringRef String);
  296.  
  297.   bool isNodeKind() const;
  298.   const ASTNodeKind &getNodeKind() const;
  299.   void setNodeKind(ASTNodeKind NodeKind);
  300.  
  301.   /// Matcher value functions.
  302.   bool isMatcher() const;
  303.   const VariantMatcher &getMatcher() const;
  304.   void setMatcher(const VariantMatcher &Matcher);
  305.  
  306.   /// Determines if the contained value can be converted to \p Kind.
  307.   ///
  308.   /// \param Kind the requested destination type.
  309.   ///
  310.   /// \param Specificity value corresponding to the "specificity" of the
  311.   ///   conversion.
  312.   bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
  313.  
  314.   /// Determines if the contained value can be converted to any kind
  315.   /// in \p Kinds.
  316.   ///
  317.   /// \param Kinds the requested destination types.
  318.   ///
  319.   /// \param Specificity value corresponding to the "specificity" of the
  320.   ///   conversion. It is the maximum specificity of all the possible
  321.   ///   conversions.
  322.   bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
  323.  
  324.   /// String representation of the type of the value.
  325.   std::string getTypeAsString() const;
  326.  
  327. private:
  328.   void reset();
  329.  
  330.   /// All supported value types.
  331.   enum ValueType {
  332.     VT_Nothing,
  333.     VT_Boolean,
  334.     VT_Double,
  335.     VT_Unsigned,
  336.     VT_String,
  337.     VT_Matcher,
  338.     VT_NodeKind
  339.   };
  340.  
  341.   /// All supported value types.
  342.   union AllValues {
  343.     unsigned Unsigned;
  344.     double Double;
  345.     bool Boolean;
  346.     std::string *String;
  347.     VariantMatcher *Matcher;
  348.     ASTNodeKind *NodeKind;
  349.   };
  350.  
  351.   ValueType Type;
  352.   AllValues Value;
  353. };
  354.  
  355. } // end namespace dynamic
  356. } // end namespace ast_matchers
  357. } // end namespace clang
  358.  
  359. #endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
  360.