Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:46

0001 //===--- VariantValue.h - Polymorphic value type ----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Polymorphic value type.
0011 ///
0012 /// Supports all the types required for dynamic Matcher construction.
0013 ///  Used by the registry to construct matchers in a generic way.
0014 ///
0015 //===----------------------------------------------------------------------===//
0016 
0017 #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
0018 #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
0019 
0020 #include "clang/ASTMatchers/ASTMatchers.h"
0021 #include "clang/ASTMatchers/ASTMatchersInternal.h"
0022 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0023 #include <memory>
0024 #include <optional>
0025 #include <vector>
0026 
0027 namespace clang {
0028 namespace ast_matchers {
0029 namespace dynamic {
0030 
0031 /// Kind identifier.
0032 ///
0033 /// It supports all types that VariantValue can contain.
0034 class ArgKind {
0035  public:
0036   enum Kind {
0037     AK_Matcher,
0038     AK_Node,
0039     AK_Boolean,
0040     AK_Double,
0041     AK_Unsigned,
0042     AK_String
0043   };
0044   /// Constructor for non-matcher types.
0045   ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
0046 
0047   /// Constructor for matcher types.
0048   static ArgKind MakeMatcherArg(ASTNodeKind MatcherKind) {
0049     return ArgKind{AK_Matcher, MatcherKind};
0050   }
0051 
0052   static ArgKind MakeNodeArg(ASTNodeKind MatcherKind) {
0053     return ArgKind{AK_Node, MatcherKind};
0054   }
0055 
0056   Kind getArgKind() const { return K; }
0057   ASTNodeKind getMatcherKind() const {
0058     assert(K == AK_Matcher);
0059     return NodeKind;
0060   }
0061   ASTNodeKind getNodeKind() const {
0062     assert(K == AK_Node);
0063     return NodeKind;
0064   }
0065 
0066   /// Determines if this type can be converted to \p To.
0067   ///
0068   /// \param To the requested destination type.
0069   ///
0070   /// \param Specificity value corresponding to the "specificity" of the
0071   ///   conversion.
0072   bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
0073 
0074   bool operator<(const ArgKind &Other) const {
0075     if ((K == AK_Matcher && Other.K == AK_Matcher) ||
0076         (K == AK_Node && Other.K == AK_Node))
0077       return NodeKind < Other.NodeKind;
0078     return K < Other.K;
0079   }
0080 
0081   /// String representation of the type.
0082   std::string asString() const;
0083 
0084 private:
0085   ArgKind(Kind K, ASTNodeKind NK) : K(K), NodeKind(NK) {}
0086   Kind K;
0087   ASTNodeKind NodeKind;
0088 };
0089 
0090 using ast_matchers::internal::DynTypedMatcher;
0091 
0092 /// A variant matcher object.
0093 ///
0094 /// The purpose of this object is to abstract simple and polymorphic matchers
0095 /// into a single object type.
0096 /// Polymorphic matchers might be implemented as a list of all the possible
0097 /// overloads of the matcher. \c VariantMatcher knows how to select the
0098 /// appropriate overload when needed.
0099 /// To get a real matcher object out of a \c VariantMatcher you can do:
0100 ///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
0101 ///    to decide which matcher to return. Eg. it contains only a single
0102 ///    matcher, or a polymorphic one with only one overload.
0103 ///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
0104 ///    the underlying matcher(s) can unambiguously return a Matcher<T>.
0105 class VariantMatcher {
0106   /// Methods that depend on T from hasTypedMatcher/getTypedMatcher.
0107   class MatcherOps {
0108   public:
0109     MatcherOps(ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
0110 
0111     bool canConstructFrom(const DynTypedMatcher &Matcher,
0112                           bool &IsExactMatch) const;
0113 
0114     /// Convert \p Matcher the destination type and return it as a new
0115     /// DynTypedMatcher.
0116     DynTypedMatcher convertMatcher(const DynTypedMatcher &Matcher) const;
0117 
0118     /// Constructs a variadic typed matcher from \p InnerMatchers.
0119     /// Will try to convert each inner matcher to the destination type and
0120     /// return std::nullopt if it fails to do so.
0121     std::optional<DynTypedMatcher>
0122     constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
0123                               ArrayRef<VariantMatcher> InnerMatchers) const;
0124 
0125   private:
0126     ASTNodeKind NodeKind;
0127   };
0128 
0129   /// Payload interface to be specialized by each matcher type.
0130   ///
0131   /// It follows a similar interface as VariantMatcher itself.
0132   class Payload {
0133   public:
0134     virtual ~Payload();
0135     virtual std::optional<DynTypedMatcher> getSingleMatcher() const = 0;
0136     virtual std::string getTypeAsString() const = 0;
0137     virtual std::optional<DynTypedMatcher>
0138     getTypedMatcher(const MatcherOps &Ops) const = 0;
0139     virtual bool isConvertibleTo(ASTNodeKind Kind,
0140                                  unsigned *Specificity) const = 0;
0141   };
0142 
0143 public:
0144   /// A null matcher.
0145   VariantMatcher();
0146 
0147   /// Clones the provided matcher.
0148   static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
0149 
0150   /// Clones the provided matchers.
0151   ///
0152   /// They should be the result of a polymorphic matcher.
0153   static VariantMatcher
0154   PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
0155 
0156   /// Creates a 'variadic' operator matcher.
0157   ///
0158   /// It will bind to the appropriate type on getTypedMatcher<T>().
0159   static VariantMatcher
0160   VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
0161                           std::vector<VariantMatcher> Args);
0162 
0163   /// Makes the matcher the "null" matcher.
0164   void reset();
0165 
0166   /// Whether the matcher is null.
0167   bool isNull() const { return !Value; }
0168 
0169   /// Return a single matcher, if there is no ambiguity.
0170   ///
0171   /// \returns the matcher, if there is only one matcher. An empty Optional, if
0172   /// the underlying matcher is a polymorphic matcher with more than one
0173   /// representation.
0174   std::optional<DynTypedMatcher> getSingleMatcher() const;
0175 
0176   /// Determines if the contained matcher can be converted to
0177   ///   \c Matcher<T>.
0178   ///
0179   /// For the Single case, it returns true if it can be converted to
0180   /// \c Matcher<T>.
0181   /// For the Polymorphic case, it returns true if one, and only one, of the
0182   /// overloads can be converted to \c Matcher<T>. If there are more than one
0183   /// that can, the result would be ambiguous and false is returned.
0184   template <class T>
0185   bool hasTypedMatcher() const {
0186     return hasTypedMatcher(ASTNodeKind::getFromNodeKind<T>());
0187   }
0188 
0189   bool hasTypedMatcher(ASTNodeKind NK) const {
0190     if (!Value) return false;
0191     return Value->getTypedMatcher(MatcherOps(NK)).has_value();
0192   }
0193 
0194   /// Determines if the contained matcher can be converted to \p Kind.
0195   ///
0196   /// \param Kind the requested destination type.
0197   ///
0198   /// \param Specificity value corresponding to the "specificity" of the
0199   ///   conversion.
0200   bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const {
0201     if (Value)
0202       return Value->isConvertibleTo(Kind, Specificity);
0203     return false;
0204   }
0205 
0206   /// Return this matcher as a \c Matcher<T>.
0207   ///
0208   /// Handles the different types (Single, Polymorphic) accordingly.
0209   /// Asserts that \c hasTypedMatcher<T>() is true.
0210   template <class T>
0211   ast_matchers::internal::Matcher<T> getTypedMatcher() const {
0212     assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
0213     return Value->getTypedMatcher(MatcherOps(ASTNodeKind::getFromNodeKind<T>()))
0214         ->template convertTo<T>();
0215   }
0216 
0217   DynTypedMatcher getTypedMatcher(ASTNodeKind NK) const {
0218     assert(hasTypedMatcher(NK) && "hasTypedMatcher(NK) == false");
0219     return *Value->getTypedMatcher(MatcherOps(NK));
0220   }
0221 
0222   /// String representation of the type of the value.
0223   ///
0224   /// If the underlying matcher is a polymorphic one, the string will show all
0225   /// the types.
0226   std::string getTypeAsString() const;
0227 
0228 private:
0229   explicit VariantMatcher(std::shared_ptr<Payload> Value)
0230       : Value(std::move(Value)) {}
0231 
0232 
0233   class SinglePayload;
0234   class PolymorphicPayload;
0235   class VariadicOpPayload;
0236 
0237   std::shared_ptr<const Payload> Value;
0238 };
0239 
0240 /// Variant value class.
0241 ///
0242 /// Basically, a tagged union with value type semantics.
0243 /// It is used by the registry as the return value and argument type for the
0244 /// matcher factory methods.
0245 /// It can be constructed from any of the supported types. It supports
0246 /// copy/assignment.
0247 ///
0248 /// Supported types:
0249 ///  - \c bool
0250 //   - \c double
0251 ///  - \c unsigned
0252 ///  - \c llvm::StringRef
0253 ///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
0254 class VariantValue {
0255 public:
0256   VariantValue() : Type(VT_Nothing) {}
0257 
0258   VariantValue(const VariantValue &Other);
0259   ~VariantValue();
0260   VariantValue &operator=(const VariantValue &Other);
0261 
0262   /// Specific constructors for each supported type.
0263   VariantValue(bool Boolean);
0264   VariantValue(double Double);
0265   VariantValue(unsigned Unsigned);
0266   VariantValue(StringRef String);
0267   VariantValue(ASTNodeKind NodeKind);
0268   VariantValue(const VariantMatcher &Matchers);
0269 
0270   /// Constructs an \c unsigned value (disambiguation from bool).
0271   VariantValue(int Signed) : VariantValue(static_cast<unsigned>(Signed)) {}
0272 
0273   /// Returns true iff this is not an empty value.
0274   explicit operator bool() const { return hasValue(); }
0275   bool hasValue() const { return Type != VT_Nothing; }
0276 
0277   /// Boolean value functions.
0278   bool isBoolean() const;
0279   bool getBoolean() const;
0280   void setBoolean(bool Boolean);
0281 
0282   /// Double value functions.
0283   bool isDouble() const;
0284   double getDouble() const;
0285   void setDouble(double Double);
0286 
0287   /// Unsigned value functions.
0288   bool isUnsigned() const;
0289   unsigned getUnsigned() const;
0290   void setUnsigned(unsigned Unsigned);
0291 
0292   /// String value functions.
0293   bool isString() const;
0294   const std::string &getString() const;
0295   void setString(StringRef String);
0296 
0297   bool isNodeKind() const;
0298   const ASTNodeKind &getNodeKind() const;
0299   void setNodeKind(ASTNodeKind NodeKind);
0300 
0301   /// Matcher value functions.
0302   bool isMatcher() const;
0303   const VariantMatcher &getMatcher() const;
0304   void setMatcher(const VariantMatcher &Matcher);
0305 
0306   /// Determines if the contained value can be converted to \p Kind.
0307   ///
0308   /// \param Kind the requested destination type.
0309   ///
0310   /// \param Specificity value corresponding to the "specificity" of the
0311   ///   conversion.
0312   bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
0313 
0314   /// Determines if the contained value can be converted to any kind
0315   /// in \p Kinds.
0316   ///
0317   /// \param Kinds the requested destination types.
0318   ///
0319   /// \param Specificity value corresponding to the "specificity" of the
0320   ///   conversion. It is the maximum specificity of all the possible
0321   ///   conversions.
0322   bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
0323 
0324   /// String representation of the type of the value.
0325   std::string getTypeAsString() const;
0326 
0327 private:
0328   void reset();
0329 
0330   /// All supported value types.
0331   enum ValueType {
0332     VT_Nothing,
0333     VT_Boolean,
0334     VT_Double,
0335     VT_Unsigned,
0336     VT_String,
0337     VT_Matcher,
0338     VT_NodeKind
0339   };
0340 
0341   /// All supported value types.
0342   union AllValues {
0343     unsigned Unsigned;
0344     double Double;
0345     bool Boolean;
0346     std::string *String;
0347     VariantMatcher *Matcher;
0348     ASTNodeKind *NodeKind;
0349   };
0350 
0351   ValueType Type;
0352   AllValues Value;
0353 };
0354 
0355 } // end namespace dynamic
0356 } // end namespace ast_matchers
0357 } // end namespace clang
0358 
0359 #endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H