wip
This commit is contained in:
parent
0e789d3f13
commit
e4e4b635c3
17
src/LLVM.zig
17
src/LLVM.zig
@ -808,6 +808,10 @@ pub const Module = opaque {
|
||||
pub fn get_intrinsic_declaration(module: *Module, intrinsic_id: Intrinsic.Id, parameter_types: []const *Type) *Value {
|
||||
return api.LLVMGetIntrinsicDeclaration(module, intrinsic_id, parameter_types.ptr, parameter_types.len);
|
||||
}
|
||||
|
||||
pub fn get_named_function(module: *Module, name: [*:0]const u8) ?*Function {
|
||||
return api.LLVMGetNamedFunction(module, name);
|
||||
}
|
||||
};
|
||||
|
||||
pub const VerifyResult = struct {
|
||||
@ -996,10 +1000,15 @@ pub const GlobalVariable = opaque {
|
||||
pub const set_initializer = api.LLVMSetInitializer;
|
||||
pub const erase_from_parent = api.LLVMDeleteGlobal;
|
||||
pub const delete = api.llvm_global_variable_delete;
|
||||
|
||||
pub fn to_value(global_variable: *GlobalVariable) *Value {
|
||||
return @ptrCast(global_variable);
|
||||
}
|
||||
|
||||
pub fn to_constant(global_variable: *GlobalVariable) *Constant {
|
||||
return @ptrCast(global_variable);
|
||||
}
|
||||
|
||||
pub const UnnamedAddress = enum(c_uint) {
|
||||
none,
|
||||
local,
|
||||
@ -1036,6 +1045,10 @@ pub const Function = opaque {
|
||||
return api.llvm_function_to_string(function).to_slice().?;
|
||||
}
|
||||
|
||||
pub fn dump(function: *Function) void {
|
||||
return lib.print_string(function.to_string());
|
||||
}
|
||||
|
||||
pub const set_calling_convention = api.LLVMSetFunctionCallConv;
|
||||
pub const get_calling_convention = api.LLVMGetFunctionCallConv;
|
||||
|
||||
@ -1060,6 +1073,10 @@ pub const Constant = opaque {
|
||||
pub fn to_value(constant: *Constant.Integer) *Value {
|
||||
return @ptrCast(constant);
|
||||
}
|
||||
|
||||
pub fn to_constant(constant: *Constant.Integer) *Constant {
|
||||
return @ptrCast(constant);
|
||||
}
|
||||
};
|
||||
|
||||
pub const get_sign_extended_value = api.LLVMConstIntGetSExtValue;
|
||||
|
@ -206,6 +206,7 @@ pub const ResolvedType = struct {
|
||||
|
||||
pub const Enumerator = struct {
|
||||
fields: []const Enumerator.Field,
|
||||
string_to_enum: ?StringToEnum = null,
|
||||
backing_type: *Type,
|
||||
line: u32,
|
||||
implicit_backing_type: bool,
|
||||
@ -214,6 +215,11 @@ pub const Enumerator = struct {
|
||||
name: []const u8,
|
||||
value: u64,
|
||||
};
|
||||
|
||||
pub const StringToEnum = struct {
|
||||
function: *llvm.Function,
|
||||
struct_type: *Type,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Type = struct {
|
||||
@ -507,6 +513,7 @@ pub const Type = struct {
|
||||
.bits => |bits| bits.backing_type.get_bit_alignment(),
|
||||
.array => |array| array.element_type.get_bit_alignment(),
|
||||
.structure => |structure| structure.bit_alignment,
|
||||
.enumerator => |enumerator| enumerator.backing_type.get_bit_alignment(),
|
||||
else => @trap(),
|
||||
};
|
||||
}
|
||||
@ -755,6 +762,7 @@ pub const Value = struct {
|
||||
int_from_pointer: *Value,
|
||||
pointer_cast: *Value,
|
||||
select: Select,
|
||||
string_to_enum: StringToEnum,
|
||||
trap,
|
||||
truncate: *Value,
|
||||
va_start,
|
||||
@ -770,6 +778,7 @@ pub const Value = struct {
|
||||
int_from_pointer,
|
||||
pointer_cast,
|
||||
select,
|
||||
string_to_enum,
|
||||
trap,
|
||||
truncate,
|
||||
va_start,
|
||||
@ -788,6 +797,11 @@ pub const Value = struct {
|
||||
list: *Value,
|
||||
type: *Type,
|
||||
};
|
||||
|
||||
const StringToEnum = struct {
|
||||
enum_type: *Type,
|
||||
string_value: *Value,
|
||||
};
|
||||
};
|
||||
|
||||
fn is_constant(value: *Value) bool {
|
||||
@ -1011,6 +1025,7 @@ pub const Module = struct {
|
||||
pointer_type: *llvm.Type,
|
||||
void_type: *llvm.Type,
|
||||
intrinsic_table: IntrinsicTable,
|
||||
memcmp: ?*llvm.Function = null,
|
||||
debug_tag: u32,
|
||||
|
||||
const IntrinsicTable = struct {
|
||||
@ -2770,7 +2785,27 @@ pub const Module = struct {
|
||||
.false_value = false_value,
|
||||
},
|
||||
},
|
||||
} };
|
||||
}, };
|
||||
},
|
||||
.string_to_enum => blk: {
|
||||
module.skip_space();
|
||||
module.expect_character(left_parenthesis);
|
||||
module.skip_space();
|
||||
const enum_type = module.parse_type(function);
|
||||
module.expect_character(',');
|
||||
module.skip_space();
|
||||
const string_value = module.parse_value(function, .{});
|
||||
module.skip_space();
|
||||
module.expect_character(right_parenthesis);
|
||||
|
||||
break :blk .{ .bb = .{
|
||||
.intrinsic = .{
|
||||
.string_to_enum = .{
|
||||
.enum_type = enum_type,
|
||||
.string_value = string_value,
|
||||
},
|
||||
},
|
||||
}, };
|
||||
},
|
||||
.trap => blk: {
|
||||
module.skip_space();
|
||||
@ -5413,12 +5448,13 @@ pub const Module = struct {
|
||||
module.report_error();
|
||||
}
|
||||
|
||||
if (binary.left.bb == .constant_integer) {
|
||||
// TODO: better strategy
|
||||
if (binary.left.bb == .constant_integer or binary.left.bb == .enum_literal) {
|
||||
module.analyze_value_type(function, binary.right, .{});
|
||||
module.analyze_value_type(function, binary.left, .{
|
||||
.type = binary.right.type,
|
||||
});
|
||||
} else if (binary.right.bb == .constant_integer) {
|
||||
} else if (binary.right.bb == .constant_integer or binary.right.bb == .enum_literal) {
|
||||
module.analyze_value_type(function, binary.left, .{});
|
||||
module.analyze_value_type(function, binary.right, .{
|
||||
.type = binary.left.type,
|
||||
@ -5466,6 +5502,211 @@ pub const Module = struct {
|
||||
const int_ty = module.integer_type(64, false);
|
||||
break :blk int_ty;
|
||||
},
|
||||
.string_to_enum => |string_to_enum| blk: {
|
||||
|
||||
if (string_to_enum.enum_type.bb != .enumerator) {
|
||||
module.report_error();
|
||||
}
|
||||
|
||||
if (string_to_enum.enum_type.bb.enumerator.string_to_enum == null) {
|
||||
const fields = string_to_enum.enum_type.bb.enumerator.fields;
|
||||
const array_element_count = fields.len;
|
||||
|
||||
const insert_block = module.llvm.builder.get_insert_block();
|
||||
defer module.llvm.builder.position_at_end(insert_block.?);
|
||||
|
||||
const uint8 = module.integer_type(8, false);
|
||||
const uint8_llvm = uint8.resolve(module).handle;
|
||||
const aligned_backing_type = module.align_integer_type(string_to_enum.enum_type.bb.enumerator.backing_type);
|
||||
const alignment = aligned_backing_type.get_byte_alignment();
|
||||
const byte_size = lib.align_forward_u64(aligned_backing_type.get_byte_size() + 1, alignment);
|
||||
|
||||
const struct_fields = module.arena.allocate(Field, 2);
|
||||
struct_fields[0] = .{
|
||||
.bit_offset = 0,
|
||||
.line = 0,
|
||||
.type = string_to_enum.enum_type,
|
||||
.name = "enum_value",
|
||||
.byte_offset = 0,
|
||||
};
|
||||
struct_fields[1] = .{
|
||||
.bit_offset = aligned_backing_type.get_byte_size() * 8,
|
||||
.line = 0,
|
||||
.type = uint8,
|
||||
.name = "is_valid",
|
||||
.byte_offset = aligned_backing_type.get_byte_size(),
|
||||
};
|
||||
|
||||
const struct_type = module.types.append(.{
|
||||
.name = "string_to_enum",
|
||||
.bb = .{
|
||||
.structure = .{
|
||||
.fields = struct_fields,
|
||||
.byte_size = byte_size,
|
||||
.bit_size = byte_size * 8,
|
||||
.byte_alignment = alignment,
|
||||
.bit_alignment = alignment * 8,
|
||||
.line = 0,
|
||||
.is_slice = false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const uint64 = module.integer_type(64, false).resolve(module).handle;
|
||||
const llvm_function_type = llvm.Type.Function.get(struct_type.resolve(module).handle, &.{uint64, uint64}, false);
|
||||
const slice_struct_type = module.llvm.context.get_struct_type(&.{module.llvm.pointer_type, uint64});
|
||||
|
||||
const llvm_function_value = module.llvm.module.create_function(.{
|
||||
.name = module.arena.join_string(&.{ "string_to_enum.", string_to_enum.enum_type.name }),
|
||||
.linkage = .InternalLinkage,
|
||||
.type = llvm_function_type,
|
||||
});
|
||||
|
||||
var name_before: ?*llvm.GlobalVariable = null;
|
||||
var value_constant_buffer: [64]*llvm.Constant = undefined;
|
||||
var name_constant_buffer: [64]*llvm.Constant = undefined;
|
||||
|
||||
for (string_to_enum.enum_type.bb.enumerator.fields, 0..) |field, field_index| {
|
||||
const value_global = aligned_backing_type.llvm.handle.?.to_integer().get_constant(field.value, 0);
|
||||
value_constant_buffer[field_index] = value_global.to_constant();
|
||||
|
||||
const null_terminate = true;
|
||||
const name_global = module.llvm.module.create_global_variable(.{
|
||||
.type = uint8_llvm.get_array_type(field.name.len + @intFromBool(null_terminate)).to_type(),
|
||||
.linkage = .InternalLinkage,
|
||||
.name = module.arena.join_string(&.{"string.", string_to_enum.enum_type.name, ".", field.name}),
|
||||
.initial_value = module.llvm.context.get_constant_string(field.name, null_terminate),
|
||||
.is_constant = true,
|
||||
.before = name_before,
|
||||
});
|
||||
name_before = name_global;
|
||||
|
||||
const slice_constant = module.llvm.context.get_anonymous_constant_struct(&.{
|
||||
name_global.to_constant(),
|
||||
uint64.to_integer().get_constant(field.name.len, 0).to_constant(),
|
||||
}, false);
|
||||
name_constant_buffer[field_index] = slice_constant;
|
||||
}
|
||||
|
||||
const value_array = aligned_backing_type.llvm.handle.?.get_constant_array(value_constant_buffer[0..array_element_count]);
|
||||
const name_array = slice_struct_type.to_type().get_constant_array(name_constant_buffer[0..array_element_count]);
|
||||
|
||||
const value_array_variable_type = aligned_backing_type.resolve(module).handle.get_array_type(array_element_count);
|
||||
const value_array_variable = module.llvm.module.create_global_variable(.{
|
||||
.type = value_array_variable_type.to_type(),
|
||||
.linkage = .InternalLinkage,
|
||||
.initial_value = value_array,
|
||||
.name = "value.array.enum",
|
||||
});
|
||||
|
||||
const name_array_variable_type = slice_struct_type.to_type().get_array_type(array_element_count);
|
||||
const name_array_variable = module.llvm.module.create_global_variable(.{
|
||||
.type = name_array_variable_type.to_type(),
|
||||
.linkage = .InternalLinkage,
|
||||
.initial_value = name_array,
|
||||
.name = "name.array.enum",
|
||||
});
|
||||
|
||||
const function_entry_block = module.llvm.context.create_basic_block("entry", llvm_function_value);
|
||||
const return_block = module.llvm.context.create_basic_block("return_block", llvm_function_value);
|
||||
const loop_entry_block = module.llvm.context.create_basic_block("loop.entry", llvm_function_value);
|
||||
const loop_body_block = module.llvm.context.create_basic_block("loop.body", llvm_function_value);
|
||||
const loop_exit_block = module.llvm.context.create_basic_block("loop.exit", llvm_function_value);
|
||||
module.llvm.builder.position_at_end(function_entry_block);
|
||||
|
||||
const return_alloca = module.llvm.builder.create_alloca(struct_type.llvm.handle.?, "retval");
|
||||
const index_alloca = module.llvm.builder.create_alloca(uint64, "idx");
|
||||
_ = module.llvm.builder.create_store(uint64.get_zero().to_value(), index_alloca);
|
||||
_ = module.llvm.builder.create_branch(loop_entry_block);
|
||||
module.llvm.builder.position_at_end(loop_entry_block);
|
||||
const index_load = module.llvm.builder.create_load(uint64, index_alloca);
|
||||
const loop_cmp = module.llvm.builder.create_integer_compare(.ult, index_load, uint64.to_integer().get_constant(array_element_count, 0).to_value());
|
||||
_ = module.llvm.builder.create_conditional_branch(loop_cmp, loop_body_block, loop_exit_block);
|
||||
|
||||
module.llvm.builder.position_at_end(loop_body_block);
|
||||
|
||||
var arguments: [2]*llvm.Argument = undefined;
|
||||
llvm_function_value.get_arguments(&arguments);
|
||||
|
||||
const body_index_load = module.llvm.builder.create_load(uint64, index_alloca);
|
||||
const array_element_pointer = module.llvm.builder.create_gep(.{
|
||||
.type = name_array_variable_type.to_type(),
|
||||
.aggregate = name_array_variable.to_value(),
|
||||
.indices = &.{body_index_load},
|
||||
});
|
||||
|
||||
const element_length_pointer = module.llvm.builder.create_struct_gep(slice_struct_type, array_element_pointer, 1);
|
||||
const element_length = module.llvm.builder.create_load(uint64, element_length_pointer);
|
||||
|
||||
const length_comparison = module.llvm.builder.create_integer_compare(.eq, arguments[1].to_value(), element_length);
|
||||
|
||||
const length_match_block = module.llvm.context.create_basic_block("length.match", llvm_function_value);
|
||||
const length_mismatch_block = module.llvm.context.create_basic_block("length.mismatch", llvm_function_value);
|
||||
_ = module.llvm.builder.create_conditional_branch(length_comparison, length_match_block, length_mismatch_block);
|
||||
|
||||
module.llvm.builder.position_at_end(length_match_block);
|
||||
const memcmp = if (module.llvm.memcmp) |memcmp| {
|
||||
_ = memcmp;
|
||||
@trap();
|
||||
} else b: {
|
||||
if (module.llvm.module.get_named_function("memcmp")) |memcmp| {
|
||||
module.llvm.memcmp = memcmp;
|
||||
break :b memcmp;
|
||||
} else {
|
||||
const memcmp = module.llvm.module.create_function(.{
|
||||
.name = "memcmp",
|
||||
.linkage = .ExternalLinkage,
|
||||
.type = llvm.Type.Function.get(module.integer_type(32, true).resolve(module).handle, &.{module.llvm.pointer_type, module.llvm.pointer_type, uint64}, false),
|
||||
});
|
||||
module.llvm.memcmp = memcmp;
|
||||
break :b memcmp;
|
||||
}
|
||||
};
|
||||
const element_pointer_pointer = module.llvm.builder.create_struct_gep(slice_struct_type, array_element_pointer, 0);
|
||||
const element_pointer = module.llvm.builder.create_load(module.llvm.pointer_type, element_pointer_pointer);
|
||||
const memcmp_return_result = module.llvm.builder.create_call(memcmp.get_type(), memcmp.to_value(), &.{module.llvm.builder.create_int_to_ptr(arguments[0].to_value(), module.llvm.pointer_type), element_pointer, element_length});
|
||||
const content_comparison = module.llvm.builder.create_integer_compare(.eq, memcmp_return_result, module.integer_type(32, true).resolve(module).handle.get_zero().to_value());
|
||||
const content_match_block = module.llvm.context.create_basic_block("content.match", llvm_function_value);
|
||||
_ = module.llvm.builder.create_conditional_branch(content_comparison, content_match_block, length_mismatch_block);
|
||||
|
||||
module.llvm.builder.position_at_end(content_match_block);
|
||||
const value_array_element_pointer = module.llvm.builder.create_gep(.{
|
||||
.type = value_array_variable_type.to_type(),
|
||||
.aggregate = value_array_variable.to_value(),
|
||||
.indices = &.{body_index_load},
|
||||
});
|
||||
const enum_value_load = module.llvm.builder.create_load(aligned_backing_type.resolve(module).handle, value_array_element_pointer);
|
||||
const ret_result_enum = module.llvm.builder.create_struct_gep(struct_type.llvm.handle.?.to_struct(), return_alloca, 0);
|
||||
_ = module.llvm.builder.create_store(enum_value_load, ret_result_enum);
|
||||
const ret_result_bool = module.llvm.builder.create_struct_gep(struct_type.llvm.handle.?.to_struct(), return_alloca, 1);
|
||||
_ = module.llvm.builder.create_store(uint8_llvm.to_integer().get_constant(1, 0).to_value(), ret_result_bool);
|
||||
_ = module.llvm.builder.create_branch(return_block);
|
||||
|
||||
module.llvm.builder.position_at_end(length_mismatch_block);
|
||||
const inc = module.llvm.builder.create_add(body_index_load, uint64.to_integer().get_constant(1, 0).to_value());
|
||||
_ = module.llvm.builder.create_store(inc, index_alloca);
|
||||
_ = module.llvm.builder.create_branch(loop_entry_block);
|
||||
|
||||
module.llvm.builder.position_at_end(loop_exit_block);
|
||||
_ = module.llvm.builder.create_store(struct_type.llvm.handle.?.get_zero().to_value(), return_alloca);
|
||||
_ = module.llvm.builder.create_branch(return_block);
|
||||
|
||||
module.llvm.builder.position_at_end(return_block);
|
||||
const ret_load = module.llvm.builder.create_load(struct_type.llvm.handle.?, return_alloca);
|
||||
module.llvm.builder.create_ret(ret_load);
|
||||
|
||||
string_to_enum.enum_type.bb.enumerator.string_to_enum = .{
|
||||
.function = llvm_function_value,
|
||||
.struct_type = struct_type,
|
||||
};
|
||||
}
|
||||
|
||||
const s2e = string_to_enum.enum_type.bb.enumerator.string_to_enum orelse unreachable;
|
||||
|
||||
module.analyze_value_type(function, string_to_enum.string_value, .{ .type = module.get_slice_type(.{ .type = module.integer_type(8, false) }) });
|
||||
|
||||
break :blk s2e.struct_type;
|
||||
},
|
||||
.trap => module.noreturn_type,
|
||||
.va_start => module.get_va_list_type(),
|
||||
.va_end => |va_list| blk: {
|
||||
@ -5886,6 +6127,15 @@ pub const Module = struct {
|
||||
const result = module.llvm.builder.create_select(condition, select.true_value.llvm.?, select.false_value.llvm.?);
|
||||
break :blk result;
|
||||
},
|
||||
.string_to_enum => |string_to_enum| blk: {
|
||||
module.emit_value(function, string_to_enum.string_value);
|
||||
const s2e = string_to_enum.enum_type.bb.enumerator.string_to_enum orelse unreachable;
|
||||
const first_field = module.llvm.builder.create_extract_value(string_to_enum.string_value.llvm.?, 0);
|
||||
const second_field = module.llvm.builder.create_extract_value(string_to_enum.string_value.llvm.?, 1);
|
||||
const ptr_to_int = module.llvm.builder.create_ptr_to_int(first_field, module.integer_type(64, false).resolve(module).handle);
|
||||
const call = module.llvm.builder.create_call(s2e.function.get_type(), s2e.function.to_value(), &.{ptr_to_int, second_field});
|
||||
break :blk call;
|
||||
},
|
||||
.trap => blk: {
|
||||
// TODO: lookup in advance
|
||||
const intrinsic_id = module.llvm.intrinsic_table.trap;
|
||||
@ -6461,9 +6711,7 @@ pub const Module = struct {
|
||||
|
||||
module.analyze(function, if_statement.condition, .{});
|
||||
const llvm_condition = switch (if_statement.condition.type.?.bb) {
|
||||
.integer => |integer| if (integer.bit_count != 1) {
|
||||
module.report_error();
|
||||
} else if_statement.condition.llvm.?,
|
||||
.integer => |integer| if (integer.bit_count != 1) module.llvm.builder.create_integer_compare(.ne, if_statement.condition.llvm.?, if_statement.condition.type.?.llvm.handle.?.get_zero().to_value()) else if_statement.condition.llvm.?,
|
||||
.pointer => module.llvm.builder.create_integer_compare(.ne, if_statement.condition.llvm.?, if_statement.condition.type.?.llvm.handle.?.get_zero().to_value()),
|
||||
else => @trap(),
|
||||
};
|
||||
@ -6729,7 +6977,7 @@ pub const Module = struct {
|
||||
.linkage = .InternalLinkage,
|
||||
.name = "conststring",
|
||||
.initial_value = constant_string,
|
||||
.type = u8_type.llvm.handle.?.get_array_type(string_literal.len + @intFromBool(null_terminate)).to_type(),
|
||||
.type = u8_type.resolve(module).handle.get_array_type(string_literal.len + @intFromBool(null_terminate)).to_type(),
|
||||
});
|
||||
global_variable.set_unnamed_address(.global);
|
||||
|
||||
@ -6767,6 +7015,21 @@ pub const Module = struct {
|
||||
}
|
||||
},
|
||||
.intrinsic => |intrinsic| switch (intrinsic) {
|
||||
.string_to_enum => |string_to_enum| {
|
||||
module.emit_value(function, string_to_enum.string_value);
|
||||
const s2e = string_to_enum.enum_type.bb.enumerator.string_to_enum orelse unreachable;
|
||||
const first_field = module.llvm.builder.create_extract_value(string_to_enum.string_value.llvm.?, 0);
|
||||
const second_field = module.llvm.builder.create_extract_value(string_to_enum.string_value.llvm.?, 1);
|
||||
const ptr_to_int = module.llvm.builder.create_ptr_to_int(first_field, module.integer_type(64, false).resolve(module).handle);
|
||||
const call = module.llvm.builder.create_call(s2e.function.get_type(), s2e.function.to_value(), &.{ptr_to_int, second_field});
|
||||
_ = module.create_store(.{
|
||||
.source_value = call,
|
||||
.destination_value = left_llvm,
|
||||
.source_type = s2e.struct_type,
|
||||
.destination_type = s2e.struct_type,
|
||||
.alignment = pointer_type.bb.pointer.alignment,
|
||||
});
|
||||
},
|
||||
.va_start => {
|
||||
assert(value_type == module.get_va_list_type());
|
||||
assert(pointer_type.bb.pointer.type == module.get_va_list_type());
|
||||
|
@ -225,13 +225,25 @@ global_state_initialize = fn () void
|
||||
};
|
||||
}
|
||||
|
||||
CompilerCommand = enum
|
||||
{
|
||||
compile,
|
||||
test,
|
||||
}
|
||||
|
||||
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8) s32
|
||||
{
|
||||
global_state_initialize();
|
||||
|
||||
if (argument_count < 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
>command_string = c_string_to_slice(argv[1]);
|
||||
|
||||
> a = #string_to_enum(CompilerCommand, command_string);
|
||||
|
||||
>relative_file_path_pointer = argv[2];
|
||||
if (!relative_file_path_pointer)
|
||||
{
|
||||
@ -256,6 +268,5 @@ global_state_initialize = fn () void
|
||||
return 1;
|
||||
}
|
||||
|
||||
global_state_initialize();
|
||||
return 0;
|
||||
}
|
||||
|
@ -124,6 +124,7 @@ pub extern fn llvm_value_is_instruction(value: *llvm.Value) bool;
|
||||
|
||||
// Intrinsics
|
||||
pub extern fn LLVMLookupIntrinsicID(name_pointer: [*]const u8, name_length: usize) llvm.Intrinsic.Id;
|
||||
pub extern fn LLVMGetNamedFunction(module: *llvm.Module, name: [*:0]const u8) *llvm.Function;
|
||||
pub extern fn LLVMGetIntrinsicDeclaration(module: *llvm.Module, intrinsic_id: llvm.Intrinsic.Id, parameter_type_pointer: [*]const *llvm.Type, parameter_type_count: usize) *llvm.Value;
|
||||
pub extern fn LLVMIntrinsicGetType(context: *llvm.Context, intrinsic_id: llvm.Intrinsic.Id, parameter_type_pointer: [*]const *llvm.Type, parameter_type_count: usize) *llvm.Type.Function;
|
||||
|
||||
|
@ -309,4 +309,5 @@ const names = &[_][]const u8{
|
||||
"c_struct_with_array",
|
||||
"c_function_pointer",
|
||||
"c_abi",
|
||||
"string_to_enum",
|
||||
};
|
||||
|
20
tests/string_to_enum.bbb
Normal file
20
tests/string_to_enum.bbb
Normal file
@ -0,0 +1,20 @@
|
||||
E = enum
|
||||
{
|
||||
asd,
|
||||
dsa,
|
||||
gsa,
|
||||
}
|
||||
|
||||
[export] main = fn [cc(c)] () s32
|
||||
{
|
||||
>e = "dsa";
|
||||
>s2e = #string_to_enum(E, e);
|
||||
>result: s32 = 1;
|
||||
|
||||
if (s2e.is_valid)
|
||||
{
|
||||
result = #extend(s2e.enum_value != .dsa);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user