Add temporary line number for for non-local structs

This commit is contained in:
Sofia 2025-07-22 16:35:15 +03:00
parent e9bca63f0d
commit fa6b7bdf87
4 changed files with 67 additions and 62 deletions

View File

@ -421,23 +421,23 @@ impl DebugMetadataHolder {
match &self.data { match &self.data {
DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable( DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable(
debug.builder, debug.builder,
*debug.programs.get(&self.program).unwrap(), *debug.programs.get(&self.location.scope).unwrap(),
into_cstring(param.name.clone()).as_ptr(), into_cstring(param.name.clone()).as_ptr(),
param.name.len(), param.name.len(),
param.arg_idx + 1, param.arg_idx + 1,
debug.file_ref, debug.file_ref,
param.location.line, self.location.line,
*debug.types.get(&param.ty).unwrap(), *debug.types.get(&param.ty).unwrap(),
param.always_preserve as i32, param.always_preserve as i32,
param.flags.as_llvm(), param.flags.as_llvm(),
), ),
DebugMetadata::LocalVar(var) => LLVMDIBuilderCreateAutoVariable( DebugMetadata::LocalVar(var) => LLVMDIBuilderCreateAutoVariable(
debug.builder, debug.builder,
*debug.programs.get(&self.program).unwrap(), *debug.programs.get(&self.location.scope).unwrap(),
into_cstring(var.name.clone()).as_ptr(), into_cstring(var.name.clone()).as_ptr(),
var.name.len(), var.name.len(),
debug.file_ref, debug.file_ref,
var.location.line, self.location.line,
*debug.types.get(&var.ty).unwrap(), *debug.types.get(&var.ty).unwrap(),
var.always_preserve as i32, var.always_preserve as i32,
var.flags.as_llvm(), var.flags.as_llvm(),
@ -504,7 +504,7 @@ impl DebugTypeHolder {
.map(|field| { .map(|field| {
LLVMDIBuilderCreateMemberType( LLVMDIBuilderCreateMemberType(
debug.builder, debug.builder,
*debug.programs.get(&st.scope).unwrap(), *debug.programs.get(&st.location.scope).unwrap(),
into_cstring(field.name.clone()).as_ptr(), into_cstring(field.name.clone()).as_ptr(),
field.name.len(), field.name.len(),
debug.file_ref, debug.file_ref,
@ -519,7 +519,7 @@ impl DebugTypeHolder {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
LLVMDIBuilderCreateStructType( LLVMDIBuilderCreateStructType(
debug.builder, debug.builder,
*debug.programs.get(&st.scope).unwrap(), *debug.programs.get(&st.location.scope).unwrap(),
into_cstring(st.name.clone()).as_ptr(), into_cstring(st.name.clone()).as_ptr(),
st.name.len(), st.name.len(),
debug.file_ref, debug.file_ref,

View File

@ -34,7 +34,7 @@ pub(crate) struct DebugScopeHolder {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DebugMetadataHolder { pub struct DebugMetadataHolder {
pub(crate) program: DebugProgramValue, pub(crate) location: DebugLocation,
pub(crate) value: DebugMetadataValue, pub(crate) value: DebugMetadataValue,
pub(crate) data: DebugMetadata, pub(crate) data: DebugMetadata,
} }
@ -140,11 +140,11 @@ impl DebugInformation {
value value
} }
pub fn metadata(&self, program: &DebugProgramValue, kind: DebugMetadata) -> DebugMetadataValue { pub fn metadata(&self, location: &DebugLocation, kind: DebugMetadata) -> DebugMetadataValue {
let mut metadata = self.metadata.borrow_mut(); let mut metadata = self.metadata.borrow_mut();
let value = DebugMetadataValue(metadata.len()); let value = DebugMetadataValue(metadata.len());
metadata.push(DebugMetadataHolder { metadata.push(DebugMetadataHolder {
program: *program, location: *location,
value: value.clone(), value: value.clone(),
data: kind, data: kind,
}); });
@ -165,6 +165,10 @@ impl DebugInformation {
unsafe { self.metadata.borrow().get_unchecked(value.0).data.clone() } unsafe { self.metadata.borrow().get_unchecked(value.0).data.clone() }
} }
pub fn get_metadata_location(&self, value: DebugMetadataValue) -> DebugLocation {
unsafe { self.metadata.borrow().get_unchecked(value.0).location }
}
pub fn get_subprogram_data(&self, value: DebugProgramValue) -> Option<DebugSubprogramData> { pub fn get_subprogram_data(&self, value: DebugProgramValue) -> Option<DebugSubprogramData> {
if value.0 == 0 { if value.0 == 0 {
None None
@ -218,8 +222,9 @@ impl DebugInformation {
} }
} }
#[derive(Clone, Copy, Default)] #[derive(Clone, Copy)]
pub struct DebugLocation { pub struct DebugLocation {
pub scope: DebugProgramValue,
pub line: u32, pub line: u32,
pub column: u32, pub column: u32,
} }
@ -238,8 +243,6 @@ pub struct DebugParamVariable {
/// parameters. arg_idx should not conflict with other parameters of the /// parameters. arg_idx should not conflict with other parameters of the
/// same subprogram. /// same subprogram.
pub arg_idx: u32, pub arg_idx: u32,
/// Used for line number
pub location: DebugLocation,
pub ty: DebugTypeValue, pub ty: DebugTypeValue,
/// If this variable will be referenced from its containing subprogram, and /// If this variable will be referenced from its containing subprogram, and
/// will survive some optimizations. /// will survive some optimizations.
@ -250,7 +253,6 @@ pub struct DebugParamVariable {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DebugLocalVariable { pub struct DebugLocalVariable {
pub name: String, pub name: String,
pub location: DebugLocation,
pub ty: DebugTypeValue, pub ty: DebugTypeValue,
pub always_preserve: bool, pub always_preserve: bool,
pub flags: DwarfFlags, pub flags: DwarfFlags,
@ -308,7 +310,6 @@ pub struct DebugPointerType {
#[derive(Clone)] #[derive(Clone)]
pub struct DebugStructType { pub struct DebugStructType {
pub name: String, pub name: String,
pub scope: DebugProgramValue,
pub location: DebugLocation, pub location: DebugLocation,
pub size_bits: u64, pub size_bits: u64,
pub flags: DwarfFlags, pub flags: DwarfFlags,

View File

@ -157,22 +157,16 @@ impl InstructionHolder {
impl DebugMetadataValue { impl DebugMetadataValue {
fn hr(&self, debug: &DebugInformation) -> String { fn hr(&self, debug: &DebugInformation) -> String {
match debug.get_metadata(*self) { let kind = match debug.get_metadata(*self) {
DebugMetadata::ParamVar(DebugParamVariable { DebugMetadata::ParamVar(DebugParamVariable {
name, name, arg_idx, ty, ..
arg_idx, }) => format!("param {} (idx {}) (type {:?}) ", name, arg_idx, ty),
location, DebugMetadata::LocalVar(DebugLocalVariable { name, ty, .. }) => {
ty, format!("var {} (type {:?}) ", name, ty)
.. }
}) => format!(
"param {} (idx {}) (type {:?}) at {}",
name, arg_idx, ty, location
),
DebugMetadata::LocalVar(DebugLocalVariable {
name, location, ty, ..
}) => format!("var {} (type {:?}) at {}", name, ty, location),
DebugMetadata::VarAssignment => todo!(), DebugMetadata::VarAssignment => todo!(),
} };
format!("{} at {}", kind, debug.get_metadata_location(*self))
} }
} }
@ -490,7 +484,6 @@ impl Debug for DebugStructType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Struct") f.debug_struct("Struct")
.field("name", &self.name) .field("name", &self.name)
.field("scope", &self.scope)
.field("location", &self.location) .field("location", &self.location)
.field("size_bit", &self.size_bits) .field("size_bit", &self.size_bits)
.field("flags", &self.flags) .field("flags", &self.flags)

View File

@ -314,7 +314,9 @@ impl mir::Module {
let mut entry = function.ir.block("entry"); let mut entry = function.ir.block("entry");
// Insert debug information // Insert debug information
let debug_scope = if let Some(location) = mir_function.signature().into_debug(tokens) { let debug_scope = if let Some(location) =
mir_function.signature().into_debug(tokens, compile_unit)
{
// let debug_scope = debug.inner_scope(&outer_scope, location); // let debug_scope = debug.inner_scope(&outer_scope, location);
let fn_param_ty = &mir_function.return_type.get_debug_type_hard( let fn_param_ty = &mir_function.return_type.get_debug_type_hard(
@ -376,15 +378,15 @@ impl mir::Module {
); );
// Generate debug info // Generate debug info
if let (Some(debug_scope), Some(location)) = if let (Some(debug_scope), Some(location)) = (
(&debug_scope, mir_function.signature().into_debug(tokens)) &debug_scope,
{ mir_function.signature().into_debug(tokens, compile_unit),
) {
debug.metadata( debug.metadata(
&debug_scope, &location,
DebugMetadata::ParamVar(DebugParamVariable { DebugMetadata::ParamVar(DebugParamVariable {
name: p_name.clone(), name: p_name.clone(),
arg_idx: i as u32, arg_idx: i as u32,
location,
ty: p_ty.get_debug_type_hard( ty: p_ty.get_debug_type_hard(
*debug_scope, *debug_scope,
&debug, &debug,
@ -434,7 +436,8 @@ impl mir::Module {
} }
if let Some(debug) = scope.debug { if let Some(debug) = scope.debug {
let location = &block.return_meta().into_debug(tokens).unwrap(); let location =
&block.return_meta().into_debug(tokens, debug.scope).unwrap();
let location = debug.info.location(&debug.scope, *location); let location = debug.info.location(&debug.scope, *location);
scope.block.set_terminator_location(location).unwrap(); scope.block.set_terminator_location(location).unwrap();
} }
@ -456,7 +459,7 @@ impl mir::Block {
for stmt in &self.statements { for stmt in &self.statements {
stmt.codegen(&mut scope, state).map(|s| { stmt.codegen(&mut scope, state).map(|s| {
if let Some(debug) = &scope.debug { if let Some(debug) = &scope.debug {
let location = stmt.1.into_debug(scope.tokens).unwrap(); let location = stmt.1.into_debug(scope.tokens, debug.scope).unwrap();
let loc_val = debug.info.location(&debug.scope, location); let loc_val = debug.info.location(&debug.scope, location);
s.instr().with_location(&mut scope.block, loc_val); s.instr().with_location(&mut scope.block, loc_val);
} }
@ -480,11 +483,10 @@ impl mir::Block {
impl mir::Statement { impl mir::Statement {
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option<StackValue> { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option<StackValue> {
let location = self.1.into_debug(scope.tokens).unwrap(); let location = scope.debug.clone().map(|d| {
let location = scope let location = self.1.into_debug(scope.tokens, d.scope).unwrap();
.debug d.info.location(&d.scope, location)
.as_ref() });
.map(|d| d.info.location(&d.scope, location));
match &self.0 { match &self.0 {
mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => {
@ -518,12 +520,11 @@ impl mir::Statement {
StackValue(stack_value, TypeKind::CodegenPtr(Box::new(value.clone().1))), StackValue(stack_value, TypeKind::CodegenPtr(Box::new(value.clone().1))),
); );
if let Some(debug) = &scope.debug { if let Some(debug) = &scope.debug {
let location = self.1.into_debug(scope.tokens).unwrap(); let location = self.1.into_debug(scope.tokens, debug.scope).unwrap();
let var = debug.info.metadata( let var = debug.info.metadata(
&debug.scope, &location,
DebugMetadata::LocalVar(DebugLocalVariable { DebugMetadata::LocalVar(DebugLocalVariable {
name: name.clone(), name: name.clone(),
location,
ty: ty.clone().get_debug_type(debug, scope), ty: ty.clone().get_debug_type(debug, scope),
always_preserve: true, always_preserve: true,
flags: DwarfFlags, flags: DwarfFlags,
@ -581,11 +582,10 @@ impl mir::Statement {
impl mir::Expression { impl mir::Expression {
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option<StackValue> { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option<StackValue> {
let location = if let Some(debug) = &scope.debug { let location = if let Some(debug) = &scope.debug {
Some( Some(debug.info.location(
debug &debug.scope,
.info self.1.into_debug(scope.tokens, debug.scope).unwrap(),
.location(&debug.scope, self.1.into_debug(scope.tokens).unwrap()), ))
)
} else { } else {
None None
}; };
@ -687,7 +687,7 @@ impl mir::Expression {
.unwrap(); .unwrap();
if let Some(debug) = &scope.debug { if let Some(debug) = &scope.debug {
let location = call.meta.into_debug(scope.tokens).unwrap(); let location = call.meta.into_debug(scope.tokens, debug.scope).unwrap();
let location_val = debug.info.location(&debug.scope, location); let location_val = debug.info.location(&debug.scope, location);
val.with_location(&mut scope.block, location_val); val.with_location(&mut scope.block, location_val);
} }
@ -1078,16 +1078,23 @@ impl mir::IfExpression {
let after_b = scope.function.ir.block("after"); let after_b = scope.function.ir.block("after");
if let Some(debug) = &scope.debug { if let Some(debug) = &scope.debug {
let before_location = self.0 .1.into_debug(scope.tokens).unwrap(); let before_location = self.0 .1.into_debug(scope.tokens, debug.scope).unwrap();
let before_v = debug.info.location(&debug.scope, before_location); let before_v = debug.info.location(&debug.scope, before_location);
scope.block.set_terminator_location(before_v).unwrap(); scope.block.set_terminator_location(before_v).unwrap();
let then_location = self.1.return_meta().into_debug(scope.tokens).unwrap(); let then_location = self
.1
.return_meta()
.into_debug(scope.tokens, debug.scope)
.unwrap();
let then_v = debug.info.location(&debug.scope, then_location); let then_v = debug.info.location(&debug.scope, then_location);
then_b.set_terminator_location(then_v).unwrap(); then_b.set_terminator_location(then_v).unwrap();
let else_location = if let Some(else_block) = &self.2 { let else_location = if let Some(else_block) = &self.2 {
else_block.return_meta().into_debug(scope.tokens).unwrap() else_block
.return_meta()
.into_debug(scope.tokens, debug.scope)
.unwrap()
} else { } else {
then_location then_location
}; };
@ -1330,7 +1337,7 @@ impl TypeKind {
for field in &struct_type.0 { for field in &struct_type.0 {
fields.push(DebugFieldType { fields.push(DebugFieldType {
name: field.0.clone(), name: field.0.clone(),
location: field.2.into_debug(tokens).unwrap(), location: field.2.into_debug(tokens, scope).unwrap(),
size_bits: field.1.size_of(), size_bits: field.1.size_of(),
offset: size_bits, offset: size_bits,
flags: DwarfFlags, flags: DwarfFlags,
@ -1348,8 +1355,7 @@ impl TypeKind {
{ {
DebugTypeData::Struct(DebugStructType { DebugTypeData::Struct(DebugStructType {
name: key.0.clone(), name: key.0.clone(),
scope, location: typedef.meta.into_debug(tokens, scope).unwrap(),
location: typedef.meta.into_debug(tokens).unwrap(),
size_bits, size_bits,
flags: DwarfFlags, flags: DwarfFlags,
fields, fields,
@ -1392,20 +1398,25 @@ impl TypeKind {
} }
impl Metadata { impl Metadata {
pub fn into_debug(&self, tokens: &Vec<FullToken>) -> Option<DebugLocation> { pub fn into_debug(
&self,
tokens: &Vec<FullToken>,
scope: DebugProgramValue,
) -> Option<DebugLocation> {
if let Some((start, _)) = self.into_positions(tokens) { if let Some((start, _)) = self.into_positions(tokens) {
Some(start.into()) Some(start.debug(scope))
} else { } else {
None Some(Position(0, 0).debug(scope))
} }
} }
} }
impl Into<DebugLocation> for Position { impl Position {
fn into(self) -> DebugLocation { fn debug(self, scope: DebugProgramValue) -> DebugLocation {
DebugLocation { DebugLocation {
line: self.1, line: self.1,
column: self.0, column: self.0,
scope,
} }
} }
} }