Browse Source

Fix default initialized values for globals (#217)

gingerBill 7 years ago
parent
commit
3b48fa8e7d
5 changed files with 92 additions and 62 deletions
  1. 2 12
      core/_preload.odin
  2. 2 5
      src/check_expr.cpp
  3. 0 1
      src/checker.cpp
  4. 59 41
      src/ir.cpp
  5. 29 3
      src/ir_print.cpp

+ 2 - 12
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;

+ 2 - 5
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;
 		}
 

+ 0 - 1
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"),

+ 59 - 41
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<irValue *> 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<irValue *>(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;
+				}
 			}
 		}
 	}

+ 29 - 3
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');