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::{scope_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::At(node_id, span) => {
51 (scope_metadata(fcx, node_id, span), span)
53 DebugLoc::ScopeAt(scope, span) => (scope, span),
55 set_debug_location(fcx.ccx, builder, UnknownLocation);
60 debug!("set_source_location: {}",
61 fcx.ccx.sess().codemap().span_to_string(span));
62 let loc = span_start(fcx.ccx, span);
63 InternalDebugLocation::new(scope, loc.line, loc.col.to_usize())
67 set_debug_location(fcx.ccx, builder, dbg_loc);
70 /// Enables emitting source locations for the given functions.
72 /// Since we don't want source locations to be emitted for the function prelude,
73 /// they are disabled when beginning to translate a new function. This functions
74 /// switches source location emitting on and must therefore be called before the
75 /// first real statement/expression of the function is translated.
76 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
77 match fcx.debug_context {
78 FunctionDebugContext::RegularContext(box ref data) => {
79 data.source_locations_enabled.set(true)
81 _ => { /* safe to ignore */ }
86 #[derive(Copy, Clone, PartialEq)]
87 pub enum InternalDebugLocation {
88 KnownLocation { scope: DIScope, line: usize, col: usize },
92 impl InternalDebugLocation {
93 pub fn new(scope: DIScope, line: usize, col: usize) -> InternalDebugLocation {
102 pub fn set_debug_location(cx: &CrateContext,
103 builder: Option<llvm::BuilderRef>,
104 debug_location: InternalDebugLocation) {
105 if builder.is_none() {
106 if debug_location == debug_context(cx).current_debug_location.get() {
111 let metadata_node = match debug_location {
112 KnownLocation { scope, line, .. } => {
113 // Always set the column to zero like Clang and GCC
114 let col = UNKNOWN_COLUMN_NUMBER;
115 debug!("setting debug location to {} {}", line, col);
118 llvm::LLVMRustDIBuilderCreateDebugLocation(
119 debug_context(cx).llcontext,
127 debug!("clearing debug location ");
132 if builder.is_none() {
133 debug_context(cx).current_debug_location.set(debug_location);
136 let builder = builder.unwrap_or_else(|| cx.raw_builder());
138 llvm::LLVMSetCurrentDebugLocation(builder, metadata_node);