wip
This commit is contained in:
parent
14f856b550
commit
3ec28ee8ab
349
src/compiler.bbb
349
src/compiler.bbb
@ -101,6 +101,29 @@ assert = macro (ok: u1) void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArgumentBuilder = struct
|
||||||
|
{
|
||||||
|
buffer: [128]&u8,
|
||||||
|
count: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
add_argument = fn (builder: &ArgumentBuilder, argument: []u8) void
|
||||||
|
{
|
||||||
|
assert(argument.pointer[argument.length] == 0);
|
||||||
|
>index = builder.count;
|
||||||
|
assert(index < builder.buffer.length);
|
||||||
|
builder.buffer[index] = argument.pointer;
|
||||||
|
builder.count = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_arguments = fn (builder: &ArgumentBuilder) []&u8
|
||||||
|
{
|
||||||
|
>argument_count = builder.count;
|
||||||
|
assert(argument_count < builder.buffer.length);
|
||||||
|
builder.buffer[argument_count] = zero;
|
||||||
|
return builder.buffer[..argument_count];
|
||||||
|
}
|
||||||
|
|
||||||
align_forward = fn (value: u64, alignment: u64) u64
|
align_forward = fn (value: u64, alignment: u64) u64
|
||||||
{
|
{
|
||||||
assert(alignment != 0);
|
assert(alignment != 0);
|
||||||
@ -154,6 +177,22 @@ string_equal = fn(a: []u8, b: []u8) u1
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string_first_character = fn (string: []u8, character: u8) u64
|
||||||
|
{
|
||||||
|
>result = string_no_match;
|
||||||
|
|
||||||
|
for (i: 0..string.length)
|
||||||
|
{
|
||||||
|
if (character == string[i])
|
||||||
|
{
|
||||||
|
result = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
string_last_character = fn(string: []u8, character: u8) u64
|
string_last_character = fn(string: []u8, character: u8) u64
|
||||||
{
|
{
|
||||||
>i = string.length;
|
>i = string.length;
|
||||||
@ -1533,6 +1572,10 @@ receives_type = fn (value: &Value) u1
|
|||||||
|
|
||||||
return receives_type(left) and receives_type(right);
|
return receives_type(left) and receives_type(right);
|
||||||
},
|
},
|
||||||
|
.unary_type =>
|
||||||
|
{
|
||||||
|
return 1; // TODO: base on unary_type_id
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -1727,6 +1770,11 @@ get_byte_size = fn (type: &Type) u64
|
|||||||
>result = element_size * element_count;
|
>result = element_size * element_count;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
.alias =>
|
||||||
|
{
|
||||||
|
>result = get_byte_size(type.content.alias.type);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -1820,6 +1868,15 @@ get_bit_size = fn (type: &Type) u64
|
|||||||
>result = type.content.union.byte_size * 8;
|
>result = type.content.union.byte_size * 8;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
.enum_array =>
|
||||||
|
{
|
||||||
|
>enum_type = type.content.enum_array.enum_type;
|
||||||
|
>element_type = type.content.enum_array.element_type;
|
||||||
|
>element_bit_size = get_byte_size(element_type) * 8;
|
||||||
|
assert(enum_type.id == .enum);
|
||||||
|
>element_count = enum_type.content.enum.fields.length;
|
||||||
|
return element_bit_size * element_count;
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -1876,6 +1933,10 @@ is_promotable_integer_type_for_abi = fn (type: &Type) u1
|
|||||||
>backing_type = type.content.enum.backing_type;
|
>backing_type = type.content.enum.backing_type;
|
||||||
return is_promotable_integer_type_for_abi(backing_type);
|
return is_promotable_integer_type_for_abi(backing_type);
|
||||||
},
|
},
|
||||||
|
.pointer =>
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -1927,6 +1988,7 @@ ValueId = enum
|
|||||||
string_to_enum,
|
string_to_enum,
|
||||||
macro_instantiation,
|
macro_instantiation,
|
||||||
field_parent_pointer,
|
field_parent_pointer,
|
||||||
|
build_mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueConstantInteger = struct
|
ValueConstantInteger = struct
|
||||||
@ -2295,6 +2357,18 @@ value_is_constant = fn (value: &Value) u1
|
|||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
|
.unary_type =>
|
||||||
|
{
|
||||||
|
>unary_type_id = value.content.unary_type.id;
|
||||||
|
switch (unary_type_id)
|
||||||
|
{
|
||||||
|
.align_of,
|
||||||
|
.byte_size,
|
||||||
|
.integer_max,
|
||||||
|
=> { return 1; },
|
||||||
|
else => { unreachable; },
|
||||||
|
}
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -3761,6 +3835,7 @@ TypeKeyword = enum
|
|||||||
void,
|
void,
|
||||||
noreturn,
|
noreturn,
|
||||||
enum_array,
|
enum_array,
|
||||||
|
fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
type_is_slice = fn (type: &Type) u1
|
type_is_slice = fn (type: &Type) u1
|
||||||
@ -4545,6 +4620,15 @@ parse_type = fn (module: &Module, scope: &Scope) &Type
|
|||||||
>enum_array_type = get_enum_array_type(module, enum_type, element_type);
|
>enum_array_type = get_enum_array_type(module, enum_type, element_type);
|
||||||
return enum_array_type;
|
return enum_array_type;
|
||||||
},
|
},
|
||||||
|
.fn =>
|
||||||
|
{
|
||||||
|
skip_space(module);
|
||||||
|
>mandate_argument_names: u1 = 0;
|
||||||
|
>function_header = parse_function_header(module, scope, mandate_argument_names);
|
||||||
|
>result = function_header.type;
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
else => { unreachable; },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -5751,7 +5835,10 @@ parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
},
|
},
|
||||||
.build_mode =>
|
.build_mode =>
|
||||||
{
|
{
|
||||||
#trap();
|
result.& = {
|
||||||
|
.id = .build_mode,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
.field_parent_pointer =>
|
.field_parent_pointer =>
|
||||||
{
|
{
|
||||||
@ -5785,7 +5872,7 @@ parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
.left_bracket =>
|
.left_bracket =>
|
||||||
{
|
{
|
||||||
>element_count: u64 = 0;
|
>element_count: u64 = 0;
|
||||||
>value_buffer: [64]&Value = undefined;
|
>value_buffer: [128]&Value = undefined;
|
||||||
|
|
||||||
skip_space(module);
|
skip_space(module);
|
||||||
|
|
||||||
@ -5826,6 +5913,7 @@ parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
>value = parse_value(module, scope, zero);
|
>value = parse_value(module, scope, zero);
|
||||||
|
assert(element_count < value_buffer.length);
|
||||||
value_buffer[element_count] = value;
|
value_buffer[element_count] = value;
|
||||||
element_count += 1;
|
element_count += 1;
|
||||||
|
|
||||||
@ -5851,7 +5939,7 @@ parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
},
|
},
|
||||||
.dot =>
|
.dot =>
|
||||||
{
|
{
|
||||||
>identifier = parse_identifier(module);
|
>identifier = parse_name(module);
|
||||||
result = new_value(module);
|
result = new_value(module);
|
||||||
result.& = {
|
result.& = {
|
||||||
.content = {
|
.content = {
|
||||||
@ -6565,7 +6653,12 @@ parse_statement = fn (module: &Module, scope: &Scope) &Statement
|
|||||||
},
|
},
|
||||||
.return =>
|
.return =>
|
||||||
{
|
{
|
||||||
>return_value = parse_value(module, scope, zero);
|
>return_value: &Value = zero;
|
||||||
|
// TODO: make this better
|
||||||
|
if (module.content[module.offset] != ';')
|
||||||
|
{
|
||||||
|
return_value = parse_value(module, scope, zero);
|
||||||
|
}
|
||||||
statement.content.return = return_value;
|
statement.content.return = return_value;
|
||||||
statement.id = .return;
|
statement.id = .return;
|
||||||
},
|
},
|
||||||
@ -8690,19 +8783,16 @@ get_member_at_offset = fn (struct_type: &Type, offset: u64) &Field
|
|||||||
>byte_size = get_byte_size(struct_type);
|
>byte_size = get_byte_size(struct_type);
|
||||||
if (byte_size > offset)
|
if (byte_size > offset)
|
||||||
{
|
{
|
||||||
>offset_it: u64 = 0;
|
|
||||||
>fields = struct_type.content.struct.fields;
|
>fields = struct_type.content.struct.fields;
|
||||||
|
|
||||||
for (&field: fields)
|
for (&field: fields)
|
||||||
{
|
{
|
||||||
if (offset_it > offset)
|
if (field.offset > offset)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = field;
|
result = field;
|
||||||
assert(offset_it == field.offset);
|
|
||||||
offset_it = align_forward(offset_it + get_byte_size(field.type), #extend(get_byte_alignment(field.type)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(result != zero);
|
assert(result != zero);
|
||||||
@ -8922,7 +9012,11 @@ abi_system_v_get_indirect_result = fn (module: &Module, type: &Type, free_gpr: u
|
|||||||
{
|
{
|
||||||
if (is_promotable_integer_type_for_abi(type))
|
if (is_promotable_integer_type_for_abi(type))
|
||||||
{
|
{
|
||||||
#trap();
|
return abi_system_v_get_extend({
|
||||||
|
.semantic_type = type,
|
||||||
|
.sign = type_is_signed(type),
|
||||||
|
zero,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -10039,6 +10133,29 @@ clone_value = fn (module: &Module, scope: &Scope, old_value: &Value) &Value
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
.call =>
|
||||||
|
{
|
||||||
|
>callable = clone_value(module, scope, old_value.content.call.callable);
|
||||||
|
>old_arguments = old_value.content.call.arguments;
|
||||||
|
>arguments = arena_allocate_slice[&Value](module.arena, old_arguments.length);
|
||||||
|
|
||||||
|
for (i: 0..arguments.length)
|
||||||
|
{
|
||||||
|
arguments[i] = clone_value(module, scope, old_arguments[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.content = {
|
||||||
|
.call = {
|
||||||
|
.callable = callable,
|
||||||
|
.arguments = arguments,
|
||||||
|
.function_type = old_value.content.call.function_type,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.unary_type =>
|
||||||
|
{
|
||||||
|
result.content = old_value.content;
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -10695,7 +10812,7 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
.unary_type =>
|
.unary_type =>
|
||||||
{
|
{
|
||||||
>unary_type_id = value.content.unary_type.id;
|
>unary_type_id = value.content.unary_type.id;
|
||||||
>unary_type = value.content.unary_type.type; // TODO: call resolve_type
|
>unary_type = resolve_type(module, value.content.unary_type.type);
|
||||||
value.content.unary_type.type = unary_type;
|
value.content.unary_type.type = unary_type;
|
||||||
|
|
||||||
if (unary_type_id == .enum_values)
|
if (unary_type_id == .enum_values)
|
||||||
@ -13320,7 +13437,14 @@ emit_call = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_type
|
|||||||
{
|
{
|
||||||
switch (value.kind)
|
switch (value.kind)
|
||||||
{
|
{
|
||||||
.right => { #trap(); },
|
.right =>
|
||||||
|
{
|
||||||
|
return create_load(module, {
|
||||||
|
.type = destination_type,
|
||||||
|
.pointer = destination_pointer,
|
||||||
|
zero,
|
||||||
|
});
|
||||||
|
},
|
||||||
.left => { #trap(); },
|
.left => { #trap(); },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13336,7 +13460,8 @@ emit_call = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, left_type
|
|||||||
|
|
||||||
emit_constant_array = fn (module: &Module, elements: []&Value, element_type: &Type) &LLVMValue
|
emit_constant_array = fn (module: &Module, elements: []&Value, element_type: &Type) &LLVMValue
|
||||||
{
|
{
|
||||||
>value_buffer: [64]&LLVMValue = undefined;
|
>value_buffer: [128]&LLVMValue = undefined;
|
||||||
|
assert(elements.length <= value_buffer.length);
|
||||||
|
|
||||||
resolve_type_in_place(module, element_type);
|
resolve_type_in_place(module, element_type);
|
||||||
|
|
||||||
@ -13455,7 +13580,14 @@ emit_field_access = fn (module: &Module, value: &Value, left_llvm: &LLVMValue, l
|
|||||||
|
|
||||||
if (left_llvm)
|
if (left_llvm)
|
||||||
{
|
{
|
||||||
#trap();
|
assert(get_evaluation_kind(field_access.type) == .aggregate);
|
||||||
|
>alignment = get_byte_alignment(field_access.type);
|
||||||
|
|
||||||
|
>u64_type = uint64(module);
|
||||||
|
resolve_type_in_place(module, u64_type);
|
||||||
|
|
||||||
|
LLVMBuildMemCpy(module.llvm.builder, left_llvm, alignment, gep, alignment, LLVMConstInt(u64_type.llvm.abi, get_byte_size(field_access.type), 0));
|
||||||
|
return gep;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -14369,7 +14501,7 @@ emit_value = fn (module: &Module, value: &Value, type_kind: TypeKind, expect_con
|
|||||||
|
|
||||||
if (type_kind == .memory)
|
if (type_kind == .memory)
|
||||||
{
|
{
|
||||||
#trap();
|
llvm_value = memory_to_abi(module, llvm_value, boolean_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -14909,6 +15041,7 @@ emit_value = fn (module: &Module, value: &Value, type_kind: TypeKind, expect_con
|
|||||||
|
|
||||||
>alloca = create_alloca(module, {
|
>alloca = create_alloca(module, {
|
||||||
.type = aggregate_type,
|
.type = aggregate_type,
|
||||||
|
.name = "",
|
||||||
zero,
|
zero,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -15047,7 +15180,33 @@ emit_value = fn (module: &Module, value: &Value, type_kind: TypeKind, expect_con
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#trap();
|
llvm_value = LLVMConstNull(abi_type);
|
||||||
|
|
||||||
|
for (&initialization_element: elements)
|
||||||
|
{
|
||||||
|
>value = initialization_element.value;
|
||||||
|
>name = initialization_element.name;
|
||||||
|
|
||||||
|
>result_field: &Field = zero;
|
||||||
|
|
||||||
|
for (&field: fields)
|
||||||
|
{
|
||||||
|
if (string_equal(name, field.name))
|
||||||
|
{
|
||||||
|
result_field = field;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(result_field != zero);
|
||||||
|
|
||||||
|
emit_value(module, value, .memory, must_be_constant);
|
||||||
|
|
||||||
|
>extended = LLVMBuildZExt(module.llvm.builder, value.llvm, abi_type, "");
|
||||||
|
>shl = LLVMBuildShl(module.llvm.builder, extended, LLVMConstInt(abi_type, result_field.offset, 0), "");
|
||||||
|
>or_value = LLVMBuildOr(module.llvm.builder, llvm_value, shl, "");
|
||||||
|
llvm_value = or_value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.enum_array =>
|
.enum_array =>
|
||||||
@ -15222,6 +15381,10 @@ emit_value = fn (module: &Module, value: &Value, type_kind: TypeKind, expect_con
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.undefined =>
|
||||||
|
{
|
||||||
|
llvm_value = LLVMGetPoison(get_llvm_type(resolved_value_type, type_kind));
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -15581,6 +15744,21 @@ emit_assignment = fn (module: &Module, left_llvm: &LLVMValue, left_type: &Type,
|
|||||||
|
|
||||||
LLVMBuildMemCpy(module.llvm.builder, left_llvm, alignment, right.content.macro_instantiation.return_alloca, alignment, LLVMConstInt(u64_type.llvm.abi, size, 0));
|
LLVMBuildMemCpy(module.llvm.builder, left_llvm, alignment, right.content.macro_instantiation.return_alloca, alignment, LLVMConstInt(u64_type.llvm.abi, size, 0));
|
||||||
},
|
},
|
||||||
|
.field_access =>
|
||||||
|
{
|
||||||
|
>value = emit_field_access(module, right, left_llvm, left_type, .memory);
|
||||||
|
right.llvm = value;
|
||||||
|
},
|
||||||
|
.array_expression =>
|
||||||
|
{
|
||||||
|
emit_value(module, right, .memory, 0);
|
||||||
|
create_store(module, {
|
||||||
|
.source = right.llvm,
|
||||||
|
.destination = left_llvm,
|
||||||
|
.type = resolved_value_type,
|
||||||
|
zero,
|
||||||
|
});
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -15939,7 +16117,7 @@ analyze_statement = fn (module: &Module, scope: &Scope, statement: &Statement) v
|
|||||||
.range =>
|
.range =>
|
||||||
{
|
{
|
||||||
>start = value.content.range[0];
|
>start = value.content.range[0];
|
||||||
>end = value.content.range[0];
|
>end = value.content.range[1];
|
||||||
|
|
||||||
for (v: value.content.range)
|
for (v: value.content.range)
|
||||||
{
|
{
|
||||||
@ -16627,29 +16805,6 @@ generate_object = fn (module: &LLVMModule, target_machine: &LLVMTargetMachine, o
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgumentBuilder = struct
|
|
||||||
{
|
|
||||||
buffer: [128]&u8,
|
|
||||||
count: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
add_argument = fn (builder: &ArgumentBuilder, argument: []u8) void
|
|
||||||
{
|
|
||||||
assert(argument.pointer[argument.length] == 0);
|
|
||||||
>index = builder.count;
|
|
||||||
assert(index < builder.buffer.length);
|
|
||||||
builder.buffer[index] = argument.pointer;
|
|
||||||
builder.count = index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_arguments = fn (builder: &ArgumentBuilder) []&u8
|
|
||||||
{
|
|
||||||
>argument_count = builder.count;
|
|
||||||
assert(argument_count < builder.buffer.length);
|
|
||||||
builder.buffer[argument_count] = zero;
|
|
||||||
return builder.buffer[..argument_count];
|
|
||||||
}
|
|
||||||
|
|
||||||
link = fn (module: &Module) void
|
link = fn (module: &Module) void
|
||||||
{
|
{
|
||||||
>arena = module.arena;
|
>arena = module.arena;
|
||||||
@ -17550,7 +17705,7 @@ emit = fn (module: &Module) void
|
|||||||
>semantic_return_type = return_abi.semantic_type;
|
>semantic_return_type = return_abi.semantic_type;
|
||||||
if (semantic_return_type == noreturn_type(module) or function.content.function.attributes.naked)
|
if (semantic_return_type == noreturn_type(module) or function.content.function.attributes.naked)
|
||||||
{
|
{
|
||||||
#trap();
|
LLVMBuildUnreachable(module.llvm.builder);
|
||||||
}
|
}
|
||||||
else if (semantic_return_type == void_type(module))
|
else if (semantic_return_type == void_type(module))
|
||||||
{
|
{
|
||||||
@ -17824,7 +17979,7 @@ compile = fn (arena: &Arena, options: CompileOptions) void
|
|||||||
emit(&module);
|
emit(&module);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_file = fn (arena: &Arena, compile_options: CompileFile) []u8
|
compile_file = fn (arena: &Arena, compile_options: CompileFile, envp: &&u8) []u8
|
||||||
{
|
{
|
||||||
>relative_file_path = compile_options.relative_file_path;
|
>relative_file_path = compile_options.relative_file_path;
|
||||||
if (relative_file_path.length < 5)
|
if (relative_file_path.length < 5)
|
||||||
@ -17901,7 +18056,113 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) []u8
|
|||||||
|
|
||||||
if (is_compiler)
|
if (is_compiler)
|
||||||
{
|
{
|
||||||
#trap();
|
>builder: ArgumentBuilder = zero;
|
||||||
|
|
||||||
|
add_argument(&builder, "/home/david/dev/llvm/install/llvm_20.1.3_x86_64-linux-Release/bin/llvm-config");
|
||||||
|
add_argument(&builder, "--libdir");
|
||||||
|
add_argument(&builder, "--libs");
|
||||||
|
add_argument(&builder, "--system-libs");
|
||||||
|
|
||||||
|
>arguments = flush_arguments(&builder);
|
||||||
|
|
||||||
|
>llvm_config = os_execute(arena, arguments, envp, {
|
||||||
|
.policies = [ .pipe, .ignore ],
|
||||||
|
zero,
|
||||||
|
});
|
||||||
|
|
||||||
|
>success = llvm_config.termination_kind == .exit and llvm_config.termination_code == 0;
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
>stream = llvm_config.streams[0];
|
||||||
|
|
||||||
|
>line = string_first_character(stream, '\n');
|
||||||
|
|
||||||
|
if (line == string_no_match)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
library_directory = stream[..line];
|
||||||
|
library_directories = { .pointer = &library_directory, .length = 1 };
|
||||||
|
|
||||||
|
stream = stream[line + 1..];
|
||||||
|
|
||||||
|
line = string_first_character(stream, '\n');
|
||||||
|
if (line == string_no_match)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
>llvm_library_stream = stream[..line];
|
||||||
|
|
||||||
|
stream = stream[line + 1..];
|
||||||
|
|
||||||
|
>library_count: u64 = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
>space = string_first_character(llvm_library_stream, ' ');
|
||||||
|
if (space == string_no_match)
|
||||||
|
{
|
||||||
|
>library_argument = llvm_library_stream;
|
||||||
|
library_buffer[library_count] = library_argument[2..];
|
||||||
|
library_count += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Omit the first two characters: "-l"
|
||||||
|
>library_argument = llvm_library_stream[2..space];
|
||||||
|
library_buffer[library_count] = library_argument;
|
||||||
|
library_count += 1;
|
||||||
|
llvm_library_stream = llvm_library_stream[space + 1..];
|
||||||
|
}
|
||||||
|
|
||||||
|
line = string_first_character(stream, '\n');
|
||||||
|
if (line == string_no_match)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(line == stream.length - 1);
|
||||||
|
|
||||||
|
>system_library_stream = stream[..line];
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
>space = string_first_character(system_library_stream, ' ');
|
||||||
|
if (space == string_no_match)
|
||||||
|
{
|
||||||
|
>library_argument = llvm_library_stream;
|
||||||
|
library_buffer[library_count] = library_argument[2..];
|
||||||
|
library_count += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Omit the first two characters: "-l"
|
||||||
|
>library_argument = system_library_stream[2..space];
|
||||||
|
library_buffer[library_count] = library_argument;
|
||||||
|
library_count += 1;
|
||||||
|
system_library_stream = system_library_stream[space + 1..];
|
||||||
|
}
|
||||||
|
|
||||||
|
library_buffer[library_count] = "gcc";
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = "gcc_s";
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = "lldCommon";
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
|
library_buffer[library_count] = "lldELF";
|
||||||
|
library_count += 1;
|
||||||
|
|
||||||
|
library_names = library_buffer[..library_count];
|
||||||
|
library_paths = { .pointer = &llvm_bindings_library, .length = 1 };
|
||||||
}
|
}
|
||||||
else if (string_equal(base_name, "c_abi"))
|
else if (string_equal(base_name, "c_abi"))
|
||||||
{
|
{
|
||||||
@ -18125,7 +18386,7 @@ names: [_][]u8 =
|
|||||||
.build_mode = build_mode,
|
.build_mode = build_mode,
|
||||||
.has_debug_info = has_debug_info,
|
.has_debug_info = has_debug_info,
|
||||||
.silent = 0,
|
.silent = 0,
|
||||||
});
|
}, envp);
|
||||||
},
|
},
|
||||||
.test =>
|
.test =>
|
||||||
{
|
{
|
||||||
@ -18149,7 +18410,7 @@ names: [_][]u8 =
|
|||||||
.build_mode = build_mode,
|
.build_mode = build_mode,
|
||||||
.has_debug_info = has_debug_info,
|
.has_debug_info = has_debug_info,
|
||||||
.silent = 1,
|
.silent = 1,
|
||||||
});
|
}, envp);
|
||||||
|
|
||||||
>arguments: [_]&u8 = [
|
>arguments: [_]&u8 = [
|
||||||
executable_path.pointer,
|
executable_path.pointer,
|
||||||
|
@ -686,20 +686,18 @@ fn Field* get_member_at_offset(Type* struct_type, u32 offset)
|
|||||||
|
|
||||||
if (struct_type->structure.byte_size > offset)
|
if (struct_type->structure.byte_size > offset)
|
||||||
{
|
{
|
||||||
u32 offset_it = 0;
|
|
||||||
auto fields = struct_type->structure.fields;
|
auto fields = struct_type->structure.fields;
|
||||||
|
|
||||||
for (u64 i = 0; i < fields.length; i += 1)
|
for (u64 i = 0; i < fields.length; i += 1)
|
||||||
{
|
{
|
||||||
auto* field = &fields[i];
|
auto* field = &fields[i];
|
||||||
|
auto field_offset = field->offset;
|
||||||
if (offset_it > offset)
|
if (field_offset > offset)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = field;
|
result = field;
|
||||||
offset_it = (u32)align_forward(offset_it + get_byte_size(field->type), get_byte_alignment(field->type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(result);
|
assert(result);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user