Fix a bunch of bugs with debug information and stuff
This commit is contained in:
		
							parent
							
								
									78a1e9f06b
								
							
						
					
					
						commit
						81ce1dfc2e
					
				| @ -389,6 +389,7 @@ impl Builder { | |||||||
|                         return Err(()); // TODO error: invalid amount of params
 |                         return Err(()); // TODO error: invalid amount of params
 | ||||||
|                     } |                     } | ||||||
|                     for (a, b) in param_types.iter().zip(params) { |                     for (a, b) in param_types.iter().zip(params) { | ||||||
|  |                         dbg!(&a, &b.get_type(&self)); | ||||||
|                         if *a != b.get_type(&self)? { |                         if *a != b.get_type(&self)? { | ||||||
|                             return Err(()); // TODO error: params do not match
 |                             return Err(()); // TODO error: params do not match
 | ||||||
|                         } |                         } | ||||||
| @ -478,7 +479,7 @@ impl Builder { | |||||||
|                 Instr::SIToFP(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), |                 Instr::SIToFP(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), | ||||||
|                 Instr::PtrToInt(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), |                 Instr::PtrToInt(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), | ||||||
|                 Instr::IntToPtr(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), |                 Instr::IntToPtr(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), | ||||||
|                 Instr::BitCast(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), |                 Instr::BitCast(instr, ty) => Ok(()), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -628,7 +629,7 @@ impl InstructionValue { | |||||||
|                 SIToFP(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), |                 SIToFP(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), | ||||||
|                 PtrToInt(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), |                 PtrToInt(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), | ||||||
|                 IntToPtr(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), |                 IntToPtr(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), | ||||||
|                 BitCast(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), |                 BitCast(_, ty) => Ok(ty.clone()), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -376,8 +376,8 @@ impl DebugLocationHolder { | |||||||
|         unsafe { |         unsafe { | ||||||
|             LLVMDIBuilderCreateDebugLocation( |             LLVMDIBuilderCreateDebugLocation( | ||||||
|                 context.context_ref, |                 context.context_ref, | ||||||
|                 self.location.line, |                 self.location.pos.line, | ||||||
|                 self.location.column, |                 self.location.pos.column, | ||||||
|                 *debug.programs.get(&self.program).unwrap(), |                 *debug.programs.get(&self.program).unwrap(), | ||||||
|                 null_mut(), |                 null_mut(), | ||||||
|             ) |             ) | ||||||
| @ -399,8 +399,8 @@ impl DebugScopeHolder { | |||||||
|                     di_builder, |                     di_builder, | ||||||
|                     parent, |                     parent, | ||||||
|                     file, |                     file, | ||||||
|                     location.line, |                     location.pos.line, | ||||||
|                     location.column, |                     location.pos.column, | ||||||
|                 ) |                 ) | ||||||
|             } else { |             } else { | ||||||
|                 LLVMDIBuilderCreateLexicalBlockFile(di_builder, parent, file, 0) |                 LLVMDIBuilderCreateLexicalBlockFile(di_builder, parent, file, 0) | ||||||
| @ -426,7 +426,7 @@ impl DebugMetadataHolder { | |||||||
|                     param.name.len(), |                     param.name.len(), | ||||||
|                     param.arg_idx + 1, |                     param.arg_idx + 1, | ||||||
|                     debug.file_ref, |                     debug.file_ref, | ||||||
|                     self.location.line, |                     self.location.pos.line, | ||||||
|                     *debug.types.get(¶m.ty).unwrap(), |                     *debug.types.get(¶m.ty).unwrap(), | ||||||
|                     param.always_preserve as i32, |                     param.always_preserve as i32, | ||||||
|                     param.flags.as_llvm(), |                     param.flags.as_llvm(), | ||||||
| @ -437,7 +437,7 @@ impl DebugMetadataHolder { | |||||||
|                     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, | ||||||
|                     self.location.line, |                     self.location.pos.line, | ||||||
|                     *debug.types.get(&var.ty).unwrap(), |                     *debug.types.get(&var.ty).unwrap(), | ||||||
|                     var.always_preserve as i32, |                     var.always_preserve as i32, | ||||||
|                     var.flags.as_llvm(), |                     var.flags.as_llvm(), | ||||||
| @ -504,11 +504,11 @@ impl DebugTypeHolder { | |||||||
|                         .map(|field| { |                         .map(|field| { | ||||||
|                             LLVMDIBuilderCreateMemberType( |                             LLVMDIBuilderCreateMemberType( | ||||||
|                                 debug.builder, |                                 debug.builder, | ||||||
|                                 *debug.programs.get(&st.location.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, | ||||||
|                                 field.location.line, |                                 field.pos.map(|p| p.line).unwrap_or(1), | ||||||
|                                 field.size_bits, |                                 field.size_bits, | ||||||
|                                 0, |                                 0, | ||||||
|                                 1, |                                 1, | ||||||
| @ -519,11 +519,11 @@ impl DebugTypeHolder { | |||||||
|                         .collect::<Vec<_>>(); |                         .collect::<Vec<_>>(); | ||||||
|                     LLVMDIBuilderCreateStructType( |                     LLVMDIBuilderCreateStructType( | ||||||
|                         debug.builder, |                         debug.builder, | ||||||
|                         *debug.programs.get(&st.location.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, | ||||||
|                         st.location.line, |                         st.pos.map(|p| p.line).unwrap_or(1), | ||||||
|                         st.size_bits, |                         st.size_bits, | ||||||
|                         0, |                         0, | ||||||
|                         st.flags.as_llvm(), |                         st.flags.as_llvm(), | ||||||
| @ -617,7 +617,7 @@ impl FunctionHolder { | |||||||
|                         mangled_name, |                         mangled_name, | ||||||
|                         mangled_length, |                         mangled_length, | ||||||
|                         debug.file_ref, |                         debug.file_ref, | ||||||
|                         subprogram.location.line, |                         subprogram.location.pos.line, | ||||||
|                         *debug.types.get(&subprogram.ty).unwrap(), |                         *debug.types.get(&subprogram.ty).unwrap(), | ||||||
|                         subprogram.opts.is_local as i32, |                         subprogram.opts.is_local as i32, | ||||||
|                         subprogram.opts.is_definition as i32, |                         subprogram.opts.is_definition as i32, | ||||||
| @ -1027,8 +1027,8 @@ impl InstructionHolder { | |||||||
| 
 | 
 | ||||||
|                 let location = LLVMDIBuilderCreateDebugLocation( |                 let location = LLVMDIBuilderCreateDebugLocation( | ||||||
|                     module.context_ref, |                     module.context_ref, | ||||||
|                     record.location.line, |                     record.location.pos.line, | ||||||
|                     record.location.column, |                     record.location.pos.column, | ||||||
|                     *debug.programs.get(&record.scope).unwrap(), |                     *debug.programs.get(&record.scope).unwrap(), | ||||||
|                     null_mut(), |                     null_mut(), | ||||||
|                 ); |                 ); | ||||||
|  | |||||||
| @ -225,6 +225,11 @@ impl DebugInformation { | |||||||
| #[derive(Clone, Copy)] | #[derive(Clone, Copy)] | ||||||
| pub struct DebugLocation { | pub struct DebugLocation { | ||||||
|     pub scope: DebugProgramValue, |     pub scope: DebugProgramValue, | ||||||
|  |     pub pos: DebugPosition, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Clone, Copy)] | ||||||
|  | pub struct DebugPosition { | ||||||
|     pub line: u32, |     pub line: u32, | ||||||
|     pub column: u32, |     pub column: u32, | ||||||
| } | } | ||||||
| @ -310,7 +315,8 @@ pub struct DebugPointerType { | |||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
| pub struct DebugStructType { | pub struct DebugStructType { | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub location: DebugLocation, |     pub scope: DebugProgramValue, | ||||||
|  |     pub pos: Option<DebugPosition>, | ||||||
|     pub size_bits: u64, |     pub size_bits: u64, | ||||||
|     pub flags: DwarfFlags, |     pub flags: DwarfFlags, | ||||||
|     pub fields: Vec<DebugFieldType>, |     pub fields: Vec<DebugFieldType>, | ||||||
| @ -319,7 +325,8 @@ pub struct DebugStructType { | |||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
| pub struct DebugFieldType { | pub struct DebugFieldType { | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub location: DebugLocation, |     pub scope: DebugProgramValue, | ||||||
|  |     pub pos: Option<DebugPosition>, | ||||||
|     pub size_bits: u64, |     pub size_bits: u64, | ||||||
|     pub offset: u64, |     pub offset: u64, | ||||||
|     pub flags: DwarfFlags, |     pub flags: DwarfFlags, | ||||||
|  | |||||||
| @ -11,8 +11,8 @@ use crate::{ | |||||||
|     debug_information::{ |     debug_information::{ | ||||||
|         DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, |         DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocalVariable, | ||||||
|         DebugLocation, DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, |         DebugLocation, DebugLocationValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, | ||||||
|         DebugPointerType, DebugProgramValue, DebugRecordKind, DebugScopeValue, DebugStructType, |         DebugPointerType, DebugPosition, DebugProgramValue, DebugRecordKind, DebugScopeValue, | ||||||
|         DebugSubprogramType, DebugTypeData, DebugTypeHolder, DebugTypeValue, |         DebugStructType, DebugSubprogramType, DebugTypeData, DebugTypeHolder, DebugTypeValue, | ||||||
|     }, |     }, | ||||||
|     pad_adapter::PadAdapter, |     pad_adapter::PadAdapter, | ||||||
| }; | }; | ||||||
| @ -171,6 +171,12 @@ impl DebugMetadataValue { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Display for DebugLocation { | impl Display for DebugLocation { | ||||||
|  |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         write!(f, "{:?} on scope {:?}", self.pos, self.scope) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Display for DebugPosition { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         write!(f, "line {}, col {}", self.line, self.column) |         write!(f, "line {}, col {}", self.line, self.column) | ||||||
|     } |     } | ||||||
| @ -484,7 +490,8 @@ impl Debug for DebugStructType { | |||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         f.debug_struct("Struct") |         f.debug_struct("Struct") | ||||||
|             .field("name", &self.name) |             .field("name", &self.name) | ||||||
|             .field("location", &self.location) |             .field("scope", &self.scope) | ||||||
|  |             .field("pos", &self.pos) | ||||||
|             .field("size_bit", &self.size_bits) |             .field("size_bit", &self.size_bits) | ||||||
|             .field("flags", &self.flags) |             .field("flags", &self.flags) | ||||||
|             .field("elements", &self.fields) |             .field("elements", &self.fields) | ||||||
| @ -495,7 +502,8 @@ impl Debug for DebugStructType { | |||||||
| impl Debug for DebugFieldType { | impl Debug for DebugFieldType { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         f.debug_struct(&format!("Field({})", self.name)) |         f.debug_struct(&format!("Field({})", self.name)) | ||||||
|             .field("location", &self.location) |             .field("scope", &self.scope) | ||||||
|  |             .field("pos", &self.pos) | ||||||
|             .field("size_bits", &self.size_bits) |             .field("size_bits", &self.size_bits) | ||||||
|             .field("offset", &self.offset) |             .field("offset", &self.offset) | ||||||
|             .field("flags", &self.flags) |             .field("flags", &self.flags) | ||||||
| @ -569,6 +577,12 @@ impl Debug for DebugLocationValue { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Debug for DebugLocation { | impl Debug for DebugLocation { | ||||||
|  |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|  |         write!(f, "{:?} on scope {:?}", self.pos, self.scope) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Debug for DebugPosition { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         write!(f, "ln {}, col {}", self.line, self.column) |         write!(f, "ln {}, col {}", self.line, self.column) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -521,7 +521,7 @@ impl ConstValue { | |||||||
|             ConstValue::U32(_) => U32, |             ConstValue::U32(_) => U32, | ||||||
|             ConstValue::U64(_) => U64, |             ConstValue::U64(_) => U64, | ||||||
|             ConstValue::U128(_) => U128, |             ConstValue::U128(_) => U128, | ||||||
|             ConstValue::Str(_) => Type::Ptr(Box::new(I8)), |             ConstValue::Str(_) => Type::Ptr(Box::new(U8)), | ||||||
|             ConstValue::Bool(_) => Bool, |             ConstValue::Bool(_) => Bool, | ||||||
|             ConstValue::F16(_) => F16, |             ConstValue::F16(_) => F16, | ||||||
|             ConstValue::F32B(_) => F32B, |             ConstValue::F32B(_) => F32B, | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ use reid_lib::{ | |||||||
|     debug_information::{ |     debug_information::{ | ||||||
|         DebugArrayType, DebugBasicType, DebugFieldType, DebugFileData, DebugInformation, |         DebugArrayType, DebugBasicType, DebugFieldType, DebugFileData, DebugInformation, | ||||||
|         DebugLocalVariable, DebugLocation, DebugMetadata, DebugParamVariable, DebugPointerType, |         DebugLocalVariable, DebugLocation, DebugMetadata, DebugParamVariable, DebugPointerType, | ||||||
|         DebugProgramValue, DebugRecordKind, DebugStructType, DebugSubprogramData, |         DebugPosition, DebugProgramValue, DebugRecordKind, DebugStructType, DebugSubprogramData, | ||||||
|         DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DebugTypeValue, |         DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DebugTypeValue, | ||||||
|         DwarfEncoding, DwarfFlags, InstructionDebugRecordData, |         DwarfEncoding, DwarfFlags, InstructionDebugRecordData, | ||||||
|     }, |     }, | ||||||
| @ -57,6 +57,8 @@ impl mir::Context { | |||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
| struct ModuleCodegen<'ctx> { | struct ModuleCodegen<'ctx> { | ||||||
|     module: Module<'ctx>, |     module: Module<'ctx>, | ||||||
|  |     tokens: &'ctx Vec<FullToken>, | ||||||
|  |     debug_types: Option<HashMap<TypeKind, DebugTypeValue>>, | ||||||
|     type_values: HashMap<TypeKey, TypeValue>, |     type_values: HashMap<TypeKey, TypeValue>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -194,7 +196,7 @@ impl Default for State { | |||||||
| 
 | 
 | ||||||
| impl mir::Module { | impl mir::Module { | ||||||
|     fn codegen<'ctx>( |     fn codegen<'ctx>( | ||||||
|         &self, |         &'ctx self, | ||||||
|         context: &'ctx Context, |         context: &'ctx Context, | ||||||
|         modules: HashMap<SourceModuleId, ModuleCodegen<'ctx>>, |         modules: HashMap<SourceModuleId, ModuleCodegen<'ctx>>, | ||||||
|     ) -> ModuleCodegen<'ctx> { |     ) -> ModuleCodegen<'ctx> { | ||||||
| @ -227,7 +229,9 @@ impl mir::Module { | |||||||
|                         &debug_types, |                         &debug_types, | ||||||
|                         &type_values, |                         &type_values, | ||||||
|                         &types, |                         &types, | ||||||
|                         tokens, |                         self.module_id, | ||||||
|  |                         &self.tokens, | ||||||
|  |                         &modules, | ||||||
|                     ), |                     ), | ||||||
|                 ) |                 ) | ||||||
|             }; |             }; | ||||||
| @ -247,29 +251,23 @@ impl mir::Module { | |||||||
|         insert_debug!(&TypeKind::Void); |         insert_debug!(&TypeKind::Void); | ||||||
|         insert_debug!(&TypeKind::Char); |         insert_debug!(&TypeKind::Char); | ||||||
| 
 | 
 | ||||||
|         for typedef in &self.typedefs { |         let mut typedefs = self.typedefs.clone(); | ||||||
|  |         typedefs.sort_by(|a, b| b.source_module.cmp(&a.source_module)); | ||||||
|  | 
 | ||||||
|  |         for typedef in typedefs { | ||||||
|             let type_key = TypeKey(typedef.name.clone(), typedef.source_module); |             let type_key = TypeKey(typedef.name.clone(), typedef.source_module); | ||||||
|             let type_value = if typedef.source_module != self.module_id { |             let type_value = match &typedef.kind { | ||||||
|                 *modules |                 TypeDefinitionKind::Struct(StructType(fields)) => { | ||||||
|                     .get(&typedef.source_module) |                     module.custom_type(CustomTypeKind::NamedStruct(NamedStruct( | ||||||
|                     .unwrap() |                         typedef.name.clone(), | ||||||
|                     .type_values |                         fields | ||||||
|                     .get(&type_key) |                             .iter() | ||||||
|                     .unwrap() |                             // TODO: Reorder custom-type definitions such that
 | ||||||
|             } else { |                             // inner types get evaluated first. Otherwise this
 | ||||||
|                 match &typedef.kind { |                             // will cause a panic!
 | ||||||
|                     TypeDefinitionKind::Struct(StructType(fields)) => { |                             .map(|StructField(_, t, _)| t.get_type(&type_values, &types)) | ||||||
|                         module.custom_type(CustomTypeKind::NamedStruct(NamedStruct( |                             .collect(), | ||||||
|                             typedef.name.clone(), |                     ))) | ||||||
|                             fields |  | ||||||
|                                 .iter() |  | ||||||
|                                 // TODO: Reorder custom-type definitions such that
 |  | ||||||
|                                 // inner types get evaluated first. Otherwise this
 |  | ||||||
|                                 // will cause a panic!
 |  | ||||||
|                                 .map(|StructField(_, t, _)| t.get_type(&type_values, &types)) |  | ||||||
|                                 .collect(), |  | ||||||
|                         ))) |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
|             types.insert(type_value, typedef.clone()); |             types.insert(type_value, typedef.clone()); | ||||||
| @ -316,120 +314,128 @@ impl mir::Module { | |||||||
| 
 | 
 | ||||||
|         for mir_function in &self.functions { |         for mir_function in &self.functions { | ||||||
|             let function = functions.get(&mir_function.name).unwrap(); |             let function = functions.get(&mir_function.name).unwrap(); | ||||||
|             let mut entry = function.ir.block("entry"); |  | ||||||
| 
 |  | ||||||
|             // Insert debug information
 |  | ||||||
|             let debug_scope = if let Some(location) = |  | ||||||
|                 mir_function.signature().into_debug(tokens, compile_unit) |  | ||||||
|             { |  | ||||||
|                 // let debug_scope = debug.inner_scope(&outer_scope, location);
 |  | ||||||
| 
 |  | ||||||
|                 let fn_param_ty = &mir_function.return_type.get_debug_type_hard( |  | ||||||
|                     compile_unit, |  | ||||||
|                     &debug, |  | ||||||
|                     &debug_types, |  | ||||||
|                     &type_values, |  | ||||||
|                     &types, |  | ||||||
|                     tokens, |  | ||||||
|                 ); |  | ||||||
| 
 |  | ||||||
|                 let debug_ty = debug.debug_type(DebugTypeData::Subprogram(DebugSubprogramType { |  | ||||||
|                     parameters: vec![*fn_param_ty], |  | ||||||
|                     flags: DwarfFlags, |  | ||||||
|                 })); |  | ||||||
| 
 |  | ||||||
|                 let subprogram = debug.subprogram(DebugSubprogramData { |  | ||||||
|                     name: mir_function.name.clone(), |  | ||||||
|                     outer_scope: compile_unit.clone(), |  | ||||||
|                     location, |  | ||||||
|                     ty: debug_ty, |  | ||||||
|                     opts: DebugSubprogramOptionals { |  | ||||||
|                         is_local: !mir_function.is_pub, |  | ||||||
|                         is_definition: true, |  | ||||||
|                         ..DebugSubprogramOptionals::default() |  | ||||||
|                     }, |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 function.ir.set_debug(subprogram); |  | ||||||
| 
 |  | ||||||
|                 Some(subprogram) |  | ||||||
|             } else { |  | ||||||
|                 None |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             // Compile actual IR part
 |  | ||||||
|             let mut stack_values = HashMap::new(); |  | ||||||
|             for (i, (p_name, p_ty)) in mir_function.parameters.iter().enumerate() { |  | ||||||
|                 // Codegen actual parameters
 |  | ||||||
|                 let arg_name = format!("arg.{}", p_name); |  | ||||||
|                 let param = entry |  | ||||||
|                     .build_named(format!("{}.get", arg_name), Instr::Param(i)) |  | ||||||
|                     .unwrap(); |  | ||||||
|                 let alloca = entry |  | ||||||
|                     .build_named( |  | ||||||
|                         &arg_name, |  | ||||||
|                         Instr::Alloca(p_ty.get_type(&type_values, &types)), |  | ||||||
|                     ) |  | ||||||
|                     .unwrap(); |  | ||||||
|                 entry |  | ||||||
|                     .build_named(format!("{}.store", arg_name), Instr::Store(alloca, param)) |  | ||||||
|                     .unwrap(); |  | ||||||
|                 stack_values.insert( |  | ||||||
|                     p_name.clone(), |  | ||||||
|                     StackValue( |  | ||||||
|                         StackValueKind::mutable(p_ty.is_mutable(), alloca), |  | ||||||
|                         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, |  | ||||||
|                                 tokens, |  | ||||||
|                             ), |  | ||||||
|                             always_preserve: true, |  | ||||||
|                             flags: DwarfFlags, |  | ||||||
|                         }), |  | ||||||
|                     ); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             let mut scope = Scope { |  | ||||||
|                 context, |  | ||||||
|                 modules: &modules, |  | ||||||
|                 tokens, |  | ||||||
|                 module: &module, |  | ||||||
|                 module_id: self.module_id, |  | ||||||
|                 function, |  | ||||||
|                 block: entry, |  | ||||||
|                 functions: &functions, |  | ||||||
|                 types: &types, |  | ||||||
|                 type_values: &type_values, |  | ||||||
|                 stack_values, |  | ||||||
|                 debug: debug_scope.and_then(|scope| { |  | ||||||
|                     Some(Debug { |  | ||||||
|                         info: &debug, |  | ||||||
|                         scope, |  | ||||||
|                         types: &debug_types, |  | ||||||
|                     }) |  | ||||||
|                 }), |  | ||||||
|             }; |  | ||||||
| 
 | 
 | ||||||
|             match &mir_function.kind { |             match &mir_function.kind { | ||||||
|                 mir::FunctionDefinitionKind::Local(block, _) => { |                 mir::FunctionDefinitionKind::Local(block, _) => { | ||||||
|  |                     let mut entry = function.ir.block("entry"); | ||||||
|  | 
 | ||||||
|  |                     // Insert debug information
 | ||||||
|  |                     let debug_scope = if let Some(location) = | ||||||
|  |                         mir_function.signature().into_debug(tokens, compile_unit) | ||||||
|  |                     { | ||||||
|  |                         // let debug_scope = debug.inner_scope(&outer_scope, location);
 | ||||||
|  | 
 | ||||||
|  |                         let fn_param_ty = &mir_function.return_type.get_debug_type_hard( | ||||||
|  |                             compile_unit, | ||||||
|  |                             &debug, | ||||||
|  |                             &debug_types, | ||||||
|  |                             &type_values, | ||||||
|  |                             &types, | ||||||
|  |                             self.module_id, | ||||||
|  |                             &self.tokens, | ||||||
|  |                             &modules, | ||||||
|  |                         ); | ||||||
|  | 
 | ||||||
|  |                         let debug_ty = | ||||||
|  |                             debug.debug_type(DebugTypeData::Subprogram(DebugSubprogramType { | ||||||
|  |                                 parameters: vec![*fn_param_ty], | ||||||
|  |                                 flags: DwarfFlags, | ||||||
|  |                             })); | ||||||
|  | 
 | ||||||
|  |                         let subprogram = debug.subprogram(DebugSubprogramData { | ||||||
|  |                             name: mir_function.name.clone(), | ||||||
|  |                             outer_scope: compile_unit.clone(), | ||||||
|  |                             location, | ||||||
|  |                             ty: debug_ty, | ||||||
|  |                             opts: DebugSubprogramOptionals { | ||||||
|  |                                 is_local: !mir_function.is_pub, | ||||||
|  |                                 is_definition: true, | ||||||
|  |                                 ..DebugSubprogramOptionals::default() | ||||||
|  |                             }, | ||||||
|  |                         }); | ||||||
|  | 
 | ||||||
|  |                         function.ir.set_debug(subprogram); | ||||||
|  | 
 | ||||||
|  |                         Some(subprogram) | ||||||
|  |                     } else { | ||||||
|  |                         None | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|  |                     // Compile actual IR part
 | ||||||
|  |                     let mut stack_values = HashMap::new(); | ||||||
|  |                     for (i, (p_name, p_ty)) in mir_function.parameters.iter().enumerate() { | ||||||
|  |                         // Codegen actual parameters
 | ||||||
|  |                         let arg_name = format!("arg.{}", p_name); | ||||||
|  |                         let param = entry | ||||||
|  |                             .build_named(format!("{}.get", arg_name), Instr::Param(i)) | ||||||
|  |                             .unwrap(); | ||||||
|  |                         let alloca = entry | ||||||
|  |                             .build_named( | ||||||
|  |                                 &arg_name, | ||||||
|  |                                 Instr::Alloca(p_ty.get_type(&type_values, &types)), | ||||||
|  |                             ) | ||||||
|  |                             .unwrap(); | ||||||
|  |                         entry | ||||||
|  |                             .build_named(format!("{}.store", arg_name), Instr::Store(alloca, param)) | ||||||
|  |                             .unwrap(); | ||||||
|  |                         stack_values.insert( | ||||||
|  |                             p_name.clone(), | ||||||
|  |                             StackValue( | ||||||
|  |                                 StackValueKind::mutable(p_ty.is_mutable(), alloca), | ||||||
|  |                                 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), | ||||||
|  |                         ) { | ||||||
|  |                             dbg!(mir_function.name.clone()); | ||||||
|  |                             dbg!(p_name.clone()); | ||||||
|  |                             // 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 mut scope = Scope { | ||||||
|  |                         context, | ||||||
|  |                         modules: &modules, | ||||||
|  |                         tokens, | ||||||
|  |                         module: &module, | ||||||
|  |                         module_id: self.module_id, | ||||||
|  |                         function, | ||||||
|  |                         block: entry, | ||||||
|  |                         functions: &functions, | ||||||
|  |                         types: &types, | ||||||
|  |                         type_values: &type_values, | ||||||
|  |                         stack_values, | ||||||
|  |                         debug: debug_scope.and_then(|scope| { | ||||||
|  |                             Some(Debug { | ||||||
|  |                                 info: &debug, | ||||||
|  |                                 scope, | ||||||
|  |                                 types: &debug_types, | ||||||
|  |                             }) | ||||||
|  |                         }), | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|                     let state = State::default(); |                     let state = State::default(); | ||||||
|                     if let Some(ret) = block.codegen(&mut scope, &state) { |                     if let Some(ret) = block.codegen(&mut scope, &state) { | ||||||
|                         scope.block.terminate(Term::Ret(ret.instr())).unwrap(); |                         scope.block.terminate(Term::Ret(ret.instr())).unwrap(); | ||||||
| @ -454,7 +460,9 @@ impl mir::Module { | |||||||
| 
 | 
 | ||||||
|         ModuleCodegen { |         ModuleCodegen { | ||||||
|             module, |             module, | ||||||
|  |             debug_types: Some(debug_types), | ||||||
|             type_values, |             type_values, | ||||||
|  |             tokens: &self.tokens, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -680,8 +688,9 @@ impl mir::Expression { | |||||||
|                 let params = call |                 let params = call | ||||||
|                     .parameters |                     .parameters | ||||||
|                     .iter() |                     .iter() | ||||||
|                     .map(|e| e.codegen(scope, &mut state.load(true)).unwrap().instr()) |                     .map(|e| e.codegen(scope, state).unwrap()) | ||||||
|                     .collect(); |                     .collect::<Vec<_>>(); | ||||||
|  |                 let param_instrs = params.iter().map(|e| e.instr()).collect(); | ||||||
|                 let callee = scope |                 let callee = scope | ||||||
|                     .functions |                     .functions | ||||||
|                     .get(&call.name) |                     .get(&call.name) | ||||||
| @ -691,7 +700,7 @@ impl mir::Expression { | |||||||
|                     .block |                     .block | ||||||
|                     .build_named( |                     .build_named( | ||||||
|                         call.name.clone(), |                         call.name.clone(), | ||||||
|                         Instr::FunctionCall(callee.ir.value(), params), |                         Instr::FunctionCall(callee.ir.value(), param_instrs), | ||||||
|                     ) |                     ) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
| 
 | 
 | ||||||
| @ -769,7 +778,6 @@ impl mir::Expression { | |||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 let (ptr, contained_ty) = if let TypeKind::UserPtr(further_inner) = *inner.clone() { |                 let (ptr, contained_ty) = if let TypeKind::UserPtr(further_inner) = *inner.clone() { | ||||||
|                     dbg!(&further_inner, &val_t); |  | ||||||
|                     let loaded = scope |                     let loaded = scope | ||||||
|                         .block |                         .block | ||||||
|                         .build_named( |                         .build_named( | ||||||
| @ -806,7 +814,6 @@ impl mir::Expression { | |||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 if state.should_load { |                 if state.should_load { | ||||||
|                     dbg!(&contained_ty); |  | ||||||
|                     Some(StackValue( |                     Some(StackValue( | ||||||
|                         kind.derive( |                         kind.derive( | ||||||
|                             scope |                             scope | ||||||
| @ -900,7 +907,6 @@ impl mir::Expression { | |||||||
|             mir::ExprKind::Accessed(expression, type_kind, field) => { |             mir::ExprKind::Accessed(expression, type_kind, field) => { | ||||||
|                 let struct_val = expression.codegen(scope, &state.load(false)).unwrap(); |                 let struct_val = expression.codegen(scope, &state.load(false)).unwrap(); | ||||||
| 
 | 
 | ||||||
|                 dbg!(&expression, &struct_val); |  | ||||||
|                 let TypeKind::CodegenPtr(inner) = &struct_val.1 else { |                 let TypeKind::CodegenPtr(inner) = &struct_val.1 else { | ||||||
|                     panic!("tried accessing non-pointer"); |                     panic!("tried accessing non-pointer"); | ||||||
|                 }; |                 }; | ||||||
| @ -1049,7 +1055,7 @@ impl mir::Expression { | |||||||
|                         }; |                         }; | ||||||
|                         StackValue( |                         StackValue( | ||||||
|                             StackValueKind::mutable(mutable, var_ptr_instr), |                             StackValueKind::mutable(mutable, var_ptr_instr), | ||||||
|                             *borrow_inner.clone(), |                             TypeKind::CodegenPtr(borrow_inner.clone()), | ||||||
|                         ) |                         ) | ||||||
|                     } |                     } | ||||||
|                 }) |                 }) | ||||||
| @ -1059,7 +1065,18 @@ impl mir::Expression { | |||||||
|                 if val.1 == *type_kind { |                 if val.1 == *type_kind { | ||||||
|                     Some(val) |                     Some(val) | ||||||
|                 } else if let (TypeKind::UserPtr(_), TypeKind::UserPtr(_)) = (&val.1, type_kind) { |                 } else if let (TypeKind::UserPtr(_), TypeKind::UserPtr(_)) = (&val.1, type_kind) { | ||||||
|                     Some(val) |                     Some(StackValue( | ||||||
|  |                         val.0.derive( | ||||||
|  |                             scope | ||||||
|  |                                 .block | ||||||
|  |                                 .build(Instr::BitCast( | ||||||
|  |                                     val.instr(), | ||||||
|  |                                     type_kind.get_type(scope.type_values, scope.types), | ||||||
|  |                                 )) | ||||||
|  |                                 .unwrap(), | ||||||
|  |                         ), | ||||||
|  |                         type_kind.clone(), | ||||||
|  |                     )) | ||||||
|                 } else { |                 } else { | ||||||
|                     let cast_instr = val |                     let cast_instr = val | ||||||
|                         .1 |                         .1 | ||||||
| @ -1262,7 +1279,7 @@ impl TypeKind { | |||||||
|             TypeKind::F128 => Type::F128, |             TypeKind::F128 => Type::F128, | ||||||
|             TypeKind::F80 => Type::F80, |             TypeKind::F80 => Type::F80, | ||||||
|             TypeKind::F128PPC => Type::F128PPC, |             TypeKind::F128PPC => Type::F128PPC, | ||||||
|             TypeKind::Char => Type::I8, |             TypeKind::Char => Type::U8, | ||||||
|             TypeKind::Array(elem_t, len) => { |             TypeKind::Array(elem_t, len) => { | ||||||
|                 Type::Array(Box::new(elem_t.get_type(type_vals, typedefs)), *len) |                 Type::Array(Box::new(elem_t.get_type(type_vals, typedefs)), *len) | ||||||
|             } |             } | ||||||
| @ -1293,7 +1310,9 @@ impl TypeKind { | |||||||
|             debug.types, |             debug.types, | ||||||
|             scope.type_values, |             scope.type_values, | ||||||
|             scope.types, |             scope.types, | ||||||
|  |             scope.module_id, | ||||||
|             scope.tokens, |             scope.tokens, | ||||||
|  |             scope.modules, | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -1304,7 +1323,9 @@ impl TypeKind { | |||||||
|         debug_types: &HashMap<TypeKind, DebugTypeValue>, |         debug_types: &HashMap<TypeKind, DebugTypeValue>, | ||||||
|         type_values: &HashMap<TypeKey, TypeValue>, |         type_values: &HashMap<TypeKey, TypeValue>, | ||||||
|         types: &HashMap<TypeValue, TypeDefinition>, |         types: &HashMap<TypeValue, TypeDefinition>, | ||||||
|  |         local_mod: SourceModuleId, | ||||||
|         tokens: &Vec<FullToken>, |         tokens: &Vec<FullToken>, | ||||||
|  |         modules: &HashMap<SourceModuleId, ModuleCodegen>, | ||||||
|     ) -> DebugTypeValue { |     ) -> DebugTypeValue { | ||||||
|         if let Some(ty) = debug_types.get(self) { |         if let Some(ty) = debug_types.get(self) { | ||||||
|             return *ty; |             return *ty; | ||||||
| @ -1322,7 +1343,9 @@ impl TypeKind { | |||||||
|                         debug_types, |                         debug_types, | ||||||
|                         type_values, |                         type_values, | ||||||
|                         types, |                         types, | ||||||
|  |                         local_mod, | ||||||
|                         tokens, |                         tokens, | ||||||
|  |                         modules, | ||||||
|                     ), |                     ), | ||||||
|                     size_bits: self.size_of(), |                     size_bits: self.size_of(), | ||||||
|                 }) |                 }) | ||||||
| @ -1334,7 +1357,9 @@ impl TypeKind { | |||||||
|                     debug_types, |                     debug_types, | ||||||
|                     type_values, |                     type_values, | ||||||
|                     types, |                     types, | ||||||
|  |                     local_mod, | ||||||
|                     tokens, |                     tokens, | ||||||
|  |                     modules, | ||||||
|                 ); |                 ); | ||||||
|                 DebugTypeData::Array(DebugArrayType { |                 DebugTypeData::Array(DebugArrayType { | ||||||
|                     size_bits: self.size_of(), |                     size_bits: self.size_of(), | ||||||
| @ -1345,15 +1370,21 @@ impl TypeKind { | |||||||
|             } |             } | ||||||
|             TypeKind::CustomType(key) => { |             TypeKind::CustomType(key) => { | ||||||
|                 let typedef = types.get(type_values.get(key).unwrap()).unwrap(); |                 let typedef = types.get(type_values.get(key).unwrap()).unwrap(); | ||||||
| 
 |  | ||||||
|                 match &typedef.kind { |                 match &typedef.kind { | ||||||
|                     TypeDefinitionKind::Struct(struct_type) => { |                     TypeDefinitionKind::Struct(struct_type) => { | ||||||
|                         let mut fields = Vec::new(); |                         let mut fields = Vec::new(); | ||||||
|                         let mut size_bits = 0; |                         let mut size_bits = 0; | ||||||
|  | 
 | ||||||
|                         for field in &struct_type.0 { |                         for field in &struct_type.0 { | ||||||
|  |                             let location = if typedef.source_module != local_mod { | ||||||
|  |                                 None | ||||||
|  |                             } else { | ||||||
|  |                                 field.2.into_debug(&tokens, scope) | ||||||
|  |                             }; | ||||||
|                             fields.push(DebugFieldType { |                             fields.push(DebugFieldType { | ||||||
|                                 name: field.0.clone(), |                                 name: field.0.clone(), | ||||||
|                                 location: field.2.into_debug(tokens, scope).unwrap(), |                                 scope, | ||||||
|  |                                 pos: location.map(|l| l.pos), | ||||||
|                                 size_bits: field.1.size_of(), |                                 size_bits: field.1.size_of(), | ||||||
|                                 offset: size_bits, |                                 offset: size_bits, | ||||||
|                                 flags: DwarfFlags, |                                 flags: DwarfFlags, | ||||||
| @ -1363,15 +1394,23 @@ impl TypeKind { | |||||||
|                                     debug_types, |                                     debug_types, | ||||||
|                                     type_values, |                                     type_values, | ||||||
|                                     types, |                                     types, | ||||||
|  |                                     local_mod, | ||||||
|                                     tokens, |                                     tokens, | ||||||
|  |                                     modules, | ||||||
|                                 ), |                                 ), | ||||||
|                             }); |                             }); | ||||||
|                             size_bits += field.1.size_of(); |                             size_bits += field.1.size_of(); | ||||||
|                         } |                         } | ||||||
|                         { |                         { | ||||||
|  |                             let location = if typedef.source_module != local_mod { | ||||||
|  |                                 None | ||||||
|  |                             } else { | ||||||
|  |                                 typedef.meta.into_debug(&tokens, scope) | ||||||
|  |                             }; | ||||||
|                             DebugTypeData::Struct(DebugStructType { |                             DebugTypeData::Struct(DebugStructType { | ||||||
|                                 name: key.0.clone(), |                                 name: key.0.clone(), | ||||||
|                                 location: typedef.meta.into_debug(tokens, scope).unwrap(), |                                 scope, | ||||||
|  |                                 pos: location.map(|l| l.pos), | ||||||
|                                 size_bits, |                                 size_bits, | ||||||
|                                 flags: DwarfFlags, |                                 flags: DwarfFlags, | ||||||
|                                 fields, |                                 fields, | ||||||
| @ -1422,7 +1461,7 @@ impl Metadata { | |||||||
|         if let Some((start, _)) = self.into_positions(tokens) { |         if let Some((start, _)) = self.into_positions(tokens) { | ||||||
|             Some(start.debug(scope)) |             Some(start.debug(scope)) | ||||||
|         } else { |         } else { | ||||||
|             Some(Position(0, 0).debug(scope)) |             None | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -1430,8 +1469,10 @@ impl Metadata { | |||||||
| impl Position { | impl Position { | ||||||
|     fn debug(self, scope: DebugProgramValue) -> DebugLocation { |     fn debug(self, scope: DebugProgramValue) -> DebugLocation { | ||||||
|         DebugLocation { |         DebugLocation { | ||||||
|             line: self.1, |             pos: DebugPosition { | ||||||
|             column: self.0, |                 line: self.1, | ||||||
|  |                 column: self.0, | ||||||
|  |             }, | ||||||
|             scope, |             scope, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user