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        ["replaceImmediateSubAttribute"]>
118  ]> {
119
120  let mnemonic = "sub_elements_access";
121
122  let parameters = (ins
123    "::mlir::Attribute":$first,
124    "::mlir::Attribute":$second,
125    "::mlir::Attribute":$third
126  );
127  let hasCustomAssemblyFormat = 1;
128}
129
130// A more complex parameterized attribute with multiple level of nesting.
131def CompoundNestedInner : Test_Attr<"CompoundNestedInner"> {
132  let mnemonic = "cmpnd_nested_inner";
133  // List of type parameters.
134  let parameters = (
135    ins
136    "int":$some_int,
137    CompoundAttrA:$cmpdA
138  );
139  let assemblyFormat = "`<` $some_int $cmpdA `>`";
140}
141
142def CompoundNestedOuter : Test_Attr<"CompoundNestedOuter"> {
143  let mnemonic = "cmpnd_nested_outer";
144
145  // List of type parameters.
146  let parameters = (
147    ins
148    CompoundNestedInner:$inner
149  );
150  let assemblyFormat = "`<` `i`  $inner `>`";
151}
152
153def CompoundNestedOuterQual : Test_Attr<"CompoundNestedOuterQual"> {
154  let mnemonic = "cmpnd_nested_outer_qual";
155
156  // List of type parameters.
157  let parameters = (ins CompoundNestedInner:$inner);
158  let assemblyFormat = "`<` `i`  qualified($inner) `>`";
159}
160
161def TestParamOne : AttrParameter<"int64_t", ""> {}
162
163def TestParamTwo : AttrParameter<"std::string", "", "llvm::StringRef"> {
164  let printer = "$_printer << '\"' << $_self << '\"'";
165}
166
167def TestParamFour : ArrayRefParameter<"int", ""> {
168  let cppStorageType = "llvm::SmallVector<int>";
169  let parser = "::parseIntArray($_parser)";
170  let printer = "::printIntArray($_printer, $_self)";
171}
172
173def TestAttrWithFormat : Test_Attr<"TestAttrWithFormat"> {
174  let parameters = (
175    ins
176    TestParamOne:$one,
177    TestParamTwo:$two,
178    "::mlir::IntegerAttr":$three,
179    TestParamFour:$four,
180    // Array of another attribute.
181    ArrayRefParameter<
182      "AttrWithTypeBuilderAttr", // The parameter C++ type.
183      "An example of an array of another Attribute" // Parameter description.
184      >: $arrayOfAttrWithTypeBuilderAttr
185  );
186
187  let mnemonic = "attr_with_format";
188  let assemblyFormat = [{
189    `<` $one `:` struct($two, $four) `:` $three `,`
190    `[` `` $arrayOfAttrWithTypeBuilderAttr `]` `>`
191  }];
192  let genVerifyDecl = 1;
193}
194
195def TestAttrUgly : Test_Attr<"TestAttrUgly"> {
196  let parameters = (ins "::mlir::Attribute":$attr);
197
198  let mnemonic = "attr_ugly";
199  let assemblyFormat = "`begin` $attr `end`";
200}
201
202def TestAttrParams: Test_Attr<"TestAttrParams"> {
203  let parameters = (ins "int":$v0, "int":$v1);
204
205  let mnemonic = "attr_params";
206  let assemblyFormat = "`<` params `>`";
207}
208
209// Test types can be parsed/printed.
210def TestAttrWithTypeParam : Test_Attr<"TestAttrWithTypeParam"> {
211  let parameters = (ins "::mlir::IntegerType":$int_type,
212                        "::mlir::Type":$any_type);
213  let mnemonic = "attr_with_type";
214  let assemblyFormat = "`<` $int_type `,` $any_type `>`";
215}
216
217// Test self type parameter with assembly format.
218def TestAttrSelfTypeParameterFormat
219    : Test_Attr<"TestAttrSelfTypeParameterFormat"> {
220  let parameters = (ins "int":$a, AttributeSelfTypeParameter<"">:$type);
221
222  let mnemonic = "attr_self_type_format";
223  let assemblyFormat = "`<` $a `>`";
224}
225
226// Test overridding attribute builders with a custom builder.
227def TestOverrideBuilderAttr : Test_Attr<"TestOverrideBuilder"> {
228  let mnemonic = "override_builder";
229  let parameters = (ins "int":$a);
230  let assemblyFormat = "`<` $a `>`";
231
232  let skipDefaultBuilders = 1;
233  let genVerifyDecl = 1;
234  let builders = [AttrBuilder<(ins "int":$a), [{
235    return ::mlir::IntegerAttr::get(::mlir::IndexType::get($_ctxt), a);
236  }], "::mlir::Attribute">];
237}
238
239// Test simple extern 1D vector using ElementsAttrInterface.
240def TestExtern1DI64ElementsAttr : Test_Attr<"TestExtern1DI64Elements", [
241    ElementsAttrInterface
242  ]> {
243  let mnemonic = "e1di64_elements";
244  let parameters = (ins
245    AttributeSelfTypeParameter<"", "::mlir::ShapedType">:$type,
246    ResourceHandleParameter<"TestExternalElementsDataHandle">:$handle
247  );
248  let extraClassDeclaration = [{
249    /// Return the elements referenced by this attribute.
250    llvm::ArrayRef<uint64_t> getElements() const;
251
252    /// The set of data types that can be iterated by this attribute.
253    using ContiguousIterableTypesT = std::tuple<uint64_t>;
254
255    /// Provide begin iterators for the various iterable types.
256    // * uint64_t
257    auto value_begin_impl(OverloadToken<uint64_t>) const {
258      return getElements().begin();
259    }
260  }];
261  let assemblyFormat = "`<` $handle `>`";
262}
263
264#endif // TEST_ATTRDEFS
265