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