mirror of
https://github.com/ziglang/zig.git
synced 2025-01-23 18:31:44 +00:00
compileError builtin includes "referenced by" notes
to help track down the cause closes #278
This commit is contained in:
parent
e64f0971fc
commit
e5b90651ba
@ -1453,8 +1453,6 @@ struct CodeGen {
|
||||
FnTableEntry *extern_panic_fn;
|
||||
LLVMValueRef cur_ret_ptr;
|
||||
LLVMValueRef cur_fn_val;
|
||||
ZigList<LLVMBasicBlockRef> break_block_stack;
|
||||
ZigList<LLVMBasicBlockRef> continue_block_stack;
|
||||
bool c_want_stdint;
|
||||
bool c_want_stdbool;
|
||||
AstNode *root_export_decl;
|
||||
@ -1510,6 +1508,7 @@ struct CodeGen {
|
||||
Buf *out_h_path;
|
||||
|
||||
ZigList<FnTableEntry *> inline_fns;
|
||||
ZigList<AstNode *> tld_ref_source_node_stack;
|
||||
};
|
||||
|
||||
enum VarLinkage {
|
||||
|
@ -2086,7 +2086,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source
|
||||
|
||||
void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) {
|
||||
Tld *tld = g->compile_var_import->decls_scope->decl_table.get(name);
|
||||
resolve_top_level_decl(g, tld, false);
|
||||
resolve_top_level_decl(g, tld, false, tld->source_node);
|
||||
assert(tld->id == TldIdVar);
|
||||
TldVar *tld_var = (TldVar *)tld;
|
||||
tld_var->var->value = value;
|
||||
@ -2399,7 +2399,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
|
||||
g->global_vars.append(tld_var);
|
||||
}
|
||||
|
||||
void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {
|
||||
void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node) {
|
||||
if (tld->resolution != TldResolutionUnresolved)
|
||||
return;
|
||||
|
||||
@ -2407,10 +2407,11 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {
|
||||
add_node_error(g, tld->source_node, buf_sprintf("'%s' depends on itself", buf_ptr(tld->name)));
|
||||
tld->resolution = TldResolutionInvalid;
|
||||
return;
|
||||
} else {
|
||||
tld->dep_loop_flag = true;
|
||||
}
|
||||
|
||||
tld->dep_loop_flag = true;
|
||||
g->tld_ref_source_node_stack.append(source_node);
|
||||
|
||||
switch (tld->id) {
|
||||
case TldIdVar:
|
||||
{
|
||||
@ -2440,6 +2441,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {
|
||||
|
||||
tld->resolution = TldResolutionOk;
|
||||
tld->dep_loop_flag = false;
|
||||
g->tld_ref_source_node_stack.pop();
|
||||
}
|
||||
|
||||
bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
|
||||
@ -3056,7 +3058,7 @@ void semantic_analyze(CodeGen *g) {
|
||||
for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {
|
||||
Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
|
||||
bool pointer_only = false;
|
||||
resolve_top_level_decl(g, tld, pointer_only);
|
||||
resolve_top_level_decl(g, tld, pointer_only, nullptr);
|
||||
}
|
||||
|
||||
for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
|
||||
|
@ -50,7 +50,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
|
||||
bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);
|
||||
VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);
|
||||
Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
|
||||
void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only);
|
||||
void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);
|
||||
bool type_is_codegen_pointer(TypeTableEntry *type);
|
||||
TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
|
||||
TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
|
||||
|
26
src/ir.cpp
26
src/ir.cpp
@ -7909,7 +7909,7 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
|
||||
|
||||
static ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) {
|
||||
Tld *tld = codegen->compile_var_import->decls_scope->decl_table.get(buf_create_from_str(name));
|
||||
resolve_top_level_decl(codegen, tld, false);
|
||||
resolve_top_level_decl(codegen, tld, false, nullptr);
|
||||
assert(tld->id == TldIdVar);
|
||||
TldVar *tld_var = (TldVar *)tld;
|
||||
ConstExprValue *var_value = tld_var->var->value;
|
||||
@ -10032,7 +10032,7 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
|
||||
auto entry = container_scope->decl_table.maybe_get(field_name);
|
||||
Tld *tld = entry ? entry->value : nullptr;
|
||||
if (tld && tld->id == TldIdFn) {
|
||||
resolve_top_level_decl(ira->codegen, tld, false);
|
||||
resolve_top_level_decl(ira->codegen, tld, false, field_ptr_instruction->base.source_node);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
TldFn *tld_fn = (TldFn *)tld;
|
||||
@ -10117,7 +10117,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
|
||||
|
||||
static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) {
|
||||
bool pointer_only = false;
|
||||
resolve_top_level_decl(ira->codegen, tld, pointer_only);
|
||||
resolve_top_level_decl(ira->codegen, tld, pointer_only, source_instruction->source_node);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
@ -10539,7 +10539,7 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
|
||||
Tld *tld = instruction->tld;
|
||||
IrInstruction *align_value = instruction->value->other;
|
||||
|
||||
resolve_top_level_decl(ira->codegen, tld, true);
|
||||
resolve_top_level_decl(ira->codegen, tld, true, instruction->base.source_node);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
@ -10602,7 +10602,7 @@ static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
|
||||
Tld *tld = instruction->tld;
|
||||
IrInstruction *section_value = instruction->value->other;
|
||||
|
||||
resolve_top_level_decl(ira->codegen, tld, true);
|
||||
resolve_top_level_decl(ira->codegen, tld, true, instruction->base.source_node);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
@ -11932,7 +11932,19 @@ static TypeTableEntry *ir_analyze_instruction_compile_err(IrAnalyze *ira,
|
||||
if (!msg_buf)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
ir_add_error(ira, &instruction->base, msg_buf);
|
||||
ErrorMsg *msg = ir_add_error(ira, &instruction->base, msg_buf);
|
||||
size_t i = ira->codegen->tld_ref_source_node_stack.length;
|
||||
for (;;) {
|
||||
if (i == 0)
|
||||
break;
|
||||
i -= 1;
|
||||
AstNode *source_node = ira->codegen->tld_ref_source_node_stack.at(i);
|
||||
if (source_node) {
|
||||
add_error_note(ira->codegen, msg, source_node,
|
||||
buf_sprintf("referenced here"));
|
||||
}
|
||||
}
|
||||
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
@ -13454,7 +13466,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
|
||||
Tld *tld = instruction->tld;
|
||||
LVal lval = instruction->lval;
|
||||
|
||||
resolve_top_level_decl(ira->codegen, tld, lval.is_ptr);
|
||||
resolve_top_level_decl(ira->codegen, tld, lval.is_ptr, instruction->base.source_node);
|
||||
if (tld->resolution == TldResolutionInvalid)
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
|
@ -8,7 +8,8 @@ const builtin = @import("builtin");
|
||||
const want_main_symbol = std.target.linking_libc;
|
||||
const want_start_symbol = !want_main_symbol;
|
||||
|
||||
const exit = std.os.posix.exit;
|
||||
const posix_exit = std.os.posix.exit;
|
||||
extern fn ExitProcess(exit_code: c_uint) -> noreturn;
|
||||
|
||||
var argc_ptr: &usize = undefined;
|
||||
|
||||
@ -34,8 +35,16 @@ fn callMainAndExit() -> noreturn {
|
||||
const argc = *argc_ptr;
|
||||
const argv = @ptrCast(&&u8, &argc_ptr[1]);
|
||||
const envp = @ptrCast(&?&u8, &argv[argc + 1]);
|
||||
callMain(argc, argv, envp) %% exit(1);
|
||||
exit(0);
|
||||
callMain(argc, argv, envp) %% exit(true);
|
||||
exit(false);
|
||||
}
|
||||
|
||||
fn exit(failure: bool) -> noreturn {
|
||||
if (builtin.os == builtin.Os.windows) {
|
||||
ExitProcess(c_uint(failure));
|
||||
} else {
|
||||
posix_exit(i32(failure));
|
||||
}
|
||||
}
|
||||
|
||||
fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void {
|
||||
|
@ -1916,4 +1916,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
|
||||
\\}
|
||||
,
|
||||
".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");
|
||||
|
||||
cases.add("@compileError shows traceback of references that caused it",
|
||||
\\const foo = @compileError("aoeu");
|
||||
\\
|
||||
\\const bar = baz + foo;
|
||||
\\const baz = 1;
|
||||
\\
|
||||
\\export fn entry() -> i32 {
|
||||
\\ return bar;
|
||||
\\}
|
||||
,
|
||||
".tmp_source.zig:1:13: error: aoeu",
|
||||
".tmp_source.zig:3:19: note: referenced here",
|
||||
".tmp_source.zig:7:12: note: referenced here");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user