diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-09-10 12:30:57 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-09-10 12:30:57 -0400 |
| commit | c9474faa4e6cfd6480c1bd24216c26f4320e3c29 (patch) | |
| tree | 4bf022698f229cd276b598ed95aa30a61e882674 /src/codegen.cpp | |
| parent | f27d82fe90e1d0007bf2d3ef52eac8cdbc381e0d (diff) | |
| parent | 7c9f7b72c59e7c6de38038f512ae332fc164e8d7 (diff) | |
| download | zig-c9474faa4e6cfd6480c1bd24216c26f4320e3c29.tar.gz zig-c9474faa4e6cfd6480c1bd24216c26f4320e3c29.zip | |
Merge remote-tracking branch 'origin/master' into llvm7
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 1509 |
1 files changed, 906 insertions, 603 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index d6c7e41a2c..c42ddeade7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -243,7 +243,7 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) { g->root_out_name = out_name; } -void codegen_set_cache_dir(CodeGen *g, Buf *cache_dir) { +void codegen_set_cache_dir(CodeGen *g, Buf cache_dir) { g->cache_dir = cache_dir; } @@ -358,6 +358,10 @@ static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char return addLLVMAttr(fn_val, param_index + 1, attr_name); } +static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const char *attr_name, uint64_t attr_val) { + return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val); +} + static bool is_symbol_available(CodeGen *g, Buf *name) { return g->exported_symbol_names.maybe_get(name) == nullptr && g->external_prototypes.maybe_get(name) == nullptr; } @@ -430,23 +434,23 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) { zig_unreachable(); } -static uint32_t get_err_ret_trace_arg_index(CodeGen *g, FnTableEntry *fn_table_entry) { +static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) { if (!g->have_err_ret_tracing) { return UINT32_MAX; } if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) { return 0; } - TypeTableEntry *fn_type = fn_table_entry->type_entry; + ZigType *fn_type = fn_table_entry->type_entry; if (!fn_type_can_fail(&fn_type->data.fn.fn_type_id)) { return UINT32_MAX; } - TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type; + ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; bool first_arg_ret = type_has_bits(return_type) && handle_is_ptr(return_type); return first_arg_ret ? 1 : 0; } -static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { +static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { if (fn_table_entry->llvm_value) return fn_table_entry->llvm_value; @@ -466,7 +470,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { } bool external_linkage = linkage != GlobalLinkageIdInternal; - if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall && external_linkage && + CallingConvention cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc; + if (cc == CallingConventionStdcall && external_linkage && g->zig_target.arch.arch == ZigLLVM_x86) { // prevent llvm name mangling @@ -474,7 +479,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { } - TypeTableEntry *fn_type = fn_table_entry->type_entry; + ZigType *fn_type = fn_table_entry->type_entry; LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref; if (fn_table_entry->body_node == nullptr) { LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); @@ -510,17 +515,17 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { break; } - if (fn_type->data.fn.fn_type_id.cc == CallingConventionNaked) { + if (cc == CallingConventionNaked) { addLLVMFnAttr(fn_table_entry->llvm_value, "naked"); } else { LLVMSetFunctionCallConv(fn_table_entry->llvm_value, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc)); } - if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) { + if (cc == CallingConventionAsync) { addLLVMFnAttr(fn_table_entry->llvm_value, "optnone"); addLLVMFnAttr(fn_table_entry->llvm_value, "noinline"); } - bool want_cold = fn_table_entry->is_cold || fn_type->data.fn.fn_type_id.cc == CallingConventionCold; + bool want_cold = fn_table_entry->is_cold || cc == CallingConventionCold; if (want_cold) { ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value); } @@ -532,8 +537,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true); } - TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type; - if (return_type->id == TypeTableEntryIdUnreachable) { + ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; + if (return_type->id == ZigTypeIdUnreachable) { addLLVMFnAttr(fn_table_entry->llvm_value, "noreturn"); } @@ -572,41 +577,26 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { // use the ABI alignment, which is fine. } + unsigned init_gen_i = 0; if (!type_has_bits(return_type)) { // nothing to do } else if (type_is_codegen_pointer(return_type)) { addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull"); - } else if (handle_is_ptr(return_type) && - calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc)) - { + } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret"); addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull"); + if (cc == CallingConventionC) { + addLLVMArgAttr(fn_table_entry->llvm_value, 0, "noalias"); + } + init_gen_i = 1; } - // set parameter attributes - for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) { - FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; - size_t gen_index = gen_info->gen_index; - bool is_byval = gen_info->is_byval; - - if (gen_index == SIZE_MAX) { - continue; - } - - FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[param_i]; - - TypeTableEntry *param_type = gen_info->type; - if (param_info->is_noalias) { - addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "noalias"); - } - if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) { - addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "readonly"); - } - if (param_type->id == TypeTableEntryIdPointer) { - addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull"); - } - } + FnWalk fn_walk = {}; + fn_walk.id = FnWalkIdAttrs; + fn_walk.data.attrs.fn = fn_table_entry; + fn_walk.data.attrs.gen_i = init_gen_i; + walk_function_params(g, fn_type, &fn_walk); uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry); if (err_ret_trace_arg_index != UINT32_MAX) { @@ -628,7 +618,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { { assert(scope->parent); ScopeFnDef *fn_scope = (ScopeFnDef *)scope; - FnTableEntry *fn_table_entry = fn_scope->fn_entry; + ZigFn *fn_table_entry = fn_scope->fn_entry; if (!fn_table_entry->proto_node) return get_di_scope(g, scope->parent); unsigned line_number = (unsigned)(fn_table_entry->proto_node->line == 0) ? @@ -678,6 +668,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { case ScopeIdSuspend: case ScopeIdCompTime: case ScopeIdCoroPrelude: + case ScopeIdRuntime: return get_di_scope(g, scope->parent); } zig_unreachable(); @@ -687,12 +678,12 @@ static void clear_debug_source_node(CodeGen *g) { ZigLLVMClearCurrentDebugLocation(g->builder); } -static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, TypeTableEntry *type_entry, +static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, ZigType *type_entry, const char *signed_name, const char *unsigned_name) { char fn_name[64]; - assert(type_entry->id == TypeTableEntryIdInt); + assert(type_entry->id == ZigTypeIdInt); const char *signed_str = type_entry->data.integral.is_signed ? signed_name : unsigned_name; sprintf(fn_name, "llvm.%s.with.overflow.i%" PRIu32, signed_str, type_entry->data.integral.bit_count); @@ -711,8 +702,8 @@ static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, TypeTableEntry *type_ return fn_val; } -static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry, AddSubMul add_sub_mul) { - assert(type_entry->id == TypeTableEntryIdInt); +static LLVMValueRef get_int_overflow_fn(CodeGen *g, ZigType *type_entry, AddSubMul add_sub_mul) { + assert(type_entry->id == ZigTypeIdInt); ZigLLVMFnKey key = {}; key.id = ZigLLVMFnIdOverflowArithmetic; @@ -741,8 +732,8 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, TypeTableEntry *type_entry, return fn_val; } -static LLVMValueRef get_float_fn(CodeGen *g, TypeTableEntry *type_entry, ZigLLVMFnId fn_id) { - assert(type_entry->id == TypeTableEntryIdFloat); +static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn_id) { + assert(type_entry->id == ZigTypeIdFloat); ZigLLVMFnKey key = {}; key.id = fn_id; @@ -786,8 +777,8 @@ static LLVMValueRef gen_store_untyped(CodeGen *g, LLVMValueRef value, LLVMValueR return instruction; } -static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr, TypeTableEntry *ptr_type) { - assert(ptr_type->id == TypeTableEntryIdPointer); +static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr, ZigType *ptr_type) { + assert(ptr_type->id == ZigTypeIdPointer); return gen_store_untyped(g, value, ptr, ptr_type->data.pointer.alignment, ptr_type->data.pointer.is_volatile); } @@ -804,17 +795,17 @@ static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alig return result; } -static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *ptr_type, const char *name) { - assert(ptr_type->id == TypeTableEntryIdPointer); +static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, const char *name) { + assert(ptr_type->id == ZigTypeIdPointer); return gen_load_untyped(g, ptr, ptr_type->data.pointer.alignment, ptr_type->data.pointer.is_volatile, name); } -static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type, TypeTableEntry *ptr_type) { +static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) { if (type_has_bits(type)) { if (handle_is_ptr(type)) { return ptr; } else { - assert(ptr_type->id == TypeTableEntryIdPointer); + assert(ptr_type->id == ZigTypeIdPointer); return gen_load(g, ptr, ptr_type, ""); } } else { @@ -917,9 +908,9 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { assert(val->global_refs->llvm_global); } - TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, + ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); - TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type); + ZigType *str_type = get_slice_type(g, u8_ptr_type); return LLVMConstBitCast(val->global_refs->llvm_global, LLVMPointerType(str_type->type_ref, 0)); } @@ -928,7 +919,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace LLVMValueRef fn_val = fn_llvm_value(g, g->panic_fn); LLVMCallConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc); if (stack_trace_arg == nullptr) { - TypeTableEntry *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); + ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); stack_trace_arg = LLVMConstNull(ptr_to_stack_trace_type->type_ref); } LLVMValueRef args[] = { @@ -1166,7 +1157,7 @@ static LLVMValueRef get_return_address_fn_val(CodeGen *g) { if (g->return_address_fn_val) return g->return_address_fn_val; - TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); + ZigType *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); LLVMTypeRef fn_type = LLVMFunctionType(return_type->type_ref, &g->builtin_types.entry_i32->type_ref, 1, false); @@ -1217,7 +1208,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, ""); - TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; + ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; @@ -1317,7 +1308,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { (unsigned)src_index_field_index, ""); LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr, (unsigned)src_addresses_field_index, ""); - TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; + ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, ""); size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; @@ -1459,7 +1450,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMSetUnnamedAddr(global_array, true); LLVMSetAlignment(global_array, u8_align_bytes); - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; LLVMValueRef full_buf_ptr_indices[] = { LLVMConstNull(usize->type_ref), LLVMConstNull(usize->type_ref), @@ -1467,9 +1458,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMValueRef full_buf_ptr = LLVMConstInBoundsGEP(global_array, full_buf_ptr_indices, 2); - TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, + ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); - TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type); + ZigType *str_type = get_slice_type(g, u8_ptr_type); LLVMValueRef global_slice_fields[] = { full_buf_ptr, LLVMConstNull(usize->type_ref), @@ -1575,7 +1566,7 @@ static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *sc LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g); LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, scope); if (err_ret_trace_val == nullptr) { - TypeTableEntry *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); + ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); err_ret_trace_val = LLVMConstNull(ptr_to_stack_trace_type->type_ref); } LLVMValueRef args[] = { @@ -1621,24 +1612,24 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val, LLVMPositionBuilderAtEnd(g->builder, ok_block); } -static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, TypeTableEntry *actual_type, - TypeTableEntry *wanted_type, LLVMValueRef expr_val) +static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, ZigType *actual_type, + ZigType *wanted_type, LLVMValueRef expr_val) { assert(actual_type->id == wanted_type->id); uint64_t actual_bits; uint64_t wanted_bits; - if (actual_type->id == TypeTableEntryIdFloat) { + if (actual_type->id == ZigTypeIdFloat) { actual_bits = actual_type->data.floating.bit_count; wanted_bits = wanted_type->data.floating.bit_count; - } else if (actual_type->id == TypeTableEntryIdInt) { + } else if (actual_type->id == ZigTypeIdInt) { actual_bits = actual_type->data.integral.bit_count; wanted_bits = wanted_type->data.integral.bit_count; } else { zig_unreachable(); } - if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt && + if (actual_bits >= wanted_bits && actual_type->id == ZigTypeIdInt && !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed && want_runtime_safety) { @@ -1658,9 +1649,9 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, T if (actual_bits == wanted_bits) { return expr_val; } else if (actual_bits < wanted_bits) { - if (actual_type->id == TypeTableEntryIdFloat) { + if (actual_type->id == ZigTypeIdFloat) { return LLVMBuildFPExt(g->builder, expr_val, wanted_type->type_ref, ""); - } else if (actual_type->id == TypeTableEntryIdInt) { + } else if (actual_type->id == ZigTypeIdInt) { if (actual_type->data.integral.is_signed) { return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, ""); } else { @@ -1670,9 +1661,9 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, T zig_unreachable(); } } else if (actual_bits > wanted_bits) { - if (actual_type->id == TypeTableEntryIdFloat) { + if (actual_type->id == ZigTypeIdFloat) { return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, ""); - } else if (actual_type->id == TypeTableEntryIdInt) { + } else if (actual_type->id == ZigTypeIdInt) { LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, ""); if (!want_runtime_safety) { return trunc_val; @@ -1701,7 +1692,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, T } } -static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddSubMul op, +static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *type_entry, AddSubMul op, LLVMValueRef val1, LLVMValueRef val2) { LLVMValueRef fn_val = get_int_overflow_fn(g, type_entry, op); @@ -1761,11 +1752,11 @@ static LLVMRealPredicate cmp_op_to_real_predicate(IrBinOp cmp_op) { } } -static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *ptr_type, +static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, LLVMValueRef value) { - assert(ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *child_type = ptr_type->data.pointer.child_type; + assert(ptr_type->id == ZigTypeIdPointer); + ZigType *child_type = ptr_type->data.pointer.child_type; if (!type_has_bits(child_type)) return nullptr; @@ -1779,7 +1770,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, value, ptr_u8, ""); LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, ""); - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, child_type->type_ref); uint64_t align_bytes = ptr_type->data.pointer.alignment; assert(size_bytes > 0); @@ -1819,7 +1810,8 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry return nullptr; } -static void gen_var_debug_decl(CodeGen *g, VariableTableEntry *var) { +static void gen_var_debug_decl(CodeGen *g, ZigVar *var) { + assert(var->di_loc_var != nullptr); AstNode *source_node = var->decl_node; ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1, (unsigned)source_node->column + 1, get_di_scope(g, var->parent_scope)); @@ -1838,9 +1830,9 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { // values are rendered with a type other than the one we expect if (handle_is_ptr(instruction->value.type)) { render_const_val_global(g, &instruction->value, ""); - TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true); + ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true); instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, ptr_type->type_ref, ""); - } else if (instruction->value.type->id == TypeTableEntryIdPointer) { + } else if (instruction->value.type->id == ZigTypeIdPointer) { instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value, instruction->value.type->type_ref, ""); } else { instruction->llvm_value = instruction->value.global_refs->llvm_value; @@ -1850,6 +1842,353 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { return instruction->llvm_value; } +ATTRIBUTE_NORETURN +static void report_errors_and_exit(CodeGen *g) { + assert(g->errors.length != 0); + for (size_t i = 0; i < g->errors.length; i += 1) { + ErrorMsg *err = g->errors.at(i); + print_err_msg(err, g->err_color); + } + exit(1); +} + +static void report_errors_and_maybe_exit(CodeGen *g) { + if (g->errors.length != 0) { + report_errors_and_exit(g); + } +} + +ATTRIBUTE_NORETURN +static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) { + ErrorMsg *msg = add_node_error(g, source_node, + buf_sprintf("TODO: support C ABI for more targets. https://github.com/ziglang/zig/issues/1481")); + add_error_note(g, msg, source_node, + buf_sprintf("pointers, integers, floats, bools, and enums work on all targets")); + report_errors_and_exit(g); +} + +static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment) { + assert(alignment > 0); + LLVMValueRef result = LLVMBuildAlloca(g->builder, type_entry->type_ref, name); + LLVMSetAlignment(result, alignment); + return result; +} + +static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk, size_t src_i) { + // Initialized from the type for some walks, but because of C var args, + // initialized based on callsite instructions for that one. + FnTypeParamInfo *param_info = nullptr; + ZigType *ty; + ZigType *dest_ty = nullptr; + AstNode *source_node = nullptr; + LLVMValueRef val; + LLVMValueRef llvm_fn; + unsigned di_arg_index; + ZigVar *var; + switch (fn_walk->id) { + case FnWalkIdAttrs: + if (src_i >= fn_type->data.fn.fn_type_id.param_count) + return false; + param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; + ty = param_info->type; + source_node = fn_walk->data.attrs.fn->proto_node; + llvm_fn = fn_walk->data.attrs.fn->llvm_value; + break; + case FnWalkIdCall: { + if (src_i >= fn_walk->data.call.inst->arg_count) + return false; + IrInstruction *arg = fn_walk->data.call.inst->args[src_i]; + ty = arg->value.type; + source_node = arg->source_node; + val = ir_llvm_value(g, arg); + break; + } + case FnWalkIdTypes: + if (src_i >= fn_type->data.fn.fn_type_id.param_count) + return false; + param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; + ty = param_info->type; + break; + case FnWalkIdVars: + assert(src_i < fn_type->data.fn.fn_type_id.param_count); + param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; + ty = param_info->type; + var = fn_walk->data.vars.var; + source_node = var->decl_node; + llvm_fn = fn_walk->data.vars.llvm_fn; + break; + case FnWalkIdInits: + if (src_i >= fn_type->data.fn.fn_type_id.param_count) + return false; + param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; + ty = param_info->type; + var = fn_walk->data.inits.fn->variable_list.at(src_i); + source_node = fn_walk->data.inits.fn->proto_node; + llvm_fn = fn_walk->data.inits.llvm_fn; + break; + } + + if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || + ty->id == ZigTypeIdInt // TODO investigate if we need to change this + ) { + switch (fn_walk->id) { + case FnWalkIdAttrs: { + ZigType *ptr_type = get_codegen_ptr_type(ty); + if (ptr_type != nullptr) { + if (ty->id != ZigTypeIdOptional) { + addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); + } + if (ptr_type->data.pointer.is_const) { + addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "readonly"); + } + if (param_info->is_noalias) { + addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "noalias"); + } + } + fn_walk->data.attrs.gen_i += 1; + break; + } + case FnWalkIdCall: + fn_walk->data.call.gen_param_values->append(val); + break; + case FnWalkIdTypes: + fn_walk->data.types.gen_param_types->append(ty->type_ref); + fn_walk->data.types.param_di_types->append(ty->di_type); + break; + case FnWalkIdVars: { + var->value_ref = build_alloca(g, ty, buf_ptr(&var->name), var->align_bytes); + di_arg_index = fn_walk->data.vars.gen_i; + fn_walk->data.vars.gen_i += 1; + dest_ty = ty; + goto var_ok; + } + case FnWalkIdInits: + clear_debug_source_node(g); + gen_store_untyped(g, LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i), var->value_ref, var->align_bytes, false); + if (var->decl_node) { + gen_var_debug_decl(g, var); + } + fn_walk->data.inits.gen_i += 1; + break; + } + return true; + } + + // Arrays are just pointers + if (ty->id == ZigTypeIdArray) { + assert(handle_is_ptr(ty)); + switch (fn_walk->id) { + case FnWalkIdAttrs: + addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); + addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); + fn_walk->data.attrs.gen_i += 1; + break; + case FnWalkIdCall: + fn_walk->data.call.gen_param_values->append(val); + break; + case FnWalkIdTypes: { + ZigType *gen_type = get_pointer_to_type(g, ty, true); + fn_walk->data.types.gen_param_types->append(gen_type->type_ref); + fn_walk->data.types.param_di_types->append(gen_type->di_type); + break; + } + case FnWalkIdVars: { + var->value_ref = LLVMGetParam(llvm_fn, fn_walk->data.vars.gen_i); + di_arg_index = fn_walk->data.vars.gen_i; + dest_ty = get_pointer_to_type(g, ty, false); + fn_walk->data.vars.gen_i += 1; + goto var_ok; + } + case FnWalkIdInits: + if (var->decl_node) { + gen_var_debug_decl(g, var); + } + fn_walk->data.inits.gen_i += 1; + break; + } + return true; + } + + if (g->zig_target.arch.arch == ZigLLVM_x86_64) { + X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty); + size_t ty_size = type_size(g, ty); + if (abi_class == X64CABIClass_MEMORY) { + assert(handle_is_ptr(ty)); + switch (fn_walk->id) { + case FnWalkIdAttrs: + addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval"); + addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); + addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); + fn_walk->data.attrs.gen_i += 1; + break; + case FnWalkIdCall: + fn_walk->data.call.gen_param_values->append(val); + break; + case FnWalkIdTypes: { + ZigType *gen_type = get_pointer_to_type(g, ty, true); + fn_walk->data.types.gen_param_types->append(gen_type->type_ref); + fn_walk->data.types.param_di_types->append(gen_type->di_type); + break; + } + case FnWalkIdVars: { + di_arg_index = fn_walk->data.vars.gen_i; + var->value_ref = LLVMGetParam(llvm_fn, fn_walk->data.vars.gen_i); + dest_ty = get_pointer_to_type(g, ty, false); + fn_walk->data.vars.gen_i += 1; + goto var_ok; + } + case FnWalkIdInits: + if (var->decl_node) { + gen_var_debug_decl(g, var); + } + fn_walk->data.inits.gen_i += 1; + break; + } + return true; + } else if (abi_class == X64CABIClass_INTEGER) { + switch (fn_walk->id) { + case FnWalkIdAttrs: + fn_walk->data.attrs.gen_i += 1; + break; + case FnWalkIdCall: { + LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0); + LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, ptr_to_int_type_ref, ""); + LLVMValueRef loaded = LLVMBuildLoad(g->builder, bitcasted, ""); + fn_walk->data.call.gen_param_values->append(loaded); + break; + } + case FnWalkIdTypes: { + ZigType *gen_type = get_int_type(g, false, ty_size * 8); + fn_walk->data.types.gen_param_types->append(gen_type->type_ref); + fn_walk->data.types.param_di_types->append(gen_type->di_type); + break; + } + case FnWalkIdVars: { + di_arg_index = fn_walk->data.vars.gen_i; + var->value_ref = build_alloca(g, ty, buf_ptr(&var->name), var->align_bytes); + fn_walk->data.vars.gen_i += 1; + dest_ty = ty; + goto var_ok; + } + case FnWalkIdInits: { + clear_debug_source_node(g); + LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i); + LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0); + LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, ""); + gen_store_untyped(g, arg, bitcasted, var->align_bytes, false); + if (var->decl_node) { + gen_var_debug_decl(g, var); + } + fn_walk->data.inits.gen_i += 1; + break; + } + } + return true; + } + } + if (source_node != nullptr) { + give_up_with_c_abi_error(g, source_node); + } + // otherwise allow codegen code to report a compile error + return false; + +var_ok: + if (dest_ty != nullptr && var->decl_node) { + // arg index + 1 because the 0 index is return value + var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), + buf_ptr(&var->name), fn_walk->data.vars.import->di_file, + (unsigned)(var->decl_node->line + 1), + dest_ty->di_type, !g->strip_debug_symbols, 0, di_arg_index + 1); + } + return true; +} + +void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { + CallingConvention cc = fn_type->data.fn.fn_type_id.cc; + if (cc == CallingConventionC) { + size_t src_i = 0; + for (;;) { + if (!iter_function_params_c_abi(g, fn_type, fn_walk, src_i)) + break; + src_i += 1; + } + return; + } + if (fn_walk->id == FnWalkIdCall) { + IrInstructionCall *instruction = fn_walk->data.call.inst; + bool is_var_args = fn_walk->data.call.is_var_args; + for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) { + IrInstruction *param_instruction = instruction->args[call_i]; + ZigType *param_type = param_instruction->value.type; + if (is_var_args || type_has_bits(param_type)) { + LLVMValueRef param_value = ir_llvm_value(g, param_instruction); + assert(param_value); + fn_walk->data.call.gen_param_values->append(param_value); + } + } + return; + } + size_t next_var_i = 0; + for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) { + FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; + size_t gen_index = gen_info->gen_index; + + if (gen_index == SIZE_MAX) { + continue; + } + + switch (fn_walk->id) { + case FnWalkIdAttrs: { + LLVMValueRef llvm_fn = fn_walk->data.attrs.fn->llvm_value; + bool is_byval = gen_info->is_byval; + FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[param_i]; + + ZigType *param_type = gen_info->type; + if (param_info->is_noalias) { + addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "noalias"); + } + if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) { + addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly"); + } + if (param_type->id == ZigTypeIdPointer) { + addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull"); + } + break; + } + case FnWalkIdInits: { + ZigFn *fn_table_entry = fn_walk->data.inits.fn; + LLVMValueRef llvm_fn = fn_table_entry->llvm_value; + ZigVar *variable = fn_table_entry->variable_list.at(next_var_i); + assert(variable->src_arg_index != SIZE_MAX); + next_var_i += 1; + + assert(variable); + assert(variable->value_ref); + + if (!handle_is_ptr(variable->value->type)) { + clear_debug_source_node(g); + gen_store_untyped(g, LLVMGetParam(llvm_fn, (unsigned)variable->gen_arg_index), variable->value_ref, + variable->align_bytes, false); + } + + if (variable->decl_node) { + gen_var_debug_decl(g, variable); + } + break; + } + case FnWalkIdCall: + // handled before for loop + zig_unreachable(); + case FnWalkIdTypes: + // Not called for non-c-abi + zig_unreachable(); + case FnWalkIdVars: + // iter_function_params_c_abi is called directly for this one + zig_unreachable(); + } + } +} + static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *executable, IrInstructionSaveErrRetAddr *save_err_ret_addr_instruction) { @@ -1866,24 +2205,22 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) { LLVMValueRef value = ir_llvm_value(g, return_instruction->value); - TypeTableEntry *return_type = return_instruction->value->value.type; - - if (handle_is_ptr(return_type)) { - if (calling_convention_does_first_arg_return(g->cur_fn->type_entry->data.fn.fn_type_id.cc)) { - assert(g->cur_ret_ptr); - gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value); - LLVMBuildRetVoid(g->builder); - } else { - LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, ""); - LLVMBuildRet(g->builder, by_val_value); - } + ZigType *return_type = return_instruction->value->value.type; + + if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) { + assert(g->cur_ret_ptr); + gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value); + LLVMBuildRetVoid(g->builder); + } else if (handle_is_ptr(return_type)) { + LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, ""); + LLVMBuildRet(g->builder, by_val_value); } else { LLVMBuildRet(g->builder, value); } return nullptr; } -static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry, +static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *type_entry, LLVMValueRef val1, LLVMValueRef val2) { // for unsigned left shifting, we do the lossy shift, then logically shift @@ -1891,7 +2228,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry, // if the values don't match, we have an overflow // for signed left shifting we do the same except arithmetic shift right - assert(type_entry->id == TypeTableEntryIdInt); + assert(type_entry->id == ZigTypeIdInt); LLVMValueRef result = LLVMBuildShl(g->builder, val1, val2, ""); LLVMValueRef orig_val; @@ -1913,10 +2250,10 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry, return result; } -static LLVMValueRef gen_overflow_shr_op(CodeGen *g, TypeTableEntry *type_entry, +static LLVMValueRef gen_overflow_shr_op(CodeGen *g, ZigType *type_entry, LLVMValueRef val1, LLVMValueRef val2) { - assert(type_entry->id == TypeTableEntryIdInt); + assert(type_entry->id == ZigTypeIdInt); LLVMValueRef result; if (type_entry->data.integral.is_signed) { @@ -1938,16 +2275,16 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, TypeTableEntry *type_entry, return result; } -static LLVMValueRef gen_floor(CodeGen *g, LLVMValueRef val, TypeTableEntry *type_entry) { - if (type_entry->id == TypeTableEntryIdInt) +static LLVMValueRef gen_floor(CodeGen *g, LLVMValueRef val, ZigType *type_entry) { + if (type_entry->id == ZigTypeIdInt) return val; LLVMValueRef floor_fn = get_float_fn(g, type_entry, ZigLLVMFnIdFloor); return LLVMBuildCall(g->builder, floor_fn, &val, 1, ""); } -static LLVMValueRef gen_ceil(CodeGen *g, LLVMValueRef val, TypeTableEntry *type_entry) { - if (type_entry->id == TypeTableEntryIdInt) +static LLVMValueRef gen_ceil(CodeGen *g, LLVMValueRef val, ZigType *type_entry) { + if (type_entry->id == ZigTypeIdInt) return val; LLVMValueRef ceil_fn = get_float_fn(g, type_entry, ZigLLVMFnIdCeil); @@ -1980,16 +2317,16 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) { static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math, LLVMValueRef val1, LLVMValueRef val2, - TypeTableEntry *type_entry, DivKind div_kind) + ZigType *type_entry, DivKind div_kind) { ZigLLVMSetFastMath(g->builder, want_fast_math); LLVMValueRef zero = LLVMConstNull(type_entry->type_ref); - if (want_runtime_safety && (want_fast_math || type_entry->id != TypeTableEntryIdFloat)) { + if (want_runtime_safety && (want_fast_math || type_entry->id != ZigTypeIdFloat)) { LLVMValueRef is_zero_bit; - if (type_entry->id == TypeTableEntryIdInt) { + if (type_entry->id == ZigTypeIdInt) { is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, ""); - } else if (type_entry->id == TypeTableEntryIdFloat) { + } else if (type_entry->id == ZigTypeIdFloat) { is_zero_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, val2, zero, ""); } else { zig_unreachable(); @@ -2003,7 +2340,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast LLVMPositionBuilderAtEnd(g->builder, div_zero_ok_block); - if (type_entry->id == TypeTableEntryIdInt && type_entry->data.integral.is_signed) { + if (type_entry->id == ZigTypeIdInt && type_entry->data.integral.is_signed) { LLVMValueRef neg_1_value = LLVMConstInt(type_entry->type_ref, -1, true); BigInt int_min_bi = {0}; eval_min_max_value_int(g, type_entry, &int_min_bi, false); @@ -2022,7 +2359,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast } } - if (type_entry->id == TypeTableEntryIdFloat) { + if (type_entry->id == ZigTypeIdFloat) { LLVMValueRef result = LLVMBuildFDiv(g->builder, val1, val2, ""); switch (div_kind) { case DivKindFloat: @@ -2073,7 +2410,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast zig_unreachable(); } - assert(type_entry->id == TypeTableEntryIdInt); + assert(type_entry->id == ZigTypeIdInt); switch (div_kind) { case DivKindFloat: @@ -2139,17 +2476,17 @@ enum RemKind { static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast_math, LLVMValueRef val1, LLVMValueRef val2, - TypeTableEntry *type_entry, RemKind rem_kind) + ZigType *type_entry, RemKind rem_kind) { ZigLLVMSetFastMath(g->builder, want_fast_math); LLVMValueRef zero = LLVMConstNull(type_entry->type_ref); if (want_runtime_safety) { LLVMValueRef is_zero_bit; - if (type_entry->id == TypeTableEntryIdInt) { + if (type_entry->id == ZigTypeIdInt) { LLVMIntPredicate pred = type_entry->data.integral.is_signed ? LLVMIntSLE : LLVMIntEQ; is_zero_bit = LLVMBuildICmp(g->builder, pred, val2, zero, ""); - } else if (type_entry->id == TypeTableEntryIdFloat) { + } else if (type_entry->id == ZigTypeIdFloat) { is_zero_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, val2, zero, ""); } else { zig_unreachable(); @@ -2164,7 +2501,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast LLVMPositionBuilderAtEnd(g->builder, rem_zero_ok_block); } - if (type_entry->id == TypeTableEntryIdFloat) { + if (type_entry->id == ZigTypeIdFloat) { if (rem_kind == RemKindRem) { return LLVMBuildFRem(g->builder, val1, val2, ""); } else { @@ -2175,7 +2512,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast return LLVMBuildSelect(g->builder, ltz, c, a, ""); } } else { - assert(type_entry->id == TypeTableEntryIdInt); + assert(type_entry->id == ZigTypeIdInt); if (type_entry->data.integral.is_signed) { if (rem_kind == RemKindRem) { return LLVMBuildSRem(g->builder, val1, val2, ""); @@ -2203,12 +2540,12 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, assert(op1->value.type == op2->value.type || op_id == IrBinOpBitShiftLeftLossy || op_id == IrBinOpBitShiftLeftExact || op_id == IrBinOpBitShiftRightLossy || op_id == IrBinOpBitShiftRightExact || - (op1->value.type->id == TypeTableEntryIdErrorSet && op2->value.type->id == TypeTableEntryIdErrorSet) || - (op1->value.type->id == TypeTableEntryIdPointer && + (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) || + (op1->value.type->id == ZigTypeIdPointer && (op_id == IrBinOpAdd || op_id == IrBinOpSub) && op1->value.type->data.pointer.ptr_len == PtrLenUnknown) ); - TypeTableEntry *type_entry = op1->value.type; + ZigType *type_entry = op1->value.type; bool want_runtime_safety = bin_op_instruction->safety_check_on && ir_want_runtime_safety(g, &bin_op_instruction->base); @@ -2234,16 +2571,16 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, case IrBinOpCmpGreaterThan: case IrBinOpCmpLessOrEq: case IrBinOpCmpGreaterOrEq: - if (type_entry->id == TypeTableEntryIdFloat) { + if (type_entry->id == ZigTypeIdFloat) { ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); LLVMRealPredicate pred = cmp_op_to_real_predicate(op_id); return LLVMBuildFCmp(g->builder, pred, op1_value, op2_value, ""); - } else if (type_entry->id == TypeTableEntryIdInt) { + } else if (type_entry->id == ZigTypeIdInt) { LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, type_entry->data.integral.is_signed); return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, ""); - } else if (type_entry->id == TypeTableEntryIdEnum || - type_entry->id == TypeTableEntryIdErrorSet || - type_entry->id == TypeTableEntryIdBool || + } else if (type_entry->id == ZigTypeIdEnum || + type_entry->id == ZigTypeIdErrorSet || + type_entry->id == ZigTypeIdBool || get_codegen_ptr_type(type_entry) != nullptr) { LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false); @@ -2253,14 +2590,14 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, } case IrBinOpAdd: case IrBinOpAddWrap: - if (type_entry->id == TypeTableEntryIdPointer) { + if (type_entry->id == ZigTypeIdPointer) { assert(type_entry->data.pointer.ptr_len == PtrLenUnknown); // TODO runtime safety return LLVMBuildInBoundsGEP(g->builder, op1_value, &op2_value, 1, ""); - } else if (type_entry->id == TypeTableEntryIdFloat) { + } else if (type_entry->id == ZigTypeIdFloat) { ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); return LLVMBuildFAdd(g->builder, op1_value, op2_value, ""); - } else if (type_entry->id == TypeTableEntryIdInt) { + } else if (type_entry->id == ZigTypeIdInt) { bool is_wrapping = (op_id == IrBinOpAddWrap); if (is_wrapping) { return LLVMBuildAdd(g->builder, op1_value, op2_value, ""); @@ -2283,7 +2620,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, case IrBinOpBitShiftLeftLossy: case IrBinOpBitShiftLeftExact: { - assert(type_entry->id == TypeTableEntryIdInt); + assert(type_entry->id == ZigTypeIdInt); LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value.type, type_entry, op2_value); bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy); @@ -2300,7 +2637,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, case IrBinOpBitShiftRightLossy: case IrBinOpBitShiftRightExact: { - assert(type_entry->id == TypeTableEntryIdInt); + assert(type_entry->id == ZigTypeIdInt); LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value.type, type_entry, op2_value); bool is_sloppy = (op_id == IrBinOpBitShiftRightLossy); @@ -2320,15 +2657,15 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, } case IrBinOpSub: case IrBinOpSubWrap: - if (type_entry->id == TypeTableEntryIdPointer) { + if (type_entry->id == ZigTypeIdPointer) { assert(type_entry->data.pointer.ptr_len == PtrLenUnknown); // TODO runtime safety LLVMValueRef subscript_value = LLVMBuildNeg(g->builder, op2_value, ""); return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, ""); - } else if (type_entry->id == TypeTableEntryIdFloat) { + } else if (type_entry->id == ZigTypeIdFloat) { ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); return LLVMBuildFSub(g->builder, op1_value, op2_value, ""); - } else if (type_entry->id == TypeTableEntryIdInt) { + } else if (type_entry->id == ZigTypeIdInt) { bool is_wrapping = (op_id == IrBinOpSubWrap); if (is_wrapping) { return LLVMBuildSub(g->builder, op1_value, op2_value, ""); @@ -2344,10 +2681,10 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, } case IrBinOpMult: case IrBinOpMultWrap: - if (type_entry->id == TypeTableEntryIdFloat) { + if (type_entry->id == ZigTypeIdFloat) { ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); return LLVMBuildFMul(g->builder, op1_value, op2_value, ""); - } else if (type_entry->id == TypeTableEntryIdInt) { + } else if (type_entry->id == ZigTypeIdInt) { bool is_wrapping = (op_id == IrBinOpMultWrap); if (is_wrapping) { return LLVMBuildMul(g->builder, op1_value, op2_value, ""); @@ -2383,8 +2720,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, zig_unreachable(); } -static void add_error_range_check(CodeGen *g, TypeTableEntry *err_set_type, TypeTableEntry *int_type, LLVMValueRef target_val) { - assert(err_set_type->id == TypeTableEntryIdErrorSet); +static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *int_type, LLVMValueRef target_val) { + assert(err_set_type->id == ZigTypeIdErrorSet); if (type_is_global_error_set(err_set_type)) { LLVMValueRef zero = LLVMConstNull(int_type->type_ref); @@ -2434,8 +2771,8 @@ static void add_error_range_check(CodeGen *g, TypeTableEntry *err_set_type, Type static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, IrInstructionCast *cast_instruction) { - TypeTableEntry *actual_type = cast_instruction->value->value.type; - TypeTableEntry *wanted_type = cast_instruction->base.value.type; + ZigType *actual_type = cast_instruction->value->value.type; + ZigType *wanted_type = cast_instruction->base.value.type; LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value); assert(expr_val); @@ -2448,15 +2785,15 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, case CastOpResizeSlice: { assert(cast_instruction->tmp_ptr); - assert(wanted_type->id == TypeTableEntryIdStruct); + assert(wanted_type->id == ZigTypeIdStruct); assert(wanted_type->data.structure.is_slice); - assert(actual_type->id == TypeTableEntryIdStruct); + assert(actual_type->id == ZigTypeIdStruct); assert(actual_type->data.structure.is_slice); - TypeTableEntry *actual_pointer_type = actual_type->data.structure.fields[0].type_entry; - TypeTableEntry *actual_child_type = actual_pointer_type->data.pointer.child_type; - TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; - TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type; + ZigType *actual_pointer_type = actual_type->data.structure.fields[0].type_entry; + ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type; + ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; + ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type; size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index].gen_index; @@ -2511,12 +2848,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, case CastOpBytesToSlice: { assert(cast_instruction->tmp_ptr); - assert(wanted_type->id == TypeTableEntryIdStruct); + assert(wanted_type->id == ZigTypeIdStruct); assert(wanted_type->data.structure.is_slice); - assert(actual_type->id == TypeTableEntryIdArray); + assert(actual_type->id == ZigTypeIdArray); - TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; - TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type; + ZigType *wanted_pointer_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type; size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index; @@ -2535,14 +2872,14 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, return cast_instruction->tmp_ptr; } case CastOpIntToFloat: - assert(actual_type->id == TypeTableEntryIdInt); + assert(actual_type->id == ZigTypeIdInt); if (actual_type->data.integral.is_signed) { return LLVMBuildSIToFP(g->builder, expr_val, wanted_type->type_ref, ""); } else { return LLVMBuildUIToFP(g->builder, expr_val, wanted_type->type_ref, ""); } case CastOpFloatToInt: { - assert(wanted_type->id == TypeTableEntryIdInt); + assert(wanted_type->id == ZigTypeIdInt); ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &cast_instruction->base)); bool want_safety = ir_want_runtime_safety(g, &cast_instruction->base); @@ -2577,8 +2914,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, return result; } case CastOpBoolToInt: - assert(wanted_type->id == TypeTableEntryIdInt); - assert(actual_type->id == TypeTableEntryIdBool); + assert(wanted_type->id == ZigTypeIdInt); + assert(actual_type->id == ZigTypeIdBool); return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, ""); case CastOpErrSet: if (ir_want_runtime_safety(g, &cast_instruction->base)) { @@ -2589,9 +2926,9 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, ""); case CastOpPtrOfArrayToSlice: { assert(cast_instruction->tmp_ptr); - assert(actual_type->id == TypeTableEntryIdPointer); - TypeTableEntry *array_type = actual_type->data.pointer.child_type; - assert(array_type->id == TypeTableEntryIdArray); + assert(actual_type->id == ZigTypeIdPointer); + ZigType *array_type = actual_type->data.pointer.child_type; + assert(array_type->id == ZigTypeIdArray); LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, slice_ptr_index, ""); @@ -2617,7 +2954,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable, IrInstructionPtrCast *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; + ZigType *wanted_type = instruction->base.value.type; if (!type_has_bits(wanted_type)) { return nullptr; } @@ -2628,7 +2965,7 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable, static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable, IrInstructionBitCast *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; + ZigType *wanted_type = instruction->base.value.type; LLVMValueRef value = ir_llvm_value(g, instruction->value); return LLVMBuildBitCast(g->builder, value, wanted_type->type_ref, ""); } @@ -2636,11 +2973,11 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable, static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable, IrInstructionWidenOrShorten *instruction) { - TypeTableEntry *actual_type = instruction->target->value.type; + ZigType *actual_type = instruction->target->value.type; // TODO instead of this logic, use the Noop instruction to change the type from // enum_tag to the underlying int type - TypeTableEntry *int_type; - if (actual_type->id == TypeTableEntryIdEnum) { + ZigType *int_type; + if (actual_type->id == ZigTypeIdEnum) { int_type = actual_type->data.enumeration.tag_int_type; } else { int_type = actual_type; @@ -2651,21 +2988,21 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa } static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutable *executable, IrInstructionIntToPtr *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; + ZigType *wanted_type = instruction->base.value.type; LLVMValueRef target_val = ir_llvm_value(g, instruction->target); return LLVMBuildIntToPtr(g->builder, target_val, wanted_type->type_ref, ""); } static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, IrExecutable *executable, IrInstructionPtrToInt *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; + ZigType *wanted_type = instruction->base.value.type; LLVMValueRef target_val = ir_llvm_value(g, instruction->target); return LLVMBuildPtrToInt(g->builder, target_val, wanted_type->type_ref, ""); } static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable, IrInstructionIntToEnum *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; - assert(wanted_type->id == TypeTableEntryIdEnum); - TypeTableEntry *tag_int_type = wanted_type->data.enumeration.tag_int_type; + ZigType *wanted_type = instruction->base.value.type; + assert(wanted_type->id == ZigTypeIdEnum); + ZigType *tag_int_type = wanted_type->data.enumeration.tag_int_type; LLVMValueRef target_val = ir_llvm_value(g, instruction->target); LLVMValueRef tag_int_value = gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), @@ -2690,11 +3027,11 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable, } static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; - assert(wanted_type->id == TypeTableEntryIdErrorSet); + ZigType *wanted_type = instruction->base.value.type; + assert(wanted_type->id == ZigTypeIdErrorSet); - TypeTableEntry *actual_type = instruction->target->value.type; - assert(actual_type->id == TypeTableEntryIdInt); + ZigType *actual_type = instruction->target->value.type; + assert(actual_type->id == ZigTypeIdInt); assert(!actual_type->data.integral.is_signed); LLVMValueRef target_val = ir_llvm_value(g, instruction->target); @@ -2707,17 +3044,17 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I } static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, IrInstructionErrToInt *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; - assert(wanted_type->id == TypeTableEntryIdInt); + ZigType *wanted_type = instruction->base.value.type; + assert(wanted_type->id == ZigTypeIdInt); assert(!wanted_type->data.integral.is_signed); - TypeTableEntry *actual_type = instruction->target->value.type; + ZigType *actual_type = instruction->target->value.type; LLVMValueRef target_val = ir_llvm_value(g, instruction->target); - if (actual_type->id == TypeTableEntryIdErrorSet) { + if (actual_type->id == ZigTypeIdErrorSet) { return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), g->err_tag_type, wanted_type, target_val); - } else if (actual_type->id == TypeTableEntryIdErrorUnion) { + } else if (actual_type->id == ZigTypeIdErrorUnion) { // this should have been a compile time constant assert(type_has_bits(actual_type->data.error_union.err_set_type)); @@ -2761,7 +3098,7 @@ static LLVMValueRef ir_render_br(CodeGen *g, IrExecutable *executable, IrInstruc static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInstructionUnOp *un_op_instruction) { IrUnOp op_id = un_op_instruction->op_id; LLVMValueRef expr = ir_llvm_value(g, un_op_instruction->value); - TypeTableEntry *expr_type = un_op_instruction->value->value.type; + ZigType *expr_type = un_op_instruction->value->value.type; switch (op_id) { case IrUnOpInvalid: @@ -2771,10 +3108,10 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst case IrUnOpNegation: case IrUnOpNegationWrap: { - if (expr_type->id == TypeTableEntryIdFloat) { + if (expr_type->id == ZigTypeIdFloat) { ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &un_op_instruction->base)); return LLVMBuildFNeg(g->builder, expr, ""); - } else if (expr_type->id == TypeTableEntryIdInt) { + } else if (expr_type->id == ZigTypeIdInt) { if (op_id == IrUnOpNegationWrap) { return LLVMBuildNeg(g->builder, expr, ""); } else if (ir_want_runtime_safety(g, &un_op_instruction->base)) { @@ -2805,7 +3142,7 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstructionDeclVar *decl_var_instruction) { - VariableTableEntry *var = decl_var_instruction->var; + ZigVar *var = decl_var_instruction->var; if (!type_has_bits(var->value->type)) return nullptr; @@ -2823,13 +3160,13 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, if (have_init_expr) { assert(var->value->type == init_value->value.type); - TypeTableEntry *var_ptr_type = get_pointer_to_type_extra(g, var->value->type, false, false, + ZigType *var_ptr_type = get_pointer_to_type_extra(g, var->value->type, false, false, PtrLenSingle, var->align_bytes, 0, 0); gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value)); } else { bool want_safe = ir_want_runtime_safety(g, &decl_var_instruction->base); if (want_safe) { - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref); assert(size_bytes > 0); @@ -2849,13 +3186,13 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, } static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrInstructionLoadPtr *instruction) { - TypeTableEntry *child_type = instruction->base.value.type; + ZigType *child_type = instruction->base.value.type; if (!type_has_bits(child_type)) return nullptr; LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); - TypeTableEntry *ptr_type = instruction->ptr->value.type; - assert(ptr_type->id == TypeTableEntryIdPointer); + ZigType *ptr_type = instruction->ptr->value.type; + assert(ptr_type->id == ZigTypeIdPointer); uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count; if (unaligned_bit_count == 0) @@ -2880,8 +3217,8 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); LLVMValueRef value = ir_llvm_value(g, instruction->value); - assert(instruction->ptr->value.type->id == TypeTableEntryIdPointer); - TypeTableEntry *ptr_type = instruction->ptr->value.type; + assert(instruction->ptr->value.type->id == ZigTypeIdPointer); + ZigType *ptr_type = instruction->ptr->value.type; gen_assign_raw(g, ptr, ptr_type, value); @@ -2889,7 +3226,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir } static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { - VariableTableEntry *var = instruction->var; + ZigVar *var = instruction->var; if (type_has_bits(var->value->type)) { assert(var->value_ref); return var->value_ref; @@ -2900,9 +3237,9 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) { LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr); - TypeTableEntry *array_ptr_type = instruction->array_ptr->value.type; - assert(array_ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type; + ZigType *array_ptr_type = instruction->array_ptr->value.type; + assert(array_ptr_type->id == ZigTypeIdPointer); + ZigType *array_type = array_ptr_type->data.pointer.child_type; LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index); assert(subscript_value); @@ -2912,11 +3249,11 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on; - if (array_type->id == TypeTableEntryIdArray || - (array_type->id == TypeTableEntryIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) + if (array_type->id == ZigTypeIdArray || + (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) { - if (array_type->id == TypeTableEntryIdPointer) { - assert(array_type->data.pointer.child_type->id == TypeTableEntryIdArray); + if (array_type->id == ZigTypeIdPointer) { + assert(array_type->data.pointer.child_type->id == ZigTypeIdArray); array_type = array_type->data.pointer.child_type; } if (safety_check_on) { @@ -2927,8 +3264,8 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI if (array_ptr_type->data.pointer.unaligned_bit_count != 0) { return array_ptr_ptr; } - TypeTableEntry *child_type = array_type->data.array.child_type; - if (child_type->id == TypeTableEntryIdStruct && + ZigType *child_type = array_type->data.array.child_type; + if (child_type->id == ZigTypeIdStruct && child_type->data.structure.layout == ContainerLayoutPacked) { size_t unaligned_bit_count = instruction->base.value.type->data.pointer.unaligned_bit_count; @@ -2951,13 +3288,13 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI subscript_value }; return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); - } else if (array_type->id == TypeTableEntryIdPointer) { + } else if (array_type->id == ZigTypeIdPointer) { assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); LLVMValueRef indices[] = { subscript_value }; return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, ""); - } else if (array_type->id == TypeTableEntryIdStruct) { + } else if (array_type->id == ZigTypeIdStruct) { assert(array_type->data.structure.is_slice); if (!type_has_bits(instruction->base.value.type)) { if (safety_check_on) { @@ -2990,8 +3327,8 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI static bool get_prefix_arg_err_ret_stack(CodeGen *g, FnTypeId *fn_type_id) { return g->have_err_ret_tracing && - (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion || - fn_type_id->return_type->id == TypeTableEntryIdErrorSet || + (fn_type_id->return_type->id == ZigTypeIdErrorUnion || + fn_type_id->return_type->id == ZigTypeIdErrorSet || fn_type_id->cc == CallingConventionAsync); } @@ -3047,7 +3384,7 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) { static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) { LLVMValueRef fn_val; - TypeTableEntry *fn_type; + ZigType *fn_type; if (instruction->fn_entry) { fn_val = fn_llvm_value(g, instruction->fn_entry); fn_type = instruction->fn_entry->type_entry; @@ -3059,43 +3396,33 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; - TypeTableEntry *src_return_type = fn_type_id->return_type; + ZigType *src_return_type = fn_type_id->return_type; bool ret_has_bits = type_has_bits(src_return_type); - bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type) && - calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc); + CallingConvention cc = fn_type->data.fn.fn_type_id.cc; + + bool first_arg_ret = ret_has_bits && want_first_arg_sret(g, fn_type_id); bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, fn_type_id); - // +2 for the async args - size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0) + 2; bool is_var_args = fn_type_id->is_var_args; - LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count); - size_t gen_param_index = 0; + ZigList<LLVMValueRef> gen_param_values = {}; if (first_arg_ret) { - gen_param_values[gen_param_index] = instruction->tmp_ptr; - gen_param_index += 1; + gen_param_values.append(instruction->tmp_ptr); } if (prefix_arg_err_ret_stack) { - gen_param_values[gen_param_index] = get_cur_err_ret_trace_val(g, instruction->base.scope); - gen_param_index += 1; + gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope)); } if (instruction->is_async) { - gen_param_values[gen_param_index] = ir_llvm_value(g, instruction->async_allocator); - gen_param_index += 1; + gen_param_values.append(ir_llvm_value(g, instruction->async_allocator)); LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, ""); - gen_param_values[gen_param_index] = err_val_ptr; - gen_param_index += 1; - } - for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) { - IrInstruction *param_instruction = instruction->args[call_i]; - TypeTableEntry *param_type = param_instruction->value.type; - if (is_var_args || type_has_bits(param_type)) { - LLVMValueRef param_value = ir_llvm_value(g, param_instruction); - assert(param_value); - gen_param_values[gen_param_index] = param_value; - gen_param_index += 1; - } + gen_param_values.append(err_val_ptr); } + FnWalk fn_walk = {}; + fn_walk.id = FnWalkIdCall; + fn_walk.data.call.inst = instruction; + fn_walk.data.call.is_var_args = is_var_args; + fn_walk.data.call.gen_param_values = &gen_param_values; + walk_function_params(g, fn_type, &fn_walk); ZigLLVM_FnInline fn_inline; switch (instruction->fn_inline) { @@ -3110,12 +3437,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr break; } - LLVMCallConv llvm_cc = get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc); + LLVMCallConv llvm_cc = get_llvm_cc(g, cc); LLVMValueRef result; if (instruction->new_stack == nullptr) { result = ZigLLVMBuildCall(g->builder, fn_val, - gen_param_values, (unsigned)gen_param_index, llvm_cc, fn_inline, ""); + gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, fn_inline, ""); } else { LLVMValueRef stacksave_fn_val = get_stacksave_fn_val(g); LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g); @@ -3124,7 +3451,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr LLVMValueRef old_stack_ref = LLVMBuildCall(g->builder, stacksave_fn_val, nullptr, 0, ""); gen_set_stack_pointer(g, new_stack_addr); result = ZigLLVMBuildCall(g->builder, fn_val, - gen_param_values, (unsigned)gen_param_index, llvm_cc, fn_inline, ""); + gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, fn_inline, ""); LLVMBuildCall(g->builder, stackrestore_fn_val, &old_stack_ref, 1, ""); } @@ -3135,7 +3462,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr return instruction->tmp_ptr; } - if (src_return_type->id == TypeTableEntryIdUnreachable) { + if (src_return_type->id == ZigTypeIdUnreachable) { return LLVMBuildUnreachable(g->builder); } else if (!ret_has_bits) { return nullptr; @@ -3155,14 +3482,14 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa IrInstructionStructFieldPtr *instruction) { LLVMValueRef struct_ptr = ir_llvm_value(g, instruction->struct_ptr); - // not necessarily a pointer. could be TypeTableEntryIdStruct - TypeTableEntry *struct_ptr_type = instruction->struct_ptr->value.type; + // not necessarily a pointer. could be ZigTypeIdStruct + ZigType *struct_ptr_type = instruction->struct_ptr->value.type; TypeStructField *field = instruction->field; if (!type_has_bits(field->type_entry)) return nullptr; - if (struct_ptr_type->id == TypeTableEntryIdPointer && + if (struct_ptr_type->id == ZigTypeIdPointer && struct_ptr_type->data.pointer.unaligned_bit_count != 0) { return struct_ptr; @@ -3175,10 +3502,10 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable, IrInstructionUnionFieldPtr *instruction) { - TypeTableEntry *union_ptr_type = instruction->union_ptr->value.type; - assert(union_ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *union_type = union_ptr_type->data.pointer.child_type; - assert(union_type->id == TypeTableEntryIdUnion); + ZigType *union_ptr_type = instruction->union_ptr->value.type; + assert(union_ptr_type->id == ZigTypeIdPointer); + ZigType *union_type = union_ptr_type->data.pointer.child_type; + assert(union_type->id == ZigTypeIdUnion); TypeUnionField *field = instruction->field; @@ -3304,7 +3631,7 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru } if (!is_return) { - VariableTableEntry *variable = instruction->output_vars[i]; + ZigVar *variable = instruction->output_vars[i]; assert(variable); param_types[param_index] = LLVMTypeOf(variable->value_ref); param_values[param_index] = variable->value_ref; @@ -3345,9 +3672,9 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru return LLVMBuildCall(g->builder, asm_fn, param_values, (unsigned)input_and_output_count, ""); } -static LLVMValueRef gen_non_null_bit(CodeGen *g, TypeTableEntry *maybe_type, LLVMValueRef maybe_handle) { - assert(maybe_type->id == TypeTableEntryIdOptional); - TypeTableEntry *child_type = maybe_type->data.maybe.child_type; +static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueRef maybe_handle) { + assert(maybe_type->id == ZigTypeIdOptional); + ZigType *child_type = maybe_type->data.maybe.child_type; if (child_type->zero_bits) { return maybe_handle; } else { @@ -3370,11 +3697,11 @@ static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapOptional *instruction) { - TypeTableEntry *ptr_type = instruction->value->value.type; - assert(ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *maybe_type = ptr_type->data.pointer.child_type; - assert(maybe_type->id == TypeTableEntryIdOptional); - TypeTableEntry *child_type = maybe_type->data.maybe.child_type; + ZigType *ptr_type = instruction->value->value.type; + assert(ptr_type->id == ZigTypeIdPointer); + ZigType *maybe_type = ptr_type->data.pointer.child_type; + assert(maybe_type->id == ZigTypeIdOptional); + ZigType *child_type = maybe_type->data.maybe.child_type; LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value); LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type); if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) { @@ -3401,7 +3728,7 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable, } } -static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, BuiltinFnId fn_id) { +static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnId fn_id) { ZigLLVMFnKey key = {}; const char *fn_name; uint32_t n_args; @@ -3444,7 +3771,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, Bui } static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) { - TypeTableEntry *int_type = instruction->value->value.type; + ZigType *int_type = instruction->value->value.type; LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz); LLVMValueRef operand = ir_llvm_value(g, instruction->value); LLVMValueRef params[] { @@ -3456,7 +3783,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru } static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) { - TypeTableEntry *int_type = instruction->value->value.type; + ZigType *int_type = instruction->value->value.type; LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz); LLVMValueRef operand = ir_llvm_value(g, instruction->value); LLVMValueRef params[] { @@ -3468,7 +3795,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru } static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) { - TypeTableEntry *int_type = instruction->value->value.type; + ZigType *int_type = instruction->value->value.type; LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); LLVMValueRef operand = ir_llvm_value(g, instruction->value); LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, ""); @@ -3545,15 +3872,15 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, ""); } -static LLVMValueRef get_enum_tag_name_function(CodeGen *g, TypeTableEntry *enum_type) { - assert(enum_type->id == TypeTableEntryIdEnum); +static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { + assert(enum_type->id == ZigTypeIdEnum); if (enum_type->data.enumeration.name_function) return enum_type->data.enumeration.name_function; - TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false, + ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false, PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); - TypeTableEntry *u8_slice_type = get_slice_type(g, u8_ptr_type); - TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type; + ZigType *u8_slice_type = get_slice_type(g, u8_ptr_type); + ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type; LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(u8_slice_type->type_ref, 0), &tag_int_type->type_ref, 1, false); @@ -3571,7 +3898,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, TypeTableEntry *enum_ LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); - FnTableEntry *prev_cur_fn = g->cur_fn; + ZigFn *prev_cur_fn = g->cur_fn; LLVMValueRef prev_cur_fn_val = g->cur_fn_val; LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); @@ -3586,7 +3913,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, TypeTableEntry *enum_ LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, tag_int_value, bad_value_block, field_count); - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; LLVMValueRef array_ptr_indices[] = { LLVMConstNull(usize->type_ref), LLVMConstNull(usize->type_ref), @@ -3643,8 +3970,8 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, TypeTableEntry *enum_ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable, IrInstructionTagName *instruction) { - TypeTableEntry *enum_type = instruction->target->value.type; - assert(enum_type->id == TypeTableEntryIdEnum); + ZigType *enum_type = instruction->target->value.type; + assert(enum_type->id == ZigTypeIdEnum); LLVMValueRef enum_name_function = get_enum_tag_name_function(g, enum_type); @@ -3656,10 +3983,10 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutable *executable, IrInstructionFieldParentPtr *instruction) { - TypeTableEntry *container_ptr_type = instruction->base.value.type; - assert(container_ptr_type->id == TypeTableEntryIdPointer); + ZigType *container_ptr_type = instruction->base.value.type; + assert(container_ptr_type->id == ZigTypeIdPointer); - TypeTableEntry *container_type = container_ptr_type->data.pointer.child_type; + ZigType *container_type = container_ptr_type->data.pointer.child_type; size_t byte_offset = LLVMOffsetOfElement(g->target_data_ref, container_type->type_ref, instruction->field->gen_index); @@ -3669,7 +3996,7 @@ static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutable *executa if (byte_offset == 0) { return LLVMBuildBitCast(g->builder, field_ptr_val, container_ptr_type->type_ref, ""); } else { - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; LLVMValueRef field_ptr_int = LLVMBuildPtrToInt(g->builder, field_ptr_val, usize->type_ref, ""); @@ -3690,32 +4017,32 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I return target_val; } - TypeTableEntry *target_type = instruction->base.value.type; + ZigType *target_type = instruction->base.value.type; uint32_t align_bytes; LLVMValueRef ptr_val; - if (target_type->id == TypeTableEntryIdPointer) { + if (target_type->id == ZigTypeIdPointer) { align_bytes = target_type->data.pointer.alignment; ptr_val = target_val; - } else if (target_type->id == TypeTableEntryIdFn) { + } else if (target_type->id == ZigTypeIdFn) { align_bytes = target_type->data.fn.fn_type_id.alignment; ptr_val = target_val; - } else if (target_type->id == TypeTableEntryIdOptional && - target_type->data.maybe.child_type->id == TypeTableEntryIdPointer) + } else if (target_type->id == ZigTypeIdOptional && + target_type->data.maybe.child_type->id == ZigTypeIdPointer) { align_bytes = target_type->data.maybe.child_type->data.pointer.alignment; ptr_val = target_val; - } else if (target_type->id == TypeTableEntryIdOptional && - target_type->data.maybe.child_type->id == TypeTableEntryIdFn) + } else if (target_type->id == ZigTypeIdOptional && + target_type->data.maybe.child_type->id == ZigTypeIdFn) { align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment; ptr_val = target_val; - } else if (target_type->id == TypeTableEntryIdOptional && - target_type->data.maybe.child_type->id == TypeTableEntryIdPromise) + } else if (target_type->id == ZigTypeIdOptional && + target_type->data.maybe.child_type->id == ZigTypeIdPromise) { zig_panic("TODO audit this function"); - } else if (target_type->id == TypeTableEntryIdStruct && target_type->data.structure.is_slice) { - TypeTableEntry *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; + } else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) { + ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; align_bytes = slice_ptr_type->data.pointer.alignment; size_t ptr_index = target_type->data.structure.fields[slice_ptr_index].gen_index; @@ -3727,7 +4054,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I assert(align_bytes != 1); - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; LLVMValueRef ptr_as_int_val = LLVMBuildPtrToInt(g->builder, ptr_val, usize->type_ref, ""); LLVMValueRef alignment_minus_1 = LLVMConstInt(usize->type_ref, align_bytes - 1, false); LLVMValueRef anded_val = LLVMBuildAnd(g->builder, ptr_as_int_val, alignment_minus_1, ""); @@ -3751,7 +4078,7 @@ static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *execu { LLVMValueRef cur_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope); if (cur_err_ret_trace_val == nullptr) { - TypeTableEntry *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); + ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); return LLVMConstNull(ptr_to_stack_trace_type->type_ref); } return cur_err_ret_trace_val; @@ -3811,9 +4138,9 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val, success_order, failure_order, instruction->is_weak); - TypeTableEntry *maybe_type = instruction->base.value.type; - assert(maybe_type->id == TypeTableEntryIdOptional); - TypeTableEntry *child_type = maybe_type->data.maybe.child_type; + ZigType *maybe_type = instruction->base.value.type; + assert(maybe_type->id == ZigTypeIdOptional); + ZigType *child_type = maybe_type->data.maybe.child_type; if (type_is_codegen_pointer(child_type)) { LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, ""); @@ -3843,8 +4170,8 @@ static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInst static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrInstructionTruncate *instruction) { LLVMValueRef target_val = ir_llvm_value(g, instruction->target); - TypeTableEntry *dest_type = instruction->base.value.type; - TypeTableEntry *src_type = instruction->target->value.type; + ZigType *dest_type = instruction->base.value.type; + ZigType *src_type = instruction->target->value.type; if (dest_type == src_type) { // no-op return target_val; @@ -3865,8 +4192,8 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); - TypeTableEntry *ptr_type = instruction->dest_ptr->value.type; - assert(ptr_type->id == TypeTableEntryIdPointer); + ZigType *ptr_type = instruction->dest_ptr->value.type; + assert(ptr_type->id == ZigTypeIdPointer); ZigLLVMBuildMemSet(g->builder, dest_ptr_casted, char_val, len_val, ptr_type->data.pointer.alignment, ptr_type->data.pointer.is_volatile); return nullptr; @@ -3882,11 +4209,11 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, ""); - TypeTableEntry *dest_ptr_type = instruction->dest_ptr->value.type; - TypeTableEntry *src_ptr_type = instruction->src_ptr->value.type; + ZigType *dest_ptr_type = instruction->dest_ptr->value.type; + ZigType *src_ptr_type = instruction->src_ptr->value.type; - assert(dest_ptr_type->id == TypeTableEntryIdPointer); - assert(src_ptr_type->id == TypeTableEntryIdPointer); + assert(dest_ptr_type->id == ZigTypeIdPointer); + assert(src_ptr_type->id == ZigTypeIdPointer); bool is_volatile = (dest_ptr_type->data.pointer.is_volatile || src_ptr_type->data.pointer.is_volatile); @@ -3899,19 +4226,19 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst assert(instruction->tmp_ptr); LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr); - TypeTableEntry *array_ptr_type = instruction->ptr->value.type; - assert(array_ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type; + ZigType *array_ptr_type = instruction->ptr->value.type; + assert(array_ptr_type->id == ZigTypeIdPointer); + ZigType *array_type = array_ptr_type->data.pointer.child_type; LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr; bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base); - if (array_type->id == TypeTableEntryIdArray || - (array_type->id == TypeTableEntryIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) + if (array_type->id == ZigTypeIdArray || + (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) { - if (array_type->id == TypeTableEntryIdPointer) { + if (array_type->id == ZigTypeIdPointer) { array_type = array_type->data.pointer.child_type; } LLVMValueRef start_val = ir_llvm_value(g, instruction->start); @@ -3952,7 +4279,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst gen_store_untyped(g, len_value, len_field_ptr, 0, false); return tmp_struct_ptr; - } else if (array_type->id == TypeTableEntryIdPointer) { + } else if (array_type->id == ZigTypeIdPointer) { assert(array_type->data.pointer.ptr_len == PtrLenUnknown); LLVMValueRef start_val = ir_llvm_value(g, instruction->start); LLVMValueRef end_val = ir_llvm_value(g, instruction->end); @@ -3974,7 +4301,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst gen_store_untyped(g, len_value, len_field_ptr, 0, false); return tmp_struct_ptr; - } else if (array_type->id == TypeTableEntryIdStruct) { + } else if (array_type->id == ZigTypeIdStruct) { assert(array_type->data.structure.is_slice); assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); @@ -4050,7 +4377,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { if (g->frame_address_fn_val) return g->frame_address_fn_val; - TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); + ZigType *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); LLVMTypeRef fn_type = LLVMFunctionType(return_type->type_ref, &g->builtin_types.entry_i32->type_ref, 1, false); @@ -4088,8 +4415,8 @@ static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable, } static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) { - TypeTableEntry *int_type = instruction->result_ptr_type; - assert(int_type->id == TypeTableEntryIdInt); + ZigType *int_type = instruction->result_ptr_type; + assert(int_type->id == ZigTypeIdInt); LLVMValueRef op1 = ir_llvm_value(g, instruction->op1); LLVMValueRef op2 = ir_llvm_value(g, instruction->op2); @@ -4128,8 +4455,8 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable, return render_shl_with_overflow(g, instruction); } - TypeTableEntry *int_type = instruction->result_ptr_type; - assert(int_type->id == TypeTableEntryIdInt); + ZigType *int_type = instruction->result_ptr_type; + assert(int_type->id == ZigTypeIdInt); LLVMValueRef fn_val = get_int_overflow_fn(g, int_type, add_sub_mul); @@ -4151,8 +4478,8 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable, } static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) { - TypeTableEntry *err_union_type = instruction->value->value.type; - TypeTableEntry *payload_type = err_union_type->data.error_union.payload_type; + ZigType *err_union_type = instruction->value->value.type; + ZigType *payload_type = err_union_type->data.error_union.payload_type; LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value); LLVMValueRef err_val; @@ -4168,10 +4495,10 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI } static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) { - TypeTableEntry *ptr_type = instruction->value->value.type; - assert(ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type; - TypeTableEntry *payload_type = err_union_type->data.error_union.payload_type; + ZigType *ptr_type = instruction->value->value.type; + assert(ptr_type->id == ZigTypeIdPointer); + ZigType *err_union_type = ptr_type->data.pointer.child_type; + ZigType *payload_type = err_union_type->data.error_union.payload_type; LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); @@ -4184,10 +4511,10 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab } static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) { - TypeTableEntry *ptr_type = instruction->value->value.type; - assert(ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type; - TypeTableEntry *payload_type = err_union_type->data.error_union.payload_type; + ZigType *ptr_type = instruction->value->value.type; + assert(ptr_type->id == ZigTypeIdPointer); + ZigType *err_union_type = ptr_type->data.pointer.child_type; + ZigType *payload_type = err_union_type->data.error_union.payload_type; LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); @@ -4223,11 +4550,11 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu } static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; + ZigType *wanted_type = instruction->base.value.type; - assert(wanted_type->id == TypeTableEntryIdOptional); + assert(wanted_type->id == ZigTypeIdOptional); - TypeTableEntry *child_type = wanted_type->data.maybe.child_type; + ZigType *child_type = wanted_type->data.maybe.child_type; if (child_type->zero_bits) { return LLVMConstInt(LLVMInt1Type(), 1, false); @@ -4250,12 +4577,12 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I } static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapCode *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; + ZigType *wanted_type = instruction->base.value.type; - assert(wanted_type->id == TypeTableEntryIdErrorUnion); + assert(wanted_type->id == ZigTypeIdErrorUnion); - TypeTableEntry *payload_type = wanted_type->data.error_union.payload_type; - TypeTableEntry *err_set_type = wanted_type->data.error_union.err_set_type; + ZigType *payload_type = wanted_type->data.error_union.payload_type; + ZigType *err_set_type = wanted_type->data.error_union.err_set_type; LLVMValueRef err_val = ir_llvm_value(g, instruction->value); @@ -4271,12 +4598,12 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable } static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) { - TypeTableEntry *wanted_type = instruction->base.value.type; + ZigType *wanted_type = instruction->base.value.type; - assert(wanted_type->id == TypeTableEntryIdErrorUnion); + assert(wanted_type->id == ZigTypeIdErrorUnion); - TypeTableEntry *payload_type = wanted_type->data.error_union.payload_type; - TypeTableEntry *err_set_type = wanted_type->data.error_union.err_set_type; + ZigType *payload_type = wanted_type->data.error_union.payload_type; + ZigType *err_set_type = wanted_type->data.error_union.err_set_type; if (!type_has_bits(err_set_type)) { return ir_llvm_value(g, instruction->value); @@ -4301,10 +4628,10 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa } static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) { - TypeTableEntry *union_type = instruction->value->value.type; + ZigType *union_type = instruction->value->value.type; assert(union_type->data.unionation.gen_tag_index != SIZE_MAX); - TypeTableEntry *tag_type = union_type->data.unionation.tag_type; + ZigType *tag_type = union_type->data.unionation.tag_type; if (!type_has_bits(tag_type)) return nullptr; @@ -4314,7 +4641,7 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_val, union_type->data.unionation.gen_tag_index, ""); - TypeTableEntry *ptr_type = get_pointer_to_type(g, tag_type, false); + ZigType *ptr_type = get_pointer_to_type(g, tag_type, false); return get_handle_value(g, tag_field_ptr, tag_type, ptr_type); } @@ -4331,7 +4658,7 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable, uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry); - TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry, + ZigType *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry, false, false, PtrLenSingle, field_align_bytes, (uint32_t)type_struct_field->packed_bits_offset, (uint32_t)type_struct_field->unaligned_bit_count); @@ -4347,14 +4674,14 @@ static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, I return nullptr; uint32_t field_align_bytes = get_abi_alignment(g, type_union_field->type_entry); - TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, type_union_field->type_entry, + ZigType *ptr_type = get_pointer_to_type_extra(g, type_union_field->type_entry, false, false, PtrLenSingle, field_align_bytes, 0, 0); LLVMValueRef uncasted_union_ptr; // Even if safety is off in this block, if the union type has the safety field, we have to populate it // correctly. Otherwise safety code somewhere other than here could fail. - TypeTableEntry *union_type = instruction->union_type; + ZigType *union_type = instruction->union_type; if (union_type->data.unionation.gen_tag_index != SIZE_MAX) { LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, union_type->data.unionation.gen_tag_index, ""); @@ -4380,14 +4707,14 @@ static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, I static LLVMValueRef ir_render_container_init_list(CodeGen *g, IrExecutable *executable, IrInstructionContainerInitList *instruction) { - TypeTableEntry *array_type = instruction->base.value.type; - assert(array_type->id == TypeTableEntryIdArray); + ZigType *array_type = instruction->base.value.type; + assert(array_type->id == ZigTypeIdArray); LLVMValueRef tmp_array_ptr = instruction->tmp_ptr; assert(tmp_array_ptr); size_t field_count = instruction->item_count; - TypeTableEntry *child_type = array_type->data.array.child_type; + ZigType *child_type = array_type->data.array.child_type; for (size_t i = 0; i < field_count; i += 1) { LLVMValueRef elem_val = ir_llvm_value(g, instruction->items[i]); LLVMValueRef indices[] = { @@ -4511,13 +4838,13 @@ static LLVMValueRef ir_render_coro_promise(CodeGen *g, IrExecutable *executable, return LLVMBuildBitCast(g->builder, uncasted_result, instruction->base.value.type->type_ref, ""); } -static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_fn_type_ref, TypeTableEntry *fn_type) { +static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_fn_type_ref, ZigType *fn_type) { if (g->coro_alloc_helper_fn_val != nullptr) return g->coro_alloc_helper_fn_val; - assert(fn_type->id == TypeTableEntryIdFn); + assert(fn_type->id == ZigTypeIdFn); - TypeTableEntry *ptr_to_err_code_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false); + ZigType *ptr_to_err_code_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false); LLVMTypeRef alloc_raw_fn_type_ref = LLVMGetElementType(alloc_fn_type_ref); LLVMTypeRef *alloc_fn_arg_types = allocate<LLVMTypeRef>(LLVMCountParamTypes(alloc_raw_fn_type_ref)); @@ -4545,7 +4872,7 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); - FnTableEntry *prev_cur_fn = g->cur_fn; + ZigFn *prev_cur_fn = g->cur_fn; LLVMValueRef prev_cur_fn_val = g->cur_fn_val; LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); @@ -4596,9 +4923,9 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f LLVMPositionBuilderAtEnd(g->builder, ok_block); LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_payload_index, ""); - TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false, + ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false, PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); - TypeTableEntry *slice_type = get_slice_type(g, u8_ptr_type); + ZigType *slice_type = get_slice_type(g, u8_ptr_type); size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, payload_ptr, ptr_field_index, ""); LLVMValueRef ptr_val = LLVMBuildLoad(g->builder, ptr_field_ptr, ""); @@ -4643,8 +4970,8 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable, IrInstructionAtomicRmw *instruction) { bool is_signed; - TypeTableEntry *operand_type = instruction->operand->value.type; - if (operand_type->id == TypeTableEntryIdInt) { + ZigType *operand_type = instruction->operand->value.type; + if (operand_type->id == ZigTypeIdInt) { is_signed = operand_type->data.integral.is_signed; } else { is_signed = false; @@ -4699,7 +5026,7 @@ static LLVMValueRef ir_render_mark_err_ret_trace_ptr(CodeGen *g, IrExecutable *e static LLVMValueRef ir_render_sqrt(CodeGen *g, IrExecutable *executable, IrInstructionSqrt *instruction) { LLVMValueRef op = ir_llvm_value(g, instruction->op); - assert(instruction->base.value.type->id == TypeTableEntryIdFloat); + assert(instruction->base.value.type->id == ZigTypeIdFloat); LLVMValueRef fn_val = get_float_fn(g, instruction->base.value.type, ZigLLVMFnIdSqrt); return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); } @@ -4780,6 +5107,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdFromBytes: case IrInstructionIdToBytes: case IrInstructionIdEnumToInt: + case IrInstructionIdCheckRuntimeScope: zig_unreachable(); case IrInstructionIdReturn: @@ -4946,7 +5274,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, zig_unreachable(); } -static void ir_render(CodeGen *g, FnTableEntry *fn_entry) { +static void ir_render(CodeGen *g, ZigFn *fn_entry) { assert(fn_entry); IrExecutable *executable = &fn_entry->analyzed_executable; @@ -4999,14 +5327,14 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr))); if (el_type == LLVMArrayTypeKind) { - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; LLVMValueRef indices[] = { LLVMConstNull(usize->type_ref), LLVMConstInt(usize->type_ref, index, false), }; return LLVMConstInBoundsGEP(base_ptr, indices, 2); } else if (el_type == LLVMStructTypeKind) { - TypeTableEntry *u32 = g->builtin_types.entry_u32; + ZigType *u32 = g->builtin_types.entry_u32; LLVMValueRef indices[] = { LLVMConstNull(u32->type_ref), LLVMConstInt(u32->type_ref, index, false), @@ -5022,7 +5350,7 @@ static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *s ConstParent *parent = &struct_const_val->data.x_struct.parent; LLVMValueRef base_ptr = gen_parent_ptr(g, struct_const_val, parent); - TypeTableEntry *u32 = g->builtin_types.entry_u32; + ZigType *u32 = g->builtin_types.entry_u32; LLVMValueRef indices[] = { LLVMConstNull(u32->type_ref), LLVMConstInt(u32->type_ref, field_index, false), @@ -5034,7 +5362,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un ConstParent *parent = &union_const_val->data.x_union.parent; LLVMValueRef base_ptr = gen_parent_ptr(g, union_const_val, parent); - TypeTableEntry *u32 = g->builtin_types.entry_u32; + ZigType *u32 = g->builtin_types.entry_u32; LLVMValueRef indices[] = { LLVMConstNull(u32->type_ref), LLVMConstInt(u32->type_ref, 0, false), // TODO test const union with more aligned tag type than payload @@ -5052,59 +5380,59 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con break; } - TypeTableEntry *type_entry = const_val->type; + ZigType *type_entry = const_val->type; assert(!type_entry->zero_bits); switch (type_entry->id) { - case TypeTableEntryIdInvalid: - case TypeTableEntryIdMetaType: - case TypeTableEntryIdUnreachable: - case TypeTableEntryIdComptimeFloat: - case TypeTableEntryIdComptimeInt: - case TypeTableEntryIdUndefined: - case TypeTableEntryIdNull: - case TypeTableEntryIdErrorUnion: - case TypeTableEntryIdErrorSet: - case TypeTableEntryIdNamespace: - case TypeTableEntryIdBlock: - case TypeTableEntryIdBoundFn: - case TypeTableEntryIdArgTuple: - case TypeTableEntryIdVoid: - case TypeTableEntryIdOpaque: + case ZigTypeIdInvalid: + case ZigTypeIdMetaType: + case ZigTypeIdUnreachable: + case ZigTypeIdComptimeFloat: + case ZigTypeIdComptimeInt: + case ZigTypeIdUndefined: + case ZigTypeIdNull: + case ZigTypeIdErrorUnion: + case ZigTypeIdErrorSet: + case ZigTypeIdNamespace: + case ZigTypeIdBlock: + case ZigTypeIdBoundFn: + case ZigTypeIdArgTuple: + case ZigTypeIdVoid: + case ZigTypeIdOpaque: zig_unreachable(); - case TypeTableEntryIdBool: + case ZigTypeIdBool: return LLVMConstInt(big_int_type_ref, const_val->data.x_bool ? 1 : 0, false); - case TypeTableEntryIdEnum: + case ZigTypeIdEnum: { assert(type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr); LLVMValueRef int_val = gen_const_val(g, const_val, ""); return LLVMConstZExt(int_val, big_int_type_ref); } - case TypeTableEntryIdInt: + case ZigTypeIdInt: { LLVMValueRef int_val = gen_const_val(g, const_val, ""); return LLVMConstZExt(int_val, big_int_type_ref); } - case TypeTableEntryIdFloat: + case ZigTypeIdFloat: { LLVMValueRef float_val = gen_const_val(g, const_val, ""); LLVMValueRef int_val = LLVMConstFPToUI(float_val, LLVMIntType((unsigned)type_entry->data.floating.bit_count)); return LLVMConstZExt(int_val, big_int_type_ref); } - case TypeTableEntryIdPointer: - case TypeTableEntryIdFn: - case TypeTableEntryIdOptional: - case TypeTableEntryIdPromise: + case ZigTypeIdPointer: + case ZigTypeIdFn: + case ZigTypeIdOptional: + case ZigTypeIdPromise: { LLVMValueRef ptr_val = gen_const_val(g, const_val, ""); LLVMValueRef ptr_size_int_val = LLVMConstPtrToInt(ptr_val, g->builtin_types.entry_usize->type_ref); return LLVMConstZExt(ptr_size_int_val, big_int_type_ref); } - case TypeTableEntryIdArray: + case ZigTypeIdArray: zig_panic("TODO bit pack an array"); - case TypeTableEntryIdUnion: + case ZigTypeIdUnion: zig_panic("TODO bit pack a union"); - case TypeTableEntryIdStruct: + case ZigTypeIdStruct: { assert(type_entry->data.structure.layout == ContainerLayoutPacked); bool is_big_endian = g->is_big_endian; // TODO get endianness from struct type @@ -5137,7 +5465,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con // We have this because union constants can't be represented by the official union type, // and this property bubbles up in whatever aggregate type contains a union constant -static bool is_llvm_value_unnamed_type(TypeTableEntry *type_entry, LLVMValueRef val) { +static bool is_llvm_value_unnamed_type(ZigType *type_entry, LLVMValueRef val) { return LLVMTypeOf(val) != type_entry->type_ref; } @@ -5162,10 +5490,10 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con render_const_val_global(g, const_val, name); ConstExprValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val; size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; - assert(array_const_val->type->id == TypeTableEntryIdArray); + assert(array_const_val->type->id == ZigTypeIdArray); if (array_const_val->type->zero_bits) { // make this a null pointer - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), const_val->type->type_ref); render_const_val_global(g, const_val, ""); @@ -5182,10 +5510,10 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con { render_const_val_global(g, const_val, name); ConstExprValue *struct_const_val = const_val->data.x_ptr.data.base_struct.struct_val; - assert(struct_const_val->type->id == TypeTableEntryIdStruct); + assert(struct_const_val->type->id == ZigTypeIdStruct); if (struct_const_val->type->zero_bits) { // make this a null pointer - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), const_val->type->type_ref); render_const_val_global(g, const_val, ""); @@ -5205,7 +5533,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con { render_const_val_global(g, const_val, name); uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr; - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false), const_val->type->type_ref); render_const_val_global(g, const_val, ""); @@ -5218,7 +5546,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con } static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const char *name) { - TypeTableEntry *type_entry = const_val->type; + ZigType *type_entry = const_val->type; assert(!type_entry->zero_bits); switch (const_val->special) { @@ -5231,13 +5559,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c } switch (type_entry->id) { - case TypeTableEntryIdInt: + case ZigTypeIdInt: return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_bigint); - case TypeTableEntryIdErrorSet: + case ZigTypeIdErrorSet: assert(const_val->data.x_err_set != nullptr); return LLVMConstInt(g->builtin_types.entry_global_error_set->type_ref, const_val->data.x_err_set->value, false); - case TypeTableEntryIdFloat: + case ZigTypeIdFloat: switch (type_entry->data.floating.bit_count) { case 16: return LLVMConstReal(type_entry->type_ref, zig_f16_to_double(const_val->data.x_f16)); @@ -5257,15 +5585,15 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c default: zig_unreachable(); } - case TypeTableEntryIdBool: + case ZigTypeIdBool: if (const_val->data.x_bool) { return LLVMConstAllOnes(LLVMInt1Type()); } else { return LLVMConstNull(LLVMInt1Type()); } - case TypeTableEntryIdOptional: + case ZigTypeIdOptional: { - TypeTableEntry *child_type = type_entry->data.maybe.child_type; + ZigType *child_type = type_entry->data.maybe.child_type; if (child_type->zero_bits) { return LLVMConstInt(LLVMInt1Type(), const_val->data.x_optional ? 1 : 0, false); } else if (type_is_codegen_pointer(child_type)) { @@ -5296,7 +5624,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c } } } - case TypeTableEntryIdStruct: + case ZigTypeIdStruct: { LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count); size_t src_field_count = type_entry->data.structure.src_field_count; @@ -5372,7 +5700,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count); } } - case TypeTableEntryIdArray: + case ZigTypeIdArray: { uint64_t len = type_entry->data.array.len; if (const_val->data.x_array.special == ConstArraySpecialUndef) { @@ -5394,12 +5722,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c return LLVMConstArray(element_type_ref, values, (unsigned)len); } } - case TypeTableEntryIdUnion: + case ZigTypeIdUnion: { LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref; if (type_entry->data.unionation.gen_field_count == 0) { - if (type_entry->data.unionation.gen_tag_index == SIZE_MAX) { + if (type_entry->data.unionation.tag_type == nullptr) { return nullptr; } else { return bigint_to_llvm_const(type_entry->data.unionation.tag_type->type_ref, @@ -5458,18 +5786,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c } - case TypeTableEntryIdEnum: + case ZigTypeIdEnum: return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_enum_tag); - case TypeTableEntryIdFn: + case ZigTypeIdFn: assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction); assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst); return fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry); - case TypeTableEntryIdPointer: + case ZigTypeIdPointer: return gen_const_val_ptr(g, const_val, name); - case TypeTableEntryIdErrorUnion: + case ZigTypeIdErrorUnion: { - TypeTableEntry *payload_type = type_entry->data.error_union.payload_type; - TypeTableEntry *err_set_type = type_entry->data.error_union.err_set_type; + ZigType *payload_type = type_entry->data.error_union.payload_type; + ZigType *err_set_type = type_entry->data.error_union.err_set_type; if (!type_has_bits(payload_type)) { assert(type_has_bits(err_set_type)); uint64_t value = const_val->data.x_err_union.err ? const_val->data.x_err_union.err->value : 0; @@ -5502,21 +5830,21 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c } } } - case TypeTableEntryIdVoid: + case ZigTypeIdVoid: return nullptr; - case TypeTableEntryIdInvalid: - case TypeTableEntryIdMetaType: - case TypeTableEntryIdUnreachable: - case TypeTableEntryIdComptimeFloat: - case TypeTableEntryIdComptimeInt: - case TypeTableEntryIdUndefined: - case TypeTableEntryIdNull: - case TypeTableEntryIdNamespace: - case TypeTableEntryIdBlock: - case TypeTableEntryIdBoundFn: - case TypeTableEntryIdArgTuple: - case TypeTableEntryIdOpaque: - case TypeTableEntryIdPromise: + case ZigTypeIdInvalid: + case ZigTypeIdMetaType: + case ZigTypeIdUnreachable: + case ZigTypeIdComptimeFloat: + case ZigTypeIdComptimeInt: + case ZigTypeIdUndefined: + case ZigTypeIdNull: + case ZigTypeIdNamespace: + case ZigTypeIdBlock: + case ZigTypeIdBoundFn: + case ZigTypeIdArgTuple: + case ZigTypeIdOpaque: + case ZigTypeIdPromise: zig_unreachable(); } @@ -5559,9 +5887,9 @@ static void generate_error_name_table(CodeGen *g) { assert(g->errors_by_index.length > 0); - TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, + ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); - TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type); + ZigType *str_type = get_slice_type(g, u8_ptr_type); LLVMValueRef *values = allocate<LLVMValueRef>(g->errors_by_index.length); values[0] = LLVMGetUndef(str_type->type_ref); @@ -5597,7 +5925,7 @@ static void generate_error_name_table(CodeGen *g) { LLVMSetAlignment(g->err_name_table, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(err_name_table_init))); } -static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) { +static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) { IrExecutable *executable = &fn->analyzed_executable; assert(executable->basic_block_list.length > 0); for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) { @@ -5608,8 +5936,8 @@ static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) { LLVMPositionBuilderAtEnd(g->builder, entry_bb->llvm_block); } -static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef init_val, - TypeTableEntry *type_entry) +static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val, + ZigType *type_entry) { if (g->strip_debug_symbols) { return; @@ -5630,33 +5958,16 @@ static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef ini // TODO ^^ make an actual global variable } -static LLVMValueRef build_alloca(CodeGen *g, TypeTableEntry *type_entry, const char *name, uint32_t alignment) { - assert(alignment > 0); - LLVMValueRef result = LLVMBuildAlloca(g->builder, type_entry->type_ref, name); - LLVMSetAlignment(result, alignment); - return result; -} - static void ensure_cache_dir(CodeGen *g) { int err; - if ((err = os_make_path(g->cache_dir))) { + if ((err = os_make_path(&g->cache_dir))) { zig_panic("unable to make cache dir: %s", err_str(err)); } } -static void report_errors_and_maybe_exit(CodeGen *g) { - if (g->errors.length != 0) { - for (size_t i = 0; i < g->errors.length; i += 1) { - ErrorMsg *err = g->errors.at(i); - print_err_msg(err, g->err_color); - } - exit(1); - } -} - static void validate_inline_fns(CodeGen *g) { for (size_t i = 0; i < g->inline_fns.length; i += 1) { - FnTableEntry *fn_entry = g->inline_fns.at(i); + ZigFn *fn_entry = g->inline_fns.at(i); LLVMValueRef fn_val = LLVMGetNamedFunction(g->module, fn_entry->llvm_name); if (fn_val != nullptr) { add_node_error(g, fn_entry->proto_node, buf_sprintf("unable to inline function")); @@ -5697,13 +6008,13 @@ static void do_code_gen(CodeGen *g) { // Generate module level variables for (size_t i = 0; i < g->global_vars.length; i += 1) { TldVar *tld_var = g->global_vars.at(i); - VariableTableEntry *var = tld_var->var; + ZigVar *var = tld_var->var; - if (var->value->type->id == TypeTableEntryIdComptimeFloat) { + if (var->value->type->id == ZigTypeIdComptimeFloat) { // Generate debug info for it but that's it. ConstExprValue *const_val = var->value; assert(const_val->special != ConstValSpecialRuntime); - TypeTableEntry *var_type = g->builtin_types.entry_f128; + ZigType *var_type = g->builtin_types.entry_f128; ConstExprValue coerced_value; coerced_value.special = ConstValSpecialStatic; coerced_value.type = var_type; @@ -5713,7 +6024,7 @@ static void do_code_gen(CodeGen *g) { continue; } - if (var->value->type->id == TypeTableEntryIdComptimeInt) { + if (var->value->type->id == ZigTypeIdComptimeInt) { // Generate debug info for it but that's it. ConstExprValue *const_val = var->value; assert(const_val->special != ConstValSpecialRuntime); @@ -5721,7 +6032,7 @@ static void do_code_gen(CodeGen *g) { if (bits_needed < 8) { bits_needed = 8; } - TypeTableEntry *var_type = get_int_type(g, const_val->data.x_bigint.is_negative, bits_needed); + ZigType *var_type = get_int_type(g, const_val->data.x_bigint.is_negative, bits_needed); LLVMValueRef init_val = bigint_to_llvm_const(var_type->type_ref, &const_val->data.x_bigint); gen_global_var(g, var, init_val, var_type); continue; @@ -5761,7 +6072,7 @@ static void do_code_gen(CodeGen *g) { LLVMSetAlignment(global_value, var->align_bytes); // TODO debug info for function pointers - if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) { + if (var->gen_is_const && var->value->type->id != ZigTypeIdFn) { gen_global_var(g, var, var->value->global_refs->llvm_value, var->value->type); } @@ -5773,12 +6084,15 @@ static void do_code_gen(CodeGen *g) { // Generate function definitions. for (size_t fn_i = 0; fn_i < g->fn_defs.length; fn_i += 1) { - FnTableEntry *fn_table_entry = g->fn_defs.at(fn_i); + ZigFn *fn_table_entry = g->fn_defs.at(fn_i); + FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; + CallingConvention cc = fn_type_id->cc; + bool is_c_abi = cc == CallingConventionC; LLVMValueRef fn = fn_llvm_value(g, fn_table_entry); g->cur_fn = fn_table_entry; g->cur_fn_val = fn; - TypeTableEntry *return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; + ZigType *return_type = fn_type_id->return_type; if (handle_is_ptr(return_type)) { g->cur_ret_ptr = LLVMGetParam(fn, 0); } else { @@ -5797,11 +6111,11 @@ static void do_code_gen(CodeGen *g) { } // error return tracing setup - bool is_async = fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; + bool is_async = cc == CallingConventionAsync; bool have_err_ret_trace_stack = g->have_err_ret_tracing && fn_table_entry->calls_or_awaits_errorable_fn && !is_async && !have_err_ret_trace_arg; LLVMValueRef err_ret_array_val = nullptr; if (have_err_ret_trace_stack) { - TypeTableEntry *array_type = get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count); + ZigType *array_type = get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count); err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses", get_abi_alignment(g, array_type)); g->cur_err_ret_trace_val_stack = build_alloca(g, g->stack_trace_type, "error_return_trace", get_abi_alignment(g, g->stack_trace_type)); } else { @@ -5812,14 +6126,14 @@ static void do_code_gen(CodeGen *g) { for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) { IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i); LLVMValueRef *slot; - TypeTableEntry *slot_type = instruction->value.type; + ZigType *slot_type = instruction->value.type; if (instruction->id == IrInstructionIdCast) { IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction; slot = &cast_instruction->tmp_ptr; } else if (instruction->id == IrInstructionIdRef) { IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction; slot = &ref_instruction->tmp_ptr; - assert(instruction->value.type->id == TypeTableEntryIdPointer); + assert(instruction->value.type->id == ZigTypeIdPointer); slot_type = instruction->value.type->data.pointer.child_type; } else if (instruction->id == IrInstructionIdContainerInitList) { IrInstructionContainerInitList *container_init_list_instruction = (IrInstructionContainerInitList *)instruction; @@ -5856,9 +6170,17 @@ static void do_code_gen(CodeGen *g) { ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base); + unsigned gen_i_init = want_first_arg_sret(g, fn_type_id) ? 1 : 0; + // create debug variable declarations for variables and allocate all local variables + FnWalk fn_walk_var = {}; + fn_walk_var.id = FnWalkIdVars; + fn_walk_var.data.vars.import = import; + fn_walk_var.data.vars.fn = fn_table_entry; + fn_walk_var.data.vars.llvm_fn = fn; + fn_walk_var.data.vars.gen_i = gen_i_init; for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { - VariableTableEntry *var = fn_table_entry->variable_list.at(var_i); + ZigVar *var = fn_table_entry->variable_list.at(var_i); if (!type_has_bits(var->value->type)) { continue; @@ -5875,9 +6197,12 @@ static void do_code_gen(CodeGen *g) { buf_ptr(&var->name), import->di_file, (unsigned)(var->decl_node->line + 1), var->value->type->di_type, !g->strip_debug_symbols, 0); + } else if (is_c_abi) { + fn_walk_var.data.vars.var = var; + iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index); } else { assert(var->gen_arg_index != SIZE_MAX); - TypeTableEntry *gen_type; + ZigType *gen_type; FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index]; if (handle_is_ptr(var->value->type)) { @@ -5903,7 +6228,7 @@ static void do_code_gen(CodeGen *g) { // finishing error return trace setup. we have to do this after all the allocas. if (have_err_ret_trace_stack) { - TypeTableEntry *usize = g->builtin_types.entry_usize; + ZigType *usize = g->builtin_types.entry_usize; size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, ""); gen_store_untyped(g, LLVMConstNull(usize->type_ref), index_field_ptr, 0, false); @@ -5911,14 +6236,14 @@ static void do_code_gen(CodeGen *g) { size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, ""); - TypeTableEntry *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; + ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); LLVMValueRef zero = LLVMConstNull(usize->type_ref); LLVMValueRef indices[] = {zero, zero}; LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val, indices, 2, ""); - TypeTableEntry *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false); + ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false); gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type); size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; @@ -5926,33 +6251,14 @@ static void do_code_gen(CodeGen *g) { gen_store(g, LLVMConstInt(usize->type_ref, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false)); } - FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; - // create debug variable declarations for parameters // rely on the first variables in the variable_list being parameters. - size_t next_var_i = 0; - for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { - FnGenParamInfo *info = &fn_table_entry->type_entry->data.fn.gen_param_info[param_i]; - if (info->gen_index == SIZE_MAX) - continue; - - VariableTableEntry *variable = fn_table_entry->variable_list.at(next_var_i); - assert(variable->src_arg_index != SIZE_MAX); - next_var_i += 1; - - assert(variable); - assert(variable->value_ref); - - if (!handle_is_ptr(variable->value->type)) { - clear_debug_source_node(g); - gen_store_untyped(g, LLVMGetParam(fn, (unsigned)variable->gen_arg_index), variable->value_ref, - variable->align_bytes, false); - } - - if (variable->decl_node) { - gen_var_debug_decl(g, variable); - } - } + FnWalk fn_walk_init = {}; + fn_walk_init.id = FnWalkIdInits; + fn_walk_init.data.inits.fn = fn_table_entry; + fn_walk_init.data.inits.llvm_fn = fn; + fn_walk_init.data.inits.gen_i = gen_i_init; + walk_function_params(g, fn_table_entry->type_entry, &fn_walk_init); ir_render(g, fn_table_entry); @@ -6007,7 +6313,7 @@ static void do_code_gen(CodeGen *g) { } Buf *output_path = buf_alloc(); - os_path_join(g->cache_dir, o_basename, output_path); + os_path_join(&g->cache_dir, o_basename, output_path); ensure_cache_dir(g); bool is_small = g->build_mode == BuildModeSmallRelease; @@ -6030,6 +6336,7 @@ static void do_code_gen(CodeGen *g) { zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); } validate_inline_fns(g); + g->link_objects.append(output_path); break; case EmitFileTypeLLVMIr: @@ -6039,6 +6346,7 @@ static void do_code_gen(CodeGen *g) { zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); } validate_inline_fns(g); + g->link_objects.append(output_path); break; default: @@ -6080,51 +6388,51 @@ static const GlobalLinkageValue global_linkage_values[] = { static void define_builtin_types(CodeGen *g) { { // if this type is anywhere in the AST, we should never hit codegen. - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInvalid); + ZigType *entry = new_type_table_entry(ZigTypeIdInvalid); buf_init_from_str(&entry->name, "(invalid)"); entry->zero_bits = true; g->builtin_types.entry_invalid = entry; } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNamespace); + ZigType *entry = new_type_table_entry(ZigTypeIdNamespace); buf_init_from_str(&entry->name, "(namespace)"); entry->zero_bits = true; g->builtin_types.entry_namespace = entry; } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBlock); + ZigType *entry = new_type_table_entry(ZigTypeIdBlock); buf_init_from_str(&entry->name, "(block)"); entry->zero_bits = true; g->builtin_types.entry_block = entry; } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdComptimeFloat); + ZigType *entry = new_type_table_entry(ZigTypeIdComptimeFloat); buf_init_from_str(&entry->name, "comptime_float"); entry->zero_bits = true; g->builtin_types.entry_num_lit_float = entry; g->primitive_type_table.put(&entry->name, entry); } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdComptimeInt); + ZigType *entry = new_type_table_entry(ZigTypeIdComptimeInt); buf_init_from_str(&entry->name, "comptime_int"); entry->zero_bits = true; g->builtin_types.entry_num_lit_int = entry; g->primitive_type_table.put(&entry->name, entry); } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefined); + ZigType *entry = new_type_table_entry(ZigTypeIdUndefined); buf_init_from_str(&entry->name, "(undefined)"); entry->zero_bits = true; g->builtin_types.entry_undef = entry; } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNull); + ZigType *entry = new_type_table_entry(ZigTypeIdNull); buf_init_from_str(&entry->name, "(null)"); entry->zero_bits = true; g->builtin_types.entry_null = entry; } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArgTuple); + ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple); buf_init_from_str(&entry->name, "(args)"); entry->zero_bits = true; g->builtin_types.entry_arg_tuple = entry; @@ -6135,7 +6443,7 @@ static void define_builtin_types(CodeGen *g) { uint32_t size_in_bits = target_c_type_size_in_bits(&g->zig_target, info->id); bool is_signed = info->is_signed; - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); + ZigType *entry = new_type_table_entry(ZigTypeIdInt); entry->type_ref = LLVMIntType(size_in_bits); buf_init_from_str(&entry->name, info->name); @@ -6152,7 +6460,7 @@ static void define_builtin_types(CodeGen *g) { } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool); + ZigType *entry = new_type_table_entry(ZigTypeIdBool); entry->type_ref = LLVMInt1Type(); buf_init_from_str(&entry->name, "bool"); uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); @@ -6166,7 +6474,7 @@ static void define_builtin_types(CodeGen *g) { for (size_t sign_i = 0; sign_i < array_length(is_signed_list); sign_i += 1) { bool is_signed = is_signed_list[sign_i]; - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); + ZigType *entry = new_type_table_entry(ZigTypeIdInt); entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8); const char u_or_i = is_signed ? 'i' : 'u'; @@ -6193,8 +6501,8 @@ static void define_builtin_types(CodeGen *g) { const char *name, uint32_t bit_count, LLVMTypeRef type_ref, - TypeTableEntry **field) { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat); + ZigType **field) { + ZigType *entry = new_type_table_entry(ZigTypeIdFloat); entry->type_ref = type_ref; buf_init_from_str(&entry->name, name); entry->data.floating.bit_count = bit_count; @@ -6213,7 +6521,7 @@ static void define_builtin_types(CodeGen *g) { add_fp_entry(g, "c_longdouble", 80, LLVMX86FP80Type(), &g->builtin_types.entry_c_longdouble); { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid); + ZigType *entry = new_type_table_entry(ZigTypeIdVoid); entry->type_ref = LLVMVoidType(); entry->zero_bits = true; buf_init_from_str(&entry->name, "void"); @@ -6224,7 +6532,7 @@ static void define_builtin_types(CodeGen *g) { g->primitive_type_table.put(&entry->name, entry); } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable); + ZigType *entry = new_type_table_entry(ZigTypeIdUnreachable); entry->type_ref = LLVMVoidType(); entry->zero_bits = true; buf_init_from_str(&entry->name, "noreturn"); @@ -6233,7 +6541,7 @@ static void define_builtin_types(CodeGen *g) { g->primitive_type_table.put(&entry->name, entry); } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType); + ZigType *entry = new_type_table_entry(ZigTypeIdMetaType); buf_init_from_str(&entry->name, "type"); entry->zero_bits = true; g->builtin_types.entry_type = entry; @@ -6255,7 +6563,7 @@ static void define_builtin_types(CodeGen *g) { } { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorSet); + ZigType *entry = new_type_table_entry(ZigTypeIdErrorSet); buf_init_from_str(&entry->name, "error"); entry->data.error_set.err_count = UINT32_MAX; @@ -6277,7 +6585,7 @@ static void define_builtin_types(CodeGen *g) { g->primitive_type_table.put(&entry->name, entry); } { - TypeTableEntry *entry = get_promise_type(g, nullptr); + ZigType *entry = get_promise_type(g, nullptr); g->primitive_type_table.put(&entry->name, entry); } @@ -6530,7 +6838,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { buf_appendf(contents, "pub const TypeId = enum {\n"); size_t field_count = type_id_len(); for (size_t i = 0; i < field_count; i += 1) { - const TypeTableEntryId id = type_id_at_index(i); + const ZigTypeId id = type_id_at_index(i); buf_appendf(contents, " %s,\n", type_id_name(id)); } buf_appendf(contents, "};\n\n"); @@ -6769,25 +7077,22 @@ static void define_builtin_compile_vars(CodeGen *g) { const char *builtin_zig_basename = "builtin.zig"; Buf *builtin_zig_path = buf_alloc(); - os_path_join(g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); + os_path_join(&g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); Buf *contents = codegen_generate_builtin_source(g); ensure_cache_dir(g); os_write_file(builtin_zig_path, contents); - int err; - Buf *abs_full_path = buf_alloc(); - if ((err = os_path_real(builtin_zig_path, abs_full_path))) { - fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err)); - exit(1); - } + Buf *resolved_path = buf_alloc(); + Buf *resolve_paths[] = {builtin_zig_path}; + *resolved_path = os_path_resolve(resolve_paths, 1); assert(g->root_package); assert(g->std_package); - g->compile_var_package = new_package(buf_ptr(g->cache_dir), builtin_zig_basename); + g->compile_var_package = new_package(buf_ptr(&g->cache_dir), builtin_zig_basename); g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package); g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package); - g->compile_var_import = add_source_file(g, g->compile_var_package, abs_full_path, contents); + g->compile_var_import = add_source_file(g, g->compile_var_package, resolved_path, contents); scan_import(g, g->compile_var_import); } @@ -6943,17 +7248,17 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package Buf *code_basename = buf_create_from_str(basename); Buf path_to_code_src = BUF_INIT; os_path_join(g->zig_std_special_dir, code_basename, &path_to_code_src); - Buf *abs_full_path = buf_alloc(); - int err; - if ((err = os_path_real(&path_to_code_src, abs_full_path))) { - zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err)); - } + + Buf *resolve_paths[] = {&path_to_code_src}; + Buf *resolved_path = buf_alloc(); + *resolved_path = os_path_resolve(resolve_paths, 1); Buf *import_code = buf_alloc(); - if ((err = os_fetch_file_path(abs_full_path, import_code, false))) { + int err; + if ((err = os_fetch_file_path(resolved_path, import_code, false))) { zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err)); } - return add_source_file(g, package, abs_full_path, import_code); + return add_source_file(g, package, resolved_path, import_code); } static PackageTableEntry *create_bootstrap_pkg(CodeGen *g, PackageTableEntry *pkg_with_main) { @@ -6978,14 +7283,14 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { exit(0); } - TypeTableEntry *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, + ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); - TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type); - TypeTableEntry *fn_type = get_test_fn_type(g); + ZigType *str_type = get_slice_type(g, u8_ptr_type); + ZigType *fn_type = get_test_fn_type(g); const char *field_names[] = { "name", "func", }; - TypeTableEntry *field_types[] = { str_type, fn_type, }; - TypeTableEntry *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2); + ZigType *field_types[] = { str_type, fn_type, }; + ZigType *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2); ConstExprValue *test_fn_array = create_const_vals(1); test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length); @@ -6993,7 +7298,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length); for (size_t i = 0; i < g->test_fns.length; i += 1) { - FnTableEntry *test_fn_entry = g->test_fns.at(i); + ZigFn *test_fn_entry = g->test_fns.at(i); ConstExprValue *this_val = &test_fn_array->data.x_array.s_none.elements[i]; this_val->special = ConstValSpecialStatic; @@ -7031,20 +7336,18 @@ static void gen_root_source(CodeGen *g) { Buf *rel_full_path = buf_alloc(); os_path_join(&g->root_package->root_src_dir, &g->root_package->root_src_path, rel_full_path); - Buf *abs_full_path = buf_alloc(); - int err; - if ((err = os_path_real(rel_full_path, abs_full_path))) { - fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(rel_full_path), err_str(err)); - exit(1); - } + Buf *resolved_path = buf_alloc(); + Buf *resolve_paths[] = {rel_full_path}; + *resolved_path = os_path_resolve(resolve_paths, 1); Buf *source_code = buf_alloc(); + int err; if ((err = os_fetch_file_path(rel_full_path, source_code, true))) { fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(rel_full_path), err_str(err)); exit(1); } - g->root_import = add_source_file(g, g->root_package, abs_full_path, source_code); + g->root_import = add_source_file(g, g->root_package, resolved_path, source_code); assert(g->root_out_name); assert(g->out_type != OutTypeUnknown); @@ -7129,66 +7432,66 @@ static const char *c_int_type_names[] = { }; struct GenH { - ZigList<TypeTableEntry *> types_to_declare; + ZigList<ZigType *> types_to_declare; }; -static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry) { +static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_entry) { if (type_entry->gen_h_loop_flag) return; type_entry->gen_h_loop_flag = true; switch (type_entry->id) { - case TypeTableEntryIdInvalid: - case TypeTableEntryIdMetaType: - case TypeTableEntryIdComptimeFloat: - case TypeTableEntryIdComptimeInt: - case TypeTableEntryIdUndefined: - case TypeTableEntryIdNull: - case TypeTableEntryIdNamespace: - case TypeTableEntryIdBlock: - case TypeTableEntryIdBoundFn: - case TypeTableEntryIdArgTuple: - case TypeTableEntryIdErrorUnion: - case TypeTableEntryIdErrorSet: - case TypeTableEntryIdPromise: + case ZigTypeIdInvalid: + case ZigTypeIdMetaType: + case ZigTypeIdComptimeFloat: + case ZigTypeIdComptimeInt: + case ZigTypeIdUndefined: + case ZigTypeIdNull: + case ZigTypeIdNamespace: + case ZigTypeIdBlock: + case ZigTypeIdBoundFn: + case ZigTypeIdArgTuple: + case ZigTypeIdErrorUnion: + case ZigTypeIdErrorSet: + case ZigTypeIdPromise: zig_unreachable(); - case TypeTableEntryIdVoid: - case TypeTableEntryIdUnreachable: - case TypeTableEntryIdBool: - case TypeTableEntryIdInt: - case TypeTableEntryIdFloat: + case ZigTypeIdVoid: + case ZigTypeIdUnreachable: + case ZigTypeIdBool: + case ZigTypeIdInt: + case ZigTypeIdFloat: return; - case TypeTableEntryIdOpaque: + case ZigTypeIdOpaque: gen_h->types_to_declare.append(type_entry); return; - case TypeTableEntryIdStruct: + case ZigTypeIdStruct: for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { TypeStructField *field = &type_entry->data.structure.fields[i]; prepend_c_type_to_decl_list(g, gen_h, field->type_entry); } gen_h->types_to_declare.append(type_entry); return; - case TypeTableEntryIdUnion: + case ZigTypeIdUnion: for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) { TypeUnionField *field = &type_entry->data.unionation.fields[i]; prepend_c_type_to_decl_list(g, gen_h, field->type_entry); } gen_h->types_to_declare.append(type_entry); return; - case TypeTableEntryIdEnum: + case ZigTypeIdEnum: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.enumeration.tag_int_type); gen_h->types_to_declare.append(type_entry); return; - case TypeTableEntryIdPointer: + case ZigTypeIdPointer: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.pointer.child_type); return; - case TypeTableEntryIdArray: + case ZigTypeIdArray: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type); return; - case TypeTableEntryIdOptional: + case ZigTypeIdOptional: prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type); return; - case TypeTableEntryIdFn: + case ZigTypeIdFn: for (size_t i = 0; i < type_entry->data.fn.fn_type_id.param_count; i += 1) { prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.param_info[i].type); } @@ -7197,7 +7500,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry } } -static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf *out_buf) { +static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_buf) { assert(type_entry); for (size_t i = 0; i < array_length(c_int_type_names); i += 1) { @@ -7228,17 +7531,17 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf prepend_c_type_to_decl_list(g, gen_h, type_entry); switch (type_entry->id) { - case TypeTableEntryIdVoid: + case ZigTypeIdVoid: buf_init_from_str(out_buf, "void"); break; - case TypeTableEntryIdBool: + case ZigTypeIdBool: buf_init_from_str(out_buf, "bool"); g->c_want_stdbool = true; break; - case TypeTableEntryIdUnreachable: + case ZigTypeIdUnreachable: buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void"); break; - case TypeTableEntryIdFloat: + case ZigTypeIdFloat: switch (type_entry->data.floating.bit_count) { case 32: buf_init_from_str(out_buf, "float"); @@ -7256,17 +7559,17 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf zig_unreachable(); } break; - case TypeTableEntryIdInt: + case ZigTypeIdInt: g->c_want_stdint = true; buf_resize(out_buf, 0); buf_appendf(out_buf, "%sint%" PRIu32 "_t", type_entry->data.integral.is_signed ? "" : "u", type_entry->data.integral.bit_count); break; - case TypeTableEntryIdPointer: + case ZigTypeIdPointer: { Buf child_buf = BUF_INIT; - TypeTableEntry *child_type = type_entry->data.pointer.child_type; + ZigType *child_type = type_entry->data.pointer.child_type; get_c_type(g, gen_h, child_type, &child_buf); const char *const_str = type_entry->data.pointer.is_const ? "const " : ""; @@ -7274,9 +7577,9 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf buf_appendf(out_buf, "%s%s *", const_str, buf_ptr(&child_buf)); break; } - case TypeTableEntryIdOptional: + case ZigTypeIdOptional: { - TypeTableEntry *child_type = type_entry->data.maybe.child_type; + ZigType *child_type = type_entry->data.maybe.child_type; if (child_type->zero_bits) { buf_init_from_str(out_buf, "bool"); return; @@ -7286,28 +7589,28 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf zig_unreachable(); } } - case TypeTableEntryIdStruct: - case TypeTableEntryIdOpaque: + case ZigTypeIdStruct: + case ZigTypeIdOpaque: { buf_init_from_str(out_buf, "struct "); buf_append_buf(out_buf, &type_entry->name); return; } - case TypeTableEntryIdUnion: + case ZigTypeIdUnion: { buf_init_from_str(out_buf, "union "); buf_append_buf(out_buf, &type_entry->name); return; } - case TypeTableEntryIdEnum: + case ZigTypeIdEnum: { buf_init_from_str(out_buf, "enum "); buf_append_buf(out_buf, &type_entry->name); return; } - case TypeTableEntryIdArray: + case ZigTypeIdArray: { - TypeTableEntryArray *array_data = &type_entry->data.array; + ZigTypeArray *array_data = &type_entry->data.array; Buf *child_buf = buf_alloc(); get_c_type(g, gen_h, array_data->child_type, child_buf); @@ -7316,21 +7619,21 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf buf_appendf(out_buf, "%s", buf_ptr(child_buf)); return; } - case TypeTableEntryIdErrorUnion: - case TypeTableEntryIdErrorSet: - case TypeTableEntryIdFn: + case ZigTypeIdErrorUnion: + case ZigTypeIdErrorSet: + case ZigTypeIdFn: zig_panic("TODO implement get_c_type for more types"); - case TypeTableEntryIdInvalid: - case TypeTableEntryIdMetaType: - case TypeTableEntryIdBoundFn: - case TypeTableEntryIdNamespace: - case TypeTableEntryIdBlock: - case TypeTableEntryIdComptimeFloat: - case TypeTableEntryIdComptimeInt: - case TypeTableEntryIdUndefined: - case TypeTableEntryIdNull: - case TypeTableEntryIdArgTuple: - case TypeTableEntryIdPromise: + case ZigTypeIdInvalid: + case ZigTypeIdMetaType: + case ZigTypeIdBoundFn: + case ZigTypeIdNamespace: + case ZigTypeIdBlock: + case ZigTypeIdComptimeFloat: + case ZigTypeIdComptimeInt: + case ZigTypeIdUndefined: + case ZigTypeIdNull: + case ZigTypeIdArgTuple: + case ZigTypeIdPromise: zig_unreachable(); } } @@ -7395,7 +7698,7 @@ static void gen_h_file(CodeGen *g) { Buf h_buf = BUF_INIT; buf_resize(&h_buf, 0); for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { - FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i); + ZigFn *fn_table_entry = g->fn_defs.at(fn_def_i); if (fn_table_entry->export_list.length == 0) continue; @@ -7421,7 +7724,7 @@ static void gen_h_file(CodeGen *g) { const char *restrict_str = param_info->is_noalias ? "restrict" : ""; get_c_type(g, gen_h, param_info->type, ¶m_type_c); - if (param_info->type->id == TypeTableEntryIdArray) { + if (param_info->type->id == ZigTypeIdArray) { // Arrays decay to pointers buf_appendf(&h_buf, "%s%s%s %s[]", comma_str, buf_ptr(¶m_type_c), restrict_str, buf_ptr(param_name)); @@ -7467,32 +7770,32 @@ static void gen_h_file(CodeGen *g) { fprintf(out_h, "\n"); for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) { - TypeTableEntry *type_entry = gen_h->types_to_declare.at(type_i); + ZigType *type_entry = gen_h->types_to_declare.at(type_i); switch (type_entry->id) { - case TypeTableEntryIdInvalid: - case TypeTableEntryIdMetaType: - case TypeTableEntryIdVoid: - case TypeTableEntryIdBool: - case TypeTableEntryIdUnreachable: - case TypeTableEntryIdInt: - case TypeTableEntryIdFloat: - case TypeTableEntryIdPointer: - case TypeTableEntryIdComptimeFloat: - case TypeTableEntryIdComptimeInt: - case TypeTableEntryIdArray: - case TypeTableEntryIdUndefined: - case TypeTableEntryIdNull: - case TypeTableEntryIdErrorUnion: - case TypeTableEntryIdErrorSet: - case TypeTableEntryIdNamespace: - case TypeTableEntryIdBlock: - case TypeTableEntryIdBoundFn: - case TypeTableEntryIdArgTuple: - case TypeTableEntryIdOptional: - case TypeTableEntryIdFn: - case TypeTableEntryIdPromise: + case ZigTypeIdInvalid: + case ZigTypeIdMetaType: + case ZigTypeIdVoid: + case ZigTypeIdBool: + case ZigTypeIdUnreachable: + case ZigTypeIdInt: + case ZigTypeIdFloat: + case ZigTypeIdPointer: + case ZigTypeIdComptimeFloat: + case ZigTypeIdComptimeInt: + case ZigTypeIdArray: + case ZigTypeIdUndefined: + case ZigTypeIdNull: + case ZigTypeIdErrorUnion: + case ZigTypeIdErrorSet: + case ZigTypeIdNamespace: + case ZigTypeIdBlock: + case ZigTypeIdBoundFn: + case ZigTypeIdArgTuple: + case ZigTypeIdOptional: + case ZigTypeIdFn: + case ZigTypeIdPromise: zig_unreachable(); - case TypeTableEntryIdEnum: + case ZigTypeIdEnum: if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { fprintf(out_h, "enum %s {\n", buf_ptr(&type_entry->name)); for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) { @@ -7510,7 +7813,7 @@ static void gen_h_file(CodeGen *g) { fprintf(out_h, "enum %s;\n", buf_ptr(&type_entry->name)); } break; - case TypeTableEntryIdStruct: + case ZigTypeIdStruct: if (type_entry->data.structure.layout == ContainerLayoutExtern) { fprintf(out_h, "struct %s {\n", buf_ptr(&type_entry->name)); for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) { @@ -7519,7 +7822,7 @@ static void gen_h_file(CodeGen *g) { Buf *type_name_buf = buf_alloc(); get_c_type(g, gen_h, struct_field->type_entry, type_name_buf); - if (struct_field->type_entry->id == TypeTableEntryIdArray) { + if (struct_field->type_entry->id == ZigTypeIdArray) { fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name), struct_field->type_entry->data.array.len); @@ -7533,7 +7836,7 @@ static void gen_h_file(CodeGen *g) { fprintf(out_h, "struct %s;\n", buf_ptr(&type_entry->name)); } break; - case TypeTableEntryIdUnion: + case ZigTypeIdUnion: if (type_entry->data.unionation.layout == ContainerLayoutExtern) { fprintf(out_h, "union %s {\n", buf_ptr(&type_entry->name)); for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) { @@ -7548,7 +7851,7 @@ static void gen_h_file(CodeGen *g) { fprintf(out_h, "union %s;\n", buf_ptr(&type_entry->name)); } break; - case TypeTableEntryIdOpaque: + case ZigTypeIdOpaque: fprintf(out_h, "struct %s;\n\n", buf_ptr(&type_entry->name)); break; } |
