Commit 349cd79fe4
Changed files (5)
src/all_types.hpp
@@ -57,6 +57,7 @@ struct IrExecutable {
Buf *c_import_buf;
AstNode *source_node;
IrExecutable *parent_exec;
+ Scope *begin_scope;
};
enum OutType {
src/analyze.cpp
@@ -3381,3 +3381,175 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
zig_unreachable();
}
}
+
+void render_const_value(Buf *buf, ConstExprValue *const_val) {
+ switch (const_val->special) {
+ case ConstValSpecialRuntime:
+ zig_unreachable();
+ case ConstValSpecialUndef:
+ buf_appendf(buf, "undefined");
+ return;
+ case ConstValSpecialZeroes:
+ buf_appendf(buf, "zeroes");
+ return;
+ case ConstValSpecialStatic:
+ break;
+ }
+ assert(const_val->type);
+
+ TypeTableEntry *canon_type = get_underlying_type(const_val->type);
+ switch (canon_type->id) {
+ case TypeTableEntryIdTypeDecl:
+ zig_unreachable();
+ case TypeTableEntryIdInvalid:
+ buf_appendf(buf, "(invalid)");
+ return;
+ case TypeTableEntryIdVar:
+ buf_appendf(buf, "(var)");
+ return;
+ case TypeTableEntryIdVoid:
+ buf_appendf(buf, "{}");
+ return;
+ case TypeTableEntryIdNumLitFloat:
+ buf_appendf(buf, "%f", const_val->data.x_bignum.data.x_float);
+ return;
+ case TypeTableEntryIdNumLitInt:
+ {
+ BigNum *bignum = &const_val->data.x_bignum;
+ const char *negative_str = bignum->is_negative ? "-" : "";
+ buf_appendf(buf, "%s%llu", negative_str, bignum->data.x_uint);
+ return;
+ }
+ case TypeTableEntryIdMetaType:
+ buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name));
+ return;
+ case TypeTableEntryIdInt:
+ {
+ BigNum *bignum = &const_val->data.x_bignum;
+ assert(bignum->kind == BigNumKindInt);
+ const char *negative_str = bignum->is_negative ? "-" : "";
+ buf_appendf(buf, "%s%llu", negative_str, bignum->data.x_uint);
+ }
+ return;
+ case TypeTableEntryIdFloat:
+ {
+ BigNum *bignum = &const_val->data.x_bignum;
+ assert(bignum->kind == BigNumKindFloat);
+ buf_appendf(buf, "%f", bignum->data.x_float);
+ }
+ return;
+ case TypeTableEntryIdUnreachable:
+ buf_appendf(buf, "@unreachable()");
+ return;
+ case TypeTableEntryIdBool:
+ {
+ const char *value = const_val->data.x_bool ? "true" : "false";
+ buf_appendf(buf, "%s", value);
+ return;
+ }
+ case TypeTableEntryIdPointer:
+ buf_appendf(buf, "&");
+ if (const_val->data.x_ptr.special == ConstPtrSpecialRuntime) {
+ buf_appendf(buf, "(runtime pointer value)");
+ } else if (const_val->data.x_ptr.special == ConstPtrSpecialCStr) {
+ buf_appendf(buf, "(c str lit)");
+ } else {
+ render_const_value(buf, const_ptr_pointee(const_val));
+ }
+ return;
+ case TypeTableEntryIdFn:
+ {
+ FnTableEntry *fn_entry = const_val->data.x_fn;
+ buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name));
+ return;
+ }
+ case TypeTableEntryIdBlock:
+ {
+ AstNode *node = const_val->data.x_block->source_node;
+ buf_appendf(buf, "(scope:%zu:%zu)", node->line + 1, node->column + 1);
+ return;
+ }
+ case TypeTableEntryIdArray:
+ {
+ uint64_t len = canon_type->data.array.len;
+ buf_appendf(buf, "%s{", buf_ptr(&canon_type->name));
+ for (uint64_t i = 0; i < len; i += 1) {
+ if (i != 0)
+ buf_appendf(buf, ",");
+ ConstExprValue *child_value = &const_val->data.x_array.elements[i];
+ render_const_value(buf, child_value);
+ }
+ buf_appendf(buf, "}");
+ return;
+ }
+ case TypeTableEntryIdNullLit:
+ {
+ buf_appendf(buf, "null");
+ return;
+ }
+ case TypeTableEntryIdUndefLit:
+ {
+ buf_appendf(buf, "undefined");
+ return;
+ }
+ case TypeTableEntryIdMaybe:
+ {
+ if (const_val->data.x_maybe) {
+ render_const_value(buf, const_val->data.x_maybe);
+ } else {
+ buf_appendf(buf, "null");
+ }
+ return;
+ }
+ case TypeTableEntryIdNamespace:
+ {
+ ImportTableEntry *import = const_val->data.x_import;
+ if (import->c_import_node) {
+ buf_appendf(buf, "(namespace from C import)");
+ } else {
+ buf_appendf(buf, "(namespace: %s)", buf_ptr(import->path));
+ }
+ return;
+ }
+ case TypeTableEntryIdBoundFn:
+ {
+ FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn;
+ buf_appendf(buf, "(bound fn %s)", buf_ptr(&fn_entry->symbol_name));
+ return;
+ }
+ case TypeTableEntryIdStruct:
+ {
+ buf_appendf(buf, "(struct %s constant)", buf_ptr(&canon_type->name));
+ return;
+ }
+ case TypeTableEntryIdEnum:
+ {
+ buf_appendf(buf, "(enum %s constant)", buf_ptr(&canon_type->name));
+ return;
+ }
+ case TypeTableEntryIdErrorUnion:
+ {
+ buf_appendf(buf, "(error union %s constant)", buf_ptr(&canon_type->name));
+ return;
+ }
+ case TypeTableEntryIdUnion:
+ {
+ buf_appendf(buf, "(union %s constant)", buf_ptr(&canon_type->name));
+ return;
+ }
+ case TypeTableEntryIdPureError:
+ {
+ buf_appendf(buf, "(pure error constant)");
+ return;
+ }
+ case TypeTableEntryIdEnumTag:
+ {
+ TypeTableEntry *enum_type = canon_type->data.enum_tag.enum_type;
+ TypeEnumField *field = &enum_type->data.enumeration.fields[const_val->data.x_bignum.data.x_uint];
+ buf_appendf(buf, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name));
+ return;
+ }
+ }
+ zig_unreachable();
+}
+
src/analyze.hpp
@@ -82,6 +82,8 @@ bool ir_get_var_is_comptime(VariableTableEntry *var);
bool const_values_equal(ConstExprValue *a, ConstExprValue *b);
void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max);
+void render_const_value(Buf *buf, ConstExprValue *const_val);
+
ScopeBlock *create_block_scope(AstNode *node, Scope *parent);
ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);
ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent);
src/ir.cpp
@@ -117,6 +117,7 @@ static void ir_ref_bb(IrBasicBlock *bb) {
}
static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) {
+ assert(instruction->id != IrInstructionIdInvalid);
instruction->ref_count += 1;
if (instruction->owner_bb != cur_bb)
ir_ref_bb(instruction->owner_bb);
@@ -3095,7 +3096,13 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope);
+ if (op1 == irb->codegen->invalid_instruction)
+ return op1;
+
IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
+ if (op2 == irb->codegen->invalid_instruction)
+ return op2;
+
return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true);
}
@@ -3956,6 +3963,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
for (size_t i = 0; i < arg_count; i += 1) {
AstNode *arg_node = node->data.fn_call_expr.params.at(i);
args[i] = ir_gen_node(irb, arg_node, scope);
+ if (args[i] == irb->codegen->invalid_instruction)
+ return args[i];
}
bool is_comptime = node->data.fn_call_expr.is_comptime;
@@ -4946,6 +4955,19 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
}
+static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope *inner_scope) {
+ if (inner_scope == nullptr || inner_scope == outer_scope) return false;
+ bool need_comma = render_instance_name_recursive(name, outer_scope, inner_scope->parent);
+ if (inner_scope->id != ScopeIdVarDecl)
+ return need_comma;
+
+ ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
+ if (need_comma)
+ buf_append_char(name, ',');
+ render_const_value(name, &var_scope->var->value);
+ return true;
+}
+
static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
assert(node->type == NodeTypeContainerDecl);
@@ -4959,9 +4981,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
name = buf_alloc();
buf_append_buf(name, &fn_entry->symbol_name);
buf_appendf(name, "(");
- // TODO render args. note that fn_type_id is likely not complete
- // at this time.
- // probably have to render them from the fn scope
+ render_instance_name_recursive(name, &fn_entry->fndef_scope->base, irb->exec->begin_scope);
buf_appendf(name, ")");
} else {
name = buf_sprintf("(anonymous %s at %s:%zu:%zu)", container_string(kind),
@@ -5822,6 +5842,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
ir_executable.is_inline = true;
ir_executable.fn_entry = fn_entry;
ir_executable.c_import_buf = c_import_buf;
+ ir_executable.begin_scope = scope;
ir_gen(codegen, node, scope, &ir_executable);
if (ir_executable.invalid)
@@ -5843,6 +5864,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
analyzed_executable.c_import_buf = c_import_buf;
analyzed_executable.backward_branch_count = backward_branch_count;
analyzed_executable.backward_branch_quota = backward_branch_quota;
+ analyzed_executable.begin_scope = scope;
TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node);
if (result_type->id == TypeTableEntryIdInvalid)
return codegen->invalid_instruction;
src/ir_print.cpp
@@ -32,175 +32,10 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) {
}
static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) {
- switch (const_val->special) {
- case ConstValSpecialRuntime:
- zig_unreachable();
- case ConstValSpecialUndef:
- fprintf(irp->f, "undefined");
- return;
- case ConstValSpecialZeroes:
- fprintf(irp->f, "zeroes");
- return;
- case ConstValSpecialStatic:
- break;
- }
- assert(const_val->type);
-
- TypeTableEntry *canon_type = get_underlying_type(const_val->type);
- switch (canon_type->id) {
- case TypeTableEntryIdTypeDecl:
- zig_unreachable();
- case TypeTableEntryIdInvalid:
- fprintf(irp->f, "(invalid)");
- return;
- case TypeTableEntryIdVar:
- fprintf(irp->f, "(var)");
- return;
- case TypeTableEntryIdVoid:
- fprintf(irp->f, "{}");
- return;
- case TypeTableEntryIdNumLitFloat:
- fprintf(irp->f, "%f", const_val->data.x_bignum.data.x_float);
- return;
- case TypeTableEntryIdNumLitInt:
- {
- BigNum *bignum = &const_val->data.x_bignum;
- const char *negative_str = bignum->is_negative ? "-" : "";
- fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);
- return;
- }
- case TypeTableEntryIdMetaType:
- fprintf(irp->f, "%s", buf_ptr(&const_val->data.x_type->name));
- return;
- case TypeTableEntryIdInt:
- {
- BigNum *bignum = &const_val->data.x_bignum;
- assert(bignum->kind == BigNumKindInt);
- const char *negative_str = bignum->is_negative ? "-" : "";
- fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);
- }
- return;
- case TypeTableEntryIdFloat:
- {
- BigNum *bignum = &const_val->data.x_bignum;
- assert(bignum->kind == BigNumKindFloat);
- fprintf(irp->f, "%f", bignum->data.x_float);
- }
- return;
- case TypeTableEntryIdUnreachable:
- fprintf(irp->f, "@unreachable()");
- return;
- case TypeTableEntryIdBool:
- {
- const char *value = const_val->data.x_bool ? "true" : "false";
- fprintf(irp->f, "%s", value);
- return;
- }
- case TypeTableEntryIdPointer:
- fprintf(irp->f, "&");
- if (const_val->data.x_ptr.special == ConstPtrSpecialRuntime) {
- fprintf(irp->f, "(runtime pointer value)");
- } else if (const_val->data.x_ptr.special == ConstPtrSpecialCStr) {
- fprintf(irp->f, "(c str lit)");
- } else {
- ir_print_const_value(irp, const_ptr_pointee(const_val));
- }
- return;
- case TypeTableEntryIdFn:
- {
- FnTableEntry *fn_entry = const_val->data.x_fn;
- fprintf(irp->f, "%s", buf_ptr(&fn_entry->symbol_name));
- return;
- }
- case TypeTableEntryIdBlock:
- {
- AstNode *node = const_val->data.x_block->source_node;
- fprintf(irp->f, "(scope:%zu:%zu)", node->line + 1, node->column + 1);
- return;
- }
- case TypeTableEntryIdArray:
- {
- uint64_t len = canon_type->data.array.len;
- fprintf(irp->f, "%s{", buf_ptr(&canon_type->name));
- for (uint64_t i = 0; i < len; i += 1) {
- if (i != 0)
- fprintf(irp->f, ",");
- ConstExprValue *child_value = &const_val->data.x_array.elements[i];
- ir_print_const_value(irp, child_value);
- }
- fprintf(irp->f, "}");
- return;
- }
- case TypeTableEntryIdNullLit:
- {
- fprintf(irp->f, "null");
- return;
- }
- case TypeTableEntryIdUndefLit:
- {
- fprintf(irp->f, "undefined");
- return;
- }
- case TypeTableEntryIdMaybe:
- {
- if (const_val->data.x_maybe) {
- ir_print_const_value(irp, const_val->data.x_maybe);
- } else {
- fprintf(irp->f, "null");
- }
- return;
- }
- case TypeTableEntryIdNamespace:
- {
- ImportTableEntry *import = const_val->data.x_import;
- if (import->c_import_node) {
- fprintf(irp->f, "(namespace from C import)");
- } else {
- fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));
- }
- return;
- }
- case TypeTableEntryIdBoundFn:
- {
- FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn;
- fprintf(irp->f, "bound %s to ", buf_ptr(&fn_entry->symbol_name));
- ir_print_other_instruction(irp, const_val->data.x_bound_fn.first_arg);
- return;
- }
- case TypeTableEntryIdStruct:
- {
- fprintf(irp->f, "(struct %s constant)", buf_ptr(&canon_type->name));
- return;
- }
- case TypeTableEntryIdEnum:
- {
- fprintf(irp->f, "(enum %s constant)", buf_ptr(&canon_type->name));
- return;
- }
- case TypeTableEntryIdErrorUnion:
- {
- fprintf(irp->f, "(error union %s constant)", buf_ptr(&canon_type->name));
- return;
- }
- case TypeTableEntryIdUnion:
- {
- fprintf(irp->f, "(union %s constant)", buf_ptr(&canon_type->name));
- return;
- }
- case TypeTableEntryIdPureError:
- {
- fprintf(irp->f, "(pure error constant)");
- return;
- }
- case TypeTableEntryIdEnumTag:
- {
- TypeTableEntry *enum_type = canon_type->data.enum_tag.enum_type;
- TypeEnumField *field = &enum_type->data.enumeration.fields[const_val->data.x_bignum.data.x_uint];
- fprintf(irp->f, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name));
- return;
- }
- }
- zig_unreachable();
+ Buf buf = BUF_INIT;
+ buf_resize(&buf, 0);
+ render_const_value(&buf, const_val);
+ fprintf(irp->f, "%s", buf_ptr(&buf));
}
static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) {