| author | |
| committer | |
| log | c7591736b4ae3aed90f6980b4cb23a4dab21d925 |
| tree | 3b9bdb91139b6c02e2c30a0c38975ac517edbde5 |
| parent | 3752e0c29040863ac959174e0457b554f9715cab |
3 files changed, 44 insertions(+), 38 deletions(-)
src/analyze.cpp-1| ... | ... | @@ -1336,7 +1336,6 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { |
| 1336 | 1336 | |
| 1337 | 1337 | Scope *scope = &struct_type->data.structure.decls_scope->base; |
| 1338 | 1338 | |
| 1339 | //if (buf_eql_str(&struct_type->name, "Particle")) { BREAKPOINT; } | |
| 1340 | 1339 | for (size_t i = 0; i < field_count; i += 1) { |
| 1341 | 1340 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 1342 | 1341 | TypeTableEntry *field_type = type_struct_field->type_entry; |
src/codegen.cpp+35-28| ... | ... | @@ -1238,7 +1238,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, |
| 1238 | 1238 | if (!type_has_bits(var->value.type)) |
| 1239 | 1239 | return nullptr; |
| 1240 | 1240 | |
| 1241 | if (var->ref_count == 0) | |
| 1241 | if (var->ref_count == 0 && g->is_release_build) | |
| 1242 | 1242 | return nullptr; |
| 1243 | 1243 | |
| 1244 | 1244 | IrInstruction *init_value = decl_var_instruction->init_value; |
| ... | ... | @@ -2501,14 +2501,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 2501 | 2501 | } |
| 2502 | 2502 | case TypeTableEntryIdArray: |
| 2503 | 2503 | { |
| 2504 | TypeTableEntry *child_type = canon_type->data.array.child_type; | |
| 2505 | 2504 | uint64_t len = canon_type->data.array.len; |
| 2506 | 2505 | LLVMValueRef *values = allocate<LLVMValueRef>(len); |
| 2507 | 2506 | for (uint64_t i = 0; i < len; i += 1) { |
| 2508 | 2507 | ConstExprValue *elem_value = &const_val->data.x_array.elements[i]; |
| 2509 | 2508 | values[i] = gen_const_val(g, elem_value); |
| 2510 | 2509 | } |
| 2511 | return LLVMConstArray(child_type->type_ref, values, len); | |
| 2510 | return LLVMConstArray(LLVMTypeOf(values[0]), values, len); | |
| 2512 | 2511 | } |
| 2513 | 2512 | case TypeTableEntryIdEnum: |
| 2514 | 2513 | { |
| ... | ... | @@ -2554,35 +2553,43 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 2554 | 2553 | { |
| 2555 | 2554 | render_const_val_global(g, const_val); |
| 2556 | 2555 | size_t index = const_val->data.x_ptr.index; |
| 2557 | if (index == SIZE_MAX) { | |
| 2558 | render_const_val(g, const_val->data.x_ptr.base_ptr); | |
| 2559 | render_const_val_global(g, const_val->data.x_ptr.base_ptr); | |
| 2560 | ConstExprValue *other_val = const_val->data.x_ptr.base_ptr; | |
| 2561 | const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref); | |
| 2562 | render_const_val_global(g, const_val); | |
| 2563 | return const_val->llvm_value; | |
| 2564 | } else { | |
| 2565 | ConstExprValue *array_const_val = const_val->data.x_ptr.base_ptr; | |
| 2566 | assert(array_const_val->type->id == TypeTableEntryIdArray); | |
| 2567 | if (array_const_val->type->zero_bits) { | |
| 2568 | // make this a null pointer | |
| 2569 | TypeTableEntry *usize_type = g->builtin_types.entry_usize; | |
| 2570 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref), | |
| 2571 | const_val->type->type_ref); | |
| 2556 | ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr; | |
| 2557 | TypeTableEntry *usize = g->builtin_types.entry_usize; | |
| 2558 | if (base_ptr) { | |
| 2559 | if (index == SIZE_MAX) { | |
| 2560 | render_const_val(g, base_ptr); | |
| 2561 | render_const_val_global(g, base_ptr); | |
| 2562 | ConstExprValue *other_val = base_ptr; | |
| 2563 | const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref); | |
| 2572 | 2564 | render_const_val_global(g, const_val); |
| 2573 | 2565 | return const_val->llvm_value; |
| 2566 | } else { | |
| 2567 | ConstExprValue *array_const_val = base_ptr; | |
| 2568 | assert(array_const_val->type->id == TypeTableEntryIdArray); | |
| 2569 | if (array_const_val->type->zero_bits) { | |
| 2570 | // make this a null pointer | |
| 2571 | TypeTableEntry *usize_type = g->builtin_types.entry_usize; | |
| 2572 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref), | |
| 2573 | const_val->type->type_ref); | |
| 2574 | render_const_val_global(g, const_val); | |
| 2575 | return const_val->llvm_value; | |
| 2576 | } | |
| 2577 | render_const_val(g, array_const_val); | |
| 2578 | render_const_val_global(g, array_const_val); | |
| 2579 | LLVMValueRef indices[] = { | |
| 2580 | LLVMConstNull(usize->type_ref), | |
| 2581 | LLVMConstInt(usize->type_ref, index, false), | |
| 2582 | }; | |
| 2583 | LLVMValueRef uncasted_ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2); | |
| 2584 | LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); | |
| 2585 | const_val->llvm_value = ptr_val; | |
| 2586 | render_const_val_global(g, const_val); | |
| 2587 | return ptr_val; | |
| 2574 | 2588 | } |
| 2575 | render_const_val(g, array_const_val); | |
| 2576 | render_const_val_global(g, array_const_val); | |
| 2577 | TypeTableEntry *usize = g->builtin_types.entry_usize; | |
| 2578 | LLVMValueRef indices[] = { | |
| 2579 | LLVMConstNull(usize->type_ref), | |
| 2580 | LLVMConstInt(usize->type_ref, index, false), | |
| 2581 | }; | |
| 2582 | LLVMValueRef ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2); | |
| 2583 | const_val->llvm_value = ptr_val; | |
| 2589 | } else { | |
| 2590 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref); | |
| 2584 | 2591 | render_const_val_global(g, const_val); |
| 2585 | return ptr_val; | |
| 2592 | return const_val->llvm_value; | |
| 2586 | 2593 | } |
| 2587 | 2594 | } |
| 2588 | 2595 | case TypeTableEntryIdErrorUnion: |
src/ir.cpp+9-9| ... | ... | @@ -3465,7 +3465,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld |
| 3465 | 3465 | { |
| 3466 | 3466 | TldVar *tld_var = (TldVar *)tld; |
| 3467 | 3467 | VariableTableEntry *var = tld_var->var; |
| 3468 | IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, source_node, var, false); | |
| 3468 | IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, source_node, var, lval == LValPurposeAddressOfConst); | |
| 3469 | 3469 | if (lval != LValPurposeNone) |
| 3470 | 3470 | return var_ptr; |
| 3471 | 3471 | else |
| ... | ... | @@ -7655,9 +7655,9 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 7655 | 7655 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); |
| 7656 | 7656 | impl_fn->fndef_scope = create_fndef_scope(impl_fn->fn_def_node, parent_scope, impl_fn); |
| 7657 | 7657 | impl_fn->child_scope = &impl_fn->fndef_scope->base; |
| 7658 | FnTypeId fn_type_id = {0}; | |
| 7659 | init_fn_type_id(&fn_type_id, fn_proto_node); | |
| 7660 | fn_type_id.param_count = 0; | |
| 7658 | FnTypeId inst_fn_type_id = {0}; | |
| 7659 | init_fn_type_id(&inst_fn_type_id, fn_proto_node); | |
| 7660 | inst_fn_type_id.param_count = 0; | |
| 7661 | 7661 | |
| 7662 | 7662 | // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly |
| 7663 | 7663 | // as the key in generic_table |
| ... | ... | @@ -7679,7 +7679,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 7679 | 7679 | } |
| 7680 | 7680 | |
| 7681 | 7681 | if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope, |
| 7682 | &next_proto_i, generic_id, &fn_type_id, casted_args, impl_fn)) | |
| 7682 | &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) | |
| 7683 | 7683 | { |
| 7684 | 7684 | return ira->codegen->builtin_types.entry_invalid; |
| 7685 | 7685 | } |
| ... | ... | @@ -7690,7 +7690,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 7690 | 7690 | return ira->codegen->builtin_types.entry_invalid; |
| 7691 | 7691 | |
| 7692 | 7692 | if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope, |
| 7693 | &next_proto_i, generic_id, &fn_type_id, casted_args, impl_fn)) | |
| 7693 | &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) | |
| 7694 | 7694 | { |
| 7695 | 7695 | return ira->codegen->builtin_types.entry_invalid; |
| 7696 | 7696 | } |
| ... | ... | @@ -7701,7 +7701,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 7701 | 7701 | TypeTableEntry *return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node); |
| 7702 | 7702 | if (return_type->id == TypeTableEntryIdInvalid) |
| 7703 | 7703 | return ira->codegen->builtin_types.entry_invalid; |
| 7704 | fn_type_id.return_type = return_type; | |
| 7704 | inst_fn_type_id.return_type = return_type; | |
| 7705 | 7705 | |
| 7706 | 7706 | if (type_requires_comptime(return_type)) { |
| 7707 | 7707 | // Throw out our work and call the function as if it were inline. |
| ... | ... | @@ -7715,7 +7715,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 7715 | 7715 | impl_fn = existing_entry->value; |
| 7716 | 7716 | } else { |
| 7717 | 7717 | // finish instantiating the function |
| 7718 | impl_fn->type_entry = get_fn_type(ira->codegen, &fn_type_id); | |
| 7718 | impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); | |
| 7719 | 7719 | if (impl_fn->type_entry->id == TypeTableEntryIdInvalid) |
| 7720 | 7720 | return ira->codegen->builtin_types.entry_invalid; |
| 7721 | 7721 | |
| ... | ... | @@ -7802,7 +7802,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction |
| 7802 | 7802 | |
| 7803 | 7803 | bool is_inline = call_instruction->is_comptime || ir_should_inline(&ira->new_irb); |
| 7804 | 7804 | |
| 7805 | if (is_inline || fn_ref->value.special != ConstValSpecialRuntime) { | |
| 7805 | if (is_inline || instr_is_comptime(fn_ref)) { | |
| 7806 | 7806 | if (fn_ref->value.type->id == TypeTableEntryIdMetaType) { |
| 7807 | 7807 | TypeTableEntry *dest_type = ir_resolve_type(ira, fn_ref); |
| 7808 | 7808 | if (dest_type->id == TypeTableEntryIdInvalid) |