diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_builtin.cpp | 23 | ||||
| -rw-r--r-- | src/checker.cpp | 3 | ||||
| -rw-r--r-- | src/checker_builtin_procs.hpp | 2 | ||||
| -rw-r--r-- | src/llvm_backend.cpp | 14 | ||||
| -rw-r--r-- | src/llvm_backend.hpp | 3 | ||||
| -rw-r--r-- | src/llvm_backend_general.cpp | 1 | ||||
| -rw-r--r-- | src/llvm_backend_proc.cpp | 3 | ||||
| -rw-r--r-- | src/types.cpp | 2 |
8 files changed, 49 insertions, 2 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index b8bf1bcc7..457100d6e 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -5363,6 +5363,29 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } + case BuiltinProc_type_map_info: + { + Operand op = {}; + Type *bt = check_type(c, ce->args[0]); + Type *type = base_type(bt); + if (type == nullptr || type == t_invalid) { + error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name)); + return false; + } + if (!is_type_map(type)) { + gbString t = type_to_string(type); + error(ce->args[0], "Expected a map type for '%.*s', got %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + add_map_key_type_dependencies(c, type); + + operand->mode = Addressing_Value; + operand->type = t_map_info_ptr; + break; + } + case BuiltinProc_constant_utf16_cstring: { String value = {}; diff --git a/src/checker.cpp b/src/checker.cpp index fa3ef245b..5b9e83bda 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2851,6 +2851,9 @@ void init_core_map_type(Checker *c) { t_map_info = find_core_type(c, str_lit("Map_Info")); t_map_cell_info = find_core_type(c, str_lit("Map_Cell_Info")); t_raw_map = find_core_type(c, str_lit("Raw_Map")); + + t_map_info_ptr = alloc_type_pointer(t_map_info); + t_map_cell_info_ptr = alloc_type_pointer(t_map_cell_info); } void init_preload(Checker *c) { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index c59ae7867..72639e071 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -277,6 +277,7 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc_type_equal_proc, BuiltinProc_type_hasher_proc, + BuiltinProc_type_map_info, BuiltinProc__type_end, @@ -572,6 +573,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_equal_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_hasher_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_map_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index fa9727106..960ef84f6 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -502,6 +502,11 @@ lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, A LLVMValueRef lb_gen_map_cell_info(lbModule *m, Type *type) { + lbAddr *found = map_get(&m->map_cell_info_map, type); + if (found) { + return found->addr.value; + } + i64 size = 0, len = 0; map_cell_size_and_len(type, &size, &len); @@ -510,8 +515,15 @@ LLVMValueRef lb_gen_map_cell_info(lbModule *m, Type *type) { const_values[1] = lb_const_int(m, t_uintptr, type_align_of(type)).value; const_values[2] = lb_const_int(m, t_uintptr, size).value; const_values[3] = lb_const_int(m, t_uintptr, len).value; - return llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values)); + LLVMValueRef llvm_res = llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values)); + lbValue res = {llvm_res, t_map_cell_info}; + + lbAddr addr = lb_add_global_generated(m, t_map_cell_info, res, nullptr); + lb_make_global_private_const(addr); + + map_set(&m->map_cell_info_map, type, addr); + return addr.addr.value; } lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) { map_type = base_type(map_type); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 2b9014d94..065bf4943 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -160,7 +160,8 @@ struct lbModule { StringMap<lbAddr> objc_classes; StringMap<lbAddr> objc_selectors; - PtrMap<Type *, lbAddr> map_info_map; + PtrMap<Type *, lbAddr> map_cell_info_map; // address of runtime.Map_Info + PtrMap<Type *, lbAddr> map_info_map; // address of runtime.Map_Cell_Info }; struct lbGenerator { diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index ffc7a1496..b7654614e 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -76,6 +76,7 @@ void lb_init_module(lbModule *m, Checker *c) { string_map_init(&m->objc_selectors, a); map_init(&m->map_info_map, a, 0); + map_init(&m->map_cell_info_map, a, 0); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index a9de7b231..3881790e0 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2324,6 +2324,9 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_type_hasher_proc: return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type); + case BuiltinProc_type_map_info: + return lb_gen_map_info_ptr(p->module, ce->args[0]->tav.type); + case BuiltinProc_fixed_point_mul: case BuiltinProc_fixed_point_div: case BuiltinProc_fixed_point_mul_sat: diff --git a/src/types.cpp b/src/types.cpp index c92d8a78f..ca15531dd 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -685,6 +685,8 @@ gb_global Type *t_source_code_location_ptr = nullptr; gb_global Type *t_map_info = nullptr; gb_global Type *t_map_cell_info = nullptr; +gb_global Type *t_map_info_ptr = nullptr; +gb_global Type *t_map_cell_info_ptr = nullptr; gb_global Type *t_raw_map = nullptr; |