Implement lexical scopes
This commit is contained in:
parent
726251e39c
commit
1b1a5934f5
@ -399,12 +399,12 @@ impl DebugScopeHolder {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let scope = match &self.data.kind {
|
let scope = match &self.data.kind {
|
||||||
DebugScopeKind::CodegenContext => panic!(),
|
DebugScopeKind::CodegenContext => panic!(),
|
||||||
DebugScopeKind::LexicalScope => LLVMDIBuilderCreateLexicalBlock(
|
DebugScopeKind::LexicalScope(data) => LLVMDIBuilderCreateLexicalBlock(
|
||||||
di_builder,
|
di_builder,
|
||||||
parent,
|
parent,
|
||||||
file,
|
file,
|
||||||
self.data.location.as_ref().unwrap().pos.line,
|
data.location.pos.line,
|
||||||
self.data.location.as_ref().unwrap().pos.column,
|
data.location.pos.column,
|
||||||
),
|
),
|
||||||
DebugScopeKind::Subprogram(_) => panic!(),
|
DebugScopeKind::Subprogram(_) => panic!(),
|
||||||
};
|
};
|
||||||
@ -607,7 +607,7 @@ impl FunctionHolder {
|
|||||||
|
|
||||||
let subprogram = match scope_data.kind {
|
let subprogram = match scope_data.kind {
|
||||||
DebugScopeKind::CodegenContext => panic!(),
|
DebugScopeKind::CodegenContext => panic!(),
|
||||||
DebugScopeKind::LexicalScope => panic!(),
|
DebugScopeKind::LexicalScope(_) => panic!(),
|
||||||
DebugScopeKind::Subprogram(subprogram) => LLVMDIBuilderCreateFunction(
|
DebugScopeKind::Subprogram(subprogram) => LLVMDIBuilderCreateFunction(
|
||||||
debug.builder,
|
debug.builder,
|
||||||
*debug.scopes.get(&scope_data.parent.unwrap()).unwrap(),
|
*debug.scopes.get(&scope_data.parent.unwrap()).unwrap(),
|
||||||
|
@ -71,10 +71,6 @@ impl DebugInformation {
|
|||||||
inner_scopes: Vec::new(),
|
inner_scopes: Vec::new(),
|
||||||
data: DebugScopeData {
|
data: DebugScopeData {
|
||||||
parent: None,
|
parent: None,
|
||||||
location: Some(DebugLocation {
|
|
||||||
scope: DebugScopeValue(Vec::new()),
|
|
||||||
pos: DebugPosition { line: 0, column: 0 },
|
|
||||||
}),
|
|
||||||
kind: DebugScopeKind::CodegenContext,
|
kind: DebugScopeKind::CodegenContext,
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
@ -86,32 +82,6 @@ impl DebugInformation {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inner_scope(&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(),
|
|
||||||
data: DebugScopeData {
|
|
||||||
parent: Some(parent.clone()),
|
|
||||||
location: Some(location),
|
|
||||||
kind: DebugScopeKind::LexicalScope,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn location(&self, scope_value: &DebugScopeValue, location: DebugLocation) -> DebugLocationValue {
|
pub fn location(&self, scope_value: &DebugScopeValue, location: DebugLocation) -> DebugLocationValue {
|
||||||
let value = DebugLocationValue(scope_value.clone(), self.locations.borrow().len());
|
let value = DebugLocationValue(scope_value.clone(), self.locations.borrow().len());
|
||||||
let location = DebugLocationHolder {
|
let location = DebugLocationHolder {
|
||||||
@ -162,13 +132,36 @@ impl DebugInformation {
|
|||||||
inner_scopes: Vec::new(),
|
inner_scopes: Vec::new(),
|
||||||
data: DebugScopeData {
|
data: DebugScopeData {
|
||||||
parent: Some(parent.clone()),
|
parent: Some(parent.clone()),
|
||||||
location: None,
|
|
||||||
kind: DebugScopeKind::Subprogram(kind),
|
kind: DebugScopeKind::Subprogram(kind),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
value
|
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 {
|
||||||
unsafe { self.metadata.borrow().get_unchecked(value.0).data.clone() }
|
unsafe { self.metadata.borrow().get_unchecked(value.0).data.clone() }
|
||||||
@ -352,17 +345,21 @@ pub enum DwarfEncoding {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DebugScopeData {
|
pub struct DebugScopeData {
|
||||||
pub parent: Option<DebugScopeValue>,
|
pub parent: Option<DebugScopeValue>,
|
||||||
pub location: Option<DebugLocation>,
|
|
||||||
pub kind: DebugScopeKind,
|
pub kind: DebugScopeKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum DebugScopeKind {
|
pub enum DebugScopeKind {
|
||||||
CodegenContext,
|
CodegenContext,
|
||||||
LexicalScope,
|
LexicalScope(DebugLexicalScope),
|
||||||
Subprogram(DebugSubprogramData),
|
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.
|
||||||
|
@ -5,8 +5,9 @@ use intrinsics::*;
|
|||||||
use reid_lib::{
|
use reid_lib::{
|
||||||
compile::CompiledModule,
|
compile::CompiledModule,
|
||||||
debug_information::{
|
debug_information::{
|
||||||
DebugFileData, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind, DebugSubprogramData,
|
DebugFileData, DebugLexicalScope, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind,
|
||||||
DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags, InstructionDebugRecordData,
|
DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags,
|
||||||
|
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,
|
||||||
@ -546,36 +547,10 @@ 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)? {
|
if let Some(ret) = block.codegen(scope, &state, false)? {
|
||||||
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() {
|
||||||
@ -604,7 +579,20 @@ 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 {
|
||||||
@ -615,7 +603,7 @@ impl mir::Block {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((kind, expr)) = &self.return_expression {
|
let return_value = 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 {
|
||||||
@ -638,7 +626,13 @@ 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,7 +753,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)?;
|
block.codegen(&mut condition_true_scope, state, true)?;
|
||||||
|
|
||||||
condition_true_scope
|
condition_true_scope
|
||||||
.block
|
.block
|
||||||
@ -933,7 +927,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)? {
|
let ret = if let Some(ret) = block.codegen(&mut inner_scope, state, true)? {
|
||||||
Some(ret)
|
Some(ret)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
Loading…
Reference in New Issue
Block a user