mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-26 15:34:59 -07:00
IR emit C ABI compatible types for calling conventions (Only for x86/amd64 like processors at the moment)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user