Compare commits
No commits in common. "1b1a5934f5ab764582d2529fac60604d12e83869" and "a60d35c0b007434dcfd043e6fa2bc5ee45132345" have entirely different histories.
1b1a5934f5
...
a60d35c0b0
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
pub fn main() -> u32 {
|
|
||||||
let b = 4;
|
|
||||||
let c = b + 4;
|
|
||||||
return c;
|
|
||||||
}
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(data) => LLVMDIBuilderCreateLexicalBlock(
|
} else {
|
||||||
di_builder,
|
LLVMDIBuilderCreateLexicalBlockFile(di_builder, parent, file, 0)
|
||||||
parent,
|
|
||||||
file,
|
|
||||||
data.location.pos.line,
|
|
||||||
data.location.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(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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,38 +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,
|
||||||
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 location(&self, scope_value: &DebugScopeValue, location: DebugLocation) -> DebugLocationValue {
|
// pub fn inner_scope(
|
||||||
let value = DebugLocationValue(scope_value.clone(), self.locations.borrow().len());
|
// &self,
|
||||||
|
// parent: &DebugScopeValue,
|
||||||
|
// location: DebugLocation,
|
||||||
|
// ) -> DebugScopeValue {
|
||||||
|
// unsafe {
|
||||||
|
// let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| {
|
||||||
|
// for i in &parent.0 {
|
||||||
|
// v = v.inner_scopes.get_unchecked_mut(*i);
|
||||||
|
// }
|
||||||
|
// v
|
||||||
|
// });
|
||||||
|
|
||||||
|
// let mut arr = parent.0.clone();
|
||||||
|
// arr.push(parent.0.len());
|
||||||
|
// let value = DebugScopeValue(arr);
|
||||||
|
|
||||||
|
// outer_scope.inner_scopes.push(DebugScopeHolder {
|
||||||
|
// value: value.clone(),
|
||||||
|
// inner_scopes: Vec::new(),
|
||||||
|
// locations: Vec::new(),
|
||||||
|
// location: Some(location),
|
||||||
|
// });
|
||||||
|
// value
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn location(
|
||||||
|
&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,
|
||||||
};
|
};
|
||||||
@ -107,60 +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()),
|
|
||||||
kind: DebugScopeKind::Subprogram(kind),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn lexical_scope(&self, parent: &DebugScopeValue, data: DebugLexicalScope) -> DebugScopeValue {
|
|
||||||
unsafe {
|
|
||||||
let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| {
|
|
||||||
for i in &parent.0 {
|
|
||||||
v = v.inner_scopes.get_unchecked_mut(*i);
|
|
||||||
}
|
|
||||||
v
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut arr = parent.0.clone();
|
|
||||||
arr.push(outer_scope.inner_scopes.len());
|
|
||||||
let value = DebugScopeValue(arr);
|
|
||||||
|
|
||||||
outer_scope.inner_scopes.push(DebugScopeHolder {
|
|
||||||
value: value.clone(),
|
|
||||||
inner_scopes: Vec::new(),
|
|
||||||
data: DebugScopeData {
|
|
||||||
parent: Some(parent.clone()),
|
|
||||||
kind: DebugScopeKind::LexicalScope(data),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_metadata(&self, value: DebugMetadataValue) -> DebugMetadata {
|
pub fn get_metadata(&self, value: DebugMetadataValue) -> DebugMetadata {
|
||||||
@ -168,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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,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>>> {
|
||||||
@ -212,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,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,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,
|
||||||
@ -317,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,
|
||||||
@ -342,29 +350,11 @@ pub enum DwarfEncoding {
|
|||||||
UnsignedChar = 8,
|
UnsignedChar = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct DebugScopeData {
|
|
||||||
pub parent: Option<DebugScopeValue>,
|
|
||||||
pub kind: DebugScopeKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum DebugScopeKind {
|
|
||||||
CodegenContext,
|
|
||||||
LexicalScope(DebugLexicalScope),
|
|
||||||
Subprogram(DebugSubprogramData),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct DebugLexicalScope {
|
|
||||||
pub location: DebugLocation,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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.
|
||||||
@ -386,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,
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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::{
|
||||||
|
@ -5,9 +5,8 @@ use intrinsics::*;
|
|||||||
use reid_lib::{
|
use reid_lib::{
|
||||||
compile::CompiledModule,
|
compile::CompiledModule,
|
||||||
debug_information::{
|
debug_information::{
|
||||||
DebugFileData, DebugLexicalScope, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind,
|
DebugFileData, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind, DebugSubprogramData,
|
||||||
DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags,
|
DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags, InstructionDebugRecordData,
|
||||||
InstructionDebugRecordData,
|
|
||||||
},
|
},
|
||||||
CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, NamedStruct,
|
CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, NamedStruct,
|
||||||
TerminatorKind as Term, Type,
|
TerminatorKind as Term, Type,
|
||||||
@ -125,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,
|
||||||
@ -280,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()
|
||||||
@ -311,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,
|
||||||
@ -328,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,
|
||||||
},
|
},
|
||||||
@ -385,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,
|
||||||
@ -403,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,
|
||||||
@ -444,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,
|
||||||
@ -462,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,
|
||||||
@ -501,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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -547,10 +542,36 @@ impl FunctionDefinitionKind {
|
|||||||
TypeKind::CodegenPtr(Box::new(p_ty.clone())),
|
TypeKind::CodegenPtr(Box::new(p_ty.clone())),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Generate debug info
|
||||||
|
// if let (Some(debug_scope), Some(location)) = (
|
||||||
|
// &debug_scope,
|
||||||
|
// mir_function.signature().into_debug(tokens, compile_unit),
|
||||||
|
// ) {
|
||||||
|
// debug.metadata(
|
||||||
|
// &location,
|
||||||
|
// DebugMetadata::ParamVar(DebugParamVariable {
|
||||||
|
// name: p_name.clone(),
|
||||||
|
// arg_idx: i as u32,
|
||||||
|
// ty: p_ty.get_debug_type_hard(
|
||||||
|
// *debug_scope,
|
||||||
|
// &debug,
|
||||||
|
// &debug_types,
|
||||||
|
// &type_values,
|
||||||
|
// &types,
|
||||||
|
// self.module_id,
|
||||||
|
// &self.tokens,
|
||||||
|
// &modules,
|
||||||
|
// ),
|
||||||
|
// always_preserve: true,
|
||||||
|
// flags: DwarfFlags,
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = State::default();
|
let state = State::default();
|
||||||
if let Some(ret) = block.codegen(scope, &state, false)? {
|
if let Some(ret) = block.codegen(scope, &state)? {
|
||||||
scope.block.terminate(Term::Ret(ret.instr())).unwrap();
|
scope.block.terminate(Term::Ret(ret.instr())).unwrap();
|
||||||
} else {
|
} else {
|
||||||
if !scope.block.delete_if_unused().unwrap() {
|
if !scope.block.delete_if_unused().unwrap() {
|
||||||
@ -561,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -579,31 +600,18 @@ impl mir::Block {
|
|||||||
&self,
|
&self,
|
||||||
mut scope: &mut Scope<'ctx, 'a>,
|
mut scope: &mut Scope<'ctx, 'a>,
|
||||||
state: &State,
|
state: &State,
|
||||||
create_debug_scope: bool,
|
|
||||||
) -> Result<Option<StackValue>, ErrorKind> {
|
) -> Result<Option<StackValue>, ErrorKind> {
|
||||||
let parent_scope = if let Some(debug) = &mut scope.debug {
|
|
||||||
let parent_scope = debug.scope.clone();
|
|
||||||
if create_debug_scope {
|
|
||||||
let location = self.meta.into_debug(scope.tokens, &debug.scope).unwrap();
|
|
||||||
let scope = debug.info.lexical_scope(&debug.scope, DebugLexicalScope { location });
|
|
||||||
debug.scope = scope;
|
|
||||||
}
|
|
||||||
Some(parent_scope)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
for stmt in &self.statements {
|
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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let return_value = if let Some((kind, expr)) = &self.return_expression {
|
if let Some((kind, expr)) = &self.return_expression {
|
||||||
if let Some(expr) = expr {
|
if let Some(expr) = expr {
|
||||||
let ret = expr.codegen(&mut scope, &mut state.load(true))?;
|
let ret = expr.codegen(&mut scope, &mut state.load(true))?;
|
||||||
match kind {
|
match kind {
|
||||||
@ -626,20 +634,14 @@ impl mir::Block {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(parent_scope) = parent_scope {
|
|
||||||
scope.debug.as_mut().unwrap().scope = parent_scope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return_value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -650,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
|
||||||
@ -668,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 {
|
||||||
@ -684,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,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -753,7 +755,7 @@ impl mir::Statement {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut condition_true_scope = scope.with_block(condition_true_block);
|
let mut condition_true_scope = scope.with_block(condition_true_block);
|
||||||
block.codegen(&mut condition_true_scope, state, true)?;
|
block.codegen(&mut condition_true_scope, state)?;
|
||||||
|
|
||||||
condition_true_scope
|
condition_true_scope
|
||||||
.block
|
.block
|
||||||
@ -775,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
|
||||||
@ -849,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) => {
|
||||||
@ -862,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) => {
|
||||||
@ -875,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!(),
|
||||||
@ -914,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(),
|
||||||
))
|
))
|
||||||
@ -927,7 +929,7 @@ impl mir::Expression {
|
|||||||
scope.block.terminate(Term::Br(inner.value())).unwrap();
|
scope.block.terminate(Term::Br(inner.value())).unwrap();
|
||||||
|
|
||||||
let mut inner_scope = scope.with_block(inner);
|
let mut inner_scope = scope.with_block(inner);
|
||||||
let ret = if let Some(ret) = block.codegen(&mut inner_scope, state, true)? {
|
let ret = if let Some(ret) = block.codegen(&mut inner_scope, state)? {
|
||||||
Some(ret)
|
Some(ret)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -960,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() {
|
||||||
@ -973,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 {
|
||||||
@ -990,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(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@ -1002,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,
|
||||||
))
|
))
|
||||||
@ -1040,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);
|
||||||
@ -1058,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),
|
||||||
@ -1138,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);
|
||||||
@ -1149,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,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)
|
||||||
}
|
}
|
||||||
@ -1308,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
|
||||||
};
|
};
|
||||||
@ -1391,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
|
||||||
};
|
};
|
||||||
|
@ -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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user