|  | 
| 1 |  | -use rustc_middle::mir::{self, NonDivergingIntrinsic}; | 
| 2 |  | -use rustc_middle::span_bug; | 
|  | 1 | +use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo}; | 
|  | 2 | +use rustc_middle::{bug, span_bug}; | 
| 3 | 3 | use tracing::instrument; | 
| 4 | 4 | 
 | 
| 5 | 5 | use super::{FunctionCx, LocalRef}; | 
|  | 6 | +use crate::common::TypeKind; | 
|  | 7 | +use crate::mir::operand::OperandValue; | 
|  | 8 | +use crate::mir::place::PlaceRef; | 
| 6 | 9 | use crate::traits::*; | 
| 7 | 10 | 
 | 
| 8 | 11 | impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | 
| 9 | 12 |     #[instrument(level = "debug", skip(self, bx))] | 
| 10 | 13 |     pub(crate) fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) { | 
|  | 14 | +        self.codegen_stmt_debuginfos(bx, &statement.debuginfos); | 
| 11 | 15 |         self.set_debug_loc(bx, statement.source_info); | 
| 12 | 16 |         match statement.kind { | 
| 13 | 17 |             mir::StatementKind::Assign(box (ref place, ref rvalue)) => { | 
| @@ -96,4 +100,68 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | 
| 96 | 100 |             | mir::StatementKind::Nop => {} | 
| 97 | 101 |         } | 
| 98 | 102 |     } | 
|  | 103 | + | 
|  | 104 | +    pub(crate) fn codegen_stmt_debuginfo(&mut self, bx: &mut Bx, debuginfo: &StmtDebugInfo<'tcx>) { | 
|  | 105 | +        match debuginfo { | 
|  | 106 | +            StmtDebugInfo::AssignRef(dest, place) => { | 
|  | 107 | +                let place_ref = match self.locals[place.local] { | 
|  | 108 | +                    LocalRef::Place(place_ref) | LocalRef::UnsizedPlace(place_ref) => { | 
|  | 109 | +                        Some(place_ref) | 
|  | 110 | +                    } | 
|  | 111 | +                    LocalRef::Operand(operand_ref) => match operand_ref.val { | 
|  | 112 | +                        OperandValue::Ref(_place_value) => { | 
|  | 113 | +                            todo!("supports OperandValue::Ref") | 
|  | 114 | +                        } | 
|  | 115 | +                        OperandValue::Immediate(v) => { | 
|  | 116 | +                            // FIXME: add ref to layout? | 
|  | 117 | +                            Some(PlaceRef::new_sized(v, operand_ref.layout)) | 
|  | 118 | +                        } | 
|  | 119 | +                        OperandValue::Pair(_, _) => None, | 
|  | 120 | +                        OperandValue::ZeroSized => None, | 
|  | 121 | +                    }, | 
|  | 122 | +                    LocalRef::PendingOperand => None, | 
|  | 123 | +                } | 
|  | 124 | +                .filter(|place_ref| { | 
|  | 125 | +                    // Drop unsupported projections. | 
|  | 126 | +                    // FIXME: Add a test case. | 
|  | 127 | +                    place.projection.iter().all(|p| p.can_use_in_debuginfo()) && | 
|  | 128 | +                    // Only pointers can calculate addresses. | 
|  | 129 | +                    bx.type_kind(bx.val_ty(place_ref.val.llval)) == TypeKind::Pointer | 
|  | 130 | +                }); | 
|  | 131 | +                let (val, layout, projection) = | 
|  | 132 | +                    match (place_ref, place.is_indirect_first_projection()) { | 
|  | 133 | +                        (Some(place_ref), false) => { | 
|  | 134 | +                            (place_ref.val, place_ref.layout, place.projection.as_slice()) | 
|  | 135 | +                        } | 
|  | 136 | +                        (Some(place_ref), true) => { | 
|  | 137 | +                            let projected_ty = | 
|  | 138 | +                                place_ref.layout.ty.builtin_deref(true).unwrap_or_else(|| { | 
|  | 139 | +                                    bug!("deref of non-pointer {:?}", place_ref) | 
|  | 140 | +                                }); | 
|  | 141 | +                            let layout = bx.cx().layout_of(projected_ty); | 
|  | 142 | +                            (place_ref.val, layout, &place.projection[1..]) | 
|  | 143 | +                        } | 
|  | 144 | +                        _ => { | 
|  | 145 | +                            // If the address cannot be computed, use poison to indicate that the value has been optimized out. | 
|  | 146 | +                            let ty = self.monomorphize(self.mir.local_decls[*dest].ty); | 
|  | 147 | +                            let layout = bx.cx().layout_of(ty); | 
|  | 148 | +                            let to_backend_ty = bx.cx().immediate_backend_type(layout); | 
|  | 149 | +                            let place_ref = | 
|  | 150 | +                                PlaceRef::new_sized(bx.cx().const_poison(to_backend_ty), layout); | 
|  | 151 | +                            (place_ref.val, layout, [].as_slice()) | 
|  | 152 | +                        } | 
|  | 153 | +                    }; | 
|  | 154 | +                self.debug_new_value_to_local(bx, *dest, val, layout, projection); | 
|  | 155 | +            } | 
|  | 156 | +        } | 
|  | 157 | +    } | 
|  | 158 | +    pub(crate) fn codegen_stmt_debuginfos( | 
|  | 159 | +        &mut self, | 
|  | 160 | +        bx: &mut Bx, | 
|  | 161 | +        debuginfos: &[StmtDebugInfo<'tcx>], | 
|  | 162 | +    ) { | 
|  | 163 | +        for debuginfo in debuginfos { | 
|  | 164 | +            self.codegen_stmt_debuginfo(bx, debuginfo); | 
|  | 165 | +        } | 
|  | 166 | +    } | 
| 99 | 167 | } | 
0 commit comments