Compare commits

..

No commits in common. "726251e39cdbeb611fe36185d6d914663b13100d" and "a60d35c0b007434dcfd043e6fa2bc5ee45132345" have entirely different histories.

17 changed files with 286 additions and 342 deletions

View File

@ -1,6 +0,0 @@
pub fn main() -> u32 {
let b = 4;
let c = b + 4;
return c;
}

View File

@ -7,7 +7,7 @@ use crate::{
Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, ModuleData, Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, ModuleData,
NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData,
debug_information::{ debug_information::{
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugScopeValue, InstructionDebugRecordData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, InstructionDebugRecordData,
}, },
util::match_types, util::match_types,
}; };
@ -47,8 +47,6 @@ 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)]
@ -119,7 +117,6 @@ impl Builder {
value, value,
data, data,
blocks: Vec::new(), blocks: Vec::new(),
debug_info: None,
}); });
value value
} }
@ -201,12 +198,12 @@ impl Builder {
} }
} }
pub(crate) unsafe fn set_debug_subprogram(&self, value: &FunctionValue, subprogram: DebugScopeValue) { pub(crate) unsafe fn set_debug_subprogram(&self, value: &FunctionValue, subprogram: DebugProgramValue) {
unsafe { unsafe {
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.debug_info = Some(subprogram) function.data.debug = Some(subprogram)
} }
} }

View File

