Refactor scopes a little bit

This commit is contained in:
Sofia 2025-07-28 18:05:19 +03:00
parent 60860498df
commit d0e1082029
4 changed files with 78 additions and 24 deletions

View File

@ -47,6 +47,8 @@ pub struct FunctionHolder {
pub(crate) value: FunctionValue, pub(crate) value: FunctionValue,
pub(crate) data: FunctionData, pub(crate) data: FunctionData,
pub(crate) blocks: Vec<BlockHolder>, pub(crate) blocks: Vec<BlockHolder>,
/// Debug scope value of this current function
pub(crate) debug_info: Option<DebugScopeValue>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -117,6 +119,7 @@ impl Builder {
value, value,
data, data,
blocks: Vec::new(), blocks: Vec::new(),
debug_info: None,
}); });
value value
} }
@ -203,7 +206,7 @@ impl Builder {
let mut modules = self.modules.borrow_mut(); let mut modules = self.modules.borrow_mut();
let module = modules.get_unchecked_mut(value.0.0); let module = modules.get_unchecked_mut(value.0.0);
let function = module.functions.get_unchecked_mut(value.1); let function = module.functions.get_unchecked_mut(value.1);
function.data.scope = Some(subprogram) function.debug_info = Some(subprogram)
} }
} }

View File

