authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-15 10:34:04-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-15 10:34:04-04:00
log60025a37045835c8bbf914eccdbeba6d6e2c275f
tree38282635e1f5aa5be22cf96e6b8cddbb72e971f4
parentacf16b5fb34e3ce985df16cba1be1455492e4564
parent7c5ceb0c4cdf5fafadd92b13048bc9878554abc4
signaturelock-open Commit is signed but in an unrecognized format.

Merge remote-tracking branch 'origin/master' into copy-elision-3


13 files changed, 121 insertions(+), 114 deletions(-)

doc/langref.html.in+2-2
...@@ -266,7 +266,7 @@ const Timestamp = struct {...@@ -266,7 +266,7 @@ const Timestamp = struct {
266 {#code_end#}266 {#code_end#}
267 <p>267 <p>
268 Doc comments are only allowed in certain places; eventually, it will268 Doc comments are only allowed in certain places; eventually, it will
269 become a compile error have a doc comment in an unexpected place, such as269 become a compile error to have a doc comment in an unexpected place, such as
270 in the middle of an expression, or just before a non-doc comment.270 in the middle of an expression, or just before a non-doc comment.
271 </p>271 </p>
272 {#header_close#}272 {#header_close#}
...@@ -6648,7 +6648,7 @@ test "main" {...@@ -6648,7 +6648,7 @@ test "main" {
6648 {#header_close#}6648 {#header_close#}
66496649
6650 {#header_open|@export#}6650 {#header_open|@export#}
6651 <pre>{#syntax#}@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8{#endsyntax#}</pre>6651 <pre>{#syntax#}@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) void{#endsyntax#}</pre>
6652 <p>6652 <p>
6653 Creates a symbol in the output object file.6653 Creates a symbol in the output object file.
6654 </p>6654 </p>
src/all_types.hpp+4-11
...@@ -1340,7 +1340,7 @@ enum FnInline {...@@ -1340,7 +1340,7 @@ enum FnInline {
1340 FnInlineNever,1340 FnInlineNever,
1341};1341};
13421342
1343struct FnExport {1343struct GlobalExport {
1344 Buf name;1344 Buf name;
1345 GlobalLinkageId linkage;1345 GlobalLinkageId linkage;
1346};1346};
...@@ -1378,7 +1378,7 @@ struct ZigFn {...@@ -1378,7 +1378,7 @@ struct ZigFn {
13781378
1379 AstNode *set_cold_node;1379 AstNode *set_cold_node;
13801380
1381 ZigList<FnExport> export_list;1381 ZigList<GlobalExport> export_list;
13821382
1383 LLVMValueRef valgrind_client_request_array;1383 LLVMValueRef valgrind_client_request_array;
13841384
...@@ -1902,14 +1902,6 @@ struct CodeGen {...@@ -1902,14 +1902,6 @@ struct CodeGen {
1902 size_t clang_argv_len;1902 size_t clang_argv_len;
1903};1903};
19041904
1905enum VarLinkage {
1906 VarLinkageInternal,
1907 VarLinkageExportStrong,
1908 VarLinkageExportWeak,
1909 VarLinkageExportLinkOnce,
1910 VarLinkageExternal,
1911};
1912
1913struct ZigVar {1905struct ZigVar {
1914 Buf name;1906 Buf name;
1915 ConstExprValue *const_value;1907 ConstExprValue *const_value;
...@@ -1932,8 +1924,9 @@ struct ZigVar {...@@ -1932,8 +1924,9 @@ struct ZigVar {
1932 // this pointer to the redefined variable.1924 // this pointer to the redefined variable.
1933 ZigVar *next_var;1925 ZigVar *next_var;
19341926
1927 ZigList<GlobalExport> export_list;
1928
1935 uint32_t align_bytes;1929 uint32_t align_bytes;
1936 VarLinkage linkage;
19371930
1938 bool shadowable;1931 bool shadowable;
1939 bool src_is_const;1932 bool src_is_const;
src/analyze.cpp+17-24
...@@ -2718,6 +2718,13 @@ ZigType *get_test_fn_type(CodeGen *g) {...@@ -2718,6 +2718,13 @@ ZigType *get_test_fn_type(CodeGen *g) {
2718 return g->test_fn_type;2718 return g->test_fn_type;
2719}2719}
27202720
2721void add_var_export(CodeGen *g, ZigVar *var, Buf *symbol_name, GlobalLinkageId linkage) {
2722 GlobalExport *global_export = var->export_list.add_one();
2723 memset(global_export, 0, sizeof(GlobalExport));
2724 buf_init_from_buf(&global_export->name, symbol_name);
2725 global_export->linkage = linkage;
2726}
2727
2721void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc) {2728void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc) {
2722 if (ccc) {2729 if (ccc) {
2723 if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {2730 if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {
...@@ -2737,8 +2744,8 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi...@@ -2737,8 +2744,8 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi
2737 }2744 }
2738 }2745 }
27392746
2740 FnExport *fn_export = fn_table_entry->export_list.add_one();2747 GlobalExport *fn_export = fn_table_entry->export_list.add_one();
2741 memset(fn_export, 0, sizeof(FnExport));2748 memset(fn_export, 0, sizeof(GlobalExport));
2742 buf_init_from_buf(&fn_export->name, symbol_name);2749 buf_init_from_buf(&fn_export->name, symbol_name);
2743 fn_export->linkage = linkage;2750 fn_export->linkage = linkage;
2744}2751}
...@@ -2786,12 +2793,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -2786,12 +2793,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
2786 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);2793 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
27872794
2788 if (fn_proto->section_expr != nullptr) {2795 if (fn_proto->section_expr != nullptr) {
2789 if (fn_table_entry->body_node == nullptr) {2796 analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
2790 add_node_error(g, fn_proto->section_expr,
2791 buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_table_entry->symbol_name)));
2792 } else {
2793 analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
2794 }
2795 }2797 }
27962798
2797 if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) {2799 if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) {
...@@ -3200,15 +3202,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3200,15 +3202,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
32003202
3201 assert(!is_export || !is_extern);3203 assert(!is_export || !is_extern);
32023204
3203 VarLinkage linkage;
3204 if (is_export) {
3205 linkage = VarLinkageExportStrong;
3206 } else if (is_extern) {
3207 linkage = VarLinkageExternal;
3208 } else {
3209 linkage = VarLinkageInternal;
3210 }
3211
3212 ConstExprValue *init_value = nullptr;3205 ConstExprValue *init_value = nullptr;
32133206
3214 // TODO more validation for types that can't be used for export/extern variables3207 // TODO more validation for types that can't be used for export/extern variables
...@@ -3223,7 +3216,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3223,7 +3216,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3223 if (implicit_type->id == ZigTypeIdUnreachable) {3216 if (implicit_type->id == ZigTypeIdUnreachable) {
3224 add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable"));3217 add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable"));
3225 implicit_type = g->builtin_types.entry_invalid;3218 implicit_type = g->builtin_types.entry_invalid;
3226 } else if ((!is_const || linkage == VarLinkageExternal) &&3219 } else if ((!is_const || is_extern) &&
3227 (implicit_type->id == ZigTypeIdComptimeFloat ||3220 (implicit_type->id == ZigTypeIdComptimeFloat ||
3228 implicit_type->id == ZigTypeIdComptimeInt ||3221 implicit_type->id == ZigTypeIdComptimeInt ||
3229 implicit_type->id == ZigTypeIdEnumLiteral))3222 implicit_type->id == ZigTypeIdEnumLiteral))
...@@ -3238,7 +3231,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3238,7 +3231,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3238 implicit_type = g->builtin_types.entry_invalid;3231 implicit_type = g->builtin_types.entry_invalid;
3239 }3232 }
3240 assert(implicit_type->id == ZigTypeIdInvalid || init_value->special != ConstValSpecialRuntime);3233 assert(implicit_type->id == ZigTypeIdInvalid || init_value->special != ConstValSpecialRuntime);
3241 } else if (linkage != VarLinkageExternal) {3234 } else if (!is_extern) {
3242 add_node_error(g, source_node, buf_sprintf("variables must be initialized"));3235 add_node_error(g, source_node, buf_sprintf("variables must be initialized"));
3243 implicit_type = g->builtin_types.entry_invalid;3236 implicit_type = g->builtin_types.entry_invalid;
3244 }3237 }
...@@ -3250,7 +3243,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3250,7 +3243,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
32503243
3251 tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol,3244 tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol,
3252 is_const, init_val, &tld_var->base, type);3245 is_const, init_val, &tld_var->base, type);
3253 tld_var->var->linkage = linkage;
3254 tld_var->var->is_thread_local = is_thread_local;3246 tld_var->var->is_thread_local = is_thread_local;
32553247
3256 if (implicit_type != nullptr && type_is_invalid(implicit_type)) {3248 if (implicit_type != nullptr && type_is_invalid(implicit_type)) {
...@@ -3264,10 +3256,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3264,10 +3256,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3264 }3256 }
32653257
3266 if (var_decl->section_expr != nullptr) {3258 if (var_decl->section_expr != nullptr) {
3267 if (var_decl->is_extern) {3259 if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
3268 add_node_error(g, var_decl->section_expr,
3269 buf_sprintf("cannot set section of external variable '%s'", buf_ptr(var_decl->symbol)));
3270 } else if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
3271 tld_var->section_name = nullptr;3260 tld_var->section_name = nullptr;
3272 }3261 }
3273 }3262 }
...@@ -3276,6 +3265,10 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3276,6 +3265,10 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3276 add_node_error(g, source_node, buf_sprintf("threadlocal variable cannot be constant"));3265 add_node_error(g, source_node, buf_sprintf("threadlocal variable cannot be constant"));
3277 }3266 }
32783267
3268 if (is_export) {
3269 add_var_export(g, tld_var->var, &tld_var->var->name, GlobalLinkageIdStrong);
3270 }
3271
3279 g->global_vars.append(tld_var);3272 g->global_vars.append(tld_var);
3280}3273}
32813274
src/analyze.hpp+1
...@@ -199,6 +199,7 @@ ZigPackage *new_anonymous_package(void);...@@ -199,6 +199,7 @@ ZigPackage *new_anonymous_package(void);
199199
200Buf *const_value_to_buffer(ConstExprValue *const_val);200Buf *const_value_to_buffer(ConstExprValue *const_val);
201void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc);201void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc);
202void add_var_export(CodeGen *g, ZigVar *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage);
202203
203204
204ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);205ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
src/codegen.cpp+48-30
...@@ -203,6 +203,10 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget...@@ -203,6 +203,10 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
203 get_target_triple(&g->triple_str, g->zig_target);203 get_target_triple(&g->triple_str, g->zig_target);
204 g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8;204 g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8;
205205
206 if (!target_has_debug_info(g->zig_target)) {
207 g->strip_debug_symbols = true;
208 }
209
206 return g;210 return g;
207}211}
208212
...@@ -248,6 +252,9 @@ void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) {...@@ -248,6 +252,9 @@ void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) {
248252
249void codegen_set_strip(CodeGen *g, bool strip) {253void codegen_set_strip(CodeGen *g, bool strip) {
250 g->strip_debug_symbols = strip;254 g->strip_debug_symbols = strip;
255 if (!target_has_debug_info(g->zig_target)) {
256 g->strip_debug_symbols = true;
257 }
251}258}
252259
253void codegen_set_out_name(CodeGen *g, Buf *out_name) {260void codegen_set_out_name(CodeGen *g, Buf *out_name) {
...@@ -475,7 +482,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -475,7 +482,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
475 symbol_name = get_mangled_name(g, unmangled_name, false);482 symbol_name = get_mangled_name(g, unmangled_name, false);
476 linkage = GlobalLinkageIdInternal;483 linkage = GlobalLinkageIdInternal;
477 } else {484 } else {
478 FnExport *fn_export = &fn_table_entry->export_list.items[0];485 GlobalExport *fn_export = &fn_table_entry->export_list.items[0];
479 symbol_name = &fn_export->name;486 symbol_name = &fn_export->name;
480 linkage = fn_export->linkage;487 linkage = fn_export->linkage;
481 }488 }
...@@ -529,7 +536,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -529,7 +536,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
529 }536 }
530537
531 for (size_t i = 1; i < fn_table_entry->export_list.length; i += 1) {538 for (size_t i = 1; i < fn_table_entry->export_list.length; i += 1) {
532 FnExport *fn_export = &fn_table_entry->export_list.items[i];539 GlobalExport *fn_export = &fn_table_entry->export_list.items[i];
533 LLVMAddAlias(g->module, LLVMTypeOf(fn_table_entry->llvm_value),540 LLVMAddAlias(g->module, LLVMTypeOf(fn_table_entry->llvm_value),
534 fn_table_entry->llvm_value, buf_ptr(&fn_export->name));541 fn_table_entry->llvm_value, buf_ptr(&fn_export->name));
535 }542 }
...@@ -6633,27 +6640,14 @@ static void validate_inline_fns(CodeGen *g) {...@@ -6633,27 +6640,14 @@ static void validate_inline_fns(CodeGen *g) {
6633}6640}
66346641
6635static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) {6642static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) {
6636 if (var->is_thread_local && (!g->is_single_threaded || var->linkage != VarLinkageInternal)) {6643 bool is_extern = var->decl_node->data.variable_declaration.is_extern;
6644 bool is_export = var->decl_node->data.variable_declaration.is_export;
6645 bool is_internal_linkage = !is_extern && !is_export;
6646 if (var->is_thread_local && (!g->is_single_threaded || !is_internal_linkage)) {
6637 LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);6647 LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);
6638 }6648 }
6639}6649}
66406650
6641static LLVMLinkage var_linkage_to_llvm(VarLinkage var_linkage) {
6642 switch (var_linkage) {
6643 case VarLinkageInternal:
6644 return LLVMInternalLinkage;
6645 case VarLinkageExportStrong:
6646 return LLVMExternalLinkage;
6647 case VarLinkageExportWeak:
6648 return LLVMWeakODRLinkage;
6649 case VarLinkageExportLinkOnce:
6650 return LLVMLinkOnceODRLinkage;
6651 case VarLinkageExternal:
6652 return LLVMExternalLinkage;
6653 }
6654 zig_unreachable();
6655}
6656
6657static void do_code_gen(CodeGen *g) {6651static void do_code_gen(CodeGen *g) {
6658 assert(!g->errors.length);6652 assert(!g->errors.length);
66596653
...@@ -6703,31 +6697,48 @@ static void do_code_gen(CodeGen *g) {...@@ -6703,31 +6697,48 @@ static void do_code_gen(CodeGen *g) {
67036697
6704 assert(var->decl_node);6698 assert(var->decl_node);
67056699
6700 GlobalLinkageId linkage;
6701 Buf *unmangled_name = &var->name;
6702 Buf *symbol_name;
6703 if (var->export_list.length == 0) {
6704 if (var->decl_node->data.variable_declaration.is_extern) {
6705 symbol_name = unmangled_name;
6706 linkage = GlobalLinkageIdStrong;
6707 } else {
6708 symbol_name = get_mangled_name(g, unmangled_name, false);
6709 linkage = GlobalLinkageIdInternal;
6710 }
6711 } else {
6712 GlobalExport *global_export = &var->export_list.items[0];
6713 symbol_name = &global_export->name;
6714 linkage = global_export->linkage;
6715 }
6716
6706 LLVMValueRef global_value;6717 LLVMValueRef global_value;
6707 if (var->linkage == VarLinkageExternal) {6718 bool externally_initialized = var->decl_node->data.variable_declaration.expr == nullptr;
6708 LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, buf_ptr(&var->name));6719 if (externally_initialized) {
6720 LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, buf_ptr(symbol_name));
6709 if (existing_llvm_var) {6721 if (existing_llvm_var) {
6710 global_value = LLVMConstBitCast(existing_llvm_var,6722 global_value = LLVMConstBitCast(existing_llvm_var,
6711 LLVMPointerType(get_llvm_type(g, var->var_type), 0));6723 LLVMPointerType(get_llvm_type(g, var->var_type), 0));
6712 } else {6724 } else {
6713 global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), buf_ptr(&var->name));6725 global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), buf_ptr(symbol_name));
6714 // TODO debug info for the extern variable6726 // TODO debug info for the extern variable
67156727
6716 LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage));6728 LLVMSetLinkage(global_value, to_llvm_linkage(linkage));
6717 maybe_import_dll(g, global_value, GlobalLinkageIdStrong);6729 maybe_import_dll(g, global_value, GlobalLinkageIdStrong);
6718 LLVMSetAlignment(global_value, var->align_bytes);6730 LLVMSetAlignment(global_value, var->align_bytes);
6719 LLVMSetGlobalConstant(global_value, var->gen_is_const);6731 LLVMSetGlobalConstant(global_value, var->gen_is_const);
6720 set_global_tls(g, var, global_value);6732 set_global_tls(g, var, global_value);
6721 }6733 }
6722 } else {6734 } else {
6723 bool exported = (var->linkage != VarLinkageInternal);6735 bool exported = (linkage != GlobalLinkageIdInternal);
6724 const char *mangled_name = buf_ptr(get_mangled_name(g, &var->name, exported));6736 render_const_val(g, var->const_value, buf_ptr(symbol_name));
6725 render_const_val(g, var->const_value, mangled_name);6737 render_const_val_global(g, var->const_value, buf_ptr(symbol_name));
6726 render_const_val_global(g, var->const_value, mangled_name);
6727 global_value = var->const_value->global_refs->llvm_global;6738 global_value = var->const_value->global_refs->llvm_global;
67286739
6729 if (exported) {6740 if (exported) {
6730 LLVMSetLinkage(global_value, var_linkage_to_llvm(var->linkage));6741 LLVMSetLinkage(global_value, to_llvm_linkage(linkage));
6731 maybe_export_dll(g, global_value, GlobalLinkageIdStrong);6742 maybe_export_dll(g, global_value, GlobalLinkageIdStrong);
6732 }6743 }
6733 if (tld_var->section_name) {6744 if (tld_var->section_name) {
...@@ -6747,6 +6758,11 @@ static void do_code_gen(CodeGen *g) {...@@ -6747,6 +6758,11 @@ static void do_code_gen(CodeGen *g) {
6747 }6758 }
67486759
6749 var->value_ref = global_value;6760 var->value_ref = global_value;
6761
6762 for (size_t export_i = 1; export_i < var->export_list.length; export_i += 1) {
6763 GlobalExport *global_export = &var->export_list.items[export_i];
6764 LLVMAddAlias(g->module, LLVMTypeOf(var->value_ref), var->value_ref, buf_ptr(&global_export->name));
6765 }
6750 }6766 }
67516767
6752 // Generate function definitions.6768 // Generate function definitions.
...@@ -7406,7 +7422,7 @@ static bool detect_single_threaded(CodeGen *g) {...@@ -7406,7 +7422,7 @@ static bool detect_single_threaded(CodeGen *g) {
7406}7422}
74077423
7408static bool detect_err_ret_tracing(CodeGen *g) {7424static bool detect_err_ret_tracing(CodeGen *g) {
7409 return !target_is_wasm(g->zig_target) &&7425 return !g->strip_debug_symbols &&
7410 g->build_mode != BuildModeFastRelease &&7426 g->build_mode != BuildModeFastRelease &&
7411 g->build_mode != BuildModeSmallRelease;7427 g->build_mode != BuildModeSmallRelease;
7412}7428}
...@@ -7840,6 +7856,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7840,6 +7856,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7840 buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing));7856 buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing));
7841 buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));7857 buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));
7842 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));7858 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
7859 buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
78437860
7844 {7861 {
7845 TargetSubsystem detected_subsystem = detect_subsystem(g);7862 TargetSubsystem detected_subsystem = detect_subsystem(g);
...@@ -7880,6 +7897,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {...@@ -7880,6 +7897,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
7880 // Only a few things affect builtin.zig7897 // Only a few things affect builtin.zig
7881 cache_buf(&cache_hash, compiler_id);7898 cache_buf(&cache_hash, compiler_id);
7882 cache_int(&cache_hash, g->build_mode);7899 cache_int(&cache_hash, g->build_mode);
7900 cache_bool(&cache_hash, g->strip_debug_symbols);
7883 cache_bool(&cache_hash, g->is_test_build);7901 cache_bool(&cache_hash, g->is_test_build);
7884 cache_bool(&cache_hash, g->is_single_threaded);7902 cache_bool(&cache_hash, g->is_single_threaded);
7885 cache_int(&cache_hash, g->zig_target->is_native);7903 cache_int(&cache_hash, g->zig_target->is_native);
...@@ -9069,7 +9087,7 @@ static void gen_h_file(CodeGen *g) {...@@ -9069,7 +9087,7 @@ static void gen_h_file(CodeGen *g) {
9069 if (fn_table_entry->export_list.length == 0) {9087 if (fn_table_entry->export_list.length == 0) {
9070 symbol_name = &fn_table_entry->symbol_name;9088 symbol_name = &fn_table_entry->symbol_name;
9071 } else {9089 } else {
9072 FnExport *fn_export = &fn_table_entry->export_list.items[0];9090 GlobalExport *fn_export = &fn_table_entry->export_list.items[0];
9073 symbol_name = &fn_export->name;9091 symbol_name = &fn_export->name;
9074 }9092 }
90759093
src/ir.cpp+11-17
...@@ -14448,20 +14448,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -14448,20 +14448,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
14448 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr);14448 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr);
14449}14449}
1445014450
14451static VarLinkage global_linkage_to_var_linkage(GlobalLinkageId id) {
14452 switch (id) {
14453 case GlobalLinkageIdStrong:
14454 return VarLinkageExportStrong;
14455 case GlobalLinkageIdWeak:
14456 return VarLinkageExportWeak;
14457 case GlobalLinkageIdLinkOnce:
14458 return VarLinkageExportLinkOnce;
14459 case GlobalLinkageIdInternal:
14460 return VarLinkageInternal;
14461 }
14462 zig_unreachable();
14463}
14464
14465static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) {14451static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) {
14466 IrInstruction *name = instruction->name->child;14452 IrInstruction *name = instruction->name->child;
14467 Buf *symbol_name = ir_resolve_str(ira, name);14453 Buf *symbol_name = ir_resolve_str(ira, name);
...@@ -14558,6 +14544,15 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -14558,6 +14544,15 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
14558 want_var_export = true;14544 want_var_export = true;
14559 }14545 }
14560 break;14546 break;
14547 case ZigTypeIdArray:
14548 if (!type_allowed_in_extern(ira->codegen, target->value.type->data.array.child_type)) {
14549 ir_add_error(ira, target,
14550 buf_sprintf("array element type '%s' not extern-compatible",
14551 buf_ptr(&target->value.type->data.array.child_type->name)));
14552 } else {
14553 want_var_export = true;
14554 }
14555 break;
14561 case ZigTypeIdMetaType: {14556 case ZigTypeIdMetaType: {
14562 ZigType *type_value = target->value.data.x_type;14557 ZigType *type_value = target->value.data.x_type;
14563 switch (type_value->id) {14558 switch (type_value->id) {
...@@ -14625,7 +14620,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -14625,7 +14620,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
14625 case ZigTypeIdInt:14620 case ZigTypeIdInt:
14626 case ZigTypeIdFloat:14621 case ZigTypeIdFloat:
14627 case ZigTypeIdPointer:14622 case ZigTypeIdPointer:
14628 case ZigTypeIdArray:
14629 case ZigTypeIdComptimeFloat:14623 case ZigTypeIdComptimeFloat:
14630 case ZigTypeIdComptimeInt:14624 case ZigTypeIdComptimeInt:
14631 case ZigTypeIdUndefined:14625 case ZigTypeIdUndefined:
...@@ -14651,7 +14645,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -14651,7 +14645,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
14651 if (load_ptr->ptr->id == IrInstructionIdVarPtr) {14645 if (load_ptr->ptr->id == IrInstructionIdVarPtr) {
14652 IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr);14646 IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr);
14653 ZigVar *var = var_ptr->var;14647 ZigVar *var = var_ptr->var;
14654 var->linkage = global_linkage_to_var_linkage(global_linkage_id);14648 add_var_export(ira->codegen, var, symbol_name, global_linkage_id);
14655 }14649 }
14656 }14650 }
1465714651
...@@ -15244,7 +15238,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,...@@ -15244,7 +15238,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
15244 ConstExprValue *mem_slot = nullptr;15238 ConstExprValue *mem_slot = nullptr;
1524515239
15246 bool comptime_var_mem = ir_get_var_is_comptime(var);15240 bool comptime_var_mem = ir_get_var_is_comptime(var);
15247 bool linkage_makes_it_runtime = var->linkage == VarLinkageExternal;15241 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern;
15248 bool is_const = var->src_is_const;15242 bool is_const = var->src_is_const;
15249 bool is_volatile = false;15243 bool is_volatile = false;
1525015244
src/main.cpp+1
...@@ -954,6 +954,7 @@ int main(int argc, char **argv) {...@@ -954,6 +954,7 @@ int main(int argc, char **argv) {
954 case CmdBuiltin: {954 case CmdBuiltin: {
955 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,955 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
956 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);956 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);
957 codegen_set_strip(g, strip);
957 g->subsystem = subsystem;958 g->subsystem = subsystem;
958 g->valgrind_support = valgrind_support;959 g->valgrind_support = valgrind_support;
959 g->want_pic = want_pic;960 g->want_pic = want_pic;
src/target.cpp+4
...@@ -1585,3 +1585,7 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {...@@ -1585,3 +1585,7 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {
1585 out_target->vendor = ZigLLVM_UnknownVendor;1585 out_target->vendor = ZigLLVM_UnknownVendor;
1586 out_target->is_native = false;1586 out_target->is_native = false;
1587}1587}
1588
1589bool target_has_debug_info(const ZigTarget *target) {
1590 return !target_is_wasm(target);
1591}
src/target.hpp+1
...@@ -177,6 +177,7 @@ bool target_is_musl(const ZigTarget *target);...@@ -177,6 +177,7 @@ bool target_is_musl(const ZigTarget *target);
177bool target_is_wasm(const ZigTarget *target);177bool target_is_wasm(const ZigTarget *target);
178bool target_is_single_threaded(const ZigTarget *target);178bool target_is_single_threaded(const ZigTarget *target);
179bool target_supports_stack_probing(const ZigTarget *target);179bool target_supports_stack_probing(const ZigTarget *target);
180bool target_has_debug_info(const ZigTarget *target);
180181
181uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);182uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
182183
std/debug.zig+7-4
...@@ -85,8 +85,8 @@ fn wantTtyColor() bool {...@@ -85,8 +85,8 @@ fn wantTtyColor() bool {
85/// TODO multithreaded awareness85/// TODO multithreaded awareness
86pub fn dumpCurrentStackTrace(start_addr: ?usize) void {86pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
87 const stderr = getStderrStream() catch return;87 const stderr = getStderrStream() catch return;
88 if (os.wasi.is_the_target) {88 if (builtin.strip_debug_info) {
89 stderr.print("Unable to dump stack trace: unimplemented on WASI\n") catch return;89 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
90 return;90 return;
91 }91 }
92 const debug_info = getSelfDebugInfo() catch |err| {92 const debug_info = getSelfDebugInfo() catch |err| {
...@@ -151,8 +151,8 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace...@@ -151,8 +151,8 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace
151/// TODO multithreaded awareness151/// TODO multithreaded awareness
152pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {152pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
153 const stderr = getStderrStream() catch return;153 const stderr = getStderrStream() catch return;
154 if (os.wasi.is_the_target) {154 if (builtin.strip_debug_info) {
155 stderr.print("Unable to dump stack trace: unimplemented on WASI\n") catch return;155 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
156 return;156 return;
157 }157 }
158 const debug_info = getSelfDebugInfo() catch |err| {158 const debug_info = getSelfDebugInfo() catch |err| {
...@@ -223,6 +223,7 @@ pub fn writeStackTrace(...@@ -223,6 +223,7 @@ pub fn writeStackTrace(
223 debug_info: *DebugInfo,223 debug_info: *DebugInfo,
224 tty_color: bool,224 tty_color: bool,
225) !void {225) !void {
226 if (builtin.strip_debug_info) return error.MissingDebugInfo;
226 var frame_index: usize = 0;227 var frame_index: usize = 0;
227 var frames_left: usize = std.math.min(stack_trace.index, stack_trace.instruction_addresses.len);228 var frames_left: usize = std.math.min(stack_trace.index, stack_trace.instruction_addresses.len);
228229
...@@ -783,6 +784,8 @@ pub const OpenSelfDebugInfoError = error{...@@ -783,6 +784,8 @@ pub const OpenSelfDebugInfoError = error{
783};784};
784785
785pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {786pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
787 if (builtin.strip_debug_info)
788 return error.MissingDebugInfo;
786 if (windows.is_the_target) {789 if (windows.is_the_target) {
787 return openSelfDebugInfoWindows(allocator);790 return openSelfDebugInfoWindows(allocator);
788 }791 }
std/hash_map.zig+24-5
...@@ -183,6 +183,11 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -183,6 +183,11 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
183 return putAssumeCapacity(self, key, value);183 return putAssumeCapacity(self, key, value);
184 }184 }
185185
186 /// Calls put() and asserts that no kv pair is clobbered.
187 pub fn putNoClobber(self: *Self, key: K, value: V) !void {
188 assert((try self.put(key, value)) == null);
189 }
190
186 pub fn putAssumeCapacity(self: *Self, key: K, value: V) ?KV {191 pub fn putAssumeCapacity(self: *Self, key: K, value: V) ?KV {
187 assert(self.count() < self.entries.len);192 assert(self.count() < self.entries.len);
188 self.incrementModificationCount();193 self.incrementModificationCount();
...@@ -199,10 +204,15 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -199,10 +204,15 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
199 return hm.internalGet(key);204 return hm.internalGet(key);
200 }205 }
201206
207 pub fn getValue(hm: *const Self, key: K) ?V {
208 return if (hm.get(key)) |kv| kv.value else null;
209 }
210
202 pub fn contains(hm: *const Self, key: K) bool {211 pub fn contains(hm: *const Self, key: K) bool {
203 return hm.get(key) != null;212 return hm.get(key) != null;
204 }213 }
205214
215 /// Returns any kv pair that was removed.
206 pub fn remove(hm: *Self, key: K) ?KV {216 pub fn remove(hm: *Self, key: K) ?KV {
207 if (hm.entries.len == 0) return null;217 if (hm.entries.len == 0) return null;
208 hm.incrementModificationCount();218 hm.incrementModificationCount();
...@@ -236,6 +246,11 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -236,6 +246,11 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
236 return null;246 return null;
237 }247 }
238248
249 /// Calls remove(), asserts that a kv pair is removed, and discards it.
250 pub fn removeAssertDiscard(hm: *Self, key: K) void {
251 assert(hm.remove(key) != null);
252 }
253
239 pub fn iterator(hm: *const Self) Iterator {254 pub fn iterator(hm: *const Self) Iterator {
240 return Iterator{255 return Iterator{
241 .hm = hm,256 .hm = hm,
...@@ -250,7 +265,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -250,7 +265,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
250 try other.initCapacity(self.entries.len);265 try other.initCapacity(self.entries.len);
251 var it = self.iterator();266 var it = self.iterator();
252 while (it.next()) |entry| {267 while (it.next()) |entry| {
253 assert((try other.put(entry.key, entry.value)) == null);268 try other.putNoClobber(entry.key, entry.value);
254 }269 }
255 return other;270 return other;
256 }271 }
...@@ -392,8 +407,8 @@ test "basic hash map usage" {...@@ -392,8 +407,8 @@ test "basic hash map usage" {
392 testing.expect((try map.put(2, 22)) == null);407 testing.expect((try map.put(2, 22)) == null);
393 testing.expect((try map.put(3, 33)) == null);408 testing.expect((try map.put(3, 33)) == null);
394 testing.expect((try map.put(4, 44)) == null);409 testing.expect((try map.put(4, 44)) == null);
395 testing.expect((try map.put(5, 55)) == null);
396410
411 try map.putNoClobber(5, 55);
397 testing.expect((try map.put(5, 66)).?.value == 55);412 testing.expect((try map.put(5, 66)).?.value == 55);
398 testing.expect((try map.put(5, 55)).?.value == 66);413 testing.expect((try map.put(5, 55)).?.value == 66);
399414
...@@ -416,12 +431,16 @@ test "basic hash map usage" {...@@ -416,12 +431,16 @@ test "basic hash map usage" {
416431
417 testing.expect(map.contains(2));432 testing.expect(map.contains(2));
418 testing.expect(map.get(2).?.value == 22);433 testing.expect(map.get(2).?.value == 22);
434 testing.expect(map.getValue(2).? == 22);
419435
420 const rmv1 = map.remove(2);436 const rmv1 = map.remove(2);
421 testing.expect(rmv1.?.key == 2);437 testing.expect(rmv1.?.key == 2);
422 testing.expect(rmv1.?.value == 22);438 testing.expect(rmv1.?.value == 22);
423 testing.expect(map.remove(2) == null);439 testing.expect(map.remove(2) == null);
424 testing.expect(map.get(2) == null);440 testing.expect(map.get(2) == null);
441 testing.expect(map.getValue(2) == null);
442
443 map.removeAssertDiscard(3);
425}444}
426445
427test "iterator hash map" {446test "iterator hash map" {
...@@ -431,9 +450,9 @@ test "iterator hash map" {...@@ -431,9 +450,9 @@ test "iterator hash map" {
431 var reset_map = AutoHashMap(i32, i32).init(&direct_allocator.allocator);450 var reset_map = AutoHashMap(i32, i32).init(&direct_allocator.allocator);
432 defer reset_map.deinit();451 defer reset_map.deinit();
433452
434 testing.expect((try reset_map.put(1, 11)) == null);453 try reset_map.putNoClobber(1, 11);
435 testing.expect((try reset_map.put(2, 22)) == null);454 try reset_map.putNoClobber(2, 22);
436 testing.expect((try reset_map.put(3, 33)) == null);455 try reset_map.putNoClobber(3, 33);
437456
438 var keys = [_]i32{457 var keys = [_]i32{
439 3,458 3,
std/process.zig+1-1
...@@ -388,7 +388,7 @@ pub fn args() ArgIterator {...@@ -388,7 +388,7 @@ pub fn args() ArgIterator {
388}388}
389389
390/// Caller must call argsFree on result.390/// Caller must call argsFree on result.
391pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {391pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {
392 if (builtin.os == .wasi) {392 if (builtin.os == .wasi) {
393 var count: usize = undefined;393 var count: usize = undefined;
394 var buf_size: usize = undefined;394 var buf_size: usize = undefined;
test/compile_errors.zig-20
...@@ -4645,16 +4645,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4645,16 +4645,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4645 "tmp.zig:1:1: note: declared here",4645 "tmp.zig:1:1: note: declared here",
4646 );4646 );
46474647
4648 cases.add(
4649 "setting a section on an extern variable",
4650 \\extern var foo: i32 linksection(".text2");
4651 \\export fn entry() i32 {
4652 \\ return foo;
4653 \\}
4654 ,
4655 "tmp.zig:1:33: error: cannot set section of external variable 'foo'",
4656 );
4657
4658 cases.add(4648 cases.add(
4659 "setting a section on a local variable",4649 "setting a section on a local variable",
4660 \\export fn entry() i32 {4650 \\export fn entry() i32 {
...@@ -4665,16 +4655,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4665,16 +4655,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4665 "tmp.zig:2:30: error: cannot set section of local variable 'foo'",4655 "tmp.zig:2:30: error: cannot set section of local variable 'foo'",
4666 );4656 );
46674657
4668 cases.add(
4669 "setting a section on an extern fn",
4670 \\extern fn foo() linksection(".text2") void;
4671 \\export fn entry() void {
4672 \\ foo();
4673 \\}
4674 ,
4675 "tmp.zig:1:29: error: cannot set section of external function 'foo'",
4676 );
4677
4678 cases.add(4658 cases.add(
4679 "returning address of local variable - simple",4659 "returning address of local variable - simple",
4680 \\export fn foo() *i32 {4660 \\export fn foo() *i32 {