From 1b1a5934f5ab764582d2529fac60604d12e83869 Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 28 Jul 2025 18:40:42 +0300 Subject: [PATCH] Implement lexical scopes --- reid-llvm-lib/src/compile.rs | 8 ++-- reid-llvm-lib/src/debug_information.rs | 63 ++++++++++++-------------- reid/src/codegen/mod.rs | 58 +++++++++++------------- 3 files changed, 60 insertions(+), 69 deletions(-) diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 7f5e7f2..25a88a9 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -399,12 +399,12 @@ impl DebugScopeHolder { unsafe { let scope = match &self.data.kind { DebugScopeKind::CodegenContext => panic!(), - DebugScopeKind::LexicalScope => LLVMDIBuilderCreateLexicalBlock( + DebugScopeKind::LexicalScope(data) => LLVMDIBuilderCreateLexicalBlock( di_builder, parent, file, - self.data.location.as_ref().unwrap().pos.line, - self.data.location.as_ref().unwrap().pos.column, + data.location.pos.line, + data.location.pos.column, ), DebugScopeKind::Subprogram(_) => panic!(), }; @@ -607,7 +607,7 @@ impl FunctionHolder { let subprogram = match scope_data.kind { DebugScopeKind::CodegenContext => panic!(), - DebugScopeKind::LexicalScope => panic!(), + DebugScopeKind::LexicalScope(_) => panic!(), DebugScopeKind::Subprogram(subprogram) => LLVMDIBuilderCreateFunction( debug.builder, *debug.scopes.get(&scope_data.parent.unwrap()).unwrap(), diff --git a/reid-llvm-lib/src/debug_information.rs b/reid-llvm-lib/src/debug_information.rs index e0b8b21..bb7b994 100644 --- a/reid-llvm-lib/src/debug_information.rs +++ b/reid-llvm-lib/src/debug_information.rs @@ -71,10 +71,6 @@ impl DebugInformation { inner_scopes: Vec::new(), data: DebugScopeData { parent: None, - location: Some(DebugLocation { - scope: DebugScopeValue(Vec::new()), - pos: DebugPosition { line: 0, column: 0 }, - }), kind: DebugScopeKind::CodegenContext, }, })), @@ -86,32 +82,6 @@ impl DebugInformation { ) } - 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); - - 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, scope_value: &DebugScopeValue, location: DebugLocation) -> DebugLocationValue { let value = DebugLocationValue(scope_value.clone(), self.locations.borrow().len()); let location = DebugLocationHolder { @@ -162,13 +132,36 @@ impl DebugInformation { inner_scopes: Vec::new(), data: DebugScopeData { parent: Some(parent.clone()), - location: None, kind: DebugScopeKind::Subprogram(kind), }, }); value } } + pub fn lexical_scope(&self, parent: &DebugScopeValue, data: DebugLexicalScope) -> 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(outer_scope.inner_scopes.len()); + let value = DebugScopeValue(arr); + + outer_scope.inner_scopes.push(DebugScopeHolder { + value: value.clone(), + inner_scopes: Vec::new(), + data: DebugScopeData { + parent: Some(parent.clone()), + kind: DebugScopeKind::LexicalScope(data), + }, + }); + value + } + } pub fn get_metadata(&self, value: DebugMetadataValue) -> DebugMetadata { unsafe { self.metadata.borrow().get_unchecked(value.0).data.clone() } @@ -352,17 +345,21 @@ pub enum DwarfEncoding { #[derive(Debug, Clone)] pub struct DebugScopeData { pub parent: Option, - pub location: Option, pub kind: DebugScopeKind, } #[derive(Debug, Clone)] pub enum DebugScopeKind { CodegenContext, - LexicalScope, + LexicalScope(DebugLexicalScope), Subprogram(DebugSubprogramData), } +#[derive(Debug, Clone)] +pub struct DebugLexicalScope { + pub location: DebugLocation, +} + #[derive(Debug, Clone)] pub struct DebugSubprogramData { /// Function name. diff --git a/reid/src/codegen/mod.rs b/reid/src/codegen/mod.rs index 36ffa57..d59860d 100644 --- a/reid/src/codegen/mod.rs +++ b/reid/src/codegen/mod.rs @@ -5,8 +5,9 @@ use intrinsics::*; use reid_lib::{ compile::CompiledModule, debug_information::{ - DebugFileData, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind, DebugSubprogramData, - DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags, InstructionDebugRecordData, + DebugFileData, DebugLexicalScope, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind, + DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags, + InstructionDebugRecordData, }, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, NamedStruct, TerminatorKind as Term, Type, @@ -546,36 +547,10 @@ impl FunctionDefinitionKind { TypeKind::CodegenPtr(Box::new(p_ty.clone())), ), ); - - // Generate debug info - // if let (Some(debug_scope), Some(location)) = ( - // &debug_scope, - // mir_function.signature().into_debug(tokens, compile_unit), - // ) { - // debug.metadata( - // &location, - // DebugMetadata::ParamVar(DebugParamVariable { - // name: p_name.clone(), - // arg_idx: i as u32, - // ty: p_ty.get_debug_type_hard( - // *debug_scope, - // &debug, - // &debug_types, - // &type_values, - // &types, - // self.module_id, - // &self.tokens, - // &modules, - // ), - // always_preserve: true, - // flags: DwarfFlags, - // }), - // ); - // } } let state = State::default(); - if let Some(ret) = block.codegen(scope, &state)? { + if let Some(ret) = block.codegen(scope, &state, false)? { scope.block.terminate(Term::Ret(ret.instr())).unwrap(); } else { if !scope.block.delete_if_unused().unwrap() { @@ -604,7 +579,20 @@ impl mir::Block { &self, mut scope: &mut Scope<'ctx, 'a>, state: &State, + create_debug_scope: bool, ) -> Result, ErrorKind> { + let parent_scope = if let Some(debug) = &mut scope.debug { + let parent_scope = debug.scope.clone(); + if create_debug_scope { + let location = self.meta.into_debug(scope.tokens, &debug.scope).unwrap(); + let scope = debug.info.lexical_scope(&debug.scope, DebugLexicalScope { location }); + debug.scope = scope; + } + Some(parent_scope) + } else { + None + }; + for stmt in &self.statements { stmt.codegen(&mut scope, state)?.map(|s| { if let Some(debug) = &scope.debug { @@ -615,7 +603,7 @@ impl mir::Block { }); } - if let Some((kind, expr)) = &self.return_expression { + let return_value = if let Some((kind, expr)) = &self.return_expression { if let Some(expr) = expr { let ret = expr.codegen(&mut scope, &mut state.load(true))?; match kind { @@ -638,7 +626,13 @@ impl mir::Block { } } else { Ok(None) + }; + + if let Some(parent_scope) = parent_scope { + scope.debug.as_mut().unwrap().scope = parent_scope; } + + return_value } } @@ -759,7 +753,7 @@ impl mir::Statement { .unwrap(); let mut condition_true_scope = scope.with_block(condition_true_block); - block.codegen(&mut condition_true_scope, state)?; + block.codegen(&mut condition_true_scope, state, true)?; condition_true_scope .block @@ -933,7 +927,7 @@ impl mir::Expression { scope.block.terminate(Term::Br(inner.value())).unwrap(); let mut inner_scope = scope.with_block(inner); - let ret = if let Some(ret) = block.codegen(&mut inner_scope, state)? { + let ret = if let Some(ret) = block.codegen(&mut inner_scope, state, true)? { Some(ret) } else { None