diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-06-14 17:23:24 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-06-14 17:23:24 -0400 |
| commit | f8f054b354088eb9e76d9207972022bc1d3dfc28 (patch) | |
| tree | a45396b18548f911ae88067c98c9c5afd1ad3358 /src/codegen.cpp | |
| parent | 42ea2d0d1c3b8cafdfc9a383cbb1bab274eb0140 (diff) | |
| download | zig-f8f054b354088eb9e76d9207972022bc1d3dfc28.tar.gz zig-f8f054b354088eb9e76d9207972022bc1d3dfc28.zip | |
fix `@export` for arrays not respecting the symbol name
Previously, the symbol name parameter of `@export` would be ignored for
variables, and the variable name would be used for the symbol name.
Now it works as expected.
See #2679
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 12b07ea6bc..bdc8de63d1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -475,7 +475,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { symbol_name = get_mangled_name(g, unmangled_name, false); linkage = GlobalLinkageIdInternal; } else { - FnExport *fn_export = &fn_table_entry->export_list.items[0]; + GlobalExport *fn_export = &fn_table_entry->export_list.items[0]; symbol_name = &fn_export->name; linkage = fn_export->linkage; } @@ -529,7 +529,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { } for (size_t i = 1; i < fn_table_entry->export_list.length; i += 1) { - FnExport *fn_export = &fn_table_entry->export_list.items[i]; + GlobalExport *fn_export = &fn_table_entry->export_list.items[i]; LLVMAddAlias(g->module, LLVMTypeOf(fn_table_entry->llvm_value), fn_table_entry->llvm_value, buf_ptr(&fn_export->name)); } @@ -6691,27 +6691,14 @@ static void validate_inline_fns(CodeGen *g) { } static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { - if (var->is_thread_local && (!g->is_single_threaded || var->linkage != VarLinkageInternal)) { + bool is_extern = var->decl_node->data.variable_declaration.is_extern; + bool is_export = var->decl_node->data.variable_declaration.is_export; + bool is_internal_linkage = !is_extern && !is_export; + if (var->is_thread_local && (!g->is_single_threaded || !is_internal_linkage)) { LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel); } } -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); @@ -6761,31 +6748,48 @@ static void do_code_gen(CodeGen *g) { assert(var->decl_node); + GlobalLinkageId linkage; + Buf *unmangled_name = &var->name; + Buf *symbol_name; + if (var->export_list.length == 0) { + if (var->decl_node->data.variable_declaration.is_extern) { + symbol_name = unmangled_name; + linkage = GlobalLinkageIdStrong; + } else { + symbol_name = get_mangled_name(g, unmangled_name, false); + linkage = GlobalLinkageIdInternal; + } + } else { + GlobalExport *global_export = &var->export_list.items[0]; + symbol_name = &global_export->name; + linkage = global_export->linkage; + } + LLVMValueRef global_value; - if (var->linkage == VarLinkageExternal) { - LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, buf_ptr(&var->name)); + bool externally_initialized = var->decl_node->data.variable_declaration.expr == nullptr; + if (externally_initialized) { + LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, buf_ptr(symbol_name)); if (existing_llvm_var) { global_value = LLVMConstBitCast(existing_llvm_var, LLVMPointerType(get_llvm_type(g, var->var_type), 0)); } else { - global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), buf_ptr(&var->name)); + global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), buf_ptr(symbol_name)); // TODO debug info for the extern variable - LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage)); + LLVMSetLinkage(global_value, to_llvm_linkage(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 != 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); + bool exported = (linkage != GlobalLinkageIdInternal); + render_const_val(g, var->const_value, buf_ptr(symbol_name)); + render_const_val_global(g, var->const_value, buf_ptr(symbol_name)); global_value = var->const_value->global_refs->llvm_global; if (exported) { - LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage)); + LLVMSetLinkage(global_value, to_llvm_linkage(linkage)); maybe_export_dll(g, global_value, GlobalLinkageIdStrong); } if (tld_var->section_name) { @@ -6805,6 +6809,11 @@ static void do_code_gen(CodeGen *g) { } var->value_ref = global_value; + + for (size_t export_i = 1; export_i < var->export_list.length; export_i += 1) { + GlobalExport *global_export = &var->export_list.items[export_i]; + LLVMAddAlias(g->module, LLVMTypeOf(var->value_ref), var->value_ref, buf_ptr(&global_export->name)); + } } // Generate function definitions. @@ -9168,7 +9177,7 @@ static void gen_h_file(CodeGen *g) { if (fn_table_entry->export_list.length == 0) { symbol_name = &fn_table_entry->symbol_name; } else { - FnExport *fn_export = &fn_table_entry->export_list.items[0]; + GlobalExport *fn_export = &fn_table_entry->export_list.items[0]; symbol_name = &fn_export->name; } |
