Merge pull request #154 from birth-software/more-enum-metaprogramming
More enum metaprogramming
This commit is contained in:
commit
57a7a07b52
@ -3916,6 +3916,7 @@ pub const Function = struct {
|
|||||||
body: Debug.Block.Index,
|
body: Debug.Block.Index,
|
||||||
return_pointer: Instruction.Index = .null,
|
return_pointer: Instruction.Index = .null,
|
||||||
alloca_index: u32 = 1,
|
alloca_index: u32 = 1,
|
||||||
|
has_debug_info: bool,
|
||||||
|
|
||||||
pub const List = BlockList(@This(), enum {});
|
pub const List = BlockList(@This(), enum {});
|
||||||
pub usingnamespace @This().List.Index;
|
pub usingnamespace @This().List.Index;
|
||||||
@ -3933,9 +3934,6 @@ pub const Function = struct {
|
|||||||
attributes: Attributes = .{},
|
attributes: Attributes = .{},
|
||||||
calling_convention: CallingConvention = .auto,
|
calling_convention: CallingConvention = .auto,
|
||||||
has_polymorphic_parameters: bool = false,
|
has_polymorphic_parameters: bool = false,
|
||||||
// comptime_parameter_declarations: []const ComptimeParameterDeclaration = &.{},
|
|
||||||
// comptime_parameter_instantiations: []const V.Comptime = &.{},
|
|
||||||
// is_member: bool = false,
|
|
||||||
|
|
||||||
const Attributes = struct {
|
const Attributes = struct {
|
||||||
naked: bool = false,
|
naked: bool = false,
|
||||||
@ -4872,7 +4870,241 @@ pub const Builder = struct {
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
.name => {
|
||||||
|
assert(argument_node_list.len == 1);
|
||||||
|
const v = try builder.resolveRuntimeValue(unit, context, Type.Expect.none, argument_node_list[0], .right);
|
||||||
|
switch (v.value) {
|
||||||
|
.runtime => switch (unit.types.get(v.type).*) {
|
||||||
|
.integer => |*integer| switch (integer.kind) {
|
||||||
|
.@"enum" => {
|
||||||
|
const name_function = try builder.get_name_function(unit, context, v.type);
|
||||||
|
var args = try UnpinnedArray(V).initialize_with_capacity(context.my_allocator, 1);
|
||||||
|
args.append_with_capacity(v);
|
||||||
|
const call = try unit.instructions.append(context.my_allocator, .{
|
||||||
|
.call = .{
|
||||||
|
.callable = .{
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.global = name_function,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = name_function.declaration.type,
|
||||||
|
},
|
||||||
|
.function_type = name_function.declaration.type,
|
||||||
|
.arguments = args.slice(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, call);
|
||||||
|
return V{
|
||||||
|
.value = .{
|
||||||
|
.runtime = call,
|
||||||
|
},
|
||||||
|
.type = unit.function_prototypes.get(unit.types.get(name_function.declaration.type).function).return_type,
|
||||||
|
};
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_name_function(builder: *Builder, unit: *Unit, context: *const Context, type_index: Type.Index) !*Debug.Declaration.Global {
|
||||||
|
if (unit.name_functions.get(type_index)) |result| return result else {
|
||||||
|
var argument_types = try UnpinnedArray(Type.Index).initialize_with_capacity(context.my_allocator, 1);
|
||||||
|
argument_types.append_with_capacity(type_index);
|
||||||
|
const return_type_index = try unit.getSliceType(context, .{
|
||||||
|
.child_pointer_type = try unit.getPointerType(context, .{
|
||||||
|
.type = .u8,
|
||||||
|
// TODO: zero-terminate?
|
||||||
|
.termination = .none,
|
||||||
|
.mutability = .@"const",
|
||||||
|
.many = true,
|
||||||
|
.nullable = false,
|
||||||
|
}),
|
||||||
|
.child_type = .u8,
|
||||||
|
// TODO: zero-terminate?
|
||||||
|
.termination = .none,
|
||||||
|
.mutability = .@"const",
|
||||||
|
.nullable = false,
|
||||||
|
});
|
||||||
|
const function_prototype_index = try unit.function_prototypes.append(context.my_allocator, .{
|
||||||
|
.argument_types = argument_types.slice(),
|
||||||
|
.return_type = return_type_index,
|
||||||
|
.abi = .{
|
||||||
|
.return_type = return_type_index,
|
||||||
|
.parameter_types = argument_types.slice(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const function_type_index = try unit.types.append(context.my_allocator, .{
|
||||||
|
.function = function_prototype_index,
|
||||||
|
});
|
||||||
|
const function_definition_index = try unit.function_definitions.append(context.my_allocator, .{
|
||||||
|
.scope = .{
|
||||||
|
.scope = .{
|
||||||
|
.file = builder.current_file,
|
||||||
|
.line = 0,
|
||||||
|
.column = 0,
|
||||||
|
.kind = .function,
|
||||||
|
.local = true,
|
||||||
|
.level = builder.current_scope.level + 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = function_type_index,
|
||||||
|
.body = .null,
|
||||||
|
.has_debug_info = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const function_definition = unit.function_definitions.get(function_definition_index);
|
||||||
|
const old_scope = builder.current_scope;
|
||||||
|
builder.current_scope = &function_definition.scope.scope;
|
||||||
|
defer builder.current_scope = old_scope;
|
||||||
|
|
||||||
|
const old_function = builder.current_function;
|
||||||
|
builder.current_function = function_definition_index;
|
||||||
|
defer builder.current_function = old_function;
|
||||||
|
|
||||||
|
const old_basic_block = builder.current_basic_block;
|
||||||
|
defer builder.current_basic_block = old_basic_block;
|
||||||
|
|
||||||
|
const argument_name_hash = try unit.processIdentifier(context, "_enum_value_");
|
||||||
|
const argument_declaration_index = try unit.argument_declarations.append(context.my_allocator, .{
|
||||||
|
.declaration = .{
|
||||||
|
.scope = builder.current_scope,
|
||||||
|
.name = argument_name_hash,
|
||||||
|
.type = type_index,
|
||||||
|
.mutability = .@"const",
|
||||||
|
.line = 0,
|
||||||
|
.column = 0,
|
||||||
|
.kind = .argument,
|
||||||
|
},
|
||||||
|
.index = 0,
|
||||||
|
});
|
||||||
|
comptime assert(@TypeOf(argument_declaration_index) == Debug.Declaration.Argument.Index);
|
||||||
|
const argument = unit.argument_declarations.get(argument_declaration_index);
|
||||||
|
|
||||||
|
try builder.current_scope.declarations.put_no_clobber(context.my_allocator, argument_name_hash, &argument.declaration);
|
||||||
|
|
||||||
|
const entry_block = try builder.newBasicBlock(unit, context);
|
||||||
|
const exit_block = try builder.newBasicBlock(unit, context);
|
||||||
|
builder.current_basic_block = entry_block;
|
||||||
|
|
||||||
|
const argument_instruction = try unit.instructions.append(context.my_allocator, .{
|
||||||
|
.abi_argument = 0,
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, argument_instruction);
|
||||||
|
const switch_instruction_index = try unit.instructions.append(context.my_allocator, .{
|
||||||
|
.@"switch" = .{
|
||||||
|
.condition = .{
|
||||||
|
.value = .{
|
||||||
|
.runtime = argument_instruction,
|
||||||
|
},
|
||||||
|
.type = type_index,
|
||||||
|
},
|
||||||
|
.block_type = return_type_index,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, switch_instruction_index);
|
||||||
|
const switch_instruction = &unit.instructions.get(switch_instruction_index).@"switch";
|
||||||
|
|
||||||
|
const phi_instruction_index = try unit.instructions.append(context.my_allocator, .{
|
||||||
|
.phi = .{
|
||||||
|
.type = return_type_index,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const phi = &unit.instructions.get(phi_instruction_index).phi;
|
||||||
|
|
||||||
|
const cases = switch (unit.types.get(type_index).*) {
|
||||||
|
.integer => |*integer| switch (integer.kind) {
|
||||||
|
.@"enum" => |*enum_type| b: {
|
||||||
|
var cases = try UnpinnedArray(Instruction.Switch.Case).initialize_with_capacity(context.my_allocator, enum_type.fields.length);
|
||||||
|
for (enum_type.fields.slice()) |enum_field_index| {
|
||||||
|
builder.current_basic_block = entry_block;
|
||||||
|
const enum_field = unit.enum_fields.get(enum_field_index);
|
||||||
|
const case_block = try builder.newBasicBlock(unit, context);
|
||||||
|
builder.current_basic_block = case_block;
|
||||||
|
const identifier = unit.getIdentifier(enum_field.name);
|
||||||
|
const identifier_z = try context.allocator.dupeZ(u8, identifier);
|
||||||
|
const string_literal = try builder.processStringLiteralFromStringAndDebugInfo(unit, context, identifier_z, .{
|
||||||
|
.line = 0,
|
||||||
|
.column = 0,
|
||||||
|
});
|
||||||
|
const slice = try unit.constant_slices.append(context.my_allocator,.{
|
||||||
|
.array = string_literal,
|
||||||
|
.start = 0,
|
||||||
|
.end = identifier_z.len,
|
||||||
|
.type = return_type_index,
|
||||||
|
});
|
||||||
|
const v = V{
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.constant_slice = slice,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = return_type_index,
|
||||||
|
};
|
||||||
|
try phi.addIncoming(context, v, builder.current_basic_block);
|
||||||
|
try builder.jump(unit, context, exit_block);
|
||||||
|
|
||||||
|
const case = Instruction.Switch.Case{
|
||||||
|
.condition = .{
|
||||||
|
.enum_value = enum_field_index,
|
||||||
|
},
|
||||||
|
.basic_block = case_block,
|
||||||
|
};
|
||||||
|
cases.append_with_capacity(case);
|
||||||
|
}
|
||||||
|
|
||||||
|
break :b cases;
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
};
|
||||||
|
|
||||||
|
switch_instruction.cases = cases;
|
||||||
|
switch_instruction.else_block = try builder.create_unreachable_block(unit, context);
|
||||||
|
|
||||||
|
builder.current_basic_block = exit_block;
|
||||||
|
try builder.appendInstruction(unit, context, phi_instruction_index);
|
||||||
|
|
||||||
|
const ret = try unit.instructions.append(context.my_allocator, .{
|
||||||
|
.ret = .{
|
||||||
|
.type = return_type_index,
|
||||||
|
.value = .{
|
||||||
|
.runtime = phi_instruction_index,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try builder.appendInstruction(unit, context, ret);
|
||||||
|
|
||||||
|
const global_index = try unit.global_declarations.append(context.my_allocator, .{
|
||||||
|
.declaration = .{
|
||||||
|
.scope = builder.current_scope,
|
||||||
|
.name = try unit.processIdentifier(context, try std.fmt.allocPrint(context.allocator, "get_enum_name_{}", .{@intFromEnum(type_index)})),
|
||||||
|
.type = function_type_index,
|
||||||
|
.line = 0,
|
||||||
|
.column = 0,
|
||||||
|
.mutability = .@"const",
|
||||||
|
.kind = .global,
|
||||||
|
},
|
||||||
|
.initial_value = .{
|
||||||
|
.function_definition = function_definition_index,
|
||||||
|
},
|
||||||
|
.type_node_index = .null,
|
||||||
|
.attributes = .{},
|
||||||
|
});
|
||||||
|
|
||||||
|
const global = unit.global_declarations.get(global_index);
|
||||||
|
|
||||||
|
try unit.code_to_emit.put_no_clobber(context.my_allocator, function_definition_index, global);
|
||||||
|
try unit.name_functions.put_no_clobber(context.my_allocator, type_index, global);
|
||||||
|
|
||||||
|
return global;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8662,6 +8894,7 @@ pub const Builder = struct {
|
|||||||
.file = builder.current_file,
|
.file = builder.current_file,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.has_debug_info = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
defer builder.current_function = old_function;
|
defer builder.current_function = old_function;
|
||||||
@ -14626,11 +14859,7 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (switch_instruction.else_block == .null) {
|
if (switch_instruction.else_block == .null) {
|
||||||
switch_instruction.else_block = try builder.newBasicBlock(unit, context);
|
switch_instruction.else_block = try builder.create_unreachable_block(unit, context);
|
||||||
const old_block = builder.current_basic_block;
|
|
||||||
builder.current_basic_block = switch_instruction.else_block;
|
|
||||||
try builder.buildUnreachable(unit, context);
|
|
||||||
builder.current_basic_block = old_block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phi_info) |phi| {
|
if (phi_info) |phi| {
|
||||||
@ -14685,6 +14914,16 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_unreachable_block(builder: *Builder, unit: *Unit, context: *const Context) !BasicBlock.Index {
|
||||||
|
const block = try builder.newBasicBlock(unit, context);
|
||||||
|
const old_block = builder.current_basic_block;
|
||||||
|
builder.current_basic_block = block;
|
||||||
|
try builder.buildUnreachable(unit, context);
|
||||||
|
builder.current_basic_block = old_block;
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
fn resolveFieldAccess(builder: *Builder, unit: *Unit, context: *const Context, type_expect: Type.Expect, node_index: Node.Index, side: Side, new_parameters: []const V.Comptime) !V {
|
fn resolveFieldAccess(builder: *Builder, unit: *Unit, context: *const Context, type_expect: Type.Expect, node_index: Node.Index, side: Side, new_parameters: []const V.Comptime) !V {
|
||||||
const node = unit.getNode(node_index);
|
const node = unit.getNode(node_index);
|
||||||
const right_node = unit.getNode(node.right);
|
const right_node = unit.getNode(node.right);
|
||||||
@ -14804,6 +15043,23 @@ pub const Builder = struct {
|
|||||||
|
|
||||||
break :b result;
|
break :b result;
|
||||||
},
|
},
|
||||||
|
.global => |global| switch (unit.types.get(global.declaration.type).*) {
|
||||||
|
.array => |array| if (byte_equal(identifier, length_field_name)) switch (type_expect) {
|
||||||
|
.none => V{
|
||||||
|
.value = .{
|
||||||
|
.@"comptime" = .{
|
||||||
|
.comptime_int = .{
|
||||||
|
.value = array.count,
|
||||||
|
.signedness = .unsigned,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.type = .comptime_int,
|
||||||
|
},
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
} else unreachable,
|
||||||
|
else => |t| @panic(@tagName(t)),
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
},
|
},
|
||||||
.runtime => |_| b: {
|
.runtime => |_| b: {
|
||||||
@ -16015,6 +16271,7 @@ pub const Unit = struct {
|
|||||||
error_unions: MyHashMap(Type.Error.Union.Descriptor, Type.Index) = .{},
|
error_unions: MyHashMap(Type.Error.Union.Descriptor, Type.Index) = .{},
|
||||||
two_structs: MyHashMap([2]Type.Index, Type.Index) = .{},
|
two_structs: MyHashMap([2]Type.Index, Type.Index) = .{},
|
||||||
fields_array: MyHashMap(Type.Index, *Debug.Declaration.Global) = .{},
|
fields_array: MyHashMap(Type.Index, *Debug.Declaration.Global) = .{},
|
||||||
|
name_functions: MyHashMap(Type.Index, *Debug.Declaration.Global) = .{},
|
||||||
error_count: u32 = 0,
|
error_count: u32 = 0,
|
||||||
|
|
||||||
code_to_emit: MyHashMap(Function.Definition.Index, *Debug.Declaration.Global) = .{},
|
code_to_emit: MyHashMap(Function.Definition.Index, *Debug.Declaration.Global) = .{},
|
||||||
|
@ -2270,29 +2270,6 @@ pub const LLVM = struct {
|
|||||||
try llvm.setCallOrFunctionAttributes(unit, context, function_prototype, .{
|
try llvm.setCallOrFunctionAttributes(unit, context, function_prototype, .{
|
||||||
.function = function,
|
.function = function,
|
||||||
});
|
});
|
||||||
// const calling_convention = getCallingConvention(function_prototype.calling_convention);
|
|
||||||
// function.setCallingConvention(calling_convention);
|
|
||||||
//
|
|
||||||
// const function_attribute_set = llvm.getFunctionAttributes(unit, context, function_prototype);
|
|
||||||
//
|
|
||||||
// var parameter_attribute_sets = try UnpinnedArray(*const LLVM.Attribute.Set).initialize_with_capacity(context.my_allocator, @intCast(function_prototype.abi.parameter_types_abi.len + @intFromBool(function_prototype.abi.return_type_abi.kind == .indirect)));
|
|
||||||
// const return_attribute_set = blk: {
|
|
||||||
// const attribute_set = try llvm.emitParameterAttributes(unit, context, function_prototype.abi.return_type_abi, true);
|
|
||||||
// break :blk switch (function_prototype.abi.return_type_abi.kind) {
|
|
||||||
// .indirect => b: {
|
|
||||||
// parameter_attribute_sets.append_with_capacity(attribute_set);
|
|
||||||
// break :b llvm.context.getAttributeSet(null, 0);
|
|
||||||
// },
|
|
||||||
// else => attribute_set,
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// for (function_prototype.abi.parameter_types_abi) |parameter_type_abi| {
|
|
||||||
// const parameter_attribute_set = try llvm.emitParameterAttributes(unit, context, parameter_type_abi, false);
|
|
||||||
// parameter_attribute_sets.append_with_capacity(parameter_attribute_set);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function.setAttributes(llvm.context, function_attribute_set, return_attribute_set, parameter_attribute_sets.pointer, parameter_attribute_sets.length);
|
|
||||||
|
|
||||||
switch (declaration.initial_value) {
|
switch (declaration.initial_value) {
|
||||||
.function_declaration => try llvm.function_declaration_map.put_no_clobber(context.my_allocator, declaration, function),
|
.function_declaration => try llvm.function_declaration_map.put_no_clobber(context.my_allocator, declaration, function),
|
||||||
@ -2300,7 +2277,13 @@ pub const LLVM = struct {
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.descriptor.generate_debug_information) {
|
const generate_debug_information = unit.descriptor.generate_debug_information and switch (declaration.initial_value) {
|
||||||
|
.function_declaration => true,
|
||||||
|
.function_definition => |function_definition_index| unit.function_definitions.get(function_definition_index).has_debug_info,
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (generate_debug_information) {
|
||||||
// if (data_structures.byte_equal(name, "nat_split_struct_ints")) @breakpoint();
|
// if (data_structures.byte_equal(name, "nat_split_struct_ints")) @breakpoint();
|
||||||
const debug_file = try llvm.getDebugInfoFile(unit, context, declaration.declaration.scope.file);
|
const debug_file = try llvm.getDebugInfoFile(unit, context, declaration.declaration.scope.file);
|
||||||
var parameter_types = try UnpinnedArray(*LLVM.DebugInfo.Type).initialize_with_capacity(context.my_allocator, @intCast(function_prototype.argument_types.len));
|
var parameter_types = try UnpinnedArray(*LLVM.DebugInfo.Type).initialize_with_capacity(context.my_allocator, @intCast(function_prototype.argument_types.len));
|
||||||
@ -2522,7 +2505,9 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
llvm.sema_function = function_declaration;
|
llvm.sema_function = function_declaration;
|
||||||
llvm.inside_branch = false;
|
llvm.inside_branch = false;
|
||||||
|
|
||||||
if (unit.descriptor.generate_debug_information) {
|
const generate_debug_information = unit.descriptor.generate_debug_information and function_definition.has_debug_info;
|
||||||
|
|
||||||
|
if (generate_debug_information) {
|
||||||
const subprogram = llvm.function.getSubprogram() orelse unreachable;
|
const subprogram = llvm.function.getSubprogram() orelse unreachable;
|
||||||
llvm.file = subprogram.getFile() orelse unreachable;
|
llvm.file = subprogram.getFile() orelse unreachable;
|
||||||
llvm.scope = subprogram.toLocalScope().toScope();
|
llvm.scope = subprogram.toLocalScope().toScope();
|
||||||
@ -2552,7 +2537,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
|
|
||||||
switch (sema_instruction.*) {
|
switch (sema_instruction.*) {
|
||||||
.push_scope => |push_scope| {
|
.push_scope => |push_scope| {
|
||||||
if (unit.descriptor.generate_debug_information) {
|
if (generate_debug_information) {
|
||||||
const old_scope = try llvm.getScope(unit, context, push_scope.old);
|
const old_scope = try llvm.getScope(unit, context, push_scope.old);
|
||||||
assert(@intFromEnum(push_scope.old.kind) >= @intFromEnum(Compilation.Debug.Scope.Kind.function));
|
assert(@intFromEnum(push_scope.old.kind) >= @intFromEnum(Compilation.Debug.Scope.Kind.function));
|
||||||
|
|
||||||
@ -2562,7 +2547,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.pop_scope => |pop_scope| {
|
.pop_scope => |pop_scope| {
|
||||||
if (unit.descriptor.generate_debug_information) {
|
if (generate_debug_information) {
|
||||||
const new = try llvm.getScope(unit, context, pop_scope.new);
|
const new = try llvm.getScope(unit, context, pop_scope.new);
|
||||||
if (pop_scope.new.kind == .function) {
|
if (pop_scope.new.kind == .function) {
|
||||||
assert(new.toSubprogram() orelse unreachable == llvm.function.getSubprogram() orelse unreachable);
|
assert(new.toSubprogram() orelse unreachable == llvm.function.getSubprogram() orelse unreachable);
|
||||||
@ -2577,7 +2562,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.debug_checkpoint => |debug_checkpoint| {
|
.debug_checkpoint => |debug_checkpoint| {
|
||||||
if (unit.descriptor.generate_debug_information) {
|
if (generate_debug_information) {
|
||||||
const scope = try llvm.getScope(unit, context, debug_checkpoint.scope);
|
const scope = try llvm.getScope(unit, context, debug_checkpoint.scope);
|
||||||
llvm.builder.setCurrentDebugLocation(llvm.context, debug_checkpoint.line + 1, debug_checkpoint.column + 1, scope, llvm.function);
|
llvm.builder.setCurrentDebugLocation(llvm.context, debug_checkpoint.line + 1, debug_checkpoint.column + 1, scope, llvm.function);
|
||||||
}
|
}
|
||||||
@ -2921,7 +2906,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, argument.toValue());
|
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, argument.toValue());
|
||||||
},
|
},
|
||||||
.debug_declare_argument => |debug_declare| {
|
.debug_declare_argument => |debug_declare| {
|
||||||
if (unit.descriptor.generate_debug_information) {
|
if (generate_debug_information) {
|
||||||
const argument_index: c_uint = debug_declare.argument.index;
|
const argument_index: c_uint = debug_declare.argument.index;
|
||||||
const declaration = &debug_declare.argument.declaration;
|
const declaration = &debug_declare.argument.declaration;
|
||||||
const debug_declaration_type = try llvm.getDebugType(unit, context, declaration.type);
|
const debug_declaration_type = try llvm.getDebugType(unit, context, declaration.type);
|
||||||
@ -2966,7 +2951,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.debug_declare_local_variable => |declare_local_variable| {
|
.debug_declare_local_variable => |declare_local_variable| {
|
||||||
if (unit.descriptor.generate_debug_information) {
|
if (generate_debug_information) {
|
||||||
const local_variable = declare_local_variable.variable;
|
const local_variable = declare_local_variable.variable;
|
||||||
const debug_declaration_type = try llvm.getDebugType(unit, context, local_variable.declaration.type);
|
const debug_declaration_type = try llvm.getDebugType(unit, context, local_variable.declaration.type);
|
||||||
const always_preserve = true;
|
const always_preserve = true;
|
||||||
@ -3190,7 +3175,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
@panic("Function block with no termination");
|
@panic("Function block with no termination");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.descriptor.generate_debug_information) {
|
if (generate_debug_information) {
|
||||||
llvm.debug_info_builder.finalizeSubprogram(llvm.function.getSubprogram() orelse unreachable, llvm.function);
|
llvm.debug_info_builder.finalizeSubprogram(llvm.function.getSubprogram() orelse unreachable, llvm.function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,15 +10,15 @@ const Enum = enum(u32) {
|
|||||||
const main = fn () *!void {
|
const main = fn () *!void {
|
||||||
var result: u32 = 0;
|
var result: u32 = 0;
|
||||||
for (#fields(Enum)) |e| {
|
for (#fields(Enum)) |e| {
|
||||||
//print(#name(e));
|
print(#name(e));
|
||||||
//print(": ");
|
print(": ");
|
||||||
const value: u32 = #cast(e);
|
const value: u32 = #cast(e);
|
||||||
print_usize(value);
|
print_usize(value);
|
||||||
print("\n");
|
print("\n");
|
||||||
result += value;
|
result += value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//try expect(#fields(Enum).length == 3);
|
try expect(#fields(Enum).length == 3);
|
||||||
|
|
||||||
try expect(result == 3);
|
try expect(result == 3);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user