mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
translate-c: add return if one is needed
This commit is contained in:
parent
c5368ba20c
commit
13e472aa2a
@ -129,7 +129,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
|
||||
}
|
||||
},
|
||||
|
||||
.Union => |info| blk: {
|
||||
.Union => |info| {
|
||||
if (info.tag_type) |tag_type| {
|
||||
const tag = meta.activeTag(key);
|
||||
const s = hash(hasher, tag, strat);
|
||||
|
||||
@ -2798,7 +2798,7 @@ pub fn floatAdd(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
|
||||
val_payload.* = .{ .val = lhs_val + rhs_val };
|
||||
break :blk &val_payload.base;
|
||||
},
|
||||
128 => blk: {
|
||||
128 => {
|
||||
return self.fail(scope, src, "TODO Implement addition for big floats", .{});
|
||||
},
|
||||
else => unreachable,
|
||||
@ -2832,7 +2832,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
|
||||
val_payload.* = .{ .val = lhs_val - rhs_val };
|
||||
break :blk &val_payload.base;
|
||||
},
|
||||
128 => blk: {
|
||||
128 => {
|
||||
return self.fail(scope, src, "TODO Implement substraction for big floats", .{});
|
||||
},
|
||||
else => unreachable,
|
||||
|
||||
@ -628,6 +628,46 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
||||
error.UnsupportedType,
|
||||
=> return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),
|
||||
};
|
||||
// add return statement if the function didn't have one
|
||||
blk: {
|
||||
const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_type);
|
||||
|
||||
if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) break :blk;
|
||||
const return_qt = ZigClangFunctionType_getReturnType(fn_ty);
|
||||
if (isCVoid(return_qt)) break :blk;
|
||||
|
||||
if (block_scope.statements.items.len > 0) {
|
||||
var last = block_scope.statements.items[block_scope.statements.items.len - 1];
|
||||
while (true) {
|
||||
switch (last.tag) {
|
||||
.Block => {
|
||||
const stmts = last.castTag(.Block).?.statements();
|
||||
if (stmts.len == 0) break;
|
||||
|
||||
last = stmts[stmts.len - 1];
|
||||
},
|
||||
// no extra return needed
|
||||
.Return => break :blk,
|
||||
else => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const return_expr = try ast.Node.ControlFlowExpression.create(rp.c.arena, .{
|
||||
.ltoken = try appendToken(rp.c, .Keyword_return, "return"),
|
||||
.tag = .Return,
|
||||
}, .{
|
||||
.rhs = transZeroInitExpr(rp, scope, fn_decl_loc, ZigClangQualType_getTypePtr(return_qt)) catch |err| switch (err) {
|
||||
error.OutOfMemory => |e| return e,
|
||||
error.UnsupportedTranslation,
|
||||
error.UnsupportedType,
|
||||
=> return failDecl(c, fn_decl_loc, fn_name, "unable to create a return value for function", .{}),
|
||||
},
|
||||
});
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
try block_scope.statements.append(&return_expr.base);
|
||||
}
|
||||
|
||||
const body_node = try block_scope.complete(rp.c);
|
||||
proto_node.setTrailer("body_node", &body_node.base);
|
||||
return addTopLevelDecl(c, fn_name, &proto_node.base);
|
||||
|
||||
@ -15,7 +15,6 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
||||
\\ }
|
||||
\\ if (s0 != 1) abort();
|
||||
\\ if (s1 != 10) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
|
||||
@ -3,12 +3,33 @@ const std = @import("std");
|
||||
const CrossTarget = std.zig.CrossTarget;
|
||||
|
||||
pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("missing return stmt",
|
||||
\\int foo() {}
|
||||
\\int bar() {
|
||||
\\ int a = 2;
|
||||
\\}
|
||||
\\int baz() {
|
||||
\\ return 0;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() c_int {
|
||||
\\ return 0;
|
||||
\\}
|
||||
\\pub export fn bar() c_int {
|
||||
\\ var a: c_int = 2;
|
||||
\\ return 0;
|
||||
\\}
|
||||
\\pub export fn baz() c_int {
|
||||
\\ return 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("alignof",
|
||||
\\int main() {
|
||||
\\void main() {
|
||||
\\ int a = _Alignof(int);
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn main() c_int {
|
||||
\\pub export fn main() void {
|
||||
\\ var a: c_int = @bitCast(c_int, @truncate(c_uint, @alignOf(c_int)));
|
||||
\\}
|
||||
});
|
||||
@ -539,6 +560,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ c = (a * b);
|
||||
\\ c = @divTrunc(a, b);
|
||||
\\ c = @rem(a, b);
|
||||
\\ return 0;
|
||||
\\}
|
||||
\\pub export fn u() c_uint {
|
||||
\\ var a: c_uint = undefined;
|
||||
@ -549,6 +571,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ c = (a *% b);
|
||||
\\ c = (a / b);
|
||||
\\ c = (a % b);
|
||||
\\ return 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
@ -1596,13 +1619,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
});
|
||||
|
||||
cases.add("worst-case assign",
|
||||
\\int foo() {
|
||||
\\void foo() {
|
||||
\\ int a;
|
||||
\\ int b;
|
||||
\\ a = b = 2;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() c_int {
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_int = undefined;
|
||||
\\ var b: c_int = undefined;
|
||||
\\ a = blk: {
|
||||
@ -1650,11 +1673,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ a = 7;
|
||||
\\ if (!true) break;
|
||||
\\ }
|
||||
\\ return 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("for loops",
|
||||
\\int foo() {
|
||||
\\void foo() {
|
||||
\\ for (int i = 2, b = 4; i + 2; i = 2) {
|
||||
\\ int a = 2;
|
||||
\\ a = 6, 5, 7;
|
||||
@ -1662,7 +1686,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ char i = 2;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() c_int {
|
||||
\\pub export fn foo() void {
|
||||
\\ {
|
||||
\\ var i: c_int = 2;
|
||||
\\ var b: c_int = 4;
|
||||
@ -1712,7 +1736,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
});
|
||||
|
||||
cases.add("switch on int",
|
||||
\\int switch_fn(int i) {
|
||||
\\void switch_fn(int i) {
|
||||
\\ int res = 0;
|
||||
\\ switch (i) {
|
||||
\\ case 0:
|
||||
@ -1727,7 +1751,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ }
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn switch_fn(arg_i: c_int) c_int {
|
||||
\\pub export fn switch_fn(arg_i: c_int) void {
|
||||
\\ var i = arg_i;
|
||||
\\ var res: c_int = 0;
|
||||
\\ @"switch": {
|
||||
@ -1787,13 +1811,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
});
|
||||
|
||||
cases.add("assign",
|
||||
\\int max(int a) {
|
||||
\\void max(int a) {
|
||||
\\ int tmp;
|
||||
\\ tmp = a;
|
||||
\\ a = tmp;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(arg_a: c_int) c_int {
|
||||
\\pub export fn max(arg_a: c_int) void {
|
||||
\\ var a = arg_a;
|
||||
\\ var tmp: c_int = undefined;
|
||||
\\ tmp = a;
|
||||
@ -2082,7 +2106,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ int b;
|
||||
\\}a;
|
||||
\\float b = 2.0f;
|
||||
\\int foo(void) {
|
||||
\\void foo(void) {
|
||||
\\ struct Foo *c;
|
||||
\\ a.b;
|
||||
\\ c->b;
|
||||
@ -2093,7 +2117,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
\\pub extern var a: struct_Foo;
|
||||
\\pub export var b: f32 = 2;
|
||||
\\pub export fn foo() c_int {
|
||||
\\pub export fn foo() void {
|
||||
\\ var c: [*c]struct_Foo = undefined;
|
||||
\\ _ = a.b;
|
||||
\\ _ = c.*.b;
|
||||
@ -2204,11 +2228,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ if (a < b) return b;
|
||||
\\ if (a < b) return b else return a;
|
||||
\\ if (a < b) {} else {}
|
||||
\\ return 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("if statements",
|
||||
\\int foo() {
|
||||
\\void foo() {
|
||||
\\ if (2) {
|
||||
\\ int a = 2;
|
||||
\\ }
|
||||
@ -2217,7 +2242,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ }
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() c_int {
|
||||
\\pub export fn foo() void {
|
||||
\\ if (true) {
|
||||
\\ var a: c_int = 2;
|
||||
\\ }
|
||||
@ -2811,12 +2836,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
});
|
||||
|
||||
cases.add("arg name aliasing decl which comes after",
|
||||
\\int foo(int bar) {
|
||||
\\void foo(int bar) {
|
||||
\\ bar = 2;
|
||||
\\}
|
||||
\\int bar = 4;
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo(arg_bar_1: c_int) c_int {
|
||||
\\pub export fn foo(arg_bar_1: c_int) void {
|
||||
\\ var bar_1 = arg_bar_1;
|
||||
\\ bar_1 = 2;
|
||||
\\}
|
||||
@ -2824,12 +2849,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
});
|
||||
|
||||
cases.add("arg name aliasing macro which comes after",
|
||||
\\int foo(int bar) {
|
||||
\\void foo(int bar) {
|
||||
\\ bar = 2;
|
||||
\\}
|
||||
\\#define bar 4
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo(arg_bar_1: c_int) c_int {
|
||||
\\pub export fn foo(arg_bar_1: c_int) void {
|
||||
\\ var bar_1 = arg_bar_1;
|
||||
\\ bar_1 = 2;
|
||||
\\}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user