Commit 349cd79fe4

Andrew Kelley <superjoe30@gmail.com>
2017-01-05 09:22:00
containers created during eval get names for parameters
1 parent 27a633b
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) {