diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 4f4dc1decd..d6a23e5f85 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -584,12 +584,15 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { PrefixOp op = node->data.prefix_op_expr.prefix_op; fprintf(ar->f, "%s", prefix_op_str(op)); - render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr); + AstNode *child_node = node->data.prefix_op_expr.primary_expr; + bool new_grouped = child_node->type == NodeTypePrefixOpExpr || child_node->type == NodeTypeAddrOfExpr; + render_node_extra(ar, child_node, new_grouped); if (!grouped) fprintf(ar->f, ")"); break; } case NodeTypeAddrOfExpr: { + if (!grouped) fprintf(ar->f, "("); fprintf(ar->f, "&"); if (node->data.addr_of_expr.align_expr != nullptr) { fprintf(ar->f, "align("); @@ -617,6 +620,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { } render_node_ungrouped(ar, node->data.addr_of_expr.op_expr); + if (!grouped) fprintf(ar->f, ")"); break; } case NodeTypeFnCallExpr: @@ -625,7 +629,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { fprintf(ar->f, "@"); } AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; - bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr); + bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypeAddrOfExpr); render_node_extra(ar, fn_ref_node, grouped); fprintf(ar->f, "("); for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) { diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 9e73c08b84..f8f5b5ba62 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4061,11 +4061,30 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok } CTok *next_tok = &ctok->tokens.at(*tok_i); - if (next_tok->id != CTokIdRParen) { + if (next_tok->id == CTokIdRParen) { + *tok_i += 1; + return inner_node; + } + + AstNode *node_to_cast = parse_ctok_expr(c, ctok, tok_i); + if (node_to_cast == nullptr) { + return nullptr; + } + + CTok *next_tok2 = &ctok->tokens.at(*tok_i); + if (next_tok2->id != CTokIdRParen) { return nullptr; } *tok_i += 1; - return inner_node; + + if (inner_node->type == NodeTypeAddrOfExpr) { + AstNode *call_node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); + call_node->data.fn_call_expr.params.append(inner_node); + call_node->data.fn_call_expr.params.append(node_to_cast); + return call_node; + } else { + return trans_create_node_cast(c, inner_node, node_to_cast); + } } case CTokIdDot: case CTokIdEOF: diff --git a/test/translate_c.zig b/test/translate_c.zig index d4974109da..bbdd56db0d 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -902,7 +902,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { \\} , \\export fn foo(x: ?&c_int) { - \\ (*(??x)) = 1; + \\ (*??x) = 1; \\} ); @@ -930,7 +930,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { \\pub fn foo() -> c_int { \\ var x: c_int = 1234; \\ var ptr: ?&c_int = &x; - \\ return *(??ptr); + \\ return *??ptr; \\} ); @@ -1188,4 +1188,10 @@ pub fn addCases(cases: &tests.TranslateCContext) { \\ const v2: &const u8 = c"2.2.2"; \\} ); + + cases.add("macro pointer cast", + \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) + , + \\pub const NRF_GPIO = @ptrCast(&NRF_GPIO_Type, NRF_GPIO_BASE); + ); }