diff options
Diffstat (limited to 'src/llvm_backend_stmt.cpp')
| -rw-r--r-- | src/llvm_backend_stmt.cpp | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 24dd321f6..851433415 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -802,8 +802,19 @@ gb_internal void lb_build_range_enum(lbProcedure *p, Type *enum_type, Type *val_ if (done_) *done_ = done; } -gb_internal void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1_type, - lbValue *val0_, lbValue *val1_, lbBlock **loop_, lbBlock **done_) { +gb_internal void lb_build_range_tuple(lbProcedure *p, AstRangeStmt *rs, Scope *scope) { + Ast *expr = unparen_expr(rs->expr); + + Type *expr_type = type_of_expr(expr); + Type *et = base_type(type_deref(expr_type)); + GB_ASSERT(et->kind == Type_Tuple); + + i32 value_count = cast(i32)et->Tuple.variables.count; + + lbValue *values = gb_alloc_array(permanent_allocator(), lbValue, value_count); + + lb_open_scope(p, scope); + lbBlock *loop = lb_create_block(p, "for.tuple.loop"); lb_emit_jump(p, loop); lb_start_block(p, loop); @@ -821,11 +832,26 @@ gb_internal void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type lb_emit_if(p, cond, body, done); lb_start_block(p, body); + for (i32 i = 0; i < value_count; i++) { + values[i] = lb_emit_tuple_ev(p, tuple_value, i); + } - if (val0_) *val0_ = lb_emit_tuple_ev(p, tuple_value, 0); - if (val1_) *val1_ = lb_emit_tuple_ev(p, tuple_value, 1); - if (loop_) *loop_ = loop; - if (done_) *done_ = done; + GB_ASSERT(rs->vals.count <= value_count); + for (isize i = 0; i < rs->vals.count; i++) { + Ast *val = rs->vals[i]; + if (val != nullptr) { + lb_store_range_stmt_val(p, val, values[i]); + } + } + + lb_push_target_list(p, rs->label, done, loop, nullptr); + + lb_build_stmt(p, rs->body); + + lb_close_scope(p, lbDeferExit_Default, nullptr); + lb_pop_target_list(p); + lb_emit_jump(p, loop); + lb_start_block(p, done); } gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs, Scope *scope) { @@ -968,6 +994,17 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc } } + TypeAndValue tav = type_and_value_of_expr(expr); + if (tav.mode != Addressing_Type) { + Type *expr_type = type_of_expr(expr); + Type *et = base_type(type_deref(expr_type)); + if (et->kind == Type_Tuple) { + lb_build_range_tuple(p, rs, scope); + return; + } + } + + lb_open_scope(p, scope); Ast *val0 = rs->vals.count > 0 ? lb_strip_and_prefix(rs->vals[0]) : nullptr; @@ -986,7 +1023,6 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc lbBlock *loop = nullptr; lbBlock *done = nullptr; bool is_map = false; - TypeAndValue tav = type_and_value_of_expr(expr); if (tav.mode == Addressing_Type) { lb_build_range_enum(p, type_deref(tav.type), val0_type, &val, &key, &loop, &done); @@ -1062,8 +1098,7 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc break; } case Type_Tuple: - lb_build_range_tuple(p, expr, val0_type, val1_type, &val, &key, &loop, &done); - break; + GB_PANIC("Should be handled already"); case Type_BitSet: { lbModule *m = p->module; |