Pass 'pointer_sub'
Some checks failed
CI / ci (Release, ubuntu-latest) (pull_request) Successful in 5m25s
CI / ci (RelWithDebInfo, ubuntu-latest) (pull_request) Successful in 5m28s
CI / ci (MinSizeRel, ubuntu-latest) (pull_request) Successful in 5m30s
CI / ci (Debug, ubuntu-latest) (pull_request) Successful in 18m3s
CI / ci (Release, ubuntu-latest) (push) Failing after 22s
CI / ci (MinSizeRel, ubuntu-latest) (push) Successful in 6m6s
CI / ci (RelWithDebInfo, ubuntu-latest) (push) Successful in 6m4s
CI / ci (Debug, ubuntu-latest) (push) Successful in 18m38s
Some checks failed
CI / ci (Release, ubuntu-latest) (pull_request) Successful in 5m25s
CI / ci (RelWithDebInfo, ubuntu-latest) (pull_request) Successful in 5m28s
CI / ci (MinSizeRel, ubuntu-latest) (pull_request) Successful in 5m30s
CI / ci (Debug, ubuntu-latest) (pull_request) Successful in 18m3s
CI / ci (Release, ubuntu-latest) (push) Failing after 22s
CI / ci (MinSizeRel, ubuntu-latest) (push) Successful in 6m6s
CI / ci (RelWithDebInfo, ubuntu-latest) (push) Successful in 6m4s
CI / ci (Debug, ubuntu-latest) (push) Successful in 18m38s
This commit is contained in:
parent
88978ef50b
commit
14f856b550
318
src/compiler.bbb
318
src/compiler.bbb
@ -1458,6 +1458,88 @@ Type = struct
|
|||||||
llvm: TypeLLVM,
|
llvm: TypeLLVM,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
receives_type = fn (value: &Value) u1
|
||||||
|
{
|
||||||
|
switch (value.id)
|
||||||
|
{
|
||||||
|
.constant_integer,
|
||||||
|
.enum_literal,
|
||||||
|
.string_literal,
|
||||||
|
.zero,
|
||||||
|
=>
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
},
|
||||||
|
.array_expression,
|
||||||
|
.call,
|
||||||
|
=>
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
.variable =>
|
||||||
|
{
|
||||||
|
return value.kind == .left and value.id == .global;
|
||||||
|
},
|
||||||
|
.field_access =>
|
||||||
|
{
|
||||||
|
>aggregate = value.content.field_access.aggregate;
|
||||||
|
>field_name = value.content.field_access.field_name;
|
||||||
|
|
||||||
|
return string_equal(field_name, "length") and? aggregate.id == .variable and? aggregate.kind == .left and? aggregate.content.variable.type.id == .array;
|
||||||
|
},
|
||||||
|
.unary =>
|
||||||
|
{
|
||||||
|
>unary_id = value.content.unary.id;
|
||||||
|
>unary_value = value.content.unary.value;
|
||||||
|
|
||||||
|
switch (unary_id)
|
||||||
|
{
|
||||||
|
.extend,
|
||||||
|
.truncate,
|
||||||
|
.pointer_cast,
|
||||||
|
.pointer_from_int,
|
||||||
|
=>
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
},
|
||||||
|
.int_from_pointer,
|
||||||
|
.ampersand,
|
||||||
|
.dereference,
|
||||||
|
.va_end,
|
||||||
|
.leading_zeroes,
|
||||||
|
.trailing_zeroes,
|
||||||
|
.exclamation,
|
||||||
|
.int_from_enum,
|
||||||
|
.enum_from_int,
|
||||||
|
.enum_name,
|
||||||
|
=>
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
.minus,
|
||||||
|
.plus,
|
||||||
|
.bitwise_not,
|
||||||
|
=>
|
||||||
|
{
|
||||||
|
return receives_type(unary_value);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.binary =>
|
||||||
|
{
|
||||||
|
>left = value.content.binary.left;
|
||||||
|
>right = value.content.binary.right;
|
||||||
|
>binary_id = value.content.binary.id;
|
||||||
|
|
||||||
|
return receives_type(left) and receives_type(right);
|
||||||
|
},
|
||||||
|
else =>
|
||||||
|
{
|
||||||
|
#trap();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type_is_signed = fn (type: &Type) u1
|
type_is_signed = fn (type: &Type) u1
|
||||||
{
|
{
|
||||||
switch (type.id)
|
switch (type.id)
|
||||||
@ -1553,7 +1635,7 @@ is_arbitrary_bit_integer = fn (type: &Type) u1
|
|||||||
|
|
||||||
switch (bit_count)
|
switch (bit_count)
|
||||||
{
|
{
|
||||||
8, 16, 32, 64, 128 => { return 0; },
|
1, 8, 16, 32, 64, 128 => { return 0; },
|
||||||
else => { return 1; },
|
else => { return 1; },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1765,6 +1847,10 @@ is_integral_or_enumeration_type = fn (type: &Type) u1
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
.alias =>
|
||||||
|
{
|
||||||
|
return is_integral_or_enumeration_type(type.content.alias.type);
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
unreachable;
|
unreachable;
|
||||||
@ -1851,6 +1937,7 @@ ValueConstantInteger = struct
|
|||||||
|
|
||||||
ValueFunctionLLVM = struct
|
ValueFunctionLLVM = struct
|
||||||
{
|
{
|
||||||
|
alloca_insertion_point: &LLVMValue,
|
||||||
return_block: &LLVMBasicBlock,
|
return_block: &LLVMBasicBlock,
|
||||||
return_alloca: &LLVMValue,
|
return_alloca: &LLVMValue,
|
||||||
}
|
}
|
||||||
@ -2583,8 +2670,10 @@ LLVMICmpPredicate = enum u32
|
|||||||
|
|
||||||
[extern] LLVMAppendBasicBlockInContext = fn [cc(c)] (context: &LLVMContext, function: &LLVMValue, name: &u8) &LLVMBasicBlock;
|
[extern] LLVMAppendBasicBlockInContext = fn [cc(c)] (context: &LLVMContext, function: &LLVMValue, name: &u8) &LLVMBasicBlock;
|
||||||
|
|
||||||
|
[extern] LLVMPositionBuilderBefore = fn [cc(c)] (builder: &LLVMBuilder, instruction: &LLVMValue) void;
|
||||||
[extern] LLVMPositionBuilderAtEnd = fn [cc(c)] (builder: &LLVMBuilder, basic_block: &LLVMBasicBlock) void;
|
[extern] LLVMPositionBuilderAtEnd = fn [cc(c)] (builder: &LLVMBuilder, basic_block: &LLVMBasicBlock) void;
|
||||||
[extern] LLVMClearInsertionPosition = fn [cc(c)] (builder: &LLVMBuilder) void;
|
[extern] LLVMClearInsertionPosition = fn [cc(c)] (builder: &LLVMBuilder) void;
|
||||||
|
[extern] LLVMGetCurrentDebugLocation2 = fn [cc(c)] (builder: &LLVMBuilder) &LLVMMetadata;
|
||||||
[extern] LLVMSetCurrentDebugLocation2 = fn [cc(c)] (builder: &LLVMBuilder, debug_location: &LLVMMetadata) void;
|
[extern] LLVMSetCurrentDebugLocation2 = fn [cc(c)] (builder: &LLVMBuilder, debug_location: &LLVMMetadata) void;
|
||||||
|
|
||||||
[extern] LLVMSetAlignment = fn [cc(c)] (value: &LLVMValue, alignment: u32) void;
|
[extern] LLVMSetAlignment = fn [cc(c)] (value: &LLVMValue, alignment: u32) void;
|
||||||
@ -3102,6 +3191,11 @@ sint32 = fn (module: &Module) &Type
|
|||||||
return integer_type(module, { .bit_count = 32, .signed = 1 });
|
return integer_type(module, { .bit_count = 32, .signed = 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sint64 = fn (module: &Module) &Type
|
||||||
|
{
|
||||||
|
return integer_type(module, { .bit_count = 64, .signed = 1 });
|
||||||
|
}
|
||||||
|
|
||||||
void_type = fn (module: &Module) &Type
|
void_type = fn (module: &Module) &Type
|
||||||
{
|
{
|
||||||
return module.scope.types.first + void_offset;
|
return module.scope.types.first + void_offset;
|
||||||
@ -9397,6 +9491,22 @@ ResolvedCallingConvention = enum
|
|||||||
win64,
|
win64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_current_function = fn (module: &Module) &Global
|
||||||
|
{
|
||||||
|
>current_function = module.current_function;
|
||||||
|
|
||||||
|
if (!current_function)
|
||||||
|
{
|
||||||
|
>macro_instantiation = module.current_macro_instantiation;
|
||||||
|
if (macro_instantiation)
|
||||||
|
{
|
||||||
|
current_function = macro_instantiation.instantiation_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return current_function;
|
||||||
|
}
|
||||||
|
|
||||||
AllocaOptions = struct
|
AllocaOptions = struct
|
||||||
{
|
{
|
||||||
type: &Type,
|
type: &Type,
|
||||||
@ -9415,7 +9525,17 @@ create_alloca = fn (module: &Module, options: AllocaOptions) &LLVMValue
|
|||||||
alignment = get_byte_alignment(abi_type);
|
alignment = get_byte_alignment(abi_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
>original_block = LLVMGetInsertBlock(module.llvm.builder);
|
||||||
|
>function = get_current_function(module);
|
||||||
|
>debug_location = LLVMGetCurrentDebugLocation2(module.llvm.builder);
|
||||||
|
>alloca_insertion_point = function.variable.storage.content.function.llvm.alloca_insertion_point;
|
||||||
|
LLVMPositionBuilderBefore(module.llvm.builder, alloca_insertion_point);
|
||||||
|
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, abi_type.llvm.memory, alignment, options.name);
|
||||||
|
LLVMPositionBuilderAtEnd(module.llvm.builder, original_block);
|
||||||
|
LLVMSetCurrentDebugLocation2(module.llvm.builder, debug_location);
|
||||||
|
|
||||||
return alloca;
|
return alloca;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9565,56 +9685,82 @@ analyze_value = fn (module: &Module, value: &Value, expected_type: &Type, type_k
|
|||||||
emit_value(module, value, type_kind, must_be_constant);
|
emit_value(module, value, type_kind, must_be_constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
analyze_binary_type = fn (module: &Module, left: &Value, right: &Value, is_boolean: u1, expected_type: &Type, must_be_constant: u1) void
|
analyze_binary_type = fn (module: &Module, left: &Value, right: &Value, is_boolean: u1, expected_type: &Type, must_be_constant: u1, is_sub: u1) void
|
||||||
{
|
{
|
||||||
>left_constant = value_is_constant(left);
|
>left_constant = value_is_constant(left);
|
||||||
>right_constant = value_is_constant(right);
|
>right_constant = value_is_constant(right);
|
||||||
|
>left_receives_type = receives_type(left);
|
||||||
|
>right_receives_type = receives_type(right);
|
||||||
|
|
||||||
if (!expected_type)
|
if (!expected_type and left_receives_type and right_receives_type)
|
||||||
{
|
{
|
||||||
if (left_constant != zero and right_constant)
|
if (left.id == right.id)
|
||||||
{
|
{
|
||||||
if (left.type == zero and right.type == zero)
|
switch (left.id)
|
||||||
{
|
{
|
||||||
>string_literal = left.id == .string_literal and right.id == .string_literal;
|
.string_literal =>
|
||||||
|
|
||||||
if (string_literal)
|
|
||||||
{
|
{
|
||||||
#trap();
|
expected_type = get_slice_type(module, uint8(module));
|
||||||
}
|
},
|
||||||
else
|
else =>
|
||||||
{
|
{
|
||||||
report_error();
|
report_error();
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (is_boolean or expected_type == zero)
|
|
||||||
{
|
|
||||||
if (left_constant)
|
|
||||||
{
|
|
||||||
analyze_type(module, right, zero, { .must_be_constant = must_be_constant, zero });
|
|
||||||
analyze_type(module, left, right.type, { .must_be_constant = must_be_constant, zero });
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
analyze_type(module, left, zero, { .must_be_constant = must_be_constant, zero });
|
report_error();
|
||||||
analyze_type(module, right, left.type, { .must_be_constant = must_be_constant, zero });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!is_boolean and expected_type != zero)
|
|
||||||
|
if (!left_receives_type and !right_receives_type)
|
||||||
{
|
{
|
||||||
|
analyze_type(module, left, zero, { .must_be_constant = must_be_constant, zero });
|
||||||
|
analyze_type(module, right, zero, { .must_be_constant = must_be_constant, zero });
|
||||||
|
}
|
||||||
|
else if (left_receives_type and !right_receives_type)
|
||||||
|
{
|
||||||
|
analyze_type(module, right, zero, { .must_be_constant = must_be_constant, zero });
|
||||||
|
analyze_type(module, left, right.type, { .must_be_constant = must_be_constant, zero });
|
||||||
|
}
|
||||||
|
else if (!left_receives_type and right_receives_type)
|
||||||
|
{
|
||||||
|
analyze_type(module, left, zero, { .must_be_constant = must_be_constant, zero });
|
||||||
|
analyze_type(module, right, left.type, { .must_be_constant = must_be_constant, zero });
|
||||||
|
}
|
||||||
|
else if (left_receives_type != zero and right_receives_type != zero)
|
||||||
|
{
|
||||||
|
assert(expected_type != zero);
|
||||||
|
|
||||||
|
if (is_boolean)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
analyze_type(module, left, expected_type, { .must_be_constant = must_be_constant, zero });
|
analyze_type(module, left, expected_type, { .must_be_constant = must_be_constant, zero });
|
||||||
analyze_type(module, right, expected_type, { .must_be_constant = must_be_constant, zero });
|
analyze_type(module, right, expected_type, { .must_be_constant = must_be_constant, zero });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
report_error();
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(left.type != zero);
|
assert(left.type != zero);
|
||||||
assert(right.type != zero);
|
assert(right.type != zero);
|
||||||
|
|
||||||
|
if (expected_type)
|
||||||
|
{
|
||||||
|
if (expected_type.id == .integer and left.type.id == .pointer and right.type.id == .pointer and is_sub)
|
||||||
|
{
|
||||||
|
check_types(module, left.type, right.type);
|
||||||
|
}
|
||||||
|
else if (!is_boolean)
|
||||||
|
{
|
||||||
|
typecheck(module, expected_type, left.type);
|
||||||
|
typecheck(module, expected_type, right.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_va_list_type = fn (module: &Module) &Type
|
get_va_list_type = fn (module: &Module) &Type
|
||||||
@ -10120,10 +10266,96 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
>id = value.content.binary.id;
|
>id = value.content.binary.id;
|
||||||
|
|
||||||
>is_boolean = binary_is_boolean(id);
|
>is_boolean = binary_is_boolean(id);
|
||||||
analyze_binary_type(module, left, right, is_boolean, expected_type, analysis.must_be_constant);
|
>is_sub = id == .sub;
|
||||||
|
analyze_binary_type(module, left, right, is_boolean, expected_type, analysis.must_be_constant, is_sub);
|
||||||
check_types(module, left.type, right.type);
|
check_types(module, left.type, right.type);
|
||||||
|
|
||||||
value_type = #select(is_boolean, uint1(module), left.type);
|
if (is_sub and left.type.id == .pointer and right.type.id == .pointer)
|
||||||
|
{
|
||||||
|
assert(left.type == right.type);
|
||||||
|
|
||||||
|
>u64_type = uint64(module);
|
||||||
|
>s64_type = sint64(module);
|
||||||
|
|
||||||
|
>left_int_from_pointer = new_value(module);
|
||||||
|
left_int_from_pointer.& = {
|
||||||
|
.content = {
|
||||||
|
.unary = {
|
||||||
|
.value = left,
|
||||||
|
.id = .int_from_pointer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = u64_type,
|
||||||
|
.id = .unary,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
|
|
||||||
|
>right_int_from_pointer = new_value(module);
|
||||||
|
right_int_from_pointer.& = {
|
||||||
|
.content = {
|
||||||
|
.unary = {
|
||||||
|
.value = right,
|
||||||
|
.id = .int_from_pointer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = u64_type,
|
||||||
|
.id = .unary,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
|
|
||||||
|
value.type = s64_type;
|
||||||
|
value.content.binary.left = left_int_from_pointer;
|
||||||
|
value.content.binary.right = right_int_from_pointer;
|
||||||
|
|
||||||
|
>sub = new_value(module);
|
||||||
|
sub.& = value.&;
|
||||||
|
|
||||||
|
>size_constant = new_value(module);
|
||||||
|
assert(left.type.id == .pointer);
|
||||||
|
|
||||||
|
>element_type = left.type.content.pointer.element_type;
|
||||||
|
size_constant.& = {
|
||||||
|
.content = {
|
||||||
|
.unary_type = {
|
||||||
|
.type = element_type,
|
||||||
|
.id = .byte_size,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.id = .unary_type,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
|
|
||||||
|
analyze_type(module, size_constant, s64_type, { .must_be_constant = 1, zero });
|
||||||
|
|
||||||
|
value.& = {
|
||||||
|
.content = {
|
||||||
|
.binary = {
|
||||||
|
.left = sub,
|
||||||
|
.right = size_constant,
|
||||||
|
.id = .div,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.id = .binary,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (expected_type)
|
||||||
|
{
|
||||||
|
#trap();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value_type = s64_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is_boolean)
|
||||||
|
{
|
||||||
|
value_type = uint1(module);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value_type = left.type;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.unary =>
|
.unary =>
|
||||||
{
|
{
|
||||||
@ -10285,7 +10517,9 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
>u32_type = uint32(module);
|
>u32_type = uint32(module);
|
||||||
resolve_type_in_place(module, u32_type);
|
resolve_type_in_place(module, u32_type);
|
||||||
|
|
||||||
// TODO: alloca insert point
|
>current_function = get_current_function(module);
|
||||||
|
>old_alloca_insertion_point = current_function.variable.storage.content.function.llvm.alloca_insertion_point;
|
||||||
|
current_function.variable.storage.content.function.llvm.alloca_insertion_point = LLVMBuildAlloca(module.llvm.builder, u32_type.llvm.abi, "alloca_insertion_point");
|
||||||
|
|
||||||
>alloca = create_alloca(module, {
|
>alloca = create_alloca(module, {
|
||||||
.type = string_type,
|
.type = string_type,
|
||||||
@ -10358,7 +10592,7 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
enum_to_string_function = llvm_function;
|
enum_to_string_function = llvm_function;
|
||||||
enum_type.content.enum.enum_to_string_function = enum_to_string_function;
|
enum_type.content.enum.enum_to_string_function = enum_to_string_function;
|
||||||
|
|
||||||
// TODO: alloca insertion point restoration
|
current_function.variable.storage.content.function.llvm.alloca_insertion_point = old_alloca_insertion_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(enum_to_string_function != zero);
|
assert(enum_to_string_function != zero);
|
||||||
@ -11332,7 +11566,7 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
analyze_type(module, condition, zero, { .must_be_constant = analysis.must_be_constant, zero });
|
analyze_type(module, condition, zero, { .must_be_constant = analysis.must_be_constant, zero });
|
||||||
>is_boolean: u1 = 0;
|
>is_boolean: u1 = 0;
|
||||||
|
|
||||||
analyze_binary_type(module, true_value, false_value, is_boolean, expected_type, analysis.must_be_constant);
|
analyze_binary_type(module, true_value, false_value, is_boolean, expected_type, analysis.must_be_constant, 0);
|
||||||
|
|
||||||
>true_type = true_value.type;
|
>true_type = true_value.type;
|
||||||
>false_type = false_value.type;
|
>false_type = false_value.type;
|
||||||
@ -11447,6 +11681,14 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
|
|
||||||
LLVMPositionBuilderAtEnd(module.llvm.builder, entry_block);
|
LLVMPositionBuilderAtEnd(module.llvm.builder, entry_block);
|
||||||
|
|
||||||
|
>current_function = get_current_function(module);
|
||||||
|
>old_alloca_insertion_point = current_function.variable.storage.content.function.llvm.alloca_insertion_point;
|
||||||
|
|
||||||
|
>u32_type = uint32(module);
|
||||||
|
resolve_type_in_place(module, u32_type);
|
||||||
|
|
||||||
|
current_function.variable.storage.content.function.llvm.alloca_insertion_point = LLVMBuildAlloca(module.llvm.builder, u32_type.llvm.abi, "alloca_insertion_point");
|
||||||
|
|
||||||
>arguments: [2]&LLVMValue = undefined;
|
>arguments: [2]&LLVMValue = undefined;
|
||||||
LLVMGetParams(llvm_function, &arguments[0]);
|
LLVMGetParams(llvm_function, &arguments[0]);
|
||||||
|
|
||||||
@ -11668,6 +11910,8 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
|
|
||||||
enum_type.content.enum.string_to_enum_function = llvm_function;
|
enum_type.content.enum.string_to_enum_function = llvm_function;
|
||||||
enum_type.content.enum.string_to_enum_struct_type = struct_type;
|
enum_type.content.enum.string_to_enum_struct_type = struct_type;
|
||||||
|
|
||||||
|
current_function.variable.storage.content.function.llvm.alloca_insertion_point = old_alloca_insertion_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
>struct_type = enum_type.content.enum.string_to_enum_struct_type;
|
>struct_type = enum_type.content.enum.string_to_enum_struct_type;
|
||||||
@ -16210,7 +16454,7 @@ analyze_statement = fn (module: &Module, scope: &Scope, statement: &Statement) v
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
analyze_binary_type(module, start, end, 0, zero, 0);
|
analyze_binary_type(module, start, end, 0, zero, 0, 0);
|
||||||
assert(start.type == end.type);
|
assert(start.type == end.type);
|
||||||
local_type = start.type;
|
local_type = start.type;
|
||||||
}
|
}
|
||||||
@ -16614,7 +16858,9 @@ emit = fn (module: &Module) void
|
|||||||
{
|
{
|
||||||
>e: LLVMIntrinsicIndex = #enum_from_int(i);
|
>e: LLVMIntrinsicIndex = #enum_from_int(i);
|
||||||
>name = #enum_name(e);
|
>name = #enum_name(e);
|
||||||
module.llvm.intrinsic_table[i] = LLVMLookupIntrinsicID(name.pointer, name.length);
|
>intrinsic_id = LLVMLookupIntrinsicID(name.pointer, name.length);
|
||||||
|
assert(intrinsic_id != 0);
|
||||||
|
module.llvm.intrinsic_table[i] = intrinsic_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i: 0..module.llvm.attribute_table.length)
|
for (i: 0..module.llvm.attribute_table.length)
|
||||||
@ -16954,6 +17200,11 @@ emit = fn (module: &Module) void
|
|||||||
LLVMPositionBuilderAtEnd(module.llvm.builder, entry_block);
|
LLVMPositionBuilderAtEnd(module.llvm.builder, entry_block);
|
||||||
LLVMSetCurrentDebugLocation2(module.llvm.builder, zero);
|
LLVMSetCurrentDebugLocation2(module.llvm.builder, zero);
|
||||||
|
|
||||||
|
>u32_type = uint32(module);
|
||||||
|
resolve_type_in_place(module, u32_type);
|
||||||
|
|
||||||
|
global.variable.storage.content.function.llvm.alloca_insertion_point = LLVMBuildAlloca(module.llvm.builder, u32_type.llvm.abi, "alloca_insertion_point");
|
||||||
|
|
||||||
>return_abi = &function_type.abi.return_abi;
|
>return_abi = &function_type.abi.return_abi;
|
||||||
switch (return_abi.flags.kind)
|
switch (return_abi.flags.kind)
|
||||||
{
|
{
|
||||||
@ -17370,6 +17621,8 @@ emit = fn (module: &Module) void
|
|||||||
LLVMBuildRet(module.llvm.builder, return_value);
|
LLVMBuildRet(module.llvm.builder, return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLVMInstructionEraseFromParent(global.variable.storage.content.function.llvm.alloca_insertion_point);
|
||||||
|
|
||||||
// END OF SCOPE
|
// END OF SCOPE
|
||||||
module.current_function = zero;
|
module.current_function = zero;
|
||||||
}
|
}
|
||||||
@ -17797,6 +18050,7 @@ names: [_][]u8 =
|
|||||||
"min_max",
|
"min_max",
|
||||||
"field_parent_pointer",
|
"field_parent_pointer",
|
||||||
"leading_trailing_zeroes",
|
"leading_trailing_zeroes",
|
||||||
|
"pointer_sub",
|
||||||
];
|
];
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32
|
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32
|
||||||
|
@ -43,6 +43,7 @@ enum class TypeKind
|
|||||||
abi,
|
abi,
|
||||||
memory,
|
memory,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn void analyze_block(Module* module, Block* block);
|
fn void analyze_block(Module* module, Block* block);
|
||||||
fn void emit_local_storage(Module* module, Variable* variable);
|
fn void emit_local_storage(Module* module, Variable* variable);
|
||||||
fn void emit_assignment(Module* module, LLVMValueRef left_llvm, Type* left_type, Value* right);
|
fn void emit_assignment(Module* module, LLVMValueRef left_llvm, Type* left_type, Value* right);
|
||||||
@ -340,6 +341,7 @@ fn bool is_arbitrary_bit_integer(Type* type)
|
|||||||
{
|
{
|
||||||
case TypeId::integer: switch (type->integer.bit_count)
|
case TypeId::integer: switch (type->integer.bit_count)
|
||||||
{
|
{
|
||||||
|
case 1:
|
||||||
case 8:
|
case 8:
|
||||||
case 16:
|
case 16:
|
||||||
case 32:
|
case 32:
|
||||||
@ -1622,7 +1624,10 @@ fn AbiInformation abi_system_v_get_indirect_result(Module* module, Type* type, 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),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1654,7 +1659,6 @@ fn AbiInformation abi_system_v_get_indirect_result(Module* module, Type* type, u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct AbiSystemVClassifyArgumentTypeOptions
|
struct AbiSystemVClassifyArgumentTypeOptions
|
||||||
{
|
{
|
||||||
u32 available_gpr;
|
u32 available_gpr;
|
||||||
@ -1949,7 +1953,7 @@ struct AllocaOptions
|
|||||||
|
|
||||||
fn Global* get_current_function(Module* module)
|
fn Global* get_current_function(Module* module)
|
||||||
{
|
{
|
||||||
Global* parent_function_global;
|
Global* parent_function_global = 0;
|
||||||
if (module->current_function)
|
if (module->current_function)
|
||||||
{
|
{
|
||||||
parent_function_global = module->current_function;
|
parent_function_global = module->current_function;
|
||||||
@ -1958,10 +1962,6 @@ fn Global* get_current_function(Module* module)
|
|||||||
{
|
{
|
||||||
parent_function_global = module->current_macro_instantiation->instantiation_function;
|
parent_function_global = module->current_macro_instantiation->instantiation_function;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
report_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent_function_global;
|
return parent_function_global;
|
||||||
}
|
}
|
||||||
@ -9375,6 +9375,7 @@ void emit(Module* module)
|
|||||||
abi_argument_type_count += 1;
|
abi_argument_type_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (u64 i = 0; i < semantic_argument_count; i += 1)
|
for (u64 i = 0; i < semantic_argument_count; i += 1)
|
||||||
{
|
{
|
||||||
auto& abi = function_type->abi.argument_abis[i];
|
auto& abi = function_type->abi.argument_abis[i];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user