1//===-- TestAttrDefs.td - Test dialect attr 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 attribute definitions for Test dialect.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef TEST_ATTRDEFS
14#define TEST_ATTRDEFS
15
16// To get the test dialect definition.
17include "TestDialect.td"
18include "mlir/IR/AttrTypeBase.td"
19include "mlir/IR/BuiltinAttributeInterfaces.td"
20include "mlir/IR/OpAsmInterface.td"
21include "mlir/IR/SubElementInterfaces.td"
22
23// All of the attributes will extend this class.
24class Test_Attr<string name, list<Trait> traits = []>
25    : AttrDef<Test_Dialect, name, traits>;
26
27def SimpleAttrA : Test_Attr<"SimpleA"> {
28  let mnemonic = "smpla";
29}
30
31// A more complex parameterized attribute.
32def CompoundAttrA : Test_Attr<"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  let hasCustomAssemblyFormat = 1;
48}
49def CompoundAttrNested : Test_Attr<"CompoundAttrNested"> {
50  let mnemonic = "cmpnd_nested";
51  let parameters = (ins CompoundAttrA : $nested );
52  let assemblyFormat = "`<` `nested` `=` $nested `>`";
53}
54
55// An attribute testing AttributeSelfTypeParameter.
56def AttrWithSelfTypeParam : Test_Attr<"AttrWithSelfTypeParam"> {
57  let mnemonic = "attr_with_self_type_param";
58  let parameters = (ins AttributeSelfTypeParameter<"">:$type);
59  let assemblyFormat = "";
60}
61
62// An attribute testing AttributeSelfTypeParameter.
63def AttrWithTypeBuilder : Test_Attr<"AttrWithTypeBuilder"> {
64  let mnemonic = "attr_with_type_builder";
65  let parameters = (ins "::mlir::IntegerAttr":$attr);
66  let typeBuilder = "$_attr.getType()";
67  let hasCustomAssemblyFormat = 1;
68}
69
70def TestAttrTrait : NativeAttrTrait<"TestAttrTrait">;
71
72// The definition of a singleton attribute that has a trait.
73def AttrWithTrait : Test_Attr<"AttrWithTrait", [TestAttrTrait]> {
74  let mnemonic = "attr_with_trait";
75}
76
77// Test support for ElementsAttrInterface.
78def TestI64ElementsAttr : Test_Attr<"TestI64Elements", [
79    ElementsAttrInterface
80  ]> {
81  let mnemonic = "i64_elements";
82  let parameters = (ins
83    AttributeSelfTypeParameter<"", "::mlir::ShapedType">:$type,
84    ArrayRefParameter<"uint64_t">:$elements
85  );
86  let extraClassDeclaration = [{
87    /// The set of data types that can be iterated by this attribute.
88    using ContiguousIterableTypesT = std::tuple<uint64_t>;
89    using NonContiguousIterableTypesT = std::tuple<mlir::Attribute, llvm::APInt>;
90
91    /// Provide begin iterators for the various iterable types.
92    // * uint64_t
93    auto value_begin_impl(OverloadToken<uint64_t>) const {
94      return getElements().begin();
95    }
96    // * Attribute
97    auto value_begin_impl(OverloadToken<mlir::Attribute>) const {
98      mlir::Type elementType = getType().getElementType();
99      return llvm::map_range(getElements(), [=](uint64_t value) {
100        return mlir::IntegerAttr::get(elementType,
101                                      llvm::APInt(/*numBits=*/64, value));
102      }).begin();
103    }
104    // * APInt
105    auto value_begin_impl(OverloadToken<llvm::APInt>) const {
106      return llvm::map_range(getElements(), [=](uint64_t value) {
107        return llvm::APInt(/*numBits=*/64, value);
108      }).begin();
109    }
110  }];
111  let genVerifyDecl = 1;
112  let hasCustomAssemblyFormat = 1;
113}
114
115def TestSubElementsAccessAttr : Test_Attr<"TestSubElementsAccess", [
116    DeclareAttrInterfaceMethods<SubElementAttrInterface,
117        ["replaceImmediateSubElements"]>
118  ]> {
119  let mnemonic = "sub_elements_access";
120
121  let parameters = (ins
122    "::mlir::Attribute":$first,
123    "::mlir::Attribute":$second,
124    "::mlir::Attribute":$third
125  );
126  let hasCustomAssemblyFormat = 1;
127}
128
129// A more complex parameterized attribute with multiple level of nesting.
130def CompoundNestedInner : Test_Attr<"CompoundNestedInner"> {
131  let mnemonic = "cmpnd_nested_inner";
132  // List of type parameters.
133  let parameters = (
134    ins
135    "int":$some_int,
136    CompoundAttrA:$cmpdA
137  );
138  let assemblyFormat = "`<` $some_int $cmpdA `>`";
139}
140
141def CompoundNestedOuter : Test_Attr<"CompoundNestedOuter"> {
142  let mnemonic = "cmpnd_nested_outer";
143
144  // List of type parameters.
145  let parameters = (
146    ins
147    CompoundNestedInner:$inner
148  );
149  let assemblyFormat = "`<` `i`  $inner `>`";
150}
151
152def CompoundNestedOuterQual : Test_Attr<"CompoundNestedOuterQual"> {
153  let mnemonic = "cmpnd_nested_outer_qual";
154
155  // List of type parameters.
156  let parameters = (ins CompoundNestedInner:$inner);
157  let assemblyFormat = "`<` `i`  qualified($inner) `>`";
158}
159
160def TestParamOne : AttrParameter<"int64_t", ""> {}
161
162def TestParamTwo : AttrParameter<"std::string", "", "llvm::StringRef"> {
163  let printer = "$_printer << '\"' << $_self << '\"'";
164}
165
166def TestParamFour : ArrayRefParameter<"int", ""> {
167  let cppStorageType = "llvm::SmallVector<int>";
168  let parser = "::parseIntArray($_parser)";
169  let printer = "::printIntArray($_printer, $_self)";
170}
171
172def TestAttrWithFormat : Test_Attr<"TestAttrWithFormat"> {
173  let parameters = (
174    ins
175    TestParamOne:$one,
176    TestParamTwo:$two,
177    "::mlir::IntegerAttr":$three,
178    TestParamFour:$four,
179    // Array of another attribute.
180    ArrayRefParameter<
181      "AttrWithTypeBuilderAttr", // The parameter C++ type.
182      "An example of an array of another Attribute" // Parameter description.
183      >: $arrayOfAttrWithTypeBuilderAttr
184  );
185
186  let mnemonic = "attr_with_format";
187  let assemblyFormat = [{
188    `<` $one `:` struct($two, $four) `:` $three `,`
189    `[` `` $arrayOfAttrWithTypeBuilderAttr `]` `>`
190  }];
191  let genVerifyDecl = 1;
192}
193
194def TestAttrUgly : Test_Attr<"TestAttrUgly"> {
195  let parameters = (ins "::mlir::Attribute":$attr);
196
197  let mnemonic = "attr_ugly";
198  let assemblyFormat = "`begin` $attr `end`";
199}
200
201def TestAttrParams: Test_Attr<"TestAttrParams"> {
202  let parameters = (ins "int":$v0, "int":$v1);
203
204  let mnemonic = "attr_params";
205  let assemblyFormat = "`<` params `>`";
206}
207
208// Test types can be parsed/printed.
209def TestAttrWithTypeParam : Test_Attr<"TestAttrWithTypeParam"> {
210  let parameters = (ins "::mlir::IntegerType":$int_type,
211                        "::mlir::Type":$any_type);
212  let mnemonic = "attr_with_type";
213  let assemblyFormat = "`<` $int_type `,` $any_type `>`";
214}
215
216// Test self type parameter with assembly format.
217def TestAttrSelfTypeParameterFormat
218    : Test_Attr<"TestAttrSelfTypeParameterFormat"> {
219  let parameters = (ins "int":$a, AttributeSelfTypeParameter<"">:$type);
220
221  let mnemonic = "attr_self_type_format";
222  let assemblyFormat = "`<` $a `>`";
223}
224
225// Test overridding attribute builders with a custom builder.
226def TestOverrideBuilderAttr : Test_Attr<"TestOverrideBuilder"> {
227  let mnemonic = "override_builder";
228  let parameters = (ins "int":$a);
229  let assemblyFormat = "`<` $a `>`";
230
231  let skipDefaultBuilders = 1;
232  let genVerifyDecl = 1;
233  let builders = [AttrBuilder<(ins "int":$a), [{
234    return ::mlir::IntegerAttr::get(::mlir::IndexType::get($_ctxt), a);
235  }], "::mlir::Attribute">];
236}
237
238// Test simple extern 1D vector using ElementsAttrInterface.
239def TestExtern1DI64ElementsAttr : Test_Attr<"TestExtern1DI64Elements", [
240    ElementsAttrInterface
241  ]> {
242  let mnemonic = "e1di64_elements";
243  let parameters = (ins
244    AttributeSelfTypeParameter<"", "::mlir::ShapedType">:$type,
245    ResourceHandleParameter<"TestExternalElementsDataHandle">:$handle
246  );
247  let extraClassDeclaration = [{
248    /// Return the elements referenced by this attribute.
249    llvm::ArrayRef<uint64_t> getElements() const;
250
251    /// The set of data types that can be iterated by this attribute.
252    using ContiguousIterableTypesT = std::tuple<uint64_t>;
253
254    /// Provide begin iterators for the various iterable types.
255    // * uint64_t
256    auto value_begin_impl(OverloadToken<uint64_t>) const {
257      return getElements().begin();
258    }
259  }];
260  let assemblyFormat = "`<` $handle `>`";
261}
262
263#endif // TEST_ATTRDEFS
264