diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 4 | ||||
| -rw-r--r-- | src/analyze.cpp | 2 | ||||
| -rw-r--r-- | src/codegen.cpp | 22 | ||||
| -rw-r--r-- | src/ir.cpp | 64 | ||||
| -rw-r--r-- | src/link.cpp | 10 |
5 files changed, 84 insertions, 18 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index f57c3124da..87f4c889ac 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1853,7 +1853,9 @@ struct CodeGen { enum VarLinkage { VarLinkageInternal, - VarLinkageExport, + VarLinkageExportStrong, + VarLinkageExportWeak, + VarLinkageExportLinkOnce, VarLinkageExternal, }; diff --git a/src/analyze.cpp b/src/analyze.cpp index 37c0041314..934da61186 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3746,7 +3746,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { VarLinkage linkage; if (is_export) { - linkage = VarLinkageExport; + linkage = VarLinkageExportStrong; } else if (is_extern) { linkage = VarLinkageExternal; } else { diff --git a/src/codegen.cpp b/src/codegen.cpp index 9085d4ea7c..843f8cfd17 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6421,6 +6421,22 @@ static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { } } +static LLVMLinkage var_linkage_to_llvm(VarLinkage var_linkage) { + switch (var_linkage) { + case VarLinkageInternal: + return LLVMInternalLinkage; + case VarLinkageExportStrong: + return LLVMExternalLinkage; + case VarLinkageExportWeak: + return LLVMWeakODRLinkage; + case VarLinkageExportLinkOnce: + return LLVMLinkOnceODRLinkage; + case VarLinkageExternal: + return LLVMExternalLinkage; + } + zig_unreachable(); +} + static void do_code_gen(CodeGen *g) { assert(!g->errors.length); @@ -6501,21 +6517,21 @@ static void do_code_gen(CodeGen *g) { global_value = LLVMAddGlobal(g->module, var->var_type->type_ref, buf_ptr(&var->name)); // TODO debug info for the extern variable - LLVMSetLinkage(global_value, LLVMExternalLinkage); + LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage)); maybe_import_dll(g, global_value, GlobalLinkageIdStrong); LLVMSetAlignment(global_value, var->align_bytes); LLVMSetGlobalConstant(global_value, var->gen_is_const); set_global_tls(g, var, global_value); } } else { - bool exported = (var->linkage == VarLinkageExport); + bool exported = (var->linkage != VarLinkageInternal); const char *mangled_name = buf_ptr(get_mangled_name(g, &var->name, exported)); render_const_val(g, var->const_value, mangled_name); render_const_val_global(g, var->const_value, mangled_name); global_value = var->const_value->global_refs->llvm_global; if (exported) { - LLVMSetLinkage(global_value, LLVMExternalLinkage); + LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage)); maybe_export_dll(g, global_value, GlobalLinkageIdStrong); } if (tld_var->section_name) { diff --git a/src/ir.cpp b/src/ir.cpp index d51df52373..5c5893cdd5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13133,6 +13133,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value); } +static VarLinkage global_linkage_to_var_linkage(GlobalLinkageId id) { + switch (id) { + case GlobalLinkageIdStrong: + return VarLinkageExportStrong; + case GlobalLinkageIdWeak: + return VarLinkageExportWeak; + case GlobalLinkageIdLinkOnce: + return VarLinkageExportLinkOnce; + case GlobalLinkageIdInternal: + return VarLinkageInternal; + } + zig_unreachable(); +} + static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { IrInstruction *name = instruction->name->child; Buf *symbol_name = ir_resolve_str(ira, name); @@ -13161,6 +13175,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); } + bool want_var_export = false; switch (target->value.type->id) { case ZigTypeIdInvalid: case ZigTypeIdUnreachable: @@ -13196,6 +13211,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio ErrorMsg *msg = ir_add_error(ira, target, buf_sprintf("exported struct value must be declared extern")); add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); + } else { + want_var_export = true; } break; case ZigTypeIdUnion: @@ -13203,6 +13220,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio ErrorMsg *msg = ir_add_error(ira, target, buf_sprintf("exported union value must be declared extern")); add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); + } else { + want_var_export = true; } break; case ZigTypeIdEnum: @@ -13210,6 +13229,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio ErrorMsg *msg = ir_add_error(ira, target, buf_sprintf("exported enum value must be declared extern")); add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); + } else { + want_var_export = true; } break; case ZigTypeIdMetaType: { @@ -13299,6 +13320,16 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio break; } + // TODO audit the various ways to use @export + if (want_var_export && target->id == IrInstructionIdLoadPtr) { + IrInstructionLoadPtr *load_ptr = reinterpret_cast<IrInstructionLoadPtr *>(target); + if (load_ptr->ptr->id == IrInstructionIdVarPtr) { + IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr); + ZigVar *var = var_ptr->var; + var->linkage = global_linkage_to_var_linkage(global_linkage_id); + } + } + return ir_const_void(ira, &instruction->base); } @@ -13586,9 +13617,16 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, if (var->var_type == nullptr || type_is_invalid(var->var_type)) return ira->codegen->invalid_instruction; + ConstExprValue *mem_slot = nullptr; + bool comptime_var_mem = ir_get_var_is_comptime(var); + bool linkage_makes_it_runtime = var->linkage == VarLinkageExternal; + bool is_const = var->src_is_const; + bool is_volatile = false; + + if (linkage_makes_it_runtime) + goto no_mem_slot; - ConstExprValue *mem_slot = nullptr; if (var->const_value->special == ConstValSpecialStatic) { mem_slot = var->const_value; } else { @@ -13602,8 +13640,6 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, } } - bool is_const = var->src_is_const; - bool is_volatile = false; if (mem_slot != nullptr) { switch (mem_slot->special) { case ConstValSpecialRuntime: @@ -20679,6 +20715,13 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); return ira->codegen->invalid_instruction; } + uint32_t src_align_bytes; + if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) + return ira->codegen->invalid_instruction; + + uint32_t dest_align_bytes; + if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) + return ira->codegen->invalid_instruction; if (instr_is_comptime(ptr)) { bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); @@ -20701,16 +20744,15 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ IrInstruction *result = ir_const(ira, source_instr, dest_type); copy_const_val(&result->value, val, false); result->value.type = dest_type; - return result; - } - uint32_t src_align_bytes; - if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) - return ira->codegen->invalid_instruction; + // Keep the bigger alignment, it can only help- + // unless the target is zero bits. + if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { + result = ir_align_cast(ira, result, src_align_bytes, false); + } - uint32_t dest_align_bytes; - if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) - return ira->codegen->invalid_instruction; + return result; + } if (dest_align_bytes > src_align_bytes) { ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); diff --git a/src/link.cpp b/src/link.cpp index 956e5b6bfc..f6f0c0ffcd 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -899,7 +899,11 @@ static void construct_linker_job_macho(LinkJob *lj) { lj->args.append("-ios_simulator_version_min"); break; } - lj->args.append(buf_ptr(buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro))); + Buf *version_string = buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro); + lj->args.append(buf_ptr(version_string)); + + lj->args.append("-sdk_version"); + lj->args.append(buf_ptr(version_string)); if (g->out_type == OutTypeExe) { @@ -920,7 +924,9 @@ static void construct_linker_job_macho(LinkJob *lj) { add_rpath(lj, &g->output_file_path); if (shared) { - lj->args.append("-headerpad_max_install_names"); + if (g->system_linker_hack) { + lj->args.append("-headerpad_max_install_names"); + } } else if (g->is_static) { lj->args.append("-lcrt0.o"); } else { |
