Merge remote-tracking branch 'origin/master' into copy-elision-3
This commit is contained in:
commit
60025a3704
|
@ -266,7 +266,7 @@ const Timestamp = struct {
|
|||
{#code_end#}
|
||||
<p>
|
||||
Doc comments are only allowed in certain places; eventually, it will
|
||||
become a compile error have a doc comment in an unexpected place, such as
|
||||
become a compile error to have a doc comment in an unexpected place, such as
|
||||
in the middle of an expression, or just before a non-doc comment.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
@ -6648,7 +6648,7 @@ test "main" {
|
|||
{#header_close#}
|
||||
|
||||
{#header_open|@export#}
|
||||
<pre>{#syntax#}@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) void{#endsyntax#}</pre>
|
||||
<p>
|
||||
Creates a symbol in the output object file.
|
||||
</p>
|
||||
|
|
|
@ -1340,7 +1340,7 @@ enum FnInline {
|
|||
FnInlineNever,
|
||||
};
|
||||
|
||||
struct FnExport {
|
||||
struct GlobalExport {
|
||||
Buf name;
|
||||
GlobalLinkageId linkage;
|
||||
};
|
||||
|
@ -1378,7 +1378,7 @@ struct ZigFn {
|
|||
|
||||
AstNode *set_cold_node;
|
||||
|
||||
ZigList<FnExport> export_list;
|
||||
ZigList<GlobalExport> export_list;
|
||||
|
||||
LLVMValueRef valgrind_client_request_array;
|
||||
|
||||
|
@ -1902,14 +1902,6 @@ struct CodeGen {
|
|||
size_t clang_argv_len;
|
||||
};
|
||||
|
||||
enum VarLinkage {
|
||||
VarLinkageInternal,
|
||||
VarLinkageExportStrong,
|
||||
VarLinkageExportWeak,
|
||||
VarLinkageExportLinkOnce,
|
||||
VarLinkageExternal,
|
||||
};
|
||||
|
||||
struct ZigVar {
|
||||
Buf name;
|
||||
ConstExprValue *const_value;
|
||||
|
@ -1932,8 +1924,9 @@ struct ZigVar {
|
|||
// this pointer to the redefined variable.
|
||||
ZigVar *next_var;
|
||||
|
||||
ZigList<GlobalExport> export_list;
|
||||
|
||||
uint32_t align_bytes;
|
||||
VarLinkage linkage;
|
||||
|
||||
bool shadowable;
|
||||
bool src_is_const;
|
||||
|
|
|
@ -2718,6 +2718,13 @@ ZigType *get_test_fn_type(CodeGen *g) {
|
|||
return g->test_fn_type;
|
||||
}
|
||||
|
||||
void add_var_export(CodeGen *g, ZigVar *var, Buf *symbol_name, GlobalLinkageId linkage) {
|
||||
GlobalExport *global_export = var->export_list.add_one();
|
||||
memset(global_export, 0, sizeof(GlobalExport));
|
||||
buf_init_from_buf(&global_export->name, symbol_name);
|
||||
global_export->linkage = linkage;
|
||||
}
|
||||
|
||||
void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc) {
|
||||
if (ccc) {
|
||||
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
|
|||
}
|
||||
}
|
||||
|
||||
FnExport *fn_export = fn_table_entry->export_list.add_one();
|
||||
memset(fn_export, 0, sizeof(FnExport));
|
||||
GlobalExport *fn_export = fn_table_entry->export_list.add_one();
|
||||
memset(fn_export, 0, sizeof(GlobalExport));
|
||||
buf_init_from_buf(&fn_export->name, symbol_name);
|
||||
fn_export->linkage = linkage;
|
||||
}
|
||||
|
@ -2786,12 +2793,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
|||
fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
|
||||
|
||||
if (fn_proto->section_expr != nullptr) {
|
||||
if (fn_table_entry->body_node == nullptr) {
|
||||
add_node_error(g, fn_proto->section_expr,
|
||||
buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_table_entry->symbol_name)));
|
||||
} else {
|
||||
analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
|
||||
}
|
||||
analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
|
||||
}
|
||||
|
||||
if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) {
|
||||
|
@ -3200,15 +3202,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
|
|||
|
||||
assert(!is_export || !is_extern);
|
||||
|
||||
VarLinkage linkage;
|
||||
if (is_export) {
|
||||
linkage = VarLinkageExportStrong;
|
||||
} else if (is_extern) {
|
||||
linkage = VarLinkageExternal;
|
||||
} else {
|
||||
linkage = VarLinkageInternal;
|
||||
}
|
||||
|
||||
ConstExprValue *init_value = nullptr;
|
||||
|
||||
// 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) {
|
|||
if (implicit_type->id == ZigTypeIdUnreachable) {
|
||||
add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable"));
|
||||
implicit_type = g->builtin_types.entry_invalid;
|
||||
} else if ((!is_const || linkage == VarLinkageExternal) &&
|
||||
} else if ((!is_const || is_extern) &&
|
||||
(implicit_type->id == ZigTypeIdComptimeFloat ||
|
||||
implicit_type->id == ZigTypeIdComptimeInt ||
|
||||
implicit_type->id == ZigTypeIdEnumLiteral))
|
||||
|
@ -3238,7 +3231,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
|
|||
implicit_type = g->builtin_types.entry_invalid;
|
||||
}
|
||||
assert(implicit_type->id == ZigTypeIdInvalid || init_value->special != ConstValSpecialRuntime);
|
||||
} else if (linkage != VarLinkageExternal) {
|
||||
} else if (!is_extern) {
|
||||
add_node_error(g, source_node, buf_sprintf("variables must be initialized"));
|
||||
implicit_type = g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
@ -3250,7 +3243,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
|
|||
|
||||
tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol,
|
||||
is_const, init_val, &tld_var->base, type);
|
||||
tld_var->var->linkage = linkage;
|
||||
tld_var->var->is_thread_local = is_thread_local;
|
||||
|
||||
if (implicit_type != nullptr && type_is_invalid(implicit_type)) {
|
||||
|
@ -3264,10 +3256,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
|
|||
}
|
||||
|
||||
if (var_decl->section_expr != nullptr) {
|
||||
if (var_decl->is_extern) {
|
||||
add_node_error(g, var_decl->section_expr,
|
||||
buf_sprintf("cannot set section of external variable '%s'", buf_ptr(var_decl->symbol)));
|
||||
} else if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
|
||||
if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
|
||||
tld_var->section_name = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -3276,6 +3265,10 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
|
|||
add_node_error(g, source_node, buf_sprintf("threadlocal variable cannot be constant"));
|
||||
}
|
||||
|
||||
if (is_export) {
|
||||
add_var_export(g, tld_var->var, &tld_var->var->name, GlobalLinkageIdStrong);
|
||||
}
|
||||
|
||||
g->global_vars.append(tld_var);
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,7 @@ ZigPackage *new_anonymous_package(void);
|
|||
|
||||
Buf *const_value_to_buffer(ConstExprValue *const_val);
|
||||
void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc);
|
||||
void add_var_export(CodeGen *g, ZigVar *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage);
|
||||
|
||||
|
||||
ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
|
||||
|
|
|
@ -203,6 +203,10 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
|
|||
get_target_triple(&g->triple_str, g->zig_target);
|
||||
g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8;
|
||||
|
||||
if (!target_has_debug_info(g->zig_target)) {
|
||||
g->strip_debug_symbols = true;
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
|
@ -248,6 +252,9 @@ void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) {
|
|||
|
||||
void codegen_set_strip(CodeGen *g, bool strip) {
|
||||
g->strip_debug_symbols = strip;
|
||||
if (!target_has_debug_info(g->zig_target)) {
|
||||
g->strip_debug_symbols = true;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
|||
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 +536,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));
|
||||
}
|
||||
|
@ -6633,27 +6640,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);
|
||||
|
||||
|
@ -6703,31 +6697,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) {
|
||||
|
@ -6747,6 +6758,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.
|
||||
|
@ -7406,7 +7422,7 @@ static bool detect_single_threaded(CodeGen *g) {
|
|||
}
|
||||
|
||||
static bool detect_err_ret_tracing(CodeGen *g) {
|
||||
return !target_is_wasm(g->zig_target) &&
|
||||
return !g->strip_debug_symbols &&
|
||||
g->build_mode != BuildModeFastRelease &&
|
||||
g->build_mode != BuildModeSmallRelease;
|
||||
}
|
||||
|
@ -7840,6 +7856,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
|||
buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing));
|
||||
buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));
|
||||
buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
|
||||
buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
|
||||
|
||||
{
|
||||
TargetSubsystem detected_subsystem = detect_subsystem(g);
|
||||
|
@ -7880,6 +7897,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
|||
// Only a few things affect builtin.zig
|
||||
cache_buf(&cache_hash, compiler_id);
|
||||
cache_int(&cache_hash, g->build_mode);
|
||||
cache_bool(&cache_hash, g->strip_debug_symbols);
|
||||
cache_bool(&cache_hash, g->is_test_build);
|
||||
cache_bool(&cache_hash, g->is_single_threaded);
|
||||
cache_int(&cache_hash, g->zig_target->is_native);
|
||||
|
@ -9069,7 +9087,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;
|
||||
}
|
||||
|
||||
|
|
28
src/ir.cpp
28
src/ir.cpp
|
@ -14448,20 +14448,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
|
|||
return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -14558,6 +14544,15 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||
want_var_export = true;
|
||||
}
|
||||
break;
|
||||
case ZigTypeIdArray:
|
||||
if (!type_allowed_in_extern(ira->codegen, target->value.type->data.array.child_type)) {
|
||||
ir_add_error(ira, target,
|
||||
buf_sprintf("array element type '%s' not extern-compatible",
|
||||
buf_ptr(&target->value.type->data.array.child_type->name)));
|
||||
} else {
|
||||
want_var_export = true;
|
||||
}
|
||||
break;
|
||||
case ZigTypeIdMetaType: {
|
||||
ZigType *type_value = target->value.data.x_type;
|
||||
switch (type_value->id) {
|
||||
|
@ -14625,7 +14620,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||
case ZigTypeIdInt:
|
||||
case ZigTypeIdFloat:
|
||||
case ZigTypeIdPointer:
|
||||
case ZigTypeIdArray:
|
||||
case ZigTypeIdComptimeFloat:
|
||||
case ZigTypeIdComptimeInt:
|
||||
case ZigTypeIdUndefined:
|
||||
|
@ -14651,7 +14645,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||
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);
|
||||
add_var_export(ira->codegen, var, symbol_name, global_linkage_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15244,7 +15238,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
|
|||
ConstExprValue *mem_slot = nullptr;
|
||||
|
||||
bool comptime_var_mem = ir_get_var_is_comptime(var);
|
||||
bool linkage_makes_it_runtime = var->linkage == VarLinkageExternal;
|
||||
bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern;
|
||||
bool is_const = var->src_is_const;
|
||||
bool is_volatile = false;
|
||||
|
||||
|
|
|
@ -954,6 +954,7 @@ int main(int argc, char **argv) {
|
|||
case CmdBuiltin: {
|
||||
CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
|
||||
out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);
|
||||
codegen_set_strip(g, strip);
|
||||
g->subsystem = subsystem;
|
||||
g->valgrind_support = valgrind_support;
|
||||
g->want_pic = want_pic;
|
||||
|
|
|
@ -1585,3 +1585,7 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {
|
|||
out_target->vendor = ZigLLVM_UnknownVendor;
|
||||
out_target->is_native = false;
|
||||
}
|
||||
|
||||
bool target_has_debug_info(const ZigTarget *target) {
|
||||
return !target_is_wasm(target);
|
||||
}
|
||||
|
|
|
@ -177,6 +177,7 @@ bool target_is_musl(const ZigTarget *target);
|
|||
bool target_is_wasm(const ZigTarget *target);
|
||||
bool target_is_single_threaded(const ZigTarget *target);
|
||||
bool target_supports_stack_probing(const ZigTarget *target);
|
||||
bool target_has_debug_info(const ZigTarget *target);
|
||||
|
||||
uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
|
||||
|
||||
|
|
|
@ -85,8 +85,8 @@ fn wantTtyColor() bool {
|
|||
/// TODO multithreaded awareness
|
||||
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||
const stderr = getStderrStream() catch return;
|
||||
if (os.wasi.is_the_target) {
|
||||
stderr.print("Unable to dump stack trace: unimplemented on WASI\n") catch return;
|
||||
if (builtin.strip_debug_info) {
|
||||
stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
|
||||
return;
|
||||
}
|
||||
const debug_info = getSelfDebugInfo() catch |err| {
|
||||
|
@ -151,8 +151,8 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace
|
|||
/// TODO multithreaded awareness
|
||||
pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
|
||||
const stderr = getStderrStream() catch return;
|
||||
if (os.wasi.is_the_target) {
|
||||
stderr.print("Unable to dump stack trace: unimplemented on WASI\n") catch return;
|
||||
if (builtin.strip_debug_info) {
|
||||
stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
|
||||
return;
|
||||
}
|
||||
const debug_info = getSelfDebugInfo() catch |err| {
|
||||
|
@ -223,6 +223,7 @@ pub fn writeStackTrace(
|
|||
debug_info: *DebugInfo,
|
||||
tty_color: bool,
|
||||
) !void {
|
||||
if (builtin.strip_debug_info) return error.MissingDebugInfo;
|
||||
var frame_index: usize = 0;
|
||||
var frames_left: usize = std.math.min(stack_trace.index, stack_trace.instruction_addresses.len);
|
||||
|
||||
|
@ -783,6 +784,8 @@ pub const OpenSelfDebugInfoError = error{
|
|||
};
|
||||
|
||||
pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
|
||||
if (builtin.strip_debug_info)
|
||||
return error.MissingDebugInfo;
|
||||
if (windows.is_the_target) {
|
||||
return openSelfDebugInfoWindows(allocator);
|
||||
}
|
||||
|
|
|
@ -183,6 +183,11 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
|
|||
return putAssumeCapacity(self, key, value);
|
||||
}
|
||||
|
||||
/// Calls put() and asserts that no kv pair is clobbered.
|
||||
pub fn putNoClobber(self: *Self, key: K, value: V) !void {
|
||||
assert((try self.put(key, value)) == null);
|
||||
}
|
||||
|
||||
pub fn putAssumeCapacity(self: *Self, key: K, value: V) ?KV {
|
||||
assert(self.count() < self.entries.len);
|
||||
self.incrementModificationCount();
|
||||
|
@ -199,10 +204,15 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
|
|||
return hm.internalGet(key);
|
||||
}
|
||||
|
||||
pub fn getValue(hm: *const Self, key: K) ?V {
|
||||
return if (hm.get(key)) |kv| kv.value else null;
|
||||
}
|
||||
|
||||
pub fn contains(hm: *const Self, key: K) bool {
|
||||
return hm.get(key) != null;
|
||||
}
|
||||
|
||||
/// Returns any kv pair that was removed.
|
||||
pub fn remove(hm: *Self, key: K) ?KV {
|
||||
if (hm.entries.len == 0) return null;
|
||||
hm.incrementModificationCount();
|
||||
|
@ -236,6 +246,11 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
|
|||
return null;
|
||||
}
|
||||
|
||||
/// Calls remove(), asserts that a kv pair is removed, and discards it.
|
||||
pub fn removeAssertDiscard(hm: *Self, key: K) void {
|
||||
assert(hm.remove(key) != null);
|
||||
}
|
||||
|
||||
pub fn iterator(hm: *const Self) Iterator {
|
||||
return Iterator{
|
||||
.hm = hm,
|
||||
|
@ -250,7 +265,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
|
|||
try other.initCapacity(self.entries.len);
|
||||
var it = self.iterator();
|
||||
while (it.next()) |entry| {
|
||||
assert((try other.put(entry.key, entry.value)) == null);
|
||||
try other.putNoClobber(entry.key, entry.value);
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
@ -392,8 +407,8 @@ test "basic hash map usage" {
|
|||
testing.expect((try map.put(2, 22)) == null);
|
||||
testing.expect((try map.put(3, 33)) == null);
|
||||
testing.expect((try map.put(4, 44)) == null);
|
||||
testing.expect((try map.put(5, 55)) == null);
|
||||
|
||||
try map.putNoClobber(5, 55);
|
||||
testing.expect((try map.put(5, 66)).?.value == 55);
|
||||
testing.expect((try map.put(5, 55)).?.value == 66);
|
||||
|
||||
|
@ -416,12 +431,16 @@ test "basic hash map usage" {
|
|||
|
||||
testing.expect(map.contains(2));
|
||||
testing.expect(map.get(2).?.value == 22);
|
||||
testing.expect(map.getValue(2).? == 22);
|
||||
|
||||
const rmv1 = map.remove(2);
|
||||
testing.expect(rmv1.?.key == 2);
|
||||
testing.expect(rmv1.?.value == 22);
|
||||
testing.expect(map.remove(2) == null);
|
||||
testing.expect(map.get(2) == null);
|
||||
testing.expect(map.getValue(2) == null);
|
||||
|
||||
map.removeAssertDiscard(3);
|
||||
}
|
||||
|
||||
test "iterator hash map" {
|
||||
|
@ -431,9 +450,9 @@ test "iterator hash map" {
|
|||
var reset_map = AutoHashMap(i32, i32).init(&direct_allocator.allocator);
|
||||
defer reset_map.deinit();
|
||||
|
||||
testing.expect((try reset_map.put(1, 11)) == null);
|
||||
testing.expect((try reset_map.put(2, 22)) == null);
|
||||
testing.expect((try reset_map.put(3, 33)) == null);
|
||||
try reset_map.putNoClobber(1, 11);
|
||||
try reset_map.putNoClobber(2, 22);
|
||||
try reset_map.putNoClobber(3, 33);
|
||||
|
||||
var keys = [_]i32{
|
||||
3,
|
||||
|
|
|
@ -388,7 +388,7 @@ pub fn args() ArgIterator {
|
|||
}
|
||||
|
||||
/// Caller must call argsFree on result.
|
||||
pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
|
||||
pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {
|
||||
if (builtin.os == .wasi) {
|
||||
var count: usize = undefined;
|
||||
var buf_size: usize = undefined;
|
||||
|
|
|
@ -4645,16 +4645,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||
"tmp.zig:1:1: note: declared here",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"setting a section on an extern variable",
|
||||
\\extern var foo: i32 linksection(".text2");
|
||||
\\export fn entry() i32 {
|
||||
\\ return foo;
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:1:33: error: cannot set section of external variable 'foo'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"setting a section on a local variable",
|
||||
\\export fn entry() i32 {
|
||||
|
@ -4665,16 +4655,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||
"tmp.zig:2:30: error: cannot set section of local variable 'foo'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"setting a section on an extern fn",
|
||||
\\extern fn foo() linksection(".text2") void;
|
||||
\\export fn entry() void {
|
||||
\\ foo();
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:1:29: error: cannot set section of external function 'foo'",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"returning address of local variable - simple",
|
||||
\\export fn foo() *i32 {
|
||||
|
|
Loading…
Reference in New Issue
Block a user