Get debug info working very preliminarily
This commit is contained in:
parent
287ab69d32
commit
1967cadbc0
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user