Introduce typealias
All checks were successful
CI / ci (ReleaseFast, ubuntu-latest) (push) Successful in 2m20s
CI / ci (ReleaseSmall, ubuntu-latest) (push) Successful in 2m18s
CI / ci (ReleaseSafe, ubuntu-latest) (push) Successful in 2m24s
CI / ci (Debug, ubuntu-latest) (push) Successful in 3m35s

This commit is contained in:
David Gonzalez Martin 2025-04-20 20:08:12 -06:00
parent 1e6dd642d9
commit 3cbd427f14
5 changed files with 65 additions and 4 deletions

View File

@ -1313,6 +1313,10 @@ pub const DI = struct {
pub fn create_enumeration_type(builder: *DI.Builder, scope: *DI.Scope, name: []const u8, file: *DI.File, line: c_uint, bit_size: u64, align_in_bits: u32, enumeration_types: []const *DI.Enumerator, backing_type: *DI.Type) *DI.Type.Composite {
return api.LLVMDIBuilderCreateEnumerationType(builder, scope, name.ptr, name.len, file, line, bit_size, align_in_bits, enumeration_types.ptr, @intCast(enumeration_types.len), backing_type);
}
pub fn create_typedef(builder: *DI.Builder, ty: *DI.Type, name: []const u8, file: *DI.File, line: c_uint, scope: *DI.Scope, align_in_bits: u32) *DI.Type.Derived {
return api.LLVMDIBuilderCreateTypedef(builder, ty, name.ptr, name.len, file, line, scope, align_in_bits);
}
};
pub const create_debug_location = api.LLVMDIBuilderCreateDebugLocation;

View File

