aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_stmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm_backend_stmt.cpp')
-rw-r--r--src/llvm_backend_stmt.cpp53
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;