authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-14 02:10:13-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-14 02:10:13-05:00
log5029322aa127cd20a08740a2215fad5863c574fa
treec9817aa3e9a361f195cd13f2afb955df053ed960
parent6ffaf4c2e26e90f7e75d2dd5461addcdb8741c85

c-to-zig: handle UO_Deref


3 files changed, 64 insertions(+), 7 deletions(-)

src/ast_render.cpp+1-1
...@@ -625,7 +625,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -625,7 +625,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
625 fprintf(ar->f, "@");625 fprintf(ar->f, "@");
626 }626 }
627 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;627 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
628 bool grouped = (fn_ref_node->type != NodeTypeBinOpExpr);628 bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr);
629 render_node_extra(ar, fn_ref_node, grouped);629 render_node_extra(ar, fn_ref_node, grouped);
630 fprintf(ar->f, "(");630 fprintf(ar->f, "(");
631 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {631 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
src/parsec.cpp+35-4
...@@ -350,6 +350,21 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location,...@@ -350,6 +350,21 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location,
350 return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr);350 return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr);
351}351}
352352
353static bool qual_type_is_fn_ptr(Context *c, const QualType &qt) {
354 const Type *ty = qt.getTypePtr();
355 if (ty->getTypeClass() != Type::Pointer) {
356 return false;
357 }
358 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
359 QualType child_qt = pointer_ty->getPointeeType();
360 const Type *child_ty = child_qt.getTypePtr();
361 if (child_ty->getTypeClass() != Type::Paren) {
362 return false;
363 }
364 const ParenType *paren_ty = static_cast<const ParenType *>(child_ty);
365 return paren_ty->getInnerType().getTypePtr()->getTypeClass() == Type::FunctionProto;
366}
367
353static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {368static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {
354 const Type *ty = qt.getTypePtr();369 const Type *ty = qt.getTypePtr();
355 switch (ty->getTypeClass()) {370 switch (ty->getTypeClass()) {
...@@ -1575,8 +1590,14 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc...@@ -1575,8 +1590,14 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
1575 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_AddrOf");1590 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_AddrOf");
1576 return nullptr;1591 return nullptr;
1577 case UO_Deref:1592 case UO_Deref:
1578 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Deref");1593 {
1579 return nullptr;1594 bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType());
1595 AstNode *value_node = trans_expr(c, result_used, block, stmt->getSubExpr(), TransRValue);
1596 if (is_fn_ptr)
1597 return value_node;
1598 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);
1599 return trans_create_node_prefix_op(c, PrefixOpDereference, unwrapped);
1600 }
1580 case UO_Plus:1601 case UO_Plus:
1581 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");1602 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");
1582 return nullptr;1603 return nullptr;
...@@ -1919,10 +1940,20 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {...@@ -1919,10 +1940,20 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {
19191940
1920static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, CallExpr *stmt) {1941static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, CallExpr *stmt) {
1921 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);1942 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
1922 node->data.fn_call_expr.fn_ref_expr = trans_expr(c, true, block, stmt->getCallee(), TransRValue);1943
1923 if (node->data.fn_call_expr.fn_ref_expr == nullptr)1944 AstNode *callee_raw_node = trans_expr(c, true, block, stmt->getCallee(), TransRValue);
1945 if (callee_raw_node == nullptr)
1924 return nullptr;1946 return nullptr;
19251947
1948 AstNode *callee_node;
1949 if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {
1950 callee_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, callee_raw_node);
1951 } else {
1952 callee_node = callee_raw_node;
1953 }
1954
1955 node->data.fn_call_expr.fn_ref_expr = callee_node;
1956
1926 unsigned num_args = stmt->getNumArgs();1957 unsigned num_args = stmt->getNumArgs();
1927 Expr **args = stmt->getArgs();1958 Expr **args = stmt->getArgs();
1928 for (unsigned i = 0; i < num_args; i += 1) {1959 for (unsigned i = 0; i < num_args; i += 1) {
test/parsec.zig+28-2
...@@ -203,13 +203,13 @@ pub fn addCases(cases: &tests.ParseCContext) {...@@ -203,13 +203,13 @@ pub fn addCases(cases: &tests.ParseCContext) {
203 \\pub extern var fn_ptr: ?extern fn();203 \\pub extern var fn_ptr: ?extern fn();
204 ,204 ,
205 \\pub inline fn foo() {205 \\pub inline fn foo() {
206 \\ ??fn_ptr()206 \\ (??fn_ptr)()
207 \\}207 \\}
208 ,208 ,
209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;
210 ,210 ,
211 \\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {211 \\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {
212 \\ ??fn_ptr2(arg0, arg1)212 \\ (??fn_ptr2)(arg0, arg1)
213 \\}213 \\}
214 );214 );
215215
...@@ -831,6 +831,32 @@ pub fn addCases(cases: &tests.ParseCContext) {...@@ -831,6 +831,32 @@ pub fn addCases(cases: &tests.ParseCContext) {
831 \\ };831 \\ };
832 \\}832 \\}
833 );833 );
834
835 cases.addC("deref function pointer",
836 \\void foo(void) {}
837 \\void bar(void) {
838 \\ void(*f)(void) = foo;
839 \\ f();
840 \\ (*(f))();
841 \\}
842 ,
843 \\export fn foo() {}
844 \\export fn bar() {
845 \\ var f: ?extern fn() = foo;
846 \\ (??f)();
847 \\ (??f)();
848 \\}
849 );
850
851 cases.addC("normal deref",
852 \\void foo(int *x) {
853 \\ *x = 1;
854 \\}
855 ,
856 \\export fn foo(x: ?&c_int) {
857 \\ (*(??x)) = 1;
858 \\}
859 );
834}860}
835861
836862