@ -238,6 +238,7 @@ pub const Type = struct {
structure: Type.Struct,
vector,
forward_declaration,
alias: Type.Alias,
},
name: []const u8,
llvm: LLVM = .{},
@ -258,6 +259,11 @@ pub const Type = struct {
};
};
pub const Alias = struct {
type: *Type,
line: u32,
};
pub const Float = struct {
const Kind = enum {
half,
@ -327,6 +333,10 @@ pub const Type = struct {
const t = bits.backing_type.llvm.abi.?;
break :blk t;
},
.alias => |alias| blk: {
alias.type.resolve(module);
break :blk alias.type.llvm.abi.?;
},
else => @trap(),
};
ty.llvm.abi = abi_type;
@ -341,6 +351,7 @@ pub const Type = struct {
.integer => module.llvm.context.get_integer_type(@intCast(ty.get_byte_size() * 8)).to_type(),
.enumerator => |enumerator| enumerator.backing_type.llvm.memory.?,
.bits => |bits| bits.backing_type.llvm.memory.?, // TODO: see assert below
.alias => |alias| alias.type.llvm.memory.?,
else => @trap(),
};
ty.llvm.memory = memory_type;
@ -400,6 +411,10 @@ pub const Type = struct {
const struct_type = module.llvm.di_builder.create_struct_type(module.scope.llvm.?, ty.name, module.llvm.file, bits.line, ty.get_bit_size(), @intCast(ty.get_bit_alignment()), .{}, llvm_debug_member_types);
break :blk struct_type.to_type();
},
.alias => |alias| blk: {
const typedef = module.llvm.di_builder.create_typedef(alias.type.llvm.debug.?, ty.name, module.llvm.file, alias.line, module.scope.llvm.?, 0);
break :blk typedef.to_type();
},
else => @trap(),
};
ty.llvm.debug = debug_type;
@ -497,11 +512,12 @@ pub const Type = struct {
};
}
pub fn is_integral_or_enumeration_type(ty: *Type) bool {
pub fn is_integral_or_enumeration_type(ty: *const Type) bool {
return switch (ty.bb) {
.integer => true,
.bits => true,
.structure => false,
.alias => |alias| alias.type.is_integral_or_enumeration_type(),
else => @trap(),
};
}
@ -522,6 +538,7 @@ pub const Type = struct {
return switch (ty.bb) {
.integer => |integer| integer.bit_count < 32,
.bits => |bits| bits.backing_type.is_promotable_integer_type_for_abi(),
.alias => |alias| alias.type.is_promotable_integer_type_for_abi(),
else => @trap(),
};
}
@ -536,6 +553,7 @@ pub const Type = struct {
.enumerator => |enumerator| enumerator.backing_type.get_byte_alignment(),
.structure => |structure| structure.byte_alignment,
.bits => |bits| bits.backing_type.get_byte_alignment(),
.alias => |alias| alias.type.get_byte_alignment(),
else => @trap(),
};
return result;
@ -562,6 +580,7 @@ pub const Type = struct {
.array => |array| array.element_type.get_byte_size() * array.element_count,
.bits => |bits| bits.backing_type.get_byte_size(),
.enumerator => |enumerator| enumerator.backing_type.get_byte_size(),
.alias => |alias| alias.type.get_byte_size(),
else => @trap(),
};
return byte_size;
@ -600,6 +619,7 @@ pub const Type = struct {
return switch (ty.bb) {
.structure, .array => .aggregate,
.integer, .bits, .pointer, .enumerator => .scalar,
.alias => |alias| alias.type.get_evaluation_kind(),
else => @trap(),
};
}
@ -973,10 +993,11 @@ const Precedence = enum {
};
const GlobalKind = enum {
@"fn",
@"struct",
bits,
@"enum",
@"fn",
@"struct",
typealias,
};
const CallingConvention = enum {
@ -4001,6 +4022,22 @@ pub const Module = struct {
},
};
},
.typealias => {
const aliased_type = module.parse_type(null);
if (!module.consume_character_if_match(';')) {
module.report_error();
}
const alias_type = module.types.append(.{
.bb = .{
.alias = .{
.type = aliased_type,
.line = global_line,
},
},
.name = global_name,
});
_ = alias_type;
},
}
} else {
module.offset -= global_string.len;
@ -5415,7 +5452,11 @@ pub const Module = struct {
},
.constant_integer => |constant_integer| blk: {
const expected_type = analysis.type orelse module.report_error();
const ty = switch (expected_type.bb) {
const et = switch (expected_type.bb) {
.alias => |alias| alias.type,
else => expected_type,
};
const ty = switch (et.bb) {
.integer => |integer| switch (constant_integer.signed) {
true => {
if (!integer.signed) {
@ -8780,6 +8821,7 @@ pub const Abi = struct {
}
}
},
.alias => |alias| return classify(alias.type, options),
else => @trap(),
}
@ -8864,6 +8906,7 @@ pub const Abi = struct {
const element_offset = (offset / element_size) * element_size;
return get_int_type_at_offset(module, element_type, @intCast(offset - element_offset), source_type, source_offset);
},
.alias => |alias| return get_int_type_at_offset(module, alias.type, offset, source_type, source_offset),
else => |t| @panic(@tagName(t)),
}

View File

@ -1,6 +1,9 @@
mode_t = typealias u64;
[extern] memcmp = fn [cc(c)] (a: &u8, b: &u8, byte_count: u64) s32;
[extern] memcpy = fn [cc(c)] (destination: &u8, source: &u8, byte_count: u64) &u8;
[extern] exit = fn [cc(c)] (exit_code: s32) noreturn;
[extern] mkdir = fn [cc(c)] (path: &u8, mode: mode_t) s32;
assert = fn (ok: u1) void
{
@ -169,6 +172,10 @@ os_commit = fn (address: u64, size: u64, protection: OS_ProtectionFlags) void
}
}
os_make_directory = fn (path: &u8) void
{
}
Arena = struct
{
reserved_size: u64,

View File

@ -231,6 +231,7 @@ pub extern fn LLVMDIBuilderCreateBitFieldMemberType(builder: *llvm.DI.Builder, s
pub extern fn LLVMDIBuilderCreatePointerType(builder: *llvm.DI.Builder, element_type: *llvm.DI.Type, bit_size: u64, align_in_bits: u32, address_space: c_uint, name_pointer: [*]const u8, name_length: usize) *llvm.DI.Type.Derived;
pub extern fn LLVMDIBuilderCreateEnumerator(builder: *llvm.DI.Builder, name_pointer: [*]const u8, name_length: usize, value: i64, is_unsigned: Bool) *llvm.DI.Enumerator;
pub extern fn LLVMDIBuilderCreateEnumerationType(builder: *llvm.DI.Builder, scope: *llvm.DI.Scope, name_pointer: [*]const u8, name_length: usize, file: *llvm.DI.File, line: c_uint, bit_size: u64, align_in_bits: u32, enumerator_pointer: [*]const *llvm.DI.Enumerator, enumerator_count: c_uint, backing_type: *llvm.DI.Type) *llvm.DI.Type.Composite;
pub extern fn LLVMDIBuilderCreateTypedef(builder: *llvm.DI.Builder, ty: *llvm.DI.Type, name_pointer: [*]const u8, name_length: usize, file: *llvm.DI.File, line_number: c_uint, scope: *llvm.DI.Scope, align_in_bits: u32) *llvm.DI.Type.Derived;
pub extern fn LLVMMetadataReplaceAllUsesWith(forward: *llvm.DI.Type.Composite, complete: *llvm.DI.Type.Composite) void;

6
tests/type_alias.bbb Normal file
View File

@ -0,0 +1,6 @@
int = typealias s32;
[export] main = fn [cc(c)] () int
{
return 0;
}