| ... | @@ -226,7 +226,7 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { | ... | @@ -226,7 +226,7 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { |
| 226 | } | 226 | } |
| 227 | | 227 | |
| 228 | static void render_const_val(CodeGen *g, ConstExprValue *const_val); | 228 | static void render_const_val(CodeGen *g, ConstExprValue *const_val); |
| 229 | static void render_const_val_global(CodeGen *g, ConstExprValue *const_val); | 229 | static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, bool is_export); |
| 230 | | 230 | |
| 231 | static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { | 231 | static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 232 | if (fn_table_entry->llvm_value) | 232 | if (fn_table_entry->llvm_value) |
| ... | @@ -681,7 +681,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { | ... | @@ -681,7 +681,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { |
| 681 | // we might have to do some pointer casting here due to the way union | 681 | // we might have to do some pointer casting here due to the way union |
| 682 | // values are rendered with a type other than the one we expect | 682 | // values are rendered with a type other than the one we expect |
| 683 | if (handle_is_ptr(instruction->value.type)) { | 683 | if (handle_is_ptr(instruction->value.type)) { |
| 684 | render_const_val_global(g, &instruction->value); | 684 | render_const_val_global(g, &instruction->value, false); |
| 685 | TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true); | 685 | TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true); |
| 686 | instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_global, ptr_type->type_ref, ""); | 686 | instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_global, ptr_type->type_ref, ""); |
| 687 | } else if (instruction->value.type->id == TypeTableEntryIdPointer) { | 687 | } else if (instruction->value.type->id == TypeTableEntryIdPointer) { |
| ... | @@ -2414,7 +2414,7 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar | ... | @@ -2414,7 +2414,7 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar |
| 2414 | base_ptr = gen_const_ptr_array_recursive(g, parent_array, parent_array_index); | 2414 | base_ptr = gen_const_ptr_array_recursive(g, parent_array, parent_array_index); |
| 2415 | } else { | 2415 | } else { |
| 2416 | render_const_val(g, array_const_val); | 2416 | render_const_val(g, array_const_val); |
| 2417 | render_const_val_global(g, array_const_val); | 2417 | render_const_val_global(g, array_const_val, false); |
| 2418 | base_ptr = array_const_val->llvm_global; | 2418 | base_ptr = array_const_val->llvm_global; |
| 2419 | } | 2419 | } |
| 2420 | TypeTableEntry *usize = g->builtin_types.entry_usize; | 2420 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| ... | @@ -2562,16 +2562,16 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -2562,16 +2562,16 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 2562 | return fn_llvm_value(g, const_val->data.x_fn); | 2562 | return fn_llvm_value(g, const_val->data.x_fn); |
| 2563 | case TypeTableEntryIdPointer: | 2563 | case TypeTableEntryIdPointer: |
| 2564 | { | 2564 | { |
| 2565 | render_const_val_global(g, const_val); | 2565 | render_const_val_global(g, const_val, false); |
| 2566 | size_t index = const_val->data.x_ptr.index; | 2566 | size_t index = const_val->data.x_ptr.index; |
| 2567 | ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr; | 2567 | ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr; |
| 2568 | if (base_ptr) { | 2568 | if (base_ptr) { |
| 2569 | if (index == SIZE_MAX) { | 2569 | if (index == SIZE_MAX) { |
| 2570 | render_const_val(g, base_ptr); | 2570 | render_const_val(g, base_ptr); |
| 2571 | render_const_val_global(g, base_ptr); | 2571 | render_const_val_global(g, base_ptr, false); |
| 2572 | ConstExprValue *other_val = base_ptr; | 2572 | ConstExprValue *other_val = base_ptr; |
| 2573 | const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref); | 2573 | const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref); |
| 2574 | render_const_val_global(g, const_val); | 2574 | render_const_val_global(g, const_val, false); |
| 2575 | return const_val->llvm_value; | 2575 | return const_val->llvm_value; |
| 2576 | } else { | 2576 | } else { |
| 2577 | ConstExprValue *array_const_val = base_ptr; | 2577 | ConstExprValue *array_const_val = base_ptr; |
| ... | @@ -2581,19 +2581,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -2581,19 +2581,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 2581 | TypeTableEntry *usize = g->builtin_types.entry_usize; | 2581 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| 2582 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), | 2582 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), |
| 2583 | const_val->type->type_ref); | 2583 | const_val->type->type_ref); |
| 2584 | render_const_val_global(g, const_val); | 2584 | render_const_val_global(g, const_val, false); |
| 2585 | return const_val->llvm_value; | 2585 | return const_val->llvm_value; |
| 2586 | } | 2586 | } |
| 2587 | LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, index); | 2587 | LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, index); |
| 2588 | LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); | 2588 | LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); |
| 2589 | const_val->llvm_value = ptr_val; | 2589 | const_val->llvm_value = ptr_val; |
| 2590 | render_const_val_global(g, const_val); | 2590 | render_const_val_global(g, const_val, false); |
| 2591 | return ptr_val; | 2591 | return ptr_val; |
| 2592 | } | 2592 | } |
| 2593 | } else { | 2593 | } else { |
| 2594 | TypeTableEntry *usize = g->builtin_types.entry_usize; | 2594 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| 2595 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref); | 2595 | const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref); |
| 2596 | render_const_val_global(g, const_val); | 2596 | render_const_val_global(g, const_val, false); |
| 2597 | return const_val->llvm_value; | 2597 | return const_val->llvm_value; |
| 2598 | } | 2598 | } |
| 2599 | } | 2599 | } |
| ... | @@ -2648,11 +2648,11 @@ static void render_const_val(CodeGen *g, ConstExprValue *const_val) { | ... | @@ -2648,11 +2648,11 @@ static void render_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 2648 | LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); | 2648 | LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); |
| 2649 | } | 2649 | } |
| 2650 | | 2650 | |
| 2651 | static void render_const_val_global(CodeGen *g, ConstExprValue *const_val) { | 2651 | static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, bool is_export) { |
| 2652 | if (!const_val->llvm_global) { | 2652 | if (!const_val->llvm_global) { |
| 2653 | LLVMTypeRef type_ref = const_val->llvm_value ? LLVMTypeOf(const_val->llvm_value) : const_val->type->type_ref; | 2653 | LLVMTypeRef type_ref = const_val->llvm_value ? LLVMTypeOf(const_val->llvm_value) : const_val->type->type_ref; |
| 2654 | LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, ""); | 2654 | LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, ""); |
| 2655 | LLVMSetLinkage(global_value, LLVMInternalLinkage); | 2655 | LLVMSetLinkage(global_value, is_export ? LLVMExternalLinkage : LLVMInternalLinkage); |
| 2656 | LLVMSetGlobalConstant(global_value, true); | 2656 | LLVMSetGlobalConstant(global_value, true); |
| 2657 | LLVMSetUnnamedAddr(global_value, true); | 2657 | LLVMSetUnnamedAddr(global_value, true); |
| 2658 | | 2658 | |
| ... | @@ -2827,15 +2827,16 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -2827,15 +2827,16 @@ static void do_code_gen(CodeGen *g) { |
| 2827 | assert(var->decl_node); | 2827 | assert(var->decl_node); |
| 2828 | | 2828 | |
| 2829 | LLVMValueRef global_value; | 2829 | LLVMValueRef global_value; |
| 2830 | if (var->is_extern) { | 2830 | if (var->linkage == VarLinkageExternal) { |
| 2831 | global_value = LLVMAddGlobal(g->module, var->value.type->type_ref, buf_ptr(&var->name)); | 2831 | global_value = LLVMAddGlobal(g->module, var->value.type->type_ref, buf_ptr(&var->name)); |
| 2832 | | 2832 | |
| 2833 | // TODO debug info for the extern variable | 2833 | // TODO debug info for the extern variable |
| 2834 | | 2834 | |
| 2835 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 2835 | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| 2836 | } else { | 2836 | } else { |
| | 2837 | bool is_export = (var->linkage == VarLinkageExport); |
| 2837 | render_const_val(g, &var->value); | 2838 | render_const_val(g, &var->value); |
| 2838 | render_const_val_global(g, &var->value); | 2839 | render_const_val_global(g, &var->value, is_export); |
| 2839 | global_value = var->value.llvm_global; | 2840 | global_value = var->value.llvm_global; |
| 2840 | // TODO debug info for function pointers | 2841 | // TODO debug info for function pointers |
| 2841 | if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) { | 2842 | if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) { |