1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use self::InternalDebugLocation::*;
13 use super::utils::{debug_context, span_start};
14 use super::metadata::UNKNOWN_COLUMN_NUMBER;
15 use super::FunctionDebugContext;
18 use llvm::debuginfo::DIScope;
20 use traits::BuilderMethods;
23 use syntax_pos::{Span, Pos};
25 /// Sets the current debug location at the beginning of the span.
27 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...).
28 pub fn set_source_location(
29 debug_context: &FunctionDebugContext<'ll>,
30 bx: &Builder<'_, 'll, '_>,
31 scope: Option<&'ll DIScope>,
34 let function_debug_context = match *debug_context {
35 FunctionDebugContext::DebugInfoDisabled => return,
36 FunctionDebugContext::FunctionWithoutDebugInfo => {
37 set_debug_location(bx, UnknownLocation);
40 FunctionDebugContext::RegularContext(ref data) => data
43 let dbg_loc = if function_debug_context.source_locations_enabled.get() {
44 debug!("set_source_location: {}", bx.sess().source_map().span_to_string(span));
45 let loc = span_start(bx.cx, span);
46 InternalDebugLocation::new(scope.unwrap(), loc.line, loc.col.to_usize())
50 set_debug_location(bx, dbg_loc);
53 /// Enables emitting source locations for the given functions.
55 /// Since we don't want source locations to be emitted for the function prelude,
56 /// they are disabled when beginning to codegen a new function. This functions
57 /// switches source location emitting on and must therefore be called before the
58 /// first real statement/expression of the function is codegened.
59 pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext<'ll>) {
60 if let FunctionDebugContext::RegularContext(ref data) = *dbg_context {
61 data.source_locations_enabled.set(true);
66 #[derive(Copy, Clone, PartialEq)]
67 pub enum InternalDebugLocation<'ll> {
68 KnownLocation { scope: &'ll DIScope, line: usize, col: usize },
72 impl InternalDebugLocation<'ll> {
73 pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self {
82 pub fn set_debug_location(
83 bx: &Builder<'_, 'll, '_>,
84 debug_location: InternalDebugLocation<'ll>
86 let metadata_node = match debug_location {
87 KnownLocation { scope, line, col } => {
88 // For MSVC, set the column number to zero.
89 // Otherwise, emit it. This mimics clang behaviour.
90 // See discussion in https://github.com/rust-lang/rust/issues/42921
91 let col_used = if bx.cx.sess().target.target.options.is_like_msvc {
96 debug!("setting debug location to {} {}", line, col);
99 Some(llvm::LLVMRustDIBuilderCreateDebugLocation(
100 debug_context(bx.cx).llcontext,
108 debug!("clearing debug location ");
114 llvm::LLVMSetCurrentDebugLocation(bx.llbuilder, metadata_node);