diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-02-11 15:50:24 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-02-11 15:50:24 +0000 |
| commit | 346aa5f71ca4e3d6a71187024f809eaf2fc6da1b (patch) | |
| tree | d61331a1bf713f66bcdba8816b8b01eef3e643b2 /src/ir.c | |
| parent | 73d6a55f5c96459d30eca5747d1458bcf6e9fec4 (diff) | |
Only check files that have been truly imported.
Diffstat (limited to 'src/ir.c')
| -rw-r--r-- | src/ir.c | 221 |
1 files changed, 117 insertions, 104 deletions
@@ -1008,6 +1008,22 @@ irValue *ir_make_value_procedure(gbAllocator a, irModule *m, Entity *entity, Typ return v; } + +irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefix, i64 id) { + gbAllocator a = m->allocator; + Token token = {Token_Ident}; + isize name_len = prefix.len + 10; + token.string.text = gb_alloc_array(a, u8, name_len); + token.string.len = gb_snprintf(cast(char *)token.string.text, name_len, + "%.*s-%llx", LIT(prefix), id)-1; + Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, elem_type, count), false); + irValue *value = ir_make_value_global(a, e, NULL); + value->Global.is_private = true; + ir_module_add_value(m, e, value); + map_ir_value_set(&m->members, hash_string(token.string), value); + return value; +} + irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) { Scope *scope = NULL; if (node != NULL) { @@ -3709,50 +3725,55 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { AstNode *sel = unparen_expr(se->selector); if (sel->kind == AstNode_Ident) { String selector = sel->Ident.string; - Type *type = type_of_expr(proc->module->info, se->expr); + TypeAndValue *tav = type_and_value_of_expression(proc->module->info, se->expr); - if (is_type_enum(type)) { + if (tav == NULL) { + // NOTE(bill): Imports + Entity *imp = entity_of_ident(proc->module->info, se->expr); + if (imp != NULL) { + GB_ASSERT(imp->kind == Entity_ImportName); + } + return ir_build_addr(proc, unparen_expr(se->selector)); + } + + + Type *type = base_type(tav->type); + if (tav->mode == Addressing_Type) { // Addressing_Type Selection sel = lookup_field(proc->module->allocator, type, selector, true); Entity *e = sel.entity; GB_ASSERT(e->kind == Entity_Variable); - i32 index = e->Variable.field_index; - switch (index) { - case 0: { + GB_ASSERT(e->flags & EntityFlag_TypeField); + String name = e->token.string; + if (str_eq(name, str_lit("names"))) { irValue *ti_ptr = ir_type_info(proc, type); - { - irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1); - args[0] = ti_ptr; - ti_ptr = ir_emit_global_call(proc, "type_info_base", args, 1); + // { + // irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1); + // args[0] = ti_ptr; + // ti_ptr = ir_emit_global_call(proc, "type_info_base", args, 1); + // } + irValue *names_ptr = NULL; + + if (is_type_enum(type)) { + irValue *enum_info = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr); + names_ptr = ir_emit_struct_ep(proc, enum_info, 1); + } else { + GB_PANIC("TODO(bill): `names` for records"); + // irValue *record_info = ir_emit_conv(proc, ti_ptr, t_type_info_record_ptr); + // names_ptr = ir_emit_struct_ep(proc, record_info, 1); } - - - irValue *enum_info = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr); - irValue *names_ptr = ir_emit_struct_ep(proc, enum_info, 1); return ir_make_addr(names_ptr); - } break; - default: - GB_PANIC("Unhandled enum index %d %.*s", index, LIT(selector)); - break; + } else { + GB_PANIC("Unhandled TypeField %.*s", LIT(name)); } + GB_PANIC("Unreachable"); } - type = base_type(type); - - if (type == t_invalid) { - // NOTE(bill): Imports - Entity *imp = entity_of_ident(proc->module->info, se->expr); - if (imp != NULL) { - GB_ASSERT(imp->kind == Entity_ImportName); - } - return ir_build_addr(proc, unparen_expr(se->selector)); - } else { - Selection sel = lookup_field(proc->module->allocator, type, selector, false); - GB_ASSERT(sel.entity != NULL); + Selection sel = lookup_field(proc->module->allocator, type, selector, false); + GB_ASSERT(sel.entity != NULL); - irValue *a = ir_build_addr(proc, se->expr).addr; - a = ir_emit_deep_field_gep(proc, type, a, sel); - return ir_make_addr(a); - } + irValue *a = ir_build_addr(proc, se->expr).addr; + a = ir_emit_deep_field_gep(proc, type, a, sel); + return ir_make_addr(a); } else { Type *type = base_type(type_of_expr(proc->module->info, se->expr)); GB_ASSERT(is_type_integer(type)); @@ -4117,33 +4138,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { ir_emit_store(proc, gep, ev); } } - - - // irValue *result = ir_add_module_constant(proc->module, type, make_exact_value_compound(expr)); - // for_array(index, cl->elems) { - // AstNode *elem = cl->elems.e[index]; - // if (ir_is_elem_const(proc->module, elem, et)) { - // continue; - // } - // irValue *field_elem = ir_build_expr(proc, elem); - // Type *t = ir_type(field_elem); - // GB_ASSERT(t->kind != Type_Tuple); - // irValue *ev = ir_emit_conv(proc, field_elem, et); - // irValue *i = ir_make_const_int(proc->module->allocator, index); - // result = ir_emit(proc, ir_make_instr_insert_element(proc, result, ev, i)); - // } - - // if (cl->elems.count == 1 && bt->Vector.count > 1) { - // isize index_count = bt->Vector.count; - // i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); - // for (isize i = 0; i < index_count; i++) { - // indices[i] = 0; - // } - // irValue *sv = ir_emit(proc, ir_make_instr_vector_shuffle(proc, result, indices, index_count)); - // ir_emit_store(proc, v, sv); - // return ir_make_addr(v); - // } - // ir_emit_store(proc, v, result); } break; case Type_Record: { @@ -4186,13 +4180,51 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } } break; - case Type_Map: { + case Type_DynamicArray: { if (cl->elems.count == 0) { break; } + Type *elem = bt->DynamicArray.elem; gbAllocator a = proc->module->allocator; + irValue *size = ir_make_const_int(a, type_size_of(proc->module->sizes, a, elem)); + irValue *align = ir_make_const_int(a, type_align_of(proc->module->sizes, a, elem)); { irValue **args = gb_alloc_array(a, irValue *, 4); + args[0] = ir_emit_conv(proc, v, t_rawptr); + args[1] = size; + args[2] = align; + args[3] = ir_make_const_int(a, 2*cl->elems.count); + ir_emit_global_call(proc, "__dynamic_array_reserve", args, 4); + } + + i64 item_count = cl->elems.count; + irValue *items = ir_generate_array(proc->module, elem, item_count, str_lit("__dacl$"), cast(i64)cast(intptr)expr); + + for_array(field_index, cl->elems) { + AstNode *f = cl->elems.e[field_index]; + irValue *value = ir_emit_conv(proc, ir_build_expr(proc, f), elem); + irValue *ep = ir_emit_array_epi(proc, items, field_index); + ir_emit_store(proc, ep, value); + } + + { + irValue **args = gb_alloc_array(a, irValue *, 5); + args[0] = ir_emit_conv(proc, v, t_rawptr); + args[1] = size; + args[2] = align; + args[3] = ir_emit_conv(proc, items, t_rawptr); + args[4] = ir_make_const_int(a, item_count); + ir_emit_global_call(proc, "__dynamic_array_append", args, 5); + } + } break; + + case Type_Map: { + if (cl->elems.count == 0) { + break; + } + gbAllocator a = proc->module->allocator; + { + irValue **args = gb_alloc_array(a, irValue *, 2); args[0] = ir_gen_map_header(proc, v, type); args[1] = ir_make_const_int(a, 2*cl->elems.count); ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2); @@ -5294,17 +5326,6 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { AstNode *clause = body->stmts.e[i]; ast_node(cc, CaseClause, clause); - if (cc->list.count == 0) { - // default case - default_stmts = cc->stmts; - default_block = ir_new_block(proc, clause, "type-match.dflt.body"); - continue; - } - GB_ASSERT(cc->list.count == 1); - - - irBlock *body = ir_new_block(proc, clause, "type-match.case.body"); - Entity *tag_var_entity = NULL; Type *tag_var_type = NULL; if (str_eq(tag_var_name, str_lit("_"))) { @@ -5324,6 +5345,26 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { irBlock *next_cond = NULL; irValue *cond = NULL; + if (cc->list.count == 0) { + // default case + default_stmts = cc->stmts; + default_block = ir_new_block(proc, clause, "type-match.dflt.body"); + + + irValue *tag_var = NULL; + if (tag_var_entity != NULL) { + tag_var = ir_add_local(proc, tag_var_entity); + } else { + tag_var = ir_add_local_generated(proc, tag_var_type); + } + ir_emit_store(proc, tag_var, parent); + continue; + } + GB_ASSERT(cc->list.count == 1); + + irBlock *body = ir_new_block(proc, clause, "type-match.case.body"); + + if (is_union_ptr) { Type *bt = type_deref(tag_var_type); irValue *index = NULL; @@ -6409,38 +6450,10 @@ void ir_gen_tree(irGen *s) { if (t->Record.field_count > 0) { Entity **fields = t->Record.fields; isize count = t->Record.field_count; - irValue *name_array = NULL; - irValue *value_array = NULL; - - { - Token token = {Token_Ident}; - i32 id = cast(i32)entry_index; - char name_base[] = "__$enum_names"; - isize name_len = gb_size_of(name_base) + 10; - token.string.text = gb_alloc_array(a, u8, name_len); - token.string.len = gb_snprintf(cast(char *)token.string.text, name_len, - "%s-%d", name_base, id)-1; - Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_string, count), false); - name_array = ir_make_value_global(a, e, NULL); - name_array->Global.is_private = true; - ir_module_add_value(m, e, name_array); - map_ir_value_set(&m->members, hash_string(token.string), name_array); - } - - { - Token token = {Token_Ident}; - i32 id = cast(i32)entry_index; - char name_base[] = "__$enum_values"; - isize name_len = gb_size_of(name_base) + 10; - token.string.text = gb_alloc_array(a, u8, name_len); - token.string.len = gb_snprintf(cast(char *)token.string.text, name_len, - "%s-%d", name_base, id)-1; - Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_type_info_enum_value, count), false); - value_array = ir_make_value_global(a, e, NULL); - value_array->Global.is_private = true; - ir_module_add_value(m, e, value_array); - map_ir_value_set(&m->members, hash_string(token.string), value_array); - } + irValue *name_array = ir_generate_array(m, t_string, count, + str_lit("__$enum_names"), cast(i64)entry_index); + irValue *value_array = ir_generate_array(m, t_type_info_enum_value, count, + str_lit("__$enum_values"), cast(i64)entry_index); bool is_value_int = is_type_integer(t->Record.enum_base_type); |