1 //===--- VariantValue.h -----------------------------------------*- 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 // Supports all the types required for dynamic Matcher construction. 10 // Used by the registry to construct matchers in a generic way. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef MLIR_TOOLS_MLIRQUERY_MATCHER_VARIANTVALUE_H 15 #define MLIR_TOOLS_MLIRQUERY_MATCHER_VARIANTVALUE_H 16 17 #include "ErrorBuilder.h" 18 #include "MatchersInternal.h" 19 #include "llvm/ADT/StringRef.h" 20 21 namespace mlir::query::matcher { 22 23 // All types that VariantValue can contain. 24 enum class ArgKind { Matcher, String }; 25 26 // A variant matcher object to abstract simple and complex matchers into a 27 // single object type. 28 class VariantMatcher { 29 class MatcherOps; 30 31 // Payload interface to be specialized by each matcher type. It follows a 32 // similar interface as VariantMatcher itself. 33 class Payload { 34 public: 35 virtual ~Payload(); 36 virtual std::optional<DynMatcher> getDynMatcher() const = 0; 37 virtual std::string getTypeAsString() const = 0; 38 }; 39 40 public: 41 // A null matcher. 42 VariantMatcher(); 43 44 // Clones the provided matcher. 45 static VariantMatcher SingleMatcher(DynMatcher matcher); 46 47 // Makes the matcher the "null" matcher. 48 void reset(); 49 50 // Checks if the matcher is null. isNull()51 bool isNull() const { return !value; } 52 53 // Returns the matcher 54 std::optional<DynMatcher> getDynMatcher() const; 55 56 // String representation of the type of the value. 57 std::string getTypeAsString() const; 58 59 private: VariantMatcher(std::shared_ptr<Payload> value)60 explicit VariantMatcher(std::shared_ptr<Payload> value) 61 : value(std::move(value)) {} 62 63 class SinglePayload; 64 65 std::shared_ptr<const Payload> value; 66 }; 67 68 // Variant value class with a tagged union with value type semantics. It is used 69 // by the registry as the return value and argument type for the matcher factory 70 // methods. It can be constructed from any of the supported types: 71 // - StringRef 72 // - VariantMatcher 73 class VariantValue { 74 public: VariantValue()75 VariantValue() : type(ValueType::Nothing) {} 76 77 VariantValue(const VariantValue &other); 78 ~VariantValue(); 79 VariantValue &operator=(const VariantValue &other); 80 81 // Specific constructors for each supported type. 82 VariantValue(const llvm::StringRef string); 83 VariantValue(const VariantMatcher &matcher); 84 85 // String value functions. 86 bool isString() const; 87 const llvm::StringRef &getString() const; 88 void setString(const llvm::StringRef &string); 89 90 // Matcher value functions. 91 bool isMatcher() const; 92 const VariantMatcher &getMatcher() const; 93 void setMatcher(const VariantMatcher &matcher); 94 95 // String representation of the type of the value. 96 std::string getTypeAsString() const; 97 98 private: 99 void reset(); 100 101 // All supported value types. 102 enum class ValueType { 103 Nothing, 104 String, 105 Matcher, 106 }; 107 108 // All supported value types. 109 union AllValues { 110 llvm::StringRef *String; 111 VariantMatcher *Matcher; 112 }; 113 114 ValueType type; 115 AllValues value; 116 }; 117 118 // A VariantValue instance annotated with its parser context. 119 struct ParserValue { ParserValueParserValue120 ParserValue() {} 121 llvm::StringRef text; 122 internal::SourceRange range; 123 VariantValue value; 124 }; 125 126 } // namespace mlir::query::matcher 127 128 #endif // MLIR_TOOLS_MLIRQUERY_MATCHER_VARIANTVALUE_H 129