From 7ca8949e8cb69202b33f1dbe003d9d6fe6f38c3c Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 28 Jul 2025 16:11:20 +0300 Subject: [PATCH] Start adding lexical scopes --- reid-llvm-lib/src/builder.rs | 6 +- reid-llvm-lib/src/compile.rs | 76 ++++----- reid-llvm-lib/src/debug_information.rs | 213 +++++++++++++------------ reid-llvm-lib/src/fmt.rs | 18 +-- reid-llvm-lib/src/lib.rs | 16 +- reid/src/codegen/mod.rs | 107 +++++++------ reid/src/codegen/scope.rs | 4 +- reid/src/codegen/util.rs | 42 ++--- 8 files changed, 244 insertions(+), 238 deletions(-) diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 1094fa6..789c724 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -7,7 +7,7 @@ use crate::{ Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, debug_information::{ - DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, InstructionDebugRecordData, + DebugInformation, DebugLocationValue, DebugMetadataValue, DebugScopeValue, InstructionDebugRecordData, }, util::match_types, }; @@ -198,12 +198,12 @@ impl Builder { } } - pub(crate) unsafe fn set_debug_subprogram(&self, value: &FunctionValue, subprogram: DebugProgramValue) { + pub(crate) unsafe fn set_debug_subprogram(&self, value: &FunctionValue, subprogram: DebugScopeValue) { unsafe { let mut modules = self.modules.borrow_mut(); let module = modules.get_unchecked_mut(value.0.0); let function = module.functions.get_unchecked_mut(value.1); - function.data.debug = Some(subprogram) + function.data.scope = Some(subprogram) } } diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 4710846..bfe8485 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -209,9 +209,8 @@ pub struct LLVMDebugInformation<'a> { debug: &'a DebugInformation, builder: LLVMDIBuilderRef, file_ref: LLVMMetadataRef, - // scopes: &'a HashMap, + scopes: &'a HashMap, types: &'a mut HashMap, - programs: &'a mut HashMap, metadata: &'a mut HashMap, locations: &'a mut HashMap, } @@ -238,7 +237,7 @@ impl ModuleHolder { let mut types = HashMap::new(); let mut metadata = HashMap::new(); - let mut programs = HashMap::new(); + let mut scopes = HashMap::new(); let mut locations = HashMap::new(); let mut debug = if let Some(debug) = &self.debug_information { @@ -294,7 +293,11 @@ impl ModuleHolder { // } // dbg!("after!"); - programs.insert(DebugProgramValue(0), compile_unit); + let scope = debug.get_scope(); + scopes.insert(DebugScopeValue(Vec::new()), compile_unit); + for scope in &scope.borrow().inner_scopes { + scope.compile_scope(compile_unit, file_ref, &mut scopes, di_builder); + } let debug = LLVMDebugInformation { builder: di_builder, @@ -302,7 +305,7 @@ impl ModuleHolder { file_ref, types: &mut types, metadata: &mut metadata, - programs: &mut programs, + scopes: &mut scopes, locations: &mut locations, }; @@ -324,18 +327,12 @@ impl ModuleHolder { for function in &self.functions { let func = function.compile_signature(context, module_ref, &types, &debug); functions.insert(function.value, func); - - if let Some(debug) = &mut debug { - if let Some(program_value) = function.data.debug { - debug.programs.insert(program_value, func.metadata.unwrap()); - } - } } 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); + debug.locations.insert(location.value.clone(), location_ref); } for meta in debug.debug.get_metadatas().borrow().iter() { @@ -376,7 +373,7 @@ impl DebugLocationHolder { context.context_ref, self.location.pos.line, self.location.pos.column, - *debug.programs.get(&self.program).unwrap(), + *debug.scopes.get(&self.scope).unwrap(), null_mut(), ) } @@ -392,7 +389,7 @@ impl DebugScopeHolder { di_builder: LLVMDIBuilderRef, ) { unsafe { - let scope = if let Some(location) = &self.location { + let scope = if let Some(location) = &self.data.location { LLVMDIBuilderCreateLexicalBlock(di_builder, parent, file, location.pos.line, location.pos.column) } else { LLVMDIBuilderCreateLexicalBlockFile(di_builder, parent, file, 0) @@ -413,7 +410,7 @@ impl DebugMetadataHolder { match &self.data { DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable( debug.builder, - *debug.programs.get(&self.location.scope).unwrap(), + *debug.scopes.get(&self.location.scope).unwrap(), into_cstring(param.name.clone()).as_ptr(), param.name.len(), param.arg_idx + 1, @@ -425,7 +422,7 @@ impl DebugMetadataHolder { ), DebugMetadata::LocalVar(var) => LLVMDIBuilderCreateAutoVariable( debug.builder, - *debug.programs.get(&self.location.scope).unwrap(), + *debug.scopes.get(&self.location.scope).unwrap(), into_cstring(var.name.clone()).as_ptr(), var.name.len(), debug.file_ref, @@ -495,7 +492,7 @@ impl DebugTypeHolder { .map(|field| { LLVMDIBuilderCreateMemberType( debug.builder, - *debug.programs.get(&st.scope).unwrap(), + *debug.scopes.get(&st.scope).unwrap(), into_cstring(field.name.clone()).as_ptr(), field.name.len(), debug.file_ref, @@ -510,7 +507,7 @@ impl DebugTypeHolder { .collect::>(); LLVMDIBuilderCreateStructType( debug.builder, - *debug.programs.get(&st.scope).unwrap(), + *debug.scopes.get(&st.scope).unwrap(), into_cstring(st.name.clone()).as_ptr(), st.name.len(), debug.file_ref, @@ -586,29 +583,34 @@ impl FunctionHolder { } let metadata = if let Some(debug) = debug { - if let Some(value) = &self.data.debug { - let subprogram = debug.debug.get_subprogram_data_unchecked(&value); + if let Some(scope_value) = &self.data.scope { + let scope = debug.debug.get_scope_data(scope_value).unwrap(); let mangled_length_ptr = &mut 0; let mangled_name = LLVMGetValueName2(function_ref, mangled_length_ptr); let mangled_length = *mangled_length_ptr; - let subprogram = LLVMDIBuilderCreateFunction( - debug.builder, - *debug.programs.get(&subprogram.outer_scope).unwrap(), - into_cstring(subprogram.name.clone()).as_ptr(), - subprogram.name.clone().len(), - mangled_name, - mangled_length, - debug.file_ref, - subprogram.location.pos.line, - *debug.types.get(&subprogram.ty).unwrap(), - subprogram.opts.is_local as i32, - subprogram.opts.is_definition as i32, - subprogram.opts.scope_line, - subprogram.opts.flags.as_llvm(), - subprogram.opts.is_optimized as i32, - ); + let subprogram = match scope.kind { + DebugScopeKind::CodegenContext => panic!(), + DebugScopeKind::LexicalScope => panic!(), + DebugScopeKind::Subprogram(subprogram) => LLVMDIBuilderCreateFunction( + debug.builder, + *debug.scopes.get(&scope.parent.unwrap()).unwrap(), + into_cstring(subprogram.name.clone()).as_ptr(), + subprogram.name.clone().len(), + mangled_name, + mangled_length, + debug.file_ref, + subprogram.location.pos.line, + *debug.types.get(&subprogram.ty).unwrap(), + subprogram.opts.is_local as i32, + subprogram.opts.is_definition as i32, + subprogram.opts.scope_line, + subprogram.opts.flags.as_llvm(), + subprogram.opts.is_optimized as i32, + ), + }; + LLVMSetSubprogram(function_ref, subprogram); Some(subprogram) } else { @@ -1013,7 +1015,7 @@ impl InstructionHolder { module.context_ref, record.location.pos.line, record.location.pos.column, - *debug.programs.get(&record.scope).unwrap(), + *debug.scopes.get(&record.scope).unwrap(), null_mut(), ); diff --git a/reid-llvm-lib/src/debug_information.rs b/reid-llvm-lib/src/debug_information.rs index c9f2a40..b065371 100644 --- a/reid-llvm-lib/src/debug_information.rs +++ b/reid-llvm-lib/src/debug_information.rs @@ -1,12 +1,16 @@ -use std::{cell::RefCell, rc::Rc}; +use std::{ + cell::{Ref, RefCell, RefMut}, + rc::Rc, +}; use crate::builder::InstructionValue; +/// Represents 1. the compilation context, 2. subprogram or 3. a lexical scope #[derive(Clone, Hash, PartialEq, Eq)] pub struct DebugScopeValue(pub Vec); -#[derive(Clone, Copy, Hash, PartialEq, Eq)] -pub struct DebugLocationValue(pub DebugProgramValue, pub usize); +#[derive(Clone, Hash, PartialEq, Eq)] +pub struct DebugLocationValue(pub DebugScopeValue, pub usize); #[derive(Clone, Copy, Hash, PartialEq, Eq)] pub struct DebugTypeValue(pub usize); @@ -14,10 +18,6 @@ pub struct DebugTypeValue(pub usize); #[derive(Clone, Copy, Hash, PartialEq, Eq)] pub struct DebugMetadataValue(pub usize); -/// Represents either a subprogram, or the compilation context -#[derive(Clone, Copy, Hash, PartialEq, Eq)] -pub struct DebugProgramValue(pub usize); - #[derive(Debug, Clone)] pub struct DebugFileData { pub name: String, @@ -27,9 +27,8 @@ pub struct DebugFileData { #[derive(Debug, Clone)] pub(crate) struct DebugScopeHolder { pub(crate) value: DebugScopeValue, - pub(crate) location: Option, + pub(crate) data: DebugScopeData, pub(crate) inner_scopes: Vec, - pub(crate) locations: Vec, } #[derive(Debug, Clone)] @@ -45,15 +44,9 @@ pub struct DebugTypeHolder { pub(crate) data: DebugTypeData, } -#[derive(Debug, Clone)] -pub struct DebugSubprogramHolder { - pub(crate) _value: DebugProgramValue, - pub(crate) data: DebugSubprogramData, -} - #[derive(Debug, Clone)] pub(crate) struct DebugLocationHolder { - pub(crate) program: DebugProgramValue, + pub(crate) scope: DebugScopeValue, pub(crate) value: DebugLocationValue, pub(crate) location: DebugLocation, } @@ -61,68 +54,68 @@ pub(crate) struct DebugLocationHolder { #[derive(Debug, Clone)] pub struct DebugInformation { pub file: DebugFileData, - // scope: Rc>, + scope: Rc>, locations: Rc>>, - programs: Rc>>, metadata: Rc>>, types: Rc>>, } impl DebugInformation { - pub fn from_file(file: DebugFileData) -> (DebugInformation, DebugProgramValue) { + pub fn from_file(file: DebugFileData) -> (DebugInformation, DebugScopeValue) { + let scope_value = DebugScopeValue(Vec::new()); ( DebugInformation { file, - // scope: Rc::new(RefCell::new(DebugScopeHolder { - // value: scope_value.clone(), - // inner_scopes: Vec::new(), - // locations: Vec::new(), - // location: None, - // })), + scope: Rc::new(RefCell::new(DebugScopeHolder { + value: scope_value.clone(), + inner_scopes: Vec::new(), + data: DebugScopeData { + parent: None, + location: Some(DebugLocation { + scope: DebugScopeValue(Vec::new()), + pos: DebugPosition { line: 0, column: 0 }, + }), + kind: DebugScopeKind::CodegenContext, + }, + })), locations: Rc::new(RefCell::new(Vec::new())), metadata: Rc::new(RefCell::new(Vec::new())), - programs: Rc::new(RefCell::new(Vec::new())), types: Rc::new(RefCell::new(Vec::new())), }, - DebugProgramValue(0), + scope_value, ) } - // pub fn inner_scope( - // &self, - // parent: &DebugScopeValue, - // location: DebugLocation, - // ) -> DebugScopeValue { - // unsafe { - // let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| { - // for i in &parent.0 { - // v = v.inner_scopes.get_unchecked_mut(*i); - // } - // v - // }); + pub fn inner_scope(&self, parent: &DebugScopeValue, location: DebugLocation) -> DebugScopeValue { + unsafe { + let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| { + for i in &parent.0 { + v = v.inner_scopes.get_unchecked_mut(*i); + } + v + }); - // let mut arr = parent.0.clone(); - // arr.push(parent.0.len()); - // let value = DebugScopeValue(arr); + let mut arr = parent.0.clone(); + arr.push(parent.0.len()); + let value = DebugScopeValue(arr); - // outer_scope.inner_scopes.push(DebugScopeHolder { - // value: value.clone(), - // inner_scopes: Vec::new(), - // locations: Vec::new(), - // location: Some(location), - // }); - // value - // } - // } + outer_scope.inner_scopes.push(DebugScopeHolder { + value: value.clone(), + inner_scopes: Vec::new(), + data: DebugScopeData { + parent: Some(parent.clone()), + location: Some(location), + kind: DebugScopeKind::LexicalScope, + }, + }); + value + } + } - pub fn location( - &self, - program_value: &DebugProgramValue, - location: DebugLocation, - ) -> DebugLocationValue { - let value = DebugLocationValue(program_value.clone(), self.locations.borrow().len()); + pub fn location(&self, scope_value: &DebugScopeValue, location: DebugLocation) -> DebugLocationValue { + let value = DebugLocationValue(scope_value.clone(), self.locations.borrow().len()); let location = DebugLocationHolder { - program: *program_value, + scope: scope_value.clone(), value: value.clone(), location, }; @@ -144,21 +137,37 @@ impl DebugInformation { let mut metadata = self.metadata.borrow_mut(); let value = DebugMetadataValue(metadata.len()); metadata.push(DebugMetadataHolder { - location: *location, + location: location.clone(), value: value.clone(), data: kind, }); value } - pub fn subprogram(&self, kind: DebugSubprogramData) -> DebugProgramValue { - let mut subprogram = self.programs.borrow_mut(); - let value = DebugProgramValue(subprogram.len() + 1); - subprogram.push(DebugSubprogramHolder { - _value: value.clone(), - data: kind, - }); - value + pub fn subprogram(&self, parent: DebugScopeValue, kind: DebugSubprogramData) -> DebugScopeValue { + unsafe { + let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| { + for i in &parent.0 { + v = v.inner_scopes.get_unchecked_mut(*i); + } + v + }); + + let mut arr = parent.0.clone(); + arr.push(parent.0.len()); + let value = DebugScopeValue(arr); + + outer_scope.inner_scopes.push(DebugScopeHolder { + value: value.clone(), + inner_scopes: Vec::new(), + data: DebugScopeData { + parent: Some(parent.clone()), + location: None, + kind: DebugScopeKind::Subprogram(kind), + }, + }); + value + } } pub fn get_metadata(&self, value: DebugMetadataValue) -> DebugMetadata { @@ -166,14 +175,24 @@ impl DebugInformation { } pub fn get_metadata_location(&self, value: DebugMetadataValue) -> DebugLocation { - unsafe { self.metadata.borrow().get_unchecked(value.0).location } + unsafe { self.metadata.borrow().get_unchecked(value.0).location.clone() } } - pub fn get_subprogram_data(&self, value: DebugProgramValue) -> Option { - if value.0 == 0 { - None + pub fn get_scope_data(&self, value: &DebugScopeValue) -> Option { + let scope = Ref::filter_map(self.scope.borrow(), |v: &DebugScopeHolder| { + let mut opt = Some(v); + for i in &value.0 { + if let Some(inner) = opt { + opt = inner.inner_scopes.get(*i); + } + } + opt + }); + + if let Ok(scope) = scope { + Some(scope.data.clone()) } else { - Some(self.get_subprogram_data_unchecked(&value)) + None } } @@ -181,14 +200,8 @@ impl DebugInformation { unsafe { self.types.borrow().get_unchecked(value.0).data.clone() } } - pub fn get_location(&self, value: DebugLocationValue) -> DebugLocation { - unsafe { - self.locations - .borrow() - .get_unchecked(value.1) - .location - .clone() - } + pub fn get_location(&self, value: &DebugLocationValue) -> DebugLocation { + unsafe { self.locations.borrow().get_unchecked(value.1).location.clone() } } pub fn get_metadatas(&self) -> Rc>> { @@ -199,8 +212,8 @@ impl DebugInformation { // self.scope.clone() // } - pub fn get_subprograms(&self) -> Rc>> { - self.programs.clone() + pub fn get_scope(&self) -> Rc> { + self.scope.clone() } pub fn get_types(&self) -> Rc>> { @@ -210,21 +223,11 @@ impl DebugInformation { pub(crate) fn get_locations(&self) -> Rc>> { self.locations.clone() } - - pub fn get_subprogram_data_unchecked(&self, value: &DebugProgramValue) -> DebugSubprogramData { - unsafe { - self.programs - .borrow() - .get_unchecked(value.0 - 1) - .data - .clone() - } - } } -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct DebugLocation { - pub scope: DebugProgramValue, + pub scope: DebugScopeValue, pub pos: DebugPosition, } @@ -315,7 +318,7 @@ pub struct DebugPointerType { #[derive(Clone)] pub struct DebugStructType { pub name: String, - pub scope: DebugProgramValue, + pub scope: DebugScopeValue, pub pos: Option, pub size_bits: u64, pub flags: DwarfFlags, @@ -325,7 +328,7 @@ pub struct DebugStructType { #[derive(Clone)] pub struct DebugFieldType { pub name: String, - pub scope: DebugProgramValue, + pub scope: DebugScopeValue, pub pos: Option, pub size_bits: u64, pub offset: u64, @@ -350,11 +353,25 @@ pub enum DwarfEncoding { UnsignedChar = 8, } +#[derive(Debug, Clone)] +pub struct DebugScopeData { + pub parent: Option, + pub location: Option, + pub kind: DebugScopeKind, +} + +#[derive(Debug, Clone)] +pub enum DebugScopeKind { + CodegenContext, + LexicalScope, + Subprogram(DebugSubprogramData), +} + #[derive(Debug, Clone)] pub struct DebugSubprogramData { /// Function name. pub name: String, - pub outer_scope: DebugProgramValue, + pub outer_scope: DebugScopeValue, /// Used for line number. pub location: DebugLocation, /// Function type. @@ -376,7 +393,7 @@ pub struct DebugSubprogramOptionals { #[derive(Clone)] pub struct InstructionDebugRecordData { - pub scope: DebugProgramValue, + pub scope: DebugScopeValue, pub variable: DebugMetadataValue, pub location: DebugLocation, pub kind: DebugRecordKind, diff --git a/reid-llvm-lib/src/fmt.rs b/reid-llvm-lib/src/fmt.rs index b351d06..a5860cb 100644 --- a/reid-llvm-lib/src/fmt.rs +++ b/reid-llvm-lib/src/fmt.rs @@ -11,8 +11,8 @@ use crate::{ debug_information::{ DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, DebugLocation, DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugPointerType, DebugPosition, - DebugProgramValue, DebugRecordKind, DebugScopeValue, DebugStructType, DebugSubprogramType, DebugTypeData, - DebugTypeHolder, DebugTypeValue, + DebugRecordKind, DebugScopeValue, DebugStructType, DebugSubprogramType, DebugTypeData, DebugTypeHolder, + DebugTypeValue, }, pad_adapter::PadAdapter, }; @@ -74,7 +74,7 @@ impl FunctionHolder { let mut state = Default::default(); let mut inner = PadAdapter::wrap(f, &mut state); writeln!(inner, "(Value = {:?}) ", self.value)?; - if let Some(debug) = self.data.debug { + if let Some(debug) = &self.data.scope { writeln!(inner, "(Debug = {:?})", debug)?; } @@ -111,7 +111,7 @@ impl BlockHolder { if let Some(terminator) = &self.data.terminator { terminator.builder_fmt(&mut inner, builder, debug)?; } - if let Some(location) = self.data.terminator_location { + if let Some(location) = &self.data.terminator_location { writeln!(inner, " ^ (At {}) ", debug.as_ref().unwrap().get_location(location))?; } @@ -142,7 +142,7 @@ impl InstructionHolder { } writeln!(f, "{:?} ({}) = {:?} ", self.value, self.name, self.data.kind)?; if let Some(debug) = debug { - if let Some(location) = self.data.location { + if let Some(location) = &self.data.location { writeln!(f, " ^ (At {}) ", debug.get_location(location))?; } if let Some(meta) = self.data.meta { @@ -261,7 +261,7 @@ impl Debug for InstructionHolder { impl Debug for InstructionData { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.kind.fmt(f)?; - if let Some(location) = self.location { + if let Some(location) = &self.location { write!(f, " ({:?})", location)?; } Ok(()) @@ -574,12 +574,6 @@ impl Debug for DebugTypeValue { } } -impl Debug for DebugProgramValue { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Subprogram[{}]", self.0) - } -} - impl Debug for DebugLocationValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Value[{:?}][{}]", self.0, self.1) diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 8698501..e3be7d3 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -5,9 +5,11 @@ use std::{fmt::Debug, marker::PhantomData}; use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue}; -use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue}; +use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue}; use fmt::PrintableModule; +use crate::debug_information::DebugScopeValue; + pub mod builder; pub mod compile; pub mod debug_information; @@ -76,7 +78,7 @@ impl<'ctx> Module<'ctx> { ret, params, flags, - debug: None, + scope: None, }, ), } @@ -103,10 +105,10 @@ impl<'ctx> Module<'ctx> { } } - pub fn create_debug_info(&mut self, file: DebugFileData) -> (DebugInformation, DebugProgramValue) { - let (debug_info, program_value) = DebugInformation::from_file(file); + pub fn create_debug_info(&mut self, file: DebugFileData) -> (DebugInformation, DebugScopeValue) { + let (debug_info, scope_value) = DebugInformation::from_file(file); self.debug_info = Some(debug_info.clone()); - (debug_info, program_value) + (debug_info, scope_value) } pub fn get_debug_info(&self) -> &Option { @@ -128,7 +130,7 @@ pub struct FunctionData { ret: Type, params: Vec, flags: FunctionFlags, - debug: Option, + scope: Option, } #[derive(Debug, Clone, Copy, Hash)] @@ -184,7 +186,7 @@ impl<'ctx> Function<'ctx> { } } - pub fn set_debug(&self, subprogram: DebugProgramValue) { + pub fn set_debug(&self, subprogram: DebugScopeValue) { unsafe { self.builder.set_debug_subprogram(&self.value, subprogram); } diff --git a/reid/src/codegen/mod.rs b/reid/src/codegen/mod.rs index 7fcbbb6..f88bd39 100644 --- a/reid/src/codegen/mod.rs +++ b/reid/src/codegen/mod.rs @@ -124,7 +124,7 @@ impl mir::Module { debug_types.insert( $kind.clone(), $kind.get_debug_type_hard( - compile_unit, + &compile_unit, &debug, &debug_types, &type_values, @@ -311,7 +311,7 @@ impl mir::Module { stack_values: HashMap::new(), debug: Some(Debug { info: &debug, - scope: compile_unit, + scope: compile_unit.clone(), types: &debug_types, }), binops: &binops, @@ -328,7 +328,9 @@ impl mir::Module { &binop.return_type, &ir_function, match &binop.fn_kind { - FunctionDefinitionKind::Local(_, meta) => meta.into_debug(tokens, compile_unit), + FunctionDefinitionKind::Local(_, meta) => { + meta.into_debug(tokens, &compile_unit) + } FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, }, @@ -383,7 +385,7 @@ impl mir::Module { stack_values: HashMap::new(), debug: Some(Debug { info: &debug, - scope: compile_unit, + scope: compile_unit.clone(), types: &debug_types, }), binops: &binops, @@ -401,7 +403,7 @@ impl mir::Module { &function, match &mir_function.kind { FunctionDefinitionKind::Local(..) => { - mir_function.signature().into_debug(tokens, compile_unit) + mir_function.signature().into_debug(tokens, &compile_unit) } FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, @@ -442,7 +444,7 @@ impl mir::Module { stack_values: HashMap::new(), debug: Some(Debug { info: &debug, - scope: compile_unit, + scope: compile_unit.clone(), types: &debug_types, }), binops: &binops, @@ -460,7 +462,7 @@ impl mir::Module { &function, match &mir_function.kind { FunctionDefinitionKind::Local(..) => { - mir_function.signature().into_debug(tokens, compile_unit) + mir_function.signature().into_debug(tokens, &compile_unit) } FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, @@ -499,22 +501,25 @@ impl FunctionDefinitionKind { flags: DwarfFlags, })); - let subprogram = debug.info.subprogram(DebugSubprogramData { - name: name.clone(), - outer_scope: debug.scope.clone(), - location, - ty: debug_ty, - opts: DebugSubprogramOptionals { - is_local: !is_pub, - is_definition: true, - ..DebugSubprogramOptionals::default() + let subprogram = debug.info.subprogram( + debug.scope.clone(), + DebugSubprogramData { + name: name.clone(), + outer_scope: debug.scope.clone(), + location, + ty: debug_ty, + opts: DebugSubprogramOptionals { + is_local: !is_pub, + is_definition: true, + ..DebugSubprogramOptionals::default() + }, }, - }); + ); - ir_function.set_debug(subprogram); + ir_function.set_debug(subprogram.clone()); scope.debug = Some(Debug { info: debug.info, - scope: subprogram, + scope: subprogram.clone(), types: debug.types, }); } @@ -582,8 +587,8 @@ impl FunctionDefinitionKind { } if let Some(debug) = &scope.debug { - if let Some(location) = &block.return_meta().into_debug(scope.tokens, debug.scope) { - let location = debug.info.location(&debug.scope, *location); + if let Some(location) = &block.return_meta().into_debug(scope.tokens, &debug.scope) { + let location = debug.info.location(&debug.scope, location.clone()); scope.block.set_terminator_location(location).unwrap(); } } @@ -604,7 +609,7 @@ impl mir::Block { for stmt in &self.statements { stmt.codegen(&mut scope, state)?.map(|s| { if let Some(debug) = &scope.debug { - let location = stmt.1.into_debug(scope.tokens, debug.scope).unwrap(); + let location = stmt.1.into_debug(scope.tokens, &debug.scope).unwrap(); let loc_val = debug.info.location(&debug.scope, location); s.instr().with_location(&mut scope.block, loc_val); } @@ -641,7 +646,7 @@ impl mir::Block { impl mir::Statement { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Result, ErrorKind> { let location = scope.debug.clone().map(|d| { - let location = self.1.into_debug(scope.tokens, d.scope).unwrap(); + let location = self.1.into_debug(scope.tokens, &d.scope).unwrap(); d.info.location(&d.scope, location) }); @@ -652,7 +657,7 @@ impl mir::Statement { let alloca = scope .allocate(name, &value.1) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); let store = scope .block @@ -670,7 +675,7 @@ impl mir::Statement { StackValue(stack_value, TypeKind::CodegenPtr(Box::new(value.clone().1))), ); if let Some(debug) = &scope.debug { - let location = self.1.into_debug(scope.tokens, debug.scope).unwrap(); + let location = self.1.into_debug(scope.tokens, &debug.scope).unwrap(); let var = debug.info.metadata( &location, DebugMetadata::LocalVar(DebugLocalVariable { @@ -686,7 +691,7 @@ impl mir::Statement { variable: var, location, kind: DebugRecordKind::Declare(alloca), - scope: debug.scope, + scope: debug.scope.clone(), }, ); } @@ -777,7 +782,7 @@ impl mir::Expression { Some( debug .info - .location(&debug.scope, self.1.into_debug(scope.tokens, debug.scope).unwrap()), + .location(&debug.scope, self.1.into_debug(scope.tokens, &debug.scope).unwrap()), ) } else { None @@ -851,12 +856,12 @@ impl mir::Expression { .block .build(Instr::UDiv(lhs, rhs)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); let mul = scope .block .build(Instr::Mul(rhs, div)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); Instr::Sub(lhs, mul) } (mir::BinaryOperator::Mod, true, false) => { @@ -864,12 +869,12 @@ impl mir::Expression { .block .build(Instr::SDiv(lhs, rhs)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); let mul = scope .block .build(Instr::Mul(rhs, div)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); Instr::Sub(lhs, mul) } (mir::BinaryOperator::Mod, _, true) => { @@ -877,12 +882,12 @@ impl mir::Expression { .block .build(Instr::FDiv(lhs, rhs)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); let mul = scope .block .build(Instr::Mul(rhs, div)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); Instr::Sub(lhs, mul) } (mir::BinaryOperator::Or, true, true) => todo!(), @@ -916,7 +921,7 @@ impl mir::Expression { .block .build(instr) .unwrap() - .maybe_location(&mut scope.block, location), + .maybe_location(&mut scope.block, location.clone()), ), return_ty.clone(), )) @@ -962,7 +967,7 @@ impl mir::Expression { .block .build_named(format!("gep"), Instr::GetElemPtr(loaded, vec![idx])) .unwrap() - .maybe_location(&mut scope.block, location), + .maybe_location(&mut scope.block, location.clone()), *further_inner, ) } else if let TypeKind::CodegenPtr(further_inner) = *inner.clone() { @@ -975,7 +980,7 @@ impl mir::Expression { .block .build_named(format!("array.gep"), Instr::GetElemPtr(kind.instr(), vec![idx])) .unwrap() - .maybe_location(&mut scope.block, location), + .maybe_location(&mut scope.block, location.clone()), val_t.clone(), ) } else { @@ -992,7 +997,7 @@ impl mir::Expression { .block .build_named(format!("array.gep"), Instr::GetElemPtr(kind.instr(), vec![first, idx])) .unwrap() - .maybe_location(&mut scope.block, location), + .maybe_location(&mut scope.block, location.clone()), val_t.clone(), ) }; @@ -1004,7 +1009,7 @@ impl mir::Expression { .block .build_named("array.load", Instr::Load(ptr, contained_ty.get_type(scope.type_values))) .unwrap() - .maybe_location(&mut scope.block, location), + .maybe_location(&mut scope.block, location.clone()), ), contained_ty, )) @@ -1042,7 +1047,7 @@ impl mir::Expression { .block .build_named(&array_name, Instr::Alloca(array_ty.clone())) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); for (index, instr) in instr_list.iter().enumerate() { let gep_n = format!("{}.{}.gep", array_name, index); @@ -1060,19 +1065,19 @@ impl mir::Expression { .block .build_named(gep_n, Instr::GetElemPtr(array, vec![first, index_expr])) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); scope .block .build_named(store_n, Instr::Store(ptr, *instr)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); } let array_val = scope .block .build_named(load_n, Instr::Load(array, array_ty)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); Some(StackValue( StackValueKind::Literal(array_val), @@ -1140,7 +1145,7 @@ impl mir::Expression { .block .build_named(name, Instr::Alloca(ty.clone())) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); for (field_n, exp) in items { let gep_n = format!("{}.{}.gep", name, field_n); @@ -1151,13 +1156,13 @@ impl mir::Expression { .block .build_named(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32)) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); if let Some(val) = exp.codegen(scope, state)? { scope .block .build_named(store_n, Instr::Store(elem_ptr, val.instr())) .unwrap() - .maybe_location(&mut scope.block, location); + .maybe_location(&mut scope.block, location.clone()); } } @@ -1277,7 +1282,7 @@ impl mir::Expression { mir::ExprKind::AssociatedFunctionCall(ty, call) => codegen_function_call(Some(ty), call, scope, state)?, }; if let Some(value) = &value { - value.instr().maybe_location(&mut scope.block, location); + value.instr().maybe_location(&mut scope.block, location.clone()); } Ok(value) } @@ -1310,7 +1315,7 @@ fn codegen_function_call<'ctx, 'a>( .collect::>(); let location = if let Some(debug) = &scope.debug { - call.meta.into_debug(scope.tokens, debug.scope) + call.meta.into_debug(scope.tokens, &debug.scope) } else { None }; @@ -1393,16 +1398,16 @@ impl mir::IfExpression { let after_b = scope.function.block("after"); if let Some(debug) = &scope.debug { - let before_location = self.0 .1.into_debug(scope.tokens, debug.scope).unwrap(); + let before_location = self.0 .1.into_debug(scope.tokens, &debug.scope).unwrap(); let before_v = debug.info.location(&debug.scope, before_location); scope.block.set_terminator_location(before_v).ok(); - let then_location = self.1 .1.into_debug(scope.tokens, debug.scope).unwrap(); - let then_v = debug.info.location(&debug.scope, then_location); + let then_location = self.1 .1.into_debug(scope.tokens, &debug.scope).unwrap(); + let then_v = debug.info.location(&debug.scope, then_location.clone()); then_b.set_terminator_location(then_v).unwrap(); let else_location = if let Some(else_expr) = self.2.as_ref() { - else_expr.1.into_debug(scope.tokens, debug.scope).unwrap() + else_expr.1.into_debug(scope.tokens, &debug.scope).unwrap() } else { then_location }; diff --git a/reid/src/codegen/scope.rs b/reid/src/codegen/scope.rs index d3a70c5..043c111 100644 --- a/reid/src/codegen/scope.rs +++ b/reid/src/codegen/scope.rs @@ -2,7 +2,7 @@ use std::{cell::RefCell, collections::HashMap, mem, rc::Rc}; use reid_lib::{ builder::{InstructionValue, TypeValue}, - debug_information::{DebugInformation, DebugLocation, DebugProgramValue, DebugTypeValue}, + debug_information::{DebugInformation, DebugLocation, DebugScopeValue, DebugTypeValue}, Block, Context, Function, Instr, Module, }; @@ -75,7 +75,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { #[derive(Debug, Clone)] pub struct Debug<'ctx> { pub(super) info: &'ctx DebugInformation, - pub(super) scope: DebugProgramValue, + pub(super) scope: DebugScopeValue, pub(super) types: &'ctx HashMap, } diff --git a/reid/src/codegen/util.rs b/reid/src/codegen/util.rs index e0b4d0c..6c78604 100644 --- a/reid/src/codegen/util.rs +++ b/reid/src/codegen/util.rs @@ -3,19 +3,15 @@ use std::collections::HashMap; use reid_lib::{ builder::{InstructionValue, TypeValue}, debug_information::{ - DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation, - DebugPointerType, DebugPosition, DebugProgramValue, DebugStructType, DebugTypeData, - DebugTypeValue, DwarfEncoding, DwarfFlags, + DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation, DebugPointerType, + DebugPosition, DebugScopeValue, DebugStructType, DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, }, Block, CmpPredicate, ConstValue, Instr, Type, }; use crate::{ lexer::{FullToken, Position}, - mir::{ - self, CustomTypeKey, Metadata, SourceModuleId, TypeDefinition, TypeDefinitionKind, - TypeKind, VagueLiteral, - }, + mir::{self, CustomTypeKey, Metadata, SourceModuleId, TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral}, }; use super::{ @@ -38,9 +34,7 @@ impl mir::CmpOperator { impl mir::Literal { pub(super) fn as_const(&self, block: &mut Block) -> InstructionValue { - block - .build_named(format!("{}", self), self.as_const_kind()) - .unwrap() + block.build_named(format!("{}", self), self.as_const_kind()).unwrap() } pub(super) fn as_const_kind(&self) -> Instr { @@ -110,7 +104,7 @@ impl TypeKind { impl TypeKind { pub(super) fn get_debug_type(&self, debug: &Debug, scope: &Scope) -> DebugTypeValue { self.get_debug_type_hard( - debug.scope, + &debug.scope, debug.info, debug.types, scope.type_values, @@ -123,7 +117,7 @@ impl TypeKind { pub(super) fn get_debug_type_hard( &self, - scope: DebugProgramValue, + scope: &DebugScopeValue, debug_info: &DebugInformation, debug_types: &HashMap, type_values: &HashMap, @@ -184,11 +178,11 @@ impl TypeKind { let location = if typedef.source_module != local_mod { None } else { - field.2.into_debug(&tokens, scope) + field.2.into_debug(&tokens, &scope) }; fields.push(DebugFieldType { name: field.0.clone(), - scope, + scope: scope.clone(), pos: location.map(|l| l.pos), size_bits: field.1.size_of(), offset: size_bits, @@ -214,7 +208,7 @@ impl TypeKind { }; DebugTypeData::Struct(DebugStructType { name: key.0.clone(), - scope, + scope: scope.clone(), pos: location.map(|l| l.pos), size_bits, flags: DwarfFlags, @@ -231,12 +225,8 @@ impl TypeKind { TypeKind::Bool => DwarfEncoding::Boolean, TypeKind::I8 => DwarfEncoding::SignedChar, TypeKind::U8 => DwarfEncoding::UnsignedChar, - TypeKind::I16 | TypeKind::I32 | TypeKind::I64 | TypeKind::I128 => { - DwarfEncoding::Signed - } - TypeKind::U16 | TypeKind::U32 | TypeKind::U64 | TypeKind::U128 => { - DwarfEncoding::Unsigned - } + TypeKind::I16 | TypeKind::I32 | TypeKind::I64 | TypeKind::I128 => DwarfEncoding::Signed, + TypeKind::U16 | TypeKind::U32 | TypeKind::U64 | TypeKind::U128 => DwarfEncoding::Unsigned, TypeKind::F16 | TypeKind::F32 | TypeKind::F32B @@ -258,13 +248,9 @@ impl TypeKind { } impl Metadata { - pub(super) fn into_debug( - &self, - tokens: &Vec, - scope: DebugProgramValue, - ) -> Option { + pub(super) fn into_debug(&self, tokens: &Vec, scope: &DebugScopeValue) -> Option { if let Some((start, _)) = self.into_positions(tokens) { - Some(start.debug(scope)) + Some(start.debug(scope.clone())) } else { None } @@ -272,7 +258,7 @@ impl Metadata { } impl Position { - pub(super) fn debug(self, scope: DebugProgramValue) -> DebugLocation { + pub(super) fn debug(self, scope: DebugScopeValue) -> DebugLocation { DebugLocation { pos: DebugPosition { line: self.1,