blob: e7aa2f5cbbdb097a7814d858f7a135cf4d0a1b9e [file] [edit]
// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s -check-prefix=CPP-DEFAULT
// RUN: mlir-translate -mlir-to-cpp -declare-variables-at-top %s | FileCheck %s -check-prefix=CPP-DECLTOP
emitc.func @emitc_func(%arg0 : i32) {
emitc.call_opaque "foo" (%arg0) : (i32) -> ()
emitc.return
}
// CPP-DEFAULT: void emitc_func(int32_t [[V0:[^ ]*]]) {
// CPP-DEFAULT-NEXT: foo([[V0:[^ ]*]]);
// CPP-DEFAULT-NEXT: return;
emitc.func @return_i32() -> i32 attributes {specifiers = ["static","inline"]} {
%0 = emitc.call_opaque "foo" (): () -> i32
emitc.return %0 : i32
}
// CPP-DEFAULT: static inline int32_t return_i32() {
// CPP-DEFAULT-NEXT: [[V0:[^ ]*]] = foo();
// CPP-DEFAULT-NEXT: return [[V0:[^ ]*]];
// CPP-DECLTOP: static inline int32_t return_i32() {
// CPP-DECLTOP-NEXT: int32_t [[V0:[^ ]*]];
// CPP-DECLTOP-NEXT: [[V0:]] = foo();
// CPP-DECLTOP-NEXT: return [[V0:[^ ]*]];
emitc.func @emitc_call() -> i32 {
%0 = emitc.call @return_i32() : () -> (i32)
emitc.return %0 : i32
}
// CPP-DEFAULT: int32_t emitc_call() {
// CPP-DEFAULT-NEXT: int32_t [[V0:[^ ]*]] = return_i32();
// CPP-DEFAULT-NEXT: return [[V0:[^ ]*]];
// CPP-DECLTOP: int32_t emitc_call() {
// CPP-DECLTOP-NEXT: int32_t [[V0:[^ ]*]];
// CPP-DECLTOP-NEXT: [[V0:[^ ]*]] = return_i32();
// CPP-DECLTOP-NEXT: return [[V0:[^ ]*]];
emitc.func private @extern_func(i32) attributes {specifiers = ["extern"]}
// CPP-DEFAULT: extern void extern_func(int32_t);
emitc.func private @array_arg(!emitc.array<3xi32>) attributes {specifiers = ["extern"]}
// CPP-DEFAULT: extern void array_arg(int32_t[3]);
emitc.class struct @return_i32_i32 {
emitc.field @field0 : i32
emitc.field @field1 : i32
}
emitc.func @return_two(%arg0: i32, %arg1: i32) -> !emitc.opaque<"struct return_i32_i32"> {
%0 = "emitc.variable"() <{value = #emitc.opaque<"">}> : () -> !emitc.lvalue<!emitc.opaque<"struct return_i32_i32">>
%1 = "emitc.member"(%0) <{member = "field0"}> : (!emitc.lvalue<!emitc.opaque<"struct return_i32_i32">>) -> !emitc.lvalue<i32>
assign %arg0 : i32 to %1 : <i32>
%2 = "emitc.member"(%0) <{member = "field1"}> : (!emitc.lvalue<!emitc.opaque<"struct return_i32_i32">>) -> !emitc.lvalue<i32>
assign %arg1 : i32 to %2 : <i32>
%3 = load %0 : <!emitc.opaque<"struct return_i32_i32">>
return %3 : !emitc.opaque<"struct return_i32_i32">
}
emitc.func @call_two(%arg0: i32) -> i32 {
%0 = call @return_two(%arg0, %arg0) : (i32, i32) -> !emitc.opaque<"struct return_i32_i32">
%1 = "emitc.member"(%0) <{member = "field1"}> : (!emitc.opaque<"struct return_i32_i32">) -> i32
return %1 : i32
}
// CPP-DEFAULT: struct return_i32_i32 {
// CPP-DEFAULT-NEXT: int32_t field0;
// CPP-DEFAULT-NEXT: int32_t field1;
// CPP-DEFAULT-NEXT: };
// CPP-DEFAULT-NEXT: struct return_i32_i32 return_two(int32_t [[V1:[^ ]*]], int32_t [[V2:[^ ]*]]) {
// CPP-DEFAULT-NEXT: struct return_i32_i32 [[V3:[^ ]*]];
// CPP-DEFAULT-NEXT: [[V3]].field0 = [[V1]];
// CPP-DEFAULT-NEXT: [[V3]].field1 = [[V2]];
// CPP-DEFAULT-NEXT: struct return_i32_i32 [[V4:[^ ]*]] = [[V3]];
// CPP-DEFAULT-NEXT: return [[V4]];
// CPP-DEFAULT-NEXT: }
// CPP-DEFAULT-NEXT: int32_t call_two(int32_t [[V1:[^ ]*]]) {
// CPP-DEFAULT-NEXT: struct return_i32_i32 [[V2:[^ ]*]] = return_two([[V1]], [[V1]]);
// CPP-DEFAULT-NEXT: int32_t [[V3:[^ ]*]] = [[V2]].field1;
// CPP-DEFAULT-NEXT: return [[V3]];
// CPP-DECLTOP: struct return_i32_i32 {
// CPP-DECLTOP-NEXT: int32_t field0;
// CPP-DECLTOP-NEXT: int32_t field1;
// CPP-DECLTOP-NEXT: };
// CPP-DECLTOP-NEXT: struct return_i32_i32 return_two(int32_t [[V1:[^ ]*]], int32_t [[V2:[^ ]*]]) {
// CPP-DECLTOP-NEXT: struct return_i32_i32 [[V3:[^ ]*]];
// CPP-DECLTOP-NEXT: struct return_i32_i32 [[V4:[^ ]*]];
// CPP-DECLTOP: [[V3]].field0 = [[V1]];
// CPP-DECLTOP-NEXT: [[V3]].field1 = [[V2]];
// CPP-DECLTOP-NEXT: [[V4]] = [[V3]];
// CPP-DECLTOP-NEXT: return [[V4]];
// CPP-DECLTOP-NEXT: }
// CPP-DECLTOP-NEXT: int32_t call_two(int32_t [[V1:[^ ]*]]) {
// CPP-DECLTOP-NEXT: struct return_i32_i32 [[V2:[^ ]*]];
// CPP-DECLTOP-NEXT: int32_t [[V3:[^ ]*]];
// CPP-DECLTOP-NEXT: [[V2]] = return_two([[V1]], [[V1]]);
// CPP-DECLTOP-NEXT: [[V3]] = [[V2]].field1;
// CPP-DECLTOP-NEXT: return [[V3]];