From 523e3b86af44b97bcf68e3eb0956ef297421ee10 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 22 Jan 2016 22:02:07 -0700 Subject: [PATCH] support statically initialized array literal --- src/analyze.cpp | 20 ++++++++++++++++---- src/codegen.cpp | 10 ++-------- std/std.zig | 6 +++--- test/run_tests.cpp | 18 +++++++++++++++++- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 56eb138a65..cc061a6b85 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -34,8 +34,6 @@ static AstNode *first_executing_node(AstNode *node) { return first_executing_node(node->data.field_access_expr.struct_expr); case NodeTypeSwitchRange: return first_executing_node(node->data.switch_range.start); - case NodeTypeContainerInitExpr: - return first_executing_node(node->data.container_init_expr.type); case NodeTypeRoot: case NodeTypeRootExportDecl: case NodeTypeFnProto: @@ -72,6 +70,7 @@ static AstNode *first_executing_node(AstNode *node) { case NodeTypeSwitchExpr: case NodeTypeSwitchProng: case NodeTypeArrayType: + case NodeTypeContainerInitExpr: return node; } zig_unreachable(); @@ -1586,9 +1585,22 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry assert(pointer_type->id == TypeTableEntryIdPointer); TypeTableEntry *child_type = pointer_type->data.pointer.child_type; + ConstExprValue *const_val = &get_resolved_expr(node)->const_val; + const_val->ok = true; + const_val->data.x_array.fields = allocate(elem_count); + for (int i = 0; i < elem_count; i += 1) { - AstNode *elem_node = container_init_expr->entries.at(i); - analyze_expression(g, import, context, child_type, elem_node); + AstNode **elem_node = &container_init_expr->entries.at(i); + analyze_expression(g, import, context, child_type, *elem_node); + + if (const_val->ok) { + ConstExprValue *elem_const_val = &get_resolved_expr(*elem_node)->const_val; + if (elem_const_val->ok) { + const_val->data.x_array.fields[i] = elem_const_val; + } else { + const_val->ok = false; + } + } } TypeTableEntry *fixed_size_array_type = get_array_type(g, child_type, elem_count); diff --git a/src/codegen.cpp b/src/codegen.cpp index 467740e946..6a5008b94e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2105,13 +2105,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE return tag_value; } else { zig_panic("TODO"); - /* - LLVMValueRef fields[] = { - tag_value, - union_value, - }; - return LLVMConstStruct(fields, 2, false); - */ } } else if (type_entry->id == TypeTableEntryIdFn) { return const_val->data.x_fn->fn_value; @@ -2197,10 +2190,11 @@ static void do_code_gen(CodeGen *g) { } else { init_val = LLVMConstNull(var->type->type_ref); } - LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), ""); + LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), buf_ptr(&var->name)); LLVMSetInitializer(global_value, init_val); LLVMSetGlobalConstant(global_value, var->is_const); LLVMSetUnnamedAddr(global_value, true); + LLVMSetLinkage(global_value, LLVMInternalLinkage); var->value_ref = global_value; } diff --git a/std/std.zig b/std/std.zig index 94a12fc0e6..f8cd598f26 100644 --- a/std/std.zig +++ b/std/std.zig @@ -12,14 +12,14 @@ pub var stdin = InStream { pub var stdout = OutStream { .fd = stdout_fileno, - .buffer = uninitialized, + .buffer = undefined, .index = 0, .buffered = true, }; pub var stderr = OutStream { .fd = stderr_fileno, - .buffer = uninitialized, + .buffer = undefined, .index = 0, .buffered = false, }; @@ -34,7 +34,7 @@ pub %.BadPerm; pub %.PipeFail; */ -//const buffer_size: u16 = 4 * 1024; +//const buffer_size = 4 * 1024; const max_u64_base10_digits: isize = 20; /* diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 9a06deb2a9..d4ff895351 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -1244,6 +1244,20 @@ pub fn main(args: [][]u8) i32 => { } )SOURCE", "OK\n"); + add_simple_case("statically initialized array literal", R"SOURCE( +import "std.zig"; +const x = []u8{1,2,3,4}; +pub fn main(args: [][]u8) i32 => { + const y : [4]u8 = x; + if (y[3] != 4) { + print_str("BAD\n"); + } + + print_str("OK\n"); + return 0; +} + )SOURCE", "OK\n"); + } @@ -1498,12 +1512,14 @@ struct A { z : i32, } fn f() => { + // we want the error on the '{' not the 'A' because + // the A could be a complicated expression const a = A { .z = 4, .y = 2, }; } - )SOURCE", 1, ".tmp_source.zig:8:17: error: missing field: 'x'"); + )SOURCE", 1, ".tmp_source.zig:10:17: error: missing field: 'x'"); add_compile_fail_case("invalid field in struct value expression", R"SOURCE( struct A {