| author | |
| committer | |
| log | 0f047337ac0bf65b5f6d92248adc1452047f2622 |
| tree | a15cc9d6f7250f056771d5ff18f9ec1862964d58 |
| parent | a07d7ee53d7695b7ca56ced0a4ba25de2532ccbc |
Previously it returned a block instead of a function when
a function had any arguments.4 files changed, 47 insertions(+), 18 deletions(-)
src/analyze.cpp+28-5| ... | ... | @@ -145,12 +145,12 @@ ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *con |
| 145 | 145 | return scope; |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | Scope *create_block_scope(AstNode *node, Scope *parent) { | |
| 148 | ScopeBlock *create_block_scope(AstNode *node, Scope *parent) { | |
| 149 | 149 | assert(node->type == NodeTypeBlock); |
| 150 | 150 | ScopeBlock *scope = allocate<ScopeBlock>(1); |
| 151 | 151 | init_scope(&scope->base, ScopeIdBlock, node, parent); |
| 152 | 152 | scope->label_table.init(1); |
| 153 | return &scope->base; | |
| 153 | return scope; | |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { |
| ... | ... | @@ -1446,7 +1446,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 1446 | 1446 | if (is_main_fn) |
| 1447 | 1447 | g->main_fn = fn_table_entry; |
| 1448 | 1448 | |
| 1449 | if (is_main_fn && !g->link_libc) { | |
| 1449 | if (is_main_fn && !g->link_libc && tld_fn->base.visib_mod != VisibModExport) { | |
| 1450 | 1450 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); |
| 1451 | 1451 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; |
| 1452 | 1452 | if (actual_return_type != err_void) { |
| ... | ... | @@ -2049,6 +2049,29 @@ FnTableEntry *scope_fn_entry(Scope *scope) { |
| 2049 | 2049 | return nullptr; |
| 2050 | 2050 | } |
| 2051 | 2051 | |
| 2052 | FnTableEntry *scope_get_fn_if_root(Scope *scope) { | |
| 2053 | assert(scope); | |
| 2054 | scope = scope->parent; | |
| 2055 | while (scope) { | |
| 2056 | switch (scope->id) { | |
| 2057 | case ScopeIdBlock: | |
| 2058 | return nullptr; | |
| 2059 | case ScopeIdDecls: | |
| 2060 | case ScopeIdDefer: | |
| 2061 | case ScopeIdVarDecl: | |
| 2062 | case ScopeIdCImport: | |
| 2063 | case ScopeIdLoop: | |
| 2064 | scope = scope->parent; | |
| 2065 | continue; | |
| 2066 | case ScopeIdFnDef: | |
| 2067 | ScopeFnDef *fn_scope = (ScopeFnDef *)scope; | |
| 2068 | return fn_scope->fn_entry; | |
| 2069 | } | |
| 2070 | zig_unreachable(); | |
| 2071 | } | |
| 2072 | return nullptr; | |
| 2073 | } | |
| 2074 | ||
| 2052 | 2075 | TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) { |
| 2053 | 2076 | for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { |
| 2054 | 2077 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| ... | ... | @@ -2392,9 +2415,9 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, |
| 2392 | 2415 | assert(proto_node->type == NodeTypeFnProto); |
| 2393 | 2416 | Buf *proto_name = proto_node->data.fn_proto.name; |
| 2394 | 2417 | |
| 2395 | bool is_private = (proto_node->data.fn_proto.visib_mod == VisibModPrivate); | |
| 2418 | bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub); | |
| 2396 | 2419 | |
| 2397 | if (buf_eql_str(proto_name, "main") && !is_private) { | |
| 2420 | if (buf_eql_str(proto_name, "main") && is_pub) { | |
| 2398 | 2421 | g->have_exported_main = true; |
| 2399 | 2422 | } |
| 2400 | 2423 | } |
src/analyze.hpp+2-1| ... | ... | @@ -74,8 +74,9 @@ FnTableEntry *create_fn(AstNode *proto_node); |
| 74 | 74 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); |
| 75 | 75 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node); |
| 76 | 76 | AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index); |
| 77 | FnTableEntry *scope_get_fn_if_root(Scope *scope); | |
| 77 | 78 | |
| 78 | Scope *create_block_scope(AstNode *node, Scope *parent); | |
| 79 | ScopeBlock *create_block_scope(AstNode *node, Scope *parent); | |
| 79 | 80 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); |
| 80 | 81 | Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var); |
| 81 | 82 | ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent); |
src/ir.cpp+15-10| ... | ... | @@ -2051,9 +2051,15 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s |
| 2051 | 2051 | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { |
| 2052 | 2052 | assert(block_node->type == NodeTypeBlock); |
| 2053 | 2053 | |
| 2054 | Scope *outer_block_scope = create_block_scope(block_node, parent_scope); | |
| 2054 | ScopeBlock *scope_block = create_block_scope(block_node, parent_scope); | |
| 2055 | Scope *outer_block_scope = &scope_block->base; | |
| 2055 | 2056 | Scope *child_scope = outer_block_scope; |
| 2056 | 2057 | |
| 2058 | FnTableEntry *fn_entry = scope_fn_entry(parent_scope); | |
| 2059 | if (fn_entry && fn_entry->child_scope == parent_scope) { | |
| 2060 | fn_entry->def_scope = scope_block; | |
| 2061 | } | |
| 2062 | ||
| 2057 | 2063 | IrInstruction *return_value = nullptr; |
| 2058 | 2064 | for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { |
| 2059 | 2065 | AstNode *statement_node = block_node->data.block.statements.at(i); |
| ... | ... | @@ -3270,12 +3276,9 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode |
| 3270 | 3276 | if (!scope->parent) |
| 3271 | 3277 | return ir_build_const_import(irb, scope, node, node->owner); |
| 3272 | 3278 | |
| 3273 | FnTableEntry *fn_entry = exec_fn_entry(irb->exec); | |
| 3274 | if (fn_entry && scope->parent && scope->parent->parent && | |
| 3275 | !scope_fn_entry(scope->parent->parent)) | |
| 3276 | { | |
| 3279 | FnTableEntry *fn_entry = scope_get_fn_if_root(scope); | |
| 3280 | if (fn_entry) | |
| 3277 | 3281 | return ir_build_const_fn(irb, scope, node, fn_entry); |
| 3278 | } | |
| 3279 | 3282 | |
| 3280 | 3283 | if (scope->id == ScopeIdDecls) { |
| 3281 | 3284 | ScopeDecls *decls_scope = (ScopeDecls *)scope; |
| ... | ... | @@ -4379,6 +4382,7 @@ static bool is_u8(TypeTableEntry *type) { |
| 4379 | 4382 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 4380 | 4383 | if (old_bb->other) |
| 4381 | 4384 | return old_bb->other; |
| 4385 | ||
| 4382 | 4386 | IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); |
| 4383 | 4387 | |
| 4384 | 4388 | // We are about to enqueue old_bb for analysis. Before we do so, check old_bb |
| ... | ... | @@ -4391,7 +4395,8 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 4391 | 4395 | IrInstructionPhi *phi_instruction = (IrInstructionPhi *)instruction; |
| 4392 | 4396 | for (size_t incoming_i = 0; incoming_i < phi_instruction->incoming_count; incoming_i += 1) { |
| 4393 | 4397 | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[incoming_i]; |
| 4394 | ir_get_new_bb(ira, predecessor); | |
| 4398 | IrBasicBlock *new_predecessor = ir_get_new_bb(ira, predecessor); | |
| 4399 | ir_ref_bb(new_predecessor); | |
| 4395 | 4400 | } |
| 4396 | 4401 | } |
| 4397 | 4402 | ira->old_bb_queue.append(old_bb); |
| ... | ... | @@ -4404,7 +4409,7 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons |
| 4404 | 4409 | ira->old_irb.current_basic_block = old_bb; |
| 4405 | 4410 | ira->const_predecessor_bb = const_predecessor_bb; |
| 4406 | 4411 | |
| 4407 | if (old_bb->other) | |
| 4412 | if (!const_predecessor_bb && old_bb->other) | |
| 4408 | 4413 | ira->new_irb.exec->basic_block_list.append(old_bb->other); |
| 4409 | 4414 | } |
| 4410 | 4415 | |
| ... | ... | @@ -6478,7 +6483,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 6478 | 6483 | IrInstruction *old_value = phi_instruction->incoming_values[i]; |
| 6479 | 6484 | assert(old_value); |
| 6480 | 6485 | IrInstruction *new_value = old_value->other; |
| 6481 | if (new_value->type_entry->id == TypeTableEntryIdInvalid) | |
| 6486 | if (!new_value || new_value->type_entry->id == TypeTableEntryIdInvalid) | |
| 6482 | 6487 | return ira->codegen->builtin_types.entry_invalid; |
| 6483 | 6488 | new_incoming_values.append(new_value); |
| 6484 | 6489 | } |
| ... | ... | @@ -7704,7 +7709,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 7704 | 7709 | |
| 7705 | 7710 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block); |
| 7706 | 7711 | ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base, |
| 7707 | target_value, new_else_block, case_count, cases, is_inline); | |
| 7712 | target_value, new_else_block, case_count, cases, false); | |
| 7708 | 7713 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 7709 | 7714 | } |
| 7710 | 7715 |
std/bootstrap.zig+2-2| ... | ... | @@ -16,7 +16,7 @@ var argv: &&u8 = undefined; |
| 16 | 16 | export nakedcc fn _start() -> unreachable { |
| 17 | 17 | @setFnVisible(this, want_start_symbol); |
| 18 | 18 | |
| 19 | switch (@compileVar("arch")) { | |
| 19 | inline switch (@compileVar("arch")) { | |
| 20 | 20 | Arch.x86_64 => { |
| 21 | 21 | argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize)); |
| 22 | 22 | argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8)); |
| ... | ... | @@ -32,7 +32,7 @@ export nakedcc fn _start() -> unreachable { |
| 32 | 32 | |
| 33 | 33 | fn callMain() -> %void { |
| 34 | 34 | const args = @alloca([]u8, argc); |
| 35 | for (args) |arg, i| { | |
| 35 | for (args) |_, i| { | |
| 36 | 36 | const ptr = argv[i]; |
| 37 | 37 | args[i] = ptr[0...cstr.len(ptr)]; |
| 38 | 38 | } |