Commit efdbede7ab
Changed files (5)
src/all_types.hpp
@@ -69,9 +69,9 @@ struct IrExecutable {
IrExecutable *source_exec;
IrAnalyze *analysis;
Scope *begin_scope;
+ ErrorMsg *first_err_trace_msg;
ZigList<Tld *> tld_list;
- bool invalid;
bool is_inline;
bool is_generic_instantiation;
bool need_err_code_spill;
@@ -1129,11 +1129,10 @@ struct ZigTypeStruct {
ResolveStatus resolve_status;
bool is_slice;
- bool resolve_loop_flag; // set this flag temporarily to detect infinite loops
- bool reported_infinite_err;
// whether any of the fields require comptime
// known after ResolveStatusZeroBitsKnown
bool requires_comptime;
+ bool resolve_loop_flag;
};
struct ZigTypeOptional {
@@ -1155,26 +1154,20 @@ struct ZigTypeErrorSet {
struct ZigTypeEnum {
AstNode *decl_node;
- ContainerLayout layout;
- uint32_t src_field_count;
TypeEnumField *fields;
- bool is_invalid; // true if any fields are invalid
ZigType *tag_int_type;
ScopeDecls *decls_scope;
- // set this flag temporarily to detect infinite loops
- bool embedded_in_current;
- bool reported_infinite_err;
- // whether we've finished resolving it
- bool complete;
-
- bool zero_bits_loop_flag;
- bool zero_bits_known;
-
LLVMValueRef name_function;
HashMap<Buf *, TypeEnumField *, buf_hash, buf_eql_buf> fields_by_name;
+ uint32_t src_field_count;
+
+ ContainerLayout layout;
+ ResolveStatus resolve_status;
+
+ bool resolve_loop_flag;
};
uint32_t type_ptr_hash(const ZigType *ptr);
@@ -1199,11 +1192,10 @@ struct ZigTypeUnion {
ResolveStatus resolve_status;
bool have_explicit_tag_type;
- bool resolve_loop_flag; // set this flag temporarily to detect infinite loops
- bool reported_infinite_err;
// whether any of the fields require comptime
// the value is not valid until zero_bits_known == true
bool requires_comptime;
+ bool resolve_loop_flag;
};
struct FnGenParamInfo {
@@ -1715,6 +1707,7 @@ struct CodeGen {
//////////////////////////// Runtime State
LLVMModuleRef module;
ZigList<ErrorMsg*> errors;
+ ErrorMsg *trace_err;
LLVMBuilderRef builder;
ZigLLVMDIBuilder *dbuilder;
ZigLLVMDICompileUnit *compile_unit;
@@ -1767,7 +1760,6 @@ struct CodeGen {
ZigList<Tld *> resolve_queue;
size_t resolve_queue_index;
ZigList<TimeEvent> timing_events;
- ZigList<AstNode *> tld_ref_source_node_stack;
ZigList<ZigFn *> inline_fns;
ZigList<ZigFn *> test_fns;
ZigList<ErrorTableEntry *> errors_by_index;
@@ -1852,7 +1844,6 @@ struct CodeGen {
ZigFn *main_fn;
ZigFn *panic_fn;
TldFn *panic_tld_fn;
- AstNode *root_export_decl;
WantPIC want_pic;
WantStackCheck want_stack_check;
src/analyze.cpp
@@ -20,7 +20,7 @@
static const size_t default_backward_branch_quota = 1000;
-static Error resolve_struct_type(CodeGen *g, ZigType *struct_type);
+static Error ATTRIBUTE_MUST_USE resolve_struct_type(CodeGen *g, ZigType *struct_type);
static Error ATTRIBUTE_MUST_USE resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type);
static Error ATTRIBUTE_MUST_USE resolve_struct_alignment(CodeGen *g, ZigType *struct_type);
@@ -271,6 +271,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
return type_entry->data.structure.resolve_status >= status;
case ZigTypeIdUnion:
return type_entry->data.unionation.resolve_status >= status;
+ case ZigTypeIdEnum:
+ return type_entry->data.enumeration.resolve_status >= status;
case ZigTypeIdFnFrame:
switch (status) {
case ResolveStatusInvalid:
@@ -285,23 +287,6 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
case ResolveStatusLLVMFull:
return type_entry->llvm_type != nullptr;
}
- case ZigTypeIdEnum:
- switch (status) {
- case ResolveStatusUnstarted:
- return true;
- case ResolveStatusInvalid:
- zig_unreachable();
- case ResolveStatusZeroBitsKnown:
- return type_entry->data.enumeration.zero_bits_known;
- case ResolveStatusAlignmentKnown:
- return type_entry->data.enumeration.zero_bits_known;
- case ResolveStatusSizeKnown:
- return type_entry->data.enumeration.complete;
- case ResolveStatusLLVMFwdDecl:
- case ResolveStatusLLVMFull:
- return type_entry->llvm_di_type != nullptr;
- }
- zig_unreachable();
case ZigTypeIdOpaque:
return status < ResolveStatusSizeKnown;
case ZigTypeIdMetaType:
@@ -865,7 +850,7 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
return table_entry->value;
}
if (fn_type_id->return_type != nullptr) {
- if ((err = ensure_complete_type(g, fn_type_id->return_type)))
+ if ((err = type_resolve(g, fn_type_id->return_type, ResolveStatusSizeKnown)))
return g->builtin_types.entry_invalid;
assert(fn_type_id->return_type->id != ZigTypeIdOpaque);
} else {
@@ -1404,7 +1389,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
add_node_error(g, proto_node,
buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447"));
return g->builtin_types.entry_invalid;
- //return get_generic_fn_type(g, &fn_type_id);
}
ZigType *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
@@ -1490,7 +1474,7 @@ bool type_is_invalid(ZigType *type_entry) {
case ZigTypeIdUnion:
return type_entry->data.unionation.resolve_status == ResolveStatusInvalid;
case ZigTypeIdEnum:
- return type_entry->data.enumeration.is_invalid;
+ return type_entry->data.enumeration.resolve_status == ResolveStatusInvalid;
default:
return false;
}
@@ -1602,9 +1586,8 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
if (struct_type->data.structure.resolve_loop_flag) {
if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
- ErrorMsg *msg = add_node_error(g, decl_node,
- buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name)));
- emit_error_notes_for_ref_stack(g, msg);
+ g->trace_err = add_node_error(g, decl_node,
+ buf_sprintf("struct '%s' depends on its own size", buf_ptr(&struct_type->name)));
}
return ErrorSemanticAnalyzeFail;
}
@@ -1728,14 +1711,13 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
if (union_type->data.unionation.resolve_status >= ResolveStatusAlignmentKnown)
return ErrorNone;
+ AstNode *decl_node = union_type->data.structure.decl_node;
+
if (union_type->data.unionation.resolve_loop_flag) {
- if (!union_type->data.unionation.reported_infinite_err) {
- AstNode *decl_node = union_type->data.unionation.decl_node;
- union_type->data.unionation.reported_infinite_err = true;
+ if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
- ErrorMsg *msg = add_node_error(g, decl_node,
- buf_sprintf("union '%s' contains itself", buf_ptr(&union_type->name)));
- emit_error_notes_for_ref_stack(g, msg);
+ g->trace_err = add_node_error(g, decl_node,
+ buf_sprintf("union '%s' depends on its own alignment", buf_ptr(&union_type->name)));
}
return ErrorSemanticAnalyzeFail;
}
@@ -1752,13 +1734,12 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
if (field->gen_index == UINT32_MAX)
continue;
+ src_assert(field->type_entry != nullptr, decl_node);
+
size_t this_field_align;
if (packed) {
// TODO: https://github.com/ziglang/zig/issues/1512
this_field_align = 1;
- // This is the same hack as resolve_struct_alignment. See the comment there.
- } else if (field->type_entry == nullptr) {
- this_field_align = g->builtin_types.entry_usize->abi_align;
} else {
if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
@@ -1839,12 +1820,10 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
size_t union_size_in_bits = 0;
if (union_type->data.unionation.resolve_loop_flag) {
- if (!union_type->data.unionation.reported_infinite_err) {
- union_type->data.unionation.reported_infinite_err = true;
+ if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
- ErrorMsg *msg = add_node_error(g, decl_node,
- buf_sprintf("union '%s' depends on its own size", buf_ptr(&union_type->name)));
- emit_error_notes_for_ref_stack(g, msg);
+ g->trace_err = add_node_error(g, decl_node,
+ buf_sprintf("union '%s' depends on its own size", buf_ptr(&union_type->name)));
}
return ErrorSemanticAnalyzeFail;
}
@@ -1925,24 +1904,25 @@ static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) {
static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
assert(enum_type->id == ZigTypeIdEnum);
- if (enum_type->data.enumeration.is_invalid)
+ if (enum_type->data.enumeration.resolve_status == ResolveStatusInvalid)
return ErrorSemanticAnalyzeFail;
-
- if (enum_type->data.enumeration.zero_bits_known)
+ if (enum_type->data.enumeration.resolve_status >= ResolveStatusZeroBitsKnown)
return ErrorNone;
- if (enum_type->data.enumeration.zero_bits_loop_flag) {
- ErrorMsg *msg = add_node_error(g, enum_type->data.enumeration.decl_node,
- buf_sprintf("'%s' depends on itself", buf_ptr(&enum_type->name)));
- emit_error_notes_for_ref_stack(g, msg);
- enum_type->data.enumeration.is_invalid = true;
+ AstNode *decl_node = enum_type->data.enumeration.decl_node;
+ assert(decl_node->type == NodeTypeContainerDecl);
+
+ if (enum_type->data.enumeration.resolve_loop_flag) {
+ if (enum_type->data.enumeration.resolve_status != ResolveStatusInvalid) {
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
+ g->trace_err = add_node_error(g, decl_node,
+ buf_sprintf("circular dependency: whether enum '%s' has non-zero size",
+ buf_ptr(&enum_type->name)));
+ }
return ErrorSemanticAnalyzeFail;
}
- enum_type->data.enumeration.zero_bits_loop_flag = true;
-
- AstNode *decl_node = enum_type->data.enumeration.decl_node;
- assert(decl_node->type == NodeTypeContainerDecl);
+ enum_type->data.enumeration.resolve_loop_flag = true;
assert(!enum_type->data.enumeration.fields);
uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
@@ -1951,9 +1931,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
enum_type->data.enumeration.src_field_count = field_count;
enum_type->data.enumeration.fields = nullptr;
- enum_type->data.enumeration.is_invalid = true;
- enum_type->data.enumeration.zero_bits_loop_flag = false;
- enum_type->data.enumeration.zero_bits_known = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
return ErrorSemanticAnalyzeFail;
}
@@ -1982,14 +1960,14 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
if (decl_node->data.container_decl.init_arg_expr != nullptr) {
ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
if (type_is_invalid(wanted_tag_int_type)) {
- enum_type->data.enumeration.is_invalid = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
} else if (wanted_tag_int_type->id != ZigTypeIdInt) {
- enum_type->data.enumeration.is_invalid = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
add_node_error(g, decl_node->data.container_decl.init_arg_expr,
buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
} else if (enum_type->data.enumeration.layout == ContainerLayoutExtern &&
!type_is_valid_extern_enum_tag(g, wanted_tag_int_type)) {
- enum_type->data.enumeration.is_invalid = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
ErrorMsg *msg = add_node_error(g, decl_node->data.container_decl.init_arg_expr,
buf_sprintf("'%s' is not a valid tag type for an extern enum",
buf_ptr(&wanted_tag_int_type->name)));
@@ -2029,7 +2007,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
ErrorMsg *msg = add_node_error(g, field_node,
buf_sprintf("duplicate enum field: '%s'", buf_ptr(type_enum_field->name)));
add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here"));
- enum_type->data.enumeration.is_invalid = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
continue;
}
@@ -2039,7 +2017,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
// A user-specified value is available
ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr);
if (type_is_invalid(result->type)) {
- enum_type->data.enumeration.is_invalid = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
continue;
}
@@ -2060,7 +2038,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
if (!bigint_fits_in_bits(&type_enum_field->value,
tag_int_type->size_in_bits,
tag_int_type->data.integral.is_signed)) {
- enum_type->data.enumeration.is_invalid = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
Buf *val_buf = buf_alloc();
bigint_append_buf(val_buf, &type_enum_field->value, 10);
@@ -2075,7 +2053,7 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
// Make sure the value is unique
auto entry = occupied_tag_values.put_unique(type_enum_field->value, field_node);
if (entry != nullptr) {
- enum_type->data.enumeration.is_invalid = true;
+ enum_type->data.enumeration.resolve_status = ResolveStatusInvalid;
Buf *val_buf = buf_alloc();
bigint_append_buf(val_buf, &type_enum_field->value, 10);
@@ -2089,13 +2067,12 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
last_enum_field = type_enum_field;
}
- enum_type->data.enumeration.zero_bits_loop_flag = false;
- enum_type->data.enumeration.zero_bits_known = true;
- enum_type->data.enumeration.complete = true;
-
- if (enum_type->data.enumeration.is_invalid)
+ if (enum_type->data.enumeration.resolve_status == ResolveStatusInvalid)
return ErrorSemanticAnalyzeFail;
+ enum_type->data.enumeration.resolve_loop_flag = false;
+ enum_type->data.enumeration.resolve_status = ResolveStatusSizeKnown;
+
return ErrorNone;
}
@@ -2113,12 +2090,13 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
assert(decl_node->type == NodeTypeContainerDecl);
if (struct_type->data.structure.resolve_loop_flag) {
- // TODO This is a problem. I believe it can be solved with lazy values.
- struct_type->size_in_bits = SIZE_MAX;
- struct_type->abi_size = SIZE_MAX;
- struct_type->data.structure.resolve_status = ResolveStatusZeroBitsKnown;
- struct_type->data.structure.resolve_loop_flag = false;
- return ErrorNone;
+ if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+ g->trace_err = add_node_error(g, decl_node,
+ buf_sprintf("circular dependency: whether struct '%s' has non-zero size",
+ buf_ptr(&struct_type->name)));
+ }
+ return ErrorSemanticAnalyzeFail;
}
struct_type->data.structure.resolve_loop_flag = true;
@@ -2237,9 +2215,8 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
if (struct_type->data.structure.resolve_loop_flag) {
if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
- ErrorMsg *msg = add_node_error(g, decl_node,
- buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name)));
- emit_error_notes_for_ref_stack(g, msg);
+ g->trace_err = add_node_error(g, decl_node,
+ buf_sprintf("struct '%s' depends on its own alignment", buf_ptr(&struct_type->name)));
}
return ErrorSemanticAnalyzeFail;
}
@@ -2255,20 +2232,12 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
if (field->gen_index == SIZE_MAX)
continue;
+ src_assert(field->type_entry != nullptr, decl_node);
+
size_t this_field_align;
if (packed) {
// TODO: https://github.com/ziglang/zig/issues/1512
this_field_align = 1;
- // TODO If we have no type_entry for the field, we've already failed to
- // compile the program correctly. This stage1 compiler needs a deeper
- // reworking to make this correct, or we can ignore the problem
- // and make sure it is fixed in stage2. This workaround is for when
- // there is a false positive of a dependency loop, of alignment depending
- // on itself. When this false positive happens we assume a pointer-aligned
- // field, which is usually fine but could be incorrectly over-aligned or
- // even under-aligned. See https://github.com/ziglang/zig/issues/1512
- } else if (field->type_entry == nullptr) {
- this_field_align = g->builtin_types.entry_usize->abi_align;
} else {
if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
@@ -2304,23 +2273,21 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
if (union_type->data.unionation.resolve_status >= ResolveStatusZeroBitsKnown)
return ErrorNone;
+ AstNode *decl_node = union_type->data.unionation.decl_node;
+ assert(decl_node->type == NodeTypeContainerDecl);
+
if (union_type->data.unionation.resolve_loop_flag) {
- // If we get here it's due to recursion. From this we conclude that the struct is
- // not zero bits.
- // TODO actually it could still be zero bits. Here we should continue analyzing
- // the union from the next field index.
- union_type->data.unionation.resolve_status = ResolveStatusZeroBitsKnown;
- union_type->data.unionation.resolve_loop_flag = false;
- union_type->abi_size = SIZE_MAX;
- union_type->size_in_bits = SIZE_MAX;
- return ErrorNone;
+ if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
+ union_type->data.unionation.resolve_status = ResolveStatusInvalid;
+ g->trace_err = add_node_error(g, decl_node,
+ buf_sprintf("circular dependency: whether union '%s' has non-zero size",
+ buf_ptr(&union_type->name)));
+ }
+ return ErrorSemanticAnalyzeFail;
}
union_type->data.unionation.resolve_loop_flag = true;
- AstNode *decl_node = union_type->data.unionation.decl_node;
- assert(decl_node->type == NodeTypeContainerDecl);
-
assert(union_type->data.unionation.fields == nullptr);
uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
if (field_count == 0) {
@@ -2380,14 +2347,13 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
tag_type->size_in_bits = tag_int_type->size_in_bits;
tag_type->data.enumeration.tag_int_type = tag_int_type;
- tag_type->data.enumeration.zero_bits_known = true;
+ tag_type->data.enumeration.resolve_status = ResolveStatusSizeKnown;
tag_type->data.enumeration.decl_node = decl_node;
tag_type->data.enumeration.layout = ContainerLayoutAuto;
tag_type->data.enumeration.src_field_count = field_count;
tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
tag_type->data.enumeration.fields_by_name.init(field_count);
tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope;
- tag_type->data.enumeration.complete = true;
} else if (enum_type_node != nullptr) {
ZigType *enum_type = analyze_type_expr(g, scope, enum_type_node);
if (type_is_invalid(enum_type)) {
@@ -3185,9 +3151,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
ZigType *explicit_type = nullptr;
if (var_decl->type) {
if (tld_var->analyzing_type) {
- ErrorMsg *msg = add_node_error(g, var_decl->type,
+ g->trace_err = add_node_error(g, var_decl->type,
buf_sprintf("type of '%s' depends on itself", buf_ptr(tld_var->base.name)));
- emit_error_notes_for_ref_stack(g, msg);
explicit_type = g->builtin_types.entry_invalid;
} else {
tld_var->analyzing_type = true;
@@ -3386,7 +3351,6 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
assert(tld->resolution != TldResolutionResolving);
tld->resolution = TldResolutionResolving;
- g->tld_ref_source_node_stack.append(source_node);
switch (tld->id) {
case TldIdVar:
@@ -3424,7 +3388,10 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
}
tld->resolution = TldResolutionOk;
- g->tld_ref_source_node_stack.pop();
+
+ if (g->trace_err != nullptr && source_node != nullptr) {
+ g->trace_err = add_error_note(g, g->trace_err, source_node, buf_create_from_str("referenced here"));
+ }
}
Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
@@ -3550,7 +3517,7 @@ TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag)
}
TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) {
- assert(enum_type->data.enumeration.zero_bits_known);
+ assert(type_is_resolved(enum_type, ResolveStatusZeroBitsKnown));
for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) {
TypeEnumField *field = &enum_type->data.enumeration.fields[i];
if (bigint_cmp(&field->value, tag) == CmpEQ) {
@@ -3619,43 +3586,6 @@ ZigType *container_ref_type(ZigType *type_entry) {
type_entry->data.pointer.child_type : type_entry;
}
-Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
- switch (type_entry->id) {
- case ZigTypeIdStruct:
- return resolve_struct_type(g, type_entry);
- case ZigTypeIdEnum:
- return resolve_enum_zero_bits(g, type_entry);
- case ZigTypeIdUnion:
- return resolve_union_type(g, type_entry);
- case ZigTypeIdPointer:
- case ZigTypeIdMetaType:
- case ZigTypeIdVoid:
- case ZigTypeIdBool:
- case ZigTypeIdUnreachable:
- case ZigTypeIdInt:
- case ZigTypeIdFloat:
- case ZigTypeIdArray:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdEnumLiteral:
- case ZigTypeIdUndefined:
- case ZigTypeIdNull:
- case ZigTypeIdOptional:
- case ZigTypeIdErrorUnion:
- case ZigTypeIdErrorSet:
- case ZigTypeIdFn:
- case ZigTypeIdBoundFn:
- case ZigTypeIdInvalid:
- case ZigTypeIdArgTuple:
- case ZigTypeIdOpaque:
- case ZigTypeIdVector:
- case ZigTypeIdFnFrame:
- case ZigTypeIdAnyFrame:
- zig_unreachable();
- }
- zig_unreachable();
-}
-
ZigType *get_src_ptr_type(ZigType *type) {
if (type->id == ZigTypeIdPointer) return type;
if (type->id == ZigTypeIdFn) return type;
@@ -3906,7 +3836,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
&fn->analyzed_executable, fn_type_id->return_type, return_type_node);
fn->src_implicit_return_type = block_return_type;
- if (type_is_invalid(block_return_type) || fn->analyzed_executable.invalid) {
+ if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) {
assert(g->errors.length > 0);
fn->anal_state = FnAnalStateInvalid;
return;
@@ -3990,7 +3920,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
assert(!fn_type->data.fn.is_generic);
ir_gen_fn(g, fn_table_entry);
- if (fn_table_entry->ir_executable.invalid) {
+ if (fn_table_entry->ir_executable.first_err_trace_msg != nullptr) {
fn_table_entry->anal_state = FnAnalStateInvalid;
return;
}
@@ -4128,12 +4058,14 @@ 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);
+ g->trace_err = nullptr;
AstNode *source_node = nullptr;
resolve_top_level_decl(g, tld, source_node);
}
for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
ZigFn *fn_entry = g->fn_defs.at(g->fn_defs_index);
+ g->trace_err = nullptr;
analyze_fn_body(g, fn_entry);
}
}
@@ -4145,6 +4077,7 @@ void semantic_analyze(CodeGen *g) {
// second pass over functions for detecting async
for (g->fn_defs_index = 0; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
ZigFn *fn = g->fn_defs.at(g->fn_defs_index);
+ g->trace_err = nullptr;
analyze_fn_async(g, fn, true);
if (fn_is_async(fn) && fn->non_async_node != nullptr) {
ErrorMsg *msg = add_node_error(g, fn->proto_node,
@@ -5143,34 +5076,6 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
}
-void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
- Error err;
- ZigType *wanted_type = const_val->type;
- if (wanted_type->id == ZigTypeIdArray) {
- const_val->special = ConstValSpecialStatic;
- const_val->data.x_array.special = ConstArraySpecialUndef;
- } else if (wanted_type->id == ZigTypeIdStruct) {
- if ((err = ensure_complete_type(g, wanted_type))) {
- return;
- }
-
- const_val->special = ConstValSpecialStatic;
- size_t field_count = wanted_type->data.structure.src_field_count;
- const_val->data.x_struct.fields = create_const_vals(field_count);
- for (size_t i = 0; i < field_count; i += 1) {
- ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
- field_val->type = wanted_type->data.structure.fields[i].type_entry;
- assert(field_val->type);
- init_const_undefined(g, field_val);
- field_val->parent.id = ConstParentIdStruct;
- field_val->parent.data.p_struct.struct_val = const_val;
- field_val->parent.data.p_struct.field_index = i;
- }
- } else {
- const_val->special = ConstValSpecialUndef;
- }
-}
-
ConstExprValue *create_const_vals(size_t count) {
ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count);
ConstExprValue *vals = allocate<ConstExprValue>(count);
@@ -5180,10 +5085,6 @@ ConstExprValue *create_const_vals(size_t count) {
return vals;
}
-Error ensure_complete_type(CodeGen *g, ZigType *type_entry) {
- return type_resolve(g, type_entry, ResolveStatusSizeKnown);
-}
-
static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync)
return orig_fn_type;
@@ -5197,27 +5098,6 @@ static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
return fn_type;
}
-static void emit_error_notes_for_type_loop(CodeGen *g, ErrorMsg *msg, ZigType *stop_type,
- ZigType *ty, AstNode *src_node)
-{
- ErrorMsg *note = add_error_note(g, msg, src_node,
- buf_sprintf("when analyzing type '%s' here", buf_ptr(&ty->name)));
- if (ty == stop_type)
- return;
- switch (ty->id) {
- case ZigTypeIdFnFrame: {
- ty->data.frame.reported_loop_err = true;
- ZigType *depending_type = ty->data.frame.resolve_loop_type;
- if (depending_type == nullptr)
- return;
- emit_error_notes_for_type_loop(g, note, stop_type,
- depending_type, ty->data.frame.resolve_loop_src_node);
- }
- default:
- return;
- }
-}
-
static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
Error err;
@@ -5230,13 +5110,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
if (frame_type->data.frame.resolve_loop_type != nullptr) {
if (!frame_type->data.frame.reported_loop_err) {
frame_type->data.frame.reported_loop_err = true;
- ErrorMsg *msg = add_node_error(g, fn->proto_node,
+ g->trace_err = add_node_error(g, fn->proto_node,
buf_sprintf("'%s' depends on itself", buf_ptr(&frame_type->name)));
- emit_error_notes_for_type_loop(g, msg,
- frame_type,
- frame_type->data.frame.resolve_loop_type,
- frame_type->data.frame.resolve_loop_src_node);
- emit_error_notes_for_ref_stack(g, msg);
}
return ErrorSemanticAnalyzeFail;
}
@@ -5252,11 +5127,9 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
return ErrorSemanticAnalyzeFail;
break;
case FnAnalStateProbing: {
- ErrorMsg *msg = add_node_error(g, fn->proto_node,
+ g->trace_err = add_node_error(g, fn->proto_node,
buf_sprintf("cannot resolve '%s': function not fully analyzed yet",
buf_ptr(&frame_type->name)));
- ir_add_analysis_trace(fn->ir_executable.analysis, msg,
- buf_sprintf("depends on its own frame here"));
return ErrorSemanticAnalyzeFail;
}
}
@@ -5327,10 +5200,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
if (callee->anal_state == FnAnalStateProbing) {
ErrorMsg *msg = add_node_error(g, fn->proto_node,
buf_sprintf("unable to determine async function frame of '%s'", buf_ptr(&fn->symbol_name)));
- ErrorMsg *note = add_error_note(g, msg, call->base.source_node,
+ g->trace_err = add_error_note(g, msg, call->base.source_node,
buf_sprintf("analysis of function '%s' depends on the frame", buf_ptr(&callee->symbol_name)));
- ir_add_analysis_trace(callee->ir_executable.analysis, note,
- buf_sprintf("depends on the frame here"));
return ErrorSemanticAnalyzeFail;
}
@@ -6229,6 +6100,40 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
zig_unreachable();
}
+static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
+ Error err;
+ ZigType *wanted_type = const_val->type;
+ if (wanted_type->id == ZigTypeIdArray) {
+ const_val->special = ConstValSpecialStatic;
+ const_val->data.x_array.special = ConstArraySpecialUndef;
+ } else if (wanted_type->id == ZigTypeIdStruct) {
+ if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) {
+ return;
+ }
+
+ const_val->special = ConstValSpecialStatic;
+ size_t field_count = wanted_type->data.structure.src_field_count;
+ const_val->data.x_struct.fields = create_const_vals(field_count);
+ for (size_t i = 0; i < field_count; i += 1) {
+ ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
+ field_val->type = wanted_type->data.structure.fields[i].type_entry;
+ assert(field_val->type);
+ init_const_undefined(g, field_val);
+ field_val->parent.id = ConstParentIdStruct;
+ field_val->parent.data.p_struct.struct_val = const_val;
+ field_val->parent.data.p_struct.field_index = i;
+ }
+ } else {
+ const_val->special = ConstValSpecialUndef;
+ }
+}
+
+void expand_undef_struct(CodeGen *g, ConstExprValue *const_val) {
+ if (const_val->special == ConstValSpecialUndef) {
+ init_const_undefined(g, const_val);
+ }
+}
+
// Canonicalize the array value as ConstArraySpecialNone
void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
size_t elem_count;
@@ -6707,19 +6612,6 @@ bool ptr_allows_addr_zero(ZigType *ptr_type) {
return false;
}
-void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg) {
- size_t i = g->tld_ref_source_node_stack.length;
- for (;;) {
- if (i == 0)
- break;
- i -= 1;
- AstNode *source_node = g->tld_ref_source_node_stack.at(i);
- if (source_node) {
- msg = add_error_note(g, msg, source_node, buf_sprintf("referenced here"));
- }
- }
-}
-
Buf *type_bare_name(ZigType *type_entry) {
if (is_slice(type_entry)) {
return &type_entry->name;
@@ -7122,10 +7014,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
struct_type->data.structure.resolve_status = ResolveStatusLLVMFull;
}
-static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {
- assert(!enum_type->data.enumeration.is_invalid);
- assert(enum_type->data.enumeration.complete);
- if (enum_type->llvm_di_type != nullptr) return;
+static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatus wanted_resolve_status) {
+ assert(enum_type->data.enumeration.resolve_status >= ResolveStatusSizeKnown);
+ if (enum_type->data.enumeration.resolve_status >= wanted_resolve_status) return;
Scope *scope = &enum_type->data.enumeration.decls_scope->base;
ZigType *import = get_scope_import(scope);
@@ -7146,6 +7037,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {
debug_align_in_bits,
ZigLLVM_DIFlags_Zero,
nullptr, di_element_types, (int)debug_field_count, 0, nullptr, "");
+ enum_type->data.enumeration.resolve_status = ResolveStatusLLVMFull;
return;
}
@@ -7178,6 +7070,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {
get_llvm_di_type(g, tag_int_type), "");
enum_type->llvm_di_type = tag_di_type;
+ enum_type->data.enumeration.resolve_status = ResolveStatusLLVMFull;
}
static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) {
@@ -7909,7 +7802,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
else
return resolve_llvm_types_struct(g, type, wanted_resolve_status, nullptr);
case ZigTypeIdEnum:
- return resolve_llvm_types_enum(g, type);
+ return resolve_llvm_types_enum(g, type, wanted_resolve_status);
case ZigTypeIdUnion:
return resolve_llvm_types_union(g, type, wanted_resolve_status);
case ZigTypeIdPointer:
src/analyze.hpp
@@ -14,7 +14,6 @@ void semantic_analyze(CodeGen *g);
ErrorMsg *add_node_error(CodeGen *g, const AstNode *node, Buf *msg);
ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg);
ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg);
-void emit_error_notes_for_ref_stack(CodeGen *g, ErrorMsg *msg);
ZigType *new_type_table_entry(ZigTypeId id);
ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn);
ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);
@@ -71,7 +70,6 @@ bool type_is_complete(ZigType *type_entry);
bool type_is_resolved(ZigType *type_entry, ResolveStatus status);
bool type_is_invalid(ZigType *type_entry);
bool type_is_global_error_set(ZigType *err_set_type);
-Error resolve_container_type(CodeGen *g, ZigType *type_entry);
ScopeDecls *get_container_scope(ZigType *type_entry);
TypeStructField *find_struct_type_field(ZigType *type_entry, Buf *name);
TypeEnumField *find_enum_type_field(ZigType *enum_type, Buf *name);
@@ -95,7 +93,6 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node);
ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value);
void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);
AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
-Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry);
Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);
void complete_enum(CodeGen *g, ZigType *enum_type);
bool ir_get_var_is_comptime(ZigVar *var);
@@ -169,12 +166,11 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t
void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end);
ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
-void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
-
ConstExprValue *create_const_vals(size_t count);
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
+void expand_undef_struct(CodeGen *g, ConstExprValue *const_val);
void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
const char *type_id_name(ZigTypeId id);
src/ir.cpp
@@ -234,6 +234,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
}
case ConstPtrSpecialBaseStruct: {
ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;
+ expand_undef_struct(g, struct_val);
result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index];
break;
}
@@ -8111,7 +8112,9 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
ir_build_reset_result(irb, scope, node, result_loc);
}
IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
- irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
+ if (result == irb->codegen->invalid_instruction) {
+ src_assert(irb->exec->first_err_trace_msg != nullptr, node);
+ }
return result;
}
@@ -8119,21 +8122,20 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
return ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
}
-static void invalidate_exec(IrExecutable *exec) {
- if (exec->invalid)
+static void invalidate_exec(IrExecutable *exec, ErrorMsg *msg) {
+ if (exec->first_err_trace_msg != nullptr)
return;
- exec->invalid = true;
+ exec->first_err_trace_msg = msg;
for (size_t i = 0; i < exec->tld_list.length; i += 1) {
exec->tld_list.items[i]->resolution = TldResolutionInvalid;
}
if (exec->source_exec != nullptr)
- invalidate_exec(exec->source_exec);
+ invalidate_exec(exec->source_exec, msg);
}
-
bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) {
assert(node->owner);
@@ -8151,8 +8153,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
assert(result);
- if (irb->exec->invalid)
+ if (irb->exec->first_err_trace_msg != nullptr) {
+ codegen->trace_err = irb->exec->first_err_trace_msg;
return false;
+ }
if (!instr_is_unreachable(result)) {
ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result));
@@ -8174,25 +8178,9 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) {
return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable);
}
-static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) {
- if (!exec || !exec->source_node || limit < 0) return;
- add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
-
- ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1);
-}
-
-void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text) {
- IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
- add_error_note(ira->codegen, err_msg, old_instruction->source_node, text);
- ir_add_call_stack_errors(ira->codegen, ira->new_irb.exec, err_msg, 10);
-}
-
static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) {
- invalidate_exec(exec);
ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
- if (exec->parent_exec) {
- ir_add_call_stack_errors(codegen, exec, err_msg, 10);
- }
+ invalidate_exec(exec, err_msg);
return err_msg;
}
@@ -10634,7 +10622,7 @@ static void ir_finish_bb(IrAnalyze *ira) {
static IrInstruction *ir_unreach_error(IrAnalyze *ira) {
ira->old_bb_index = SIZE_MAX;
- ira->new_irb.exec->invalid = true;
+ assert(ira->new_irb.exec->first_err_trace_msg != nullptr);
return ira->codegen->unreach_instruction;
}
@@ -10761,8 +10749,11 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
ir_executable->begin_scope = scope;
ir_gen(codegen, node, scope, ir_executable);
- if (ir_executable->invalid)
+ if (ir_executable->first_err_trace_msg != nullptr) {
+ codegen->trace_err = add_error_note(codegen, ir_executable->first_err_trace_msg,
+ source_node, buf_create_from_str("called from here"));
return &codegen->invalid_instruction->value;
+ }
if (codegen->verbose_ir) {
fprintf(stderr, "\nSource: ");
@@ -10783,8 +10774,9 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
analyzed_executable->backward_branch_quota = backward_branch_quota;
analyzed_executable->begin_scope = scope;
ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node);
- if (type_is_invalid(result_type))
+ if (type_is_invalid(result_type)) {
return &codegen->invalid_instruction->value;
+ }
if (codegen->verbose_ir) {
fprintf(stderr, "{ // (analyzed)\n");
@@ -11322,7 +11314,7 @@ static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruc
IrInstruction *target, ZigType *wanted_type)
{
IrInstruction *result = ir_const(ira, source_instr, wanted_type);
- init_const_undefined(ira->codegen, &result->value);
+ result->value.special = ConstValSpecialUndef;
return result;
}
@@ -11461,7 +11453,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour
ZigType *actual_type = target->value.type;
- if ((err = ensure_complete_type(ira->codegen, wanted_type)))
+ if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
if (actual_type != wanted_type->data.enumeration.tag_int_type) {
@@ -12719,7 +12711,9 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
if (type_is_invalid(operand->value.type))
return ir_unreach_error(ira);
- if (!instr_is_comptime(operand) && handle_is_ptr(ira->explicit_return_type)) {
+ if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr &&
+ handle_is_ptr(ira->explicit_return_type))
+ {
// result location mechanism took care of it.
IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr);
@@ -15513,8 +15507,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
ira->codegen->memoized_fn_eval_table.put(exec_scope, result);
}
- if (type_is_invalid(result->type))
+ if (type_is_invalid(result->type)) {
return ira->codegen->invalid_instruction;
+ }
}
IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type);
@@ -16727,7 +16722,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
bool safety_check_on = elem_ptr_instruction->safety_check_on;
- if ((err = ensure_complete_type(ira->codegen, return_type->data.pointer.child_type)))
+ if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
@@ -17113,7 +17108,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
Error err;
ZigType *bare_type = container_ref_type(container_type);
- if ((err = ensure_complete_type(ira->codegen, bare_type)))
+ if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
assert(container_ptr->value.type->id == ZigTypeIdPointer);
@@ -17243,15 +17238,15 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
}
static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) {
- ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected"));
- emit_error_notes_for_ref_stack(ira->codegen, msg);
+ ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected"));
return ira->codegen->invalid_instruction;
}
static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) {
resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node);
- if (tld->resolution == TldResolutionInvalid)
+ if (tld->resolution == TldResolutionInvalid) {
return ira->codegen->invalid_instruction;
+ }
switch (tld->id) {
case TldIdContainer:
@@ -17396,7 +17391,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
return ira->codegen->invalid_instruction;
} else if (is_container(child_type)) {
if (child_type->id == ZigTypeIdEnum) {
- if ((err = ensure_complete_type(ira->codegen, child_type)))
+ if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
TypeEnumField *field = find_enum_type_field(child_type, field_name);
@@ -17425,7 +17420,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
(child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr ||
child_type->data.unionation.decl_node->data.container_decl.auto_enum))
{
- if ((err = ensure_complete_type(ira->codegen, child_type)))
+ if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
TypeUnionField *field = find_union_type_field(child_type, field_name);
if (field) {
@@ -18008,7 +18003,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira,
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
{
- if ((err = ensure_complete_type(ira->codegen, child_type)))
+ if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
ZigType *result_type = get_array_type(ira->codegen, child_type, size);
return ir_const_type(ira, &array_type_instruction->base, result_type);
@@ -18024,7 +18019,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
IrInstruction *type_value = size_of_instruction->type_value->child;
ZigType *type_entry = ir_resolve_type(ira, type_value);
- if ((err = ensure_complete_type(ira->codegen, type_entry)))
+ if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
switch (type_entry->id) {
@@ -18529,7 +18524,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
if (pointee_val->special == ConstValSpecialRuntime)
pointee_val = nullptr;
}
- if ((err = ensure_complete_type(ira->codegen, target_type)))
+ if ((err = type_resolve(ira->codegen, target_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
switch (target_type->id) {
@@ -19276,8 +19271,7 @@ static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira,
if (!msg_buf)
return ira->codegen->invalid_instruction;
- ErrorMsg *msg = ir_add_error(ira, &instruction->base, msg_buf);
- emit_error_notes_for_ref_stack(ira->codegen, msg);
+ ir_add_error(ira, &instruction->base, msg_buf);
return ira->codegen->invalid_instruction;
}
@@ -19391,7 +19385,7 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
return ira->codegen->invalid_instruction;
}
- if ((err = ensure_complete_type(ira->codegen, container_type)))
+ if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
TypeStructField *field = find_struct_type_field(container_type, field_name);
@@ -19470,7 +19464,7 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira,
return nullptr;
Error err;
- if ((err = ensure_complete_type(ira->codegen, container_type)))
+ if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
return nullptr;
Buf *field_name = ir_resolve_str(ira, field_name_value);
@@ -19574,7 +19568,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
ZigVar *var = tld->var;
- if ((err = ensure_complete_type(ira->codegen, var->const_value->type)))
+ if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown)))
return ira->codegen->builtin_types.entry_invalid;
assert(var->const_value->type->id == ZigTypeIdMetaType);
@@ -19594,15 +19588,15 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
ensure_field_index(type_info_declaration_type, "data", 2);
ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
- if ((err = ensure_complete_type(ira->codegen, type_info_declaration_data_type)))
+ if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))
return err;
ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type);
- if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_type)))
+ if ((err = type_resolve(ira->codegen, type_info_fn_decl_type, ResolveStatusSizeKnown)))
return err;
ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type);
- if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_inline_type)))
+ if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown)))
return err;
// Loop through our declarations once to figure out how many declarations we will generate info for.
@@ -19673,7 +19667,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
case TldIdVar:
{
ZigVar *var = ((TldVar *)curr_entry->value)->var;
- if ((err = ensure_complete_type(ira->codegen, var->const_value->type)))
+ if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown)))
return ErrorSemanticAnalyzeFail;
if (var->const_value->type->id == ZigTypeIdMetaType) {
@@ -19799,7 +19793,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
case TldIdContainer:
{
ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry;
- if ((err = ensure_complete_type(ira->codegen, type_entry)))
+ if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))
return ErrorSemanticAnalyzeFail;
// This is a type.
@@ -19855,7 +19849,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
return nullptr;
ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr);
- assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_type));
+ assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown));
ConstExprValue *result = create_const_vals(1);
result->special = ConstValSpecialStatic;
@@ -19867,7 +19861,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
// size: Size
ensure_field_index(result->type, "size", 0);
ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type);
- assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_size_type));
+ assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown));
fields[0].special = ConstValSpecialStatic;
fields[0].type = type_info_pointer_size_type;
bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index);
@@ -22021,7 +22015,7 @@ static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInst
return ira->codegen->invalid_instruction;
ZigType *container_type = ir_resolve_type(ira, container);
- if ((err = ensure_complete_type(ira->codegen, container_type)))
+ if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
uint64_t result;
@@ -22057,7 +22051,7 @@ static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstr
if (type_is_invalid(container_type))
return ira->codegen->invalid_instruction;
- if ((err = ensure_complete_type(ira->codegen, container_type)))
+ if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
@@ -22100,7 +22094,7 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr
if (type_is_invalid(container_type))
return ira->codegen->invalid_instruction;
- if ((err = ensure_complete_type(ira->codegen, container_type)))
+ if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
uint64_t member_index;
@@ -23309,8 +23303,10 @@ static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExp
}
static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
- if (val->special == ConstValSpecialUndef)
+ if (val->special == ConstValSpecialUndef) {
+ expand_undef_struct(codegen, val);
val->special = ConstValSpecialStatic;
+ }
assert(val->special == ConstValSpecialStatic);
switch (val->type->id) {
case ZigTypeIdInvalid:
@@ -23746,8 +23742,9 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
IrInstructionDeclRef *instruction)
{
IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld);
- if (type_is_invalid(ref_instruction->value.type))
+ if (type_is_invalid(ref_instruction->value.type)) {
return ira->codegen->invalid_instruction;
+ }
if (instruction->lval == LValPtr) {
return ref_instruction;
@@ -23954,7 +23951,7 @@ static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
if (enum_type->id == ZigTypeIdEnum) {
- if ((err = ensure_complete_type(ira->codegen, enum_type)))
+ if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type);
@@ -25100,7 +25097,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec,
ZigType *expected_type, AstNode *expected_type_source_node)
{
- assert(!old_exec->invalid);
+ assert(old_exec->first_err_trace_msg == nullptr);
assert(expected_type == nullptr || !type_is_invalid(expected_type));
IrAnalyze *ira = allocate<IrAnalyze>(1);
@@ -25147,6 +25144,15 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
old_instruction->child = new_instruction;
if (type_is_invalid(new_instruction->value.type)) {
+ if (new_exec->first_err_trace_msg != nullptr) {
+ ira->codegen->trace_err = new_exec->first_err_trace_msg;
+ } else {
+ new_exec->first_err_trace_msg = ira->codegen->trace_err;
+ }
+ if (new_exec->first_err_trace_msg != nullptr) {
+ new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg,
+ old_instruction->source_node, buf_create_from_str("referenced here"));
+ }
return ira->codegen->builtin_types.entry_invalid;
}
@@ -25158,7 +25164,12 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
ira->instruction_index += 1;
}
- if (new_exec->invalid) {
+ if (new_exec->first_err_trace_msg != nullptr) {
+ codegen->trace_err = new_exec->first_err_trace_msg;
+ if (codegen->trace_err != nullptr) {
+ codegen->trace_err = add_error_note(codegen, codegen->trace_err,
+ new_exec->source_node, buf_create_from_str("referenced here"));
+ }
return ira->codegen->builtin_types.entry_invalid;
} else if (ira->src_implicit_return_type_list.length == 0) {
return codegen->builtin_types.entry_unreachable;
src/ir.hpp
@@ -28,6 +28,4 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal
AstNode *source_node);
const char *float_op_to_name(BuiltinFnId op, bool llvm_name);
-void ir_add_analysis_trace(IrAnalyze *ira, ErrorMsg *err_msg, Buf *text);
-
#endif