File indexing completed on 2026-05-10 08:36:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
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
0032
0033
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
0045 ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
0046
0047
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
0067
0068
0069
0070
0071
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
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
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 class VariantMatcher {
0106
0107 class MatcherOps {
0108 public:
0109 MatcherOps(ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
0110
0111 bool canConstructFrom(const DynTypedMatcher &Matcher,
0112 bool &IsExactMatch) const;
0113
0114
0115
0116 DynTypedMatcher convertMatcher(const DynTypedMatcher &Matcher) const;
0117
0118
0119
0120
0121 std::optional<DynTypedMatcher>
0122 constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
0123 ArrayRef<VariantMatcher> InnerMatchers) const;
0124
0125 private:
0126 ASTNodeKind NodeKind;
0127 };
0128
0129
0130
0131
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
0145 VariantMatcher();
0146
0147
0148 static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
0149
0150
0151
0152
0153 static VariantMatcher
0154 PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
0155
0156
0157
0158
0159 static VariantMatcher
0160 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
0161 std::vector<VariantMatcher> Args);
0162
0163
0164 void reset();
0165
0166
0167 bool isNull() const { return !Value; }
0168
0169
0170
0171
0172
0173
0174 std::optional<DynTypedMatcher> getSingleMatcher() const;
0175
0176
0177
0178
0179
0180
0181
0182
0183
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
0195
0196
0197
0198
0199
0200 bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const {
0201 if (Value)
0202 return Value->isConvertibleTo(Kind, Specificity);
0203 return false;
0204 }
0205
0206
0207
0208
0209
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
0223
0224
0225
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
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
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
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
0271 VariantValue(int Signed) : VariantValue(static_cast<unsigned>(Signed)) {}
0272
0273
0274 explicit operator bool() const { return hasValue(); }
0275 bool hasValue() const { return Type != VT_Nothing; }
0276
0277
0278 bool isBoolean() const;
0279 bool getBoolean() const;
0280 void setBoolean(bool Boolean);
0281
0282
0283 bool isDouble() const;
0284 double getDouble() const;
0285 void setDouble(double Double);
0286
0287
0288 bool isUnsigned() const;
0289 unsigned getUnsigned() const;
0290 void setUnsigned(unsigned Unsigned);
0291
0292
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
0302 bool isMatcher() const;
0303 const VariantMatcher &getMatcher() const;
0304 void setMatcher(const VariantMatcher &Matcher);
0305
0306
0307
0308
0309
0310
0311
0312 bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
0323
0324
0325 std::string getTypeAsString() const;
0326
0327 private:
0328 void reset();
0329
0330
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
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 }
0356 }
0357 }
0358
0359 #endif