@ -3,6 +3,7 @@
//! with the LLVM API. //! with the LLVM API.
use std::{ use std::{
cell::Ref,
collections::HashMap, collections::HashMap,
ptr::{null, null_mut}, ptr::{null, null_mut},
}; };
@ -206,10 +207,10 @@ impl<'a> Drop for LLVMModule<'a> {
} }
pub struct LLVMDebugInformation<'a> { pub struct LLVMDebugInformation<'a> {
debug: &'a DebugInformation, info: &'a DebugInformation,
builder: LLVMDIBuilderRef, builder: LLVMDIBuilderRef,
file_ref: LLVMMetadataRef, file_ref: LLVMMetadataRef,
scopes: &'a HashMap<DebugScopeValue, LLVMMetadataRef>, scopes: &'a mut HashMap<DebugScopeValue, LLVMMetadataRef>,
types: &'a mut HashMap<DebugTypeValue, LLVMMetadataRef>, types: &'a mut HashMap<DebugTypeValue, LLVMMetadataRef>,
metadata: &'a mut HashMap<DebugMetadataValue, LLVMMetadataRef>, metadata: &'a mut HashMap<DebugMetadataValue, LLVMMetadataRef>,
locations: &'a mut HashMap<DebugLocationValue, LLVMMetadataRef>, locations: &'a mut HashMap<DebugLocationValue, LLVMMetadataRef>,
@ -293,15 +294,11 @@ impl ModuleHolder {
// } // }
// dbg!("after!"); // dbg!("after!");
let scope = debug.get_scope();
scopes.insert(DebugScopeValue(Vec::new()), compile_unit); 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 { let debug = LLVMDebugInformation {
builder: di_builder, builder: di_builder,
debug: debug, info: debug,
file_ref, file_ref,
types: &mut types, types: &mut types,
metadata: &mut metadata, metadata: &mut metadata,
@ -309,7 +306,7 @@ impl ModuleHolder {
locations: &mut locations, locations: &mut locations,
}; };
for ty in debug.debug.get_types().borrow().iter() { for ty in debug.info.get_types().borrow().iter() {
let meta_ref = ty.compile_debug(&debug); let meta_ref = ty.compile_debug(&debug);
debug.types.insert(ty.value.clone(), meta_ref); debug.types.insert(ty.value.clone(), meta_ref);
} }
@ -325,17 +322,28 @@ impl ModuleHolder {
let mut functions = HashMap::new(); let mut functions = HashMap::new();
for function in &self.functions { for function in &self.functions {
let func = function.compile_signature(context, module_ref, &types, &debug); let func = function.compile_signature(context, module_ref, &types, &mut debug);
functions.insert(function.value, func); functions.insert(function.value, func);
if let (Some(debug), Some(debug_info)) = (&mut debug, &function.debug_info) {
let scope_refcell = debug.info.get_scope();
let mut scope = scope_refcell.borrow();
for i in &debug_info.0 {
scope = Ref::map(scope, |v| v.inner_scopes.get_unchecked(*i));
}
for scope in &scope.inner_scopes {
scope.compile_scope(func.metadata.unwrap(), debug.file_ref, debug.scopes, debug.builder);
}
}
} }
if let Some(debug) = &mut debug { if let Some(debug) = &mut debug {
for location in debug.debug.get_locations().borrow().iter() { for location in debug.info.get_locations().borrow().iter() {
let location_ref = location.compile(context, &debug); let location_ref = location.compile(context, &debug);
debug.locations.insert(location.value.clone(), location_ref); debug.locations.insert(location.value.clone(), location_ref);
} }
for meta in debug.debug.get_metadatas().borrow().iter() { for meta in debug.info.get_metadatas().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);
} }
@ -389,10 +397,16 @@ impl DebugScopeHolder {
di_builder: LLVMDIBuilderRef, di_builder: LLVMDIBuilderRef,
) { ) {
unsafe { unsafe {
let scope = if let Some(location) = &self.data.location { let scope = match &self.data.kind {
LLVMDIBuilderCreateLexicalBlock(di_builder, parent, file, location.pos.line, location.pos.column) DebugScopeKind::CodegenContext => panic!(),
} else { DebugScopeKind::LexicalScope => LLVMDIBuilderCreateLexicalBlock(
LLVMDIBuilderCreateLexicalBlockFile(di_builder, parent, file, 0) di_builder,
parent,
file,
self.data.location.as_ref().unwrap().pos.line,
self.data.location.as_ref().unwrap().pos.column,
),
DebugScopeKind::Subprogram(_) => panic!(),
}; };
for inner in &self.inner_scopes { for inner in &self.inner_scopes {
@ -555,12 +569,48 @@ impl TypeHolder {
} }
impl FunctionHolder { impl FunctionHolder {
unsafe fn compile_debug_info(
&self,
di_builder: LLVMDIBuilderRef,
parent: LLVMMetadataRef,
file: LLVMMetadataRef,
types: &mut HashMap<DebugTypeValue, LLVMMetadataRef>,
func: LLVMFunction,
scope: DebugScopeHolder,
) -> LLVMMetadataRef {
unsafe {
let DebugScopeKind::Subprogram(subprogram) = scope.data.kind else {
panic!();
};
let mangled_length_ptr = &mut 0;
let mangled_name = LLVMGetValueName2(func.value_ref, mangled_length_ptr);
let mangled_length = *mangled_length_ptr;
LLVMDIBuilderCreateFunction(
di_builder,
parent,
into_cstring(subprogram.name.clone()).as_ptr(),
subprogram.name.clone().len(),
mangled_name,
mangled_length,
file,
subprogram.location.pos.line,
*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,
)
}
}
unsafe fn compile_signature( unsafe fn compile_signature(
&self, &self,
context: &LLVMContext, context: &LLVMContext,
module_ref: LLVMModuleRef, module_ref: LLVMModuleRef,
types: &HashMap<TypeValue, LLVMTypeRef>, types: &HashMap<TypeValue, LLVMTypeRef>,
debug: &Option<LLVMDebugInformation>, debug: &mut Option<LLVMDebugInformation>,
) -> LLVMFunction { ) -> LLVMFunction {
unsafe { unsafe {
let ret_type = self.data.ret.as_llvm(context.context_ref, types); let ret_type = self.data.ret.as_llvm(context.context_ref, types);
@ -583,19 +633,21 @@ impl FunctionHolder {
} }
let metadata = if let Some(debug) = debug { let metadata = if let Some(debug) = debug {
if let Some(scope_value) = &self.data.scope { if let Some(scope_value) = &self.debug_info {
let scope = debug.debug.get_scope_data(scope_value).unwrap(); let scope_data = debug.info.get_scope_data(scope_value).unwrap();
let mangled_length_ptr = &mut 0; let mangled_length_ptr = &mut 0;
let mangled_name = LLVMGetValueName2(function_ref, mangled_length_ptr); let mangled_name = LLVMGetValueName2(function_ref, mangled_length_ptr);
let mangled_length = *mangled_length_ptr; let mangled_length = *mangled_length_ptr;
let subprogram = match scope.kind { dbg!(&scope_data);
let subprogram = match scope_data.kind {
DebugScopeKind::CodegenContext => panic!(), DebugScopeKind::CodegenContext => panic!(),
DebugScopeKind::LexicalScope => panic!(), DebugScopeKind::LexicalScope => panic!(),
DebugScopeKind::Subprogram(subprogram) => LLVMDIBuilderCreateFunction( DebugScopeKind::Subprogram(subprogram) => LLVMDIBuilderCreateFunction(
debug.builder, debug.builder,
*debug.scopes.get(&scope.parent.unwrap()).unwrap(), *debug.scopes.get(&scope_data.parent.unwrap()).unwrap(),
into_cstring(subprogram.name.clone()).as_ptr(), into_cstring(subprogram.name.clone()).as_ptr(),
subprogram.name.clone().len(), subprogram.name.clone().len(),
mangled_name, mangled_name,
@ -612,6 +664,7 @@ impl FunctionHolder {
}; };
LLVMSetSubprogram(function_ref, subprogram); LLVMSetSubprogram(function_ref, subprogram);
debug.scopes.insert(scope_value.clone(), subprogram);
Some(subprogram) Some(subprogram)
} else { } else {
None None

View File

@ -74,7 +74,7 @@ impl FunctionHolder {
let mut state = Default::default(); let mut state = Default::default();
let mut inner = PadAdapter::wrap(f, &mut state); let mut inner = PadAdapter::wrap(f, &mut state);
writeln!(inner, "(Value = {:?}) ", self.value)?; writeln!(inner, "(Value = {:?}) ", self.value)?;
if let Some(debug) = &self.data.scope { if let Some(debug) = &self.debug_info {
writeln!(inner, "(Debug = {:?})", debug)?; writeln!(inner, "(Debug = {:?})", debug)?;
} }

View File

@ -78,7 +78,6 @@ impl<'ctx> Module<'ctx> {
ret, ret,
params, params,
flags, flags,
scope: None,
}, },
), ),
} }
@ -130,7 +129,6 @@ pub struct FunctionData {
ret: Type, ret: Type,
params: Vec<Type>, params: Vec<Type>,
flags: FunctionFlags, flags: FunctionFlags,
scope: Option<DebugScopeValue>,
} }
#[derive(Debug, Clone, Copy, Hash)] #[derive(Debug, Clone, Copy, Hash)]