authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-18 23:56:39+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-18 23:56:39+02:00
logd54c288bd351adb84dd98b26848687d66cb725dc
treea5f1c8904da7b2c42a7fc9696f6569b2b7143b40
parentc2666c48a4cf5c0576cf846171744b53f39acb80
signature Commit is signed but in an unrecognized format.

translate-c-2 function calls


3 files changed, 112 insertions(+), 18 deletions(-)

src-self-hosted/clang.zig+6
......@@ -839,6 +839,7 @@ pub extern fn ZigClangFunctionType_getReturnType(self: *const ZigClangFunctionTy
839839pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool;
840840pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint;
841841pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType;
842pub extern fn ZigClangFunctionProtoType_getReturnType(self: *const ZigClangFunctionProtoType) ZigClangQualType;
842843
843844pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
844845pub const ZigClangQualType = struct_ZigClangQualType;
......@@ -993,6 +994,7 @@ pub extern fn ZigClangIncompleteArrayType_getElementType(*const ZigClangIncomple
993994pub extern fn ZigClangConstantArrayType_getElementType(self: *const struct_ZigClangConstantArrayType) ZigClangQualType;
994995pub extern fn ZigClangConstantArrayType_getSize(self: *const struct_ZigClangConstantArrayType) *const struct_ZigClangAPInt;
995996pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl;
997pub extern fn ZigClangDeclRefExpr_getFoundDecl(*const ZigClangDeclRefExpr) *const ZigClangNamedDecl;
996998
997999pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType;
9981000
......@@ -1105,3 +1107,7 @@ pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const
11051107pub extern fn ZigClangArraySubscriptExpr_getBase(*const ZigClangArraySubscriptExpr) *const ZigClangExpr;
11061108pub extern fn ZigClangArraySubscriptExpr_getIdx(*const ZigClangArraySubscriptExpr) *const ZigClangExpr;
11071109
1110pub extern fn ZigClangCallExpr_getCallee(*const ZigClangCallExpr) *const ZigClangExpr;
1111pub extern fn ZigClangCallExpr_getNumArgs(*const ZigClangCallExpr) c_uint;
1112pub extern fn ZigClangCallExpr_getArgs(*const ZigClangCallExpr) [*]const *const ZigClangExpr;
1113
src-self-hosted/translate_c.zig+84
......@@ -851,6 +851,7 @@ fn transStmt(
851851 .StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),
852852 .MemberExprClass => return transMemberExpr(rp, scope, @ptrCast(*const ZigClangMemberExpr, stmt), result_used),
853853 .ArraySubscriptExprClass => return transArrayAccess(rp, scope, @ptrCast(*const ZigClangArraySubscriptExpr, stmt), result_used),
854 .CallExprClass => return transCallExpr(rp, scope, @ptrCast(*const ZigClangCallExpr, stmt), result_used),
854855 else => {
855856 return revertAndWarn(
856857 rp,
......@@ -2004,6 +2005,73 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS
20042005 return maybeSuppressResult(rp, scope, result_used, &node.base);
20052006}
20062007
2008fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr, result_used: ResultUsed) TransError!*ast.Node {
2009 const callee = ZigClangCallExpr_getCallee(stmt);
2010 var raw_fn_expr = try transExpr(rp, scope, callee, .used, .r_value);
2011
2012 var is_ptr = false;
2013 const fn_ty = qualTypeGetFnProto(ZigClangExpr_getType(callee), &is_ptr);
2014
2015 const fn_expr = if (is_ptr and fn_ty != null) blk: {
2016 if (ZigClangExpr_getStmtClass(callee) == .ImplicitCastExprClass) {
2017 const implicit_cast = @ptrCast(*const ZigClangImplicitCastExpr, callee);
2018
2019 if (ZigClangImplicitCastExpr_getCastKind(implicit_cast) == .FunctionToPointerDecay) {
2020 const subexpr = ZigClangImplicitCastExpr_getSubExpr(implicit_cast);
2021 if (ZigClangExpr_getStmtClass(subexpr) == .DeclRefExprClass) {
2022 const decl_ref = @ptrCast(*const ZigClangDeclRefExpr, subexpr);
2023 const named_decl = ZigClangDeclRefExpr_getFoundDecl(decl_ref);
2024 if (ZigClangDecl_getKind(@ptrCast(*const ZigClangDecl, named_decl)) == .Function) {
2025 break :blk raw_fn_expr;
2026 }
2027 }
2028 }
2029 }
2030 break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr);
2031 } else
2032 raw_fn_expr;
2033 const node = try transCreateNodeFnCall(rp.c, fn_expr);
2034
2035 const num_args = ZigClangCallExpr_getNumArgs(stmt);
2036 const args = ZigClangCallExpr_getArgs(stmt);
2037 var i: usize = 0;
2038 while (i < num_args) : (i+=1) {
2039 if (i != 0) {
2040 _ = try appendToken(rp.c, .Comma, ",");
2041 }
2042 const arg = try transExpr(rp, scope, args[i], .used, .r_value);
2043 try node.op.Call.params.push(arg);
2044 }
2045 node.rtoken = try appendToken(rp.c, .RParen, ")");
2046
2047 if (fn_ty) |ty| {
2048 const canon = ZigClangQualType_getCanonicalType(ZigClangFunctionProtoType_getReturnType(ty));
2049 const ret_ty = ZigClangQualType_getTypePtr(canon);
2050 if (ZigClangType_isVoidType(ret_ty)) {
2051 _ = try appendToken(rp.c, .Semicolon, ";");
2052 return &node.base;
2053 }
2054 }
2055
2056 return maybeSuppressResult(rp, scope, result_used, &node.base);
2057}
2058
2059fn qualTypeGetFnProto(qt: ZigClangQualType, is_ptr: *bool) ?*const ZigClangFunctionProtoType {
2060 const canon = ZigClangQualType_getCanonicalType(qt);
2061 var ty = ZigClangQualType_getTypePtr(canon);
2062 is_ptr.* = false;
2063
2064 if (ZigClangType_getTypeClass(ty) == .Pointer) {
2065 is_ptr.* = true;
2066 const child_qt = ZigClangType_getPointeeType(ty);
2067 ty = ZigClangQualType_getTypePtr(child_qt);
2068 }
2069 if (ZigClangType_getTypeClass(ty) == .FunctionProto) {
2070 return @ptrCast(*const ZigClangFunctionProtoType, ty);
2071 }
2072 return null;
2073}
2074
20072075fn transCPtrCast(
20082076 rp: RestorePoint,
20092077 loc: ZigClangSourceLocation,
......@@ -3947,6 +4015,22 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
39474015 if (it.next().?.id != .RBrace)
39484016 return error.ParseError;
39494017 },
4018 .LParen => {
4019 const call_node = try transCreateNodeFnCall(rp.c, node);
4020 while (true) {
4021 const arg = try parseCExpr(rp, it, source_loc, scope);
4022 try call_node.op.Call.params.push(arg);
4023 const next = it.next().?;
4024 if (next.id == .Comma)
4025 _ = try appendToken(rp.c, .Comma, ",")
4026 else if (next.id == .RParen)
4027 break
4028 else
4029 return error.ParseError;
4030 }
4031 call_node.rtoken = try appendToken(rp.c, .RParen, ")");
4032 node = &call_node.base;
4033 },
39504034 else => {
39514035 _ = it.prev();
39524036 return node;
test/translate_c.zig+22-18
......@@ -702,6 +702,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
702702 \\}
703703 });
704704
705 cases.addC_both("function call",
706 \\static void bar(void) { }
707 \\void foo(int *(baz)(void)) {
708 \\ bar();
709 \\ baz();
710 \\}
711 , &[_][]const u8{
712 \\pub fn bar() void {}
713 \\pub export fn foo(baz: ?extern fn () [*c]c_int) void {
714 \\ bar();
715 \\ _ = baz.?();
716 \\}
717 });
718
705719 /////////////// Cases that pass for only stage2 ////////////////
706720
707721 cases.add_2("Parameterless function prototypes",
......@@ -1538,6 +1552,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15381552 \\pub const ACCESS = array[2];
15391553 });
15401554
1555 cases.add_2("macro call",
1556 \\#define CALL(arg) bar(arg)
1557 , &[_][]const u8{
1558 \\pub inline fn CALL(arg: var) @TypeOf(bar(arg)) {
1559 \\ return bar(arg);
1560 \\}
1561 });
1562
15411563 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
15421564
15431565 cases.addAllowWarnings("simple data types",
......@@ -1728,24 +1750,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17281750 \\}
17291751 });
17301752
1731 cases.addC("function call",
1732 \\static void bar(void) { }
1733 \\static int baz(void) { return 0; }
1734 \\void foo(void) {
1735 \\ bar();
1736 \\ baz();
1737 \\}
1738 , &[_][]const u8{
1739 \\pub fn bar() void {}
1740 \\pub fn baz() c_int {
1741 \\ return 0;
1742 \\}
1743 \\pub export fn foo() void {
1744 \\ bar();
1745 \\ _ = baz();
1746 \\}
1747 });
1748
17491753 cases.addC("sizeof",
17501754 \\#include <stddef.h>
17511755 \\size_t size_of(void) {