1//===-- TestTypeDefs.td - Test dialect type definitions ----*- tablegen -*-===//
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// TableGen data type definitions for Test dialect.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef TEST_TYPEDEFS
14#define TEST_TYPEDEFS
15
16// To get the test dialect def.
17include "TestDialect.td"
18include "TestAttrDefs.td"
19include "TestInterfaces.td"
20include "mlir/IR/BuiltinTypes.td"
21include "mlir/Interfaces/DataLayoutInterfaces.td"
22
23// All of the types will extend this class.
24class Test_Type<string name, list<Trait> traits = []>
25    : TypeDef<Test_Dialect, name, traits>;
26
27def SimpleTypeA : Test_Type<"SimpleA"> {
28  let mnemonic = "smpla";
29}
30
31// A more complex parameterized type.
32def CompoundTypeA : Test_Type<"CompoundA"> {
33  let mnemonic = "cmpnd_a";
34
35  // List of type parameters.
36  let parameters = (
37    ins
38    "int":$widthOfSomething,
39    "::mlir::Type":$oneType,
40    // This is special syntax since ArrayRefs require allocation in the
41    // constructor.
42    ArrayRefParameter<
43      "int", // The parameter C++ type.
44      "An example of an array of ints" // Parameter description.
45    >:$arrayOfInts
46  );
47
48  let extraClassDeclaration = [{
49    struct SomeCppStruct {};
50  }];
51  let hasCustomAssemblyFormat = 1;
52}
53
54// A more complex and nested parameterized type.
55def CompoundNestedInnerType : Test_Type<"CompoundNestedInner"> {
56  let mnemonic = "cmpnd_inner";
57  // List of type parameters.
58  let parameters = (
59    ins
60    "int":$some_int,
61    CompoundTypeA:$cmpdA
62  );
63  let assemblyFormat = "`<` $some_int $cmpdA `>`";
64}
65
66def CompoundNestedOuterType : Test_Type<"CompoundNestedOuter"> {
67  let mnemonic = "cmpnd_nested_outer";
68
69  // List of type parameters.
70  let parameters = (ins CompoundNestedInnerType:$inner);
71  let assemblyFormat = "`<` `i`  $inner `>`";
72}
73
74def CompoundNestedOuterTypeQual : Test_Type<"CompoundNestedOuterQual"> {
75  let mnemonic = "cmpnd_nested_outer_qual";
76
77  // List of type parameters.
78  let parameters = (
79    ins
80    CompoundNestedInnerType:$inner
81  );
82  let assemblyFormat = "`<` `i`  qualified($inner) `>`";
83}
84
85// An example of how one could implement a standard integer.
86def IntegerType : Test_Type<"TestInteger"> {
87  let mnemonic = "int";
88  let genVerifyDecl = 1;
89  let parameters = (
90    ins
91    "unsigned":$width,
92    // SignednessSemantics is defined below.
93    "::test::TestIntegerType::SignednessSemantics":$signedness
94  );
95
96  // Indicate we use a custom format.
97  let hasCustomAssemblyFormat = 1;
98
99  // Define custom builder methods.
100  let builders = [
101    TypeBuilder<(ins "unsigned":$width,
102                     CArg<"SignednessSemantics", "Signless">:$signedness), [{
103      return $_get($_ctxt, width, signedness);
104    }]>
105  ];
106  let skipDefaultBuilders = 1;
107
108  // Any extra code one wants in the type's class declaration.
109  let extraClassDeclaration = [{
110    /// Signedness semantics.
111    enum SignednessSemantics {
112      Signless, /// No signedness semantics
113      Signed,   /// Signed integer
114      Unsigned, /// Unsigned integer
115    };
116
117    /// Return true if this is a signless integer type.
118    bool isSignless() const { return getSignedness() == Signless; }
119    /// Return true if this is a signed integer type.
120    bool isSigned() const { return getSignedness() == Signed; }
121    /// Return true if this is an unsigned integer type.
122    bool isUnsigned() const { return getSignedness() == Unsigned; }
123  }];
124}
125
126// A parent type for any type which is just a list of fields (e.g. structs,
127// unions).
128class FieldInfo_Type<string name> : Test_Type<name> {
129  let parameters = (
130    ins
131    // An ArrayRef of something which requires allocation in the storage
132    // constructor.
133    ArrayRefOfSelfAllocationParameter<
134      "::test::FieldInfo", // FieldInfo is defined/declared in TestTypes.h.
135      "Models struct fields">: $fields
136  );
137  let hasCustomAssemblyFormat = 1;
138}
139
140def StructType : FieldInfo_Type<"Struct"> {
141    let mnemonic = "struct";
142}
143
144def TestType : Test_Type<"Test", [
145  DeclareTypeInterfaceMethods<TestTypeInterface>
146]> {
147  let mnemonic = "test_type";
148}
149
150def TestTypeWithLayoutType : Test_Type<"TestTypeWithLayout", [
151  DeclareTypeInterfaceMethods<DataLayoutTypeInterface, ["areCompatible"]>
152]> {
153  let mnemonic = "test_type_with_layout";
154  let parameters = (ins "unsigned":$key);
155  let extraClassDeclaration = [{
156    ::mlir::LogicalResult verifyEntries(::mlir::DataLayoutEntryListRef params,
157                                ::mlir::Location loc) const;
158
159  private:
160    unsigned extractKind(::mlir::DataLayoutEntryListRef params,
161                         ::llvm::StringRef expectedKind) const;
162
163  public:
164  }];
165  let hasCustomAssemblyFormat = 1;
166}
167
168def TestMemRefElementType : Test_Type<"TestMemRefElementType",
169                                      [MemRefElementTypeInterface]> {
170  let mnemonic = "memref_element";
171}
172
173def TestTypeTrait : NativeTypeTrait<"TestTypeTrait">;
174
175// The definition of a singleton type that has a trait.
176def TestTypeWithTrait : Test_Type<"TestTypeWithTrait", [TestTypeTrait]> {
177  let mnemonic = "test_type_with_trait";
178}
179
180// Type with assembly format.
181def TestTypeWithFormat : Test_Type<"TestTypeWithFormat"> {
182  let parameters = (
183    ins
184    TestParamOne:$one,
185    TestParamTwo:$two,
186    "::mlir::Attribute":$three
187  );
188
189  let mnemonic = "type_with_format";
190  let assemblyFormat = "`<` $one `,` struct($three, $two) `>`";
191}
192
193// Test dispatch to parseField
194def TestTypeNoParser : Test_Type<"TestTypeNoParser"> {
195  let parameters = (
196    ins
197    "uint32_t":$one,
198    ArrayRefParameter<"int64_t">:$two,
199    StringRefParameter<>:$three,
200    "::test::CustomParam":$four
201  );
202
203  let mnemonic = "no_parser";
204  let assemblyFormat = "`<` $one `,` `[` $two `]` `,` $three `,` $four `>`";
205}
206
207def TestTypeStructCaptureAll : Test_Type<"TestStructTypeCaptureAll"> {
208  let parameters = (
209    ins
210    "int":$v0,
211    "int":$v1,
212    "int":$v2,
213    "int":$v3
214  );
215
216  let mnemonic = "struct_capture_all";
217  let assemblyFormat = "`<` struct(params) `>`";
218}
219
220def TestTypeOptionalParam : Test_Type<"TestTypeOptionalParam"> {
221  let parameters = (ins OptionalParameter<"mlir::Optional<int>">:$a, "int":$b);
222  let mnemonic = "optional_param";
223  let assemblyFormat = "`<` $a `,` $b `>`";
224}
225
226def TestTypeOptionalParams : Test_Type<"TestTypeOptionalParams"> {
227  let parameters = (ins OptionalParameter<"mlir::Optional<int>">:$a,
228                        StringRefParameter<>:$b);
229  let mnemonic = "optional_params";
230  let assemblyFormat = "`<` params `>`";
231}
232
233def TestTypeOptionalParamsAfterRequired
234    : Test_Type<"TestTypeOptionalParamsAfterRequired"> {
235  let parameters = (ins StringRefParameter<>:$a,
236                        OptionalParameter<"mlir::Optional<int>">:$b);
237  let mnemonic = "optional_params_after";
238  let assemblyFormat = "`<` params `>`";
239}
240
241def TestTypeOptionalStruct : Test_Type<"TestTypeOptionalStruct"> {
242  let parameters = (ins OptionalParameter<"mlir::Optional<int>">:$a,
243                        StringRefParameter<>:$b);
244  let mnemonic = "optional_struct";
245  let assemblyFormat = "`<` struct(params) `>`";
246}
247
248def TestTypeAllOptionalParams : Test_Type<"TestTypeAllOptionalParams"> {
249  let parameters = (ins OptionalParameter<"mlir::Optional<int>">:$a,
250                        OptionalParameter<"mlir::Optional<int>">:$b);
251  let mnemonic = "all_optional_params";
252  let assemblyFormat = "`<` params `>`";
253}
254
255def TestTypeAllOptionalStruct : Test_Type<"TestTypeAllOptionalStruct"> {
256  let parameters = (ins OptionalParameter<"mlir::Optional<int>">:$a,
257                        OptionalParameter<"mlir::Optional<int>">:$b);
258  let mnemonic = "all_optional_struct";
259  let assemblyFormat = "`<` struct(params) `>`";
260}
261
262def TestTypeOptionalGroup : Test_Type<"TestTypeOptionalGroup"> {
263  let parameters = (ins "int":$a, OptionalParameter<"mlir::Optional<int>">:$b);
264  let mnemonic = "optional_group";
265  let assemblyFormat = "`<` (`(` $b^ `)`) : (`x`)? $a `>`";
266}
267
268def TestTypeOptionalGroupParams : Test_Type<"TestTypeOptionalGroupParams"> {
269  let parameters = (ins DefaultValuedParameter<"mlir::Optional<int>", "10">:$a,
270                        OptionalParameter<"mlir::Optional<int>">:$b);
271  let mnemonic = "optional_group_params";
272  let assemblyFormat = "`<` (`(` params^ `)`) : (`x`)? `>`";
273}
274
275def TestTypeOptionalGroupStruct : Test_Type<"TestTypeOptionalGroupStruct"> {
276  let parameters = (ins OptionalParameter<"mlir::Optional<int>">:$a,
277                        OptionalParameter<"mlir::Optional<int>">:$b);
278  let mnemonic = "optional_group_struct";
279  let assemblyFormat = "`<` (`(` struct(params)^ `)`) : (`x`)? `>`";
280}
281
282def TestTypeSpaces : Test_Type<"TestTypeSpaceS"> {
283  let parameters = (ins "int":$a, "int":$b);
284  let mnemonic = "spaces";
285  let assemblyFormat = "`<` ` ` $a `\\n` `(` `)` `` `(` `)` $b `>`";
286}
287
288class DefaultValuedAPFloat<string value>
289    : DefaultValuedParameter<"llvm::Optional<llvm::APFloat>",
290                             "llvm::Optional<llvm::APFloat>(" # value # ")"> {
291  let comparator = "$_lhs->bitwiseIsEqual(*$_rhs)";
292  let parser = [{ [&]() -> mlir::FailureOr<llvm::Optional<llvm::APFloat>> {
293    mlir::FloatAttr attr;
294    auto result = $_parser.parseOptionalAttribute(attr);
295    if (result.hasValue() && mlir::succeeded(*result))
296      return {attr.getValue()};
297    if (!result.hasValue())
298      return llvm::Optional<llvm::APFloat>();
299    return mlir::failure();
300  }() }];
301  let printer = "$_printer << *$_self";
302}
303
304def TestTypeAPFloat : Test_Type<"TestTypeAPFloat"> {
305  let parameters = (ins
306    DefaultValuedAPFloat<"APFloat::getZero(APFloat::IEEEdouble())">:$a
307  );
308  let mnemonic = "ap_float";
309  let assemblyFormat = "`<` $a `>`";
310}
311
312def TestTypeDefaultValuedType : Test_Type<"TestTypeDefaultValuedType"> {
313  let parameters = (ins
314    DefaultValuedParameter<"mlir::IntegerType",
315                           "mlir::IntegerType::get($_ctxt, 32)">:$type
316  );
317  let mnemonic = "default_valued_type";
318  let assemblyFormat = "`<` (`(` $type^ `)`)? `>`";
319}
320
321def TestTypeCustom : Test_Type<"TestTypeCustom"> {
322  let parameters = (ins "int":$a, OptionalParameter<"mlir::Optional<int>">:$b);
323  let mnemonic = "custom_type";
324  let assemblyFormat = [{ `<` custom<CustomTypeA>($a)
325                              custom<CustomTypeB>(ref($a), $b) `>` }];
326}
327
328def TestTypeCustomString : Test_Type<"TestTypeCustomString"> {
329  let parameters = (ins StringRefParameter<>:$foo);
330  let mnemonic = "custom_type_string";
331  let assemblyFormat = [{ `<` custom<FooString>($foo)
332                              custom<BarString>(ref($foo)) `>` }];
333}
334
335#endif // TEST_TYPEDEFS
336