| author | |
| committer | |
| log | 60025a37045835c8bbf914eccdbeba6d6e2c275f |
| tree | 38282635e1f5aa5be22cf96e6b8cddbb72e971f4 |
| parent | acf16b5fb34e3ce985df16cba1be1455492e4564 |
| parent | 7c5ceb0c4cdf5fafadd92b13048bc9878554abc4 |
| signature | Commit is signed but in an unrecognized format. |
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 will | 268 | 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 as | 269 | 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#} |
| 6649 | 6649 | ||
| 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 | }; |
| 1342 | 1342 | ||
| 1343 | struct FnExport { | 1343 | struct 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 { |
| 1378 | 1378 | ||
| 1379 | AstNode *set_cold_node; | 1379 | AstNode *set_cold_node; |
| 1380 | 1380 | ||
| 1381 | ZigList<FnExport> export_list; | 1381 | ZigList<GlobalExport> export_list; |
| 1382 | 1382 | ||
| 1383 | LLVMValueRef valgrind_client_request_array; | 1383 | LLVMValueRef valgrind_client_request_array; |
| 1384 | 1384 | ||
| ... | @@ -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 | }; |
| 1904 | 1904 | ||
| 1905 | enum VarLinkage { | ||
| 1906 | VarLinkageInternal, | ||
| 1907 | VarLinkageExportStrong, | ||
| 1908 | VarLinkageExportWeak, | ||
| 1909 | VarLinkageExportLinkOnce, | ||
| 1910 | VarLinkageExternal, | ||
| 1911 | }; | ||
| 1912 | |||
| 1913 | struct ZigVar { | 1905 | struct 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; |
| 1934 | 1926 | ||
| 1927 | ZigList<GlobalExport> export_list; | ||
| 1928 | |||
| 1935 | uint32_t align_bytes; | 1929 | uint32_t align_bytes; |
| 1936 | VarLinkage linkage; | ||
| 1937 | 1930 | ||
| 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 | } |
| 2720 | 2720 | ||
| 2721 | void 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 | |||
| 2721 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc) { | 2728 | void 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 | } |
| 2739 | 2746 | ||
| 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); |
| 2787 | 2794 | ||
| 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 | } |
| 2796 | 2798 | ||
| 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) { |
| 3200 | 3202 | ||
| 3201 | assert(!is_export || !is_extern); | 3203 | assert(!is_export || !is_extern); |
| 3202 | 3204 | ||
| 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; |
| 3213 | 3206 | ||
| 3214 | // TODO more validation for types that can't be used for export/extern variables | 3207 | // 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) { |
| 3250 | 3243 | ||
| 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; |
| 3255 | 3247 | ||
| 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 | } |
| 3265 | 3257 | ||
| 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 | } |
| 3278 | 3267 | ||
| 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 | } |
| 3281 | 3274 |
src/analyze.hpp+1| ... | @@ -199,6 +199,7 @@ ZigPackage *new_anonymous_package(void); | ... | @@ -199,6 +199,7 @@ ZigPackage *new_anonymous_package(void); |
| 199 | 199 | ||
| 200 | Buf *const_value_to_buffer(ConstExprValue *const_val); | 200 | Buf *const_value_to_buffer(ConstExprValue *const_val); |
| 201 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc); | 201 | void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc); |
| 202 | void add_var_export(CodeGen *g, ZigVar *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage); | ||
| 202 | 203 | ||
| 203 | 204 | ||
| 204 | ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name); | 205 | ConstExprValue *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; |
| 205 | 205 | ||
| 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 | } |
| 208 | 212 | ||
| ... | @@ -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) { |
| 248 | 252 | ||
| 249 | void codegen_set_strip(CodeGen *g, bool strip) { | 253 | void 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 | } |
| 252 | 259 | ||
| 253 | void codegen_set_out_name(CodeGen *g, Buf *out_name) { | 260 | void 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 | } |
| 530 | 537 | ||
| 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 | } |
| 6634 | 6641 | ||
| 6635 | static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { | 6642 | static 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 | } |
| 6640 | 6650 | ||
| 6641 | static 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 | |||
| 6657 | static void do_code_gen(CodeGen *g) { | 6651 | static void do_code_gen(CodeGen *g) { |
| 6658 | assert(!g->errors.length); | 6652 | assert(!g->errors.length); |
| 6659 | 6653 | ||
| ... | @@ -6703,31 +6697,48 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -6703,31 +6697,48 @@ static void do_code_gen(CodeGen *g) { |
| 6703 | 6697 | ||
| 6704 | assert(var->decl_node); | 6698 | assert(var->decl_node); |
| 6705 | 6699 | ||
| 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 variable | 6726 | // TODO debug info for the extern variable |
| 6715 | 6727 | ||
| 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; |
| 6728 | 6739 | ||
| 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 | } |
| 6748 | 6759 | ||
| 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 | } |
| 6751 | 6767 | ||
| 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 | } |
| 7407 | 7423 | ||
| 7408 | static bool detect_err_ret_tracing(CodeGen *g) { | 7424 | static 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)); | ||
| 7843 | 7860 | ||
| 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.zig | 7897 | // 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 | } |
| 9075 | 9093 |
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 | } |
| 14450 | 14450 | ||
| 14451 | static 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 | |||
| 14465 | static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { | 14451 | static 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 | } |
| 14657 | 14651 | ||
| ... | @@ -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; |
| 15245 | 15239 | ||
| 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; |
| 15250 | 15244 |
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 | |||
| 1589 | bool 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); |
| 177 | bool target_is_wasm(const ZigTarget *target); | 177 | bool target_is_wasm(const ZigTarget *target); |
| 178 | bool target_is_single_threaded(const ZigTarget *target); | 178 | bool target_is_single_threaded(const ZigTarget *target); |
| 179 | bool target_supports_stack_probing(const ZigTarget *target); | 179 | bool target_supports_stack_probing(const ZigTarget *target); |
| 180 | bool target_has_debug_info(const ZigTarget *target); | ||
| 180 | 181 | ||
| 181 | uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch); | 182 | uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch); |
| 182 | 183 |
std/debug.zig+7-4| ... | @@ -85,8 +85,8 @@ fn wantTtyColor() bool { | ... | @@ -85,8 +85,8 @@ fn wantTtyColor() bool { |
| 85 | /// TODO multithreaded awareness | 85 | /// TODO multithreaded awareness |
| 86 | pub fn dumpCurrentStackTrace(start_addr: ?usize) void { | 86 | pub 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 awareness | 151 | /// TODO multithreaded awareness |
| 152 | pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void { | 152 | pub 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); |
| 228 | 229 | ||
| ... | @@ -783,6 +784,8 @@ pub const OpenSelfDebugInfoError = error{ | ... | @@ -783,6 +784,8 @@ pub const OpenSelfDebugInfoError = error{ |
| 783 | }; | 784 | }; |
| 784 | 785 | ||
| 785 | pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo { | 786 | pub 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 | } |
| 185 | 185 | ||
| 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 | } |
| 201 | 206 | ||
| 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 | } |
| 205 | 214 | ||
| 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 | } |
| 238 | 248 | ||
| 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); | ||
| 396 | 410 | ||
| 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); |
| 399 | 414 | ||
| ... | @@ -416,12 +431,16 @@ test "basic hash map usage" { | ... | @@ -416,12 +431,16 @@ test "basic hash map usage" { |
| 416 | 431 | ||
| 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); | ||
| 419 | 435 | ||
| 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 | } |
| 426 | 445 | ||
| 427 | test "iterator hash map" { | 446 | test "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(); |
| 433 | 452 | ||
| 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); |
| 437 | 456 | ||
| 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 | } |
| 389 | 389 | ||
| 390 | /// Caller must call argsFree on result. | 390 | /// Caller must call argsFree on result. |
| 391 | pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 { | 391 | pub 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 | ); |
| 4647 | 4647 | ||
| 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 | ); |
| 4667 | 4657 | ||
| 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 { |