diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-12-17 20:47:35 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-12-17 20:47:35 -0500 |
| commit | 0f047337ac0bf65b5f6d92248adc1452047f2622 (patch) | |
| tree | a15cc9d6f7250f056771d5ff18f9ec1862964d58 /src | |
| parent | a07d7ee53d7695b7ca56ced0a4ba25de2532ccbc (diff) | |
| download | zig-0f047337ac0bf65b5f6d92248adc1452047f2622.tar.gz zig-0f047337ac0bf65b5f6d92248adc1452047f2622.zip | |
IR: fix `this` expression
Previously it returned a block instead of a function when
a function had any arguments.
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 33 | ||||
| -rw-r--r-- | src/analyze.hpp | 3 | ||||
| -rw-r--r-- | src/ir.cpp | 25 |
3 files changed, 45 insertions, 16 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 18cb3329a1..8bc861c879 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -145,12 +145,12 @@ ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *con return scope; } -Scope *create_block_scope(AstNode *node, Scope *parent) { +ScopeBlock *create_block_scope(AstNode *node, Scope *parent) { assert(node->type == NodeTypeBlock); ScopeBlock *scope = allocate<ScopeBlock>(1); init_scope(&scope->base, ScopeIdBlock, node, parent); scope->label_table.init(1); - return &scope->base; + return scope; } ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { @@ -1446,7 +1446,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { if (is_main_fn) g->main_fn = fn_table_entry; - if (is_main_fn && !g->link_libc) { + if (is_main_fn && !g->link_libc && tld_fn->base.visib_mod != VisibModExport) { TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; if (actual_return_type != err_void) { @@ -2049,6 +2049,29 @@ FnTableEntry *scope_fn_entry(Scope *scope) { return nullptr; } +FnTableEntry *scope_get_fn_if_root(Scope *scope) { + assert(scope); + scope = scope->parent; + while (scope) { + switch (scope->id) { + case ScopeIdBlock: + return nullptr; + case ScopeIdDecls: + case ScopeIdDefer: + case ScopeIdVarDecl: + case ScopeIdCImport: + case ScopeIdLoop: + scope = scope->parent; + continue; + case ScopeIdFnDef: + ScopeFnDef *fn_scope = (ScopeFnDef *)scope; + return fn_scope->fn_entry; + } + zig_unreachable(); + } + return nullptr; +} + TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) { for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; @@ -2392,9 +2415,9 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, assert(proto_node->type == NodeTypeFnProto); Buf *proto_name = proto_node->data.fn_proto.name; - bool is_private = (proto_node->data.fn_proto.visib_mod == VisibModPrivate); + bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub); - if (buf_eql_str(proto_name, "main") && !is_private) { + if (buf_eql_str(proto_name, "main") && is_pub) { g->have_exported_main = true; } } diff --git a/src/analyze.hpp b/src/analyze.hpp index db4759f4c9..16261036d4 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -74,8 +74,9 @@ FnTableEntry *create_fn(AstNode *proto_node); FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node); AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index); +FnTableEntry *scope_get_fn_if_root(Scope *scope); -Scope *create_block_scope(AstNode *node, Scope *parent); +ScopeBlock *create_block_scope(AstNode *node, Scope *parent); ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var); ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent); diff --git a/src/ir.cpp b/src/ir.cpp index 5a1df80277..ee5577209e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2051,9 +2051,15 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { assert(block_node->type == NodeTypeBlock); - Scope *outer_block_scope = create_block_scope(block_node, parent_scope); + ScopeBlock *scope_block = create_block_scope(block_node, parent_scope); + Scope *outer_block_scope = &scope_block->base; Scope *child_scope = outer_block_scope; + FnTableEntry *fn_entry = scope_fn_entry(parent_scope); + if (fn_entry && fn_entry->child_scope == parent_scope) { + fn_entry->def_scope = scope_block; + } + IrInstruction *return_value = nullptr; for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 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 if (!scope->parent) return ir_build_const_import(irb, scope, node, node->owner); - FnTableEntry *fn_entry = exec_fn_entry(irb->exec); - if (fn_entry && scope->parent && scope->parent->parent && - !scope_fn_entry(scope->parent->parent)) - { + FnTableEntry *fn_entry = scope_get_fn_if_root(scope); + if (fn_entry) return ir_build_const_fn(irb, scope, node, fn_entry); - } if (scope->id == ScopeIdDecls) { ScopeDecls *decls_scope = (ScopeDecls *)scope; @@ -4379,6 +4382,7 @@ static bool is_u8(TypeTableEntry *type) { static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) { if (old_bb->other) return old_bb->other; + IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); // 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) { IrInstructionPhi *phi_instruction = (IrInstructionPhi *)instruction; for (size_t incoming_i = 0; incoming_i < phi_instruction->incoming_count; incoming_i += 1) { IrBasicBlock *predecessor = phi_instruction->incoming_blocks[incoming_i]; - ir_get_new_bb(ira, predecessor); + IrBasicBlock *new_predecessor = ir_get_new_bb(ira, predecessor); + ir_ref_bb(new_predecessor); } } ira->old_bb_queue.append(old_bb); @@ -4404,7 +4409,7 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons ira->old_irb.current_basic_block = old_bb; ira->const_predecessor_bb = const_predecessor_bb; - if (old_bb->other) + if (!const_predecessor_bb && old_bb->other) ira->new_irb.exec->basic_block_list.append(old_bb->other); } @@ -6478,7 +6483,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP IrInstruction *old_value = phi_instruction->incoming_values[i]; assert(old_value); IrInstruction *new_value = old_value->other; - if (new_value->type_entry->id == TypeTableEntryIdInvalid) + if (!new_value || new_value->type_entry->id == TypeTableEntryIdInvalid) return ira->codegen->builtin_types.entry_invalid; new_incoming_values.append(new_value); } @@ -7704,7 +7709,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira, IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block); ir_build_switch_br_from(&ira->new_irb, &switch_br_instruction->base, - target_value, new_else_block, case_count, cases, is_inline); + target_value, new_else_block, case_count, cases, false); return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); } |
