| 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,12 +145,12 @@ ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *con |
| 145 | return scope; | 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 | assert(node->type == NodeTypeBlock); | 149 | assert(node->type == NodeTypeBlock); |
| 150 | ScopeBlock *scope = allocate<ScopeBlock>(1); | 150 | ScopeBlock *scope = allocate<ScopeBlock>(1); |
| 151 | init_scope(&scope->base, ScopeIdBlock, node, parent); | 151 | init_scope(&scope->base, ScopeIdBlock, node, parent); |
| 152 | scope->label_table.init(1); | 152 | scope->label_table.init(1); |
| 153 | return &scope->base; | 153 | return scope; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { | 156 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { |
| ... | @@ -1446,7 +1446,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -1446,7 +1446,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 1446 | if (is_main_fn) | 1446 | if (is_main_fn) |
| 1447 | g->main_fn = fn_table_entry; | 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 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | 1450 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); |
| 1451 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; | 1451 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; |
| 1452 | if (actual_return_type != err_void) { | 1452 | if (actual_return_type != err_void) { |
| ... | @@ -2049,6 +2049,29 @@ FnTableEntry *scope_fn_entry(Scope *scope) { | ... | @@ -2049,6 +2049,29 @@ FnTableEntry *scope_fn_entry(Scope *scope) { |
| 2049 | return nullptr; | 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 | TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) { | 2075 | TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) { |
| 2053 | for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { | 2076 | for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { |
| 2054 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 2077 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| ... | @@ -2392,9 +2415,9 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, | ... | @@ -2392,9 +2415,9 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, |
| 2392 | assert(proto_node->type == NodeTypeFnProto); | 2415 | assert(proto_node->type == NodeTypeFnProto); |
| 2393 | Buf *proto_name = proto_node->data.fn_proto.name; | 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 | g->have_exported_main = true; | 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,8 +74,9 @@ FnTableEntry *create_fn(AstNode *proto_node); |
| 74 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); | 74 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); |
| 75 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node); | 75 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node); |
| 76 | AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index); | 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 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); | 80 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); |
| 80 | Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var); | 81 | Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var); |
| 81 | ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent); | 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,9 +2051,15 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s |
| 2051 | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { | 2051 | static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { |
| 2052 | assert(block_node->type == NodeTypeBlock); | 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 | Scope *child_scope = outer_block_scope; | 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 | IrInstruction *return_value = nullptr; | 2063 | IrInstruction *return_value = nullptr; |
| 2058 | for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { | 2064 | for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { |
| 2059 | AstNode *statement_node = block_node->data.block.statements.at(i); | 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,12 +3276,9 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode |
| 3270 | if (!scope->parent) | 3276 | if (!scope->parent) |
| 3271 | return ir_build_const_import(irb, scope, node, node->owner); | 3277 | return ir_build_const_import(irb, scope, node, node->owner); |
| 3272 | 3278 | ||
| 3273 | FnTableEntry *fn_entry = exec_fn_entry(irb->exec); | 3279 | FnTableEntry *fn_entry = scope_get_fn_if_root(scope); |
| 3274 | if (fn_entry && scope->parent && scope->parent->parent && | 3280 | if (fn_entry) |
| 3275 | !scope_fn_entry(scope->parent->parent)) | ||
| 3276 | { | ||
| 3277 | return ir_build_const_fn(irb, scope, node, fn_entry); | 3281 | return ir_build_const_fn(irb, scope, node, fn_entry); |
| 3278 | } | ||
| 3279 | 3282 | ||
| 3280 | if (scope->id == ScopeIdDecls) { | 3283 | if (scope->id == ScopeIdDecls) { |
| 3281 | ScopeDecls *decls_scope = (ScopeDecls *)scope; | 3284 | ScopeDecls *decls_scope = (ScopeDecls *)scope; |
| ... | @@ -4379,6 +4382,7 @@ static bool is_u8(TypeTableEntry *type) { | ... | @@ -4379,6 +4382,7 @@ static bool is_u8(TypeTableEntry *type) { |
| 4379 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { | 4382 | static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 4380 | if (old_bb->other) | 4383 | if (old_bb->other) |
| 4381 | return old_bb->other; | 4384 | return old_bb->other; |
| 4385 | |||
| 4382 | IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); | 4386 | IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); |
| 4383 | 4387 | ||
| 4384 | // We are about to enqueue old_bb for analysis. Before we do so, check old_bb | 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,7 +4395,8 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { |
| 4391 | IrInstructionPhi *phi_instruction = (IrInstructionPhi *)instruction; | 4395 | IrInstructionPhi *phi_instruction = (IrInstructionPhi *)instruction; |
| 4392 | for (size_t incoming_i = 0; incoming_i < phi_instruction->incoming_count; incoming_i += 1) { | 4396 | for (size_t incoming_i = 0; incoming_i < phi_instruction->incoming_count; incoming_i += 1) { |
| 4393 | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[incoming_i]; | 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 | ira->old_bb_queue.append(old_bb); | 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,7 +4409,7 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons |
| 4404 | ira->old_irb.current_basic_block = old_bb; | 4409 | ira->old_irb.current_basic_block = old_bb; |
| 4405 | ira->const_predecessor_bb = const_predecessor_bb; | 4410 | ira->const_predecessor_bb = const_predecessor_bb; |
| 4406 | 4411 | ||
| 4407 | if (old_bb->other) | 4412 | if (!const_predecessor_bb && old_bb->other) |
| 4408 | ira->new_irb.exec->basic_block_list.append(old_bb->other); | 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,7 +6483,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 6478 | IrInstruction *old_value = phi_instruction->incoming_values[i]; | 6483 | IrInstruction *old_value = phi_instruction->incoming_values[i]; |
| 6479 | assert(old_value); | 6484 | assert(old_value); |
| 6480 | IrInstruction *new_value = old_value->other; | 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 | return ira->codegen->builtin_types.entry_invalid; | 6487 | return ira->codegen->builtin_types.entry_invalid; |
| 6483 | new_incoming_values.append(new_value); | 6488 | new_incoming_values.append(new_value); |
| 6484 | } | 6489 | } |
| ... | @@ -7704,7 +7709,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, | ... | @@ -7704,7 +7709,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, |
| 7704 | 7709 | ||
| 7705 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block); | 7710 | IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block); |
| 7706 | ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base, | 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 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); | 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,7 +16,7 @@ var argv: &&u8 = undefined; |
| 16 | export nakedcc fn _start() -> unreachable { | 16 | export nakedcc fn _start() -> unreachable { |
| 17 | @setFnVisible(this, want_start_symbol); | 17 | @setFnVisible(this, want_start_symbol); |
| 18 | 18 | ||
| 19 | switch (@compileVar("arch")) { | 19 | inline switch (@compileVar("arch")) { |
| 20 | Arch.x86_64 => { | 20 | Arch.x86_64 => { |
| 21 | argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize)); | 21 | argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize)); |
| 22 | argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8)); | 22 | argv = asm("lea 0x8(%%rsp), %[argv]": [argv] "=r" (-> &&u8)); |
| ... | @@ -32,7 +32,7 @@ export nakedcc fn _start() -> unreachable { | ... | @@ -32,7 +32,7 @@ export nakedcc fn _start() -> unreachable { |
| 32 | 32 | ||
| 33 | fn callMain() -> %void { | 33 | fn callMain() -> %void { |
| 34 | const args = @alloca([]u8, argc); | 34 | const args = @alloca([]u8, argc); |
| 35 | for (args) |arg, i| { | 35 | for (args) |_, i| { |
| 36 | const ptr = argv[i]; | 36 | const ptr = argv[i]; |
| 37 | args[i] = ptr[0...cstr.len(ptr)]; | 37 | args[i] = ptr[0...cstr.len(ptr)]; |
| 38 | } | 38 | } |