diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-04-16 10:38:42 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-04-16 10:38:42 +0100 |
| commit | abb9930725c10d8bf8cb5560bca9afe6aad204e1 (patch) | |
| tree | 812ffced8e15d7e6615d4425b9670d6d4a3ece0c /src/check_expr.c | |
| parent | 169310a9f61f3d9a9d420fd3a73fe3115d995595 (diff) | |
IR emit C ABI compatible types for calling conventions (Only for x86/amd64 like processors at the moment)
Diffstat (limited to 'src/check_expr.c')
| -rw-r--r-- | src/check_expr.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/check_expr.c b/src/check_expr.c index 1dba6dbbd..9d4eb0905 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -1014,6 +1014,50 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) { return tuple; } +Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { + Type *new_type = original_type; + // NOTE(bill): Changing the passing parameter value type is to match C's ABI + // IMPORTANT TODO(bill): This only matches the ABI on MSVC at the moment + Type *bt = core_type(original_type); + switch (bt->kind) { + // Okay to pass by value + // Especially the only Odin types + case Type_Basic: break; + case Type_Pointer: break; + case Type_Proc: break; // NOTE(bill): Just a pointer + + // Odin only types + case Type_Slice: + case Type_DynamicArray: + case Type_Map: + break; + + // Odin specific + case Type_Array: + case Type_Vector: + // Could be in C too + case Type_Record: { + i64 size = type_size_of(a, original_type); + switch (8*size) { + case 8: new_type = t_u8; break; + case 16: new_type = t_u16; break; + case 32: new_type = t_u32; break; + case 64: new_type = t_u64; break; + default: + // NOTE(bill): It could be an empty struct that is passed + // and if that is the case, no need to pass by pointer + // (I think..) + if (size > 0) { + new_type = make_type_pointer(a, original_type); + } + break; + } + } break; + } + + return new_type; +} + void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) { ast_node(pt, ProcType, proc_type_node); @@ -1034,6 +1078,20 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) { type->Proc.result_count = result_count; type->Proc.variadic = variadic; type->Proc.calling_convention = pt->calling_convention; + + + type->Proc.abi_compat_params = gb_alloc_array(c->allocator, Type *, param_count); + for (isize i = 0; i < param_count; i++) { + Type *original_type = type->Proc.params->Tuple.variables[i]->type; + Type *new_type = type_to_abi_compat_param_type(c->allocator, original_type); + type->Proc.abi_compat_params[i] = new_type; + } + + // NOTE(bill): The types are the same + type->Proc.abi_compat_results = gb_alloc_array(c->allocator, Type *, result_count); + for (isize i = 0; i < result_count; i++) { + type->Proc.abi_compat_results[i] = type->Proc.results->Tuple.variables[i]->type; + } } |