Merge pull request #59 from birth-software/debug-info
debug info implementation
This commit is contained in:
commit
cbd1438781
@ -505,7 +505,7 @@ pub const Type = union(enum) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Instruction = union(enum) {
|
pub const Instruction = union(enum) {
|
||||||
argument_declaration: ArgumentDeclaration,
|
argument_declaration: *Debug.Declaration.Argument,
|
||||||
block: Debug.Block.Index,
|
block: Debug.Block.Index,
|
||||||
// TODO
|
// TODO
|
||||||
call: Instruction.Call,
|
call: Instruction.Call,
|
||||||
@ -516,6 +516,7 @@ pub const Instruction = union(enum) {
|
|||||||
type: Type.Index,
|
type: Type.Index,
|
||||||
},
|
},
|
||||||
debug_checkpoint: DebugCheckPoint,
|
debug_checkpoint: DebugCheckPoint,
|
||||||
|
debug_declare_local_variable: DebugDeclareLocalVariable,
|
||||||
global: *Debug.Declaration.Global,
|
global: *Debug.Declaration.Global,
|
||||||
inline_assembly: InlineAssembly.Index,
|
inline_assembly: InlineAssembly.Index,
|
||||||
integer_binary_operation: Instruction.IntegerBinaryOperation,
|
integer_binary_operation: Instruction.IntegerBinaryOperation,
|
||||||
@ -530,6 +531,10 @@ pub const Instruction = union(enum) {
|
|||||||
syscall: Syscall,
|
syscall: Syscall,
|
||||||
@"unreachable",
|
@"unreachable",
|
||||||
|
|
||||||
|
const DebugDeclareLocalVariable = struct{
|
||||||
|
variable: *Debug.Declaration.Local,
|
||||||
|
stack: Instruction.Index,
|
||||||
|
};
|
||||||
|
|
||||||
const Syscall = struct{
|
const Syscall = struct{
|
||||||
arguments: []const V,
|
arguments: []const V,
|
||||||
@ -654,12 +659,13 @@ pub const Function = struct{
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Struct = struct{
|
pub const Struct = struct{
|
||||||
fields: ArrayList(Field) = .{},
|
fields: ArrayList(Field) = .{},
|
||||||
scope: Debug.Scope.Global,
|
scope: Debug.Scope.Global,
|
||||||
backing_type: Type.Index,
|
backing_type: Type.Index,
|
||||||
|
type: Type.Index,
|
||||||
|
|
||||||
const Field = struct{
|
pub const Field = struct{
|
||||||
name: u32,
|
name: u32,
|
||||||
type: u32,
|
type: u32,
|
||||||
value: V.Comptime,
|
value: V.Comptime,
|
||||||
@ -780,14 +786,16 @@ pub const Debug = struct{
|
|||||||
declaration: *Declaration,
|
declaration: *Declaration,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Local = struct{
|
pub const Local = struct{
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
local_declaration_map: AutoArrayHashMap(*Debug.Declaration.Local, Instruction.Index) = .{},
|
local_declaration_map: AutoArrayHashMap(*Debug.Declaration.Local, Instruction.Index) = .{},
|
||||||
};
|
};
|
||||||
const Global = struct{
|
|
||||||
|
pub const Global = struct{
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
};
|
};
|
||||||
const Function = struct{
|
|
||||||
|
pub const Function = struct{
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
argument_map: AutoArrayHashMap(*Debug.Declaration.Argument, Instruction.Index) = .{},
|
argument_map: AutoArrayHashMap(*Debug.Declaration.Argument, Instruction.Index) = .{},
|
||||||
};
|
};
|
||||||
@ -820,7 +828,7 @@ pub const Debug = struct{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Kind = enum{
|
pub const Kind = enum{
|
||||||
compilation_unit,
|
compilation_unit,
|
||||||
file,
|
file,
|
||||||
file_container,
|
file_container,
|
||||||
@ -1138,7 +1146,10 @@ pub const Builder = struct {
|
|||||||
fn pushScope(builder: *Builder, unit: *Unit, context: *const Context, new_scope: *Debug.Scope) !void {
|
fn pushScope(builder: *Builder, unit: *Unit, context: *const Context, new_scope: *Debug.Scope) !void {
|
||||||
const old_scope = builder.current_scope;
|
const old_scope = builder.current_scope;
|
||||||
|
|
||||||
|
assert(@intFromEnum(old_scope.kind) <= @intFromEnum(new_scope.kind));
|
||||||
|
|
||||||
if (builder.current_basic_block != .null) {
|
if (builder.current_basic_block != .null) {
|
||||||
|
assert(@intFromEnum(old_scope.kind) >= @intFromEnum(Debug.Scope.Kind.function));
|
||||||
const instruction = try unit.instructions.append(context.allocator, .{
|
const instruction = try unit.instructions.append(context.allocator, .{
|
||||||
.push_scope = .{
|
.push_scope = .{
|
||||||
.old = old_scope,
|
.old = old_scope,
|
||||||
@ -1156,6 +1167,8 @@ pub const Builder = struct {
|
|||||||
const old_scope = builder.current_scope;
|
const old_scope = builder.current_scope;
|
||||||
const new_scope = old_scope.parent.?;
|
const new_scope = old_scope.parent.?;
|
||||||
|
|
||||||
|
assert(@intFromEnum(old_scope.kind) >= @intFromEnum(new_scope.kind));
|
||||||
|
|
||||||
if (builder.current_basic_block != .null) {
|
if (builder.current_basic_block != .null) {
|
||||||
const instruction = try unit.instructions.append(context.allocator, .{
|
const instruction = try unit.instructions.append(context.allocator, .{
|
||||||
.pop_scope = .{
|
.pop_scope = .{
|
||||||
@ -1178,6 +1191,14 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn analyzeFile(builder: *Builder, unit: *Unit, context: *const Context, file_index: Debug.File.Index) !void {
|
fn analyzeFile(builder: *Builder, unit: *Unit, context: *const Context, file_index: Debug.File.Index) !void {
|
||||||
|
const old_function = builder.current_function;
|
||||||
|
builder.current_function = .null;
|
||||||
|
defer builder.current_function = old_function;
|
||||||
|
|
||||||
|
const old_basic_block = builder.current_basic_block;
|
||||||
|
defer builder.current_basic_block = old_basic_block;
|
||||||
|
builder.current_basic_block = .null;
|
||||||
|
|
||||||
const old_scope = builder.current_scope;
|
const old_scope = builder.current_scope;
|
||||||
builder.current_scope = &unit.scope.scope;
|
builder.current_scope = &unit.scope.scope;
|
||||||
defer builder.current_scope = old_scope;
|
defer builder.current_scope = old_scope;
|
||||||
@ -1471,7 +1492,7 @@ pub const Builder = struct {
|
|||||||
const function = unit.function_definitions.get(builder.current_function);
|
const function = unit.function_definitions.get(builder.current_function);
|
||||||
|
|
||||||
builder.last_check_point = .{};
|
builder.last_check_point = .{};
|
||||||
|
assert(builder.current_scope.kind == .file_container or builder.current_scope.kind == .file);
|
||||||
try builder.pushScope(unit, context, &function.scope.scope);
|
try builder.pushScope(unit, context, &function.scope.scope);
|
||||||
defer builder.popScope(unit, context) catch unreachable;
|
defer builder.popScope(unit, context) catch unreachable;
|
||||||
|
|
||||||
@ -1479,6 +1500,9 @@ pub const Builder = struct {
|
|||||||
builder.current_basic_block = entry_basic_block;
|
builder.current_basic_block = entry_basic_block;
|
||||||
defer builder.current_basic_block = .null;
|
defer builder.current_basic_block = .null;
|
||||||
|
|
||||||
|
const body_node = unit.getNode(body_node_index);
|
||||||
|
try builder.insertDebugCheckPoint(unit, context, body_node.token);
|
||||||
|
|
||||||
// Get argument declarations into scope
|
// Get argument declarations into scope
|
||||||
const function_prototype_node = unit.getNode(function_prototype_node_index);
|
const function_prototype_node = unit.getNode(function_prototype_node_index);
|
||||||
if (function_prototype_node.left != .null) {
|
if (function_prototype_node.left != .null) {
|
||||||
@ -1516,10 +1540,7 @@ pub const Builder = struct {
|
|||||||
try builder.current_scope.declarations.putNoClobber(context.allocator, argument_name_hash, &argument.declaration);
|
try builder.current_scope.declarations.putNoClobber(context.allocator, argument_name_hash, &argument.declaration);
|
||||||
|
|
||||||
const argument_instruction = try unit.instructions.append(context.allocator, .{
|
const argument_instruction = try unit.instructions.append(context.allocator, .{
|
||||||
.argument_declaration = .{
|
.argument_declaration = argument,
|
||||||
.name = argument.declaration.name,
|
|
||||||
.type = argument.declaration.type,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
try builder.appendInstruction(unit, context, argument_instruction);
|
try builder.appendInstruction(unit, context, argument_instruction);
|
||||||
@ -1528,8 +1549,6 @@ pub const Builder = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const body_node = unit.getNode(body_node_index);
|
|
||||||
|
|
||||||
if (body_node.id == .block) {
|
if (body_node.id == .block) {
|
||||||
function.body = try builder.resolveBlock(unit, context, body_node_index);
|
function.body = try builder.resolveBlock(unit, context, body_node_index);
|
||||||
|
|
||||||
@ -1548,7 +1567,7 @@ pub const Builder = struct {
|
|||||||
log(.compilation, .ir, "{}, {}", .{checkpoint.line, checkpoint.column});
|
log(.compilation, .ir, "{}, {}", .{checkpoint.line, checkpoint.column});
|
||||||
},
|
},
|
||||||
.argument_declaration => |arg|{
|
.argument_declaration => |arg|{
|
||||||
log(.compilation, .ir, "\"{s}\"", .{unit.getIdentifier(arg.name)});
|
log(.compilation, .ir, "\"{s}\"", .{unit.getIdentifier(arg.declaration.name)});
|
||||||
},
|
},
|
||||||
.cast => |cast| {
|
.cast => |cast| {
|
||||||
log(.compilation, .ir, "{s}", .{@tagName(cast.id)});
|
log(.compilation, .ir, "{s}", .{@tagName(cast.id)});
|
||||||
@ -2056,12 +2075,14 @@ pub const Builder = struct {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
.backing_type = backing_type,
|
.backing_type = backing_type,
|
||||||
|
.type = .null,
|
||||||
});
|
});
|
||||||
const struct_type = unit.structs.get(struct_index);
|
const struct_type = unit.structs.get(struct_index);
|
||||||
|
|
||||||
const type_index = try unit.types.append(context.allocator, .{
|
const type_index = try unit.types.append(context.allocator, .{
|
||||||
.@"struct" = struct_index,
|
.@"struct" = struct_index,
|
||||||
});
|
});
|
||||||
|
struct_type.type = type_index;
|
||||||
|
|
||||||
// Save file type
|
// Save file type
|
||||||
switch (builder.current_scope.kind) {
|
switch (builder.current_scope.kind) {
|
||||||
@ -2641,6 +2662,10 @@ pub const Builder = struct {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const block = unit.blocks.get(block_index);
|
const block = unit.blocks.get(block_index);
|
||||||
|
if (builder.current_basic_block != .null) {
|
||||||
|
assert(builder.current_scope.kind == .block or builder.current_scope.kind == .function);
|
||||||
|
}
|
||||||
|
|
||||||
try builder.pushScope(unit, context, &block.scope.scope);
|
try builder.pushScope(unit, context, &block.scope.scope);
|
||||||
defer builder.popScope(unit, context) catch unreachable;
|
defer builder.popScope(unit, context) catch unreachable;
|
||||||
|
|
||||||
@ -2681,6 +2706,12 @@ pub const Builder = struct {
|
|||||||
std.debug.panic("Identifier '{s}' already declarared on scope", .{identifier});
|
std.debug.panic("Identifier '{s}' already declarared on scope", .{identifier});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mutability: Mutability = switch (statement_node.id) {
|
||||||
|
.constant_symbol_declaration => .@"const",
|
||||||
|
.variable_symbol_declaration => .@"var",
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
const metadata_node_index = statement_node.left;
|
const metadata_node_index = statement_node.left;
|
||||||
const value_node_index = statement_node.right;
|
const value_node_index = statement_node.right;
|
||||||
assert(value_node_index != .null);
|
assert(value_node_index != .null);
|
||||||
@ -2700,17 +2731,13 @@ pub const Builder = struct {
|
|||||||
|
|
||||||
const initialization = try builder.resolveRuntimeValue(unit, context, type_expect, value_node_index, .right);
|
const initialization = try builder.resolveRuntimeValue(unit, context, type_expect, value_node_index, .right);
|
||||||
|
|
||||||
|
const emit = !(mutability == .@"const" and initialization.value == .@"comptime");
|
||||||
|
|
||||||
const declaration_type = switch (type_expect) {
|
const declaration_type = switch (type_expect) {
|
||||||
.none => initialization.type,
|
.none => initialization.type,
|
||||||
.type => |type_index| type_index,
|
.type => |type_index| type_index,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutability: Mutability = switch (statement_node.id) {
|
|
||||||
.constant_symbol_declaration => .@"const",
|
|
||||||
.variable_symbol_declaration => .@"var",
|
|
||||||
else => unreachable,
|
|
||||||
};
|
|
||||||
|
|
||||||
const declaration_index = try unit.local_declarations.append(context.allocator, .{
|
const declaration_index = try unit.local_declarations.append(context.allocator, .{
|
||||||
.declaration = .{
|
.declaration = .{
|
||||||
.scope = builder.current_scope,
|
.scope = builder.current_scope,
|
||||||
@ -2726,7 +2753,7 @@ pub const Builder = struct {
|
|||||||
const local_declaration = unit.local_declarations.get(declaration_index);
|
const local_declaration = unit.local_declarations.get(declaration_index);
|
||||||
try builder.current_scope.declarations.putNoClobber(context.allocator, identifier_hash, &local_declaration.declaration);
|
try builder.current_scope.declarations.putNoClobber(context.allocator, identifier_hash, &local_declaration.declaration);
|
||||||
|
|
||||||
if (!(mutability == .@"const" and initialization.value == .@"comptime")) {
|
if (emit) {
|
||||||
const stack = try unit.instructions.append(context.allocator, .{
|
const stack = try unit.instructions.append(context.allocator, .{
|
||||||
.stack_slot = .{
|
.stack_slot = .{
|
||||||
.type = declaration_type,
|
.type = declaration_type,
|
||||||
@ -2737,6 +2764,15 @@ pub const Builder = struct {
|
|||||||
|
|
||||||
try block.scope.local_declaration_map.putNoClobber(context.allocator, local_declaration, stack);
|
try block.scope.local_declaration_map.putNoClobber(context.allocator, local_declaration, stack);
|
||||||
|
|
||||||
|
const debug_declare_local = try unit.instructions.append(context.allocator, .{
|
||||||
|
.debug_declare_local_variable = .{
|
||||||
|
.variable = local_declaration,
|
||||||
|
.stack = stack,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try builder.appendInstruction(unit, context, debug_declare_local);
|
||||||
|
|
||||||
const store = try unit.instructions.append(context.allocator, .{
|
const store = try unit.instructions.append(context.allocator, .{
|
||||||
.store = .{
|
.store = .{
|
||||||
.destination = .{
|
.destination = .{
|
||||||
|
@ -96,6 +96,22 @@ extern "C" void NativityLLVMBuilderSetCurrentDebugLocation(IRBuilder<>& builder,
|
|||||||
builder.SetCurrentDebugLocation(debug_location);
|
builder.SetCurrentDebugLocation(debug_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" DIExpression* NativityLLVMDebugInfoBuilderCreateExpression(DIBuilder& builder, uint64_t* address, size_t length)
|
||||||
|
{
|
||||||
|
auto expr = ArrayRef<uint64_t>(address, length);
|
||||||
|
auto* expression = builder.createExpression(expr);
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" DIGlobalVariableExpression* NativityLLVMDebugInfoBuilderCreateGlobalVariableExpression(DIBuilder& builder, DIScope* scope, const char* name_ptr, size_t name_len, const char* linkage_name_ptr, size_t linkage_name_len, DIFile* file, unsigned line_number, DIType* type, bool is_local_to_unit, bool is_defined, DIExpression* expression, MDNode* declaration, MDTuple* template_parameters, uint32_t alignment)
|
||||||
|
{
|
||||||
|
auto name = StringRef(name_ptr, name_len);
|
||||||
|
auto linkage_name = StringRef(linkage_name_ptr, linkage_name_len);
|
||||||
|
auto annotations = nullptr;
|
||||||
|
auto* global_variable = builder.createGlobalVariableExpression(scope, name, linkage_name, file, line_number, type, is_local_to_unit, is_defined, expression, declaration, template_parameters, alignment, annotations);
|
||||||
|
return global_variable;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" DILocalVariable* NativityLLVMDebugInfoBuilderCreateParameterVariable(DIBuilder& builder, DIScope* scope, const char* name_ptr, size_t name_len, unsigned argument_index, DIFile* file, unsigned line_number, DIType* type, bool always_preserve, DINode::DIFlags flags)
|
extern "C" DILocalVariable* NativityLLVMDebugInfoBuilderCreateParameterVariable(DIBuilder& builder, DIScope* scope, const char* name_ptr, size_t name_len, unsigned argument_index, DIFile* file, unsigned line_number, DIType* type, bool always_preserve, DINode::DIFlags flags)
|
||||||
{
|
{
|
||||||
assert(isa<DILocalScope>(scope));
|
assert(isa<DILocalScope>(scope));
|
||||||
|
@ -27,7 +27,7 @@ pub const LLVM = struct {
|
|||||||
context: *LLVM.Context,
|
context: *LLVM.Context,
|
||||||
module: *LLVM.Module,
|
module: *LLVM.Module,
|
||||||
builder: *LLVM.Builder,
|
builder: *LLVM.Builder,
|
||||||
debug_info_builder: ?*LLVM.DebugInfo.Builder,
|
debug_info_builder: *LLVM.DebugInfo.Builder,
|
||||||
debug_info_file_map: AutoHashMap(Compilation.Debug.File.Index, *LLVM.DebugInfo.File) = .{},
|
debug_info_file_map: AutoHashMap(Compilation.Debug.File.Index, *LLVM.DebugInfo.File) = .{},
|
||||||
debug_type_map: AutoHashMap(Compilation.Type.Index, *LLVM.DebugInfo.Type) = .{},
|
debug_type_map: AutoHashMap(Compilation.Type.Index, *LLVM.DebugInfo.Type) = .{},
|
||||||
type_name_map: AutoHashMap(Compilation.Type.Index, []const u8) = .{},
|
type_name_map: AutoHashMap(Compilation.Type.Index, []const u8) = .{},
|
||||||
@ -43,10 +43,10 @@ pub const LLVM = struct {
|
|||||||
sema_function: *Compilation.Debug.Declaration.Global = undefined,
|
sema_function: *Compilation.Debug.Declaration.Global = undefined,
|
||||||
alloca_map: AutoHashMap(Compilation.Instruction.Index, *LLVM.Value) = .{},
|
alloca_map: AutoHashMap(Compilation.Instruction.Index, *LLVM.Value) = .{},
|
||||||
argument_allocas: AutoHashMap(Compilation.Instruction.Index, *LLVM.Value) = .{},
|
argument_allocas: AutoHashMap(Compilation.Instruction.Index, *LLVM.Value) = .{},
|
||||||
// declaration_names: AutoHashMap(Compilation.Declaration.Index, []const u8) = .{},
|
|
||||||
return_phi_node: ?*LLVM.Value.Instruction.PhiNode = null,
|
return_phi_node: ?*LLVM.Value.Instruction.PhiNode = null,
|
||||||
scope: *LLVM.DebugInfo.Scope = undefined,
|
scope: *LLVM.DebugInfo.Scope = undefined,
|
||||||
file: *LLVM.DebugInfo.File = undefined,
|
file: *LLVM.DebugInfo.File = undefined,
|
||||||
|
subprogram: *LLVM.DebugInfo.Subprogram = undefined,
|
||||||
arg_index: u32 = 0,
|
arg_index: u32 = 0,
|
||||||
inside_branch: bool = false,
|
inside_branch: bool = false,
|
||||||
|
|
||||||
@ -191,6 +191,8 @@ pub const LLVM = struct {
|
|||||||
const createLexicalBlock = bindings.NativityLLVMDebugInfoBuilderCreateLexicalBlock;
|
const createLexicalBlock = bindings.NativityLLVMDebugInfoBuilderCreateLexicalBlock;
|
||||||
const createParameterVariable = bindings.NativityLLVMDebugInfoBuilderCreateParameterVariable;
|
const createParameterVariable = bindings.NativityLLVMDebugInfoBuilderCreateParameterVariable;
|
||||||
const createAutoVariable = bindings.NativityLLVMDebugInfoBuilderCreateAutoVariable;
|
const createAutoVariable = bindings.NativityLLVMDebugInfoBuilderCreateAutoVariable;
|
||||||
|
const createGlobalVariableExpression = bindings.NativityLLVMDebugInfoBuilderCreateGlobalVariableExpression;
|
||||||
|
const createExpression = bindings.NativityLLVMDebugInfoBuilderCreateExpression;
|
||||||
const createBasicType = bindings.NativityLLVMDebugInfoBuilderCreateBasicType;
|
const createBasicType = bindings.NativityLLVMDebugInfoBuilderCreateBasicType;
|
||||||
const createPointerType = bindings.NativityLLVMDebugInfoBuilderCreatePointerType;
|
const createPointerType = bindings.NativityLLVMDebugInfoBuilderCreatePointerType;
|
||||||
const createStructType = bindings.NativityLLVMDebugInfoBuilderCreateStructType;
|
const createStructType = bindings.NativityLLVMDebugInfoBuilderCreateStructType;
|
||||||
@ -222,6 +224,10 @@ pub const LLVM = struct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Expression = opaque{};
|
||||||
|
|
||||||
|
pub const GlobalVariableExpression = opaque{};
|
||||||
|
|
||||||
pub const LocalVariable = opaque {};
|
pub const LocalVariable = opaque {};
|
||||||
pub const LexicalBlock = opaque {
|
pub const LexicalBlock = opaque {
|
||||||
fn toScope(this: *@This()) *Scope {
|
fn toScope(this: *@This()) *Scope {
|
||||||
@ -324,6 +330,10 @@ pub const LLVM = struct {
|
|||||||
|
|
||||||
pub const SubroutineType = opaque {};
|
pub const SubroutineType = opaque {};
|
||||||
pub const Type = opaque {
|
pub const Type = opaque {
|
||||||
|
fn toScope(this: *@This()) *Scope {
|
||||||
|
return @ptrCast(this);
|
||||||
|
}
|
||||||
|
|
||||||
pub const Derived = opaque {
|
pub const Derived = opaque {
|
||||||
fn toType(this: *@This()) *LLVM.DebugInfo.Type {
|
fn toType(this: *@This()) *LLVM.DebugInfo.Type {
|
||||||
return @ptrCast(this);
|
return @ptrCast(this);
|
||||||
@ -345,6 +355,7 @@ pub const LLVM = struct {
|
|||||||
|
|
||||||
pub const Metadata = opaque {
|
pub const Metadata = opaque {
|
||||||
pub const Node = opaque {};
|
pub const Node = opaque {};
|
||||||
|
pub const Tuple = opaque{};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Attribute = enum(u32) {
|
pub const Attribute = enum(u32) {
|
||||||
@ -1085,35 +1096,6 @@ pub const LLVM = struct {
|
|||||||
|
|
||||||
// fn emitDeclaration(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, declaration_index: Compilation.Declaration.Index, maybe_argument: ?*LLVM.Value.Argument) !*LLVM.Value {
|
// fn emitDeclaration(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, declaration_index: Compilation.Declaration.Index, maybe_argument: ?*LLVM.Value.Argument) !*LLVM.Value {
|
||||||
// _ = unit; // autofix
|
// _ = unit; // autofix
|
||||||
// const sema_declaration = llvm.sema.values.declarations.get(declaration_index);
|
|
||||||
// const declaration_name = llvm.sema.getName(sema_declaration.name).?;
|
|
||||||
//
|
|
||||||
// const sema_declaration_type_index = sema_declaration.getType();
|
|
||||||
//
|
|
||||||
// const declaration_type = if (maybe_argument) |argument| blk: {
|
|
||||||
// const argument_value: *LLVM.Value = argument.toValue();
|
|
||||||
// break :blk argument_value.getType();
|
|
||||||
// } else try llvm.getType(sema_declaration_type_index);
|
|
||||||
// const is_volatile = false;
|
|
||||||
//
|
|
||||||
// const initial_value: ?*LLVM.Value = if (maybe_argument) |argument| blk: {
|
|
||||||
// assert(sema_declaration.init_value.invalid);
|
|
||||||
// const argument_value: *LLVM.Value = argument.toValue();
|
|
||||||
// argument_value.setName(declaration_name.ptr, declaration_name.len);
|
|
||||||
// break :blk argument_value;
|
|
||||||
// } else blk: {
|
|
||||||
// if (!sema_declaration.init_value.invalid) {
|
|
||||||
// assert(maybe_argument == null);
|
|
||||||
// break :blk switch (llvm.sema.values.array.get(sema_declaration.init_value).*) {
|
|
||||||
// .undefined => null,
|
|
||||||
// else => try llvm.emitValue(sema_declaration.init_value, sema_declaration.scope_type),
|
|
||||||
// };
|
|
||||||
// } else {
|
|
||||||
// assert(maybe_argument != null);
|
|
||||||
// break :blk null;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// const declaration_value: *Value = switch (sema_declaration.scope_type) {
|
// const declaration_value: *Value = switch (sema_declaration.scope_type) {
|
||||||
// .local => blk: {
|
// .local => blk: {
|
||||||
// const sema_declaration_type = llvm.sema.types.array.get(sema_declaration_type_index);
|
// const sema_declaration_type = llvm.sema.types.array.get(sema_declaration_type_index);
|
||||||
@ -1129,50 +1111,6 @@ pub const LLVM = struct {
|
|||||||
// const declaration_alloca = llvm.builder.createAlloca(declaration_type, address_space, alloca_array_size, declaration_name.ptr, declaration_name.len) orelse return LLVM.Value.Instruction.Error.alloca;
|
// const declaration_alloca = llvm.builder.createAlloca(declaration_type, address_space, alloca_array_size, declaration_name.ptr, declaration_name.len) orelse return LLVM.Value.Instruction.Error.alloca;
|
||||||
// const alloca_value: *LLVM.Value = declaration_alloca.toValue();
|
// const alloca_value: *LLVM.Value = declaration_alloca.toValue();
|
||||||
//
|
//
|
||||||
// const debug_declaration_type = try llvm.getDebugType(sema_declaration.getType());
|
|
||||||
// const always_preserve = true;
|
|
||||||
// const flags = LLVM.DebugInfo.Node.Flags{
|
|
||||||
// .visibility = .none,
|
|
||||||
// .forward_declaration = false,
|
|
||||||
// .apple_block = false,
|
|
||||||
// .block_by_ref_struct = false,
|
|
||||||
// .virtual = false,
|
|
||||||
// .artificial = false,
|
|
||||||
// .explicit = false,
|
|
||||||
// .prototyped = false,
|
|
||||||
// .objective_c_class_complete = false,
|
|
||||||
// .object_pointer = false,
|
|
||||||
// .vector = false,
|
|
||||||
// .static_member = false,
|
|
||||||
// .lvalue_reference = false,
|
|
||||||
// .rvalue_reference = false,
|
|
||||||
// .reserved = false,
|
|
||||||
// .inheritance = .none,
|
|
||||||
// .introduced_virtual = false,
|
|
||||||
// .bit_field = false,
|
|
||||||
// .no_return = false,
|
|
||||||
// .type_pass_by_value = false,
|
|
||||||
// .type_pass_by_reference = false,
|
|
||||||
// .enum_class = false,
|
|
||||||
// .thunk = false,
|
|
||||||
// .non_trivial = false,
|
|
||||||
// .big_endian = false,
|
|
||||||
// .little_endian = false,
|
|
||||||
// .all_calls_described = false,
|
|
||||||
// };
|
|
||||||
// const local_variable = if (maybe_argument) |argument| b: {
|
|
||||||
// const argument_index = argument.getIndex();
|
|
||||||
// const parameter_variable = llvm.debug_info_builder.createParameterVariable(llvm.scope, declaration_name.ptr, declaration_name.len, argument_index + 1, llvm.file, sema_declaration.line, debug_declaration_type, always_preserve, flags) orelse unreachable;
|
|
||||||
// break :b parameter_variable;
|
|
||||||
// } else b: {
|
|
||||||
// // TODO:
|
|
||||||
// const alignment = 0;
|
|
||||||
// const auto_variable = llvm.debug_info_builder.createAutoVariable(llvm.scope, declaration_name.ptr, declaration_name.len, llvm.file, sema_declaration.line, debug_declaration_type, always_preserve, flags, alignment) orelse unreachable;
|
|
||||||
// break :b auto_variable;
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// const insert_declare = llvm.debug_info_builder.insertDeclare(alloca_value, local_variable, llvm.context, sema_declaration.line, sema_declaration.column, (llvm.function.getSubprogram() orelse unreachable).toLocalScope().toScope(), llvm.builder.getInsertBlock() orelse unreachable);
|
|
||||||
// _ = insert_declare;
|
|
||||||
//
|
//
|
||||||
// if (initial_value) |init_value| {
|
// if (initial_value) |init_value| {
|
||||||
// const store = llvm.builder.createStore(init_value, alloca_value, is_volatile) orelse return LLVM.Value.Instruction.Error.store;
|
// const store = llvm.builder.createStore(init_value, alloca_value, is_volatile) orelse return LLVM.Value.Instruction.Error.store;
|
||||||
@ -2447,7 +2385,7 @@ pub const LLVM = struct {
|
|||||||
llvm.scope = previous_scope;
|
llvm.scope = previous_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getDebugInfoFile(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, sema_file_index: Compilation.File.Index) !*DebugInfo.File {
|
fn getDebugInfoFile(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, sema_file_index: Compilation.Debug.File.Index) !*DebugInfo.File {
|
||||||
if (llvm.debug_info_file_map.get(sema_file_index)) |file| {
|
if (llvm.debug_info_file_map.get(sema_file_index)) |file| {
|
||||||
return file;
|
return file;
|
||||||
} else {
|
} else {
|
||||||
@ -2455,7 +2393,7 @@ pub const LLVM = struct {
|
|||||||
const sub_path = std.fs.path.dirname(sema_file.relative_path) orelse "";
|
const sub_path = std.fs.path.dirname(sema_file.relative_path) orelse "";
|
||||||
const file_path = std.fs.path.basename(sema_file.relative_path);
|
const file_path = std.fs.path.basename(sema_file.relative_path);
|
||||||
const directory_path = try std.fs.path.join(context.allocator, &.{ sema_file.package.directory.path, sub_path });
|
const directory_path = try std.fs.path.join(context.allocator, &.{ sema_file.package.directory.path, sub_path });
|
||||||
const debug_file = llvm.debug_info_builder.?.createFile(file_path.ptr, file_path.len, directory_path.ptr, directory_path.len) orelse unreachable;
|
const debug_file = llvm.debug_info_builder.createFile(file_path.ptr, file_path.len, directory_path.ptr, directory_path.len) orelse unreachable;
|
||||||
try llvm.debug_info_file_map.putNoClobber(context.allocator, sema_file_index, debug_file);
|
try llvm.debug_info_file_map.putNoClobber(context.allocator, sema_file_index, debug_file);
|
||||||
return debug_file;
|
return debug_file;
|
||||||
}
|
}
|
||||||
@ -2487,17 +2425,21 @@ pub const LLVM = struct {
|
|||||||
try name.appendSlice(context.allocator, element_type_name);
|
try name.appendSlice(context.allocator, element_type_name);
|
||||||
break :b name.items;
|
break :b name.items;
|
||||||
},
|
},
|
||||||
.@"enum",
|
.@"struct" => b: {
|
||||||
.@"struct",
|
// TODO:
|
||||||
=> b: {
|
break :b "anon1";
|
||||||
if (unit.type_declaration_map.get(sema_type_index)) |type_declaration_index| {
|
|
||||||
const declaration = unit.declarations.get(type_declaration_index);
|
|
||||||
const name = unit.getIdentifier(declaration.name);
|
|
||||||
break :b name;
|
|
||||||
} else {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
// .@"enum",
|
||||||
|
// .@"struct",
|
||||||
|
// => b: {
|
||||||
|
// if (unit.type_declaration_map.get(sema_type_index)) |type_declaration_index| {
|
||||||
|
// const declaration = unit.declarations.get(type_declaration_index);
|
||||||
|
// const name = unit.getIdentifier(declaration.name);
|
||||||
|
// break :b name;
|
||||||
|
// } else {
|
||||||
|
// unreachable;
|
||||||
|
// }
|
||||||
|
// },
|
||||||
// .optional => |optional| b: {
|
// .optional => |optional| b: {
|
||||||
// var name = ArrayList(u8){};
|
// var name = ArrayList(u8){};
|
||||||
// const element_type_name = try llvm.renderTypeName(optional.element_type);
|
// const element_type_name = try llvm.renderTypeName(optional.element_type);
|
||||||
@ -2572,7 +2514,6 @@ pub const LLVM = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn getDebugType(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, sema_type_index: Compilation.Type.Index) !*LLVM.DebugInfo.Type {
|
fn getDebugType(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, sema_type_index: Compilation.Type.Index) !*LLVM.DebugInfo.Type {
|
||||||
if (llvm.debug_info_builder) |di_builder| {
|
|
||||||
if (llvm.debug_type_map.get(sema_type_index)) |t| {
|
if (llvm.debug_type_map.get(sema_type_index)) |t| {
|
||||||
return t;
|
return t;
|
||||||
} else {
|
} else {
|
||||||
@ -2613,14 +2554,14 @@ pub const LLVM = struct {
|
|||||||
.little_endian = false,
|
.little_endian = false,
|
||||||
.all_calls_described = false,
|
.all_calls_described = false,
|
||||||
};
|
};
|
||||||
const integer_type = di_builder.createBasicType(name.ptr, name.len, integer.bit_count, dwarf_encoding, flags) orelse unreachable;
|
const integer_type = llvm.debug_info_builder.createBasicType(name.ptr, name.len, integer.bit_count, dwarf_encoding, flags) orelse unreachable;
|
||||||
break :b integer_type;
|
break :b integer_type;
|
||||||
},
|
},
|
||||||
.pointer => |pointer| b: {
|
.pointer => |pointer| b: {
|
||||||
const element_type = try llvm.getDebugType(unit, context, pointer.type);
|
const element_type = try llvm.getDebugType(unit, context, pointer.type);
|
||||||
const pointer_width = @bitSizeOf(usize);
|
const pointer_width = @bitSizeOf(usize);
|
||||||
const alignment = 0;
|
const alignment = 0;
|
||||||
const pointer_type = di_builder.createPointerType(element_type, pointer_width, alignment, name.ptr, name.len) orelse unreachable;
|
const pointer_type = llvm.debug_info_builder.createPointerType(element_type, pointer_width, alignment, name.ptr, name.len) orelse unreachable;
|
||||||
break :b pointer_type.toType();
|
break :b pointer_type.toType();
|
||||||
},
|
},
|
||||||
.bool => {
|
.bool => {
|
||||||
@ -2653,25 +2594,31 @@ pub const LLVM = struct {
|
|||||||
.little_endian = false,
|
.little_endian = false,
|
||||||
.all_calls_described = false,
|
.all_calls_described = false,
|
||||||
};
|
};
|
||||||
const boolean_type = di_builder.createBasicType("bool", "bool".len, 1, .boolean, flags) orelse unreachable;
|
const boolean_type = llvm.debug_info_builder.createBasicType("bool", "bool".len, 1, .boolean, flags) orelse unreachable;
|
||||||
return boolean_type;
|
return boolean_type;
|
||||||
},
|
},
|
||||||
// // .@"struct" => |struct_index| b: {
|
.@"struct" => |struct_index| b: {
|
||||||
// // const sema_struct_type = unit.structs.get(struct_index);
|
const sema_struct_type = unit.structs.get(struct_index);
|
||||||
// //
|
|
||||||
// // var field_types = try ArrayList(*LLVM.DebugInfo.Type).initCapacity(context.allocator, sema_struct_type.fields.items.len);
|
assert(sema_struct_type.fields.items.len == 0);
|
||||||
// // for (sema_struct_type.fields.items) |struct_field_index| {
|
// var field_types = try ArrayList(*LLVM.DebugInfo.Type).initCapacity(context.allocator, sema_struct_type.fields.items.len);
|
||||||
// // const struct_field = llvm.sema.types.container_fields.get(struct_field_index);
|
for (sema_struct_type.fields.items) |struct_field_index| {
|
||||||
// // const field_type = try llvm.getDebugType(struct_field.type);
|
_ = struct_field_index; // autofix
|
||||||
// // field_types.appendAssumeCapacity(field_type);
|
unreachable;
|
||||||
// // }
|
// const struct_field = unit. .get(struct_field_index);
|
||||||
// // const sema_declaration_index = llvm.sema.map.types.get(sema_type_index) orelse unreachable;
|
// const field_type = try llvm.getDebugType(struct_field.type);
|
||||||
// // const sema_declaration = llvm.sema.values.declarations.get(sema_declaration_index);
|
// field_types.appendAssumeCapacity(field_type);
|
||||||
// // const file = try llvm.getDebugInfoFile(llvm.sema.values.scopes.get(sema_declaration.scope).file);
|
}
|
||||||
// // const line = sema_declaration.line + 1;
|
|
||||||
// // const struct_type = llvm.createDebugStructType(.{ .scope = null, .name = name, .file = file, .line = line, .bitsize = sema_type.getBitSize(llvm.sema), .alignment = 0, .field_types = field_types.items });
|
const fields = &.{};
|
||||||
// // break :b struct_type.toType();
|
// const sema_declaration_index = llvm.sema.map.types.get(sema_type_index) orelse unreachable;
|
||||||
// // },
|
// const sema_declaration = llvm.sema.values.declarations.get(sema_declaration_index);
|
||||||
|
const file = try llvm.getDebugInfoFile(unit, context, sema_struct_type.scope.scope.file);
|
||||||
|
// const line = sema_declaration.line + 1;
|
||||||
|
const line = 0;
|
||||||
|
const struct_type = llvm.createDebugStructType(.{ .scope = null, .name = name, .file = file, .line = line, .bitsize = 0, .alignment = 0, .field_types = fields });
|
||||||
|
break :b struct_type.toType();
|
||||||
|
},
|
||||||
// .@"enum" => |enum_index| b: {
|
// .@"enum" => |enum_index| b: {
|
||||||
// const enum_type = llvm.sema.types.enums.get(enum_index);
|
// const enum_type = llvm.sema.types.enums.get(enum_index);
|
||||||
// var enumerators = try ArrayList(*LLVM.DebugInfo.Type.Enumerator).initCapacity(context.allocator, enum_type.fields.items.len);
|
// var enumerators = try ArrayList(*LLVM.DebugInfo.Type.Enumerator).initCapacity(context.allocator, enum_type.fields.items.len);
|
||||||
@ -2747,12 +2694,8 @@ pub const LLVM = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try llvm.debug_type_map.putNoClobber(context.allocator, sema_type_index, result);
|
try llvm.debug_type_map.putNoClobber(context.allocator, sema_type_index, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emitLeftValue(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, v: Compilation.V) !*LLVM.Value {
|
fn emitLeftValue(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, v: Compilation.V) !*LLVM.Value {
|
||||||
@ -2836,64 +2779,10 @@ pub const LLVM = struct {
|
|||||||
_ = basic_block_index; // autofix
|
_ = basic_block_index; // autofix
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getGlobal(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, global_variable_index: Compilation.GlobalVariable.Index) !*LLVM.Value.Constant.GlobalVariable {
|
fn getScope(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, sema_scope: *Compilation.Debug.Scope) !*LLVM.DebugInfo.Scope {
|
||||||
if (llvm.global_variable_map.get(global_variable_index)) |result| {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
const global_variable_descriptor = unit.global_variables.get(global_variable_index);
|
|
||||||
const is_constant = switch (global_variable_descriptor.mutability) {
|
|
||||||
.@"const" => true,
|
|
||||||
.@"var" => false,
|
|
||||||
};
|
|
||||||
const global_type = try llvm.getType(unit, context, global_variable_descriptor.symbol.type);
|
|
||||||
const name = unit.getIdentifier(global_variable_descriptor.symbol.name);
|
|
||||||
// TODO:
|
|
||||||
const linkage = LLVM.Linkage.@"extern";
|
|
||||||
// Manual lower here to make sure the expression is constant?
|
|
||||||
const initializer = switch (unit.values.get(global_variable_descriptor.value).*) {
|
|
||||||
// .integer => |integer| b: {
|
|
||||||
// const constant_int = try llvm.emitInteger(unit, integer);
|
|
||||||
// const constant = constant_int.toConstant();
|
|
||||||
// break :b constant;
|
|
||||||
// },
|
|
||||||
.undefined => b: {
|
|
||||||
const undefined_value = global_type.getUndefined() orelse unreachable;
|
|
||||||
break :b undefined_value.toConstant();
|
|
||||||
},
|
|
||||||
else => |t| @panic(@tagName(t)),
|
|
||||||
};
|
|
||||||
|
|
||||||
const thread_local_mode = LLVM.ThreadLocalMode.not_thread_local;
|
|
||||||
const externally_initialized = false;
|
|
||||||
const global_variable = llvm.module.addGlobalVariable(global_type, is_constant, linkage, initializer, name.ptr, name.len, null, thread_local_mode, address_space, externally_initialized) orelse return LLVM.Value.Error.constant_int;
|
|
||||||
|
|
||||||
try llvm.global_variable_map.putNoClobber(context.allocator, global_variable_index, global_variable);
|
|
||||||
|
|
||||||
return global_variable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getDeclarationAlloca(llvm: *LLVM, unit: *Compilation.Unit, declaration_index: Compilation.Declaration.Index) !*LLVM.Value {
|
|
||||||
_ = llvm; // autofix
|
|
||||||
_ = unit; // autofix
|
|
||||||
_ = declaration_index; // autofix
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getScope(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, sema_scope: *Compilation.Scope) !*LLVM.DebugInfo.Scope {
|
|
||||||
_ = unit; // autofix
|
|
||||||
_ = context; // autofix
|
|
||||||
switch (sema_scope.kind) {
|
switch (sema_scope.kind) {
|
||||||
.function => {
|
.function, .block, .compilation_unit, => {
|
||||||
if (llvm.scope.toSubprogram()) |_| {
|
return llvm.scope_map.get(sema_scope).?;
|
||||||
return llvm.scope;
|
|
||||||
} else {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.block => {
|
|
||||||
const scope = llvm.scope_map.get(sema_scope).?;
|
|
||||||
return scope;
|
|
||||||
},
|
},
|
||||||
.file => {
|
.file => {
|
||||||
unreachable;
|
unreachable;
|
||||||
@ -2902,13 +2791,14 @@ pub const LLVM = struct {
|
|||||||
if (llvm.scope_map.get(sema_scope)) |scope| {
|
if (llvm.scope_map.get(sema_scope)) |scope| {
|
||||||
return scope;
|
return scope;
|
||||||
} else {
|
} else {
|
||||||
// unit.struct_type_map.get();
|
const global_scope = @fieldParentPtr(Compilation.Debug.Scope.Global, "scope", sema_scope);
|
||||||
unreachable;
|
const struct_type = @fieldParentPtr(Compilation.Struct, "scope", global_scope);
|
||||||
|
const struct_t = try llvm.getDebugType(unit, context, struct_type.type);
|
||||||
|
return struct_t.toScope();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
// const lexical_block = llvm.debug_info_builder.createLexicalBlock(previous_scope, llvm.file, block.line + 1, block.column + 1) orelse unreachable;
|
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -2937,19 +2827,18 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
const module = LLVM.Module.create(@ptrCast(unit.descriptor.name.ptr), unit.descriptor.name.len, llvm_context) orelse return Error.module;
|
const module = LLVM.Module.create(@ptrCast(unit.descriptor.name.ptr), unit.descriptor.name.len, llvm_context) orelse return Error.module;
|
||||||
// TODO:
|
// TODO:
|
||||||
const builder = LLVM.Builder.create(llvm_context) orelse return Error.builder;
|
const builder = LLVM.Builder.create(llvm_context) orelse return Error.builder;
|
||||||
const generate_debug_info = false;
|
|
||||||
|
|
||||||
var llvm = LLVM{
|
var llvm = LLVM{
|
||||||
.context = llvm_context,
|
.context = llvm_context,
|
||||||
.module = module,
|
.module = module,
|
||||||
.builder = builder,
|
.builder = builder,
|
||||||
.debug_info_builder = if (generate_debug_info) module.createDebugInfoBuilder() orelse return Error.debug_info_builder else null,
|
.debug_info_builder = module.createDebugInfoBuilder() orelse return Error.debug_info_builder,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (llvm.debug_info_builder) |debug_info_builder| {
|
if (unit.descriptor.generate_debug_information) {
|
||||||
const filename = "main";
|
const filename = "main";
|
||||||
const directory = ".";
|
const directory = ".";
|
||||||
const debug_info_file = debug_info_builder.createFile(filename, filename.len, directory, directory.len) orelse unreachable;
|
const debug_info_file = llvm.debug_info_builder.createFile(filename, filename.len, directory, directory.len) orelse unreachable;
|
||||||
const producer = "nativity";
|
const producer = "nativity";
|
||||||
const is_optimized = false;
|
const is_optimized = false;
|
||||||
const flags = "";
|
const flags = "";
|
||||||
@ -2963,8 +2852,10 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
const ranges_base_address = false;
|
const ranges_base_address = false;
|
||||||
const sysroot = "";
|
const sysroot = "";
|
||||||
const sdk = "";
|
const sdk = "";
|
||||||
const compile_unit = debug_info_builder.createCompileUnit(LLVM.DebugInfo.Language.c, debug_info_file, producer, producer.len, is_optimized, flags, flags.len, runtime_version, splitname, splitname.len, debug_info_kind, DWOId, split_debug_inlining, debug_info_for_profiling, name_table_kind, ranges_base_address, sysroot, sysroot.len, sdk, sdk.len) orelse unreachable;
|
const compile_unit = llvm.debug_info_builder.createCompileUnit(LLVM.DebugInfo.Language.c, debug_info_file, producer, producer.len, is_optimized, flags, flags.len, runtime_version, splitname, splitname.len, debug_info_kind, DWOId, split_debug_inlining, debug_info_for_profiling, name_table_kind, ranges_base_address, sysroot, sysroot.len, sdk, sdk.len) orelse unreachable;
|
||||||
llvm.scope = compile_unit.toScope();
|
llvm.scope = compile_unit.toScope();
|
||||||
|
|
||||||
|
try llvm.scope_map.putNoClobber(context.allocator, &unit.scope.scope, llvm.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, cache all the global variables
|
// First, cache all the global variables
|
||||||
@ -2984,6 +2875,20 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
const externally_initialized = false;
|
const externally_initialized = false;
|
||||||
const global_variable = llvm.module.addGlobalVariable(global_type, constant, linkage, initializer, name.ptr, name.len, null, thread_local_mode, address_space, externally_initialized) orelse return LLVM.Value.Error.constant_int;
|
const global_variable = llvm.module.addGlobalVariable(global_type, constant, linkage, initializer, name.ptr, name.len, null, thread_local_mode, address_space, externally_initialized) orelse return LLVM.Value.Error.constant_int;
|
||||||
try llvm.global_variable_map.putNoClobber(context.allocator, global_declaration, global_variable);
|
try llvm.global_variable_map.putNoClobber(context.allocator, global_declaration, global_variable);
|
||||||
|
|
||||||
|
if (unit.descriptor.generate_debug_information) {
|
||||||
|
const scope = try llvm.getScope(unit, context, global_declaration.declaration.scope);
|
||||||
|
const file = try llvm.getDebugInfoFile(unit, context, global_declaration.declaration.scope.file);
|
||||||
|
const debug_type = try llvm.getDebugType(unit, context, global_declaration.declaration.type);
|
||||||
|
const is_local_to_unit = !global_declaration.attributes.contains(.@"export");
|
||||||
|
const is_defined = true;
|
||||||
|
const expression = null;
|
||||||
|
const declaration = null;
|
||||||
|
const template_parameters = null;
|
||||||
|
const alignment = 0;
|
||||||
|
const debug_global_variable = llvm.debug_info_builder.createGlobalVariableExpression(scope, name.ptr, name.len, name.ptr, name.len, file, global_declaration.declaration.line, debug_type, is_local_to_unit, is_defined, expression, declaration, template_parameters, alignment) orelse unreachable;
|
||||||
|
_ = debug_global_variable; // autofix
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (llvm.global_variable_map.keys(), llvm.global_variable_map.values()) |global_declaration, global_variable| {
|
for (llvm.global_variable_map.keys(), llvm.global_variable_map.values()) |global_declaration, global_variable| {
|
||||||
@ -3052,63 +2957,69 @@ 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;
|
||||||
const function_prototype = unit.function_prototypes.get(unit.types.get(function_definition.type).function);
|
const function_prototype = unit.function_prototypes.get(unit.types.get(function_definition.type).function);
|
||||||
// if (llvm.debug_info_builder) |di_builder| {
|
|
||||||
// const debug_file = try llvm.getDebugInfoFile(unit, context, sema_declaration.scope.file);
|
if (unit.descriptor.generate_debug_information) {
|
||||||
// var parameter_types = try ArrayList(*LLVM.DebugInfo.Type).initCapacity(context.allocator, function_prototype.argument_types.len);
|
const debug_file = try llvm.getDebugInfoFile(unit, context, function_declaration.declaration.scope.file);
|
||||||
// for (function_prototype.argument_types) |argument_type_index| {
|
var parameter_types = try ArrayList(*LLVM.DebugInfo.Type).initCapacity(context.allocator, function_prototype.argument_types.len);
|
||||||
// const argument_type = try llvm.getDebugType(unit, context, argument_type_index);
|
for (function_prototype.argument_types) |argument_type_index| {
|
||||||
// parameter_types.appendAssumeCapacity(argument_type);
|
const argument_type = try llvm.getDebugType(unit, context, argument_type_index);
|
||||||
// }
|
parameter_types.appendAssumeCapacity(argument_type);
|
||||||
// const subroutine_type_flags = LLVM.DebugInfo.Node.Flags{
|
}
|
||||||
// .visibility = .none,
|
const subroutine_type_flags = LLVM.DebugInfo.Node.Flags{
|
||||||
// .forward_declaration = false,
|
.visibility = .none,
|
||||||
// .apple_block = false,
|
.forward_declaration = false,
|
||||||
// .block_by_ref_struct = false,
|
.apple_block = false,
|
||||||
// .virtual = false,
|
.block_by_ref_struct = false,
|
||||||
// .artificial = false,
|
.virtual = false,
|
||||||
// .explicit = false,
|
.artificial = false,
|
||||||
// .prototyped = false,
|
.explicit = false,
|
||||||
// .objective_c_class_complete = false,
|
.prototyped = false,
|
||||||
// .object_pointer = false,
|
.objective_c_class_complete = false,
|
||||||
// .vector = false,
|
.object_pointer = false,
|
||||||
// .static_member = false,
|
.vector = false,
|
||||||
// .lvalue_reference = false,
|
.static_member = false,
|
||||||
// .rvalue_reference = false,
|
.lvalue_reference = false,
|
||||||
// .reserved = false,
|
.rvalue_reference = false,
|
||||||
// .inheritance = .none,
|
.reserved = false,
|
||||||
// .introduced_virtual = false,
|
.inheritance = .none,
|
||||||
// .bit_field = false,
|
.introduced_virtual = false,
|
||||||
// .no_return = false,
|
.bit_field = false,
|
||||||
// .type_pass_by_value = false,
|
.no_return = false,
|
||||||
// .type_pass_by_reference = false,
|
.type_pass_by_value = false,
|
||||||
// .enum_class = false,
|
.type_pass_by_reference = false,
|
||||||
// .thunk = false,
|
.enum_class = false,
|
||||||
// .non_trivial = false,
|
.thunk = false,
|
||||||
// .big_endian = false,
|
.non_trivial = false,
|
||||||
// .little_endian = false,
|
.big_endian = false,
|
||||||
// .all_calls_described = false,
|
.little_endian = false,
|
||||||
// };
|
.all_calls_described = false,
|
||||||
// const subroutine_type_calling_convention = LLVM.DebugInfo.CallingConvention.none;
|
};
|
||||||
// const subroutine_type = di_builder.createSubroutineType(parameter_types.items.ptr, parameter_types.items.len, subroutine_type_flags, subroutine_type_calling_convention) orelse unreachable;
|
const subroutine_type_calling_convention = LLVM.DebugInfo.CallingConvention.none;
|
||||||
// const scope_line = 0;
|
const subroutine_type = llvm.debug_info_builder.createSubroutineType(parameter_types.items.ptr, parameter_types.items.len, subroutine_type_flags, subroutine_type_calling_convention) orelse unreachable;
|
||||||
// const subprogram_flags = LLVM.DebugInfo.Subprogram.Flags{
|
const scope_line = 0;
|
||||||
// .virtuality = .none,
|
const subprogram_flags = LLVM.DebugInfo.Subprogram.Flags{
|
||||||
// .local_to_unit = true,
|
.virtuality = .none,
|
||||||
// .definition = true,
|
.local_to_unit = true,
|
||||||
// .optimized = false,
|
.definition = true,
|
||||||
// .pure = false,
|
.optimized = false,
|
||||||
// .elemental = false,
|
.pure = false,
|
||||||
// .recursive = false,
|
.elemental = false,
|
||||||
// .main_subprogram = false,
|
.recursive = false,
|
||||||
// .deleted = false,
|
.main_subprogram = false,
|
||||||
// .object_c_direct = false,
|
.deleted = false,
|
||||||
// };
|
.object_c_direct = false,
|
||||||
// const subprogram_declaration = null;
|
};
|
||||||
// const subprogram = di_builder.createFunction(debug_file.toScope(), name.ptr, name.len, name.ptr, name.len, debug_file, sema_declaration.line + 1, subroutine_type, scope_line, subroutine_type_flags, subprogram_flags, subprogram_declaration) orelse unreachable;
|
const subprogram_declaration = null;
|
||||||
// llvm.function.setSubprogram(subprogram);
|
const name = unit.getIdentifier(function_declaration.declaration.name);
|
||||||
// llvm.file = subprogram.getFile() orelse unreachable;
|
const subprogram = llvm.debug_info_builder.createFunction(debug_file.toScope(), name.ptr, name.len, name.ptr, name.len, debug_file, function_declaration.declaration.line + 1, subroutine_type, scope_line, subroutine_type_flags, subprogram_flags, subprogram_declaration) orelse unreachable;
|
||||||
// llvm.scope = subprogram.toLocalScope().toScope();
|
llvm.function.setSubprogram(subprogram);
|
||||||
// }
|
llvm.file = subprogram.getFile() orelse unreachable;
|
||||||
|
llvm.subprogram = subprogram;
|
||||||
|
llvm.scope = subprogram.toLocalScope().toScope();
|
||||||
|
|
||||||
|
try llvm.scope_map.putNoClobber(context.allocator, &function_definition.scope.scope, llvm.scope);
|
||||||
|
}
|
||||||
|
|
||||||
llvm.arg_index = 0;
|
llvm.arg_index = 0;
|
||||||
llvm.alloca_map.clearRetainingCapacity();
|
llvm.alloca_map.clearRetainingCapacity();
|
||||||
|
|
||||||
@ -3122,17 +3033,32 @@ 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| {
|
||||||
_ = push_scope; // autofix
|
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));
|
||||||
// const lexical_block = llvm.debug_info_builder.createLexicalBlock(old_scope, llvm.file, push_scope.new.line + 1, push_scope.new.column + 1) orelse unreachable;
|
|
||||||
// try llvm.scope_map.putNoClobber(context.allocator, push_scope.new, lexical_block.toScope());
|
const lexical_block = llvm.debug_info_builder.createLexicalBlock(old_scope, llvm.file, push_scope.new.line + 1, push_scope.new.column + 1) orelse unreachable;
|
||||||
// llvm.scope = lexical_block.toScope();
|
try llvm.scope_map.putNoClobber(context.allocator, push_scope.new, lexical_block.toScope());
|
||||||
|
llvm.scope = lexical_block.toScope();
|
||||||
|
},
|
||||||
|
.pop_scope => |pop_scope| {
|
||||||
|
const old = try llvm.getScope(unit, context, pop_scope.old);
|
||||||
|
assert(llvm.scope == old);
|
||||||
|
const new = try llvm.getScope(unit, context, pop_scope.new);
|
||||||
|
if (pop_scope.new.kind == .function) {
|
||||||
|
assert(new.toSubprogram() orelse unreachable == llvm.subprogram);
|
||||||
|
}
|
||||||
|
llvm.scope = new;
|
||||||
|
var scope = pop_scope.old;
|
||||||
|
while (scope.kind != .function) {
|
||||||
|
scope = scope.parent.?;
|
||||||
|
}
|
||||||
|
const subprogram_scope = try llvm.getScope(unit, context, scope);
|
||||||
|
assert(llvm.subprogram == subprogram_scope.toSubprogram() orelse unreachable);
|
||||||
},
|
},
|
||||||
.debug_checkpoint => |debug_checkpoint| {
|
.debug_checkpoint => |debug_checkpoint| {
|
||||||
_ = debug_checkpoint; // autofix
|
const scope = try llvm.getScope(unit, context, debug_checkpoint.scope);
|
||||||
// const scope = try llvm.getScope(unit, context, debug_checkpoint.scope);
|
assert(scope == llvm.scope);
|
||||||
// assert(scope == llvm.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);
|
|
||||||
},
|
},
|
||||||
.inline_assembly => |inline_assembly_index| {
|
.inline_assembly => |inline_assembly_index| {
|
||||||
const assembly_block = unit.inline_assembly.get(inline_assembly_index);
|
const assembly_block = unit.inline_assembly.get(inline_assembly_index);
|
||||||
@ -3210,37 +3136,6 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
const call = llvm.builder.createCall(function_type, inline_assembly.toValue(), operand_values.items.ptr, operand_values.items.len, "", "".len, null) orelse return LLVM.Value.Instruction.Error.call;
|
const call = llvm.builder.createCall(function_type, inline_assembly.toValue(), operand_values.items.ptr, operand_values.items.len, "", "".len, null) orelse return LLVM.Value.Instruction.Error.call;
|
||||||
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, call.toValue());
|
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, call.toValue());
|
||||||
},
|
},
|
||||||
.pop_scope => {},
|
|
||||||
.argument_declaration => |argument_declaration| {
|
|
||||||
var argument_buffer: [16]*LLVM.Value.Argument = undefined;
|
|
||||||
var argument_count: usize = argument_buffer.len;
|
|
||||||
llvm.function.getArguments(&argument_buffer, &argument_count);
|
|
||||||
const arguments = argument_buffer[0..argument_count];
|
|
||||||
const argument = arguments[llvm.arg_index];
|
|
||||||
llvm.arg_index += 1;
|
|
||||||
const name = unit.getIdentifier(argument_declaration.name);
|
|
||||||
argument.toValue().setName(name.ptr, name.len);
|
|
||||||
const argument_type_index = argument_declaration.type;
|
|
||||||
switch (unit.types.get(argument_type_index).*) {
|
|
||||||
.void, .noreturn, .type => unreachable,
|
|
||||||
.comptime_int => unreachable,
|
|
||||||
.bool => unreachable,
|
|
||||||
.@"struct" => {},
|
|
||||||
.@"enum" => {},
|
|
||||||
.function => unreachable,
|
|
||||||
.integer => {},
|
|
||||||
.pointer => {},
|
|
||||||
}
|
|
||||||
const argument_type = argument.toValue().getType();
|
|
||||||
const alloca_array_size: ?*LLVM.Value = null;
|
|
||||||
const argument_value = argument.toValue();
|
|
||||||
const declaration_alloca = llvm.builder.createAlloca(argument_type, address_space, alloca_array_size, "", "".len) orelse return LLVM.Value.Instruction.Error.alloca;
|
|
||||||
const is_volatile = false;
|
|
||||||
const store = llvm.builder.createStore(argument_value, declaration_alloca.toValue(), is_volatile) orelse return LLVM.Value.Instruction.Error.store;
|
|
||||||
_ = store; // autofix
|
|
||||||
try llvm.argument_allocas.putNoClobber(context.allocator, instruction_index, declaration_alloca.toValue());
|
|
||||||
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, declaration_alloca.toValue());
|
|
||||||
},
|
|
||||||
.stack_slot => |stack_slot| {
|
.stack_slot => |stack_slot| {
|
||||||
switch (unit.types.get(stack_slot.type).*) {
|
switch (unit.types.get(stack_slot.type).*) {
|
||||||
.void, .noreturn, .type => unreachable,
|
.void, .noreturn, .type => unreachable,
|
||||||
@ -3401,6 +3296,124 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
.@"unreachable" => {
|
.@"unreachable" => {
|
||||||
_ = llvm.builder.createUnreachable() orelse return LLVM.Value.Instruction.Error.@"unreachable";
|
_ = llvm.builder.createUnreachable() orelse return LLVM.Value.Instruction.Error.@"unreachable";
|
||||||
},
|
},
|
||||||
|
.argument_declaration => |argument_declaration| {
|
||||||
|
var argument_buffer: [16]*LLVM.Value.Argument = undefined;
|
||||||
|
var argument_count: usize = argument_buffer.len;
|
||||||
|
llvm.function.getArguments(&argument_buffer, &argument_count);
|
||||||
|
const arguments = argument_buffer[0..argument_count];
|
||||||
|
const argument_index = llvm.arg_index;
|
||||||
|
llvm.arg_index += 1;
|
||||||
|
const argument = arguments[argument_index];
|
||||||
|
const name = unit.getIdentifier(argument_declaration.declaration.name);
|
||||||
|
argument.toValue().setName(name.ptr, name.len);
|
||||||
|
const argument_type_index = argument_declaration.declaration.type;
|
||||||
|
switch (unit.types.get(argument_type_index).*) {
|
||||||
|
.void, .noreturn, .type => unreachable,
|
||||||
|
.comptime_int => unreachable,
|
||||||
|
.bool => unreachable,
|
||||||
|
.@"struct" => {},
|
||||||
|
.@"enum" => {},
|
||||||
|
.function => unreachable,
|
||||||
|
.integer => {},
|
||||||
|
.pointer => {},
|
||||||
|
}
|
||||||
|
const argument_type = argument.toValue().getType();
|
||||||
|
const alloca_array_size: ?*LLVM.Value = null;
|
||||||
|
const argument_value = argument.toValue();
|
||||||
|
const declaration_alloca = llvm.builder.createAlloca(argument_type, address_space, alloca_array_size, "", "".len) orelse return LLVM.Value.Instruction.Error.alloca;
|
||||||
|
|
||||||
|
if (unit.descriptor.generate_debug_information) {
|
||||||
|
const debug_declaration_type = try llvm.getDebugType(unit, context, argument_declaration.declaration.type);
|
||||||
|
const always_preserve = true;
|
||||||
|
const flags = LLVM.DebugInfo.Node.Flags{
|
||||||
|
.visibility = .none,
|
||||||
|
.forward_declaration = false,
|
||||||
|
.apple_block = false,
|
||||||
|
.block_by_ref_struct = false,
|
||||||
|
.virtual = false,
|
||||||
|
.artificial = false,
|
||||||
|
.explicit = false,
|
||||||
|
.prototyped = false,
|
||||||
|
.objective_c_class_complete = false,
|
||||||
|
.object_pointer = false,
|
||||||
|
.vector = false,
|
||||||
|
.static_member = false,
|
||||||
|
.lvalue_reference = false,
|
||||||
|
.rvalue_reference = false,
|
||||||
|
.reserved = false,
|
||||||
|
.inheritance = .none,
|
||||||
|
.introduced_virtual = false,
|
||||||
|
.bit_field = false,
|
||||||
|
.no_return = false,
|
||||||
|
.type_pass_by_value = false,
|
||||||
|
.type_pass_by_reference = false,
|
||||||
|
.enum_class = false,
|
||||||
|
.thunk = false,
|
||||||
|
.non_trivial = false,
|
||||||
|
.big_endian = false,
|
||||||
|
.little_endian = false,
|
||||||
|
.all_calls_described = false,
|
||||||
|
};
|
||||||
|
const declaration_name = unit.getIdentifier(argument_declaration.declaration.name);
|
||||||
|
const line = argument_declaration.declaration.line;
|
||||||
|
const column = argument_declaration.declaration.column;
|
||||||
|
const debug_parameter_variable = llvm.debug_info_builder.createParameterVariable(llvm.scope, declaration_name.ptr, declaration_name.len, argument_index, llvm.file, line, debug_declaration_type, always_preserve, flags) orelse unreachable;
|
||||||
|
|
||||||
|
const insert_declare = llvm.debug_info_builder.insertDeclare(declaration_alloca.toValue(), debug_parameter_variable, llvm.context, line, column, (llvm.function.getSubprogram() orelse unreachable).toLocalScope().toScope(), llvm.builder.getInsertBlock() orelse unreachable);
|
||||||
|
_ = insert_declare;
|
||||||
|
}
|
||||||
|
|
||||||
|
const is_volatile = false;
|
||||||
|
const store = llvm.builder.createStore(argument_value, declaration_alloca.toValue(), is_volatile) orelse return LLVM.Value.Instruction.Error.store;
|
||||||
|
_ = store; // autofix
|
||||||
|
try llvm.argument_allocas.putNoClobber(context.allocator, instruction_index, declaration_alloca.toValue());
|
||||||
|
try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, declaration_alloca.toValue());
|
||||||
|
},
|
||||||
|
.debug_declare_local_variable => |declare_local_variable| {
|
||||||
|
const local_variable = declare_local_variable.variable;
|
||||||
|
const debug_declaration_type = try llvm.getDebugType(unit, context, local_variable.declaration.type);
|
||||||
|
const always_preserve = true;
|
||||||
|
const flags = LLVM.DebugInfo.Node.Flags{
|
||||||
|
.visibility = .none,
|
||||||
|
.forward_declaration = false,
|
||||||
|
.apple_block = false,
|
||||||
|
.block_by_ref_struct = false,
|
||||||
|
.virtual = false,
|
||||||
|
.artificial = false,
|
||||||
|
.explicit = false,
|
||||||
|
.prototyped = false,
|
||||||
|
.objective_c_class_complete = false,
|
||||||
|
.object_pointer = false,
|
||||||
|
.vector = false,
|
||||||
|
.static_member = false,
|
||||||
|
.lvalue_reference = false,
|
||||||
|
.rvalue_reference = false,
|
||||||
|
.reserved = false,
|
||||||
|
.inheritance = .none,
|
||||||
|
.introduced_virtual = false,
|
||||||
|
.bit_field = false,
|
||||||
|
.no_return = false,
|
||||||
|
.type_pass_by_value = false,
|
||||||
|
.type_pass_by_reference = false,
|
||||||
|
.enum_class = false,
|
||||||
|
.thunk = false,
|
||||||
|
.non_trivial = false,
|
||||||
|
.big_endian = false,
|
||||||
|
.little_endian = false,
|
||||||
|
.all_calls_described = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const alignment = 0;
|
||||||
|
const declaration_name = unit.getIdentifier(local_variable.declaration.name);
|
||||||
|
const line = local_variable.declaration.line;
|
||||||
|
const column = local_variable.declaration.column;
|
||||||
|
const debug_local_variable = llvm.debug_info_builder.createAutoVariable(llvm.scope, declaration_name.ptr, declaration_name.len, llvm.file, line, debug_declaration_type, always_preserve, flags, alignment) orelse unreachable;
|
||||||
|
|
||||||
|
const local = llvm.alloca_map.get(declare_local_variable.stack).?;
|
||||||
|
|
||||||
|
const insert_declare = llvm.debug_info_builder.insertDeclare(local, debug_local_variable, llvm.context, line, column, (llvm.function.getSubprogram() orelse unreachable).toLocalScope().toScope(), llvm.builder.getInsertBlock() orelse unreachable);
|
||||||
|
_ = insert_declare;
|
||||||
|
},
|
||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3416,25 +3429,23 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const verify_function = true;
|
// const verify_function = true;
|
||||||
if (verify_function) {
|
// if (verify_function) {
|
||||||
var message_ptr: [*]const u8 = undefined;
|
// var message_ptr: [*]const u8 = undefined;
|
||||||
var message_len: usize = 0;
|
// var message_len: usize = 0;
|
||||||
const result = llvm.function.verify(&message_ptr, &message_len);
|
// const result = llvm.function.verify(&message_ptr, &message_len);
|
||||||
|
//
|
||||||
if (!result) {
|
// if (!result) {
|
||||||
var function_len: usize = 0;
|
// var function_len: usize = 0;
|
||||||
const function_ptr = llvm.function.toString(&function_len);
|
// const function_ptr = llvm.function.toString(&function_len);
|
||||||
const function_ir = function_ptr[0..function_len];
|
// const function_ir = function_ptr[0..function_len];
|
||||||
const error_message = message_ptr[0..message_len];
|
// const error_message = message_ptr[0..message_len];
|
||||||
std.debug.panic("\n{s}. LLVM verification for the function above failed:\n{s}\n", .{ function_ir, error_message });
|
// std.debug.panic("\n{s}. LLVM verification for the function above failed:\n{s}\n", .{ function_ir, error_message });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (llvm.debug_info_builder) |di_builder| {
|
llvm.debug_info_builder.finalize();
|
||||||
di_builder.finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
var module_len: usize = 0;
|
var module_len: usize = 0;
|
||||||
const module_ptr = llvm.module.toString(&module_len);
|
const module_ptr = llvm.module.toString(&module_len);
|
||||||
@ -3447,6 +3458,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
var message_len: usize = 0;
|
var message_len: usize = 0;
|
||||||
const result = llvm.module.verify(&message_ptr, &message_len);
|
const result = llvm.module.verify(&message_ptr, &message_len);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
std.debug.print("{s}\n", .{module_string});
|
||||||
std.debug.panic("LLVM module verification failed:\n{s}\n", .{message_ptr[0..message_len]});
|
std.debug.panic("LLVM module verification failed:\n{s}\n", .{message_ptr[0..message_len]});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3485,8 +3497,6 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
|
|||||||
try arguments.append(context.allocator, "14");
|
try arguments.append(context.allocator, "14");
|
||||||
try arguments.append(context.allocator, "-arch");
|
try arguments.append(context.allocator, "-arch");
|
||||||
try arguments.append(context.allocator, "arm64");
|
try arguments.append(context.allocator, "arm64");
|
||||||
try arguments.append(context.allocator, "-lSystem");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var stdout_ptr: [*]const u8 = undefined;
|
var stdout_ptr: [*]const u8 = undefined;
|
||||||
|
@ -17,9 +17,13 @@ pub extern fn NativityLLVMDebugInfoBuilderCreateCompileUnit(builder: *LLVM.Debug
|
|||||||
pub extern fn NativityLLVMDebugInfoBuilderCreateFunction(builder: *LLVM.DebugInfo.Builder, scope: *LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, linkage_name_ptr: [*]const u8, linkage_name_len: usize, file: *LLVM.DebugInfo.File, line_number: c_uint, type: *LLVM.DebugInfo.SubroutineType, scope_line: c_uint, flags: LLVM.DebugInfo.Node.Flags, subprogram_flags: LLVM.DebugInfo.Subprogram.Flags, declaration: ?*LLVM.DebugInfo.Subprogram) ?*LLVM.DebugInfo.Subprogram;
|
pub extern fn NativityLLVMDebugInfoBuilderCreateFunction(builder: *LLVM.DebugInfo.Builder, scope: *LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, linkage_name_ptr: [*]const u8, linkage_name_len: usize, file: *LLVM.DebugInfo.File, line_number: c_uint, type: *LLVM.DebugInfo.SubroutineType, scope_line: c_uint, flags: LLVM.DebugInfo.Node.Flags, subprogram_flags: LLVM.DebugInfo.Subprogram.Flags, declaration: ?*LLVM.DebugInfo.Subprogram) ?*LLVM.DebugInfo.Subprogram;
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderCreateSubroutineType(builder: *LLVM.DebugInfo.Builder, parameter_types_ptr: [*]const *LLVM.DebugInfo.Type, parameter_type_count: usize, flags: LLVM.DebugInfo.Node.Flags, calling_convention: LLVM.DebugInfo.CallingConvention) ?*LLVM.DebugInfo.SubroutineType;
|
pub extern fn NativityLLVMDebugInfoBuilderCreateSubroutineType(builder: *LLVM.DebugInfo.Builder, parameter_types_ptr: [*]const *LLVM.DebugInfo.Type, parameter_type_count: usize, flags: LLVM.DebugInfo.Node.Flags, calling_convention: LLVM.DebugInfo.CallingConvention) ?*LLVM.DebugInfo.SubroutineType;
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderCreateLexicalBlock(builder: *LLVM.DebugInfo.Builder, parent_scope: *LLVM.DebugInfo.Scope, parent_file: *LLVM.DebugInfo.File, line: c_uint, column: c_uint) ?*LLVM.DebugInfo.LexicalBlock;
|
pub extern fn NativityLLVMDebugInfoBuilderCreateLexicalBlock(builder: *LLVM.DebugInfo.Builder, parent_scope: *LLVM.DebugInfo.Scope, parent_file: *LLVM.DebugInfo.File, line: c_uint, column: c_uint) ?*LLVM.DebugInfo.LexicalBlock;
|
||||||
|
|
||||||
|
pub extern fn NativityLLVMDebugInfoBuilderCreateExpression(builder: *LLVM.DebugInfo.Builder, address: [*]const u64, length: usize) *LLVM.DebugInfo.Expression;
|
||||||
|
pub extern fn NativityLLVMDebugInfoBuilderCreateGlobalVariableExpression(builder: *LLVM.DebugInfo.Builder, scope: *LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, linkage_name_ptr: [*]const u8, linkage_name_len: usize, file: *LLVM.DebugInfo.File, line_number: c_uint, type: *LLVM.DebugInfo.Type, is_local_to_unit: bool, is_defined: bool, expression: ?*LLVM.DebugInfo.Expression, declaration: ?*LLVM.Metadata.Node, template_parameters: ?*LLVM.Metadata.Tuple, alignment: u32) ?*LLVM.DebugInfo.GlobalVariableExpression;
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderCreateParameterVariable(builder: *LLVM.DebugInfo.Builder, scope: *LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, argument_index: c_uint, file: *LLVM.DebugInfo.File, line_number: c_uint, type: *LLVM.DebugInfo.Type, always_preserve: bool, flags: LLVM.DebugInfo.Node.Flags) ?*LLVM.DebugInfo.LocalVariable;
|
pub extern fn NativityLLVMDebugInfoBuilderCreateParameterVariable(builder: *LLVM.DebugInfo.Builder, scope: *LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, argument_index: c_uint, file: *LLVM.DebugInfo.File, line_number: c_uint, type: *LLVM.DebugInfo.Type, always_preserve: bool, flags: LLVM.DebugInfo.Node.Flags) ?*LLVM.DebugInfo.LocalVariable;
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderCreateAutoVariable(builder: *LLVM.DebugInfo.Builder, scope: *LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, file: *LLVM.DebugInfo.File, line_number: c_uint, type: *LLVM.DebugInfo.Type, always_preserve: bool, flags: LLVM.DebugInfo.Node.Flags, alignment: u32) ?*LLVM.DebugInfo.LocalVariable; // 0 means 1 << 0 (alignment of 1)
|
pub extern fn NativityLLVMDebugInfoBuilderCreateAutoVariable(builder: *LLVM.DebugInfo.Builder, scope: *LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, file: *LLVM.DebugInfo.File, line_number: c_uint, type: *LLVM.DebugInfo.Type, always_preserve: bool, flags: LLVM.DebugInfo.Node.Flags, alignment: u32) ?*LLVM.DebugInfo.LocalVariable; // 0 means 1 << 0 (alignment of 1)
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderInsertDeclare(builder: *LLVM.DebugInfo.Builder, pointer: *LLVM.Value, local_variable: *LLVM.DebugInfo.LocalVariable, context: *LLVM.Context, line: c_uint, column: c_uint, scope: *LLVM.DebugInfo.Scope, basic_block: *LLVM.Value.BasicBlock) ?*LLVM.Value.Instruction;
|
pub extern fn NativityLLVMDebugInfoBuilderInsertDeclare(builder: *LLVM.DebugInfo.Builder, pointer: *LLVM.Value, local_variable: *LLVM.DebugInfo.LocalVariable, context: *LLVM.Context, line: c_uint, column: c_uint, scope: *LLVM.DebugInfo.Scope, basic_block: *LLVM.Value.BasicBlock) ?*LLVM.Value.Instruction;
|
||||||
|
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderCreateBasicType(builder: *LLVM.DebugInfo.Builder, name_ptr: [*]const u8, name_len: usize, bit_count: u64, dwarf_encoding: LLVM.DebugInfo.AttributeType, flags: LLVM.DebugInfo.Node.Flags) ?*LLVM.DebugInfo.Type;
|
pub extern fn NativityLLVMDebugInfoBuilderCreateBasicType(builder: *LLVM.DebugInfo.Builder, name_ptr: [*]const u8, name_len: usize, bit_count: u64, dwarf_encoding: LLVM.DebugInfo.AttributeType, flags: LLVM.DebugInfo.Node.Flags) ?*LLVM.DebugInfo.Type;
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderCreatePointerType(builder: *LLVM.DebugInfo.Builder, element_type: *LLVM.DebugInfo.Type, pointer_bit_count: u64, alignment: u32, name_ptr: [*]const u8, name_len: usize) ?*LLVM.DebugInfo.Type.Derived;
|
pub extern fn NativityLLVMDebugInfoBuilderCreatePointerType(builder: *LLVM.DebugInfo.Builder, element_type: *LLVM.DebugInfo.Type, pointer_bit_count: u64, alignment: u32, name_ptr: [*]const u8, name_len: usize) ?*LLVM.DebugInfo.Type.Derived;
|
||||||
pub extern fn NativityLLVMDebugInfoBuilderCreateStructType(builder: *LLVM.DebugInfo.Builder, scope: ?*LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, file: ?*LLVM.DebugInfo.File, line_number: c_uint, bit_count: u64, alignment: u32, flags: LLVM.DebugInfo.Node.Flags, derived_from: ?*LLVM.DebugInfo.Type, element_type_ptr: [*]const *LLVM.DebugInfo.Type, element_type_count: usize) ?*LLVM.DebugInfo.Type.Composite;
|
pub extern fn NativityLLVMDebugInfoBuilderCreateStructType(builder: *LLVM.DebugInfo.Builder, scope: ?*LLVM.DebugInfo.Scope, name_ptr: [*]const u8, name_len: usize, file: ?*LLVM.DebugInfo.File, line_number: c_uint, bit_count: u64, alignment: u32, flags: LLVM.DebugInfo.Node.Flags, derived_from: ?*LLVM.DebugInfo.Type, element_type_ptr: [*]const *LLVM.DebugInfo.Type, element_type_count: usize) ?*LLVM.DebugInfo.Type.Composite;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user