diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td index 937b34a625628..59beac7d64154 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td @@ -1697,6 +1697,7 @@ def EmitC_GetFieldOp let arguments = (ins FlatSymbolRefAttr:$field_name); let results = (outs EmitCType:$result); let assemblyFormat = "$field_name `:` type($result) attr-dict"; + let hasVerifier = 1; } #endif // MLIR_DIALECT_EMITC_IR_EMITC diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp index e6a3154721faa..4ef8ce0cb9cee 100644 --- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp +++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp @@ -1398,6 +1398,7 @@ void FileOp::build(OpBuilder &builder, OperationState &state, StringRef id) { //===----------------------------------------------------------------------===// // FieldOp //===----------------------------------------------------------------------===// + static void printEmitCFieldOpTypeAndInitialValue(OpAsmPrinter &p, FieldOp op, TypeAttr type, Attribute initialValue) { @@ -1455,6 +1456,15 @@ LogicalResult FieldOp::verify() { //===----------------------------------------------------------------------===// // GetFieldOp //===----------------------------------------------------------------------===// + +LogicalResult GetFieldOp::verify() { + auto parentClassOp = getOperation()->getParentOfType(); + if (!parentClassOp.getOperation()) + return emitOpError(" must be nested within an emitc.class operation"); + + return success(); +} + LogicalResult GetFieldOp::verifySymbolUses(SymbolTableCollection &symbolTable) { mlir::FlatSymbolRefAttr fieldNameAttr = getFieldNameAttr(); FieldOp fieldOp = diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir index 3946a36a83c6f..6d7f79ead2974 100644 --- a/mlir/test/Dialect/EmitC/invalid_ops.mlir +++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir @@ -676,3 +676,35 @@ func.func @test_verbatim(%arg0 : !emitc.ptr, %arg1 : i32) { emitc.verbatim "{a} " args %arg0, %arg1 : !emitc.ptr, i32 return } + +// ----- + +// expected-error @+1 {{'emitc.field' op field must be nested within an emitc.class operation}} +emitc.field @testField : !emitc.array<1xf32> + +// ----- + +// expected-error @+1 {{'emitc.get_field' op must be nested within an emitc.class operation}} +%1 = emitc.get_field @testField : !emitc.array<1xf32> + +// ----- + +emitc.func @testMethod() { + %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t + // expected-error @+1 {{'emitc.get_field' op must be nested within an emitc.class operation}} + %1 = get_field @testField : !emitc.array<1xf32> + %2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue + return +} + +// ----- + +emitc.class @testClass { + emitc.func @testMethod() { + %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t + // expected-error @+1 {{'emitc.get_field' op field '@testField' not found in the class}} + %1 = get_field @testField : !emitc.array<1xf32> + %2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue + return + } +}