aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_stmt.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-03-12 16:33:21 +0000
committergingerBill <bill@gingerbill.org>2023-03-12 16:33:21 +0000
commit93f7d3bfb9addc2203596e3f281f1f5f99b2f6a2 (patch)
treecad1041e8d71b9dd7713c32d89979256fcf45642 /src/llvm_backend_stmt.cpp
parentf0ef10aa57fa8999f5ef08c9bda88591ced58b80 (diff)
Allow `case nil` within a type switch statement (experimental idea)
Diffstat (limited to 'src/llvm_backend_stmt.cpp')
-rw-r--r--src/llvm_backend_stmt.cpp19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp
index 99a16094a..c7f8590f9 100644
--- a/src/llvm_backend_stmt.cpp
+++ b/src/llvm_backend_stmt.cpp
@@ -1423,9 +1423,11 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
continue;
}
Entity *case_entity = implicit_entity_of_node(clause);
- max_size = gb_max(max_size, type_size_of(case_entity->type));
- max_align = gb_max(max_align, type_align_of(case_entity->type));
- variants_found = true;
+ if (!is_type_untyped_nil(case_entity->type)) {
+ max_size = gb_max(max_size, type_size_of(case_entity->type));
+ max_align = gb_max(max_align, type_align_of(case_entity->type));
+ variants_found = true;
+ }
}
if (variants_found) {
Type *t = alloc_type_array(t_u8, max_size);
@@ -1449,6 +1451,8 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
if (p->debug_info != nullptr) {
LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, clause));
}
+
+ bool saw_nil = false;
for (Ast *type_expr : cc->list) {
Type *case_type = type_of_expr(type_expr);
lbValue on_val = {};
@@ -1457,7 +1461,12 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
on_val = lb_const_union_tag(m, ut, case_type);
} else if (switch_kind == TypeSwitch_Any) {
- on_val = lb_typeid(m, case_type);
+ if (is_type_untyped_nil(case_type)) {
+ saw_nil = true;
+ on_val = lb_const_nil(m, t_typeid);
+ } else {
+ on_val = lb_typeid(m, case_type);
+ }
}
GB_ASSERT(on_val.value != nullptr);
LLVMAddCase(switch_instr, on_val.value, body->block);
@@ -1469,7 +1478,7 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
bool by_reference = (case_entity->flags & EntityFlag_Value) == 0;
- if (cc->list.count == 1) {
+ if (cc->list.count == 1 && !saw_nil) {
lbValue data = {};
if (switch_kind == TypeSwitch_Union) {
data = union_data;