]> git.lizzy.rs Git - rust.git/commitdiff
[WIP] debuginfo: Add types for locals
authorbjorn3 <bjorn3@users.noreply.github.com>
Sat, 9 Nov 2019 17:40:11 +0000 (18:40 +0100)
committerbjorn3 <bjorn3@users.noreply.github.com>
Mon, 16 Dec 2019 11:04:34 +0000 (12:04 +0100)
src/base.rs
src/debuginfo.rs

index 91c2587331315e6e1abe4a4d14a4a6e2d3585478..bb0ffb51bcec14882b7fd7056130d697f20b5325 100644 (file)
@@ -17,7 +17,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
     let mut debug_context = cx
         .debug_context
         .as_mut()
-        .map(|debug_context| FunctionDebugContext::new(tcx, debug_context, mir, func_id, &name, &sig));
+        .map(|debug_context| FunctionDebugContext::new(debug_context, mir, func_id, &name, &sig));
 
     // Make FunctionBuilder
     let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);
index 0998236e5822905f06df5c279baa73591aadadb4..b3de6449ff4b437abea97654af39ba1197bbd7b8 100644 (file)
@@ -70,13 +70,15 @@ pub enum DebugRelocName {
 }
 
 pub struct DebugContext<'tcx> {
+    tcx: TyCtxt<'tcx>,
+
     endian: RunTimeEndian,
     symbols: indexmap::IndexMap<FuncId, String>,
 
     dwarf: DwarfUnit,
     unit_range_list: RangeList,
 
-    _dummy: PhantomData<&'tcx ()>,
+    types: HashMap<Ty<'tcx>, UnitEntryId>,
 }
 
 impl<'tcx> DebugContext<'tcx> {
@@ -132,18 +134,20 @@ pub fn new(tcx: TyCtxt<'tcx>, address_size: u8) -> Self {
         }
 
         DebugContext {
+            tcx,
+
             endian: target_endian(tcx),
             symbols: indexmap::IndexMap::new(),
 
             dwarf,
             unit_range_list: RangeList(Vec::new()),
 
-            _dummy: PhantomData,
+            types: HashMap::new(),
         }
     }
 
-    fn emit_location(&mut self, tcx: TyCtxt<'tcx>, entry_id: UnitEntryId, span: Span) {
-        let loc = tcx.sess.source_map().lookup_char_pos(span.lo());
+    fn emit_location(&mut self, entry_id: UnitEntryId, span: Span) {
+        let loc = self.tcx.sess.source_map().lookup_char_pos(span.lo());
 
         let file_id = line_program_add_file(
             &mut self.dwarf.unit.line_program,
@@ -168,6 +172,58 @@ fn emit_location(&mut self, tcx: TyCtxt<'tcx>, entry_id: UnitEntryId, span: Span
         );
     }
 
+    fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId {
+        if let Some(type_id) = self.types.get(ty) {
+            return *type_id;
+        }
+
+        let new_entry = |dwarf: &mut DwarfUnit, tag| {
+            dwarf.unit.add(dwarf.unit.root(), tag)
+        };
+
+        let primtive = |dwarf: &mut DwarfUnit, ate| {
+            let type_id = new_entry(dwarf, gimli::DW_TAG_base_type);
+            let type_entry = dwarf.unit.get_mut(type_id);
+            type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(ate));
+            type_id
+        };
+
+        let type_id = match ty.kind {
+            ty::Bool => primtive(&mut self.dwarf, gimli::DW_ATE_boolean),
+            ty::Char => primtive(&mut self.dwarf, gimli::DW_ATE_UTF),
+            ty::Uint(_) => primtive(&mut self.dwarf, gimli::DW_ATE_unsigned),
+            ty::Int(_) => primtive(&mut self.dwarf, gimli::DW_ATE_signed),
+            ty::Float(_) => primtive(&mut self.dwarf, gimli::DW_ATE_float),
+            ty::Ref(_, pointee_ty, mutbl) | ty::RawPtr(ty::TypeAndMut { ty: pointee_ty, mutbl }) => {
+                let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type);
+
+                // Ensure that type is inserted before recursing to avoid duplicates
+                self.types.insert(ty, type_id);
+
+                let pointee = self.dwarf_ty(pointee_ty);
+
+                let type_entry = self.dwarf.unit.get_mut(type_id);
+
+                //type_entry.set(gimli::DW_AT_mutable, AttributeValue::Flag(mutbl == rustc::hir::Mutability::MutMutable));
+                type_entry.set(gimli::DW_AT_type, AttributeValue::ThisUnitEntryRef(pointee));
+
+                type_id
+            }
+            _ => new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type),
+        };
+        let name = format!("{}", ty);
+        let layout = self.tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap();
+
+        let type_entry = self.dwarf.unit.get_mut(type_id);
+
+        type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
+        type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes()));
+
+        self.types.insert(ty, type_id);
+
+        type_id
+    }
+
     pub fn emit<P: WriteDebugInfo>(&mut self, product: &mut P) {
         let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
         let root = self.dwarf.unit.root();
@@ -205,13 +261,13 @@ pub struct FunctionDebugContext<'a, 'tcx> {
     entry_id: UnitEntryId,
     symbol: usize,
     mir_span: Span,
+    local_decls: rustc_index::vec::IndexVec<mir::Local, mir::LocalDecl<'tcx>>,
 }
 
 impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
     pub fn new(
-        tcx: TyCtxt<'tcx>,
         debug_context: &'a mut DebugContext<'tcx>,
-        mir: &Body,
+        mir: &'tcx Body,
         func_id: FuncId,
         name: &str,
         _sig: &Signature,
@@ -237,13 +293,14 @@ pub fn new(
             AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
         );
 
-        debug_context.emit_location(tcx, entry_id, mir.span);
+        debug_context.emit_location(entry_id, mir.span);
 
         FunctionDebugContext {
             debug_context,
             entry_id,
             symbol,
             mir_span: mir.span,
+            local_decls: mir.local_decls.clone(),
         }
     }
 
@@ -329,6 +386,8 @@ pub fn define(
                 );
                 let live_ranges_id = self.debug_context.dwarf.unit.ranges.add(live_ranges);
 
+                let local_type = self.debug_context.dwarf_ty(self.local_decls[mir::Local::from_u32(value_label.as_u32())].ty);
+
                 let var_id = self
                     .debug_context
                     .dwarf
@@ -344,6 +403,10 @@ pub fn define(
                     gimli::DW_AT_name,
                     AttributeValue::String(format!("{:?}", value_label).into_bytes()),
                 );
+                var_entry.set(
+                    gimli::DW_AT_type,
+                    AttributeValue::ThisUnitEntryRef(local_type),
+                );
             }
         }