This commit is contained in:
David Gonzalez Martin 2025-05-31 17:56:44 -06:00
parent 9b1c5ce7b0
commit c7ed43162e
4 changed files with 186 additions and 10 deletions

View File

@ -808,6 +808,7 @@ ValueId = enum
external_function,
function,
constant_integer,
global,
}
ValueConstantInteger = struct
@ -2784,6 +2785,40 @@ parse = fn (module: &Module) void
}
}
resolve_alias = fn (module: &Module, type: &Type) &Type
{
>result: &Type = zero;
switch (type.id)
{
.void,
.integer,
=>
{
result = type;
},
else =>
{
#trap();
},
}
assert(result != zero);
return result;
}
abi_system_v_classify_return_type = fn (module: &Module, type: &Type) AbiInformation
{
#trap();
}
ResolvedCallingConvention = enum
{
system_v,
win64,
}
emit = fn (module: &Module) void
{
assert(!module.current_function);
@ -2889,6 +2924,79 @@ emit = fn (module: &Module) void
>name = #enum_name(e);
module.llvm.intrinsic_table[i] = LLVMLookupIntrinsicID(name.pointer, name.length);
}
>global = module.first_global;
while (global)
{
assert(!module.current_function);
assert(!module.current_macro_instantiation);
assert(!module.current_macro_declaration);
if (global.emitted)
{
continue;
}
>global_pointer_type = global.variable.storage.type;
assert(global_pointer_type.id == .pointer);
>global_value_type = global_pointer_type.content.pointer.element_type;
switch (global.variable.storage.id)
{
.function, .external_function =>
{
>function_type = &global_value_type.content.function;
>semantic_argument_types = function_type.semantic_argument_types;
>semantic_return_type = function_type.semantic_return_type;
function_type.argument_abis = arena_allocate_slice[AbiInformation](module.arena, semantic_argument_types.length);
>llvm_abi_argument_type_buffer: [64]&LLVMType = undefined;
>resolved_calling_convention: ResolvedCallingConvention = undefined;
switch (function_type.calling_convention)
{
.c =>
{
// TODO: switch on platform
resolved_calling_convention = .system_v;
},
}
>is_reg_call = resolved_calling_convention == .system_v and 0; // TODO: regcall calling convention
switch (resolved_calling_convention)
{
.system_v =>
{
function_type.available_registers = {
.system_v = {
.gpr = #select(is_reg_call, 11, 6),
.sse = #select(is_reg_call, 16, 8),
},
};
function_type.return_abi = abi_system_v_classify_return_type(module, resolve_alias(module, semantic_return_type));
#trap();
},
.win64 =>
{
#trap();
},
}
},
.global =>
{
#trap();
},
else =>
{
report_error();
},
}
global = global.next;
}
#trap();
}
compile = fn (arena: &Arena, options: CompileOptions) void

View File

@ -629,6 +629,11 @@ fn u64 get_bit_size(Type* type)
case TypeId::integer: return type->integer.bit_count;
case TypeId::enumerator: return get_bit_size(type->enumerator.backing_type);
case TypeId::alias: return get_bit_size(type->alias.type);
case TypeId::array: return get_byte_size(type->array.element_type) * type->array.element_count * 8;
case TypeId::pointer: return 64;
case TypeId::structure: return type->structure.byte_size * 8;
case TypeId::union_type: return type->union_type.byte_size * 8;
case TypeId::enum_array: return get_byte_size(type->enum_array.element_type) * type->enum_array.enum_type->enumerator.fields.length * 8;
default: trap();
}
}

View File

