diff options
| author | gingerBill <bill@gingerbill.org> | 2021-03-24 22:34:55 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-03-24 22:34:55 +0000 |
| commit | 5faf859a561e63000184b592154c6503be024fb4 (patch) | |
| tree | e9f764e01d31bb5eb97727199cad99add478d0f2 /src | |
| parent | 7028797d5398699c2edbfd0ab1d83272bcdcd1ce (diff) | |
Support `using` on intermediate soa field value from a for-in statement
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_stmt.cpp | 5 | ||||
| -rw-r--r-- | src/llvm_backend.cpp | 15 |
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; |