| //===--- Variantvalue.cpp -------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "mlir/Query/Matcher/VariantValue.h" | |
| namespace mlir::query::matcher { | |
| VariantMatcher::Payload::~Payload() = default; | |
| class VariantMatcher::SinglePayload : public VariantMatcher::Payload { | |
| public: | |
| explicit SinglePayload(DynMatcher matcher) : matcher(std::move(matcher)) {} | |
| std::optional<DynMatcher> getDynMatcher() const override { return matcher; } | |
| std::string getTypeAsString() const override { return "Matcher"; } | |
| private: | |
| DynMatcher matcher; | |
| }; | |
| class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload { | |
| public: | |
| VariadicOpPayload(DynMatcher::VariadicOperator varOp, | |
| std::vector<VariantMatcher> args) | |
| : varOp(varOp), args(std::move(args)) {} | |
| std::optional<DynMatcher> getDynMatcher() const override { | |
| std::vector<DynMatcher> dynMatchers; | |
| for (const auto &variantMatcher : args) { | |
| std::optional<DynMatcher> dynMatcher = variantMatcher.getDynMatcher(); | |
| if (dynMatcher) | |
| dynMatchers.push_back(dynMatcher.value()); | |
| } | |
| auto result = DynMatcher::constructVariadic(varOp, dynMatchers); | |
| return *result; | |
| } | |
| std::string getTypeAsString() const override { | |
| std::string inner; | |
| llvm::interleave( | |
| args, [&](auto const &arg) { inner += arg.getTypeAsString(); }, | |
| [&] { inner += " & "; }); | |
| return inner; | |
| } | |
| private: | |
| const DynMatcher::VariadicOperator varOp; | |
| const std::vector<VariantMatcher> args; | |
| }; | |
| VariantMatcher::VariantMatcher() = default; | |
| VariantMatcher VariantMatcher::SingleMatcher(DynMatcher matcher) { | |
| return VariantMatcher(std::make_shared<SinglePayload>(std::move(matcher))); | |
| } | |
| VariantMatcher | |
| VariantMatcher::VariadicOperatorMatcher(DynMatcher::VariadicOperator varOp, | |
| ArrayRef<VariantMatcher> args) { | |
| return VariantMatcher(std::make_shared<VariadicOpPayload>(varOp, args)); | |
| } | |
| std::optional<DynMatcher> VariantMatcher::MatcherOps::constructVariadicOperator( | |
| DynMatcher::VariadicOperator varOp, | |
| ArrayRef<VariantMatcher> innerMatchers) const { | |
| std::vector<DynMatcher> dynMatchers; | |
| for (const auto &innerMatcher : innerMatchers) { | |
| if (!innerMatcher.value) | |
| return std::nullopt; | |
| std::optional<DynMatcher> inner = innerMatcher.value->getDynMatcher(); | |
| if (!inner) | |
| return std::nullopt; | |
| dynMatchers.push_back(*inner); | |
| } | |
| return *DynMatcher::constructVariadic(varOp, dynMatchers); | |
| } | |
| std::optional<DynMatcher> VariantMatcher::getDynMatcher() const { | |
| return value ? value->getDynMatcher() : std::nullopt; | |
| } | |
| void VariantMatcher::reset() { value.reset(); } | |
| std::string VariantMatcher::getTypeAsString() const { return "<Nothing>"; } | |
| VariantValue::VariantValue(const VariantValue &other) | |
| : type(ValueType::Nothing) { | |
| *this = other; | |
| } | |
| VariantValue::VariantValue(const llvm::StringRef string) | |
| : type(ValueType::String) { | |
| value.String = new llvm::StringRef(string); | |
| } | |
| VariantValue::VariantValue(const VariantMatcher &matcher) | |
| : type(ValueType::Matcher) { | |
| value.Matcher = new VariantMatcher(matcher); | |
| } | |
| VariantValue::VariantValue(int64_t signedValue) : type(ValueType::Signed) { | |
| value.Signed = signedValue; | |
| } | |
| VariantValue::VariantValue(bool setBoolean) : type(ValueType::Boolean) { | |
| value.Boolean = setBoolean; | |
| } | |
| VariantValue::~VariantValue() { reset(); } | |
| VariantValue &VariantValue::operator=(const VariantValue &other) { | |
| if (this == &other) | |
| return *this; | |
| reset(); | |
| switch (other.type) { | |
| case ValueType::String: | |
| setString(other.getString()); | |
| break; | |
| case ValueType::Matcher: | |
| setMatcher(other.getMatcher()); | |
| break; | |
| case ValueType::Signed: | |
| setSigned(other.getSigned()); | |
| break; | |
| case ValueType::Boolean: | |
| setBoolean(other.getBoolean()); | |
| break; | |
| case ValueType::Nothing: | |
| type = ValueType::Nothing; | |
| break; | |
| } | |
| return *this; | |
| } | |
| void VariantValue::reset() { | |
| switch (type) { | |
| case ValueType::String: | |
| delete value.String; | |
| break; | |
| case ValueType::Matcher: | |
| delete value.Matcher; | |
| break; | |
| // Cases that do nothing. | |
| case ValueType::Signed: | |
| case ValueType::Boolean: | |
| case ValueType::Nothing: | |
| break; | |
| } | |
| type = ValueType::Nothing; | |
| } | |
| // Signed | |
| bool VariantValue::isSigned() const { return type == ValueType::Signed; } | |
| int64_t VariantValue::getSigned() const { return value.Signed; } | |
| void VariantValue::setSigned(int64_t newValue) { | |
| type = ValueType::Signed; | |
| value.Signed = newValue; | |
| } | |
| // Boolean | |
| bool VariantValue::isBoolean() const { return type == ValueType::Boolean; } | |
| bool VariantValue::getBoolean() const { return value.Boolean; } | |
| void VariantValue::setBoolean(bool newValue) { | |
| type = ValueType::Boolean; | |
| value.Boolean = newValue; | |
| } | |
| bool VariantValue::isString() const { return type == ValueType::String; } | |
| const llvm::StringRef &VariantValue::getString() const { | |
| assert(isString()); | |
| return *value.String; | |
| } | |
| void VariantValue::setString(const llvm::StringRef &newValue) { | |
| reset(); | |
| type = ValueType::String; | |
| value.String = new llvm::StringRef(newValue); | |
| } | |
| bool VariantValue::isMatcher() const { return type == ValueType::Matcher; } | |
| const VariantMatcher &VariantValue::getMatcher() const { | |
| assert(isMatcher()); | |
| return *value.Matcher; | |
| } | |
| void VariantValue::setMatcher(const VariantMatcher &newValue) { | |
| reset(); | |
| type = ValueType::Matcher; | |
| value.Matcher = new VariantMatcher(newValue); | |
| } | |
| std::string VariantValue::getTypeAsString() const { | |
| switch (type) { | |
| case ValueType::String: | |
| return "String"; | |
| case ValueType::Matcher: | |
| return "Matcher"; | |
| case ValueType::Signed: | |
| return "Signed"; | |
| case ValueType::Boolean: | |
| return "Boolean"; | |
| case ValueType::Nothing: | |
| return "Nothing"; | |
| } | |
| llvm_unreachable("Invalid Type"); | |
| } | |
| } // namespace mlir::query::matcher |