aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-03-24 22:34:55 +0000
committergingerBill <bill@gingerbill.org>2021-03-24 22:34:55 +0000
commit5faf859a561e63000184b592154c6503be024fb4 (patch)
treee9f764e01d31bb5eb97727199cad99add478d0f2 /src
parent7028797d5398699c2edbfd0ab1d83272bcdcd1ce (diff)
Support `using` on intermediate soa field value from a for-in statement
Diffstat (limited to 'src')
-rw-r--r--src/check_stmt.cpp5
-rw-r--r--src/llvm_backend.cpp15
2 files changed, 17 insertions, 3 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 46eb1d177..402324cdd 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -558,8 +558,11 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b
bool is_ptr = is_type_pointer(e->type);
Type *t = base_type(type_deref(e->type));
if (t->kind == Type_Struct) {
- // TODO(bill): Make it work for unions too
Scope *found = scope_of_node(t->Struct.node);
+ if (found == nullptr) {
+ found = t->Struct.scope;
+ }
+ GB_ASSERT(found != nullptr);
for_array(i, found->elements.entries) {
Entity *f = found->elements.entries[i].value;
if (f->kind == Entity_Variable) {
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp
index 9ab2609e9..32a74cb53 100644
--- a/src/llvm_backend.cpp
+++ b/src/llvm_backend.cpp
@@ -162,6 +162,11 @@ lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
return final_ptr;
}
+ case lbAddr_SoaVariable: {
+ // TODO(bill): FIX THIS HACK
+ return lb_address_from_load(p, lb_addr_load(p, addr));
+ }
+
case lbAddr_Context:
GB_PANIC("lbAddr_Context should be handled elsewhere");
}
@@ -10780,15 +10785,21 @@ lbValue lb_get_using_variable(lbProcedure *p, Entity *e) {
Selection sel = lookup_field(parent->type, name, false);
GB_ASSERT(sel.entity != nullptr);
lbValue *pv = map_get(&p->module->values, hash_entity(parent));
+
lbValue v = {};
- if (pv != nullptr) {
+
+ if (pv == nullptr && parent->flags & EntityFlag_SoaPtrField) {
+ // NOTE(bill): using SOA value (probably from for-in statement)
+ lbAddr parent_addr = lb_get_soa_variable_addr(p, parent);
+ v = lb_addr_get_ptr(p, parent_addr);
+ } else if (pv != nullptr) {
v = *pv;
} else {
GB_ASSERT_MSG(e->using_expr != nullptr, "%.*s", LIT(name));
v = lb_build_addr_ptr(p, e->using_expr);
}
GB_ASSERT(v.value != nullptr);
- GB_ASSERT(parent->type == type_deref(v.type));
+ GB_ASSERT_MSG(parent->type == type_deref(v.type), "%s %s", type_to_string(parent->type), type_to_string(v.type));
lbValue ptr = lb_emit_deep_field_gep(p, v, sel);
lb_add_debug_local_variable(p, ptr.value, e->type, e->token);
return ptr;