mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-04 03:44:59 +00:00
[mlir][ODS] Add support for passing properties to ref
in custom
This is essentially a follow up to https://reviews.llvm.org/D155072 This adds support for also passing properties as `ref` parameter to `custom`. This requires the property to have been bound previously and will error otherwise. This makes it possible for an implementation of `custom` to take previously parsed data into account, creating nice context-dependent grammars :-) Differential Revision: https://reviews.llvm.org/D155297
This commit is contained in:
parent
feaf70b3cd
commit
f69a9f3974
@ -24,3 +24,12 @@ test.with_wrapped_properties <{prop = "content for properties"}>
|
|||||||
// GENERIC: "test.using_property_in_custom"()
|
// GENERIC: "test.using_property_in_custom"()
|
||||||
// GENERIC-SAME: prop = array<i64: 1, 4, 20>
|
// GENERIC-SAME: prop = array<i64: 1, 4, 20>
|
||||||
test.using_property_in_custom [1, 4, 20]
|
test.using_property_in_custom [1, 4, 20]
|
||||||
|
|
||||||
|
// CHECK: test.using_property_ref_in_custom
|
||||||
|
// CHECK-SAME: 1 + 4 = 5
|
||||||
|
// GENERIC: "test.using_property_ref_in_custom"()
|
||||||
|
// GENERIC-SAME: <{
|
||||||
|
// GENERIC-SAME: first = 1
|
||||||
|
// GENERIC-SAME: second = 4
|
||||||
|
// GENERIC-SAME: }>
|
||||||
|
test.using_property_ref_in_custom 1 + 4 = 5
|
||||||
|
@ -1945,6 +1945,34 @@ static void printUsingPropertyInCustom(OpAsmPrinter &printer, Operation *op,
|
|||||||
printer << '[' << value << ']';
|
printer << '[' << value << ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parseIntProperty(OpAsmParser &parser, int64_t &value) {
|
||||||
|
return failed(parser.parseInteger(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printIntProperty(OpAsmPrinter &printer, Operation *op,
|
||||||
|
int64_t value) {
|
||||||
|
printer << value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parseSumProperty(OpAsmParser &parser, int64_t &second,
|
||||||
|
int64_t first) {
|
||||||
|
int64_t sum;
|
||||||
|
auto loc = parser.getCurrentLocation();
|
||||||
|
if (parser.parseInteger(second) || parser.parseEqual() ||
|
||||||
|
parser.parseInteger(sum))
|
||||||
|
return true;
|
||||||
|
if (sum != second + first) {
|
||||||
|
parser.emitError(loc, "Expected sum to equal first + second");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printSumProperty(OpAsmPrinter &printer, Operation *op,
|
||||||
|
int64_t second, int64_t first) {
|
||||||
|
printer << second << " = " << (second + first);
|
||||||
|
}
|
||||||
|
|
||||||
#include "TestOpEnums.cpp.inc"
|
#include "TestOpEnums.cpp.inc"
|
||||||
#include "TestOpInterfaces.cpp.inc"
|
#include "TestOpInterfaces.cpp.inc"
|
||||||
#include "TestTypeInterfaces.cpp.inc"
|
#include "TestTypeInterfaces.cpp.inc"
|
||||||
|
@ -3349,6 +3349,11 @@ def TestOpUsingPropertyInCustom : TEST_Op<"using_property_in_custom"> {
|
|||||||
let arguments = (ins ArrayProperty<"int64_t", 3>:$prop);
|
let arguments = (ins ArrayProperty<"int64_t", 3>:$prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def TestOpUsingPropertyRefInCustom : TEST_Op<"using_property_ref_in_custom"> {
|
||||||
|
let assemblyFormat = "custom<IntProperty>($first) `+` custom<SumProperty>($second, ref($first)) attr-dict";
|
||||||
|
let arguments = (ins IntProperty<"int64_t">:$first, IntProperty<"int64_t">:$second);
|
||||||
|
}
|
||||||
|
|
||||||
// Op with a properties struct defined out-of-line. The struct has custom
|
// Op with a properties struct defined out-of-line. The struct has custom
|
||||||
// printer/parser.
|
// printer/parser.
|
||||||
|
|
||||||
|
@ -483,6 +483,11 @@ def VariableInvalidO : TestFormat_Op<[{
|
|||||||
custom<Test>($prop, $prop) attr-dict
|
custom<Test>($prop, $prop) attr-dict
|
||||||
}]>, Arguments<(ins IntProperty<"int64_t">:$prop)>;
|
}]>, Arguments<(ins IntProperty<"int64_t">:$prop)>;
|
||||||
|
|
||||||
|
// CHECK: error: property 'prop' must be bound before it is referenced
|
||||||
|
def VariableInvalidP : TestFormat_Op<[{
|
||||||
|
custom<Test>(ref($prop)) attr-dict
|
||||||
|
}]>, Arguments<(ins IntProperty<"int64_t">:$prop)>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Coverage Checks
|
// Coverage Checks
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -2957,12 +2957,18 @@ OpFormatParser::parseVariableImpl(SMLoc loc, StringRef name, Context ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (const NamedProperty *property = findArg(op.getProperties(), name)) {
|
if (const NamedProperty *property = findArg(op.getProperties(), name)) {
|
||||||
if (ctx != CustomDirectiveContext)
|
if (ctx != CustomDirectiveContext && ctx != RefDirectiveContext)
|
||||||
return emitError(
|
return emitError(
|
||||||
loc, "properties currently only supported in `custom` directive");
|
loc, "properties currently only supported in `custom` directive");
|
||||||
|
|
||||||
if (!seenProperties.insert(property).second)
|
if (ctx == RefDirectiveContext) {
|
||||||
return emitError(loc, "property '" + name + "' is already bound");
|
if (!seenProperties.count(property))
|
||||||
|
return emitError(loc, "property '" + name +
|
||||||
|
"' must be bound before it is referenced");
|
||||||
|
} else {
|
||||||
|
if (!seenProperties.insert(property).second)
|
||||||
|
return emitError(loc, "property '" + name + "' is already bound");
|
||||||
|
}
|
||||||
|
|
||||||
return create<PropertyVariable>(property);
|
return create<PropertyVariable>(property);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user