[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / mlir / test / mlir-tblgen / op-attribute.td
blob3dc426cbf5d7f54682c0969ed398c760b09e67d3
1 // RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL
2 // RUN: mlir-tblgen -gen-op-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF
3 // RUN: mlir-tblgen -print-records -I %S/../../include %s | FileCheck %s --check-prefix=RECORD
5 include "mlir/IR/AttrTypeBase.td"
6 include "mlir/IR/EnumAttr.td"
7 include "mlir/IR/OpBase.td"
9 def Test_Dialect : Dialect {
10   let name = "test";
11   let cppNamespace = "foobar";
13 class NS_Op<string mnemonic, list<Trait> traits> :
14     Op<Test_Dialect, mnemonic, traits>;
16 def SomeAttr : Attr<CPred<"some-condition">, "some attribute kind"> {
17   let storageType = "some-attr-kind";
18   let returnType = "some-return-type";
19   let convertFromStorage = "$_self.some-convert-from-storage()";
20   let constBuilderCall = "some-const-builder-call($_builder, $0)";
23 def SomeAttrDef : AttrDef<Test_Dialect, "SomeAttr"> {
27 // Test required, optional, default-valued attributes
28 // ---
30 def AOp : NS_Op<"a_op", []> {
31   let arguments = (ins
32       SomeAttr:$aAttr,
33       DefaultValuedAttr<SomeAttr, "4.2">:$bAttr,
34       OptionalAttr<SomeAttr>:$cAttr,
35       DefaultValuedOptionalAttr<SomeAttr, "4.2">:$dAttr
36   );
39 // DECL-LABEL: AOp declarations
41 // Test attribute name methods
42 // ---
44 // DECL:      static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames()
45 // DECL-NEXT:   static ::llvm::StringRef attrNames[] =
46 // DECL-SAME:     {::llvm::StringRef("aAttr"), ::llvm::StringRef("bAttr"), ::llvm::StringRef("cAttr"), ::llvm::StringRef("dAttr")};
47 // DECL-NEXT:   return ::llvm::ArrayRef(attrNames);
49 // DECL:      ::mlir::StringAttr getAAttrAttrName()
50 // DECL-NEXT:      return getAttributeNameForIndex(0);
51 // DECL:      ::mlir::StringAttr getAAttrAttrName(::mlir::OperationName name)
52 // DECL-NEXT:      return getAttributeNameForIndex(name, 0);
54 // DECL:      ::mlir::StringAttr getBAttrAttrName()
55 // DECL-NEXT:      return getAttributeNameForIndex(1);
56 // DECL:      ::mlir::StringAttr getBAttrAttrName(::mlir::OperationName name)
57 // DECL-NEXT:      return getAttributeNameForIndex(name, 1);
59 // DECL:      ::mlir::StringAttr getCAttrAttrName()
60 // DECL-NEXT:      return getAttributeNameForIndex(2);
61 // DECL:      ::mlir::StringAttr getCAttrAttrName(::mlir::OperationName name)
62 // DECL-NEXT:      return getAttributeNameForIndex(name, 2);
64 // DEF-LABEL: AOp definitions
66 // Test verify method
67 // ---
69 // DEF:      ::mlir::LogicalResult AOpAdaptor::verify
70 // DEF:      ::mlir::Attribute tblgen_aAttr;
71 // DEF-NEXT: while (true) {
72 // DEF-NEXT:   if (namedAttrIt == namedAttrRange.end())
73 // DEF-NEXT:     return emitError(loc, "'test.a_op' op ""requires attribute 'aAttr'");
74 // DEF-NEXT:   if (namedAttrIt->getName() == AOp::getAAttrAttrName(*odsOpName)) {
75 // DEF-NEXT:     tblgen_aAttr = namedAttrIt->getValue();
76 // DEF-NEXT:     break;
77 // DEF:      ::mlir::Attribute tblgen_bAttr;
78 // DEF-NEXT: ::mlir::Attribute tblgen_cAttr;
79 // DEF-NEXT: ::mlir::Attribute tblgen_dAttr;
80 // DEF-NEXT: while (true) {
81 // DEF-NEXT:   if (namedAttrIt == namedAttrRange.end())
82 // DEF-NEXT:     break;
83 // DEF:        if (namedAttrIt->getName() == AOp::getBAttrAttrName(*odsOpName))
84 // DEF-NEXT:     tblgen_bAttr = namedAttrIt->getValue();
85 // DEF:        if (namedAttrIt->getName() == AOp::getCAttrAttrName(*odsOpName))
86 // DEF-NEXT:     tblgen_cAttr = namedAttrIt->getValue();
87 // DEF:      if (tblgen_aAttr && !((some-condition)))
88 // DEF-NEXT:   return emitError(loc, "'test.a_op' op ""attribute 'aAttr' failed to satisfy constraint: some attribute kind");
89 // DEF:      if (tblgen_bAttr && !((some-condition)))
90 // DEF-NEXT:   return emitError(loc, "'test.a_op' op ""attribute 'bAttr' failed to satisfy constraint: some attribute kind");
91 // DEF:      if (tblgen_cAttr && !((some-condition)))
92 // DEF-NEXT:   return emitError(loc, "'test.a_op' op ""attribute 'cAttr' failed to satisfy constraint: some attribute kind");
93 // DEF:      if (tblgen_dAttr && !((some-condition)))
94 // DEF-NEXT:   return emitError(loc, "'test.a_op' op ""attribute 'dAttr' failed to satisfy constraint: some attribute kind");
96 // Test getter methods
97 // ---
99 // DEF:      some-attr-kind AOp::getAAttrAttr()
100 // DEF-NEXT:   ::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 0, (*this)->getAttrs().end() - 0, getAAttrAttrName()).cast<some-attr-kind>()
101 // DEF:      some-return-type AOp::getAAttr() {
102 // DEF-NEXT:   auto attr = getAAttrAttr()
103 // DEF-NEXT:   return attr.some-convert-from-storage();
105 // DEF:      some-attr-kind AOp::getBAttrAttr()
106 // DEF-NEXT:   ::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 1, (*this)->getAttrs().end() - 0, getBAttrAttrName()).dyn_cast_or_null<some-attr-kind>()
107 // DEF:      some-return-type AOp::getBAttr() {
108 // DEF-NEXT:   auto attr = getBAttrAttr();
109 // DEF-NEXT:   return attr.some-convert-from-storage();
111 // DEF:      some-attr-kind AOp::getCAttrAttr()
112 // DEF-NEXT:   ::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 1, (*this)->getAttrs().end() - 0, getCAttrAttrName()).dyn_cast_or_null<some-attr-kind>()
113 // DEF:      ::std::optional<some-return-type> AOp::getCAttr() {
114 // DEF-NEXT:   auto attr = getCAttrAttr()
115 // DEF-NEXT:   return attr ? ::std::optional<some-return-type>(attr.some-convert-from-storage()) : (::std::nullopt);
117 // DEF:      some-attr-kind AOp::getDAttrAttr()
118 // DEF-NEXT:   ::mlir::impl::getAttrFromSortedRange((*this)->getAttrs().begin() + 1, (*this)->getAttrs().end() - 0, getDAttrAttrName()).dyn_cast_or_null<some-attr-kind>()
119 // DEF:      some-return-type AOp::getDAttr() {
120 // DEF-NEXT:   auto attr = getDAttrAttr();
121 // DEF-NEXT:   if (!attr)
122 // DEF-NEXT:       return some-const-builder-call(::mlir::Builder((*this)->getContext()), 4.2).some-convert-from-storage();
123 // DEF-NEXT:   return attr.some-convert-from-storage();
125 // Test setter methods
126 // ---
128 // DEF:      void AOp::setAAttrAttr(some-attr-kind attr) {
129 // DEF-NEXT:   (*this)->setAttr(getAAttrAttrName(), attr);
130 // DEF:      void AOp::setAAttr(some-return-type attrValue) {
131 // DEF-NEXT:   (*this)->setAttr(getAAttrAttrName(), some-const-builder-call(::mlir::Builder((*this)->getContext()), attrValue));
132 // DEF:      void AOp::setBAttrAttr(some-attr-kind attr) {
133 // DEF-NEXT:   (*this)->setAttr(getBAttrAttrName(), attr);
134 // DEF:      void AOp::setBAttr(some-return-type attrValue) {
135 // DEF-NEXT:   (*this)->setAttr(getBAttrAttrName(), some-const-builder-call(::mlir::Builder((*this)->getContext()), attrValue));
136 // DEF:      void AOp::setCAttrAttr(some-attr-kind attr) {
137 // DEF-NEXT:   (*this)->setAttr(getCAttrAttrName(), attr);
138 // DEF:      void AOp::setCAttr(::std::optional<some-return-type> attrValue) {
139 // DEF-NEXT:   if (attrValue)
140 // DEF-NEXT:     return (*this)->setAttr(getCAttrAttrName(), some-const-builder-call(::mlir::Builder((*this)->getContext()), *attrValue));
141 // DEF-NEXT:   (*this)->removeAttr(getCAttrAttrName());
143 // Test remove methods
144 // ---
146 // DEF: ::mlir::Attribute AOp::removeCAttrAttr() {
147 // DEF-NEXT: return (*this)->removeAttr(getCAttrAttrName());
149 // Test build methods
150 // ---
152 // DEF:      void AOp::build(
153 // DEF:        odsState.addAttribute(getAAttrAttrName(odsState.name), aAttr);
154 // DEF:        odsState.addAttribute(getBAttrAttrName(odsState.name), bAttr);
155 // DEF:        if (cAttr) {
156 // DEF-NEXT:     odsState.addAttribute(getCAttrAttrName(odsState.name), cAttr);
158 // DEF:        odsState.addAttribute(getAAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, aAttr));
159 // DEF-NEXT:   odsState.addAttribute(getBAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, bAttr));
160 // DEF-NEXT:   if (cAttr) {
161 // DEF-NEXT:   odsState.addAttribute(getCAttrAttrName(odsState.name), cAttr);
162 // DEF-NEXT:   }
163 // DEF-NOT:    if (dAttr)
164 // DEF:        odsState.addAttribute(getDAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, dAttr));
166 // DEF:      void AOp::build(
167 // DEF:        some-return-type aAttr, some-return-type bAttr, /*optional*/some-attr-kind cAttr
168 // DEF:        odsState.addAttribute(getAAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, aAttr));
170 // DEF:      void AOp::build(
171 // DEF:        ::llvm::ArrayRef<::mlir::NamedAttribute> attributes
172 // DEF:      odsState.addAttributes(attributes);
174 // Test the above but with prefix.
176 def Test2_Dialect : Dialect {
177   let name = "test2";
178   let cppNamespace = "foobar2";
180 def AgetOp : Op<Test2_Dialect, "a_get_op", []> {
181   let arguments = (ins
182       SomeAttr:$aAttr,
183       DefaultValuedOptionalAttr<SomeAttr, "4.2">:$bAttr,
184       OptionalAttr<SomeAttr>:$cAttr
185   );
188 // DECL-LABEL: AgetOp declarations
190 // Test attribute name methods
191 // ---
193 // DECL:      static ::llvm::ArrayRef<::llvm::StringRef> getAttributeNames()
194 // DECL-NEXT:   static ::llvm::StringRef attrNames[] =
195 // DECL-SAME:     {::llvm::StringRef("aAttr"), ::llvm::StringRef("bAttr"), ::llvm::StringRef("cAttr")};
196 // DECL-NEXT:   return ::llvm::ArrayRef(attrNames);
198 // DECL:      ::mlir::StringAttr getAAttrAttrName()
199 // DECL-NEXT:      return getAttributeNameForIndex(0);
200 // DECL:      ::mlir::StringAttr getAAttrAttrName(::mlir::OperationName name)
201 // DECL-NEXT:      return getAttributeNameForIndex(name, 0);
203 // DECL:      ::mlir::StringAttr getBAttrAttrName()
204 // DECL-NEXT:      return getAttributeNameForIndex(1);
205 // DECL:      ::mlir::StringAttr getBAttrAttrName(::mlir::OperationName name)
206 // DECL-NEXT:      return getAttributeNameForIndex(name, 1);
208 // DECL:      ::mlir::StringAttr getCAttrAttrName()
209 // DECL-NEXT:      return getAttributeNameForIndex(2);
210 // DECL:      ::mlir::StringAttr getCAttrAttrName(::mlir::OperationName name)
211 // DECL-NEXT:      return getAttributeNameForIndex(name, 2);
213 // DEF-LABEL: AgetOp definitions
215 // Test verify method
216 // ---
218 // DEF:      ::mlir::LogicalResult AgetOpAdaptor::verify
219 // DEF:      ::mlir::Attribute tblgen_aAttr;
220 // DEF-NEXT: while (true)
221 // DEF:      ::mlir::Attribute tblgen_bAttr;
222 // DEF-NEXT: ::mlir::Attribute tblgen_cAttr;
223 // DEF-NEXT: while (true)
224 // DEF:      if (tblgen_aAttr && !((some-condition)))
225 // DEF-NEXT:   return emitError(loc, "'test2.a_get_op' op ""attribute 'aAttr' failed to satisfy constraint: some attribute kind");
226 // DEF:      if (tblgen_bAttr && !((some-condition)))
227 // DEF-NEXT:   return emitError(loc, "'test2.a_get_op' op ""attribute 'bAttr' failed to satisfy constraint: some attribute kind");
228 // DEF:      if (tblgen_cAttr && !((some-condition)))
229 // DEF-NEXT:   return emitError(loc, "'test2.a_get_op' op ""attribute 'cAttr' failed to satisfy constraint: some attribute kind");
231 // Test getter methods
232 // ---
234 // DEF:      some-attr-kind AgetOp::getAAttrAttr()
235 // DEF-NEXT:   ::mlir::impl::getAttrFromSortedRange({{.*}}).cast<some-attr-kind>()
236 // DEF:      some-return-type AgetOp::getAAttr() {
237 // DEF-NEXT:   auto attr = getAAttrAttr()
238 // DEF-NEXT:   return attr.some-convert-from-storage();
240 // DEF:      some-attr-kind AgetOp::getBAttrAttr()
241 // DEF-NEXT:   return ::mlir::impl::getAttrFromSortedRange({{.*}}).dyn_cast_or_null<some-attr-kind>()
242 // DEF:      some-return-type AgetOp::getBAttr() {
243 // DEF-NEXT:   auto attr = getBAttrAttr();
244 // DEF-NEXT:   if (!attr)
245 // DEF-NEXT:       return some-const-builder-call(::mlir::Builder((*this)->getContext()), 4.2).some-convert-from-storage();
246 // DEF-NEXT:   return attr.some-convert-from-storage();
248 // DEF:      some-attr-kind AgetOp::getCAttrAttr()
249 // DEF-NEXT:   return ::mlir::impl::getAttrFromSortedRange({{.*}}).dyn_cast_or_null<some-attr-kind>()
250 // DEF:      ::std::optional<some-return-type> AgetOp::getCAttr() {
251 // DEF-NEXT:   auto attr = getCAttrAttr()
252 // DEF-NEXT:   return attr ? ::std::optional<some-return-type>(attr.some-convert-from-storage()) : (::std::nullopt);
254 // Test setter methods
255 // ---
257 // DEF:      void AgetOp::setAAttrAttr(some-attr-kind attr) {
258 // DEF-NEXT:   (*this)->setAttr(getAAttrAttrName(), attr);
259 // DEF:      void AgetOp::setBAttrAttr(some-attr-kind attr) {
260 // DEF-NEXT:   (*this)->setAttr(getBAttrAttrName(), attr);
261 // DEF:      void AgetOp::setCAttrAttr(some-attr-kind attr) {
262 // DEF-NEXT:   (*this)->setAttr(getCAttrAttrName(), attr);
264 // Test remove methods
265 // ---
267 // DEF: ::mlir::Attribute AgetOp::removeCAttrAttr() {
268 // DEF-NEXT: return (*this)->removeAttr(getCAttrAttrName());
270 // Test build methods
271 // ---
273 // DEF:      void AgetOp::build(
274 // DEF:        odsState.addAttribute(getAAttrAttrName(odsState.name), aAttr);
275 // DEF:        odsState.addAttribute(getBAttrAttrName(odsState.name), bAttr);
276 // DEF:        if (cAttr) {
277 // DEF-NEXT:     odsState.addAttribute(getCAttrAttrName(odsState.name), cAttr);
279 // DEF:      void AgetOp::build(
280 // DEF:        some-return-type aAttr, /*optional*/some-return-type bAttr, /*optional*/some-attr-kind cAttr
281 // DEF:        odsState.addAttribute(getAAttrAttrName(odsState.name), some-const-builder-call(odsBuilder, aAttr));
283 // DEF:      void AgetOp::build(
284 // DEF:        ::llvm::ArrayRef<::mlir::NamedAttribute> attributes
285 // DEF:      odsState.addAttributes(attributes);
287 def SomeTypeAttr : TypeAttrBase<"SomeType", "some type attribute">;
289 def BOp : NS_Op<"b_op", []> {
290   let arguments = (ins
291     AnyAttr:$any_attr,
292     BoolAttr:$bool_attr,
293     I32Attr:$i32_attr,
294     I64Attr:$i64_attr,
295     F32Attr:$f32_attr,
296     F64Attr:$f64_attr,
297     StrAttr:$str_attr,
298     ElementsAttr:$elements_attr,
299     FlatSymbolRefAttr:$function_attr,
300     SomeTypeAttr:$some_type_attr,
301     ArrayAttr:$array_attr,
302     TypedArrayAttrBase<SomeAttr, "SomeAttr array">:$some_attr_array,
303     TypeAttr:$type_attr
304   );
308 // Test common attribute kinds' constraints
309 // ---
311 // DEF-LABEL: BOpAdaptor::verify
312 // DEF: if (tblgen_any_attr && !((true)))
313 // DEF: if (tblgen_bool_attr && !((tblgen_bool_attr.isa<::mlir::BoolAttr>())))
314 // DEF: if (tblgen_i32_attr && !(((tblgen_i32_attr.isa<::mlir::IntegerAttr>())) && ((tblgen_i32_attr.cast<::mlir::IntegerAttr>().getType().isSignlessInteger(32)))))
315 // DEF: if (tblgen_i64_attr && !(((tblgen_i64_attr.isa<::mlir::IntegerAttr>())) && ((tblgen_i64_attr.cast<::mlir::IntegerAttr>().getType().isSignlessInteger(64)))))
316 // DEF: if (tblgen_f32_attr && !(((tblgen_f32_attr.isa<::mlir::FloatAttr>())) && ((tblgen_f32_attr.cast<::mlir::FloatAttr>().getType().isF32()))))
317 // DEF: if (tblgen_f64_attr && !(((tblgen_f64_attr.isa<::mlir::FloatAttr>())) && ((tblgen_f64_attr.cast<::mlir::FloatAttr>().getType().isF64()))))
318 // DEF: if (tblgen_str_attr && !((tblgen_str_attr.isa<::mlir::StringAttr>())))
319 // DEF: if (tblgen_elements_attr && !((tblgen_elements_attr.isa<::mlir::ElementsAttr>())))
320 // DEF: if (tblgen_function_attr && !((tblgen_function_attr.isa<::mlir::FlatSymbolRefAttr>())))
321 // DEF: if (tblgen_some_type_attr && !(((tblgen_some_type_attr.isa<::mlir::TypeAttr>())) && ((tblgen_some_type_attr.cast<::mlir::TypeAttr>().getValue().isa<SomeType>()))))
322 // DEF: if (tblgen_array_attr && !((tblgen_array_attr.isa<::mlir::ArrayAttr>())))
323 // DEF: if (tblgen_some_attr_array && !(((tblgen_some_attr_array.isa<::mlir::ArrayAttr>())) && (::llvm::all_of(tblgen_some_attr_array.cast<::mlir::ArrayAttr>(), [&](::mlir::Attribute attr) { return attr && ((some-condition)); }))))
324 // DEF: if (tblgen_type_attr && !(((tblgen_type_attr.isa<::mlir::TypeAttr>())) && ((tblgen_type_attr.cast<::mlir::TypeAttr>().getValue().isa<::mlir::Type>()))))
326 // Test common attribute kind getters' return types
327 // ---
329 // DEF: ::mlir::Attribute BOp::getAnyAttr()
330 // DEF: bool BOp::getBoolAttr()
331 // DEF: uint32_t BOp::getI32Attr()
332 // DEF: uint64_t BOp::getI64Attr()
333 // DEF: ::llvm::APFloat BOp::getF32Attr()
334 // DEF: ::llvm::APFloat BOp::getF64Attr()
335 // DEF: ::llvm::StringRef BOp::getStrAttr()
336 // DEF: ::mlir::ElementsAttr BOp::getElementsAttr()
337 // DEF: ::llvm::StringRef BOp::getFunctionAttr()
338 // DEF: SomeType BOp::getSomeTypeAttr()
339 // DEF: ::mlir::ArrayAttr BOp::getArrayAttr()
340 // DEF: ::mlir::ArrayAttr BOp::getSomeAttrArray()
341 // DEF: ::mlir::Type BOp::getTypeAttr()
343 // Test building constant values for array attribute kinds
344 // ---
346 def COp : NS_Op<"c_op", []> {
347   let arguments = (ins
348     DefaultValuedOptionalAttr<I32ArrayAttr, "{1, 2}">:$i32_array_attr,
349     DefaultValuedOptionalAttr<I64ArrayAttr, "{3, 4}">:$i64_array_attr,
350     DefaultValuedOptionalAttr<F32ArrayAttr, "{5.f, 6.f}">:$f32_array_attr,
351     DefaultValuedOptionalAttr<F64ArrayAttr, "{7., 8.}">:$f64_array_attr,
352     DefaultValuedOptionalAttr<StrArrayAttr, "{\"a\", \"b\"}">:$str_array_attr
353   );
356 // DEF-LABEL: COp definitions
357 // DEF: ::mlir::Builder((*this)->getContext()).getI32ArrayAttr({1, 2})
358 // DEF: ::mlir::Builder((*this)->getContext()).getI64ArrayAttr({3, 4})
359 // DEF: ::mlir::Builder((*this)->getContext()).getF32ArrayAttr({5.f, 6.f})
360 // DEF: ::mlir::Builder((*this)->getContext()).getF64ArrayAttr({7., 8.})
361 // DEF: ::mlir::Builder((*this)->getContext()).getStrArrayAttr({"a", "b"})
364 // Test builder method which takes unwrapped values for attributes
365 // ---
367 def I32Case5:  I32EnumAttrCase<"case5", 5>;
368 def I32Case10: I32EnumAttrCase<"case10", 10>;
370 def SomeI32Enum: I32EnumAttr<
371   "SomeI32Enum", "", [I32Case5, I32Case10]>;
373 def DOp : NS_Op<"d_op", []> {
374   let arguments = (ins
375     I32Attr:$i32_attr,
376     F64Attr:$f64_attr,
377     StrAttr:$str_attr,
378     BoolAttr:$bool_attr,
379     SomeI32Enum:$enum_attr,
380     DefaultValuedAttr<I32Attr, "42">:$dv_i32_attr,
381     DefaultValuedAttr<F64Attr, "8.">:$dv_f64_attr,
382     DefaultValuedStrAttr<StrAttr, "abc">:$dv_str_attr,
383     DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr,
384     DefaultValuedAttr<SomeI32Enum, "::SomeI32Enum::case5">:$dv_enum_attr
385   );
388 // DECL-LABEL: DOp declarations
389 // DECL: static void build({{.*}}, uint32_t i32_attr, ::llvm::APFloat f64_attr, ::llvm::StringRef str_attr, bool bool_attr, ::SomeI32Enum enum_attr, uint32_t dv_i32_attr, ::llvm::APFloat dv_f64_attr, ::llvm::StringRef dv_str_attr = "abc", bool dv_bool_attr = true, ::SomeI32Enum dv_enum_attr = ::SomeI32Enum::case5)
391 // DEF-LABEL: DOp definitions
392 // DEF: odsState.addAttribute(getStrAttrAttrName(odsState.name), odsBuilder.getStringAttr(str_attr));
393 // DEF: odsState.addAttribute(getDvStrAttrAttrName(odsState.name), odsBuilder.getStringAttr(dv_str_attr));
396 // Test default dictionary attribute.
397 // ---
399 def DefaultDictAttrOp : NS_Op<"default_dict_attr_op", []> {
400   let arguments = (ins
401     DefaultValuedAttr<DictionaryAttr, "{}">:$empty,
402     DefaultValuedAttr<DictionaryAttr, "getDefaultDictAttrs($_builder)">:$non_empty
403   );
406 // DEF-LABEL: DefaultDictAttrOp definitions
407 // DEF: if (!attributes.get(attrNames[0]))
408 // DEF:   attributes.append(attrNames[0], odsBuilder.getDictionaryAttr({}));
409 // DEF: if (!attributes.get(attrNames[1]))
410 // DEF:   attributes.append(attrNames[1], odsBuilder.getDictionaryAttr(getDefaultDictAttrs(odsBuilder)));
412 // DECL-LABEL: DefaultDictAttrOp declarations
413 // DECL: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::DictionaryAttr empty, ::mlir::DictionaryAttr non_empty)
416 // Test derived type attr.
417 // ---
418 def DerivedTypeAttrOp : NS_Op<"derived_type_attr_op", []> {
419   let results = (outs AnyTensor:$output);
420   DerivedTypeAttr element_dtype = DerivedTypeAttr<"return output().getType();">;
423 // DECL: class DerivedTypeAttrOp : public ::mlir::Op
424 // DECL-SAME: DerivedAttributeOpInterface::Trait
425 // DECL: static bool isDerivedAttribute
426 // DEF: bool DerivedTypeAttrOp::isDerivedAttribute(::llvm::StringRef name) {
427 // DEF:   if (name == "element_dtype") return true;
428 // DEF:   return false;
429 // DEF: }
430 // DEF: DerivedTypeAttrOp::materializeDerivedAttributes
432 // Test that only default valued attributes at the end of the arguments
433 // list get default values in the builder signature
434 // ---
436 def EOp : NS_Op<"e_op", []> {
437   let arguments = (ins
438     I32Attr:$i32_attr,
439     DefaultValuedAttr<I32Attr, "42">:$dv_i32_attr,
440     F64Attr:$f64_attr,
441     DefaultValuedAttr<F64Attr, "8.">:$dv_f64_attr,
442     StrAttr:$str_attr,
443     DefaultValuedStrAttr<StrAttr, "abc">:$dv_str_attr,
444     BoolAttr:$bool_attr,
445     DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr,
446     SomeI32Enum:$enum_attr,
447     DefaultValuedAttr<SomeI32Enum, "::SomeI32Enum::case5">:$dv_enum_attr
448   );
451 // DECL-LABEL: EOp declarations
452 // DECL: static void build({{.*}}, uint32_t i32_attr, uint32_t dv_i32_attr, ::llvm::APFloat f64_attr, ::llvm::APFloat dv_f64_attr, ::llvm::StringRef str_attr, ::llvm::StringRef dv_str_attr, bool bool_attr, bool dv_bool_attr, ::SomeI32Enum enum_attr, ::SomeI32Enum dv_enum_attr = ::SomeI32Enum::case5)
455 // Test proper namespacing for AttrDef
456 // ---
458 def NamespaceOp : NS_Op<"namespace_op", []> {
459   let arguments = (ins
460       SomeAttrDef:$AttrDef
461   );
463 // DECL: NamespaceOp
464 // DECL: foobar::SomeAttrAttr getAttrDef()
467 // Test mixing operands and attributes in arbitrary order
468 // ---
470 def MixOperandsAndAttrs : NS_Op<"mix_operands_and_attrs", []> {
471   let arguments = (ins F32Attr:$attr, F32:$operand, F32Attr:$otherAttr, F32:$otherArg);
474 def OpWithDefaultAndRegion : NS_Op<"default_with_region", []> {
475   let arguments = (ins
476           DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr
477   );
478   let regions = (region VariadicRegion<AnyRegion>:$region);
481 // We should not have a default attribute in this case.
483 // DECL-LABEL: OpWithDefaultAndRegion declarations
484 // DECL: static void build({{.*}}, bool dv_bool_attr, unsigned regionCount)
486 def OpWithDefaultAndSuccessor : NS_Op<"default_with_succ", []> {
487   let arguments = (ins
488           DefaultValuedAttr<BoolAttr, "true">:$dv_bool_attr
489   );
490   let successors = (successor VariadicSuccessor<AnySuccessor>:$succ);
493 // We should not have a default attribute in this case.
495 // DECL-LABEL: OpWithDefaultAndSuccessor declarations
496 // DECL: static void build({{.*}}, bool dv_bool_attr, ::mlir::BlockRange succ)
498 // DEF-LABEL: MixOperandsAndAttrs definitions
499 // DEF-DAG: ::mlir::TypedValue<::mlir::FloatType> MixOperandsAndAttrs::getOperand()
500 // DEF-DAG: ::mlir::TypedValue<::mlir::FloatType> MixOperandsAndAttrs::getOtherArg()
501 // DEF-DAG: void MixOperandsAndAttrs::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::FloatAttr attr, ::mlir::Value operand, ::mlir::FloatAttr otherAttr, ::mlir::Value otherArg)
502 // DEF-DAG: ::llvm::APFloat MixOperandsAndAttrs::getAttr()
503 // DEF-DAG: ::llvm::APFloat MixOperandsAndAttrs::getOtherAttr()
505 // Test unit attributes.
506 // ---
508 def UnitAttrOp : NS_Op<"unit_attr_op", []> {
509   let arguments = (ins UnitAttr:$attr);
512 // DEF-LABEL: UnitAttrOp definitions
513 // DEF: bool UnitAttrOp::getAttr() {
514 // DEF:   return {{.*}} != nullptr
516 // DEF: ::mlir::Attribute UnitAttrOp::removeAttrAttr() {
517 // DEF-NEXT:   (*this)->removeAttr(getAttrAttrName());
519 // DEF: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/::mlir::UnitAttr attr)
520 // DEF: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/bool attr)
522 // DECL-LABEL: UnitAttrOp declarations
523 // DECL-NOT: declarations
524 // DECL: build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/bool attr = false)
527 // Test elementAttr field of TypedArrayAttr.
528 // ---
530 def SomeTypedArrayAttr : TypedArrayAttrBase<SomeAttr, "SomeAttr array">;
532 // RECORD-LABEL: def SomeTypedArrayAttr
533 // RECORD: Attr elementAttr = SomeAttr;