fix bad LLVM IR when for target expr needs to be spilled
Also reduce the size of ZigVar in memory by making the name a `const char *` rather than a `Buf`.master
parent
e4c3067617
commit
f50bfb94b5
|
@ -2070,7 +2070,7 @@ struct CodeGen {
|
|||
};
|
||||
|
||||
struct ZigVar {
|
||||
Buf name;
|
||||
const char *name;
|
||||
ConstExprValue *const_value;
|
||||
ZigType *var_type;
|
||||
LLVMValueRef value_ref;
|
||||
|
@ -2085,7 +2085,6 @@ struct ZigVar {
|
|||
LLVMValueRef param_value_ref;
|
||||
size_t mem_slot_index;
|
||||
IrExecutable *owner_exec;
|
||||
size_t ref_count;
|
||||
|
||||
// In an inline loop, multiple variables may be created,
|
||||
// In this case, a reference to a variable should follow
|
||||
|
@ -2095,6 +2094,7 @@ struct ZigVar {
|
|||
ZigList<GlobalExport> export_list;
|
||||
|
||||
uint32_t align_bytes;
|
||||
uint32_t ref_count;
|
||||
|
||||
bool shadowable;
|
||||
bool src_is_const;
|
||||
|
|
|
@ -3148,26 +3148,26 @@ 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) {
|
||||
void add_var_export(CodeGen *g, ZigVar *var, const char *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);
|
||||
buf_init_from_str(&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) {
|
||||
void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, bool ccc) {
|
||||
if (ccc) {
|
||||
if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {
|
||||
if (strcmp(symbol_name, "main") == 0 && g->libc_link_lib != nullptr) {
|
||||
g->have_c_main = true;
|
||||
} else if (buf_eql_str(symbol_name, "WinMain") &&
|
||||
} else if (strcmp(symbol_name, "WinMain") == 0 &&
|
||||
g->zig_target->os == OsWindows)
|
||||
{
|
||||
g->have_winmain = true;
|
||||
} else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
|
||||
} else if (strcmp(symbol_name, "WinMainCRTStartup") == 0 &&
|
||||
g->zig_target->os == OsWindows)
|
||||
{
|
||||
g->have_winmain_crt_startup = true;
|
||||
} else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&
|
||||
} else if (strcmp(symbol_name, "DllMainCRTStartup") == 0 &&
|
||||
g->zig_target->os == OsWindows)
|
||||
{
|
||||
g->have_dllmain_crt_startup = true;
|
||||
|
@ -3176,7 +3176,7 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi
|
|||
|
||||
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);
|
||||
buf_init_from_str(&fn_export->name, symbol_name);
|
||||
fn_export->linkage = linkage;
|
||||
}
|
||||
|
||||
|
@ -3200,7 +3200,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
|||
|
||||
if (fn_proto->is_export) {
|
||||
bool ccc = (fn_proto->cc == CallingConventionUnspecified || fn_proto->cc == CallingConventionC);
|
||||
add_fn_export(g, fn_table_entry, &fn_table_entry->symbol_name, GlobalLinkageIdStrong, ccc);
|
||||
add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), GlobalLinkageIdStrong, ccc);
|
||||
}
|
||||
|
||||
if (!is_extern) {
|
||||
|
@ -3559,7 +3559,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
|
|||
variable_entry->src_arg_index = SIZE_MAX;
|
||||
|
||||
assert(name);
|
||||
buf_init_from_buf(&variable_entry->name, name);
|
||||
variable_entry->name = strdup(buf_ptr(name));
|
||||
|
||||
if ((err = type_resolve(g, var_type, ResolveStatusAlignmentKnown))) {
|
||||
variable_entry->var_type = g->builtin_types.entry_invalid;
|
||||
|
@ -3707,7 +3707,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
|
|||
}
|
||||
|
||||
if (is_export) {
|
||||
add_var_export(g, tld_var->var, &tld_var->var->name, GlobalLinkageIdStrong);
|
||||
add_var_export(g, tld_var->var, tld_var->var->name, GlobalLinkageIdStrong);
|
||||
}
|
||||
|
||||
g->global_vars.append(tld_var);
|
||||
|
@ -3916,7 +3916,7 @@ ZigVar *find_variable(CodeGen *g, Scope *scope, Buf *name, ScopeFnDef **crossed_
|
|||
while (scope) {
|
||||
if (scope->id == ScopeIdVarDecl) {
|
||||
ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
|
||||
if (buf_eql_buf(name, &var_scope->var->name)) {
|
||||
if (buf_eql_str(name, var_scope->var->name)) {
|
||||
if (crossed_fndef_scope != nullptr)
|
||||
*crossed_fndef_scope = my_crossed_fndef_scope;
|
||||
return var_scope->var;
|
||||
|
|
|
@ -189,8 +189,8 @@ ZigType *get_align_amt_type(CodeGen *g);
|
|||
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);
|
||||
void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, bool ccc);
|
||||
void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage);
|
||||
|
||||
|
||||
ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
|
||||
|
|
|
@ -57,6 +57,11 @@ static inline void buf_deinit(Buf *buf) {
|
|||
buf->list.deinit();
|
||||
}
|
||||
|
||||
static inline void buf_destroy(Buf *buf) {
|
||||
buf_deinit(buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static inline void buf_init_from_mem(Buf *buf, const char *ptr, size_t len) {
|
||||
assert(len != SIZE_MAX);
|
||||
buf->list.resize(len + 1);
|
||||
|
|
|
@ -234,18 +234,23 @@ static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const c
|
|||
return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val);
|
||||
}
|
||||
|
||||
static bool is_symbol_available(CodeGen *g, Buf *name) {
|
||||
return g->exported_symbol_names.maybe_get(name) == nullptr && g->external_prototypes.maybe_get(name) == nullptr;
|
||||
static bool is_symbol_available(CodeGen *g, const char *name) {
|
||||
Buf *buf_name = buf_create_from_str(name);
|
||||
bool result =
|
||||
g->exported_symbol_names.maybe_get(buf_name) == nullptr &&
|
||||
g->external_prototypes.maybe_get(buf_name) == nullptr;
|
||||
buf_destroy(buf_name);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Buf *get_mangled_name(CodeGen *g, Buf *original_name, bool external_linkage) {
|
||||
static const char *get_mangled_name(CodeGen *g, const char *original_name, bool external_linkage) {
|
||||
if (external_linkage || is_symbol_available(g, original_name)) {
|
||||
return original_name;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
for (;; n += 1) {
|
||||
Buf *new_name = buf_sprintf("%s.%d", buf_ptr(original_name), n);
|
||||
const char *new_name = buf_ptr(buf_sprintf("%s.%d", original_name, n));
|
||||
if (is_symbol_available(g, new_name)) {
|
||||
return new_name;
|
||||
}
|
||||
|
@ -387,8 +392,8 @@ static bool codegen_have_frame_pointer(CodeGen *g) {
|
|||
}
|
||||
|
||||
static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
||||
Buf *unmangled_name = &fn->symbol_name;
|
||||
Buf *symbol_name;
|
||||
const char *unmangled_name = buf_ptr(&fn->symbol_name);
|
||||
const char *symbol_name;
|
||||
GlobalLinkageId linkage;
|
||||
if (fn->body_node == nullptr) {
|
||||
symbol_name = unmangled_name;
|
||||
|
@ -398,7 +403,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
|||
linkage = GlobalLinkageIdInternal;
|
||||
} else {
|
||||
GlobalExport *fn_export = &fn->export_list.items[0];
|
||||
symbol_name = &fn_export->name;
|
||||
symbol_name = buf_ptr(&fn_export->name);
|
||||
linkage = fn_export->linkage;
|
||||
}
|
||||
|
||||
|
@ -408,7 +413,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
|||
g->zig_target->arch == ZigLLVM_x86)
|
||||
{
|
||||
// prevent llvm name mangling
|
||||
symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));
|
||||
symbol_name = buf_ptr(buf_sprintf("\x01_%s", symbol_name));
|
||||
}
|
||||
|
||||
bool is_async = fn_is_async(fn);
|
||||
|
@ -420,13 +425,16 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
|||
LLVMTypeRef fn_llvm_type = fn->raw_type_ref;
|
||||
LLVMValueRef llvm_fn = nullptr;
|
||||
if (fn->body_node == nullptr) {
|
||||
LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));
|
||||
LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, symbol_name);
|
||||
if (existing_llvm_fn) {
|
||||
return LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0));
|
||||
} else {
|
||||
auto entry = g->exported_symbol_names.maybe_get(symbol_name);
|
||||
Buf *buf_symbol_name = buf_create_from_str(symbol_name);
|
||||
auto entry = g->exported_symbol_names.maybe_get(buf_symbol_name);
|
||||
buf_destroy(buf_symbol_name);
|
||||
|
||||
if (entry == nullptr) {
|
||||
llvm_fn = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
|
||||
llvm_fn = LLVMAddFunction(g->module, symbol_name, fn_llvm_type);
|
||||
|
||||
if (target_is_wasm(g->zig_target)) {
|
||||
assert(fn->proto_node->type == NodeTypeFnProto);
|
||||
|
@ -440,7 +448,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
|||
TldFn *tld_fn = reinterpret_cast<TldFn *>(entry->value);
|
||||
// Make the raw_type_ref populated
|
||||
resolve_llvm_types_fn(g, tld_fn->fn_entry);
|
||||
tld_fn->fn_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name),
|
||||
tld_fn->fn_entry->llvm_value = LLVMAddFunction(g->module, symbol_name,
|
||||
tld_fn->fn_entry->raw_type_ref);
|
||||
llvm_fn = LLVMConstBitCast(tld_fn->fn_entry->llvm_value, LLVMPointerType(fn_llvm_type, 0));
|
||||
return llvm_fn;
|
||||
|
@ -448,7 +456,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
|||
}
|
||||
} else {
|
||||
if (llvm_fn == nullptr) {
|
||||
llvm_fn = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
|
||||
llvm_fn = LLVMAddFunction(g->module, symbol_name, fn_llvm_type);
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < fn->export_list.length; i += 1) {
|
||||
|
@ -1058,8 +1066,8 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
|
|||
};
|
||||
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false);
|
||||
|
||||
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_add_err_ret_trace_addr"), false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
|
||||
const char *fn_name = get_mangled_name(g, "__zig_add_err_ret_trace_addr", false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
|
||||
addLLVMFnAttr(fn_val, "alwaysinline");
|
||||
LLVMSetLinkage(fn_val, LLVMInternalLinkage);
|
||||
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
|
||||
|
@ -1138,8 +1146,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
|
|||
};
|
||||
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 1, false);
|
||||
|
||||
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_return_error"), false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
|
||||
const char *fn_name = get_mangled_name(g, "__zig_return_error", false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
|
||||
addLLVMFnAttr(fn_val, "noinline"); // so that we can look at return address
|
||||
addLLVMFnAttr(fn_val, "cold");
|
||||
LLVMSetLinkage(fn_val, LLVMInternalLinkage);
|
||||
|
@ -1208,7 +1216,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
|
|||
LLVMSetLinkage(msg_prefix, LLVMInternalLinkage);
|
||||
LLVMSetGlobalConstant(msg_prefix, true);
|
||||
|
||||
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);
|
||||
const char *fn_name = get_mangled_name(g, "__zig_fail_unwrap", false);
|
||||
LLVMTypeRef fn_type_ref;
|
||||
if (g->have_err_ret_tracing) {
|
||||
LLVMTypeRef arg_types[] = {
|
||||
|
@ -1222,7 +1230,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
|
|||
};
|
||||
fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 1, false);
|
||||
}
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
|
||||
addLLVMFnAttr(fn_val, "noreturn");
|
||||
addLLVMFnAttr(fn_val, "cold");
|
||||
LLVMSetLinkage(fn_val, LLVMInternalLinkage);
|
||||
|
@ -1805,7 +1813,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
|||
fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, ty));
|
||||
break;
|
||||
case FnWalkIdVars: {
|
||||
var->value_ref = build_alloca(g, ty, buf_ptr(&var->name), var->align_bytes);
|
||||
var->value_ref = build_alloca(g, ty, var->name, var->align_bytes);
|
||||
di_arg_index = fn_walk->data.vars.gen_i;
|
||||
fn_walk->data.vars.gen_i += 1;
|
||||
dest_ty = ty;
|
||||
|
@ -1916,7 +1924,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
|||
}
|
||||
case FnWalkIdVars: {
|
||||
di_arg_index = fn_walk->data.vars.gen_i;
|
||||
var->value_ref = build_alloca(g, ty, buf_ptr(&var->name), var->align_bytes);
|
||||
var->value_ref = build_alloca(g, ty, var->name, var->align_bytes);
|
||||
fn_walk->data.vars.gen_i += 1;
|
||||
dest_ty = ty;
|
||||
goto var_ok;
|
||||
|
@ -1949,7 +1957,7 @@ var_ok:
|
|||
if (dest_ty != nullptr && var->decl_node) {
|
||||
// arg index + 1 because the 0 index is return value
|
||||
var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
buf_ptr(&var->name), fn_walk->data.vars.import->data.structure.root_struct->di_file,
|
||||
var->name, fn_walk->data.vars.import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
get_llvm_di_type(g, dest_ty), !g->strip_debug_symbols, 0, di_arg_index + 1);
|
||||
}
|
||||
|
@ -2060,8 +2068,8 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
|
|||
};
|
||||
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), param_types, 2, false);
|
||||
|
||||
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_merge_error_return_traces"), false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
|
||||
const char *fn_name = get_mangled_name(g, "__zig_merge_error_return_traces", false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
|
||||
LLVMSetLinkage(fn_val, LLVMInternalLinkage);
|
||||
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
|
||||
addLLVMFnAttr(fn_val, "nounwind");
|
||||
|
@ -3743,12 +3751,11 @@ static void render_async_spills(CodeGen *g) {
|
|||
continue;
|
||||
}
|
||||
|
||||
var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, async_var_index,
|
||||
buf_ptr(&var->name));
|
||||
var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, async_var_index, var->name);
|
||||
async_var_index += 1;
|
||||
if (var->decl_node) {
|
||||
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
buf_ptr(&var->name), import->data.structure.root_struct->di_file,
|
||||
var->name, import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
|
||||
gen_var_debug_decl(g, var);
|
||||
|
@ -4653,8 +4660,9 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
|
|||
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(get_llvm_type(g, u8_slice_type), 0),
|
||||
&tag_int_llvm_type, 1, false);
|
||||
|
||||
Buf *fn_name = get_mangled_name(g, buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name)), false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
|
||||
const char *fn_name = get_mangled_name(g,
|
||||
buf_ptr(buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name))), false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
|
||||
LLVMSetLinkage(fn_val, LLVMInternalLinkage);
|
||||
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
|
||||
addLLVMFnAttr(fn_val, "nounwind");
|
||||
|
@ -6919,7 +6927,7 @@ static void generate_error_name_table(CodeGen *g) {
|
|||
LLVMValueRef err_name_table_init = LLVMConstArray(get_llvm_type(g, str_type), values, (unsigned)g->errors_by_index.length);
|
||||
|
||||
g->err_name_table = LLVMAddGlobal(g->module, LLVMTypeOf(err_name_table_init),
|
||||
buf_ptr(get_mangled_name(g, buf_create_from_str("__zig_err_name_table"), false)));
|
||||
get_mangled_name(g, buf_ptr(buf_create_from_str("__zig_err_name_table")), false));
|
||||
LLVMSetInitializer(g->err_name_table, err_name_table_init);
|
||||
LLVMSetLinkage(g->err_name_table, LLVMPrivateLinkage);
|
||||
LLVMSetGlobalConstant(g->err_name_table, true);
|
||||
|
@ -6960,8 +6968,8 @@ static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,
|
|||
assert(import);
|
||||
|
||||
bool is_local_to_unit = true;
|
||||
ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), buf_ptr(&var->name),
|
||||
buf_ptr(&var->name), import->data.structure.root_struct->di_file,
|
||||
ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), var->name,
|
||||
var->name, import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
get_llvm_di_type(g, type_entry), is_local_to_unit);
|
||||
|
||||
|
@ -7043,8 +7051,8 @@ static void do_code_gen(CodeGen *g) {
|
|||
assert(var->decl_node);
|
||||
|
||||
GlobalLinkageId linkage;
|
||||
Buf *unmangled_name = &var->name;
|
||||
Buf *symbol_name;
|
||||
const char *unmangled_name = var->name;
|
||||
const char *symbol_name;
|
||||
if (var->export_list.length == 0) {
|
||||
if (var->decl_node->data.variable_declaration.is_extern) {
|
||||
symbol_name = unmangled_name;
|
||||
|
@ -7055,19 +7063,19 @@ static void do_code_gen(CodeGen *g) {
|
|||
}
|
||||
} else {
|
||||
GlobalExport *global_export = &var->export_list.items[0];
|
||||
symbol_name = &global_export->name;
|
||||
symbol_name = buf_ptr(&global_export->name);
|
||||
linkage = global_export->linkage;
|
||||
}
|
||||
|
||||
LLVMValueRef global_value;
|
||||
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));
|
||||
LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, 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(symbol_name));
|
||||
global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), symbol_name);
|
||||
// TODO debug info for the extern variable
|
||||
|
||||
LLVMSetLinkage(global_value, to_llvm_linkage(linkage));
|
||||
|
@ -7078,8 +7086,8 @@ static void do_code_gen(CodeGen *g) {
|
|||
}
|
||||
} else {
|
||||
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));
|
||||
render_const_val(g, var->const_value, symbol_name);
|
||||
render_const_val_global(g, var->const_value, symbol_name);
|
||||
global_value = var->const_value->global_refs->llvm_global;
|
||||
|
||||
if (exported) {
|
||||
|
@ -7234,7 +7242,7 @@ static void do_code_gen(CodeGen *g) {
|
|||
|
||||
if (var->src_arg_index == SIZE_MAX) {
|
||||
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
buf_ptr(&var->name), import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
|
||||
var->name, import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
|
||||
get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
|
||||
|
||||
} else if (is_c_abi) {
|
||||
|
@ -7254,11 +7262,11 @@ static void do_code_gen(CodeGen *g) {
|
|||
var->value_ref = LLVMGetParam(fn, gen_info->gen_index);
|
||||
} else {
|
||||
gen_type = var->var_type;
|
||||
var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes);
|
||||
var->value_ref = build_alloca(g, var->var_type, var->name, var->align_bytes);
|
||||
}
|
||||
if (var->decl_node) {
|
||||
var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
buf_ptr(&var->name), import->data.structure.root_struct->di_file,
|
||||
var->name, import->data.structure.root_struct->di_file,
|
||||
(unsigned)(var->decl_node->line + 1),
|
||||
get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(gen_info->gen_index+1));
|
||||
}
|
||||
|
|
28
src/ir.cpp
28
src/ir.cpp
|
@ -3628,7 +3628,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
|
|||
}
|
||||
|
||||
if (name) {
|
||||
buf_init_from_buf(&variable_entry->name, name);
|
||||
variable_entry->name = strdup(buf_ptr(name));
|
||||
|
||||
if (!skip_name_check) {
|
||||
ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr);
|
||||
|
@ -3661,7 +3661,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
|
|||
// TODO make this name not actually be in scope. user should be able to make a variable called "_anon"
|
||||
// might already be solved, let's just make sure it has test coverage
|
||||
// maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables
|
||||
buf_init_from_str(&variable_entry->name, "_anon");
|
||||
variable_entry->name = "_anon";
|
||||
}
|
||||
|
||||
variable_entry->src_is_const = src_is_const;
|
||||
|
@ -6467,15 +6467,15 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
|
|||
}
|
||||
assert(elem_node->type == NodeTypeSymbol);
|
||||
|
||||
IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr);
|
||||
ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope);
|
||||
|
||||
IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr);
|
||||
if (array_val_ptr == irb->codegen->invalid_instruction)
|
||||
return array_val_ptr;
|
||||
|
||||
IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node,
|
||||
ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline);
|
||||
|
||||
ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope);
|
||||
|
||||
AstNode *index_var_source_node;
|
||||
ZigVar *index_var;
|
||||
const char *index_var_name;
|
||||
|
@ -14559,7 +14559,8 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
|
|||
// We make a new variable so that it can hold a different type, and so the debug info can
|
||||
// be distinct.
|
||||
ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope,
|
||||
&var->name, var->src_is_const, var->gen_is_const, var->shadowable, var->is_comptime, true);
|
||||
buf_create_from_str(var->name), var->src_is_const, var->gen_is_const,
|
||||
var->shadowable, var->is_comptime, true);
|
||||
new_var->owner_exec = var->owner_exec;
|
||||
new_var->align_bytes = var->align_bytes;
|
||||
if (var->mem_slot_index != SIZE_MAX) {
|
||||
|
@ -14702,7 +14703,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||
case CallingConventionNaked:
|
||||
case CallingConventionCold:
|
||||
case CallingConventionStdcall:
|
||||
add_fn_export(ira->codegen, fn_entry, symbol_name, global_linkage_id, cc == CallingConventionC);
|
||||
add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id,
|
||||
cc == CallingConventionC);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
@ -14840,7 +14842,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;
|
||||
add_var_export(ira->codegen, var, symbol_name, global_linkage_id);
|
||||
add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17023,7 +17025,7 @@ static IrInstruction *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructi
|
|||
IrInstruction *result = ir_get_var_ptr(ira, &instruction->base, var);
|
||||
if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) {
|
||||
ErrorMsg *msg = ir_add_error(ira, &instruction->base,
|
||||
buf_sprintf("'%s' not accessible from inner function", buf_ptr(&var->name)));
|
||||
buf_sprintf("'%s' not accessible from inner function", var->name));
|
||||
add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node,
|
||||
buf_sprintf("crossed function definition here"));
|
||||
add_error_note(ira->codegen, msg, var->decl_node,
|
||||
|
@ -17735,7 +17737,8 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
|
|||
return ir_error_dependency_loop(ira, source_instruction);
|
||||
}
|
||||
if (tld_var->extern_lib_name != nullptr) {
|
||||
add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node);
|
||||
add_link_lib_symbol(ira, tld_var->extern_lib_name, buf_create_from_str(var->name),
|
||||
source_instruction->source_node);
|
||||
}
|
||||
|
||||
return ir_get_var_ptr(ira, source_instruction, var);
|
||||
|
@ -20189,8 +20192,9 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
|
|||
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
|
||||
ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
|
||||
ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index];
|
||||
ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name);
|
||||
init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true);
|
||||
ConstExprValue *arg_name = create_const_str_lit(ira->codegen,
|
||||
buf_create_from_str(arg_var->name));
|
||||
init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, strlen(arg_var->name), true);
|
||||
fn_arg_name_val->parent.id = ConstParentIdArray;
|
||||
fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array;
|
||||
fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;
|
||||
|
|
|
@ -531,7 +531,7 @@ static void ir_print_bin_op(IrPrint *irp, IrInstructionBinOp *bin_op_instruction
|
|||
|
||||
static void ir_print_decl_var_src(IrPrint *irp, IrInstructionDeclVarSrc *decl_var_instruction) {
|
||||
const char *var_or_const = decl_var_instruction->var->gen_is_const ? "const" : "var";
|
||||
const char *name = buf_ptr(&decl_var_instruction->var->name);
|
||||
const char *name = decl_var_instruction->var->name;
|
||||
if (decl_var_instruction->var_type) {
|
||||
fprintf(irp->f, "%s %s: ", var_or_const, name);
|
||||
ir_print_other_instruction(irp, decl_var_instruction->var_type);
|
||||
|
@ -747,7 +747,7 @@ static void ir_print_elem_ptr(IrPrint *irp, IrInstructionElemPtr *instruction) {
|
|||
}
|
||||
|
||||
static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {
|
||||
fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));
|
||||
fprintf(irp->f, "&%s", instruction->var->name);
|
||||
}
|
||||
|
||||
static void ir_print_return_ptr(IrPrint *irp, IrInstructionReturnPtr *instruction) {
|
||||
|
@ -1852,7 +1852,7 @@ static void ir_print_mul_add(IrPrint *irp, IrInstructionMulAdd *instruction) {
|
|||
static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_var_instruction) {
|
||||
ZigVar *var = decl_var_instruction->var;
|
||||
const char *var_or_const = decl_var_instruction->var->gen_is_const ? "const" : "var";
|
||||
const char *name = buf_ptr(&decl_var_instruction->var->name);
|
||||
const char *name = decl_var_instruction->var->name;
|
||||
fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name),
|
||||
var->align_bytes);
|
||||
|
||||
|
|
|
@ -1201,3 +1201,35 @@ test "correctly spill when returning the error union result of another async fn"
|
|||
resume S.global_frame;
|
||||
}
|
||||
|
||||
|
||||
test "spill target expr in a for loop" {
|
||||
const S = struct {
|
||||
var global_frame: anyframe = undefined;
|
||||
|
||||
fn doTheTest() void {
|
||||
var foo = Foo{
|
||||
.slice = [_]i32{1, 2},
|
||||
};
|
||||
expect(atest(&foo) == 3);
|
||||
}
|
||||
|
||||
const Foo = struct {
|
||||
slice: []i32,
|
||||
};
|
||||
|
||||
fn atest(foo: *Foo) i32 {
|
||||
var sum: i32 = 0;
|
||||
for (foo.slice) |x| {
|
||||
suspend {
|
||||
global_frame = @frame();
|
||||
}
|
||||
sum += x;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
_ = async S.doTheTest();
|
||||
resume S.global_frame;
|
||||
resume S.global_frame;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue