| author | |
| committer | |
| log | d54c288bd351adb84dd98b26848687d66cb725dc |
| tree | a5f1c8904da7b2c42a7fc9696f6569b2b7143b40 |
| parent | c2666c48a4cf5c0576cf846171744b53f39acb80 |
| signature | Commit is signed but in an unrecognized format. |
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 | ... | @@ -839,6 +839,7 @@ pub extern fn ZigClangFunctionType_getReturnType(self: *const ZigClangFunctionTy |
| 839 | pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool; | 839 | pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool; |
| 840 | pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint; | 840 | pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint; |
| 841 | pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType; | 841 | pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType; |
| 842 | pub extern fn ZigClangFunctionProtoType_getReturnType(self: *const ZigClangFunctionProtoType) ZigClangQualType; | ||
| 842 | 843 | ||
| 843 | pub const ZigClangSourceLocation = struct_ZigClangSourceLocation; | 844 | pub const ZigClangSourceLocation = struct_ZigClangSourceLocation; |
| 844 | pub const ZigClangQualType = struct_ZigClangQualType; | 845 | pub const ZigClangQualType = struct_ZigClangQualType; |
| ... | @@ -993,6 +994,7 @@ pub extern fn ZigClangIncompleteArrayType_getElementType(*const ZigClangIncomple | ... | @@ -993,6 +994,7 @@ pub extern fn ZigClangIncompleteArrayType_getElementType(*const ZigClangIncomple |
| 993 | pub extern fn ZigClangConstantArrayType_getElementType(self: *const struct_ZigClangConstantArrayType) ZigClangQualType; | 994 | pub extern fn ZigClangConstantArrayType_getElementType(self: *const struct_ZigClangConstantArrayType) ZigClangQualType; |
| 994 | pub extern fn ZigClangConstantArrayType_getSize(self: *const struct_ZigClangConstantArrayType) *const struct_ZigClangAPInt; | 995 | pub extern fn ZigClangConstantArrayType_getSize(self: *const struct_ZigClangConstantArrayType) *const struct_ZigClangAPInt; |
| 995 | pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl; | 996 | pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl; |
| 997 | pub extern fn ZigClangDeclRefExpr_getFoundDecl(*const ZigClangDeclRefExpr) *const ZigClangNamedDecl; | ||
| 996 | 998 | ||
| 997 | pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType; | 999 | pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType; |
| 998 | 1000 | ||
| ... | @@ -1105,3 +1107,7 @@ pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const | ... | @@ -1105,3 +1107,7 @@ pub extern fn ZigClangMemberExpr_getMemberDecl(*const ZigClangMemberExpr) *const |
| 1105 | pub extern fn ZigClangArraySubscriptExpr_getBase(*const ZigClangArraySubscriptExpr) *const ZigClangExpr; | 1107 | pub extern fn ZigClangArraySubscriptExpr_getBase(*const ZigClangArraySubscriptExpr) *const ZigClangExpr; |
| 1106 | pub extern fn ZigClangArraySubscriptExpr_getIdx(*const ZigClangArraySubscriptExpr) *const ZigClangExpr; | 1108 | pub extern fn ZigClangArraySubscriptExpr_getIdx(*const ZigClangArraySubscriptExpr) *const ZigClangExpr; |
| 1107 | 1109 | ||
| 1110 | pub extern fn ZigClangCallExpr_getCallee(*const ZigClangCallExpr) *const ZigClangExpr; | ||
| 1111 | pub extern fn ZigClangCallExpr_getNumArgs(*const ZigClangCallExpr) c_uint; | ||
| 1112 | pub extern fn ZigClangCallExpr_getArgs(*const ZigClangCallExpr) [*]const *const ZigClangExpr; | ||
| 1113 |
src-self-hosted/translate_c.zig+84| ... | @@ -851,6 +851,7 @@ fn transStmt( | ... | @@ -851,6 +851,7 @@ fn transStmt( |
| 851 | .StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used), | 851 | .StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used), |
| 852 | .MemberExprClass => return transMemberExpr(rp, scope, @ptrCast(*const ZigClangMemberExpr, stmt), result_used), | 852 | .MemberExprClass => return transMemberExpr(rp, scope, @ptrCast(*const ZigClangMemberExpr, stmt), result_used), |
| 853 | .ArraySubscriptExprClass => return transArrayAccess(rp, scope, @ptrCast(*const ZigClangArraySubscriptExpr, stmt), result_used), | 853 | .ArraySubscriptExprClass => return transArrayAccess(rp, scope, @ptrCast(*const ZigClangArraySubscriptExpr, stmt), result_used), |
| 854 | .CallExprClass => return transCallExpr(rp, scope, @ptrCast(*const ZigClangCallExpr, stmt), result_used), | ||
| 854 | else => { | 855 | else => { |
| 855 | return revertAndWarn( | 856 | return revertAndWarn( |
| 856 | rp, | 857 | rp, |
| ... | @@ -2004,6 +2005,73 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS | ... | @@ -2004,6 +2005,73 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS |
| 2004 | return maybeSuppressResult(rp, scope, result_used, &node.base); | 2005 | return maybeSuppressResult(rp, scope, result_used, &node.base); |
| 2005 | } | 2006 | } |
| 2006 | 2007 | ||
| 2008 | fn 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 | |||
| 2059 | fn 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 | |||
| 2007 | fn transCPtrCast( | 2075 | fn transCPtrCast( |
| 2008 | rp: RestorePoint, | 2076 | rp: RestorePoint, |
| 2009 | loc: ZigClangSourceLocation, | 2077 | loc: ZigClangSourceLocation, |
| ... | @@ -3947,6 +4015,22 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc | ... | @@ -3947,6 +4015,22 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc |
| 3947 | if (it.next().?.id != .RBrace) | 4015 | if (it.next().?.id != .RBrace) |
| 3948 | return error.ParseError; | 4016 | return error.ParseError; |
| 3949 | }, | 4017 | }, |
| 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 | }, | ||
| 3950 | else => { | 4034 | else => { |
| 3951 | _ = it.prev(); | 4035 | _ = it.prev(); |
| 3952 | return node; | 4036 | return node; |
test/translate_c.zig+22-18| ... | @@ -702,6 +702,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -702,6 +702,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 702 | \\} | 702 | \\} |
| 703 | }); | 703 | }); |
| 704 | 704 | ||
| 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 | |||
| 705 | /////////////// Cases that pass for only stage2 //////////////// | 719 | /////////////// Cases that pass for only stage2 //////////////// |
| 706 | 720 | ||
| 707 | cases.add_2("Parameterless function prototypes", | 721 | cases.add_2("Parameterless function prototypes", |
| ... | @@ -1538,6 +1552,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1538,6 +1552,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1538 | \\pub const ACCESS = array[2]; | 1552 | \\pub const ACCESS = array[2]; |
| 1539 | }); | 1553 | }); |
| 1540 | 1554 | ||
| 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 | |||
| 1541 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// | 1563 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// |
| 1542 | 1564 | ||
| 1543 | cases.addAllowWarnings("simple data types", | 1565 | cases.addAllowWarnings("simple data types", |
| ... | @@ -1728,24 +1750,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1728,24 +1750,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1728 | \\} | 1750 | \\} |
| 1729 | }); | 1751 | }); |
| 1730 | 1752 | ||
| 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 | |||
| 1749 | cases.addC("sizeof", | 1753 | cases.addC("sizeof", |
| 1750 | \\#include <stddef.h> | 1754 | \\#include <stddef.h> |
| 1751 | \\size_t size_of(void) { | 1755 | \\size_t size_of(void) { |