| ... | @@ -643,8 +643,8 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr | ... | @@ -643,8 +643,8 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr |
| 643 | return new_instruction; | 643 | return new_instruction; |
| 644 | } | 644 | } |
| 645 | | 645 | |
| 646 | static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) { | 646 | static IrInstruction *ir_create_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) { |
| 647 | IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node); | 647 | IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb->exec, source_node); |
| 648 | br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; | 648 | br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable; |
| 649 | br_instruction->base.static_value.special = ConstValSpecialStatic; | 649 | br_instruction->base.static_value.special = ConstValSpecialStatic; |
| 650 | br_instruction->dest_block = dest_block; | 650 | br_instruction->dest_block = dest_block; |
| ... | @@ -655,6 +655,12 @@ static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicB | ... | @@ -655,6 +655,12 @@ static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicB |
| 655 | return &br_instruction->base; | 655 | return &br_instruction->base; |
| 656 | } | 656 | } |
| 657 | | 657 | |
| | 658 | static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) { |
| | 659 | IrInstruction *instruction = ir_create_br(irb, source_node, dest_block, is_inline); |
| | 660 | ir_instruction_append(irb->current_basic_block, instruction); |
| | 661 | return instruction; |
| | 662 | } |
| | 663 | |
| 658 | static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instruction, IrBasicBlock *dest_block) { | 664 | static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instruction, IrBasicBlock *dest_block) { |
| 659 | IrInstruction *new_instruction = ir_build_br(irb, old_instruction->source_node, dest_block, false); | 665 | IrInstruction *new_instruction = ir_build_br(irb, old_instruction->source_node, dest_block, false); |
| 660 | ir_link_new_instruction(new_instruction, old_instruction); | 666 | ir_link_new_instruction(new_instruction, old_instruction); |
| ... | @@ -2438,6 +2444,55 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { | ... | @@ -2438,6 +2444,55 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) { |
| 2438 | return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); | 2444 | return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 2439 | } | 2445 | } |
| 2440 | | 2446 | |
| | 2447 | static LabelTableEntry *find_label(IrExecutable *exec, BlockContext *orig_context, Buf *name) { |
| | 2448 | BlockContext *context = orig_context; |
| | 2449 | while (context) { |
| | 2450 | auto entry = context->label_table.maybe_get(name); |
| | 2451 | if (entry) { |
| | 2452 | return entry->value; |
| | 2453 | } |
| | 2454 | context = context->parent; |
| | 2455 | } |
| | 2456 | return nullptr; |
| | 2457 | } |
| | 2458 | |
| | 2459 | static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) { |
| | 2460 | assert(node->type == NodeTypeLabel); |
| | 2461 | |
| | 2462 | Buf *label_name = node->data.label.name; |
| | 2463 | IrBasicBlock *label_block = ir_build_basic_block(irb, buf_ptr(label_name)); |
| | 2464 | LabelTableEntry *label = allocate<LabelTableEntry>(1); |
| | 2465 | label->decl_node = node; |
| | 2466 | label->bb = label_block; |
| | 2467 | irb->exec->all_labels.append(label); |
| | 2468 | |
| | 2469 | LabelTableEntry *existing_label = find_label(irb->exec, node->block_context, label_name); |
| | 2470 | if (existing_label) { |
| | 2471 | ErrorMsg *msg = add_node_error(irb->codegen, node, |
| | 2472 | buf_sprintf("duplicate label name '%s'", buf_ptr(label_name))); |
| | 2473 | add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here")); |
| | 2474 | return irb->codegen->invalid_instruction; |
| | 2475 | } else { |
| | 2476 | node->block_context->label_table.put(label_name, label); |
| | 2477 | } |
| | 2478 | |
| | 2479 | bool is_inline = (node->block_context->fn_entry == nullptr); |
| | 2480 | ir_build_br(irb, node, label_block, is_inline); |
| | 2481 | ir_set_cursor_at_end(irb, label_block); |
| | 2482 | return ir_build_const_void(irb, node); |
| | 2483 | } |
| | 2484 | |
| | 2485 | static IrInstruction *ir_gen_goto(IrBuilder *irb, AstNode *node) { |
| | 2486 | assert(node->type == NodeTypeGoto); |
| | 2487 | |
| | 2488 | // make a placeholder unreachable statement and a note to come back and |
| | 2489 | // replace the instruction with a branch instruction |
| | 2490 | node->data.goto_expr.bb = irb->current_basic_block; |
| | 2491 | node->data.goto_expr.instruction_index = irb->current_basic_block->instruction_list.length; |
| | 2492 | irb->exec->goto_list.append(node); |
| | 2493 | return ir_build_unreachable(irb, node); |
| | 2494 | } |
| | 2495 | |
| 2441 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContext *block_context, | 2496 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContext *block_context, |
| 2442 | LValPurpose lval) | 2497 | LValPurpose lval) |
| 2443 | { | 2498 | { |
| ... | @@ -2491,13 +2546,15 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex | ... | @@ -2491,13 +2546,15 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex |
| 2491 | return ir_gen_if_var_expr(irb, node); | 2546 | return ir_gen_if_var_expr(irb, node); |
| 2492 | case NodeTypeSwitchExpr: | 2547 | case NodeTypeSwitchExpr: |
| 2493 | return ir_gen_switch_expr(irb, node); | 2548 | return ir_gen_switch_expr(irb, node); |
| | 2549 | case NodeTypeLabel: |
| | 2550 | return ir_gen_label(irb, node); |
| | 2551 | case NodeTypeGoto: |
| | 2552 | return ir_gen_goto(irb, node); |
| 2494 | case NodeTypeUnwrapErrorExpr: | 2553 | case NodeTypeUnwrapErrorExpr: |
| 2495 | case NodeTypeDefer: | 2554 | case NodeTypeDefer: |
| 2496 | case NodeTypeSliceExpr: | 2555 | case NodeTypeSliceExpr: |
| 2497 | case NodeTypeGoto: | | |
| 2498 | case NodeTypeBreak: | 2556 | case NodeTypeBreak: |
| 2499 | case NodeTypeContinue: | 2557 | case NodeTypeContinue: |
| 2500 | case NodeTypeLabel: | | |
| 2501 | case NodeTypeCharLiteral: | 2558 | case NodeTypeCharLiteral: |
| 2502 | case NodeTypeZeroesLiteral: | 2559 | case NodeTypeZeroesLiteral: |
| 2503 | case NodeTypeErrorType: | 2560 | case NodeTypeErrorType: |
| ... | @@ -2533,11 +2590,46 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *s | ... | @@ -2533,11 +2590,46 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *s |
| 2533 | return ir_gen_node_extra(irb, node, scope, LValPurposeNone); | 2590 | return ir_gen_node_extra(irb, node, scope, LValPurposeNone); |
| 2534 | } | 2591 | } |
| 2535 | | 2592 | |
| | 2593 | static bool ir_goto_pass2(IrBuilder *irb) { |
| | 2594 | for (size_t i = 0; i < irb->exec->goto_list.length; i += 1) { |
| | 2595 | AstNode *goto_node = irb->exec->goto_list.at(i); |
| | 2596 | size_t instruction_index = goto_node->data.goto_expr.instruction_index; |
| | 2597 | IrInstruction **slot = &goto_node->data.goto_expr.bb->instruction_list.at(instruction_index); |
| | 2598 | IrInstruction *old_instruction = *slot; |
| | 2599 | |
| | 2600 | Buf *label_name = goto_node->data.goto_expr.name; |
| | 2601 | LabelTableEntry *label = find_label(irb->exec, goto_node->block_context, label_name); |
| | 2602 | if (!label) { |
| | 2603 | add_node_error(irb->codegen, goto_node, |
| | 2604 | buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); |
| | 2605 | return false; |
| | 2606 | } |
| | 2607 | label->used = true; |
| | 2608 | |
| | 2609 | bool is_inline = goto_node->data.goto_expr.is_inline || (goto_node->block_context->fn_entry == nullptr); |
| | 2610 | IrInstruction *new_instruction = ir_create_br(irb, goto_node, label->bb, is_inline); |
| | 2611 | new_instruction->ref_count = old_instruction->ref_count; |
| | 2612 | *slot = new_instruction; |
| | 2613 | } |
| | 2614 | |
| | 2615 | for (size_t i = 0; i < irb->exec->all_labels.length; i += 1) { |
| | 2616 | LabelTableEntry *label = irb->exec->all_labels.at(i); |
| | 2617 | if (!label->used) { |
| | 2618 | add_node_error(irb->codegen, label->decl_node, |
| | 2619 | buf_sprintf("label '%s' defined but not used", |
| | 2620 | buf_ptr(label->decl_node->data.label.name))); |
| | 2621 | return false; |
| | 2622 | } |
| | 2623 | } |
| | 2624 | |
| | 2625 | return true; |
| | 2626 | } |
| | 2627 | |
| 2536 | IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrExecutable *ir_executable) { | 2628 | IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrExecutable *ir_executable) { |
| 2537 | assert(node->owner); | 2629 | assert(node->owner); |
| 2538 | | 2630 | |
| 2539 | IrBuilder ir_gen = {0}; | 2631 | IrBuilder ir_builder = {0}; |
| 2540 | IrBuilder *irb = &ir_gen; | 2632 | IrBuilder *irb = &ir_builder; |
| 2541 | | 2633 | |
| 2542 | irb->codegen = codegen; | 2634 | irb->codegen = codegen; |
| 2543 | irb->exec = ir_executable; | 2635 | irb->exec = ir_executable; |
| ... | @@ -2549,10 +2641,16 @@ IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrEx | ... | @@ -2549,10 +2641,16 @@ IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, BlockContext *scope, IrEx |
| 2549 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValPurposeNone); | 2641 | IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValPurposeNone); |
| 2550 | assert(result); | 2642 | assert(result); |
| 2551 | | 2643 | |
| | 2644 | IrInstruction *return_instruction = ir_build_return(irb, result->source_node, result); |
| | 2645 | assert(return_instruction); |
| | 2646 | |
| 2552 | if (result == codegen->invalid_instruction) | 2647 | if (result == codegen->invalid_instruction) |
| 2553 | return result; | 2648 | return codegen->invalid_instruction; |
| 2554 | | 2649 | |
| 2555 | return ir_build_return(irb, result->source_node, result); | 2650 | if (!ir_goto_pass2(irb)) |
| | 2651 | return codegen->invalid_instruction; |
| | 2652 | |
| | 2653 | return return_instruction; |
| 2556 | } | 2654 | } |
| 2557 | | 2655 | |
| 2558 | IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) { | 2656 | IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) { |
| ... | @@ -7241,19 +7339,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -7241,19 +7339,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 7241 | // } | 7339 | // } |
| 7242 | // zig_unreachable(); | 7340 | // zig_unreachable(); |
| 7243 | //} | 7341 | //} |
| 7244 | //static TypeTableEntry *analyze_goto_pass1(CodeGen *g, ImportTableEntry *import, BlockContext *context, | | |
| 7245 | // TypeTableEntry *expected_type, AstNode *node) | | |
| 7246 | //{ | | |
| 7247 | // assert(node->type == NodeTypeGoto); | | |
| 7248 | // | | |
| 7249 | // FnTableEntry *fn_table_entry = context->fn_entry; | | |
| 7250 | // assert(fn_table_entry); | | |
| 7251 | // | | |
| 7252 | // fn_table_entry->goto_list.append(node); | | |
| 7253 | // | | |
| 7254 | // return g->builtin_types.entry_unreachable; | | |
| 7255 | //} | | |
| 7256 | // | | |
| 7257 | //static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 7342 | //static TypeTableEntry *analyze_enum_value_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 7258 | // AstNode *field_access_node, AstNode *value_node, TypeTableEntry *enum_type, Buf *field_name, | 7343 | // AstNode *field_access_node, AstNode *value_node, TypeTableEntry *enum_type, Buf *field_name, |
| 7259 | // AstNode *out_node) | 7344 | // AstNode *out_node) |
| ... | @@ -7710,69 +7795,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -7710,69 +7795,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 7710 | // return g->builtin_types.entry_void; | 7795 | // return g->builtin_types.entry_void; |
| 7711 | //} | 7796 | //} |
| 7712 | // | 7797 | // |
| 7713 | //static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context, | | |
| 7714 | // TypeTableEntry *expected_type, AstNode *node) | | |
| 7715 | //{ | | |
| 7716 | // BlockContext *child_context = new_block_context(node, parent_context); | | |
| 7717 | // node->data.block.child_block = child_context; | | |
| 7718 | // TypeTableEntry *return_type = g->builtin_types.entry_void; | | |
| 7719 | // | | |
| 7720 | // for (size_t i = 0; i < node->data.block.statements.length; i += 1) { | | |
| 7721 | // AstNode *child = node->data.block.statements.at(i); | | |
| 7722 | // if (child->type == NodeTypeLabel) { | | |
| 7723 | // FnTableEntry *fn_table_entry = child_context->fn_entry; | | |
| 7724 | // assert(fn_table_entry); | | |
| 7725 | // | | |
| 7726 | // LabelTableEntry *label = allocate<LabelTableEntry>(1); | | |
| 7727 | // label->decl_node = child; | | |
| 7728 | // label->entered_from_fallthrough = (return_type->id != TypeTableEntryIdUnreachable); | | |
| 7729 | // | | |
| 7730 | // child->block_context = child_context; | | |
| 7731 | // child->data.label.label_entry = label; | | |
| 7732 | // fn_table_entry->all_labels.append(label); | | |
| 7733 | // | | |
| 7734 | // child_context->label_table.put(child->data.label.name, label); | | |
| 7735 | // | | |
| 7736 | // return_type = g->builtin_types.entry_void; | | |
| 7737 | // continue; | | |
| 7738 | // } | | |
| 7739 | // if (return_type->id == TypeTableEntryIdUnreachable) { | | |
| 7740 | // if (is_node_void_expr(child)) { | | |
| 7741 | // // {unreachable;void;void} is allowed. | | |
| 7742 | // // ignore void statements once we enter unreachable land. | | |
| 7743 | // analyze_expression(g, import, child_context, g->builtin_types.entry_void, child); | | |
| 7744 | // continue; | | |
| 7745 | // } | | |
| 7746 | // add_node_error(g, first_executing_node(child), buf_sprintf("unreachable code")); | | |
| 7747 | // break; | | |
| 7748 | // } | | |
| 7749 | // bool is_last = (i == node->data.block.statements.length - 1); | | |
| 7750 | // TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr; | | |
| 7751 | // return_type = analyze_expression(g, import, child_context, passed_expected_type, child); | | |
| 7752 | // if (child->type == NodeTypeDefer && return_type->id != TypeTableEntryIdInvalid) { | | |
| 7753 | // // defer starts a new block context | | |
| 7754 | // child_context = child->data.defer.child_block; | | |
| 7755 | // assert(child_context); | | |
| 7756 | // } | | |
| 7757 | // if (!is_last) { | | |
| 7758 | // validate_voided_expr(g, child, return_type); | | |
| 7759 | // } | | |
| 7760 | // } | | |
| 7761 | // node->data.block.nested_block = child_context; | | |
| 7762 | // | | |
| 7763 | // ConstExprValue *const_val = &node->data.block.resolved_expr.const_val; | | |
| 7764 | // if (node->data.block.statements.length == 0) { | | |
| 7765 | // const_val->ok = true; | | |
| 7766 | // } else if (node->data.block.statements.length == 1) { | | |
| 7767 | // AstNode *only_node = node->data.block.statements.at(0); | | |
| 7768 | // ConstExprValue *other_const_val = &get_resolved_expr(only_node)->const_val; | | |
| 7769 | // if (other_const_val->ok) { | | |
| 7770 | // *const_val = *other_const_val; | | |
| 7771 | // } | | |
| 7772 | // } | | |
| 7773 | // | | |
| 7774 | // return return_type; | | |
| 7775 | //} | | |
| 7776 | // | 7798 | // |
| 7777 | //static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, | 7799 | //static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, |
| 7778 | // BlockContext *context, AstNode *node, Buf *err_name) | 7800 | // BlockContext *context, AstNode *node, Buf *err_name) |
| ... | @@ -7841,51 +7863,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -7841,51 +7863,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 7841 | // | 7863 | // |
| 7842 | // return ir_build_return(irb, source_node, value); | 7864 | // return ir_build_return(irb, source_node, value); |
| 7843 | //} | 7865 | //} |
| 7844 | /* | | |
| 7845 | static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) { | | |
| 7846 | assert(node->type == NodeTypeGoto); | | |
| 7847 | Buf *label_name = node->data.goto_expr.name; | | |
| 7848 | BlockContext *context = node->block_context; | | |
| 7849 | assert(context); | | |
| 7850 | LabelTableEntry *label = find_label(g, context, label_name); | | |
| 7851 | | | |
| 7852 | if (!label) { | | |
| 7853 | add_node_error(g, node, buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); | | |
| 7854 | return; | | |
| 7855 | } | | |
| 7856 | | | |
| 7857 | label->used = true; | | |
| 7858 | node->data.goto_expr.label_entry = label; | | |
| 7859 | } | | |
| 7860 | | | |
| 7861 | for (size_t i = 0; i < fn_table_entry->goto_list.length; i += 1) { | | |
| 7862 | AstNode *goto_node = fn_table_entry->goto_list.at(i); | | |
| 7863 | assert(goto_node->type == NodeTypeGoto); | | |
| 7864 | analyze_goto_pass2(g, import, goto_node); | | |
| 7865 | } | | |
| 7866 | | | |
| 7867 | for (size_t i = 0; i < fn_table_entry->all_labels.length; i += 1) { | | |
| 7868 | LabelTableEntry *label = fn_table_entry->all_labels.at(i); | | |
| 7869 | if (!label->used) { | | |
| 7870 | add_node_error(g, label->decl_node, | | |
| 7871 | buf_sprintf("label '%s' defined but not used", | | |
| 7872 | buf_ptr(label->decl_node->data.label.name))); | | |
| 7873 | } | | |
| 7874 | } | | |
| 7875 | */ | | |
| 7876 | | | |
| 7877 | //static LabelTableEntry *find_label(CodeGen *g, BlockContext *orig_context, Buf *name) { | | |
| 7878 | // BlockContext *context = orig_context; | | |
| 7879 | // while (context && context->fn_entry) { | | |
| 7880 | // auto entry = context->label_table.maybe_get(name); | | |
| 7881 | // if (entry) { | | |
| 7882 | // return entry->value; | | |
| 7883 | // } | | |
| 7884 | // context = context->parent; | | |
| 7885 | // } | | |
| 7886 | // return nullptr; | | |
| 7887 | //} | | |
| 7888 | | | |
| 7889 | // | 7866 | // |
| 7890 | //static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) { | 7867 | //static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) { |
| 7891 | // assert(node->type == NodeTypeFnCallExpr); | 7868 | // assert(node->type == NodeTypeFnCallExpr); |
| ... | @@ -9180,20 +9157,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no | ... | @@ -9180,20 +9157,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no |
| 9180 | // return nullptr; | 9157 | // return nullptr; |
| 9181 | //} | 9158 | //} |
| 9182 | // | 9159 | // |
| 9183 | //static LLVMValueRef gen_goto(CodeGen *g, AstNode *node) { | | |
| 9184 | // assert(node->type == NodeTypeGoto); | | |
| 9185 | // | | |
| 9186 | // // generate defers for blocks that we exit | | |
| 9187 | // LabelTableEntry *label = node->data.goto_expr.label_entry; | | |
| 9188 | // BlockContext *this_context = node->block_context; | | |
| 9189 | // BlockContext *target_context = label->decl_node->block_context; | | |
| 9190 | // gen_defers_for_block(g, this_context, target_context, false, false); | | |
| 9191 | // | | |
| 9192 | // set_debug_source_node(g, node); | | |
| 9193 | // LLVMBuildBr(g->builder, node->data.goto_expr.label_entry->basic_block); | | |
| 9194 | // return nullptr; | | |
| 9195 | //} | | |
| 9196 | // | | |
| 9197 | //static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) { | 9160 | //static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) { |
| 9198 | // AstNode *init_expr = node->data.variable_declaration.expr; | 9161 | // AstNode *init_expr = node->data.variable_declaration.expr; |
| 9199 | // if (node->data.variable_declaration.is_const && init_expr) { | 9162 | // if (node->data.variable_declaration.is_const && init_expr) { |
| ... | @@ -9249,18 +9212,3 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no | ... | @@ -9249,18 +9212,3 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no |
| 9249 | // } | 9212 | // } |
| 9250 | // return result; | 9213 | // return result; |
| 9251 | //} | 9214 | //} |
| 9252 | // | | |
| 9253 | //static LLVMValueRef gen_label(CodeGen *g, AstNode *node) { | | |
| 9254 | // assert(node->type == NodeTypeLabel); | | |
| 9255 | // | | |
| 9256 | // LabelTableEntry *label = node->data.label.label_entry; | | |
| 9257 | // assert(label); | | |
| 9258 | // | | |
| 9259 | // LLVMBasicBlockRef basic_block = label->basic_block; | | |
| 9260 | // if (label->entered_from_fallthrough) { | | |
| 9261 | // set_debug_source_node(g, node); | | |
| 9262 | // LLVMBuildBr(g->builder, basic_block); | | |
| 9263 | // } | | |
| 9264 | // LLVMPositionBuilderAtEnd(g->builder, basic_block); | | |
| 9265 | // return nullptr; | | |
| 9266 | //} | | |