(&mut self, span: Span)
| 664 | } |
| 665 | |
| 666 | fn set_span(&mut self, span: Span) { |
| 667 | // HACK(eddyb) this is what `#[track_caller]` does, and we need it to be |
| 668 | // able to point at e.g. a use of `panic!`, instead of its implementation, |
| 669 | // but it should be more fine-grained and/or include macro backtraces in |
| 670 | // debuginfo (so the decision to use them can be deferred). |
| 671 | let span = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); |
| 672 | |
| 673 | let old_span = self.current_span.replace(span); |
| 674 | |
| 675 | // FIXME(eddyb) enable this once cross-block interactions are figured out |
| 676 | // (in particular, every block starts off with no debuginfo active). |
| 677 | if false { |
| 678 | // Avoid redundant debuginfo. |
| 679 | if old_span == Some(span) { |
| 680 | return; |
| 681 | } |
| 682 | } |
| 683 | |
| 684 | // HACK(eddyb) this is only to aid testing (and to not remove the old code). |
| 685 | let use_custom_insts = true; |
| 686 | |
| 687 | if use_custom_insts { |
| 688 | // FIXME(eddyb) this should be cached more efficiently. |
| 689 | let void_ty = SpirvType::Void.def(rustc_span::DUMMY_SP, self); |
| 690 | |
| 691 | // We may not always have valid spans. |
| 692 | // FIXME(eddyb) reduce the sources of this as much as possible. |
| 693 | if span.is_dummy() { |
| 694 | self.custom_inst(void_ty, CustomInst::ClearDebugSrcLoc); |
| 695 | } else { |
| 696 | let (file, line_col_range) = self.builder.file_line_col_range_for_debuginfo(span); |
| 697 | let ((line_start, col_start), (line_end, col_end)) = |
| 698 | (line_col_range.start, line_col_range.end); |
| 699 | |
| 700 | self.custom_inst( |
| 701 | void_ty, |
| 702 | CustomInst::SetDebugSrcLoc { |
| 703 | file: Operand::IdRef(file.file_name_op_string_id), |
| 704 | line_start: Operand::IdRef(self.const_u32(line_start).def(self)), |
| 705 | line_end: Operand::IdRef(self.const_u32(line_end).def(self)), |
| 706 | col_start: Operand::IdRef(self.const_u32(col_start).def(self)), |
| 707 | col_end: Operand::IdRef(self.const_u32(col_end).def(self)), |
| 708 | }, |
| 709 | ); |
| 710 | } |
| 711 | |
| 712 | // HACK(eddyb) remove the previous instruction if made irrelevant. |
| 713 | let mut builder = self.emit(); |
| 714 | if let (Some(func_idx), Some(block_idx)) = |
| 715 | (builder.selected_function(), builder.selected_block()) |
| 716 | { |
| 717 | let block = &mut builder.module_mut().functions[func_idx].blocks[block_idx]; |
| 718 | match &block.instructions[..] { |
| 719 | [.., a, b] |
| 720 | if a.class.opcode == b.class.opcode |
| 721 | && a.operands[..2] == b.operands[..2] => |
| 722 | { |
| 723 | block.instructions.remove(block.instructions.len() - 2); |
no test coverage detected