use self::InternalDebugLocation::*; use super::metadata::UNKNOWN_COLUMN_NUMBER; use super::utils::{debug_context, span_start}; use rustc_codegen_ssa::mir::debuginfo::FunctionDebugContext; use crate::builder::Builder; use crate::llvm; use crate::llvm::debuginfo::DIScope; use log::debug; use rustc_codegen_ssa::traits::*; use libc::c_uint; use rustc_span::{Pos, Span}; /// Sets the current debug location at the beginning of the span. /// /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). pub fn set_source_location( debug_context: &FunctionDebugContext, bx: &Builder<'_, 'll, '_>, scope: &'ll DIScope, span: Span, ) { let dbg_loc = if debug_context.source_locations_enabled { debug!("set_source_location: {}", bx.sess().source_map().span_to_string(span)); let loc = span_start(bx.cx(), span); InternalDebugLocation::new(scope, loc.line, loc.col.to_usize()) } else { UnknownLocation }; set_debug_location(bx, dbg_loc); } #[derive(Copy, Clone, PartialEq)] pub enum InternalDebugLocation<'ll> { KnownLocation { scope: &'ll DIScope, line: usize, col: usize }, UnknownLocation, } impl InternalDebugLocation<'ll> { pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self { KnownLocation { scope, line, col } } } pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDebugLocation<'ll>) { let metadata_node = match debug_location { KnownLocation { scope, line, col } => { // For MSVC, set the column number to zero. // Otherwise, emit it. This mimics clang behaviour. // See discussion in https://github.com/rust-lang/rust/issues/42921 let col_used = if bx.sess().target.target.options.is_like_msvc { UNKNOWN_COLUMN_NUMBER } else { col as c_uint }; debug!("setting debug location to {} {}", line, col); unsafe { Some(llvm::LLVMRustDIBuilderCreateDebugLocation( debug_context(bx.cx()).llcontext, line as c_uint, col_used, scope, None, )) } } UnknownLocation => { debug!("clearing debug location "); None } }; unsafe { llvm::LLVMSetCurrentDebugLocation(bx.llbuilder, metadata_node); } }