]>
Commit | Line | Data |
---|---|---|
d9579d0f AL |
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. | |
4 | // | |
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. | |
10 | ||
11 | use self::InternalDebugLocation::*; | |
12 | ||
a7813a04 | 13 | use super::utils::{debug_context, span_start}; |
32a655c1 SL |
14 | use super::metadata::UNKNOWN_COLUMN_NUMBER; |
15 | use super::FunctionDebugContext; | |
d9579d0f AL |
16 | |
17 | use llvm; | |
18 | use llvm::debuginfo::DIScope; | |
a7813a04 | 19 | use builder::Builder; |
d9579d0f AL |
20 | |
21 | use libc::c_uint; | |
32a655c1 | 22 | use syntax_pos::{Span, Pos}; |
d9579d0f AL |
23 | |
24 | /// Sets the current debug location at the beginning of the span. | |
25 | /// | |
a7813a04 | 26 | /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). |
32a655c1 | 27 | pub fn set_source_location( |
b7449926 XL |
28 | debug_context: &FunctionDebugContext<'ll>, |
29 | bx: &Builder<'_, 'll, '_>, | |
30 | scope: Option<&'ll DIScope>, | |
31 | span: Span, | |
32a655c1 SL |
32 | ) { |
33 | let function_debug_context = match *debug_context { | |
d9579d0f AL |
34 | FunctionDebugContext::DebugInfoDisabled => return, |
35 | FunctionDebugContext::FunctionWithoutDebugInfo => { | |
2c00a5a8 | 36 | set_debug_location(bx, UnknownLocation); |
d9579d0f AL |
37 | return; |
38 | } | |
32a655c1 | 39 | FunctionDebugContext::RegularContext(ref data) => data |
a7813a04 | 40 | }; |
d9579d0f | 41 | |
a7813a04 | 42 | let dbg_loc = if function_debug_context.source_locations_enabled.get() { |
b7449926 | 43 | debug!("set_source_location: {}", bx.sess().source_map().span_to_string(span)); |
2c00a5a8 | 44 | let loc = span_start(bx.cx, span); |
b7449926 | 45 | InternalDebugLocation::new(scope.unwrap(), loc.line, loc.col.to_usize()) |
a7813a04 XL |
46 | } else { |
47 | UnknownLocation | |
48 | }; | |
2c00a5a8 | 49 | set_debug_location(bx, dbg_loc); |
d9579d0f AL |
50 | } |
51 | ||
d9579d0f AL |
52 | /// Enables emitting source locations for the given functions. |
53 | /// | |
54 | /// Since we don't want source locations to be emitted for the function prelude, | |
94b46f34 | 55 | /// they are disabled when beginning to codegen a new function. This functions |
d9579d0f | 56 | /// switches source location emitting on and must therefore be called before the |
94b46f34 | 57 | /// first real statement/expression of the function is codegened. |
b7449926 | 58 | pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext<'ll>) { |
0bf4aa26 XL |
59 | if let FunctionDebugContext::RegularContext(ref data) = *dbg_context { |
60 | data.source_locations_enabled.set(true); | |
d9579d0f AL |
61 | } |
62 | } | |
63 | ||
64 | ||
65 | #[derive(Copy, Clone, PartialEq)] | |
b7449926 XL |
66 | pub enum InternalDebugLocation<'ll> { |
67 | KnownLocation { scope: &'ll DIScope, line: usize, col: usize }, | |
d9579d0f AL |
68 | UnknownLocation |
69 | } | |
70 | ||
b7449926 XL |
71 | impl InternalDebugLocation<'ll> { |
72 | pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self { | |
d9579d0f | 73 | KnownLocation { |
3b2f2976 XL |
74 | scope, |
75 | line, | |
76 | col, | |
d9579d0f AL |
77 | } |
78 | } | |
79 | } | |
80 | ||
b7449926 | 81 | pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDebugLocation<'ll>) { |
a7813a04 | 82 | let metadata_node = match debug_location { |
8faf50e0 XL |
83 | KnownLocation { scope, line, col } => { |
84 | // For MSVC, set the column number to zero. | |
85 | // Otherwise, emit it. This mimics clang behaviour. | |
86 | // See discussion in https://github.com/rust-lang/rust/issues/42921 | |
87 | let col_used = if bx.cx.sess().target.target.options.is_like_msvc { | |
88 | UNKNOWN_COLUMN_NUMBER | |
89 | } else { | |
90 | col as c_uint | |
91 | }; | |
d9579d0f AL |
92 | debug!("setting debug location to {} {}", line, col); |
93 | ||
94 | unsafe { | |
b7449926 | 95 | Some(llvm::LLVMRustDIBuilderCreateDebugLocation( |
2c00a5a8 | 96 | debug_context(bx.cx).llcontext, |
d9579d0f | 97 | line as c_uint, |
8faf50e0 | 98 | col_used, |
d9579d0f | 99 | scope, |
b7449926 | 100 | None)) |
d9579d0f AL |
101 | } |
102 | } | |
103 | UnknownLocation => { | |
104 | debug!("clearing debug location "); | |
b7449926 | 105 | None |
d9579d0f AL |
106 | } |
107 | }; | |
108 | ||
a7813a04 | 109 | unsafe { |
2c00a5a8 | 110 | llvm::LLVMSetCurrentDebugLocation(bx.llbuilder, metadata_node); |
a7813a04 | 111 | } |
d9579d0f | 112 | } |