diff --git a/src/analyze.hpp b/src/analyze.hpp index e6100c692c..e12c4cda44 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -180,5 +180,6 @@ void add_link_lib_symbol(CodeGen *g, Buf *lib_name, Buf *symbol_name); uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry); TypeTableEntry *get_align_amt_type(CodeGen *g); +PackageTableEntry *new_anonymous_package(void); #endif diff --git a/src/codegen.cpp b/src/codegen.cpp index d052ef159a..44b3df3526 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -55,6 +55,10 @@ static PackageTableEntry *new_package(const char *root_src_dir, const char *root return entry; } +PackageTableEntry *new_anonymous_package(void) { + return new_package("", ""); +} + CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode, Buf *zig_lib_dir) { diff --git a/src/ir.cpp b/src/ir.cpp index 0512ab5e36..62927f46a0 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -14052,6 +14052,9 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc ImportTableEntry *child_import = allocate(1); child_import->decls_scope = create_decls_scope(node, nullptr, nullptr, child_import); child_import->c_import_node = node; + child_import->package = new_anonymous_package(); + child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); + child_import->package->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); ZigList errors = {0}; diff --git a/src/translate_c.cpp b/src/translate_c.cpp index f8f5b5ba62..4575d4ee56 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -173,6 +173,14 @@ static AstNode * trans_create_node(Context *c, NodeType id) { return node; } +static AstNode *trans_create_node_if(Context *c, AstNode *cond_node, AstNode *then_node, AstNode *else_node) { + AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr); + node->data.if_bool_expr.condition = cond_node; + node->data.if_bool_expr.then_block = then_node; + node->data.if_bool_expr.else_node = else_node; + return node; +} + static AstNode *trans_create_node_float_lit(Context *c, double value) { AstNode *node = trans_create_node(c, NodeTypeFloatLiteral); node->data.float_literal.bigfloat = allocate(1); @@ -4077,14 +4085,35 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok } *tok_i += 1; - 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); - } + + //if (@typeId(@typeOf(x)) == @import("builtin").TypeId.Pointer) + // @ptrCast(dest, x) + //else if (@typeId(@typeOf(x)) == @import("builtin").TypeId.Integer) + // @intToPtr(dest, x) + //else + // (dest)(x) + + AstNode *import_builtin = trans_create_node_builtin_fn_call_str(c, "import"); + import_builtin->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("builtin"))); + AstNode *typeid_type = trans_create_node_field_access_str(c, import_builtin, "TypeId"); + AstNode *typeid_pointer = trans_create_node_field_access_str(c, typeid_type, "Pointer"); + AstNode *typeid_integer = trans_create_node_field_access_str(c, typeid_type, "Int"); + AstNode *typeof_x = trans_create_node_builtin_fn_call_str(c, "typeOf"); + typeof_x->data.fn_call_expr.params.append(node_to_cast); + AstNode *typeid_value = trans_create_node_builtin_fn_call_str(c, "typeId"); + typeid_value->data.fn_call_expr.params.append(typeof_x); + + AstNode *outer_if_cond = trans_create_node_bin_op(c, typeid_value, BinOpTypeCmpEq, typeid_pointer); + AstNode *inner_if_cond = trans_create_node_bin_op(c, typeid_value, BinOpTypeCmpEq, typeid_integer); + AstNode *inner_if_then = trans_create_node_builtin_fn_call_str(c, "intToPtr"); + inner_if_then->data.fn_call_expr.params.append(inner_node); + inner_if_then->data.fn_call_expr.params.append(node_to_cast); + AstNode *inner_if_else = trans_create_node_cast(c, inner_node, node_to_cast); + AstNode *inner_if = trans_create_node_if(c, inner_if_cond, inner_if_then, inner_if_else); + AstNode *outer_if_then = trans_create_node_builtin_fn_call_str(c, "ptrCast"); + outer_if_then->data.fn_call_expr.params.append(inner_node); + outer_if_then->data.fn_call_expr.params.append(node_to_cast); + return trans_create_node_if(c, outer_if_cond, outer_if_then, inner_if); } case CTokIdDot: case CTokIdEOF: diff --git a/test/translate_c.zig b/test/translate_c.zig index bbdd56db0d..d50c7b9691 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -1192,6 +1192,6 @@ pub fn addCases(cases: &tests.TranslateCContext) { 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); + \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast(&NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr(&NRF_GPIO_Type, NRF_GPIO_BASE) else (&NRF_GPIO_Type)(NRF_GPIO_BASE); ); }