mirror of
https://github.com/ziglang/zig.git
synced 2026-01-03 03:53:20 +00:00
containers created during eval get names for parameters
This commit is contained in:
parent
27a633b32a
commit
349cd79fe4
@ -57,6 +57,7 @@ struct IrExecutable {
|
||||
Buf *c_import_buf;
|
||||
AstNode *source_node;
|
||||
IrExecutable *parent_exec;
|
||||
Scope *begin_scope;
|
||||
};
|
||||
|
||||
enum OutType {
|
||||
|
||||
172
src/analyze.cpp
172
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();
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
28
src/ir.cpp
28
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;
|
||||
|
||||
173
src/ir_print.cpp
173
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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user