Get debug info working very preliminarily

This commit is contained in:
Sofia 2025-07-18 17:26:11 +03:00
parent 287ab69d32
commit 1967cadbc0
5 changed files with 83 additions and 13 deletions

View File

@ -2,7 +2,10 @@
//! LLIR ([`Context`]) into LLVM IR. This module is the only one that interfaces
//! with the LLVM API.
use std::{collections::HashMap, ptr::null_mut};
use std::{
collections::HashMap,
ptr::{null, null_mut},
};
use llvm_sys::{
LLVMIntPredicate, LLVMLinkage,
@ -203,6 +206,7 @@ pub struct LLVMDebugInformation<'a> {
types: &'a mut HashMap<DebugTypeValue, LLVMMetadataRef>,
programs: &'a mut HashMap<DebugProgramValue, LLVMMetadataRef>,
metadata: &'a mut HashMap<DebugMetadataValue, LLVMMetadataRef>,
locations: &'a mut HashMap<DebugLocationValue, LLVMMetadataRef>,
}
#[derive(Clone, Copy)]
@ -230,6 +234,7 @@ impl ModuleHolder {
let mut types = HashMap::new();
let mut metadata = HashMap::new();
let mut programs = HashMap::new();
let mut locations = HashMap::new();
let mut debug = if let Some(debug) = &self.debug_information {
let di_builder = LLVMCreateDIBuilder(module_ref);
@ -293,6 +298,7 @@ impl ModuleHolder {
types: &mut types,
metadata: &mut metadata,
programs: &mut programs,
locations: &mut locations,
};
for ty in debug.debug.get_types().borrow().iter() {
@ -322,6 +328,11 @@ impl ModuleHolder {
}
if let Some(debug) = &mut debug {
for location in debug.debug.get_locations().borrow().iter() {
let location_ref = location.compile(context, &debug);
debug.locations.insert(location.value, location_ref);
}
for meta in debug.debug.get_metadata().borrow().iter() {
let meta_ref = meta.compile(&debug);
debug.metadata.insert(meta.value.clone(), meta_ref);
@ -353,6 +364,24 @@ impl ModuleHolder {
}
}
impl DebugLocationHolder {
unsafe fn compile(
&self,
context: &LLVMContext,
debug: &LLVMDebugInformation,
) -> LLVMMetadataRef {
unsafe {
LLVMDIBuilderCreateDebugLocation(
context.context_ref,
self.location.line,
self.location.column,
*debug.programs.get(&self.program).unwrap(),
null_mut(),
)
}
}
}
impl DebugScopeHolder {
unsafe fn compile_scope(
&self,
@ -761,6 +790,7 @@ impl InstructionHolder {
}
}
};
if let Some(location_value) = &self.data.location {}
LLVMValue {
_ty,
value_ref: val,

View File

@ -6,7 +6,7 @@ use std::{
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct DebugScopeValue(pub Vec<usize>);
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct DebugLocationValue(pub DebugProgramValue, pub usize);
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
@ -54,8 +54,9 @@ pub struct DebugSubprogramHolder {
#[derive(Debug, Clone)]
pub(crate) struct DebugLocationHolder {
value: DebugLocationValue,
location: DebugLocation,
pub(crate) program: DebugProgramValue,
pub(crate) value: DebugLocationValue,
pub(crate) location: DebugLocation,
}
#[derive(Debug, Clone)]
@ -118,13 +119,13 @@ impl DebugInformation {
pub fn location(
&self,
program_value: &DebugProgramValue,
line: u32,
column: u32,
location: DebugLocation,
) -> DebugLocationValue {
let value = DebugLocationValue(program_value.clone(), self.locations.borrow().len());
let location = DebugLocationHolder {
program: *program_value,
value: value.clone(),
location: DebugLocation { line, column },
location,
};
self.locations.borrow_mut().push(location);
value
@ -184,6 +185,10 @@ impl DebugInformation {
self.types.clone()
}
pub fn get_locations(&self) -> Rc<RefCell<Vec<DebugLocationHolder>>> {
self.locations.clone()
}
pub fn get_subprogram_data(&self, value: &DebugProgramValue) -> DebugSubprogramData {
unsafe {
self.programs

View File

@ -250,6 +250,28 @@ impl<'builder> Block<'builder> {
}
}
impl InstructionValue {
pub fn with_location(self, block: &Block, location: DebugLocationValue) -> InstructionValue {
unsafe {
block.builder.add_instruction_location(&self, location);
}
self
}
pub fn maybe_location(
self,
block: &mut Block,
location: Option<DebugLocationValue>,
) -> InstructionValue {
unsafe {
if let Some(location) = location {
block.builder.add_instruction_location(&self, location);
}
}
self
}
}
#[derive(Clone)]
pub struct InstructionData {
kind: Instr,

View File

@ -89,7 +89,7 @@ pub struct Scope<'ctx, 'a> {
#[derive(Debug, Clone)]
pub struct Debug<'ctx> {
info: &'ctx DebugInformation,
scope: Option<DebugProgramValue>,
scope: DebugProgramValue,
}
pub struct StackFunction<'ctx> {
@ -440,6 +440,16 @@ impl mir::Expression {
scope: &mut Scope<'ctx, 'a>,
state: &State,
) -> Option<InstructionValue> {
let location = if let Some(debug) = &scope.debug {
Some(
debug
.info
.location(&debug.scope, self.1.into_debug(scope.tokens).unwrap()),
)
} else {
None
};
match &self.0 {
mir::ExprKind::Variable(varref) => {
varref.0.known().expect("variable type unknown");
@ -463,7 +473,10 @@ impl mir::Expression {
_ => panic!("Found an unknown-mutable variable!"),
})
}
mir::ExprKind::Literal(lit) => Some(lit.as_const(&mut scope.block)),
mir::ExprKind::Literal(lit) => Some(
lit.as_const(&mut scope.block)
.maybe_location(&mut scope.block, location),
),
mir::ExprKind::BinOp(binop, lhs_exp, rhs_exp) => {
lhs_exp
.return_type()

View File

@ -95,10 +95,10 @@ impl<'map> Pass for LinkerPass<'map> {
modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens))));
}
modules.insert(
"std".to_owned(),
Rc::new(RefCell::new(compile_std(&mut self.module_map))),
);
// modules.insert(
// "std".to_owned(),
// Rc::new(RefCell::new(compile_std(&mut self.module_map))),
// );
let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> =
modules.values().cloned().collect();