diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 27d40f4a3..87af6b7bb 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -24,7 +24,7 @@ import "intrinsics" // implemented within the compiler rather than in this "preload" file // NOTE(bill): This must match the compiler's -Calling_Convention :: enum { +Calling_Convention :: enum u8 { Invalid = 0, Odin = 1, Contextless = 2, diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 67172d951..e9b6869c8 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1155,10 +1155,12 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { } } + bool is_reference = false; + if (is_ptr && cc->list.count == 1 && case_type != nullptr) { - case_type = alloc_type_pointer(case_type); + is_reference = true; } if (cc->list.count > 1) { @@ -1173,7 +1175,9 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { { Entity *tag_var = alloc_entity_variable(ctx->scope, lhs->Ident.token, case_type, EntityState_Resolved); tag_var->flags |= EntityFlag_Used; - tag_var->flags |= EntityFlag_Value; + if (!is_reference) { + tag_var->flags |= EntityFlag_Value; + } add_entity(ctx->checker, ctx->scope, lhs, tag_var); add_entity_use(ctx, lhs, tag_var); add_implicit_entity(ctx, stmt, tag_var); diff --git a/src/entity.cpp b/src/entity.cpp index 9cc77360e..a64e767d6 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -2,6 +2,8 @@ struct Scope; struct Checker; struct Type; struct DeclInfo; +struct lbModule; +struct lbProcedure; #define ENTITY_KINDS \ @@ -30,7 +32,7 @@ String const entity_strings[] = { #undef ENTITY_KIND }; -enum EntityFlag { +enum EntityFlag : u32 { EntityFlag_Visited = 1<<0, EntityFlag_Used = 1<<1, EntityFlag_Using = 1<<2, @@ -106,6 +108,9 @@ struct Entity { Entity * using_parent; Ast * using_expr; + lbModule * code_gen_module; + lbProcedure *code_gen_procedure; + isize order_in_src; String deprecated_message; diff --git a/src/ir.cpp b/src/ir.cpp index 540bd0406..f51538a2e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15,7 +15,7 @@ struct irModule { u64 state_flags; // String source_filename; - String layout; + // String layout; // String triple; PtrSet min_dep_set; @@ -3762,7 +3762,6 @@ irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) { } if (addr.kind == irAddr_Map) { - // TODO(bill): map lookup Type *map_type = base_type(addr.map_type); irValue *v = ir_add_local_generated(proc, map_type->Map.lookup_result_type, true); irValue *h = ir_gen_map_header(proc, addr.addr, map_type); @@ -5927,34 +5926,6 @@ irValue *ir_type_info(irProcedure *proc, Type *type) { return ir_emit_array_ep(proc, ir_global_type_info_data, ir_const_i32(id)); } -// IMPORTANT NOTE(bill): This must match the same as the in core.odin -enum Typeid_Kind : u8 { - Typeid_Invalid, - Typeid_Integer, - Typeid_Rune, - Typeid_Float, - Typeid_Complex, - Typeid_Quaternion, - Typeid_String, - Typeid_Boolean, - Typeid_Any, - Typeid_Type_Id, - Typeid_Pointer, - Typeid_Procedure, - Typeid_Array, - Typeid_Enumerated_Array, - Typeid_Dynamic_Array, - Typeid_Slice, - Typeid_Tuple, - Typeid_Struct, - Typeid_Union, - Typeid_Enum, - Typeid_Map, - Typeid_Bit_Field, - Typeid_Bit_Set, -}; - - irValue *ir_typeid(irModule *m, Type *type) { type = default_type(type); @@ -9559,13 +9530,16 @@ void ir_build_range_tuple(irProcedure *proc, Ast *expr, Type *val0_type, Type *v void ir_store_type_case_implicit(irProcedure *proc, Ast *clause, irValue *value) { Entity *e = implicit_entity_of_node(clause); GB_ASSERT(e != nullptr); -#if 1 - irValue *x = ir_add_local(proc, e, nullptr, false); - ir_emit_store(proc, x, value); -#else - irValue *x = ir_address_from_load_or_generate_local(proc, value); - ir_module_add_value(proc->module, e, x); -#endif + + if (e->flags & EntityFlag_Value) { + // by value + irValue *x = ir_add_local(proc, e, nullptr, false); + GB_ASSERT(are_types_identical(ir_type(value), e->type)); + ir_emit_store(proc, x, value); + } else { + // by reference + ir_module_add_value(proc->module, e, value); + } } void ir_type_case_body(irProcedure *proc, Ast *label, Ast *clause, irBlock *body, irBlock *done) { @@ -10506,14 +10480,8 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { ir_start_block(proc, body); // bool any_or_not_ptr = is_type_any(type_deref(parent_type)) || !is_parent_ptr; - bool any_or_not_ptr = !is_parent_ptr; if (cc->list.count == 1) { - Type *ct = case_entity->type; - if (any_or_not_ptr) { - ct = alloc_type_pointer(ct); - } - GB_ASSERT_MSG(is_type_pointer(ct), "%s", type_to_string(ct)); irValue *data = nullptr; if (switch_kind == TypeSwitch_Union) { data = union_data; @@ -10521,9 +10489,17 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { irValue *any_data = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 0)); data = any_data; } - value = ir_emit_conv(proc, data, ct); - if (any_or_not_ptr) { + Type *ct = case_entity->type; + Type *ct_ptr = alloc_type_pointer(ct); + + + value = ir_emit_conv(proc, data, ct_ptr); + + if (case_entity->flags & EntityFlag_Value) { + // by value value = ir_emit_load(proc, value); + } else { + // by reference } } @@ -11503,7 +11479,7 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info ir_emit_store(proc, results, ir_get_type_info_ptr(proc, t->Proc.results)); } ir_emit_store(proc, variadic, ir_const_bool(t->Proc.variadic)); - ir_emit_store(proc, convention, ir_const_int(t->Proc.calling_convention)); + ir_emit_store(proc, convention, ir_const_u8(t->Proc.calling_convention)); // TODO(bill): TypeInfo for procedures break; diff --git a/src/types.cpp b/src/types.cpp index d2a040b0b..86be0d38f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -302,6 +302,34 @@ struct Type { bool failure; }; +// IMPORTANT NOTE(bill): This must match the same as the in core.odin +enum Typeid_Kind : u8 { + Typeid_Invalid, + Typeid_Integer, + Typeid_Rune, + Typeid_Float, + Typeid_Complex, + Typeid_Quaternion, + Typeid_String, + Typeid_Boolean, + Typeid_Any, + Typeid_Type_Id, + Typeid_Pointer, + Typeid_Procedure, + Typeid_Array, + Typeid_Enumerated_Array, + Typeid_Dynamic_Array, + Typeid_Slice, + Typeid_Tuple, + Typeid_Struct, + Typeid_Union, + Typeid_Enum, + Typeid_Map, + Typeid_Bit_Field, + Typeid_Bit_Set, +}; + + // TODO(bill): Should I add extra information here specifying the kind of selection? @@ -1113,13 +1141,13 @@ bool is_type_simd_vector(Type *t) { } Type *base_array_type(Type *t) { - if (is_type_array(t)) { - t = base_type(t); - return t->Array.elem; - } - if (is_type_simd_vector(t)) { - t = base_type(t); - return t->SimdVector.elem; + Type *bt = base_type(t); + if (is_type_array(bt)) { + return bt->Array.elem; + } else if (is_type_enumerated_array(bt)) { + return bt->EnumeratedArray.elem; + } else if (is_type_simd_vector(bt)) { + return bt->SimdVector.elem; } return t; } @@ -3160,6 +3188,14 @@ i64 type_offset_of_from_selection(Type *type, Selection sel) { return offset; } + +Type *get_struct_field_type(Type *t, isize index) { + t = base_type(type_deref(t)); + GB_ASSERT(t->kind == Type_Struct); + return t->Struct.fields[index]->type; +} + + gbString write_type_to_string(gbString str, Type *type) { if (type == nullptr) { return gb_string_appendc(str, ""); @@ -3391,7 +3427,13 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_appendc(str, ")"); if (type->Proc.results) { str = gb_string_appendc(str, " -> "); + if (type->Proc.results->Tuple.variables.count > 1) { + str = gb_string_appendc(str, "("); + } str = write_type_to_string(str, type->Proc.results); + if (type->Proc.results->Tuple.variables.count > 1) { + str = gb_string_appendc(str, ")"); + } } break; @@ -3448,4 +3490,3 @@ gbString type_to_string(Type *type) { return write_type_to_string(gb_string_make(heap_allocator(), ""), type); } -