use self::InternalDebugLocation::*; use super::utils::{debug_context, span_start}; use super::metadata::UNKNOWN_COLUMN_NUMBER; use rustc_codegen_ssa::mir::debuginfo::FunctionDebugContext; use crate::llvm; use crate::llvm::debuginfo::DIScope; use crate::builder::Builder; use rustc_codegen_ssa::traits::*; use log::debug; use libc::c_uint; use syntax_pos::{Span, Pos}; /// 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); } }