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
|
//! LLIR ([`Context`]) into LLVM IR. This module is the only one that interfaces
|
||||||
//! with the LLVM API.
|
//! with the LLVM API.
|
||||||
|
|
||||||
use std::{collections::HashMap, ptr::null_mut};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
ptr::{null, null_mut},
|
||||||
|
};
|
||||||
|
|
||||||
use llvm_sys::{
|
use llvm_sys::{
|
||||||
LLVMIntPredicate, LLVMLinkage,
|
LLVMIntPredicate, LLVMLinkage,
|
||||||
@ -203,6 +206,7 @@ pub struct LLVMDebugInformation<'a> {
|
|||||||
types: &'a mut HashMap<DebugTypeValue, LLVMMetadataRef>,
|
types: &'a mut HashMap<DebugTypeValue, LLVMMetadataRef>,
|
||||||
programs: &'a mut HashMap<DebugProgramValue, LLVMMetadataRef>,
|
programs: &'a mut HashMap<DebugProgramValue, LLVMMetadataRef>,
|
||||||
metadata: &'a mut HashMap<DebugMetadataValue, LLVMMetadataRef>,
|
metadata: &'a mut HashMap<DebugMetadataValue, LLVMMetadataRef>,
|
||||||
|
locations: &'a mut HashMap<DebugLocationValue, LLVMMetadataRef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@ -230,6 +234,7 @@ impl ModuleHolder {
|
|||||||
let mut types = HashMap::new();
|
let mut types = HashMap::new();
|
||||||
let mut metadata = HashMap::new();
|
let mut metadata = HashMap::new();
|
||||||
let mut programs = HashMap::new();
|
let mut programs = HashMap::new();
|
||||||
|
let mut locations = HashMap::new();
|
||||||
|
|
||||||
let mut debug = if let Some(debug) = &self.debug_information {
|
let mut debug = if let Some(debug) = &self.debug_information {
|
||||||
let di_builder = LLVMCreateDIBuilder(module_ref);
|
let di_builder = LLVMCreateDIBuilder(module_ref);
|
||||||
@ -293,6 +298,7 @@ impl ModuleHolder {
|
|||||||
types: &mut types,
|
types: &mut types,
|
||||||
metadata: &mut metadata,
|
metadata: &mut metadata,
|
||||||
programs: &mut programs,
|
programs: &mut programs,
|
||||||
|
locations: &mut locations,
|
||||||
};
|
};
|
||||||
|
|
||||||
for ty in debug.debug.get_types().borrow().iter() {
|
for ty in debug.debug.get_types().borrow().iter() {
|
||||||
@ -322,6 +328,11 @@ impl ModuleHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(debug) = &mut debug {
|
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() {
|
for meta in debug.debug.get_metadata().borrow().iter() {
|
||||||
let meta_ref = meta.compile(&debug);
|
let meta_ref = meta.compile(&debug);
|
||||||
debug.metadata.insert(meta.value.clone(), meta_ref);
|
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 {
|
impl DebugScopeHolder {
|
||||||
unsafe fn compile_scope(
|
unsafe fn compile_scope(
|
||||||
&self,
|
&self,
|
||||||
@ -761,6 +790,7 @@ impl InstructionHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if let Some(location_value) = &self.data.location {}
|
||||||
LLVMValue {
|
LLVMValue {
|
||||||
_ty,
|
_ty,
|
||||||
value_ref: val,
|
value_ref: val,
|
||||||
|
@ -6,7 +6,7 @@ use std::{
|
|||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||||
pub struct DebugScopeValue(pub Vec<usize>);
|
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);
|
pub struct DebugLocationValue(pub DebugProgramValue, pub usize);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
@ -54,8 +54,9 @@ pub struct DebugSubprogramHolder {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct DebugLocationHolder {
|
pub(crate) struct DebugLocationHolder {
|
||||||
value: DebugLocationValue,
|
pub(crate) program: DebugProgramValue,
|
||||||
location: DebugLocation,
|
pub(crate) value: DebugLocationValue,
|
||||||
|
pub(crate) location: DebugLocation,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -118,13 +119,13 @@ impl DebugInformation {
|
|||||||
pub fn location(
|
pub fn location(
|
||||||
&self,
|
&self,
|
||||||
program_value: &DebugProgramValue,
|
program_value: &DebugProgramValue,
|
||||||
line: u32,
|
location: DebugLocation,
|
||||||
column: u32,
|
|
||||||
) -> DebugLocationValue {
|
) -> DebugLocationValue {
|
||||||
let value = DebugLocationValue(program_value.clone(), self.locations.borrow().len());
|
let value = DebugLocationValue(program_value.clone(), self.locations.borrow().len());
|
||||||
let location = DebugLocationHolder {
|
let location = DebugLocationHolder {
|
||||||
|
program: *program_value,
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
location: DebugLocation { line, column },
|
location,
|
||||||
};
|
};
|
||||||
self.locations.borrow_mut().push(location);
|
self.locations.borrow_mut().push(location);
|
||||||
value
|
value
|
||||||
@ -184,6 +185,10 @@ impl DebugInformation {
|
|||||||
self.types.clone()
|
self.types.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_locations(&self) -> Rc<RefCell<Vec<DebugLocationHolder>>> {
|
||||||
|
self.locations.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_subprogram_data(&self, value: &DebugProgramValue) -> DebugSubprogramData {
|
pub fn get_subprogram_data(&self, value: &DebugProgramValue) -> DebugSubprogramData {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.programs
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct InstructionData {
|
pub struct InstructionData {
|
||||||
kind: Instr,
|
kind: Instr,
|
||||||
|
@ -89,7 +89,7 @@ pub struct Scope<'ctx, 'a> {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Debug<'ctx> {
|
pub struct Debug<'ctx> {
|
||||||
info: &'ctx DebugInformation,
|
info: &'ctx DebugInformation,
|
||||||
scope: Option<DebugProgramValue>,
|
scope: DebugProgramValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StackFunction<'ctx> {
|
pub struct StackFunction<'ctx> {
|
||||||
@ -440,6 +440,16 @@ impl mir::Expression {
|
|||||||
scope: &mut Scope<'ctx, 'a>,
|
scope: &mut Scope<'ctx, 'a>,
|
||||||
state: &State,
|
state: &State,
|
||||||
) -> Option<InstructionValue> {
|
) -> 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 {
|
match &self.0 {
|
||||||
mir::ExprKind::Variable(varref) => {
|
mir::ExprKind::Variable(varref) => {
|
||||||
varref.0.known().expect("variable type unknown");
|
varref.0.known().expect("variable type unknown");
|
||||||
@ -463,7 +473,10 @@ impl mir::Expression {
|
|||||||
_ => panic!("Found an unknown-mutable variable!"),
|
_ => 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) => {
|
mir::ExprKind::BinOp(binop, lhs_exp, rhs_exp) => {
|
||||||
lhs_exp
|
lhs_exp
|
||||||
.return_type()
|
.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(module.name.clone(), Rc::new(RefCell::new((module, tokens))));
|
||||||
}
|
}
|
||||||
|
|
||||||
modules.insert(
|
// modules.insert(
|
||||||
"std".to_owned(),
|
// "std".to_owned(),
|
||||||
Rc::new(RefCell::new(compile_std(&mut self.module_map))),
|
// Rc::new(RefCell::new(compile_std(&mut self.module_map))),
|
||||||
);
|
// );
|
||||||
|
|
||||||
let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> =
|
let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> =
|
||||||
modules.values().cloned().collect();
|
modules.values().cloned().collect();
|
||||||
|
Loading…
Reference in New Issue
Block a user