From 25a670d74e16463c7a8f91c3af91f44bf52a9e27 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 11 Jan 2017 19:09:17 -0500 Subject: [PATCH] pass more tests --- src/all_types.hpp | 1 + src/ast_render.cpp | 5 ++++- src/ir.cpp | 6 ++++++ src/parseh.cpp | 14 ++++++++++++++ test/run_tests.cpp | 28 ++++++++++++---------------- 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 791ac2445..bd322d114 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1022,6 +1022,7 @@ struct FnTableEntry { IrExecutable analyzed_executable; size_t prealloc_bbc; AstNode **param_source_nodes; + Buf **param_names; AstNode *fn_no_inline_set_node; AstNode *fn_export_set_node; diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 0ade4005b..6fc8c31fb 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -902,10 +902,13 @@ static void ast_render_tld_fn(AstRender *ar, TldFn *tld_fn) { fprintf(ar->f, "%s%s%s%sfn %s(", visib_mod_str, extern_str, coldcc_str, nakedcc_str, buf_ptr(&fn_entry->symbol_name)); for (size_t i = 0; i < fn_type_id->param_count; i += 1) { FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; + if (i != 0) { + fprintf(ar->f, ", "); + } if (param_info->is_noalias) { fprintf(ar->f, "noalias "); } - fprintf(ar->f, "arg_%zu: %s", i, buf_ptr(¶m_info->type->name)); + fprintf(ar->f, "%s: %s", buf_ptr(tld_fn->fn_entry->param_names[i]), buf_ptr(¶m_info->type->name)); } if (fn_type_id->return_type->id == TypeTableEntryIdVoid) { fprintf(ar->f, ");\n"); diff --git a/src/ir.cpp b/src/ir.cpp index a7367472a..c5d647cdc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -8471,6 +8471,9 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source FnTableEntry *fn_entry = tld_fn->fn_entry; assert(fn_entry->type_entry); + if (fn_entry->type_entry->id == TypeTableEntryIdInvalid) + return ira->codegen->builtin_types.entry_invalid; + // TODO instead of allocating this every time, put it in the tld value and we can reference // the same one every time ConstExprValue *const_val = allocate(1); @@ -8568,6 +8571,9 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru } else if (is_container(child_type)) { if (child_type->id == TypeTableEntryIdEnum) { ensure_complete_type(ira->codegen, child_type); + if (child_type->data.enumeration.is_invalid) + return ira->codegen->builtin_types.entry_invalid; + TypeEnumField *field = find_enum_type_field(child_type, field_name); if (field) { if (field->type_entry->id == TypeTableEntryIdVoid) { diff --git a/src/parseh.cpp b/src/parseh.cpp index dcd34d342..ff2f9c129 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -618,6 +618,20 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { assert(!fn_type->data.fn.fn_type_id.is_naked); + size_t arg_count = fn_type->data.fn.fn_type_id.param_count; + fn_entry->param_names = allocate(arg_count); + Buf *name_buf; + for (size_t i = 0; i < arg_count; i += 1) { + const ParmVarDecl *param = fn_decl->getParamDecl(i); + const char *name = decl_name(param); + if (strlen(name) == 0) { + name_buf = buf_sprintf("arg%zu", i); + } else { + name_buf = buf_create_from_str(name); + } + fn_entry->param_names[i] = name_buf; + } + TldFn *tld_fn = allocate(1); parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name); tld_fn->fn_entry = fn_entry; diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 5972da4c9..395f9ab85 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -1486,11 +1486,11 @@ pub fn f() { pub fn main(args: [][]bogus) -> %void {} )SOURCE", 1, ".tmp_source.zig:2:23: error: use of undeclared identifier 'bogus'"); - add_compile_fail_case("main function with bogus args type", R"SOURCE( + add_compile_fail_case("for loop missing element param", R"SOURCE( fn foo(blah: []u8) { for (blah) { } } - )SOURCE", 1, ".tmp_source.zig:3:16: error: for loop expression missing element parameter"); + )SOURCE", 1, ".tmp_source.zig:3:5: error: for loop expression missing element parameter"); add_compile_fail_case("misspelled type with pointer only reference", R"SOURCE( const JasonHM = u8; @@ -1511,14 +1511,14 @@ const JsonType = enum { JSONObject, }; -pub struct JsonNode { +pub const JsonNode = struct { kind: JsonType, jobject: ?JsonOA, -} +}; fn foo() { var jll: JasonList = undefined; - jll.init(&debug.global_allocator); + jll.init(1234); var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} }; } )SOURCE", 2, @@ -1526,7 +1526,7 @@ fn foo() { ".tmp_source.zig:27:8: error: no member named 'init' in 'JsonNode'"); add_compile_fail_case("method call with first arg type primitive", R"SOURCE( -const Foo = { +const Foo = struct { x: i32, fn init(x: i32) -> Foo { @@ -1541,12 +1541,10 @@ fn f() { derp.init(); } - )SOURCE", 2, - ".tmp_source.zig:15:14: error: function called as method of 'Foo', but first parameter is of type 'i32'", - ".tmp_source.zig:5:5: note: function declared here"); + )SOURCE", 1, ".tmp_source.zig:15:5: error: expected type 'i32', found '&const Foo'"); add_compile_fail_case("method call with first arg type wrong container", R"SOURCE( -pub struct List { +pub const List = struct { len: usize, allocator: &Allocator, @@ -1556,23 +1554,21 @@ pub struct List { .allocator = allocator, } } -} +}; pub var global_allocator = Allocator { .field = 1234, }; -pub struct Allocator { +pub const Allocator = struct { field: i32, -} +}; fn foo() { var x = List.init(&global_allocator); x.init(); } - )SOURCE", 2, - ".tmp_source.zig:24:11: error: function called as method of 'List', but first parameter is of type '&Allocator'", - ".tmp_source.zig:6:9: note: function declared here"); + )SOURCE", 1, ".tmp_source.zig:24:5: error: expected type '&Allocator', found '&List'"); add_compile_fail_case("binary not on number literal", R"SOURCE( const TINY_QUANTUM_SHIFT = 4;