@ -1103,7 +1103,7 @@ fn void resolve_type_in_place_debug(Module* module, Type* type)
assert(array_element_count);
resolve_type_in_place_debug(module, array_element_type);
auto bit_alignment = get_byte_alignment(type) * 8;
auto array_type = LLVMDIBuilderCreateArrayType(module->llvm.di_builder, array_element_count, bit_alignment, array_element_type->llvm.debug, 0, 0);
auto array_type = LLVMDIBuilderCreateArrayType(module->llvm.di_builder, get_bit_size(type), bit_alignment, array_element_type->llvm.debug, 0, 0);
result = array_type;
} break;
case TypeId::enumerator:
@ -1119,7 +1119,10 @@ fn void resolve_type_in_place_debug(Module* module, Type* type)
field_buffer[i] = enum_field;
}
result = LLVMDIBuilderCreateEnumerationType(module->llvm.di_builder, module->scope.llvm, (char*)type->name.pointer, type->name.length, module->llvm.file, type->enumerator.line, get_bit_size(type), get_byte_alignment(type) * 8, field_buffer, type->enumerator.fields.length, backing_type->llvm.debug);
auto debug_aligned_type = align_integer_type(module, backing_type);
resolve_type_in_place_debug(module, debug_aligned_type);
result = LLVMDIBuilderCreateEnumerationType(module->llvm.di_builder, module->scope.llvm, (char*)type->name.pointer, type->name.length, module->llvm.file, type->enumerator.line, get_bit_size(type), get_byte_alignment(type) * 8, field_buffer, type->enumerator.fields.length, debug_aligned_type->llvm.debug);
} break;
case TypeId::structure:
{
@ -1136,7 +1139,7 @@ fn void resolve_type_in_place_debug(Module* module, Type* type)
auto& field = fields[i];
auto field_type = field.type;
resolve_type_in_place_debug(module, field_type);
auto member_type = LLVMDIBuilderCreateMemberType(module->llvm.di_builder, module->scope.llvm, (char*)field.name.pointer, field.name.length, module->llvm.file, field.line, get_byte_size(field_type) * 8, get_byte_alignment(field_type) * 8, field.offset * 8, flags, field_type->llvm.debug);
auto member_type = LLVMDIBuilderCreateMemberType(module->llvm.di_builder, module->scope.llvm, (char*)field.name.pointer, field.name.length, module->llvm.file, field.line, get_bit_size(field_type), get_byte_alignment(field_type) * 8, field.offset * 8, flags, field_type->llvm.debug);
llvm_type_buffer[i] = member_type;
}
@ -2278,8 +2281,8 @@ enum class IndexType
struct TypeAnalysis
{
Type* indexing_type;
bool must_be_constant;
bool is_index;
};
fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnalysis analysis);
@ -2692,7 +2695,7 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal
{
if (!expected_type)
{
if (analysis.is_index)
if (analysis.indexing_type)
{
expected_type = uint64(module);
}
@ -3268,7 +3271,9 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal
}
auto pointer_element_type = array_like_type->pointer.element_type;
analyze_type(module, value->array_expression.index, 0, { .must_be_constant = analysis.must_be_constant, .is_index = true });
auto indexing_type = pointer_element_type->id == TypeId::enum_array ? pointer_element_type->enum_array.enum_type : uint64(module);
analyze_type(module, value->array_expression.index, 0, { .indexing_type = indexing_type, .must_be_constant = analysis.must_be_constant });
Type* element_type = 0;
switch (pointer_element_type->id)
@ -3311,6 +3316,11 @@ fn void analyze_type(Module* module, Value* value, Type* expected_type, TypeAnal
} break;
case ValueId::enum_literal:
{
if (!expected_type)
{
expected_type = analysis.indexing_type;
}
if (!expected_type)
{
report_error();
@ -4379,10 +4389,20 @@ fn ValueTypePair enter_struct_pointer_for_coerced_access(Module* module, LLVMVal
if (!(first_field_size < destination_size && first_field_size < source_size))
{
trap();
auto gep = LLVMBuildStructGEP2(module->llvm.builder, source_type->llvm.abi, source_value, 0, "coerce.dive");
if (first_field_type->id == TypeId::structure)
{
trap();
}
else
{
return { gep, first_field_type };
}
}
else
{
return { source_value, source_type };
}
return { source_value, source_type };
}
fn LLVMValueRef coerce_integer_or_pointer_to_integer_or_pointer(Module* module, LLVMValueRef source, Type* source_type, Type* destination_type)
@ -4418,7 +4438,12 @@ fn LLVMValueRef create_coerced_load(Module* module, LLVMValueRef source, Type* s
if (type_is_integer_backing(source_type) && type_is_integer_backing(destination_type))
{
trap();
auto load = create_load(module, {
.type = source_type,
.pointer = source,
});
auto result = coerce_integer_or_pointer_to_integer_or_pointer(module, load, source_type, destination_type);
return result;
}
else
{

38
tests/enum_debug_info.bbb Normal file
View File

@ -0,0 +1,38 @@
TypeId = enum
{
void,
noreturn,
forward_declaration,
integer,
function,
pointer,
array,
enum,
struct,
bits,
alias,
union,
unresolved,
vector,
floating_point,
enum_array,
opaque,
}
Type = struct
{
arr: [5]u32,
id: TypeId,
a: [2]u64,
b: u64,
}
[export] main = fn [cc(c)] () s32
{
>t: Type = {
.id = .integer,
zero,
};
t.arr[0] = 1;
return 0;
}