diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index e13b6d4..9266ec2 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -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, programs: &'a mut HashMap, metadata: &'a mut HashMap, + locations: &'a mut HashMap, } #[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, diff --git a/reid-llvm-lib/src/debug_information.rs b/reid-llvm-lib/src/debug_information.rs index 03fc710..d1f05a4 100644 --- a/reid-llvm-lib/src/debug_information.rs +++ b/reid-llvm-lib/src/debug_information.rs @@ -6,7 +6,7 @@ use std::{ #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct DebugScopeValue(pub Vec); -#[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>> { + self.locations.clone() + } + pub fn get_subprogram_data(&self, value: &DebugProgramValue) -> DebugSubprogramData { unsafe { self.programs diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 252f87f..b5c8c2e 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -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, + ) -> InstructionValue { + unsafe { + if let Some(location) = location { + block.builder.add_instruction_location(&self, location); + } + } + self + } +} + #[derive(Clone)] pub struct InstructionData { kind: Instr, diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index b43d40e..111c727 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -89,7 +89,7 @@ pub struct Scope<'ctx, 'a> { #[derive(Debug, Clone)] pub struct Debug<'ctx> { info: &'ctx DebugInformation, - scope: Option, + scope: DebugProgramValue, } pub struct StackFunction<'ctx> { @@ -440,6 +440,16 @@ impl mir::Expression { scope: &mut Scope<'ctx, 'a>, state: &State, ) -> Option { + 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() diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index f9a6d12..cc81277 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -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)>>> = modules.values().cloned().collect();