1//===--- Variantvalue.cpp -------------------------------------------------===//
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//
10//===----------------------------------------------------------------------===//
11
12#include "mlir/Query/Matcher/VariantValue.h"
13
14namespace mlir::query::matcher {
15
16VariantMatcher::Payload::~Payload() = default;
17
18class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
19public:
20 explicit SinglePayload(DynMatcher matcher) : matcher(std::move(matcher)) {}
21
22 std::optional<DynMatcher> getDynMatcher() const override { return matcher; }
23
24 std::string getTypeAsString() const override { return "Matcher"; }
25
26private:
27 DynMatcher matcher;
28};
29
30class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
31public:
32 VariadicOpPayload(DynMatcher::VariadicOperator varOp,
33 std::vector<VariantMatcher> args)
34 : varOp(varOp), args(std::move(args)) {}
35
36 std::optional<DynMatcher> getDynMatcher() const override {
37 std::vector<DynMatcher> dynMatchers;
38 for (auto variantMatcher : args) {
39 std::optional<DynMatcher> dynMatcher = variantMatcher.getDynMatcher();
40 if (dynMatcher)
41 dynMatchers.push_back(x: dynMatcher.value());
42 }
43 auto result = DynMatcher::constructVariadic(Op: varOp, innerMatchers: dynMatchers);
44 return *result;
45 }
46
47 std::string getTypeAsString() const override {
48 std::string inner;
49 llvm::interleave(
50 c: args, each_fn: [&](auto const &arg) { inner += arg.getTypeAsString(); },
51 between_fn: [&] { inner += " & "; });
52 return inner;
53 }
54
55private:
56 const DynMatcher::VariadicOperator varOp;
57 const std::vector<VariantMatcher> args;
58};
59
60VariantMatcher::VariantMatcher() = default;
61
62VariantMatcher VariantMatcher::SingleMatcher(DynMatcher matcher) {
63 return VariantMatcher(std::make_shared<SinglePayload>(args: std::move(matcher)));
64}
65
66VariantMatcher
67VariantMatcher::VariadicOperatorMatcher(DynMatcher::VariadicOperator varOp,
68 ArrayRef<VariantMatcher> args) {
69 return VariantMatcher(
70 std::make_shared<VariadicOpPayload>(args&: varOp, args: std::move(args)));
71}
72
73std::optional<DynMatcher> VariantMatcher::MatcherOps::constructVariadicOperator(
74 DynMatcher::VariadicOperator varOp,
75 ArrayRef<VariantMatcher> innerMatchers) const {
76 std::vector<DynMatcher> dynMatchers;
77 for (const auto &innerMatcher : innerMatchers) {
78 if (!innerMatcher.value)
79 return std::nullopt;
80 std::optional<DynMatcher> inner = innerMatcher.value->getDynMatcher();
81 if (!inner)
82 return std::nullopt;
83 dynMatchers.push_back(x: *inner);
84 }
85 return *DynMatcher::constructVariadic(Op: varOp, innerMatchers: dynMatchers);
86}
87
88std::optional<DynMatcher> VariantMatcher::getDynMatcher() const {
89 return value ? value->getDynMatcher() : std::nullopt;
90}
91
92void VariantMatcher::reset() { value.reset(); }
93
94std::string VariantMatcher::getTypeAsString() const { return "<Nothing>"; }
95
96VariantValue::VariantValue(const VariantValue &other)
97 : type(ValueType::Nothing) {
98 *this = other;
99}
100
101VariantValue::VariantValue(const llvm::StringRef string)
102 : type(ValueType::String) {
103 value.String = new llvm::StringRef(string);
104}
105
106VariantValue::VariantValue(const VariantMatcher &matcher)
107 : type(ValueType::Matcher) {
108 value.Matcher = new VariantMatcher(matcher);
109}
110
111VariantValue::VariantValue(int64_t signedValue) : type(ValueType::Signed) {
112 value.Signed = signedValue;
113}
114
115VariantValue::VariantValue(bool setBoolean) : type(ValueType::Boolean) {
116 value.Boolean = setBoolean;
117}
118
119VariantValue::~VariantValue() { reset(); }
120
121VariantValue &VariantValue::operator=(const VariantValue &other) {
122 if (this == &other)
123 return *this;
124 reset();
125 switch (other.type) {
126 case ValueType::String:
127 setString(other.getString());
128 break;
129 case ValueType::Matcher:
130 setMatcher(other.getMatcher());
131 break;
132 case ValueType::Signed:
133 setSigned(other.getSigned());
134 break;
135 case ValueType::Boolean:
136 setBoolean(other.getBoolean());
137 break;
138 case ValueType::Nothing:
139 type = ValueType::Nothing;
140 break;
141 }
142 return *this;
143}
144
145void VariantValue::reset() {
146 switch (type) {
147 case ValueType::String:
148 delete value.String;
149 break;
150 case ValueType::Matcher:
151 delete value.Matcher;
152 break;
153 // Cases that do nothing.
154 case ValueType::Signed:
155 case ValueType::Boolean:
156 case ValueType::Nothing:
157 break;
158 }
159 type = ValueType::Nothing;
160}
161
162// Signed
163bool VariantValue::isSigned() const { return type == ValueType::Signed; }
164
165int64_t VariantValue::getSigned() const { return value.Signed; }
166
167void VariantValue::setSigned(int64_t newValue) {
168 type = ValueType::Signed;
169 value.Signed = newValue;
170}
171
172// Boolean
173bool VariantValue::isBoolean() const { return type == ValueType::Boolean; }
174
175bool VariantValue::getBoolean() const { return value.Boolean; }
176
177void VariantValue::setBoolean(bool newValue) {
178 type = ValueType::Boolean;
179 value.Boolean = newValue;
180}
181
182bool VariantValue::isString() const { return type == ValueType::String; }
183
184const llvm::StringRef &VariantValue::getString() const {
185 assert(isString());
186 return *value.String;
187}
188
189void VariantValue::setString(const llvm::StringRef &newValue) {
190 reset();
191 type = ValueType::String;
192 value.String = new llvm::StringRef(newValue);
193}
194
195bool VariantValue::isMatcher() const { return type == ValueType::Matcher; }
196
197const VariantMatcher &VariantValue::getMatcher() const {
198 assert(isMatcher());
199 return *value.Matcher;
200}
201
202void VariantValue::setMatcher(const VariantMatcher &newValue) {
203 reset();
204 type = ValueType::Matcher;
205 value.Matcher = new VariantMatcher(newValue);
206}
207
208std::string VariantValue::getTypeAsString() const {
209 switch (type) {
210 case ValueType::String:
211 return "String";
212 case ValueType::Matcher:
213 return "Matcher";
214 case ValueType::Signed:
215 return "Signed";
216 case ValueType::Boolean:
217 return "Boolean";
218 case ValueType::Nothing:
219 return "Nothing";
220 }
221 llvm_unreachable("Invalid Type");
222}
223
224} // namespace mlir::query::matcher
225

source code of mlir/lib/Query/Matcher/VariantValue.cpp