clang  19.0.0git
VariantValue.h
Go to the documentation of this file.
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 
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 {
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; }
58  assert(K == AK_Matcher);
59  return NodeKind;
60  }
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>.
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:
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>)
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);
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;
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;
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
Kind identifier.
Definition: ASTTypeTraits.h:51
The base class of the type hierarchy.
Definition: Type.h:1813
bool operator<(const ArgKind &Other) const
Definition: VariantValue.h:74
static ArgKind MakeMatcherArg(ASTNodeKind MatcherKind)
Constructor for matcher types.
Definition: VariantValue.h:48
std::string asString() const
String representation of the type.
static ArgKind MakeNodeArg(ASTNodeKind MatcherKind)
Definition: VariantValue.h:52
bool isConvertibleTo(ArgKind To, unsigned *Specificity) const
Determines if this type can be converted to To.
ArgKind(Kind K)
Constructor for non-matcher types.
Definition: VariantValue.h:45
ast_matchers::internal::Matcher< T > getTypedMatcher() const
Return this matcher as a Matcher<T>.
Definition: VariantValue.h:211
static VariantMatcher PolymorphicMatcher(std::vector< DynTypedMatcher > Matchers)
Clones the provided matchers.
DynTypedMatcher getTypedMatcher(ASTNodeKind NK) const
Definition: VariantValue.h:217
bool hasTypedMatcher(ASTNodeKind NK) const
Definition: VariantValue.h:189
bool hasTypedMatcher() const
Determines if the contained matcher can be converted to Matcher<T>.
Definition: VariantValue.h:185
void reset()
Makes the matcher the "null" matcher.
std::optional< DynTypedMatcher > getSingleMatcher() const
Return a single matcher, if there is no ambiguity.
bool isNull() const
Whether the matcher is null.
Definition: VariantValue.h:167
std::string getTypeAsString() const
String representation of the type of the value.
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const
Determines if the contained matcher can be converted to Kind.
Definition: VariantValue.h:200
static VariantMatcher VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, std::vector< VariantMatcher > Args)
Creates a 'variadic' operator matcher.
static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher)
Clones the provided matcher.
VariantValue(int Signed)
Constructs an unsigned value (disambiguation from bool).
Definition: VariantValue.h:271
bool isString() const
String value functions.
void setNodeKind(ASTNodeKind NodeKind)
const ASTNodeKind & getNodeKind() const
const std::string & getString() const
bool isUnsigned() const
Unsigned value functions.
std::string getTypeAsString() const
String representation of the type of the value.
bool isConvertibleTo(ArgKind Kind, unsigned *Specificity) const
Determines if the contained value can be converted to Kind.
const VariantMatcher & getMatcher() const
bool isMatcher() const
Matcher value functions.
bool isBoolean() const
Boolean value functions.
void setMatcher(const VariantMatcher &Matcher)
VariantValue & operator=(const VariantValue &Other)
bool isDouble() const
Double value functions.
NodeKind
A kind of a syntax node, used for implementing casts.
Definition: Nodes.h:32
The JSON file list parser is used to communicate input to InstallAPI.
@ Other
Other implicit parameter.
Definition: Format.h:5433
#define bool
Definition: stdbool.h:24