diff --git a/mlir/include/mlir/IR/AttrTypeBase.td b/mlir/include/mlir/IR/AttrTypeBase.td --- a/mlir/include/mlir/IR/AttrTypeBase.td +++ b/mlir/include/mlir/IR/AttrTypeBase.td @@ -329,6 +329,18 @@ class TypeParameter : AttrOrTypeParameter; +// An optional parameter. +class OptionalParameter : + AttrOrTypeParameter { + let defaultValue = cppStorageType # "()"; +} + +// A parameter with a default value. +class DefaultValuedParameter : + AttrOrTypeParameter { + let defaultValue = value; +} + // For StringRefs, which require allocation. class StringRefParameter : AttrOrTypeParameter<"::llvm::StringRef", desc> { @@ -350,6 +362,15 @@ let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">"; } +// Regular array parameterse cannot be parsed when empty. This optional array +// parameter can be used with optional groups to be parsed when empty. +class OptionalArrayRefParameter : + OptionalParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> { + let allocator = [{$_dst = $_allocator.copyInto($_self);}]; + let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">"; + let comparator = "::llvm::makeArrayRef($_lhs) == ::llvm::makeArrayRef($_rhs)"; +} + // For classes which require allocation and have their own allocateInto method. class SelfAllocationParameter : AttrOrTypeParameter { @@ -367,18 +388,6 @@ }]; } -// An optional parameter. -class OptionalParameter : - AttrOrTypeParameter { - let defaultValue = cppStorageType # "()"; -} - -// A parameter with a default value. -class DefaultValuedParameter : - AttrOrTypeParameter { - let defaultValue = value; -} - // This is a special attribute parameter that represents the "self" type of the // attribute. It is specially handled by the assembly format generator to derive // its value from the optional trailing type after each attribute. @@ -406,9 +415,9 @@ class ArrayOfAttr traits = []> : AttrDef { - let parameters = (ins ArrayRefParameter:$value); + let parameters = (ins OptionalArrayRefParameter:$value); let mnemonic = attrMnemonic; - let assemblyFormat = "`[` $value `]`"; + let assemblyFormat = "`[` (`]`) : ($value^ `]`)?"; let returnType = "::llvm::ArrayRef<" # eltName # ">"; let constBuilderCall = "$_builder.getAttr<" # attrName # "Attr>($0)"; diff --git a/mlir/test/IR/array-of-attr.mlir b/mlir/test/IR/array-of-attr.mlir --- a/mlir/test/IR/array-of-attr.mlir +++ b/mlir/test/IR/array-of-attr.mlir @@ -8,3 +8,7 @@ b = [0, 1, -42, 42], // CHECK-SAME: [a, b, b, a] c = [a, b, b, a] + +// CHECK: test.array_of_attr_op +// CHECK-SAME: a = [], b = [], c = [] +test.array_of_attr_op a = [], b = [], c = [] diff --git a/mlir/test/lib/Dialect/Test/TestAttrDefs.td b/mlir/test/lib/Dialect/Test/TestAttrDefs.td --- a/mlir/test/lib/Dialect/Test/TestAttrDefs.td +++ b/mlir/test/lib/Dialect/Test/TestAttrDefs.td @@ -270,7 +270,7 @@ // An array of nested attributes. def TestArrayOfUglyAttrs : ArrayOfAttr { - let assemblyFormat = "`[` $value ` ` `]`"; + let assemblyFormat = "`[` (`]`) : ($value^ ` ` `]`)?"; } // An array of integers.