@ -3,7 +3,6 @@
//! 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},
}; };
@ -207,11 +206,12 @@ impl<'a> Drop for LLVMModule<'a> {
} }
pub struct LLVMDebugInformation<'a> { pub struct LLVMDebugInformation<'a> {
info: &'a DebugInformation, debug: &'a DebugInformation,
builder: LLVMDIBuilderRef, builder: LLVMDIBuilderRef,
file_ref: LLVMMetadataRef, file_ref: LLVMMetadataRef,
scopes: &'a mut HashMap<DebugScopeValue, LLVMMetadataRef>, // scopes: &'a HashMap<DebugScopeValue, LLVMMetadataRef>,
types: &'a mut HashMap<DebugTypeValue, LLVMMetadataRef>, types: &'a mut HashMap<DebugTypeValue, LLVMMetadataRef>,
programs: &'a mut HashMap<DebugProgramValue, 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>,
} }
@ -238,7 +238,7 @@ impl ModuleHolder {
let mut types = HashMap::new(); let mut types = HashMap::new();
let mut metadata = HashMap::new(); let mut metadata = HashMap::new();
let mut scopes = HashMap::new(); let mut programs = HashMap::new();
let mut locations = HashMap::new(); let mut locations = HashMap::new();
let mut debug = if let Some(debug) = &self.debug_information { let mut debug = if let Some(debug) = &self.debug_information {
@ -294,19 +294,19 @@ impl ModuleHolder {
// } // }
// dbg!("after!"); // dbg!("after!");
scopes.insert(DebugScopeValue(Vec::new()), compile_unit); programs.insert(DebugProgramValue(0), compile_unit);
let debug = LLVMDebugInformation { let debug = LLVMDebugInformation {
builder: di_builder, builder: di_builder,
info: debug, debug: debug,
file_ref, file_ref,
types: &mut types, types: &mut types,
metadata: &mut metadata, metadata: &mut metadata,
scopes: &mut scopes, programs: &mut programs,
locations: &mut locations, locations: &mut locations,
}; };
for ty in debug.info.get_types().borrow().iter() { for ty in debug.debug.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);
} }
@ -322,28 +322,23 @@ 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, &mut debug); let func = function.compile_signature(context, module_ref, &types, &debug);
functions.insert(function.value, func); functions.insert(function.value, func);
if let (Some(debug), Some(debug_info)) = (&mut debug, &function.debug_info) { if let Some(debug) = &mut debug {
let scope_refcell = debug.info.get_scope(); if let Some(program_value) = function.data.debug {
let mut scope = scope_refcell.borrow(); debug.programs.insert(program_value, func.metadata.unwrap());
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.info.get_locations().borrow().iter() { for location in debug.debug.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, location_ref);
} }
for meta in debug.info.get_metadatas().borrow().iter() { for meta in debug.debug.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);
} }
@ -381,7 +376,7 @@ impl DebugLocationHolder {
context.context_ref, context.context_ref,
self.location.pos.line, self.location.pos.line,
self.location.pos.column, self.location.pos.column,
*debug.scopes.get(&self.scope).unwrap(), *debug.programs.get(&self.program).unwrap(),
null_mut(), null_mut(),
) )
} }
@ -397,16 +392,10 @@ impl DebugScopeHolder {
di_builder: LLVMDIBuilderRef, di_builder: LLVMDIBuilderRef,
) { ) {
unsafe { unsafe {
let scope = match &self.data.kind { let scope = if let Some(location) = &self.location {
DebugScopeKind::CodegenContext => panic!(), LLVMDIBuilderCreateLexicalBlock(di_builder, parent, file, location.pos.line, location.pos.column)
DebugScopeKind::LexicalScope => LLVMDIBuilderCreateLexicalBlock( } else {
di_builder, LLVMDIBuilderCreateLexicalBlockFile(di_builder, parent, file, 0)
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 {
@ -424,7 +413,7 @@ impl DebugMetadataHolder {
match &self.data { match &self.data {
DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable( DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable(
debug.builder, debug.builder,
*debug.scopes.get(&self.location.scope).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,
@ -436,7 +425,7 @@ impl DebugMetadataHolder {
), ),
DebugMetadata::LocalVar(var) => LLVMDIBuilderCreateAutoVariable( DebugMetadata::LocalVar(var) => LLVMDIBuilderCreateAutoVariable(
debug.builder, debug.builder,
*debug.scopes.get(&self.location.scope).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,
@ -506,7 +495,7 @@ impl DebugTypeHolder {
.map(|field| { .map(|field| {
LLVMDIBuilderCreateMemberType( LLVMDIBuilderCreateMemberType(
debug.builder, debug.builder,
*debug.scopes.get(&st.scope).unwrap(), *debug.programs.get(&st.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,
@ -521,7 +510,7 @@ impl DebugTypeHolder {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
LLVMDIBuilderCreateStructType( LLVMDIBuilderCreateStructType(
debug.builder, debug.builder,
*debug.scopes.get(&st.scope).unwrap(), *debug.programs.get(&st.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,
@ -574,7 +563,7 @@ impl FunctionHolder {
context: &LLVMContext, context: &LLVMContext,
module_ref: LLVMModuleRef, module_ref: LLVMModuleRef,
types: &HashMap<TypeValue, LLVMTypeRef>, types: &HashMap<TypeValue, LLVMTypeRef>,
debug: &mut Option<LLVMDebugInformation>, debug: &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);
@ -597,37 +586,30 @@ impl FunctionHolder {
} }
let metadata = if let Some(debug) = debug { let metadata = if let Some(debug) = debug {
if let Some(scope_value) = &self.debug_info { if let Some(value) = &self.data.debug {
let scope_data = debug.info.get_scope_data(scope_value).unwrap(); let subprogram = debug.debug.get_subprogram_data_unchecked(&value);
dbg!(&debug.info.get_scope());
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_data.kind { let subprogram = LLVMDIBuilderCreateFunction(
DebugScopeKind::CodegenContext => panic!(), debug.builder,
DebugScopeKind::LexicalScope => panic!(), *debug.programs.get(&subprogram.outer_scope).unwrap(),
DebugScopeKind::Subprogram(subprogram) => LLVMDIBuilderCreateFunction( into_cstring(subprogram.name.clone()).as_ptr(),
debug.builder, subprogram.name.clone().len(),
*debug.scopes.get(&scope_data.parent.unwrap()).unwrap(), mangled_name,
into_cstring(subprogram.name.clone()).as_ptr(), mangled_length,
subprogram.name.clone().len(), debug.file_ref,
mangled_name, subprogram.location.pos.line,
mangled_length, *debug.types.get(&subprogram.ty).unwrap(),
debug.file_ref, subprogram.opts.is_local as i32,
subprogram.location.pos.line, subprogram.opts.is_definition as i32,
*debug.types.get(&subprogram.ty).unwrap(), subprogram.opts.scope_line,
subprogram.opts.is_local as i32, subprogram.opts.flags.as_llvm(),
subprogram.opts.is_definition as i32, subprogram.opts.is_optimized as i32,
subprogram.opts.scope_line, );
subprogram.opts.flags.as_llvm(),
subprogram.opts.is_optimized as i32,
),
};
LLVMSetSubprogram(function_ref, subprogram); LLVMSetSubprogram(function_ref, subprogram);
debug.scopes.insert(scope_value.clone(), subprogram);
Some(subprogram) Some(subprogram)
} else { } else {
None None
@ -1031,7 +1013,7 @@ impl InstructionHolder {
module.context_ref, module.context_ref,
record.location.pos.line, record.location.pos.line,
record.location.pos.column, record.location.pos.column,
*debug.scopes.get(&record.scope).unwrap(), *debug.programs.get(&record.scope).unwrap(),
null_mut(), null_mut(),
); );

View File

@ -1,16 +1,12 @@
use std::{ use std::{cell::RefCell, rc::Rc};
cell::{Ref, RefCell, RefMut},
rc::Rc,
};
use crate::builder::InstructionValue; use crate::builder::InstructionValue;
/// Represents 1. the compilation context, 2. subprogram or 3. a lexical scope
#[derive(Clone, Hash, PartialEq, Eq)] #[derive(Clone, Hash, PartialEq, Eq)]
pub struct DebugScopeValue(pub Vec<usize>); pub struct DebugScopeValue(pub Vec<usize>);
#[derive(Clone, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub struct DebugLocationValue(pub DebugScopeValue, pub usize); pub struct DebugLocationValue(pub DebugProgramValue, pub usize);
#[derive(Clone, Copy, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub struct DebugTypeValue(pub usize); pub struct DebugTypeValue(pub usize);
@ -18,6 +14,10 @@ pub struct DebugTypeValue(pub usize);
#[derive(Clone, Copy, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub struct DebugMetadataValue(pub usize); 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)] #[derive(Debug, Clone)]
pub struct DebugFileData { pub struct DebugFileData {
pub name: String, pub name: String,
@ -27,8 +27,9 @@ pub struct DebugFileData {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct DebugScopeHolder { pub(crate) struct DebugScopeHolder {
pub(crate) value: DebugScopeValue, pub(crate) value: DebugScopeValue,
pub(crate) data: DebugScopeData, pub(crate) location: Option<DebugLocation>,
pub(crate) inner_scopes: Vec<DebugScopeHolder>, pub(crate) inner_scopes: Vec<DebugScopeHolder>,
pub(crate) locations: Vec<DebugLocationHolder>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -44,9 +45,15 @@ pub struct DebugTypeHolder {
pub(crate) data: DebugTypeData, pub(crate) data: DebugTypeData,
} }
#[derive(Debug, Clone)]
pub struct DebugSubprogramHolder {
pub(crate) _value: DebugProgramValue,
pub(crate) data: DebugSubprogramData,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct DebugLocationHolder { pub(crate) struct DebugLocationHolder {
pub(crate) scope: DebugScopeValue, pub(crate) program: DebugProgramValue,
pub(crate) value: DebugLocationValue, pub(crate) value: DebugLocationValue,
pub(crate) location: DebugLocation, pub(crate) location: DebugLocation,
} }
@ -54,68 +61,68 @@ pub(crate) struct DebugLocationHolder {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DebugInformation { pub struct DebugInformation {
pub file: DebugFileData, pub file: DebugFileData,
scope: Rc<RefCell<DebugScopeHolder>>, // scope: Rc<RefCell<DebugScopeHolder>>,
locations: Rc<RefCell<Vec<DebugLocationHolder>>>, locations: Rc<RefCell<Vec<DebugLocationHolder>>>,
programs: Rc<RefCell<Vec<DebugSubprogramHolder>>>,
metadata: Rc<RefCell<Vec<DebugMetadataHolder>>>, metadata: Rc<RefCell<Vec<DebugMetadataHolder>>>,
types: Rc<RefCell<Vec<DebugTypeHolder>>>, types: Rc<RefCell<Vec<DebugTypeHolder>>>,
} }
impl DebugInformation { impl DebugInformation {
pub fn from_file(file: DebugFileData) -> (DebugInformation, DebugScopeValue) { pub fn from_file(file: DebugFileData) -> (DebugInformation, DebugProgramValue) {
let scope_value = DebugScopeValue(Vec::new());
( (
DebugInformation { DebugInformation {
file, file,
scope: Rc::new(RefCell::new(DebugScopeHolder { // scope: Rc::new(RefCell::new(DebugScopeHolder {
value: scope_value.clone(), // value: scope_value.clone(),
inner_scopes: Vec::new(), // inner_scopes: Vec::new(),
data: DebugScopeData { // locations: Vec::new(),
parent: None, // location: None,
location: Some(DebugLocation { // })),
scope: DebugScopeValue(Vec::new()),
pos: DebugPosition { line: 0, column: 0 },
}),
kind: DebugScopeKind::CodegenContext,
},
})),
locations: Rc::new(RefCell::new(Vec::new())), locations: Rc::new(RefCell::new(Vec::new())),
metadata: 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())), types: Rc::new(RefCell::new(Vec::new())),
}, },
scope_value, DebugProgramValue(0),
) )
} }
pub fn inner_scope(&self, parent: &DebugScopeValue, location: DebugLocation) -> DebugScopeValue { // pub fn inner_scope(
unsafe { // &self,
let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| { // parent: &DebugScopeValue,
for i in &parent.0 { // location: DebugLocation,
v = v.inner_scopes.get_unchecked_mut(*i); // ) -> DebugScopeValue {
} // unsafe {
v // 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(); // let mut arr = parent.0.clone();
arr.push(parent.0.len()); // arr.push(parent.0.len());
let value = DebugScopeValue(arr); // let value = DebugScopeValue(arr);
outer_scope.inner_scopes.push(DebugScopeHolder { // outer_scope.inner_scopes.push(DebugScopeHolder {
value: value.clone(), // value: value.clone(),
inner_scopes: Vec::new(), // inner_scopes: Vec::new(),
data: DebugScopeData { // locations: Vec::new(),
parent: Some(parent.clone()), // location: Some(location),
location: Some(location), // });
kind: DebugScopeKind::LexicalScope, // value
}, // }
}); // }
value
}
}
pub fn location(&self, scope_value: &DebugScopeValue, location: DebugLocation) -> DebugLocationValue { pub fn location(
let value = DebugLocationValue(scope_value.clone(), self.locations.borrow().len()); &self,
program_value: &DebugProgramValue,
location: DebugLocation,
) -> DebugLocationValue {
let value = DebugLocationValue(program_value.clone(), self.locations.borrow().len());
let location = DebugLocationHolder { let location = DebugLocationHolder {
scope: scope_value.clone(), program: *program_value,
value: value.clone(), value: value.clone(),
location, location,
}; };
@ -137,37 +144,21 @@ impl DebugInformation {
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 {
location: location.clone(), location: *location,
value: value.clone(), value: value.clone(),
data: kind, data: kind,
}); });
value value
} }
pub fn subprogram(&self, parent: DebugScopeValue, kind: DebugSubprogramData) -> DebugScopeValue { pub fn subprogram(&self, kind: DebugSubprogramData) -> DebugProgramValue {
unsafe { let mut subprogram = self.programs.borrow_mut();
let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| { let value = DebugProgramValue(subprogram.len() + 1);
for i in &parent.0 { subprogram.push(DebugSubprogramHolder {
v = v.inner_scopes.get_unchecked_mut(*i); _value: value.clone(),
} data: kind,
v });
}); value
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()),
location: None,
kind: DebugScopeKind::Subprogram(kind),
},
});
value
}
} }
pub fn get_metadata(&self, value: DebugMetadataValue) -> DebugMetadata { pub fn get_metadata(&self, value: DebugMetadataValue) -> DebugMetadata {
@ -175,24 +166,14 @@ impl DebugInformation {
} }
pub fn get_metadata_location(&self, value: DebugMetadataValue) -> DebugLocation { pub fn get_metadata_location(&self, value: DebugMetadataValue) -> DebugLocation {
unsafe { self.metadata.borrow().get_unchecked(value.0).location.clone() } unsafe { self.metadata.borrow().get_unchecked(value.0).location }
} }
pub fn get_scope_data(&self, value: &DebugScopeValue) -> Option<DebugScopeData> { pub fn get_subprogram_data(&self, value: DebugProgramValue) -> Option<DebugSubprogramData> {
let scope = Ref::filter_map(self.scope.borrow(), |v: &DebugScopeHolder| { if value.0 == 0 {
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 {
None None
} else {
Some(self.get_subprogram_data_unchecked(&value))
} }
} }
@ -200,16 +181,26 @@ impl DebugInformation {
unsafe { self.types.borrow().get_unchecked(value.0).data.clone() } unsafe { self.types.borrow().get_unchecked(value.0).data.clone() }
} }
pub fn get_location(&self, value: &DebugLocationValue) -> DebugLocation { pub fn get_location(&self, value: DebugLocationValue) -> DebugLocation {
unsafe { self.locations.borrow().get_unchecked(value.1).location.clone() } unsafe {
self.locations
.borrow()
.get_unchecked(value.1)
.location
.clone()
}
} }
pub fn get_metadatas(&self) -> Rc<RefCell<Vec<DebugMetadataHolder>>> { pub fn get_metadatas(&self) -> Rc<RefCell<Vec<DebugMetadataHolder>>> {
self.metadata.clone() self.metadata.clone()
} }
pub(crate) fn get_scope(&self) -> Rc<RefCell<DebugScopeHolder>> { // pub fn get_scopes(&self) -> Rc<RefCell<DebugScopeHolder>> {
self.scope.clone() // self.scope.clone()
// }
pub fn get_subprograms(&self) -> Rc<RefCell<Vec<DebugSubprogramHolder>>> {
self.programs.clone()
} }
pub fn get_types(&self) -> Rc<RefCell<Vec<DebugTypeHolder>>> { pub fn get_types(&self) -> Rc<RefCell<Vec<DebugTypeHolder>>> {
@ -219,11 +210,21 @@ impl DebugInformation {
pub(crate) fn get_locations(&self) -> Rc<RefCell<Vec<DebugLocationHolder>>> { pub(crate) fn get_locations(&self) -> Rc<RefCell<Vec<DebugLocationHolder>>> {
self.locations.clone() 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)] #[derive(Clone, Copy)]
pub struct DebugLocation { pub struct DebugLocation {
pub scope: DebugScopeValue, pub scope: DebugProgramValue,
pub pos: DebugPosition, pub pos: DebugPosition,
} }
@ -314,7 +315,7 @@ pub struct DebugPointerType {
#[derive(Clone)] #[derive(Clone)]
pub struct DebugStructType { pub struct DebugStructType {
pub name: String, pub name: String,
pub scope: DebugScopeValue, pub scope: DebugProgramValue,
pub pos: Option<DebugPosition>, pub pos: Option<DebugPosition>,
pub size_bits: u64, pub size_bits: u64,
pub flags: DwarfFlags, pub flags: DwarfFlags,
@ -324,7 +325,7 @@ pub struct DebugStructType {
#[derive(Clone)] #[derive(Clone)]
pub struct DebugFieldType { pub struct DebugFieldType {
pub name: String, pub name: String,
pub scope: DebugScopeValue, pub scope: DebugProgramValue,
pub pos: Option<DebugPosition>, pub pos: Option<DebugPosition>,
pub size_bits: u64, pub size_bits: u64,
pub offset: u64, pub offset: u64,
@ -349,25 +350,11 @@ pub enum DwarfEncoding {
UnsignedChar = 8, UnsignedChar = 8,
} }
#[derive(Debug, Clone)]
pub struct DebugScopeData {
pub parent: Option<DebugScopeValue>,
pub location: Option<DebugLocation>,
pub kind: DebugScopeKind,
}
#[derive(Debug, Clone)]
pub enum DebugScopeKind {
CodegenContext,
LexicalScope,
Subprogram(DebugSubprogramData),
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DebugSubprogramData { pub struct DebugSubprogramData {
/// Function name. /// Function name.
pub name: String, pub name: String,
pub outer_scope: DebugScopeValue, pub outer_scope: DebugProgramValue,
/// Used for line number. /// Used for line number.
pub location: DebugLocation, pub location: DebugLocation,
/// Function type. /// Function type.
@ -389,7 +376,7 @@ pub struct DebugSubprogramOptionals {
#[derive(Clone)] #[derive(Clone)]
pub struct InstructionDebugRecordData { pub struct InstructionDebugRecordData {
pub scope: DebugScopeValue, pub scope: DebugProgramValue,
pub variable: DebugMetadataValue, pub variable: DebugMetadataValue,
pub location: DebugLocation, pub location: DebugLocation,
pub kind: DebugRecordKind, pub kind: DebugRecordKind,

View File

@ -11,8 +11,8 @@ use crate::{
debug_information::{ debug_information::{
DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, DebugLocation, DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, DebugLocation,
DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugPointerType, DebugPosition, DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugPointerType, DebugPosition,
DebugRecordKind, DebugScopeValue, DebugStructType, DebugSubprogramType, DebugTypeData, DebugTypeHolder, DebugProgramValue, DebugRecordKind, DebugScopeValue, DebugStructType, DebugSubprogramType, DebugTypeData,
DebugTypeValue, DebugTypeHolder, DebugTypeValue,
}, },
pad_adapter::PadAdapter, pad_adapter::PadAdapter,
}; };
@ -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.debug_info { if let Some(debug) = self.data.debug {
writeln!(inner, "(Debug = {:?})", debug)?; writeln!(inner, "(Debug = {:?})", debug)?;
} }
@ -111,7 +111,7 @@ impl BlockHolder {
if let Some(terminator) = &self.data.terminator { if let Some(terminator) = &self.data.terminator {
terminator.builder_fmt(&mut inner, builder, debug)?; 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))?; 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)?; writeln!(f, "{:?} ({}) = {:?} ", self.value, self.name, self.data.kind)?;
if let Some(debug) = debug { 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))?; writeln!(f, " ^ (At {}) ", debug.get_location(location))?;
} }
if let Some(meta) = self.data.meta { if let Some(meta) = self.data.meta {
@ -261,7 +261,7 @@ impl Debug for InstructionHolder {
impl Debug for InstructionData { impl Debug for InstructionData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.kind.fmt(f)?; self.kind.fmt(f)?;
if let Some(location) = &self.location { if let Some(location) = self.location {
write!(f, " ({:?})", location)?; write!(f, " ({:?})", location)?;
} }
Ok(()) Ok(())
@ -574,6 +574,12 @@ 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 { impl Debug for DebugLocationValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Value[{:?}][{}]", self.0, self.1) write!(f, "Value[{:?}][{}]", self.0, self.1)

View File

@ -5,11 +5,9 @@
use std::{fmt::Debug, marker::PhantomData}; use std::{fmt::Debug, marker::PhantomData};
use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue}; use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue};
use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue}; use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue};
use fmt::PrintableModule; use fmt::PrintableModule;
use crate::debug_information::DebugScopeValue;
pub mod builder; pub mod builder;
pub mod compile; pub mod compile;
pub mod debug_information; pub mod debug_information;
@ -78,6 +76,7 @@ impl<'ctx> Module<'ctx> {
ret, ret,
params, params,
flags, flags,
debug: None,
}, },
), ),
} }
@ -104,10 +103,10 @@ impl<'ctx> Module<'ctx> {
} }
} }
pub fn create_debug_info(&mut self, file: DebugFileData) -> (DebugInformation, DebugScopeValue) { pub fn create_debug_info(&mut self, file: DebugFileData) -> (DebugInformation, DebugProgramValue) {
let (debug_info, scope_value) = DebugInformation::from_file(file); let (debug_info, program_value) = DebugInformation::from_file(file);
self.debug_info = Some(debug_info.clone()); self.debug_info = Some(debug_info.clone());
(debug_info, scope_value) (debug_info, program_value)
} }
pub fn get_debug_info(&self) -> &Option<DebugInformation> { pub fn get_debug_info(&self) -> &Option<DebugInformation> {
@ -129,6 +128,7 @@ pub struct FunctionData {
ret: Type, ret: Type,
params: Vec<Type>, params: Vec<Type>,
flags: FunctionFlags, flags: FunctionFlags,
debug: Option<DebugProgramValue>,
} }
#[derive(Debug, Clone, Copy, Hash)] #[derive(Debug, Clone, Copy, Hash)]
@ -184,7 +184,7 @@ impl<'ctx> Function<'ctx> {
} }
} }
pub fn set_debug(&self, subprogram: DebugScopeValue) { pub fn set_debug(&self, subprogram: DebugProgramValue) {
unsafe { unsafe {
self.builder.set_debug_subprogram(&self.value, subprogram); self.builder.set_debug_subprogram(&self.value, subprogram);
} }
@ -546,7 +546,7 @@ impl ConstValue {
} }
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum TypeCategory { enum TypeCategory {
SignedInteger, SignedInteger,
UnsignedInteger, UnsignedInteger,
Void, Void,

View File

@ -122,8 +122,8 @@ pub enum BinaryOperator {
And, And,
Or, Or,
Xor, Xor,
BitAnd, BWAnd,
BitOr, BWOr,
LT, LT,
LE, LE,
GT, GT,
@ -141,8 +141,9 @@ impl BinaryOperator {
Mult => 15, Mult => 15,
Div => 20, Div => 20,
Mod => 20, Mod => 20,
BitAnd => 90, BWAnd => 90,
BitOr => 90, BWOr => 90,
BWXor => 90,
BitshiftLeft => 100, BitshiftLeft => 100,
BitshiftRight => 100, BitshiftRight => 100,
And => 150, And => 150,

View File

@ -518,8 +518,8 @@ impl Parse for BinaryOperator {
} }
(Some(Token::Hat), _) => BinaryOperator::Xor, (Some(Token::Hat), _) => BinaryOperator::Xor,
(Some(Token::Et), _) => BinaryOperator::BitAnd, (Some(Token::Et), _) => BinaryOperator::BWAnd,
(Some(Token::Pipe), _) => BinaryOperator::BitOr, (Some(Token::Pipe), _) => BinaryOperator::BWOr,
(Some(Token::LessThan), _) => BinaryOperator::LT, (Some(Token::LessThan), _) => BinaryOperator::LT,
(Some(Token::GreaterThan), _) => BinaryOperator::GT, (Some(Token::GreaterThan), _) => BinaryOperator::GT,

View File

@ -459,8 +459,8 @@ impl ast::BinaryOperator {
ast::BinaryOperator::BitshiftRight => mir::BinaryOperator::BitshiftRight, ast::BinaryOperator::BitshiftRight => mir::BinaryOperator::BitshiftRight,
ast::BinaryOperator::BitshiftLeft => mir::BinaryOperator::BitshiftLeft, ast::BinaryOperator::BitshiftLeft => mir::BinaryOperator::BitshiftLeft,
ast::BinaryOperator::Xor => mir::BinaryOperator::Xor, ast::BinaryOperator::Xor => mir::BinaryOperator::Xor,
ast::BinaryOperator::BitAnd => mir::BinaryOperator::BitAnd, ast::BinaryOperator::BWAnd => mir::BinaryOperator::BitAnd,
ast::BinaryOperator::BitOr => mir::BinaryOperator::BitOr, ast::BinaryOperator::BWOr => mir::BinaryOperator::BitOr,
} }
} }
} }

View File

@ -1,3 +1,5 @@
use std::ops::BitAnd;
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type}; use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type};
use crate::{ use crate::{

View File

@ -124,7 +124,7 @@ impl mir::Module {
debug_types.insert( debug_types.insert(
$kind.clone(), $kind.clone(),
$kind.get_debug_type_hard( $kind.get_debug_type_hard(
&compile_unit, compile_unit,
&debug, &debug,
&debug_types, &debug_types,
&type_values, &type_values,
@ -279,6 +279,7 @@ impl mir::Module {
binop.return_type.get_type(&type_values), binop.return_type.get_type(&type_values),
vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)], vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)],
FunctionFlags { FunctionFlags {
inline: true,
is_pub: binop.exported, is_pub: binop.exported,
is_imported: binop.exported, is_imported: binop.exported,
..Default::default() ..Default::default()
@ -310,7 +311,7 @@ impl mir::Module {
stack_values: HashMap::new(), stack_values: HashMap::new(),
debug: Some(Debug { debug: Some(Debug {
info: &debug, info: &debug,
scope: compile_unit.clone(), scope: compile_unit,
types: &debug_types, types: &debug_types,
}), }),
binops: &binops, binops: &binops,
@ -327,9 +328,7 @@ impl mir::Module {
&binop.return_type, &binop.return_type,
&ir_function, &ir_function,
match &binop.fn_kind { match &binop.fn_kind {
FunctionDefinitionKind::Local(_, meta) => { FunctionDefinitionKind::Local(_, meta) => meta.into_debug(tokens, compile_unit),
meta.into_debug(tokens, &compile_unit)
}
FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Extern(_) => None,
FunctionDefinitionKind::Intrinsic(_) => None, FunctionDefinitionKind::Intrinsic(_) => None,
}, },
@ -384,7 +383,7 @@ impl mir::Module {
stack_values: HashMap::new(), stack_values: HashMap::new(),
debug: Some(Debug { debug: Some(Debug {
info: &debug, info: &debug,
scope: compile_unit.clone(), scope: compile_unit,
types: &debug_types, types: &debug_types,
}), }),
binops: &binops, binops: &binops,
@ -402,7 +401,7 @@ impl mir::Module {
&function, &function,
match &mir_function.kind { match &mir_function.kind {
FunctionDefinitionKind::Local(..) => { FunctionDefinitionKind::Local(..) => {
mir_function.signature().into_debug(tokens, &compile_unit) mir_function.signature().into_debug(tokens, compile_unit)
} }
FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Extern(_) => None,
FunctionDefinitionKind::Intrinsic(_) => None, FunctionDefinitionKind::Intrinsic(_) => None,
@ -443,7 +442,7 @@ impl mir::Module {
stack_values: HashMap::new(), stack_values: HashMap::new(),
debug: Some(Debug { debug: Some(Debug {
info: &debug, info: &debug,
scope: compile_unit.clone(), scope: compile_unit,
types: &debug_types, types: &debug_types,
}), }),
binops: &binops, binops: &binops,
@ -461,7 +460,7 @@ impl mir::Module {
&function, &function,
match &mir_function.kind { match &mir_function.kind {
FunctionDefinitionKind::Local(..) => { FunctionDefinitionKind::Local(..) => {
mir_function.signature().into_debug(tokens, &compile_unit) mir_function.signature().into_debug(tokens, compile_unit)
} }
FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Extern(_) => None,
FunctionDefinitionKind::Intrinsic(_) => None, FunctionDefinitionKind::Intrinsic(_) => None,
@ -500,25 +499,22 @@ impl FunctionDefinitionKind {
flags: DwarfFlags, flags: DwarfFlags,
})); }));
let subprogram = debug.info.subprogram( let subprogram = debug.info.subprogram(DebugSubprogramData {
debug.scope.clone(), name: name.clone(),
DebugSubprogramData { outer_scope: debug.scope.clone(),
name: name.clone(), location,
outer_scope: debug.scope.clone(), ty: debug_ty,
location, opts: DebugSubprogramOptionals {
ty: debug_ty, is_local: !is_pub,
opts: DebugSubprogramOptionals { is_definition: true,
is_local: !is_pub, ..DebugSubprogramOptionals::default()
is_definition: true,
..DebugSubprogramOptionals::default()
},
}, },
); });
ir_function.set_debug(subprogram.clone()); ir_function.set_debug(subprogram);
scope.debug = Some(Debug { scope.debug = Some(Debug {
info: debug.info, info: debug.info,
scope: subprogram.clone(), scope: subprogram,
types: debug.types, types: debug.types,
}); });
} }
@ -586,8 +582,8 @@ impl FunctionDefinitionKind {
} }
if let Some(debug) = &scope.debug { if let Some(debug) = &scope.debug {
if let Some(location) = &block.return_meta().into_debug(scope.tokens, &debug.scope) { if let Some(location) = &block.return_meta().into_debug(scope.tokens, debug.scope) {
let location = debug.info.location(&debug.scope, location.clone()); let location = debug.info.location(&debug.scope, *location);
scope.block.set_terminator_location(location).unwrap(); scope.block.set_terminator_location(location).unwrap();
} }
} }
@ -608,7 +604,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, &debug.scope).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);
} }
@ -645,7 +641,7 @@ impl mir::Block {
impl mir::Statement { impl mir::Statement {
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Result<Option<StackValue>, ErrorKind> { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Result<Option<StackValue>, ErrorKind> {
let location = scope.debug.clone().map(|d| { 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) d.info.location(&d.scope, location)
}); });
@ -656,7 +652,7 @@ impl mir::Statement {
let alloca = scope let alloca = scope
.allocate(name, &value.1) .allocate(name, &value.1)
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
let store = scope let store = scope
.block .block
@ -674,7 +670,7 @@ 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, &debug.scope).unwrap(); let location = self.1.into_debug(scope.tokens, debug.scope).unwrap();
let var = debug.info.metadata( let var = debug.info.metadata(
&location, &location,
DebugMetadata::LocalVar(DebugLocalVariable { DebugMetadata::LocalVar(DebugLocalVariable {
@ -690,7 +686,7 @@ impl mir::Statement {
variable: var, variable: var,
location, location,
kind: DebugRecordKind::Declare(alloca), kind: DebugRecordKind::Declare(alloca),
scope: debug.scope.clone(), scope: debug.scope,
}, },
); );
} }
@ -781,7 +777,7 @@ impl mir::Expression {
Some( Some(
debug debug
.info .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 { } else {
None None
@ -855,12 +851,12 @@ impl mir::Expression {
.block .block
.build(Instr::UDiv(lhs, rhs)) .build(Instr::UDiv(lhs, rhs))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
let mul = scope let mul = scope
.block .block
.build(Instr::Mul(rhs, div)) .build(Instr::Mul(rhs, div))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
Instr::Sub(lhs, mul) Instr::Sub(lhs, mul)
} }
(mir::BinaryOperator::Mod, true, false) => { (mir::BinaryOperator::Mod, true, false) => {
@ -868,12 +864,12 @@ impl mir::Expression {
.block .block
.build(Instr::SDiv(lhs, rhs)) .build(Instr::SDiv(lhs, rhs))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
let mul = scope let mul = scope
.block .block
.build(Instr::Mul(rhs, div)) .build(Instr::Mul(rhs, div))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
Instr::Sub(lhs, mul) Instr::Sub(lhs, mul)
} }
(mir::BinaryOperator::Mod, _, true) => { (mir::BinaryOperator::Mod, _, true) => {
@ -881,12 +877,12 @@ impl mir::Expression {
.block .block
.build(Instr::FDiv(lhs, rhs)) .build(Instr::FDiv(lhs, rhs))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
let mul = scope let mul = scope
.block .block
.build(Instr::Mul(rhs, div)) .build(Instr::Mul(rhs, div))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
Instr::Sub(lhs, mul) Instr::Sub(lhs, mul)
} }
(mir::BinaryOperator::Or, true, true) => todo!(), (mir::BinaryOperator::Or, true, true) => todo!(),
@ -920,7 +916,7 @@ impl mir::Expression {
.block .block
.build(instr) .build(instr)
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()), .maybe_location(&mut scope.block, location),
), ),
return_ty.clone(), return_ty.clone(),
)) ))
@ -966,7 +962,7 @@ impl mir::Expression {
.block .block
.build_named(format!("gep"), Instr::GetElemPtr(loaded, vec![idx])) .build_named(format!("gep"), Instr::GetElemPtr(loaded, vec![idx]))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()), .maybe_location(&mut scope.block, location),
*further_inner, *further_inner,
) )
} else if let TypeKind::CodegenPtr(further_inner) = *inner.clone() { } else if let TypeKind::CodegenPtr(further_inner) = *inner.clone() {
@ -979,7 +975,7 @@ impl mir::Expression {
.block .block
.build_named(format!("array.gep"), Instr::GetElemPtr(kind.instr(), vec![idx])) .build_named(format!("array.gep"), Instr::GetElemPtr(kind.instr(), vec![idx]))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()), .maybe_location(&mut scope.block, location),
val_t.clone(), val_t.clone(),
) )
} else { } else {
@ -996,7 +992,7 @@ impl mir::Expression {
.block .block
.build_named(format!("array.gep"), Instr::GetElemPtr(kind.instr(), vec![first, idx])) .build_named(format!("array.gep"), Instr::GetElemPtr(kind.instr(), vec![first, idx]))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()), .maybe_location(&mut scope.block, location),
val_t.clone(), val_t.clone(),
) )
}; };
@ -1008,7 +1004,7 @@ impl mir::Expression {
.block .block
.build_named("array.load", Instr::Load(ptr, contained_ty.get_type(scope.type_values))) .build_named("array.load", Instr::Load(ptr, contained_ty.get_type(scope.type_values)))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()), .maybe_location(&mut scope.block, location),
), ),
contained_ty, contained_ty,
)) ))
@ -1046,7 +1042,7 @@ impl mir::Expression {
.block .block
.build_named(&array_name, Instr::Alloca(array_ty.clone())) .build_named(&array_name, Instr::Alloca(array_ty.clone()))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
for (index, instr) in instr_list.iter().enumerate() { for (index, instr) in instr_list.iter().enumerate() {
let gep_n = format!("{}.{}.gep", array_name, index); let gep_n = format!("{}.{}.gep", array_name, index);
@ -1064,19 +1060,19 @@ impl mir::Expression {
.block .block
.build_named(gep_n, Instr::GetElemPtr(array, vec![first, index_expr])) .build_named(gep_n, Instr::GetElemPtr(array, vec![first, index_expr]))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
scope scope
.block .block
.build_named(store_n, Instr::Store(ptr, *instr)) .build_named(store_n, Instr::Store(ptr, *instr))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
} }
let array_val = scope let array_val = scope
.block .block
.build_named(load_n, Instr::Load(array, array_ty)) .build_named(load_n, Instr::Load(array, array_ty))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
Some(StackValue( Some(StackValue(
StackValueKind::Literal(array_val), StackValueKind::Literal(array_val),
@ -1144,7 +1140,7 @@ impl mir::Expression {
.block .block
.build_named(name, Instr::Alloca(ty.clone())) .build_named(name, Instr::Alloca(ty.clone()))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
for (field_n, exp) in items { for (field_n, exp) in items {
let gep_n = format!("{}.{}.gep", name, field_n); let gep_n = format!("{}.{}.gep", name, field_n);
@ -1155,13 +1151,13 @@ impl mir::Expression {
.block .block
.build_named(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32)) .build_named(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
if let Some(val) = exp.codegen(scope, state)? { if let Some(val) = exp.codegen(scope, state)? {
scope scope
.block .block
.build_named(store_n, Instr::Store(elem_ptr, val.instr())) .build_named(store_n, Instr::Store(elem_ptr, val.instr()))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location);
} }
} }
@ -1281,7 +1277,7 @@ impl mir::Expression {
mir::ExprKind::AssociatedFunctionCall(ty, call) => codegen_function_call(Some(ty), call, scope, state)?, mir::ExprKind::AssociatedFunctionCall(ty, call) => codegen_function_call(Some(ty), call, scope, state)?,
}; };
if let Some(value) = &value { if let Some(value) = &value {
value.instr().maybe_location(&mut scope.block, location.clone()); value.instr().maybe_location(&mut scope.block, location);
} }
Ok(value) Ok(value)
} }
@ -1314,7 +1310,7 @@ fn codegen_function_call<'ctx, 'a>(
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let location = if let Some(debug) = &scope.debug { 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 { } else {
None None
}; };
@ -1397,16 +1393,16 @@ impl mir::IfExpression {
let after_b = scope.function.block("after"); let after_b = scope.function.block("after");
if let Some(debug) = &scope.debug { 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); let before_v = debug.info.location(&debug.scope, before_location);
scope.block.set_terminator_location(before_v).ok(); scope.block.set_terminator_location(before_v).ok();
let then_location = self.1 .1.into_debug(scope.tokens, &debug.scope).unwrap(); let then_location = self.1 .1.into_debug(scope.tokens, debug.scope).unwrap();
let then_v = debug.info.location(&debug.scope, then_location.clone()); 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_expr) = self.2.as_ref() { 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 { } else {
then_location then_location
}; };

View File

@ -2,7 +2,7 @@ use std::{cell::RefCell, collections::HashMap, mem, rc::Rc};
use reid_lib::{ use reid_lib::{
builder::{InstructionValue, TypeValue}, builder::{InstructionValue, TypeValue},
debug_information::{DebugInformation, DebugLocation, DebugScopeValue, DebugTypeValue}, debug_information::{DebugInformation, DebugLocation, DebugProgramValue, DebugTypeValue},
Block, Context, Function, Instr, Module, Block, Context, Function, Instr, Module,
}; };
@ -75,7 +75,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Debug<'ctx> { pub struct Debug<'ctx> {
pub(super) info: &'ctx DebugInformation, pub(super) info: &'ctx DebugInformation,
pub(super) scope: DebugScopeValue, pub(super) scope: DebugProgramValue,
pub(super) types: &'ctx HashMap<TypeKind, DebugTypeValue>, pub(super) types: &'ctx HashMap<TypeKind, DebugTypeValue>,
} }

View File

@ -3,15 +3,19 @@ use std::collections::HashMap;
use reid_lib::{ use reid_lib::{
builder::{InstructionValue, TypeValue}, builder::{InstructionValue, TypeValue},
debug_information::{ debug_information::{
DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation, DebugPointerType, DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation,
DebugPosition, DebugScopeValue, DebugStructType, DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, DebugPointerType, DebugPosition, DebugProgramValue, DebugStructType, DebugTypeData,
DebugTypeValue, DwarfEncoding, DwarfFlags,
}, },
Block, CmpPredicate, ConstValue, Instr, Type, Block, CmpPredicate, ConstValue, Instr, Type,
}; };
use crate::{ use crate::{
lexer::{FullToken, Position}, lexer::{FullToken, Position},
mir::{self, CustomTypeKey, Metadata, SourceModuleId, TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral}, mir::{
self, CustomTypeKey, Metadata, SourceModuleId, TypeDefinition, TypeDefinitionKind,
TypeKind, VagueLiteral,
},
}; };
use super::{ use super::{
@ -34,7 +38,9 @@ impl mir::CmpOperator {
impl mir::Literal { impl mir::Literal {
pub(super) fn as_const(&self, block: &mut Block) -> InstructionValue { 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 { pub(super) fn as_const_kind(&self) -> Instr {
@ -104,7 +110,7 @@ impl TypeKind {
impl TypeKind { impl TypeKind {
pub(super) fn get_debug_type(&self, debug: &Debug, scope: &Scope) -> DebugTypeValue { pub(super) fn get_debug_type(&self, debug: &Debug, scope: &Scope) -> DebugTypeValue {
self.get_debug_type_hard( self.get_debug_type_hard(
&debug.scope, debug.scope,
debug.info, debug.info,
debug.types, debug.types,
scope.type_values, scope.type_values,
@ -117,7 +123,7 @@ impl TypeKind {
pub(super) fn get_debug_type_hard( pub(super) fn get_debug_type_hard(
&self, &self,
scope: &DebugScopeValue, scope: DebugProgramValue,
debug_info: &DebugInformation, debug_info: &DebugInformation,
debug_types: &HashMap<TypeKind, DebugTypeValue>, debug_types: &HashMap<TypeKind, DebugTypeValue>,
type_values: &HashMap<CustomTypeKey, TypeValue>, type_values: &HashMap<CustomTypeKey, TypeValue>,
@ -178,11 +184,11 @@ impl TypeKind {
let location = if typedef.source_module != local_mod { let location = if typedef.source_module != local_mod {
None None
} else { } else {
field.2.into_debug(&tokens, &scope) field.2.into_debug(&tokens, scope)
}; };
fields.push(DebugFieldType { fields.push(DebugFieldType {
name: field.0.clone(), name: field.0.clone(),
scope: scope.clone(), scope,
pos: location.map(|l| l.pos), pos: location.map(|l| l.pos),
size_bits: field.1.size_of(), size_bits: field.1.size_of(),
offset: size_bits, offset: size_bits,
@ -208,7 +214,7 @@ impl TypeKind {
}; };
DebugTypeData::Struct(DebugStructType { DebugTypeData::Struct(DebugStructType {
name: key.0.clone(), name: key.0.clone(),
scope: scope.clone(), scope,
pos: location.map(|l| l.pos), pos: location.map(|l| l.pos),
size_bits, size_bits,
flags: DwarfFlags, flags: DwarfFlags,
@ -225,8 +231,12 @@ impl TypeKind {
TypeKind::Bool => DwarfEncoding::Boolean, TypeKind::Bool => DwarfEncoding::Boolean,
TypeKind::I8 => DwarfEncoding::SignedChar, TypeKind::I8 => DwarfEncoding::SignedChar,
TypeKind::U8 => DwarfEncoding::UnsignedChar, TypeKind::U8 => DwarfEncoding::UnsignedChar,
TypeKind::I16 | TypeKind::I32 | TypeKind::I64 | TypeKind::I128 => DwarfEncoding::Signed, TypeKind::I16 | TypeKind::I32 | TypeKind::I64 | TypeKind::I128 => {
TypeKind::U16 | TypeKind::U32 | TypeKind::U64 | TypeKind::U128 => DwarfEncoding::Unsigned, DwarfEncoding::Signed
}
TypeKind::U16 | TypeKind::U32 | TypeKind::U64 | TypeKind::U128 => {
DwarfEncoding::Unsigned
}
TypeKind::F16 TypeKind::F16
| TypeKind::F32 | TypeKind::F32
| TypeKind::F32B | TypeKind::F32B
@ -248,9 +258,13 @@ impl TypeKind {
} }
impl Metadata { impl Metadata {
pub(super) fn into_debug(&self, tokens: &Vec<FullToken>, scope: &DebugScopeValue) -> Option<DebugLocation> { pub(super) 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.debug(scope.clone())) Some(start.debug(scope))
} else { } else {
None None
} }
@ -258,7 +272,7 @@ impl Metadata {
} }
impl Position { impl Position {
pub(super) fn debug(self, scope: DebugScopeValue) -> DebugLocation { pub(super) fn debug(self, scope: DebugProgramValue) -> DebugLocation {
DebugLocation { DebugLocation {
pos: DebugPosition { pos: DebugPosition {
line: self.1, line: self.1,

View File

@ -1,5 +1,3 @@
use std::collections::HashSet;
use crate::mir::VagueType as Vague; use crate::mir::VagueType as Vague;
use crate::mir::*; use crate::mir::*;
use typecheck::ErrorTypedefKind; use typecheck::ErrorTypedefKind;
@ -293,7 +291,7 @@ impl TypeKind {
pub(super) fn resolve_weak(&self, refs: &TypeRefs) -> TypeKind { pub(super) fn resolve_weak(&self, refs: &TypeRefs) -> TypeKind {
match self { match self {
TypeKind::Vague(Vague::TypeRef(idx)) => refs.retrieve_wide_type(*idx, &mut HashSet::new()).unwrap(), TypeKind::Vague(Vague::TypeRef(idx)) => refs.retrieve_wide_type(*idx).unwrap(),
_ => self.clone(), _ => self.clone(),
} }
} }

View File

@ -1,6 +1,6 @@
//! This module contains code relevant to doing a type checking pass on the MIR. //! This module contains code relevant to doing a type checking pass on the MIR.
//! During typechecking relevant types are also coerced if possible. //! During typechecking relevant types are also coerced if possible.
use std::{collections::HashSet, convert::Infallible, iter}; use std::{collections::HashSet, convert::Infallible, hint, iter};
use crate::{mir::*, util::try_all}; use crate::{mir::*, util::try_all};
use VagueType as Vague; use VagueType as Vague;
@ -415,6 +415,7 @@ impl Expression {
// First find unfiltered parameters to binop // First find unfiltered parameters to binop
let lhs_res = lhs.typecheck(state, &typerefs, HintKind::None); let lhs_res = lhs.typecheck(state, &typerefs, HintKind::None);
let rhs_res = rhs.typecheck(state, &typerefs, HintKind::None); let rhs_res = rhs.typecheck(state, &typerefs, HintKind::None);
dbg!(&lhs_res, &rhs_res, &ret_ty);
let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1); let lhs_type = state.or_else(lhs_res, TypeKind::Vague(Vague::Unknown), lhs.1);
let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1); let rhs_type = state.or_else(rhs_res, TypeKind::Vague(Vague::Unknown), rhs.1);
@ -432,6 +433,8 @@ impl Expression {
operator: *op, operator: *op,
}); });
dbg!(&binops);
// dbg!(&lhs_type, &rhs_type, &binops, &ret_ty, &expected_return_ty);
if let Some(binop) = binops if let Some(binop) = binops
.iter() .iter()
.filter(|f| f.1.return_ty.narrow_into(&expected_return_ty).is_ok()) .filter(|f| f.1.return_ty.narrow_into(&expected_return_ty).is_ok())
@ -750,7 +753,9 @@ impl Expression {
.into_iter() .into_iter()
.chain(iter::repeat(TypeKind::Vague(Vague::Unknown))); .chain(iter::repeat(TypeKind::Vague(Vague::Unknown)));
for (param, true_param_t) in function_call.parameters.iter_mut().zip(true_params_iter) { for (i, (param, true_param_t)) in
function_call.parameters.iter_mut().zip(true_params_iter).enumerate()
{
// Typecheck every param separately // Typecheck every param separately
let param_res = param.typecheck(state, &typerefs, HintKind::Coerce(true_param_t.clone())); let param_res = param.typecheck(state, &typerefs, HintKind::Coerce(true_param_t.clone()));
let param_t = state.or_else(param_res, TypeKind::Vague(Vague::Unknown), param.1); let param_t = state.or_else(param_res, TypeKind::Vague(Vague::Unknown), param.1);

View File

@ -285,7 +285,7 @@ impl Block {
let rhs_ref = state.ok(rhs_infer, rhs.1); let rhs_ref = state.ok(rhs_infer, rhs.1);
// Try to narrow the lhs with rhs // Try to narrow the lhs with rhs
if let (Some(lhs_ref), Some(mut rhs_ref)) = (lhs_ref, rhs_ref) { if let (Some(mut lhs_ref), Some(mut rhs_ref)) = (lhs_ref, rhs_ref) {
rhs_ref.narrow(&lhs_ref); rhs_ref.narrow(&lhs_ref);
} }
} }

View File

@ -15,7 +15,7 @@ impl<'scope> TypeRef<'scope> {
/// Resolve current type in a weak manner, not resolving any Arrays or /// Resolve current type in a weak manner, not resolving any Arrays or
/// further inner types /// further inner types
pub fn resolve_weak(&self) -> Option<TypeKind> { pub fn resolve_weak(&self) -> Option<TypeKind> {
Some(self.1.types.retrieve_wide_type(*self.0.borrow(), &mut HashSet::new())?) Some(self.1.types.retrieve_wide_type(*self.0.borrow())?)
} }
/// Resolve type deeply, trying to resolve any inner types as well. /// Resolve type deeply, trying to resolve any inner types as well.
@ -62,16 +62,17 @@ pub enum TypeRefKind {
} }
impl TypeRefKind { impl TypeRefKind {
pub fn widen(&self, types: &TypeRefs, seen: &mut HashSet<usize>) -> TypeKind { pub fn widen(&self, types: &TypeRefs) -> TypeKind {
match self { match self {
TypeRefKind::BinOp(op, lhs, rhs) => { TypeRefKind::BinOp(op, lhs, rhs) => {
let lhs_resolved = types.cut_recursion(lhs, seen).resolve_ref(types);
let rhs_resolved = types.cut_recursion(rhs, seen).resolve_ref(types);
let mut binops = types let mut binops = types
.binop_types .binop_types
.iter() .iter()
.filter(|b| b.1.operator == *op) .filter(|b| b.1.operator == *op)
.map(|b| b.1.narrow(&lhs_resolved, &rhs_resolved).map(|b| b.2)) .map(|b| {
b.1.narrow(&lhs.resolve_ref(types), &rhs.resolve_ref(types))
.map(|b| b.2)
})
.filter_map(|s| s); .filter_map(|s| s);
if let Some(mut ty) = binops.next() { if let Some(mut ty) = binops.next() {
while let Some(other) = binops.next() { while let Some(other) = binops.next() {
@ -83,7 +84,7 @@ impl TypeRefKind {
} }
} }
TypeRefKind::Direct(ty) => match ty { TypeRefKind::Direct(ty) => match ty {
TypeKind::Vague(VagueType::TypeRef(id)) => types.retrieve_wide_type(*id, seen).unwrap(), TypeKind::Vague(VagueType::TypeRef(id)) => types.retrieve_wide_type(*id).unwrap(),
_ => ty.clone(), _ => ty.clone(),
}, },
} }
@ -109,7 +110,7 @@ impl std::fmt::Display for TypeRefs {
i, i,
unsafe { *self.recurse_type_ref(idx).borrow() }, unsafe { *self.recurse_type_ref(idx).borrow() },
self.retrieve_typeref(idx), self.retrieve_typeref(idx),
self.retrieve_wide_type(idx, &mut HashSet::new()), self.retrieve_wide_type(idx),
)?; )?;
} }
Ok(()) Ok(())
@ -181,35 +182,8 @@ impl TypeRefs {
self.hints.borrow().get(inner_idx).cloned() self.hints.borrow().get(inner_idx).cloned()
} }
pub fn retrieve_wide_type(&self, idx: usize, seen: &mut HashSet<usize>) -> Option<TypeKind> { pub fn retrieve_wide_type(&self, idx: usize) -> Option<TypeKind> {
self.retrieve_typeref(idx).map(|t| t.widen(self, seen)) self.retrieve_typeref(idx).map(|t| t.widen(self))
}
pub fn cut_recursion_weak<'s>(&self, idx: usize, seen: &mut HashSet<usize>) -> Option<TypeRefKind> {
if seen.insert(idx) {
self.retrieve_typeref(idx)
} else {
None
}
}
pub(super) fn cut_recursion(&self, kind: &TypeKind, seen: &mut HashSet<usize>) -> TypeKind {
match kind {
TypeKind::Array(type_kind, len) => TypeKind::Array(Box::new(self.cut_recursion(&type_kind, seen)), *len),
TypeKind::Borrow(type_kind, mutable) => {
TypeKind::Borrow(Box::new(self.cut_recursion(&type_kind, seen)), *mutable)
}
TypeKind::UserPtr(type_kind) => TypeKind::UserPtr(Box::new(self.cut_recursion(&type_kind, seen))),
TypeKind::CodegenPtr(type_kind) => TypeKind::CodegenPtr(Box::new(self.cut_recursion(&type_kind, seen))),
TypeKind::Vague(VagueType::TypeRef(idx)) => {
if let Some(tyref) = self.cut_recursion_weak(*idx, seen) {
tyref.widen(self, seen)
} else {
TypeKind::Vague(VagueType::Unknown)
}
}
_ => kind.clone(),
}
} }
} }
@ -355,7 +329,7 @@ impl<'outer> ScopeTypeRefs<'outer> {
.borrow() .borrow()
.get_unchecked(*hint2.0.borrow()) .get_unchecked(*hint2.0.borrow())
.clone() .clone()
.widen(self.types, &mut HashSet::new()); .widen(self.types);
self.narrow_to_type(&hint1, &ty)?; self.narrow_to_type(&hint1, &ty)?;
let hint1_typeref = self.types.retrieve_typeref(*hint1.0.borrow()).unwrap(); let hint1_typeref = self.types.retrieve_typeref(*hint1.0.borrow()).unwrap();
let hint2_typeref = self.types.retrieve_typeref(*hint2.0.borrow()).unwrap(); let hint2_typeref = self.types.retrieve_typeref(*hint2.0.borrow()).unwrap();
@ -383,22 +357,10 @@ impl<'outer> ScopeTypeRefs<'outer> {
} }
} }
(TypeRefKind::BinOp(_, lhs1, rhs1), TypeRefKind::BinOp(_, lhs2, rhs2)) => { (TypeRefKind::BinOp(_, lhs1, rhs1), TypeRefKind::BinOp(_, lhs2, rhs2)) => {
let mut lhs_ref = self let mut lhs_ref = self.from_type(&lhs1).unwrap();
.from_type(&self.types.cut_recursion(lhs1, &mut HashSet::new())) let mut rhs_ref = self.from_type(&rhs1).unwrap();
.unwrap(); lhs_ref.narrow(&self.from_type(&lhs2).unwrap());
let mut rhs_ref = self rhs_ref.narrow(&self.from_type(&rhs2).unwrap());
.from_type(&self.types.cut_recursion(rhs1, &mut HashSet::new()))
.unwrap();
lhs_ref.narrow(
&self
.from_type(&self.types.cut_recursion(lhs2, &mut HashSet::new()))
.unwrap(),
);
rhs_ref.narrow(
&self
.from_type(&self.types.cut_recursion(rhs2, &mut HashSet::new()))
.unwrap(),
);
} }
_ => {} _ => {}
} }