Fix debug info for structs

This commit is contained in:
Sofia 2025-07-31 23:25:46 +03:00
parent 4f0ee72c83
commit 4fada0036c
8 changed files with 57 additions and 241 deletions

10
examples/a.reid Normal file
View File

@ -0,0 +1,10 @@
struct Foo {
a: i32,
b: i32,
}
fn main() -> i32 {
// ISSUE: The debugger says b is 1
let foos = [Foo { a: 1, b: 2}];
return 0;
}

View File

@ -540,7 +540,7 @@ impl DebugTypeHolder {
field.pos.map(|p| p.line).unwrap_or(1),
field.size_bits,
0,
1,
field.offset,
field.flags.as_llvm(),
*debug.types.get(&field.ty).unwrap(),
)

View File

@ -1,4 +1,4 @@
use reid_lib::{CmpPredicate, ConstValueKind, Instr, Type, builder::InstructionValue};
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type};
use crate::{
codegen::{ErrorKind, StackValueKind},
@ -377,7 +377,9 @@ impl IntrinsicFunction for IntrinsicSizeOf {
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> {
let instr = scope
.block
.build(Instr::Constant(reid_lib::ConstValueKind::U64(self.0.size_of() / 8)))
.build(Instr::Constant(reid_lib::ConstValueKind::U64(
self.0.size_of(&scope.type_map) / 8,
)))
.unwrap();
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
}
@ -395,7 +397,9 @@ impl IntrinsicFunction for IntrinsicMalloc {
let sizeof = scope
.block
.build(Instr::Constant(ConstValueKind::U64(self.0.size_of() / 8)))
.build(Instr::Constant(ConstValueKind::U64(
self.0.size_of(&scope.type_map) / 8,
)))
.unwrap();
let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap();
let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap();

View File

@ -144,6 +144,7 @@ impl mir::Module {
let mut types = HashMap::new();
let mut type_values = HashMap::new();
let mut debug_types = HashMap::new();
let mut type_map = HashMap::new();
macro_rules! insert_debug {
($kind:expr) => {
@ -153,8 +154,7 @@ impl mir::Module {
&compile_unit,
&debug,
&debug_types,
&type_values,
&types,
&type_map,
self.module_id,
&self.tokens,
&modules,
@ -182,6 +182,8 @@ impl mir::Module {
for typedef in typedefs {
let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module);
type_map.insert(type_key.clone(), typedef.clone());
let type_value = match &typedef.kind {
TypeDefinitionKind::Struct(StructType(fields)) => {
module.custom_type(CustomTypeKind::NamedStruct(NamedStruct(
@ -198,6 +200,7 @@ impl mir::Module {
};
types.insert(type_value, typedef.clone());
type_values.insert(type_key.clone(), type_value);
insert_debug!(&TypeKind::CustomType(type_key.clone()));
}
@ -380,6 +383,7 @@ impl mir::Module {
functions: &functions,
types: &types,
type_values: &type_values,
type_map: &type_map,
globals: &globals,
stack_values: HashMap::new(),
debug: Some(Debug {
@ -457,6 +461,7 @@ impl mir::Module {
functions: &functions,
types: &types,
type_values: &type_values,
type_map: &type_map,
stack_values: HashMap::new(),
debug: Some(Debug {
info: &debug,
@ -518,6 +523,7 @@ impl mir::Module {
functions: &functions,
types: &types,
type_values: &type_values,
type_map: &type_map,
stack_values: HashMap::new(),
debug: Some(Debug {
info: &debug,
@ -1388,7 +1394,11 @@ impl mir::Expression {
.build(Instr::Alloca(ty.get_type(scope.type_values)))
.unwrap();
scope.block.build(Instr::Store(allocated, value)).unwrap();
scope
.block
.build(Instr::Store(allocated, value))
.unwrap()
.maybe_location(&mut scope.block, location.clone());
let a = Some(StackValue(
StackValueKind::Literal(allocated),

View File

@ -26,6 +26,7 @@ pub struct Scope<'ctx, 'scope> {
pub(super) block: Block<'ctx>,
pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>,
pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>,
pub(super) type_map: &'scope HashMap<CustomTypeKey, TypeDefinition>,
pub(super) assoc_functions: &'scope HashMap<AssociatedFunctionKey, ScopeFunctionKind<'ctx>>,
pub(super) functions: &'scope HashMap<String, ScopeFunctionKind<'ctx>>,
pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>,
@ -49,6 +50,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
functions: self.functions,
types: self.types,
type_values: self.type_values,
type_map: self.type_map,
stack_values: self.stack_values.clone(),
debug: self.debug.clone(),
allocator: self.allocator.clone(),

View File

@ -109,8 +109,7 @@ impl TypeKind {
&debug.scope,
debug.info,
debug.types,
scope.type_values,
scope.types,
scope.type_map,
scope.module_id,
scope.tokens,
scope.modules,
@ -122,8 +121,7 @@ impl TypeKind {
scope: &DebugScopeValue,
debug_info: &DebugInformation,
debug_types: &HashMap<TypeKind, DebugTypeValue>,
type_values: &HashMap<CustomTypeKey, TypeValue>,
types: &HashMap<TypeValue, TypeDefinition>,
type_map: &HashMap<CustomTypeKey, TypeDefinition>,
local_mod: SourceModuleId,
tokens: &Vec<FullToken>,
modules: &HashMap<SourceModuleId, ModuleCodegen>,
@ -142,13 +140,12 @@ impl TypeKind {
scope,
debug_info,
debug_types,
type_values,
types,
type_map,
local_mod,
tokens,
modules,
),
size_bits: self.size_of(),
size_bits: self.size_of(type_map),
})
}
TypeKind::Array(elem_ty, len) => {
@ -156,21 +153,20 @@ impl TypeKind {
scope,
debug_info,
debug_types,
type_values,
types,
type_map,
local_mod,
tokens,
modules,
);
DebugTypeData::Array(DebugArrayType {
size_bits: self.size_of(),
size_bits: self.size_of(type_map),
align_bits: self.alignment(),
element_type: elem_ty,
length: *len,
})
}
TypeKind::CustomType(key) => {
let typedef = types.get(type_values.get(key).unwrap()).unwrap();
let typedef = type_map.get(key).unwrap();
match &typedef.kind {
TypeDefinitionKind::Struct(struct_type) => {
let mut fields = Vec::new();
@ -186,21 +182,20 @@ impl TypeKind {
name: field.0.clone(),
scope: scope.clone(),
pos: location.map(|l| l.pos),
size_bits: field.1.size_of(),
size_bits: field.1.size_of(type_map),
offset: size_bits,
flags: DwarfFlags,
ty: field.1.get_debug_type_hard(
scope,
debug_info,
debug_types,
type_values,
types,
type_map,
local_mod,
tokens,
modules,
),
});
size_bits += field.1.size_of();
size_bits += field.1.size_of(type_map);
}
{
let location = if typedef.source_module != local_mod {
@ -222,7 +217,7 @@ impl TypeKind {
}
_ => DebugTypeData::Basic(DebugBasicType {
name,
size_bits: self.size_of(),
size_bits: self.size_of(type_map),
encoding: match self {
TypeKind::Bool => DwarfEncoding::Boolean,
TypeKind::I8 => DwarfEncoding::SignedChar,

View File

@ -1,3 +1,5 @@
use reid_lib::builder::TypeValue;
use crate::util::maybe;
use super::{typecheck::typerefs::TypeRefs, *};
@ -57,7 +59,7 @@ impl TypeKind {
}
}
pub fn size_of(&self) -> u64 {
pub fn size_of(&self, map: &HashMap<CustomTypeKey, TypeDefinition>) -> u64 {
match self {
TypeKind::Bool => 1,
TypeKind::I8 => 8,
@ -72,8 +74,16 @@ impl TypeKind {
TypeKind::U128 => 128,
TypeKind::Void => 0,
TypeKind::Char => 8,
TypeKind::Array(type_kind, len) => type_kind.size_of() * (*len as u64),
TypeKind::CustomType(..) => 32,
TypeKind::Array(type_kind, len) => type_kind.size_of(map) * (*len as u64),
TypeKind::CustomType(key) => match &map.get(key).unwrap().kind {
TypeDefinitionKind::Struct(struct_type) => {
let mut size = 0;
for field in &struct_type.0 {
size += field.1.size_of(map)
}
size
}
},
TypeKind::CodegenPtr(_) => 64,
TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"),
TypeKind::Borrow(..) => 64,

215
test.reid
View File

@ -1,215 +0,0 @@
////////////
/// math ///
////////////
struct Vec2 { x: f32, y: f32 }
impl Vec2 {
pub fn zero() -> Vec2 { Vec2 { x: 0.0, y: 0.0 } }
pub fn at(x: f32, y: f32) -> Vec2 { Vec2 { x: x, y: y } }
}
//impl binop ()
///////////////////
/// SDL externs ///
///////////////////
struct SDL_FPoint { x: f32, y: f32 }
struct SDL_FColor { r: f32, g: f32, b: f32, a: f32 }
struct SDL_Vertex { position: SDL_FPoint, color: SDL_FColor, tex_coord: SDL_FPoint }
impl SDL_Vertex {
pub fn new() -> SDL_Vertex {
SDL_Vertex {
position: SDL_FPoint { x: 0.0, y: 0.0 },
color: SDL_FColor { r: 1.0, g: 0.0, b: 1.0, a: 1.0 },
tex_coord: SDL_FPoint { x: 0.0, y: 0.0 },
}
}
pub fn pos(self, pos: Vec2) -> SDL_Vertex {
return SDL_Vertex {
position: SDL_FPoint { x: pos.x, y: pos.y },
color: self.color,
tex_coord: self.tex_coord,
};
}
pub fn col(self, color: [f32; 3]) -> SDL_Vertex {
return SDL_Vertex {
position: self.position,
color: [color[0], color[1], color[2], self.color.a],
tex_coord: self.tex_coord,
};
}
}
struct SDL_Window {}
struct SDL_Renderer {}
struct SDL_Texture {}
struct SDL_Event { type: u32, reserved: [u8; 124] }
struct SDL_FRect { x: f32, y: f32, w: f32, h: f32 }
struct SDL_Rect { x: i32, y: i32, w: i32, h: i32 }
extern fn SDL_malloc(size: u64) -> *u8;
extern fn SDL_Init(flags: u32) -> bool;
extern fn SDL_Quit();
extern fn SDL_CreateWindowAndRenderer(title: *char, width: i32, height: i32, flags: i32,
window_out: &mut *SDL_Window, renderer_out: &mut *SDL_Renderer) -> bool;
extern fn SDL_Delay(ms: u32);
extern fn SDL_SetRenderDrawColor(renderer: *SDL_Renderer, r: u8, g: u8, b: u8, a: u8);
extern fn SDL_RenderClear(renderer: *SDL_Renderer);
extern fn SDL_RenderPresent(renderer: *SDL_Renderer);
extern fn SDL_HasEvent(event_type: u32) -> bool;
extern fn SDL_PollEvent(event: &mut SDL_Event) -> bool;
extern fn SDL_PumpEvents();
extern fn SDL_FlushEvents(min_type: u32, max_type: u32);
extern fn SDL_GetTicks() -> u64;
extern fn SDL_SetWindowTitle(window: *SDL_Window, title: *char) -> bool;
extern fn SDL_CreateTexture(renderer: *SDL_Renderer,
pixel_format: u32, texture_access: u32, width: u32, height: u32) -> *SDL_Texture;
extern fn SDL_RenderTexture(renderer: *SDL_Renderer,
texture: *SDL_Texture, srcfrect: &SDL_FRect, dstfrect: &SDL_FRect) -> bool;
extern fn SDL_UpdateTexture(texture: *SDL_Texture, rect: &SDL_Rect, pixels: *u8, pitch: u32) -> bool;
extern fn SDL_GetError() -> *char;
extern fn SDL_GetWindowSize(window: *SDL_Window, w: &mut i32, h: &mut i32) -> bool;
extern fn SDL_rand(max_exclusive: u32) -> u32;
extern fn SDL_SetTextureScaleMode(texture: *SDL_Texture, scale_mode: i32) -> bool;
extern fn SDL_sqrtf(value: f32) -> f32;
extern fn SDL_randf() -> f32;
extern fn SDL_powf(value: f32, power: f32) -> f32;
extern fn exit(exit_code: i32);
extern fn SDL_RenderGeometry(renderer: *SDL_Renderer, texture: *SDL_Texture,
vertices: *SDL_Vertex, num_vertices: i32, indices: *i32, num_indices: i32) -> bool;
// SDL error reporting helper
import std::print;
import std::String;
fn print_sdl_error(context: *char) {
let mut message = String::new();
message = message + context + ": " + SDL_GetError();
print(message);
message.free();
}
////////////////
/// the game ///
////////////////
struct Ship {
position: Vec2,
}
struct Game {
ship: Ship,
}
impl Game {
pub fn new() -> Game {
Game {
ship: Ship {
position: Vec2::zero(),
},
}
}
pub fn run_frame(&mut self, dt: f32, renderer: *SDL_Renderer, aspect_ratio: f32) {
let ship = *self.ship;
let vertices = [
SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]),
SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]),
SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0])
];
let borrow: &[SDL_Vertex; 3] = &vertices;
SDL_RenderGeometry(renderer, SDL_Texture::null(),
borrow as *SDL_Vertex, 3, i32::null(), 0);
// TODO: add a ship
// TODO: wind sim
// TODO: wave sim
}
}
////////////////
/// the game ///
////////////////
struct Platform {
window: *SDL_Window,
renderer: *SDL_Renderer,
game: Game,
last_frame_ticks: u64,
}
impl Platform {
pub fn new() -> Platform {
let SDL_INIT_VIDEO = 32;
let SDL_WINDOW_RESIZABLE = 32;
let init_success = SDL_Init(SDL_INIT_VIDEO);
if init_success == false {
print_sdl_error("SDL init failed");
return exit(1);
}
let mut window = SDL_Window::null();
let mut renderer = SDL_Renderer::null();
let mut window_title = "Yacht Reid";
let gfx_init_success = SDL_CreateWindowAndRenderer(
window_title, 640, 480, SDL_WINDOW_RESIZABLE,
&mut window, &mut renderer
);
if gfx_init_success == false {
print_sdl_error("SDL renderer and window creation failed");
return exit(1);
}
return Platform {
window: window,
renderer: renderer,
game: Game::new(),
last_frame_ticks: SDL_GetTicks(),
};
}
pub fn run_frame(&mut self) -> bool {
let mut event = SDL_Event { type: 0, reserved: [0; 124] };
while (SDL_PollEvent(&mut event)) {
if event.type == 256 { // SDL_EVENT_QUIT
return false;
}
}
let now = SDL_GetTicks();
let dt = (now - *self.last_frame_ticks) as f32 / 1000.0;
*self.last_frame_ticks = now;
let mut screen_width = 0;
let mut screen_height = 0;
SDL_GetWindowSize(*self.window, &mut screen_width, &mut screen_height);
let aspect_ratio = screen_width as f32 / screen_height as f32;
SDL_SetRenderDrawColor(*self.renderer, 0, 50, 90, 255);
SDL_RenderClear(*self.renderer);
*self.game.run_frame(dt, *self.renderer, aspect_ratio);
SDL_RenderPresent(*self.renderer);
return true;
}
pub fn cleanup(&mut self) {
SDL_Quit();
}
}
////////////
/// main ///
////////////
fn main() -> i32 {
let mut platform = Platform::new();
while platform.run_frame() {}
return 0;
}