diff options
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 246 |
1 files changed, 236 insertions, 10 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 86f7cb7702..2210a17da3 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -593,9 +593,9 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con } if (inferred_struct_field != nullptr) { - entry->abi_size = g->builtin_types.entry_usize->abi_size; - entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; - entry->abi_align = g->builtin_types.entry_usize->abi_align; + entry->abi_size = SIZE_MAX; + entry->size_in_bits = SIZE_MAX; + entry->abi_align = UINT32_MAX; } else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) { if (type_has_bits(child_type)) { entry->abi_size = g->builtin_types.entry_usize->abi_size; @@ -1102,11 +1102,28 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name, UndefAllowed undef) { + Error err; + + ZigValue *result = create_const_vals(1); + ZigValue *result_ptr = create_const_vals(1); + result->special = ConstValSpecialUndef; + result->type = (type_entry == nullptr) ? g->builtin_types.entry_var : type_entry; + result_ptr->special = ConstValSpecialStatic; + result_ptr->type = get_pointer_to_type(g, result->type, false); + result_ptr->data.x_ptr.mut = ConstPtrMutComptimeVar; + result_ptr->data.x_ptr.special = ConstPtrSpecialRef; + result_ptr->data.x_ptr.data.ref.pointee = result; + size_t backward_branch_count = 0; size_t backward_branch_quota = default_backward_branch_quota; - return ir_eval_const_value(g, scope, node, type_entry, + if ((err = ir_eval_const_value(g, scope, node, result_ptr, &backward_branch_count, &backward_branch_quota, - nullptr, nullptr, node, type_name, nullptr, nullptr, undef); + nullptr, nullptr, node, type_name, nullptr, nullptr, undef))) + { + return g->invalid_inst_gen->value; + } + destroy(result_ptr, "ZigValue"); + return result; } Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent_type, @@ -3829,7 +3846,6 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf variable_entry->var_type = var_type; variable_entry->parent_scope = parent_scope; variable_entry->shadowable = false; - variable_entry->mem_slot_index = SIZE_MAX; variable_entry->src_arg_index = SIZE_MAX; assert(name); @@ -3930,7 +3946,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { // TODO more validation for types that can't be used for export/extern variables ZigType *implicit_type = nullptr; - if (explicit_type && explicit_type->id == ZigTypeIdInvalid) { + if (explicit_type != nullptr && explicit_type->id == ZigTypeIdInvalid) { implicit_type = explicit_type; } else if (var_decl->expr) { init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, @@ -4718,8 +4734,14 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) { assert(!fn_type->data.fn.is_generic); FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; + if (fn->analyzed_executable.begin_scope == nullptr) { + fn->analyzed_executable.begin_scope = &fn->def_scope->base; + } + if (fn->analyzed_executable.source_node == nullptr) { + fn->analyzed_executable.source_node = fn->body_node; + } ZigType *block_return_type = ir_analyze(g, fn->ir_executable, - &fn->analyzed_executable, fn_type_id->return_type, return_type_node); + &fn->analyzed_executable, fn_type_id->return_type, return_type_node, nullptr); fn->src_implicit_return_type = block_return_type; if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) { @@ -5619,6 +5641,8 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { return OnePossibleValueYes; return type_has_one_possible_value(g, type_entry->data.array.child_type); case ZigTypeIdStruct: + // If the recursive function call asks, then we are not one possible value. + type_entry->one_possible_value = OnePossibleValueNo; for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { TypeStructField *field = type_entry->data.structure.fields[i]; OnePossibleValue opv = (field->type_entry != nullptr) ? @@ -5626,6 +5650,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { type_val_resolve_has_one_possible_value(g, field->type_val); switch (opv) { case OnePossibleValueInvalid: + type_entry->one_possible_value = OnePossibleValueInvalid; return OnePossibleValueInvalid; case OnePossibleValueNo: return OnePossibleValueNo; @@ -5633,6 +5658,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { continue; } } + type_entry->one_possible_value = OnePossibleValueYes; return OnePossibleValueYes; case ZigTypeIdErrorSet: case ZigTypeIdEnum: @@ -5678,6 +5704,9 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) { assert(field_type != nullptr); result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type); } + } else if (result->type->id == ZigTypeIdPointer) { + result->data.x_ptr.special = ConstPtrSpecialRef; + result->data.x_ptr.data.ref.pointee = get_the_one_possible_value(g, result->type->data.pointer.child_type); } g->one_possible_values.put(type_entry, result); return result; @@ -6452,7 +6481,21 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) { } ty->data.pointer.resolve_loop_flag_zero_bits = true; - ZigType *elem_type = ty->data.pointer.child_type; + ZigType *elem_type; + InferredStructField *isf = ty->data.pointer.inferred_struct_field; + if (isf != nullptr) { + TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); + assert(field != nullptr); + if (field->is_comptime) { + ty->abi_size = 0; + ty->size_in_bits = 0; + ty->abi_align = 0; + return ErrorNone; + } + elem_type = field->type_entry; + } else { + elem_type = ty->data.pointer.child_type; + } bool has_bits; if ((err = type_has_bits2(g, elem_type, &has_bits))) @@ -6875,6 +6918,7 @@ static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ZigValu } case ConstArraySpecialNone: { ZigValue *base = &array->data.s_none.elements[start]; + assert(base != nullptr); assert(start + len <= const_val->type->data.array.len); buf_appendf(buf, "%s{", buf_ptr(type_name)); @@ -6890,6 +6934,10 @@ static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ZigValu } void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val) { + if (const_val == nullptr) { + buf_appendf(buf, "(invalid nullptr value)"); + return; + } switch (const_val->special) { case ConstValSpecialRuntime: buf_appendf(buf, "(runtime value)"); @@ -9295,10 +9343,13 @@ bool type_has_optional_repr(ZigType *ty) { } void copy_const_val(ZigValue *dest, ZigValue *src) { + uint32_t prev_align = dest->llvm_align; + ConstParent prev_parent = dest->parent; memcpy(dest, src, sizeof(ZigValue)); + dest->llvm_align = prev_align; if (src->special != ConstValSpecialStatic) return; - dest->parent.id = ConstParentIdNone; + dest->parent = prev_parent; if (dest->type->id == ZigTypeIdStruct) { dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { @@ -9307,6 +9358,16 @@ void copy_const_val(ZigValue *dest, ZigValue *src) { dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest; dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i; } + } else if (dest->type->id == ZigTypeIdArray) { + if (dest->data.x_array.special == ConstArraySpecialNone) { + dest->data.x_array.data.s_none.elements = create_const_vals(dest->type->data.array.len); + for (uint64_t i = 0; i < dest->type->data.array.len; i += 1) { + copy_const_val(&dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]); + dest->data.x_array.data.s_none.elements[i].parent.id = ConstParentIdArray; + dest->data.x_array.data.s_none.elements[i].parent.data.p_array.array_val = dest; + dest->data.x_array.data.s_none.elements[i].parent.data.p_array.elem_index = i; + } + } } else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) { dest->data.x_optional = create_const_vals(1); copy_const_val(dest->data.x_optional, src->data.x_optional); @@ -9353,6 +9414,171 @@ bool type_is_numeric(ZigType *ty) { zig_unreachable(); } +static void dump_value_indent(ZigValue *val, int indent) { + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, "Value@%p(", val); + if (val->type != nullptr) { + fprintf(stderr, "%s)", buf_ptr(&val->type->name)); + } else { + fprintf(stderr, "type=nullptr)"); + } + switch (val->special) { + case ConstValSpecialUndef: + fprintf(stderr, "[undefined]\n"); + return; + case ConstValSpecialLazy: + fprintf(stderr, "[lazy]\n"); + return; + case ConstValSpecialRuntime: + fprintf(stderr, "[runtime]\n"); + return; + case ConstValSpecialStatic: + break; + } + if (val->type == nullptr) + return; + switch (val->type->id) { + case ZigTypeIdInvalid: + fprintf(stderr, "<invalid>\n"); + return; + case ZigTypeIdUnreachable: + fprintf(stderr, "<unreachable>\n"); + return; + case ZigTypeIdUndefined: + fprintf(stderr, "<undefined>\n"); + return; + case ZigTypeIdVoid: + fprintf(stderr, "<{}>\n"); + return; + case ZigTypeIdMetaType: + fprintf(stderr, "<%s>\n", buf_ptr(&val->data.x_type->name)); + return; + case ZigTypeIdBool: + fprintf(stderr, "<%s>\n", val->data.x_bool ? "true" : "false"); + return; + case ZigTypeIdComptimeInt: + case ZigTypeIdInt: { + Buf *tmp_buf = buf_alloc(); + bigint_append_buf(tmp_buf, &val->data.x_bigint, 10); + fprintf(stderr, "<%s>\n", buf_ptr(tmp_buf)); + buf_destroy(tmp_buf); + return; + } + case ZigTypeIdComptimeFloat: + case ZigTypeIdFloat: + fprintf(stderr, "<TODO dump number>\n"); + return; + + case ZigTypeIdStruct: + fprintf(stderr, "<struct\n"); + for (size_t i = 0; i < val->type->data.structure.src_field_count; i += 1) { + for (int j = 0; j < indent; j += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, "%s: ", buf_ptr(val->type->data.structure.fields[i]->name)); + if (val->data.x_struct.fields == nullptr) { + fprintf(stderr, "<null>\n"); + } else { + dump_value_indent(val->data.x_struct.fields[i], 1); + } + } + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, ">\n"); + return; + + case ZigTypeIdOptional: + fprintf(stderr, "<\n"); + dump_value_indent(val->data.x_optional, indent + 1); + + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, ">\n"); + return; + + case ZigTypeIdErrorUnion: + if (val->data.x_err_union.payload != nullptr) { + fprintf(stderr, "<\n"); + dump_value_indent(val->data.x_err_union.payload, indent + 1); + } else { + fprintf(stderr, "<\n"); + dump_value_indent(val->data.x_err_union.error_set, 0); + } + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, ">\n"); + return; + + case ZigTypeIdPointer: + switch (val->data.x_ptr.special) { + case ConstPtrSpecialInvalid: + fprintf(stderr, "<!invalid ptr!>\n"); + return; + case ConstPtrSpecialRef: + fprintf(stderr, "<ref\n"); + dump_value_indent(val->data.x_ptr.data.ref.pointee, indent + 1); + break; + case ConstPtrSpecialBaseStruct: { + ZigValue *struct_val = val->data.x_ptr.data.base_struct.struct_val; + size_t field_index = val->data.x_ptr.data.base_struct.field_index; + fprintf(stderr, "<struct %p field %zu\n", struct_val, field_index); + if (struct_val != nullptr) { + ZigValue *field_val = struct_val->data.x_struct.fields[field_index]; + if (field_val != nullptr) { + dump_value_indent(field_val, indent + 1); + } else { + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, "(invalid null field)\n"); + } + } + break; + } + case ConstPtrSpecialBaseOptionalPayload: { + ZigValue *optional_val = val->data.x_ptr.data.base_optional_payload.optional_val; + fprintf(stderr, "<optional %p payload\n", optional_val); + if (optional_val != nullptr) { + dump_value_indent(optional_val, indent + 1); + } + break; + } + default: + fprintf(stderr, "TODO dump more pointer things\n"); + } + for (int i = 0; i < indent; i += 1) { + fprintf(stderr, " "); + } + fprintf(stderr, ">\n"); + return; + + case ZigTypeIdVector: + case ZigTypeIdArray: + case ZigTypeIdNull: + case ZigTypeIdErrorSet: + case ZigTypeIdEnum: + case ZigTypeIdUnion: + case ZigTypeIdFn: + case ZigTypeIdBoundFn: + case ZigTypeIdOpaque: + case ZigTypeIdFnFrame: + case ZigTypeIdAnyFrame: + case ZigTypeIdEnumLiteral: + fprintf(stderr, "<TODO dump value>\n"); + return; + } + zig_unreachable(); +} + +void ZigValue::dump() { + dump_value_indent(this, 0); +} + // float ops that take a single argument //TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign, lround, llround, lrint, llrint const char *float_op_to_name(BuiltinFnId op) { |
