diff --git a/src/compiler/c_abi_internal.h b/src/compiler/c_abi_internal.h index 00872e0cd..4fe5b4f95 100644 --- a/src/compiler/c_abi_internal.h +++ b/src/compiler/c_abi_internal.h @@ -23,8 +23,8 @@ ABIArgInfo *abi_arg_new_direct_coerce(AbiType *target_type); ABIArgInfo *abi_arg_new_expand_coerce(AbiType *target_type, unsigned offset); ABIArgInfo *abi_arg_new_expand_coerce_pair(AbiType *first_element, unsigned initial_offset, AbiType *second_element, unsigned padding, bool is_packed); ABIArgInfo *abi_arg_new_expand_padded(Type *padding); -ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment); -ABIArgInfo *abi_arg_new_indirect_by_val(void); +ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment, Type *by_val_type); +ABIArgInfo *abi_arg_new_indirect_by_val(Type *by_val_type); ABIArgInfo *abi_arg_new_indirect_not_by_val(void); ByteSize abi_type_abi_alignment(AbiType *type); diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 4baa1ae6d..e13965749 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -6,7 +6,7 @@ #include "../build/build_options.h" #include -Compiler compiler; +GlobalContext global_context; BuildTarget active_target; Vmem ast_arena; @@ -22,8 +22,8 @@ void compiler_init(const char *std_lib_dir) // Skip library detection. //compiler.lib_dir = find_lib_dir(); //DEBUG_LOG("Found std library: %s", compiler.lib_dir); - stable_init(&compiler.modules, 64); - stable_init(&compiler.global_symbols, 0x1000); + stable_init(&global_context.modules, 64); + stable_init(&global_context.global_symbols, 0x1000); vmem_init(&ast_arena, 4 * 1024); vmem_init(&expr_arena, 4 * 1024); vmem_init(&decl_arena, 1024); @@ -37,20 +37,20 @@ void compiler_init(const char *std_lib_dir) (void) tokdata_calloc(); if (std_lib_dir) { - compiler.lib_dir = std_lib_dir; + global_context.lib_dir = std_lib_dir; } else { - compiler.lib_dir = find_lib_dir(); + global_context.lib_dir = find_lib_dir(); } } static void compiler_lex(void) { - VECEACH(compiler.sources, i) + VECEACH(global_context.sources, i) { bool loaded = false; - File *file = source_file_load(compiler.sources[i], &loaded); + File *file = source_file_load(global_context.sources[i], &loaded); if (loaded) continue; Lexer lexer; lexer_init_with_file(&lexer, file); @@ -68,10 +68,10 @@ static void compiler_lex(void) void compiler_parse(void) { - VECEACH(compiler.sources, i) + VECEACH(global_context.sources, i) { bool loaded = false; - File *file = source_file_load(compiler.sources[i], &loaded); + File *file = source_file_load(global_context.sources[i], &loaded); if (loaded) continue; diag_setup(active_target.test_output); Context *context = context_create(file); @@ -85,19 +85,19 @@ void compiler_compile(void) { Context **contexts = NULL; diag_setup(active_target.test_output); - if (compiler.lib_dir) + if (global_context.lib_dir) { - vec_add(compiler.sources, strformat("%s/std/runtime.c3", compiler.lib_dir)); - vec_add(compiler.sources, strformat("%s/std/builtin.c3", compiler.lib_dir)); - vec_add(compiler.sources, strformat("%s/std/io.c3", compiler.lib_dir)); - vec_add(compiler.sources, strformat("%s/std/mem.c3", compiler.lib_dir)); - vec_add(compiler.sources, strformat("%s/std/array.c3", compiler.lib_dir)); - vec_add(compiler.sources, strformat("%s/std/math.c3", compiler.lib_dir)); + vec_add(global_context.sources, strformat("%s/std/runtime.c3", global_context.lib_dir)); + vec_add(global_context.sources, strformat("%s/std/builtin.c3", global_context.lib_dir)); + vec_add(global_context.sources, strformat("%s/std/io.c3", global_context.lib_dir)); + vec_add(global_context.sources, strformat("%s/std/mem.c3", global_context.lib_dir)); + vec_add(global_context.sources, strformat("%s/std/array.c3", global_context.lib_dir)); + vec_add(global_context.sources, strformat("%s/std/math.c3", global_context.lib_dir)); } - VECEACH(compiler.sources, i) + VECEACH(global_context.sources, i) { bool loaded = false; - File *file = source_file_load(compiler.sources[i], &loaded); + File *file = source_file_load(global_context.sources[i], &loaded); if (loaded) continue; Context *context = context_create(file); vec_add(contexts, context); @@ -272,7 +272,7 @@ void compile_file_list(BuildOptions *options) void compile() { - compiler.sources = active_target.sources; + global_context.sources = active_target.sources; symtab_init(active_target.symtab_size ? active_target.symtab_size : 64 * 1024); target_expand_source_names(&active_target); target_setup(&active_target); @@ -294,19 +294,19 @@ void compile() Decl *compiler_find_symbol(const char *string) { - return stable_get(&compiler.global_symbols, string); + return stable_get(&global_context.global_symbols, string); } -void compiler_add_type(Type *type) +void global_context_add_type(Type *type) { DEBUG_LOG("Created type %s.", type->name); assert(type_ok(type)); - VECADD(compiler.type, type); + VECADD(global_context.type, type); } Module *compiler_find_or_create_module(Path *module_name) { - Module *module = stable_get(&compiler.modules, module_name->module); + Module *module = stable_get(&global_context.modules, module_name->module); if (module) { @@ -324,7 +324,7 @@ Module *compiler_find_or_create_module(Path *module_name) module = CALLOCS(Module); module->name = module_name; stable_init(&module->symbols, 0x10000); - stable_set(&compiler.modules, module_name->module, module); + stable_set(&global_context.modules, module_name->module, module); // Now find the possible parent array: Path *parent_path = path_find_parent_path(NULL, module_name); if (parent_path) @@ -339,15 +339,15 @@ Module *compiler_find_or_create_module(Path *module_name) void compiler_register_public_symbol(Decl *decl) { assert(decl->name); - Decl *prev = stable_get(&compiler.global_symbols, decl->name); + Decl *prev = stable_get(&global_context.global_symbols, decl->name); // If the previous symbol was already declared globally, remove it. - stable_set(&compiler.global_symbols, decl->name, prev ? poisoned_decl : decl); - STable *sub_module_space = stable_get(&compiler.qualified_symbols, decl->module->name->module); + stable_set(&global_context.global_symbols, decl->name, prev ? poisoned_decl : decl); + STable *sub_module_space = stable_get(&global_context.qualified_symbols, decl->module->name->module); if (!sub_module_space) { sub_module_space = malloc_arena(sizeof(*sub_module_space)); stable_init(sub_module_space, 0x100); - stable_set(&compiler.qualified_symbols, decl->module->name->module, sub_module_space); + stable_set(&global_context.qualified_symbols, decl->module->name->module, sub_module_space); } prev = stable_get(sub_module_space, decl->name); stable_set(sub_module_space, decl->name, prev ? poisoned_decl : decl); diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 385ac515a..964b56e0b 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -206,6 +206,7 @@ typedef struct typedef struct { struct _FunctionSignature *signature; + const char *mangled_function_signature; } TypeFunc; struct _Type @@ -354,7 +355,6 @@ typedef struct _FunctionSignature struct ABIArgInfo_ *ret_abi_info; struct ABIArgInfo_ *failable_abi_info; Decl** params; - const char *mangled_signature; } FunctionSignature; typedef struct @@ -1287,7 +1287,7 @@ typedef struct Type **type; const char *lib_dir; const char **sources; -} Compiler; +} GlobalContext; typedef enum { @@ -1370,13 +1370,13 @@ typedef struct ABIArgInfo_ { // We may request a certain alignment of the parameters. AlignSize realignment; - bool by_val : 1; + Type *by_val_type; } indirect; }; } ABIArgInfo; -extern Compiler compiler; +extern GlobalContext global_context; extern BuildTarget active_target; extern Ast *poisoned_ast; extern Decl *poisoned_decl; @@ -1489,7 +1489,7 @@ void llvm_codegen_setup(); void header_gen(Context *context); -void compiler_add_type(Type *type); +void global_context_add_type(Type *type); Decl *compiler_find_symbol(const char *name); Module *compiler_find_or_create_module(Path *module_name); void compiler_register_public_symbol(Decl *decl); @@ -1850,7 +1850,7 @@ static inline Type *type_new(TypeKind kind, const char *name) type->type_kind = kind; assert(name); type->name = name; - compiler_add_type(type); + global_context_add_type(type); return type; } diff --git a/src/compiler/llvm_codegen_c_abi.c b/src/compiler/llvm_codegen_c_abi.c index b6f48fcdf..0255adbd1 100644 --- a/src/compiler/llvm_codegen_c_abi.c +++ b/src/compiler/llvm_codegen_c_abi.c @@ -84,26 +84,26 @@ bool abi_arg_is_indirect(ABIArgInfo *info) UNREACHABLE } -ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment) +ABIArgInfo *abi_arg_new_indirect_realigned(unsigned alignment, Type *by_val_type) { assert(alignment > 0); ABIArgInfo *info = abi_arg_new(ABI_ARG_INDIRECT); info->indirect.realignment = alignment; - info->indirect.by_val = true; + info->indirect.by_val_type = by_val_type; return info; } -ABIArgInfo *abi_arg_new_indirect_by_val(void) +ABIArgInfo *abi_arg_new_indirect_by_val(Type *by_val_type) { ABIArgInfo *info = abi_arg_new(ABI_ARG_INDIRECT); - info->indirect.by_val = true; + info->indirect.by_val_type = by_val_type; return info; } ABIArgInfo *abi_arg_new_indirect_not_by_val(void) { ABIArgInfo *info = abi_arg_new(ABI_ARG_INDIRECT); - info->indirect.by_val = false; + info->indirect.by_val_type = NULL; return info; } @@ -221,9 +221,9 @@ ABIArgInfo *c_abi_classify_argument_type_default(Type *type) type = type_lowering(type); // Struct-likes are returned by sret - if (type_is_abi_aggregate(type)) return abi_arg_new_indirect_by_val(); + if (type_is_abi_aggregate(type)) return abi_arg_new_indirect_by_val(type); - if (type_is_int128(type) && !platform_target.int128) return abi_arg_new_indirect_by_val(); + if (type_is_int128(type) && !platform_target.int128) return abi_arg_new_indirect_by_val(type); // Otherwise do we have a type that needs promotion? if (type_is_promotable_integer(type)) return abi_arg_new_direct_int_ext(type); diff --git a/src/compiler/llvm_codegen_c_abi_aarch64.c b/src/compiler/llvm_codegen_c_abi_aarch64.c index 8edda5edb..1d83a7d70 100644 --- a/src/compiler/llvm_codegen_c_abi_aarch64.c +++ b/src/compiler/llvm_codegen_c_abi_aarch64.c @@ -134,7 +134,7 @@ ABIArgInfo *aarch64_classify_return_type(Type *type, bool variadic) return abi_arg_new_direct_coerce(abi_type_new_int_bits(aligned_size * 8)); } - return abi_arg_new_indirect_by_val(); + return abi_arg_new_indirect_by_val(type); } diff --git a/src/compiler/llvm_codegen_c_abi_x64.c b/src/compiler/llvm_codegen_c_abi_x64.c index c06674cf2..ec3a4061d 100644 --- a/src/compiler/llvm_codegen_c_abi_x64.c +++ b/src/compiler/llvm_codegen_c_abi_x64.c @@ -113,16 +113,16 @@ ABIArgInfo *x64_indirect_result(Type *type, unsigned free_int_regs) if (!free_int_regs) { unsigned size = type_size(type); - if (align == 8 && size <= 8) + if (align <= 8 && size <= 8) { return abi_arg_new_direct_coerce(abi_type_new_int_bits(size * 8)); } } if (align < 8) { - return abi_arg_new_indirect_realigned(8); + return abi_arg_new_indirect_realigned(8, type); } - return abi_arg_new_direct(); + return abi_arg_new_indirect_by_val(type); } @@ -794,7 +794,7 @@ static ABIArgInfo *x64_classify_argument_type(Type *type, unsigned free_int_regs { X64Class hi_class; X64Class lo_class; - x64_classify(type, 0, &lo_class, &hi_class, NAMED); + x64_classify(type, 0, &lo_class, &hi_class, is_named); // Invariants assert(hi_class != CLASS_MEMORY || lo_class == CLASS_MEMORY); diff --git a/src/compiler/llvm_codegen_c_abi_x86.c b/src/compiler/llvm_codegen_c_abi_x86.c index 2e6445ed1..24ea1b8fa 100644 --- a/src/compiler/llvm_codegen_c_abi_x86.c +++ b/src/compiler/llvm_codegen_c_abi_x86.c @@ -72,10 +72,10 @@ static ABIArgInfo *x86_create_indirect_result(Regs *regs, Type *type, ByVal by_v // Realign if alignment is greater. if (alignment > stack_alignment) { - return abi_arg_new_indirect_realigned(stack_alignment); + return abi_arg_new_indirect_realigned(stack_alignment, type); } - return abi_arg_new_indirect_by_val(); + return abi_arg_new_indirect_by_val(type); } diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index 08f638d2b..b15f50f84 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -470,7 +470,7 @@ static LLVMMetadataRef llvm_debug_typedef_type(GenContext *c, Type *type) NULL, 0, NULL, 0); } - Type *original_type = type->type_kind == TYPE_TYPEDEF ? decl->typedef_decl.type_info->type : decl->distinct_decl.base_type; + Type *original_type = type->type_kind == TYPE_TYPEDEF ? type->canonical : decl->distinct_decl.base_type; SourceLocation *location = TOKLOC(decl->span.loc); // Use forward references in case we haven't resolved the original type, since we could have this: diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 1f6d4f0ac..105893867 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -2790,7 +2790,9 @@ void llvm_emit_call_expr(GenContext *c, BEValue *be_value, Expr *expr) } } - // 10. Create the actual call + + // 10. Create the actual call (remember to emit a loc, because we might have shifted loc emitting the params) + EMIT_LOC(c, expr); LLVMValueRef call_value = LLVMBuildCall2(c->builder, func_type, func, values, vec_size(values), ""); // 11. Process the return value. diff --git a/src/compiler/llvm_codegen_function.c b/src/compiler/llvm_codegen_function.c index 6095ccb86..3da889da1 100644 --- a/src/compiler/llvm_codegen_function.c +++ b/src/compiler/llvm_codegen_function.c @@ -507,8 +507,11 @@ static void llvm_emit_param_attributes(GenContext *context, LLVMValueRef functio else { // TODO then type attributes are added to LLVM-C, use that for byval. - if (info->indirect.by_val) llvm_attribute_add(context, function, attribute_byval, index); - llvm_attribute_add(context, function, attribute_noalias, index); + if (info->indirect.by_val_type) llvm_attribute_add(context, function, attribute_byval, index); + if (!info->indirect.realignment) + { + llvm_attribute_add_int(context, function, attribute_align, type_abi_alignment(info->indirect.by_val_type), index); + } } break; diff --git a/src/compiler/llvm_codegen_internal.h b/src/compiler/llvm_codegen_internal.h index aef5754ea..7e141608b 100644 --- a/src/compiler/llvm_codegen_internal.h +++ b/src/compiler/llvm_codegen_internal.h @@ -21,6 +21,8 @@ #include #include "dwarf.h" + + typedef enum { BE_VALUE, @@ -45,11 +47,6 @@ typedef struct LLVMBasicBlockRef next_block; } BreakContinue; - - - - - typedef struct { unsigned runtime_version : 8; diff --git a/src/compiler/llvm_codegen_module.c b/src/compiler/llvm_codegen_module.c index 15984d306..c82dc4b0a 100644 --- a/src/compiler/llvm_codegen_module.c +++ b/src/compiler/llvm_codegen_module.c @@ -65,9 +65,10 @@ void gencontext_begin_module(GenContext *c) c->block_global_unique_count = 0; c->ast_alloca_addr_space = target_alloca_addr_space(); - VECEACH(compiler.type, i) + VECEACH(global_context.type, i) { - compiler.type[i]->backend_type = NULL; + global_context.type[i]->backend_type = NULL; + global_context.type[i]->backend_debug_type = NULL; } } diff --git a/src/compiler/llvm_codegen_type.c b/src/compiler/llvm_codegen_type.c index 486913a61..dce37427a 100644 --- a/src/compiler/llvm_codegen_type.c +++ b/src/compiler/llvm_codegen_type.c @@ -323,11 +323,11 @@ LLVMTypeRef llvm_get_pointee_type(GenContext *c, Type *any_type) LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type) { - if (any_type->backend_type && LLVMGetTypeContext(any_type->backend_type) == c->context) + if (any_type->backend_type) { + assert(LLVMGetTypeContext(any_type->backend_type) == c->context && "Should have been purged"); return any_type->backend_type; } - DEBUG_LOG("Generating type %s", any_type->name); switch (any_type->type_kind) { case TYPE_POISONED: diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 3e53ce36c..10f6c5942 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -420,15 +420,16 @@ static inline Type *sema_analyse_function_signature(Context *context, FunctionSi if (!all_ok) return NULL; TokenType type = TOKEN_INVALID_TOKEN; - signature->mangled_signature = symtab_add(buffer, buffer_write_offset, fnv1a(buffer, buffer_write_offset), &type); - Type *func_type = stable_get(&context->local_symbols, signature->mangled_signature); + const char *mangled_signature = symtab_add(buffer, buffer_write_offset, fnv1a(buffer, buffer_write_offset), &type); + Type *func_type = stable_get(&context->local_symbols, mangled_signature); c_abi_func_create(signature); if (!func_type) { - func_type = type_new(TYPE_FUNC, signature->mangled_signature); + func_type = type_new(TYPE_FUNC, mangled_signature); func_type->canonical = func_type; func_type->func.signature = signature; - stable_set(&context->local_symbols, signature->mangled_signature, func_type); + func_type->func.mangled_function_signature = mangled_signature; + stable_set(&context->local_symbols, mangled_signature, func_type); } return func_type; diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index 74828b545..ac8a1ee22 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -25,7 +25,7 @@ void sema_analysis_pass_process_imports(Context *context) Decl *import = context->imports[i]; import->resolve_status = RESOLVE_RUNNING; Path *path = import->import.path; - Module *module = stable_get(&compiler.modules, path->module); + Module *module = stable_get(&global_context.modules, path->module); DEBUG_LOG("- Import of %s.", path->module); if (!module) { diff --git a/src/compiler/types.c b/src/compiler/types.c index a7e3393d3..e36fc99b4 100644 --- a/src/compiler/types.c +++ b/src/compiler/types.c @@ -122,17 +122,7 @@ const char *type_to_error_string(Type *type) case TYPE_VIRTUAL: return type->name; case TYPE_FUNC: - { - asprintf(&buffer, type->func.signature->failable ? "func %s!(" : "func %s(", - type_to_error_string(type->func.signature->rtype->type)); - VECEACH(type->func.signature->params, i) - { - if (i != 0) buffer = strcat_arena(buffer, ", "); - strcat_arena(buffer, type_to_error_string(type->func.signature->params[i]->type)); - } - - return strcat_arena(buffer, ")"); - } + return strcat_arena("func ", type->func.mangled_function_signature); case TYPE_COMPLEX: switch (type->complex->type_kind) { @@ -1037,6 +1027,7 @@ static void type_create(const char *name, Type *location, TypeKind kind, unsigne }; location->name = name; location->canonical = location; + global_context_add_type(location); } static void type_create_alias(const char *name, Type *location, Type *canonical) @@ -1046,6 +1037,7 @@ static void type_create_alias(const char *name, Type *location, Type *canonical) .name = name, .canonical = canonical }; + global_context_add_type(location); } diff --git a/test/test_suite/expressions/casts/cast_func_to_various.c3 b/test/test_suite/expressions/casts/cast_func_to_various.c3 index 23a3d3093..3fbdbbca6 100644 --- a/test/test_suite/expressions/casts/cast_func_to_various.c3 +++ b/test/test_suite/expressions/casts/cast_func_to_various.c3 @@ -23,17 +23,17 @@ func void test1(Func arg) func void test2(Func arg) { - ichar b = cast(arg as ichar); // #error: Cannot cast 'Func' (func void()) to 'ichar'. + ichar b = cast(arg as ichar); // #error: Cannot cast 'Func' (func void(int)) to 'ichar'. } func void test3(Func arg) { - uint c = cast(arg as uint); // #error: Cannot cast 'Func' (func void()) to 'uint'. + uint c = cast(arg as uint); // #error: Cannot cast 'Func' (func void(int)) to 'uint'. } func void test4(Func arg) { - float d = cast(arg as float); // #error: Cannot cast 'Func' (func void()) to 'float'. + float d = cast(arg as float); // #error: Cannot cast 'Func' (func void(int)) to 'float'. } func void test7(Func arg) @@ -41,7 +41,7 @@ func void test7(Func arg) usize g = cast(arg as usize); FuncOther k = cast(arg as FuncOther); FuncSame l = cast(arg as FuncSame); - FuncOther ke = arg; // #error: Cannot implicitly cast 'Func' (func void()) to 'FuncOther' (func bool()) + FuncOther ke = arg; // #error: Cannot implicitly cast 'Func' (func void(int)) to 'FuncOther' (func bool(char*)) FuncSame fe = arg; - Enum j = cast(arg as Enum); // #error: Cannot cast 'Func' (func void()) to 'Enum'. + Enum j = cast(arg as Enum); // #error: Cannot cast 'Func' (func void(int)) to 'Enum'. }