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, DebugLoc};
18 use llvm::debuginfo::DIScope;
20 use common::{CrateContext, FunctionContext};
26 /// Sets the current debug location at the beginning of the span.
28 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...).
29 pub fn set_source_location(fcx: &FunctionContext,
30 builder: Option<&Builder>,
31 debug_loc: DebugLoc) {
32 let builder = builder.map(|b| b.llbuilder);
33 let function_debug_context = match fcx.debug_context {
34 FunctionDebugContext::DebugInfoDisabled => return,
35 FunctionDebugContext::FunctionWithoutDebugInfo => {
36 set_debug_location(fcx.ccx, builder, UnknownLocation);
39 FunctionDebugContext::RegularContext(box ref data) => data
42 if function_debug_context.source_location_override.get() {
43 // Just ignore any attempts to set a new debug location while
44 // the override is active.
48 let dbg_loc = if function_debug_context.source_locations_enabled.get() {
49 let (scope, span) = match debug_loc {
50 DebugLoc::ScopeAt(scope, span) => (scope, span),
52 set_debug_location(fcx.ccx, builder, UnknownLocation);
57 debug!("set_source_location: {}",
58 fcx.ccx.sess().codemap().span_to_string(span));
59 let loc = span_start(fcx.ccx, span);
60 InternalDebugLocation::new(scope, loc.line, loc.col.to_usize())
64 set_debug_location(fcx.ccx, builder, dbg_loc);
67 /// Enables emitting source locations for the given functions.
69 /// Since we don't want source locations to be emitted for the function prelude,
70 /// they are disabled when beginning to translate a new function. This functions
71 /// switches source location emitting on and must therefore be called before the
72 /// first real statement/expression of the function is translated.
73 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
74 match fcx.debug_context {
75 FunctionDebugContext::RegularContext(box ref data) => {
76 data.source_locations_enabled.set(true)
78 _ => { /* safe to ignore */ }
83 #[derive(Copy, Clone, PartialEq)]
84 pub enum InternalDebugLocation {
85 KnownLocation { scope: DIScope, line: usize, col: usize },
89 impl InternalDebugLocation {
90 pub fn new(scope: DIScope, line: usize, col: usize) -> InternalDebugLocation {
99 pub fn set_debug_location(cx: &CrateContext,
100 builder: Option<llvm::BuilderRef>,
101 debug_location: InternalDebugLocation) {
102 if builder.is_none() {
103 if debug_location == debug_context(cx).current_debug_location.get() {
108 let metadata_node = match debug_location {
109 KnownLocation { scope, line, .. } => {
110 // Always set the column to zero like Clang and GCC
111 let col = UNKNOWN_COLUMN_NUMBER;
112 debug!("setting debug location to {} {}", line, col);
115 llvm::LLVMRustDIBuilderCreateDebugLocation(
116 debug_context(cx).llcontext,
124 debug!("clearing debug location ");
129 if builder.is_none() {
130 debug_context(cx).current_debug_location.set(debug_location);
133 let builder = builder.unwrap_or_else(|| cx.raw_builder());
135 llvm::LLVMSetCurrentDebugLocation(builder, metadata_node);