Fix some coerced store/loads
Some checks failed
CI / release (ubuntu-latest) (push) Has been cancelled
CI / ci (Release-assertions, ubuntu-latest) (push) Has been cancelled
CI / ci (Release, ubuntu-latest) (push) Has been cancelled
CI / ci (Debug, ubuntu-latest) (push) Has been cancelled
CI / ci (Release, ubuntu-latest) (pull_request) Successful in 6m8s
CI / ci (Release-assertions, ubuntu-latest) (pull_request) Successful in 6m43s
Some checks failed
CI / release (ubuntu-latest) (push) Has been cancelled
CI / ci (Release-assertions, ubuntu-latest) (push) Has been cancelled
CI / ci (Release, ubuntu-latest) (push) Has been cancelled
CI / ci (Debug, ubuntu-latest) (push) Has been cancelled
CI / ci (Release, ubuntu-latest) (pull_request) Successful in 6m8s
CI / ci (Release-assertions, ubuntu-latest) (pull_request) Successful in 6m43s
This commit is contained in:
parent
a0b2218cc3
commit
e2765e7b39
112
src/compiler.bbb
Normal file → Executable file
112
src/compiler.bbb
Normal file → Executable file
@ -3735,7 +3735,7 @@ parse_name = fn (module: &Module) []u8
|
|||||||
result = parse_identifier(module);
|
result = parse_identifier(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return arena_duplicate_string(module.arena, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_value = fn (module: &Module) &Value
|
new_value = fn (module: &Module) &Value
|
||||||
@ -5488,7 +5488,7 @@ parse_aggregate_initialization = fn (module: &Module, scope: &Scope, builder: Va
|
|||||||
|
|
||||||
if (consume_character_if_match(module, '.'))
|
if (consume_character_if_match(module, '.'))
|
||||||
{
|
{
|
||||||
>name = parse_identifier(module);
|
>name = arena_duplicate_string(module.arena, parse_identifier(module));
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
expect_character(module, '=');
|
expect_character(module, '=');
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
@ -6499,7 +6499,7 @@ parse_right = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
|
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
|
|
||||||
>identifier = parse_identifier(module);
|
>identifier = arena_duplicate_string(module.arena, parse_identifier(module));
|
||||||
result = new_value(module);
|
result = new_value(module);
|
||||||
|
|
||||||
result.& = {
|
result.& = {
|
||||||
@ -7370,7 +7370,7 @@ parse = fn (module: &Module) void
|
|||||||
}
|
}
|
||||||
|
|
||||||
>field_line = get_line(module);
|
>field_line = get_line(module);
|
||||||
>field_name = parse_identifier(module);
|
>field_name = arena_duplicate_string(module.arena, parse_identifier(module));
|
||||||
|
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
expect_character(module, ':');
|
expect_character(module, ':');
|
||||||
@ -7865,7 +7865,7 @@ parse = fn (module: &Module) void
|
|||||||
|
|
||||||
>field_index = field_count;
|
>field_index = field_count;
|
||||||
>field_line = get_line(module);
|
>field_line = get_line(module);
|
||||||
>field_name = parse_identifier(module);
|
>field_name = arena_duplicate_string(module.arena, parse_identifier(module));
|
||||||
|
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
expect_character(module, ':');
|
expect_character(module, ':');
|
||||||
@ -7990,7 +7990,7 @@ parse = fn (module: &Module) void
|
|||||||
field_count += 1;
|
field_count += 1;
|
||||||
|
|
||||||
>field_line = get_line(module);
|
>field_line = get_line(module);
|
||||||
>field_name = parse_identifier(module);
|
>field_name = arena_duplicate_string(module.arena, parse_identifier(module));
|
||||||
|
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
expect_character(module, ':');
|
expect_character(module, ':');
|
||||||
@ -9646,11 +9646,33 @@ get_current_function = fn (module: &Module) &Global
|
|||||||
return current_function;
|
return current_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeKind = enum
|
||||||
|
{
|
||||||
|
abi,
|
||||||
|
memory,
|
||||||
|
}
|
||||||
|
|
||||||
|
get_llvm_type = fn (type: &Type, kind: TypeKind) &LLVMType
|
||||||
|
{
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
.abi =>
|
||||||
|
{
|
||||||
|
return type.llvm.abi;
|
||||||
|
},
|
||||||
|
.memory =>
|
||||||
|
{
|
||||||
|
return type.llvm.memory;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AllocaOptions = struct
|
AllocaOptions = struct
|
||||||
{
|
{
|
||||||
type: &Type,
|
type: &Type,
|
||||||
name: []u8,
|
name: []u8,
|
||||||
alignment: u32,
|
alignment: u32,
|
||||||
|
use_abi: u1,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_alloca = fn (module: &Module, options: AllocaOptions) &LLVMValue
|
create_alloca = fn (module: &Module, options: AllocaOptions) &LLVMValue
|
||||||
@ -9671,7 +9693,7 @@ create_alloca = fn (module: &Module, options: AllocaOptions) &LLVMValue
|
|||||||
LLVMPositionBuilderBefore(module.llvm.builder, alloca_insertion_point);
|
LLVMPositionBuilderBefore(module.llvm.builder, alloca_insertion_point);
|
||||||
LLVMSetCurrentDebugLocation2(module.llvm.builder, zero);
|
LLVMSetCurrentDebugLocation2(module.llvm.builder, zero);
|
||||||
|
|
||||||
>alloca = llvm_create_alloca(module.llvm.builder, abi_type.llvm.memory, alignment, options.name);
|
>alloca = llvm_create_alloca(module.llvm.builder, get_llvm_type(abi_type, @select(options.use_abi, .abi, .memory)), alignment, options.name);
|
||||||
LLVMPositionBuilderAtEnd(module.llvm.builder, original_block);
|
LLVMPositionBuilderAtEnd(module.llvm.builder, original_block);
|
||||||
LLVMSetCurrentDebugLocation2(module.llvm.builder, debug_location);
|
LLVMSetCurrentDebugLocation2(module.llvm.builder, debug_location);
|
||||||
|
|
||||||
@ -9713,12 +9735,6 @@ create_store = fn (module: &Module, options: StoreOptions) void
|
|||||||
LLVMSetAlignment(store, alignment);
|
LLVMSetAlignment(store, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeKind = enum
|
|
||||||
{
|
|
||||||
abi,
|
|
||||||
memory,
|
|
||||||
}
|
|
||||||
|
|
||||||
memory_to_abi = fn (module: &Module, value: &LLVMValue, type: &Type) &LLVMValue
|
memory_to_abi = fn (module: &Module, value: &LLVMValue, type: &Type) &LLVMValue
|
||||||
{
|
{
|
||||||
>result = value;
|
>result = value;
|
||||||
@ -9735,6 +9751,7 @@ LoadOptions = struct
|
|||||||
pointer: &LLVMValue,
|
pointer: &LLVMValue,
|
||||||
alignment: u32,
|
alignment: u32,
|
||||||
kind: TypeKind,
|
kind: TypeKind,
|
||||||
|
use_abi: u1,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_load = fn (module: &Module, options: LoadOptions) &LLVMValue
|
create_load = fn (module: &Module, options: LoadOptions) &LLVMValue
|
||||||
@ -9746,9 +9763,11 @@ create_load = fn (module: &Module, options: LoadOptions) &LLVMValue
|
|||||||
alignment = get_byte_alignment(options.type);
|
alignment = get_byte_alignment(options.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
>result = LLVMBuildLoad2(module.llvm.builder, options.type.llvm.memory, options.pointer, "");
|
>result = LLVMBuildLoad2(module.llvm.builder, get_llvm_type(options.type, @select(options.use_abi, .abi, .memory)), options.pointer, "");
|
||||||
LLVMSetAlignment(result, alignment);
|
LLVMSetAlignment(result, alignment);
|
||||||
|
|
||||||
|
if (!options.use_abi)
|
||||||
|
{
|
||||||
switch (options.kind)
|
switch (options.kind)
|
||||||
{
|
{
|
||||||
.abi =>
|
.abi =>
|
||||||
@ -9757,6 +9776,7 @@ create_load = fn (module: &Module, options: LoadOptions) &LLVMValue
|
|||||||
},
|
},
|
||||||
.memory => {},
|
.memory => {},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -12008,7 +12028,7 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
zero,
|
zero,
|
||||||
});
|
});
|
||||||
|
|
||||||
>element_length_pointer = LLVMBuildStructGEP2(module.llvm.builder, slice_struct_type.llvm.abi, array_element_pointer, 1, "");
|
>element_length_pointer = LLVMBuildStructGEP2(module.llvm.builder, slice_struct_type.llvm.abi, array_element_pointer, 1, "length");
|
||||||
>element_length = create_load(module, {
|
>element_length = create_load(module, {
|
||||||
.type = u64_type,
|
.type = u64_type,
|
||||||
.pointer = element_length_pointer,
|
.pointer = element_length_pointer,
|
||||||
@ -12061,7 +12081,7 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
zero,
|
zero,
|
||||||
});
|
});
|
||||||
|
|
||||||
>element_pointer_pointer = LLVMBuildStructGEP2(module.llvm.builder, slice_struct_type.llvm.abi, length_array_element_pointer, 0, "");
|
>element_pointer_pointer = LLVMBuildStructGEP2(module.llvm.builder, slice_struct_type.llvm.abi, length_array_element_pointer, 0, "pointer");
|
||||||
>element_pointer = create_load(module, {
|
>element_pointer = create_load(module, {
|
||||||
.type = get_pointer_type(module, u8_type),
|
.type = get_pointer_type(module, u8_type),
|
||||||
.pointer = element_pointer_pointer,
|
.pointer = element_pointer_pointer,
|
||||||
@ -12456,21 +12476,6 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
value.type = value_type;
|
value.type = value_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_llvm_type = fn (type: &Type, kind: TypeKind) &LLVMType
|
|
||||||
{
|
|
||||||
switch (kind)
|
|
||||||
{
|
|
||||||
.abi =>
|
|
||||||
{
|
|
||||||
return type.llvm.abi;
|
|
||||||
},
|
|
||||||
.memory =>
|
|
||||||
{
|
|
||||||
return type.llvm.memory;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit_intrinsic_call = fn (module: &Module, index: LLVMIntrinsicIndex, argument_types: []&LLVMType, argument_values: []&LLVMValue) &LLVMValue
|
emit_intrinsic_call = fn (module: &Module, index: LLVMIntrinsicIndex, argument_types: []&LLVMType, argument_values: []&LLVMValue) &LLVMValue
|
||||||
{
|
{
|
||||||
>intrinsic_id = module.llvm.intrinsic_table[index];
|
>intrinsic_id = module.llvm.intrinsic_table[index];
|
||||||
@ -12741,7 +12746,9 @@ coerce_integer_or_pointer_to_integer_or_pointer = fn (module: &Module, source: &
|
|||||||
|
|
||||||
create_coerced_store = fn (module: &Module, source_value: &LLVMValue, source_type: &Type, destination_value: &LLVMValue, destination_type: &Type, destination_size: u64, destination_volatile: u1) void
|
create_coerced_store = fn (module: &Module, source_value: &LLVMValue, source_type: &Type, destination_value: &LLVMValue, destination_type: &Type, destination_size: u64, destination_volatile: u1) void
|
||||||
{
|
{
|
||||||
>source_size = get_byte_size(source_type);
|
>source_size = get_bit_size(source_type);
|
||||||
|
assert(source_size % 8 == 0);
|
||||||
|
source_size = source_size / 8;
|
||||||
|
|
||||||
// TODO: this smells badly
|
// TODO: this smells badly
|
||||||
// destination_type != uint1(module)
|
// destination_type != uint1(module)
|
||||||
@ -12770,7 +12777,7 @@ create_coerced_store = fn (module: &Module, source_value: &LLVMValue, source_typ
|
|||||||
{
|
{
|
||||||
>field = &fields[i];
|
>field = &fields[i];
|
||||||
|
|
||||||
>gep = LLVMBuildStructGEP2(module.llvm.builder, source_type.llvm.abi, destination_value, @truncate(i), "");
|
>gep = LLVMBuildStructGEP2(module.llvm.builder, source_type.llvm.abi, destination_value, @truncate(i), field.name.pointer);
|
||||||
>field_value = LLVMBuildExtractValue(module.llvm.builder, source_value, @truncate(i), "");
|
>field_value = LLVMBuildExtractValue(module.llvm.builder, source_value, @truncate(i), "");
|
||||||
|
|
||||||
create_store(module, {
|
create_store(module, {
|
||||||
@ -12810,8 +12817,9 @@ create_coerced_store = fn (module: &Module, source_value: &LLVMValue, source_typ
|
|||||||
>source_alloca_alignment = @max(original_destination_alignment, get_byte_alignment(source_type));
|
>source_alloca_alignment = @max(original_destination_alignment, get_byte_alignment(source_type));
|
||||||
>source_alloca = create_alloca(module, {
|
>source_alloca = create_alloca(module, {
|
||||||
.type = source_type,
|
.type = source_type,
|
||||||
.name = "coerce",
|
.name = "coerce.store.alloca",
|
||||||
.alignment = source_alloca_alignment,
|
.alignment = source_alloca_alignment,
|
||||||
|
zero,
|
||||||
});
|
});
|
||||||
|
|
||||||
create_store(module, {
|
create_store(module, {
|
||||||
@ -12887,8 +12895,9 @@ create_coerced_load = fn (module: &Module, source: &LLVMValue, source_type: &Typ
|
|||||||
>destination_alignment = @max(original_destination_alignment, source_alignment);
|
>destination_alignment = @max(original_destination_alignment, source_alignment);
|
||||||
>destination_alloca = create_alloca(module, {
|
>destination_alloca = create_alloca(module, {
|
||||||
.type = destination_type,
|
.type = destination_type,
|
||||||
.name = "coerce",
|
.name = "coerce.load.alloca",
|
||||||
.alignment = destination_alignment,
|
.alignment = destination_alignment,
|
||||||
|
.use_abi = 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
>u64_type = uint64(module);
|
>u64_type = uint64(module);
|
||||||
@ -12900,6 +12909,7 @@ create_coerced_load = fn (module: &Module, source: &LLVMValue, source_type: &Typ
|
|||||||
.type = destination_type,
|
.type = destination_type,
|
||||||
.pointer = destination_alloca,
|
.pointer = destination_alloca,
|
||||||
.alignment = destination_alignment,
|
.alignment = destination_alignment,
|
||||||
|
.use_abi = 1,
|
||||||
zero,
|
zero,
|
||||||
});
|
});
|
||||||
result = load;
|
result = load;
|
||||||
@ -13186,8 +13196,9 @@ emit_call = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_type
|
|||||||
{
|
{
|
||||||
>alloca = create_alloca(module, {
|
>alloca = create_alloca(module, {
|
||||||
.type = argument_abi.semantic_type,
|
.type = argument_abi.semantic_type,
|
||||||
.name = "coerce",
|
.name = "struct.coerce.alloca",
|
||||||
.alignment = alignment,
|
.alignment = alignment,
|
||||||
|
zero,
|
||||||
});
|
});
|
||||||
>u64_type = uint64(module);
|
>u64_type = uint64(module);
|
||||||
resolve_type_in_place(module, u64_type);
|
resolve_type_in_place(module, u64_type);
|
||||||
@ -13208,7 +13219,7 @@ emit_call = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_type
|
|||||||
for (i: 0..coerce_fields.length)
|
for (i: 0..coerce_fields.length)
|
||||||
{
|
{
|
||||||
>field = &coerce_fields[i];
|
>field = &coerce_fields[i];
|
||||||
>gep = LLVMBuildStructGEP2(module.llvm.builder, coerce_to_type.llvm.memory, source, @truncate(i), "");
|
>gep = LLVMBuildStructGEP2(module.llvm.builder, coerce_to_type.llvm.memory, source, @truncate(i), field.name.pointer);
|
||||||
>maybe_undef: u1 = 0;
|
>maybe_undef: u1 = 0;
|
||||||
if (maybe_undef)
|
if (maybe_undef)
|
||||||
{
|
{
|
||||||
@ -13256,8 +13267,8 @@ emit_call = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_type
|
|||||||
|
|
||||||
for (i: 0..coerce_fields.length)
|
for (i: 0..coerce_fields.length)
|
||||||
{
|
{
|
||||||
>gep = LLVMBuildStructGEP2(module.llvm.builder, coerce_to_type.llvm.abi, global, @truncate(i), "");
|
|
||||||
>field = &coerce_fields[i];
|
>field = &coerce_fields[i];
|
||||||
|
>gep = LLVMBuildStructGEP2(module.llvm.builder, coerce_to_type.llvm.abi, global, @truncate(i), field.name.pointer);
|
||||||
|
|
||||||
>maybe_undef: u1 = 0;
|
>maybe_undef: u1 = 0;
|
||||||
if (maybe_undef)
|
if (maybe_undef)
|
||||||
@ -13557,7 +13568,7 @@ emit_call = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_type
|
|||||||
{
|
{
|
||||||
coerce_alloca = create_alloca(module, {
|
coerce_alloca = create_alloca(module, {
|
||||||
.type = return_abi.semantic_type,
|
.type = return_abi.semantic_type,
|
||||||
.name = "coerce",
|
.name = "call.return.coerce",
|
||||||
zero,
|
zero,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -13724,6 +13735,7 @@ emit_field_access = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, l
|
|||||||
|
|
||||||
assert(result_field != zero);
|
assert(result_field != zero);
|
||||||
>field_index: u32 = @truncate(result_field - fields.pointer);
|
>field_index: u32 = @truncate(result_field - fields.pointer);
|
||||||
|
>field = &fields[field_index];
|
||||||
|
|
||||||
field_access = {
|
field_access = {
|
||||||
.type = resolved_aggregate_type.content.struct.fields[field_index].type,
|
.type = resolved_aggregate_type.content.struct.fields[field_index].type,
|
||||||
@ -13760,7 +13772,7 @@ emit_field_access = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, l
|
|||||||
else => { unreachable; },
|
else => { unreachable; },
|
||||||
}
|
}
|
||||||
|
|
||||||
>gep = LLVMBuildStructGEP2(module.llvm.builder, field_access.struct_type, v, field_access.field_index, "");
|
>gep = LLVMBuildStructGEP2(module.llvm.builder, field_access.struct_type, v, field_access.field_index, field_name.pointer);
|
||||||
|
|
||||||
if (left_llvm)
|
if (left_llvm)
|
||||||
{
|
{
|
||||||
@ -14023,7 +14035,7 @@ emit_va_arg_from_memory = fn (module: &Module, va_list_pointer: &LLVMValue, va_l
|
|||||||
{
|
{
|
||||||
assert(va_list_struct.id == .struct);
|
assert(va_list_struct.id == .struct);
|
||||||
|
|
||||||
>overflow_arg_area_pointer = LLVMBuildStructGEP2(module.llvm.builder, va_list_struct.llvm.abi, va_list_pointer, 2, "");
|
>overflow_arg_area_pointer = LLVMBuildStructGEP2(module.llvm.builder, va_list_struct.llvm.abi, va_list_pointer, 2, "overflow_arg_area");
|
||||||
>overflow_arg_area_type = va_list_struct.content.struct.fields[2].type;
|
>overflow_arg_area_type = va_list_struct.content.struct.fields[2].type;
|
||||||
>overflow_arg_area = create_load(module, {
|
>overflow_arg_area = create_load(module, {
|
||||||
.type = overflow_arg_area_type,
|
.type = overflow_arg_area_type,
|
||||||
@ -14116,7 +14128,7 @@ emit_va_arg = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_ty
|
|||||||
|
|
||||||
if (needed_registers.gpr != 0)
|
if (needed_registers.gpr != 0)
|
||||||
{
|
{
|
||||||
gpr_offset_pointer = LLVMBuildStructGEP2(module.llvm.builder, va_list_struct_llvm, va_list_value_llvm, 0, "");
|
gpr_offset_pointer = LLVMBuildStructGEP2(module.llvm.builder, va_list_struct_llvm, va_list_value_llvm, 0, "gpr_offset");
|
||||||
gpr_offset = create_load(module, {
|
gpr_offset = create_load(module, {
|
||||||
.type = va_list_struct.content.struct.fields[0].type,
|
.type = va_list_struct.content.struct.fields[0].type,
|
||||||
.pointer = gpr_offset_pointer,
|
.pointer = gpr_offset_pointer,
|
||||||
@ -14190,7 +14202,7 @@ emit_va_arg = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_ty
|
|||||||
>reg_save_area_type = va_list_struct.content.struct.fields[3].type;
|
>reg_save_area_type = va_list_struct.content.struct.fields[3].type;
|
||||||
>reg_save_area = create_load(module, {
|
>reg_save_area = create_load(module, {
|
||||||
.type = reg_save_area_type,
|
.type = reg_save_area_type,
|
||||||
.pointer = LLVMBuildStructGEP2(module.llvm.builder, va_list_struct_llvm, va_list_value_llvm, 3, ""),
|
.pointer = LLVMBuildStructGEP2(module.llvm.builder, va_list_struct_llvm, va_list_value_llvm, 3, "reg_save_area"),
|
||||||
.alignment = 16,
|
.alignment = 16,
|
||||||
zero,
|
zero,
|
||||||
});
|
});
|
||||||
@ -15731,11 +15743,12 @@ emit_assignment = fn (module: &Module, left_llvm: &LLVMValue, left_type: &Type,
|
|||||||
{
|
{
|
||||||
>string_literal = emit_string_literal(module, right);
|
>string_literal = emit_string_literal(module, right);
|
||||||
>slice_type = get_slice_type(module, uint8(module));
|
>slice_type = get_slice_type(module, uint8(module));
|
||||||
|
>slice_fields = slice_type.content.struct.fields;
|
||||||
for (i: 0..string_literal.length)
|
for (i: 0..string_literal.length)
|
||||||
{
|
{
|
||||||
>member_pointer = LLVMBuildStructGEP2(module.llvm.builder, slice_type.llvm.abi, left_llvm, @truncate(i), "");
|
>slice_field = &slice_fields[i];
|
||||||
>slice_member_type = slice_type.content.struct.fields[i].type;
|
>member_pointer = LLVMBuildStructGEP2(module.llvm.builder, slice_type.llvm.abi, left_llvm, @truncate(i), slice_field.name.pointer);
|
||||||
|
>slice_member_type = slice_field.type;
|
||||||
create_store(module, {
|
create_store(module, {
|
||||||
.source = string_literal[i],
|
.source = string_literal[i],
|
||||||
.destination = member_pointer,
|
.destination = member_pointer,
|
||||||
@ -15834,7 +15847,7 @@ emit_assignment = fn (module: &Module, left_llvm: &LLVMValue, left_type: &Type,
|
|||||||
|
|
||||||
>field = &fields[declaration_index];
|
>field = &fields[declaration_index];
|
||||||
|
|
||||||
>destination_pointer = LLVMBuildStructGEP2(module.llvm.builder, resolved_value_type.llvm.memory, left_llvm, @truncate(declaration_index), "");
|
>destination_pointer = LLVMBuildStructGEP2(module.llvm.builder, resolved_value_type.llvm.memory, left_llvm, @truncate(declaration_index), field.name.pointer);
|
||||||
|
|
||||||
emit_assignment(module, destination_pointer, get_pointer_type(module, field.type), value);
|
emit_assignment(module, destination_pointer, get_pointer_type(module, field.type), value);
|
||||||
}
|
}
|
||||||
@ -15906,7 +15919,7 @@ emit_assignment = fn (module: &Module, left_llvm: &LLVMValue, left_type: &Type,
|
|||||||
zero,
|
zero,
|
||||||
});
|
});
|
||||||
|
|
||||||
>slice_length_destination = LLVMBuildStructGEP2(module.llvm.builder, resolved_value_type.llvm.abi, left_llvm, 1, "");
|
>slice_length_destination = LLVMBuildStructGEP2(module.llvm.builder, resolved_value_type.llvm.abi, left_llvm, 1, "length");
|
||||||
create_store(module, {
|
create_store(module, {
|
||||||
.source = slice_values[1],
|
.source = slice_values[1],
|
||||||
.destination = slice_length_destination,
|
.destination = slice_length_destination,
|
||||||
@ -17848,6 +17861,7 @@ emit = fn (module: &Module) void
|
|||||||
.type = coerce_to_type,
|
.type = coerce_to_type,
|
||||||
.name = "coerce",
|
.name = "coerce",
|
||||||
.alignment = address_alignment,
|
.alignment = address_alignment,
|
||||||
|
zero,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17859,7 +17873,7 @@ emit = fn (module: &Module) void
|
|||||||
for (i: 0..fields.length)
|
for (i: 0..fields.length)
|
||||||
{
|
{
|
||||||
>field = &fields[i];
|
>field = &fields[i];
|
||||||
>gep = LLVMBuildStructGEP2(module.llvm.builder, coerce_to_type.llvm.abi, address, @truncate(i), "");
|
>gep = LLVMBuildStructGEP2(module.llvm.builder, coerce_to_type.llvm.abi, address, @truncate(i), field.name.pointer);
|
||||||
create_store(module, {
|
create_store(module, {
|
||||||
.source = argument_abi_arguments[i],
|
.source = argument_abi_arguments[i],
|
||||||
.destination = gep,
|
.destination = gep,
|
||||||
|
@ -2070,6 +2070,66 @@ breakpoint = fn () void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPUArchitecture = enum
|
||||||
|
{
|
||||||
|
x86_64,
|
||||||
|
}
|
||||||
|
|
||||||
|
OperatingSystem = enum
|
||||||
|
{
|
||||||
|
linux,
|
||||||
|
}
|
||||||
|
|
||||||
|
Target = struct
|
||||||
|
{
|
||||||
|
cpu: CPUArchitecture,
|
||||||
|
os: OperatingSystem,
|
||||||
|
host_cpu_model: u1,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_arbitrary_int_abi_function = fn [cc(c)] (host_cpu_model: u1) Target
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
.cpu = .x86_64,
|
||||||
|
.os = .linux,
|
||||||
|
.host_cpu_model = host_cpu_model,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
StructArbitraryIntAbiContainer = struct
|
||||||
|
{
|
||||||
|
a: u8,
|
||||||
|
b: u8,
|
||||||
|
c: Target,
|
||||||
|
d: u8,
|
||||||
|
e: u8
|
||||||
|
f: u8,
|
||||||
|
g: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_arbitrary_int_abi = fn () void
|
||||||
|
{
|
||||||
|
>some_struct: StructArbitraryIntAbiContainer = {
|
||||||
|
.f = 45,
|
||||||
|
.g = 46,
|
||||||
|
.e = 123,
|
||||||
|
.d = 231,
|
||||||
|
.c = struct_arbitrary_int_abi_function(0),
|
||||||
|
.a = 123,
|
||||||
|
.b = 231,
|
||||||
|
};
|
||||||
|
|
||||||
|
require(some_struct.a == 123);
|
||||||
|
require(some_struct.b == 231);
|
||||||
|
require(some_struct.c.cpu == .x86_64);
|
||||||
|
require(some_struct.c.os == .linux);
|
||||||
|
require(!some_struct.c.host_cpu_model);
|
||||||
|
require(some_struct.d == 231);
|
||||||
|
require(some_struct.e == 123);
|
||||||
|
require(some_struct.f == 45);
|
||||||
|
require(some_struct.g == 46);
|
||||||
|
}
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argc: s32, argv: &&u8, envp: &&u8) s32
|
[export] main = fn [cc(c)] (argc: s32, argv: &&u8, envp: &&u8) s32
|
||||||
{
|
{
|
||||||
>rc = return_constant();
|
>rc = return_constant();
|
||||||
@ -2335,5 +2395,7 @@ breakpoint = fn () void
|
|||||||
|
|
||||||
breakpoint();
|
breakpoint();
|
||||||
|
|
||||||
|
struct_arbitrary_int_abi();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user