From 3b48fa8e7d87c9a6270cf1e59c67c66c3f3f9410 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 12 May 2018 21:22:39 +0100 Subject: [PATCH] Fix default initialized values for globals (#217) --- core/_preload.odin | 14 +------ src/check_expr.cpp | 7 +--- src/checker.cpp | 1 - src/ir.cpp | 100 ++++++++++++++++++++++++++------------------- src/ir_print.cpp | 32 +++++++++++++-- 5 files changed, 92 insertions(+), 62 deletions(-) diff --git a/core/_preload.odin b/core/_preload.odin index 646a6313c..baccecebb 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -244,7 +244,7 @@ __typeid_of :: proc "contextless" (ti: ^Type_Info) -> typeid { start := uintptr(&__type_table[0]); end := uintptr(ti); id := (end-start)/size_of(Type_Info); - if uintptr(len(__type_table)) < id { + if uintptr(len(__type_table)) <= id { return nil; } return transmute(typeid)id; @@ -287,11 +287,6 @@ foreign __llvm_core { -make_source_code_location :: inline proc "contextless" (file: string, line, column: int, procedure: string) -> Source_Code_Location { - return Source_Code_Location{file, line, column, procedure}; -} - - __init_context_from_ptr :: proc "contextless" (c: ^Context, other: ^Context) { @@ -312,11 +307,6 @@ __init_context :: proc "contextless" (c: ^Context) { } -/* -__check_context :: proc() { - __init_context(&__context); -} -*/ alloc :: inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> rawptr { a := context.allocator; @@ -489,7 +479,7 @@ reserve :: proc[reserve_dynamic_array, reserve_map]; -new :: inline proc(T: type, loc := #caller_location) -> ^T { +new :: inline proc(T: type, loc := #caller_location) -> ^T { ptr := cast(^T)alloc(size_of(T), align_of(T), loc); ptr^ = T{}; return ptr; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 760e72cfe..0e575e07d 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3424,13 +3424,12 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id if (is_operand_value(o) && is_type_typeid(t)) { add_preload_dependency(c, "__type_info_of"); } else if (o.mode != Addressing_Type) { - error(ce->args[0], "Expected a type or typeid for 'type_info_of'"); + error(expr, "Expected a type or typeid for 'type_info_of'"); return false; } operand->mode = Addressing_Value; operand->type = t_type_info_ptr; - break; } @@ -3461,9 +3460,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id if (is_operand_value(o) && are_types_identical(t, t_type_info_ptr)) { add_preload_dependency(c, "__typeid_of"); } else if (o.mode != Addressing_Type) { - gbString ts = type_to_string(o.type); - error(ce->args[0], "Expected a type or type info for 'typeid_of', got %s", ts); - gb_string_free(ts); + error(expr, "Expected a type or type info for 'typeid_of'"); return false; } diff --git a/src/checker.cpp b/src/checker.cpp index b0aa30e04..dd2033d0d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1338,7 +1338,6 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("__mem_zero"), str_lit("__init_context"), str_lit("default_allocator"), - str_lit("make_source_code_location"), str_lit("__args__"), str_lit("__type_table"), diff --git a/src/ir.cpp b/src/ir.cpp index 7197534ae..3511d8482 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -334,6 +334,7 @@ enum irValueKind { irValue_TypeName, irValue_Global, irValue_Param, + irValue_SourceCodeLocation, irValue_Proc, irValue_Block, @@ -397,6 +398,13 @@ struct irValueParam { Array referrers; }; +struct irValueSourceCodeLocation { + irValue *file; + irValue *line; + irValue *column; + irValue *procedure; +}; + struct irValue { irValueKind kind; @@ -414,6 +422,7 @@ struct irValue { irProcedure Proc; irBlock Block; irInstr Instr; + irValueSourceCodeLocation SourceCodeLocation; }; }; @@ -663,6 +672,8 @@ Type *ir_type(irValue *value) { return value->Global.type; case irValue_Param: return value->Param.type; + case irValue_SourceCodeLocation: + return t_source_code_location; case irValue_Proc: return value->Proc.type; case irValue_Instr: @@ -4121,12 +4132,12 @@ bool is_double_pointer(Type *t) { irValue *ir_emit_source_code_location(irProcedure *proc, String procedure, TokenPos pos) { gbAllocator a = proc->module->allocator; - auto args = array_make(proc->module->allocator, 4); - args[0] = ir_find_or_add_entity_string(proc->module, pos.file); - args[1] = ir_const_int(a, pos.line); - args[2] = ir_const_int(a, pos.column); - args[3] = ir_find_or_add_entity_string(proc->module, procedure); - return ir_emit_global_call(proc, "make_source_code_location", args); + irValue *v = ir_alloc_value(a, irValue_SourceCodeLocation); + v->SourceCodeLocation.file = ir_find_or_add_entity_string(proc->module, pos.file); + v->SourceCodeLocation.line = ir_const_int(a, pos.line); + v->SourceCodeLocation.column = ir_const_int(a, pos.column); + v->SourceCodeLocation.procedure = ir_find_or_add_entity_string(proc->module, procedure); + return v; } @@ -7695,6 +7706,11 @@ void ir_init_module(irModule *m, Checker *c) { for_array(entry_index, m->info->type_info_types) { Type *t = m->info->type_info_types[entry_index]; + isize index = ir_type_info_index(m->info, t, false); + if (index < 0) { + continue; + } + switch (t->kind) { case Type_Union: count += t->Union.variants.count; @@ -7708,42 +7724,44 @@ void ir_init_module(irModule *m, Checker *c) { } } - { - String name = str_lit(IR_TYPE_INFO_TYPES_NAME); - Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), - alloc_type_array(t_type_info_ptr, count), false); - irValue *g = ir_value_global(m->allocator, e, nullptr); - ir_module_add_value(m, e, g); - map_set(&m->members, hash_string(name), g); - ir_global_type_info_member_types = g; - } - { - String name = str_lit(IR_TYPE_INFO_NAMES_NAME); - Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), - alloc_type_array(t_string, count), false); - irValue *g = ir_value_global(m->allocator, e, nullptr); - ir_module_add_value(m, e, g); - map_set(&m->members, hash_string(name), g); - ir_global_type_info_member_names = g; - } - { - String name = str_lit(IR_TYPE_INFO_OFFSETS_NAME); - Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), - alloc_type_array(t_uintptr, count), false); - irValue *g = ir_value_global(m->allocator, e, nullptr); - ir_module_add_value(m, e, g); - map_set(&m->members, hash_string(name), g); - ir_global_type_info_member_offsets = g; - } + if (count > 0) { + { + String name = str_lit(IR_TYPE_INFO_TYPES_NAME); + Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), + alloc_type_array(t_type_info_ptr, count), false); + irValue *g = ir_value_global(m->allocator, e, nullptr); + ir_module_add_value(m, e, g); + map_set(&m->members, hash_string(name), g); + ir_global_type_info_member_types = g; + } + { + String name = str_lit(IR_TYPE_INFO_NAMES_NAME); + Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), + alloc_type_array(t_string, count), false); + irValue *g = ir_value_global(m->allocator, e, nullptr); + ir_module_add_value(m, e, g); + map_set(&m->members, hash_string(name), g); + ir_global_type_info_member_names = g; + } + { + String name = str_lit(IR_TYPE_INFO_OFFSETS_NAME); + Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), + alloc_type_array(t_uintptr, count), false); + irValue *g = ir_value_global(m->allocator, e, nullptr); + ir_module_add_value(m, e, g); + map_set(&m->members, hash_string(name), g); + ir_global_type_info_member_offsets = g; + } - { - String name = str_lit(IR_TYPE_INFO_USINGS_NAME); - Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), - alloc_type_array(t_bool, count), false); - irValue *g = ir_value_global(m->allocator, e, nullptr); - ir_module_add_value(m, e, g); - map_set(&m->members, hash_string(name), g); - ir_global_type_info_member_usings = g; + { + String name = str_lit(IR_TYPE_INFO_USINGS_NAME); + Entity *e = alloc_entity_variable(nullptr, make_token_ident(name), + alloc_type_array(t_bool, count), false); + irValue *g = ir_value_global(m->allocator, e, nullptr); + ir_module_add_value(m, e, g); + map_set(&m->members, hash_string(name), g); + ir_global_type_info_member_usings = g; + } } } } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 862281a55..1d98557d4 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -319,8 +319,6 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) { case Basic_rune: ir_write_str_lit(f, "i32"); return; - case Basic_typeid: - /* fallthrough */ case Basic_int: case Basic_uint: case Basic_uintptr: @@ -343,6 +341,8 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) { case Basic_rawptr: ir_write_str_lit(f, "%..rawptr"); return; case Basic_string: ir_write_str_lit(f, "%..string"); return; case Basic_cstring: ir_write_str_lit(f, "i8*"); return; + + case Basic_typeid: ir_write_str_lit(f, "%..typeid"); return; } break; @@ -953,6 +953,23 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin case irValue_Param: ir_print_encoded_local(f, value->Param.entity->token.string); break; + case irValue_SourceCodeLocation: { + irValue *file = value->SourceCodeLocation.file; + irValue *line = value->SourceCodeLocation.line; + irValue *column = value->SourceCodeLocation.column; + irValue *procedure = value->SourceCodeLocation.procedure; + + ir_write_byte(f, '{'); + ir_print_type(f, m, t_string); ir_write_byte(f, ' '); ir_print_value(f, m, file, t_string); + ir_write_string(f, str_lit(", ")); + ir_print_type(f, m, t_int); ir_write_byte(f, ' '); ir_print_value(f, m, line, t_int); + ir_write_string(f, str_lit(", ")); + ir_print_type(f, m, t_int); ir_write_byte(f, ' '); ir_print_value(f, m, column, t_int); + ir_write_string(f, str_lit(", ")); + ir_print_type(f, m, t_string); ir_write_byte(f, ' '); ir_print_value(f, m, procedure, t_string); + ir_write_byte(f, '}'); + break; + } case irValue_Proc: ir_print_encoded_global(f, value->Proc.name, ir_print_is_proc_global(m, &value->Proc)); break; @@ -1747,6 +1764,11 @@ void print_llvm_ir(irGen *ir) { ir_print_encoded_local(f, str_lit("..complex128")); ir_write_str_lit(f, " = type {double, double} ; Basic_complex128\n"); + ir_print_encoded_local(f, str_lit("..typeid")); + ir_write_str_lit(f, " = type "); + ir_print_type(f, m, t_uintptr); + ir_write_str_lit(f, " ; Basic_typeid\n"); + ir_print_encoded_local(f, str_lit("..any")); ir_write_str_lit(f, " = type {"); ir_print_type(f, m, t_rawptr); @@ -1851,7 +1873,11 @@ void print_llvm_ir(irGen *ir) { if (g->value != nullptr) { ir_print_value(f, m, g->value, g->entity->type); } else { - ir_write_string(f, str_lit("zeroinitializer")); + if (ir_type_has_default_values(g->entity->type)) { + ir_print_exact_value(f, m, empty_exact_value, g->entity->type); + } else { + ir_write_string(f, str_lit("zeroinitializer")); + } } } ir_write_byte(f, '\n');