MLIR 22.0.0git
DialectImplementation.h
Go to the documentation of this file.
1//===- DialectImplementation.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// This file contains utilities classes for implementing dialect attributes and
10// types.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_IR_DIALECTIMPLEMENTATION_H
15#define MLIR_IR_DIALECTIMPLEMENTATION_H
16
18#include <type_traits>
19
20namespace {
21
22// reference https://stackoverflow.com/a/16000226
23template <typename T, typename = void>
24struct HasStaticDialectName : std::false_type {};
25
26template <typename T>
27struct HasStaticDialectName<
28 T, typename std::enable_if<
29 std::is_same<::llvm::StringLiteral,
30 std::decay_t<decltype(T::dialectName)>>::value,
31 void>::type> : std::true_type {};
32
33} // namespace
34
35namespace mlir {
36
37//===----------------------------------------------------------------------===//
38// DialectAsmPrinter
39//===----------------------------------------------------------------------===//
40
41/// This is a pure-virtual base class that exposes the asmprinter hooks
42/// necessary to implement a custom printAttribute/printType() method on a
43/// dialect.
45public:
48};
49
50//===----------------------------------------------------------------------===//
51// DialectAsmParser
52//===----------------------------------------------------------------------===//
53
54/// The DialectAsmParser has methods for interacting with the asm parser when
55/// parsing attributes and types.
57public:
60
61 /// Returns the full specification of the symbol being parsed. This allows for
62 /// using a separate parser if necessary.
63 virtual StringRef getFullSymbolSpec() const = 0;
64};
65
66//===----------------------------------------------------------------------===//
67// Parse Fields
68//===----------------------------------------------------------------------===//
69
70/// Provide a template class that can be specialized by users to dispatch to
71/// parsers. Auto-generated parsers generate calls to `FieldParser<T>::parse`,
72/// where `T` is the parameter storage type, to parse custom types.
73template <typename T, typename = T>
75
76/// Parse an attribute.
77template <typename AttributeT>
79 AttributeT, std::enable_if_t<std::is_base_of<Attribute, AttributeT>::value,
80 AttributeT>> {
81 static FailureOr<AttributeT> parse(AsmParser &parser) {
82 if constexpr (HasStaticDialectName<AttributeT>::value) {
83 parser.getContext()->getOrLoadDialect(AttributeT::dialectName);
84 }
85 AttributeT value;
86 if (parser.parseCustomAttributeWithFallback(value))
87 return failure();
88 return value;
89 }
90};
91
92/// Parse a type.
93template <typename TypeT>
95 TypeT, std::enable_if_t<std::is_base_of<Type, TypeT>::value, TypeT>> {
96 static FailureOr<TypeT> parse(AsmParser &parser) {
97 TypeT value;
98 if (parser.parseCustomTypeWithFallback(value))
99 return failure();
100 return value;
101 }
102};
103
104/// Parse any integer.
105template <typename IntT>
106struct FieldParser<IntT, std::enable_if_t<(std::is_integral<IntT>::value ||
107 std::is_same_v<IntT, llvm::APInt>),
108 IntT>> {
109 static FailureOr<IntT> parse(AsmParser &parser) {
110 IntT value{};
111 if (parser.parseInteger(value))
112 return failure();
113 return value;
114 }
115};
116
117/// Parse a string.
118template <>
119struct FieldParser<std::string> {
120 static FailureOr<std::string> parse(AsmParser &parser) {
121 std::string value;
122 if (parser.parseString(&value))
123 return failure();
124 return value;
125 }
126};
127
128/// Parse an Optional attribute.
129template <typename AttributeT>
131 std::optional<AttributeT>,
132 std::enable_if_t<std::is_base_of<Attribute, AttributeT>::value,
133 std::optional<AttributeT>>> {
134 static FailureOr<std::optional<AttributeT>> parse(AsmParser &parser) {
135 if constexpr (HasStaticDialectName<AttributeT>::value) {
136 parser.getContext()->getOrLoadDialect(AttributeT::dialectName);
137 }
138 AttributeT attr;
140 if (result.has_value()) {
141 if (succeeded(*result))
142 return {std::optional<AttributeT>(attr)};
143 return failure();
144 }
145 return {std::nullopt};
146 }
147};
148
149/// Parse an Optional integer.
150template <typename IntT>
152 std::optional<IntT>,
153 std::enable_if_t<std::is_integral<IntT>::value, std::optional<IntT>>> {
154 static FailureOr<std::optional<IntT>> parse(AsmParser &parser) {
155 IntT value;
157 if (result.has_value()) {
158 if (succeeded(*result))
159 return {std::optional<IntT>(value)};
160 return failure();
161 }
162 return {std::nullopt};
163 }
164};
165
166namespace detail {
167template <typename T>
168using has_push_back_t = decltype(std::declval<T>().push_back(
169 std::declval<typename T::value_type &&>()));
170} // namespace detail
171
172/// Parse any container that supports back insertion as a list.
173template <typename ContainerT>
174struct FieldParser<ContainerT,
175 std::enable_if_t<llvm::is_detected<detail::has_push_back_t,
176 ContainerT>::value,
177 ContainerT>> {
178 using ElementT = typename ContainerT::value_type;
179 static FailureOr<ContainerT> parse(AsmParser &parser) {
180 ContainerT elements;
181 auto elementParser = [&]() {
182 auto element = FieldParser<ElementT>::parse(parser);
183 if (failed(element))
184 return failure();
185 elements.push_back(std::move(*element));
186 return success();
187 };
188 if (parser.parseCommaSeparatedList(elementParser))
189 return failure();
190 return elements;
191 }
192};
193
194/// Parse an affine map.
195template <>
197 static FailureOr<AffineMap> parse(AsmParser &parser) {
198 AffineMap map;
199 if (failed(parser.parseAffineMap(map)))
200 return failure();
201 return map;
202 }
203};
204
205} // namespace mlir
206
207#endif // MLIR_IR_DIALECTIMPLEMENTATION_H
return success()
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition AffineMap.h:46
This base class exposes generic asm parser hooks, usable across the various derived parsers.
virtual OptionalParseResult parseOptionalInteger(APInt &result)=0
Parse an optional integer value from the stream.
AsmParser()=default
virtual ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())=0
Parse a list of comma-separated items with an optional delimiter.
MLIRContext * getContext() const
ParseResult parseInteger(IntT &result)
Parse an integer value from the stream.
virtual ParseResult parseAffineMap(AffineMap &map)=0
Parse an affine map instance into 'map'.
virtual ParseResult parseCustomAttributeWithFallback(Attribute &result, Type type, function_ref< ParseResult(Attribute &result, Type type)> parseAttribute)=0
Parse a custom attribute with the provided callback, unless the next token is #, in which case the ge...
ParseResult parseString(std::string *string)
Parse a quoted string token.
virtual ParseResult parseCustomTypeWithFallback(Type &result, function_ref< ParseResult(Type &result)> parseType)=0
Parse a custom type with the provided callback, unless the next token is #, in which case the generic...
virtual OptionalParseResult parseOptionalAttribute(Attribute &result, Type type={})=0
Parse an arbitrary optional attribute of a given type and return it in result.
AsmPrinter(Impl &impl)
Initialize the printer with the given internal implementation.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
virtual StringRef getFullSymbolSpec() const =0
Returns the full specification of the symbol being parsed.
~DialectAsmParser() override
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
~DialectAsmPrinter() override
AsmPrinter(Impl &impl)
Initialize the printer with the given internal implementation.
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
This class implements Optional functionality for ParseResult.
decltype(std::declval< T >().push_back( std::declval< typename T::value_type && >())) has_push_back_t
Include the generated interface declarations.
static FailureOr< AffineMap > parse(AsmParser &parser)
static FailureOr< std::string > parse(AsmParser &parser)
Provide a template class that can be specialized by users to dispatch to parsers.