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
17#include "mlir/IR/OpImplementation.h"
18
19namespace mlir {
20
21//===----------------------------------------------------------------------===//
22// DialectAsmPrinter
23//===----------------------------------------------------------------------===//
24
25/// This is a pure-virtual base class that exposes the asmprinter hooks
26/// necessary to implement a custom printAttribute/printType() method on a
27/// dialect.
28class DialectAsmPrinter : public AsmPrinter {
29public:
30 using AsmPrinter::AsmPrinter;
31 ~DialectAsmPrinter() override;
32};
33
34//===----------------------------------------------------------------------===//
35// DialectAsmParser
36//===----------------------------------------------------------------------===//
37
38/// The DialectAsmParser has methods for interacting with the asm parser when
39/// parsing attributes and types.
40class DialectAsmParser : public AsmParser {
41public:
42 using AsmParser::AsmParser;
43 ~DialectAsmParser() override;
44
45 /// Returns the full specification of the symbol being parsed. This allows for
46 /// using a separate parser if necessary.
47 virtual StringRef getFullSymbolSpec() const = 0;
48};
49
50//===----------------------------------------------------------------------===//
51// Parse Fields
52//===----------------------------------------------------------------------===//
53
54/// Provide a template class that can be specialized by users to dispatch to
55/// parsers. Auto-generated parsers generate calls to `FieldParser<T>::parse`,
56/// where `T` is the parameter storage type, to parse custom types.
57template <typename T, typename = T>
58struct FieldParser;
59
60/// Parse an attribute.
61template <typename AttributeT>
62struct FieldParser<
63 AttributeT, std::enable_if_t<std::is_base_of<Attribute, AttributeT>::value,
64 AttributeT>> {
65 static FailureOr<AttributeT> parse(AsmParser &parser) {
66 AttributeT value;
67 if (parser.parseCustomAttributeWithFallback(value))
68 return failure();
69 return value;
70 }
71};
72
73/// Parse an attribute.
74template <typename TypeT>
75struct FieldParser<
76 TypeT, std::enable_if_t<std::is_base_of<Type, TypeT>::value, TypeT>> {
77 static FailureOr<TypeT> parse(AsmParser &parser) {
78 TypeT value;
79 if (parser.parseCustomTypeWithFallback(value))
80 return failure();
81 return value;
82 }
83};
84
85/// Parse any integer.
86template <typename IntT>
87struct FieldParser<IntT,
88 std::enable_if_t<std::is_integral<IntT>::value, IntT>> {
89 static FailureOr<IntT> parse(AsmParser &parser) {
90 IntT value = 0;
91 if (parser.parseInteger(value))
92 return failure();
93 return value;
94 }
95};
96
97/// Parse a string.
98template <>
99struct FieldParser<std::string> {
100 static FailureOr<std::string> parse(AsmParser &parser) {
101 std::string value;
102 if (parser.parseString(string: &value))
103 return failure();
104 return value;
105 }
106};
107
108/// Parse an Optional attribute.
109template <typename AttributeT>
110struct FieldParser<
111 std::optional<AttributeT>,
112 std::enable_if_t<std::is_base_of<Attribute, AttributeT>::value,
113 std::optional<AttributeT>>> {
114 static FailureOr<std::optional<AttributeT>> parse(AsmParser &parser) {
115 AttributeT attr;
116 OptionalParseResult result = parser.parseOptionalAttribute(attr);
117 if (result.has_value()) {
118 if (succeeded(result: *result))
119 return {std::optional<AttributeT>(attr)};
120 return failure();
121 }
122 return {std::nullopt};
123 }
124};
125
126/// Parse an Optional integer.
127template <typename IntT>
128struct FieldParser<
129 std::optional<IntT>,
130 std::enable_if_t<std::is_integral<IntT>::value, std::optional<IntT>>> {
131 static FailureOr<std::optional<IntT>> parse(AsmParser &parser) {
132 IntT value;
133 OptionalParseResult result = parser.parseOptionalInteger(value);
134 if (result.has_value()) {
135 if (succeeded(result: *result))
136 return {std::optional<IntT>(value)};
137 return failure();
138 }
139 return {std::nullopt};
140 }
141};
142
143namespace detail {
144template <typename T>
145using has_push_back_t = decltype(std::declval<T>().push_back(
146 std::declval<typename T::value_type &&>()));
147} // namespace detail
148
149/// Parse any container that supports back insertion as a list.
150template <typename ContainerT>
151struct FieldParser<ContainerT,
152 std::enable_if_t<llvm::is_detected<detail::has_push_back_t,
153 ContainerT>::value,
154 ContainerT>> {
155 using ElementT = typename ContainerT::value_type;
156 static FailureOr<ContainerT> parse(AsmParser &parser) {
157 ContainerT elements;
158 auto elementParser = [&]() {
159 auto element = FieldParser<ElementT>::parse(parser);
160 if (failed(element))
161 return failure();
162 elements.push_back(std::move(*element));
163 return success();
164 };
165 if (parser.parseCommaSeparatedList(elementParser))
166 return failure();
167 return elements;
168 }
169};
170
171/// Parse an affine map.
172template <>
173struct FieldParser<AffineMap> {
174 static FailureOr<AffineMap> parse(AsmParser &parser) {
175 AffineMap map;
176 if (failed(result: parser.parseAffineMap(map)))
177 return failure();
178 return map;
179 }
180};
181
182} // namespace mlir
183
184#endif // MLIR_IR_DIALECTIMPLEMENTATION_H
185

source code of mlir/include/mlir/IR/DialectImplementation.h