Skip to content

Commit 62c0579

Browse files
authored
Rollup merge of #69357 - tmiasko:debuginfo-column, r=michaelwoerister
Emit 1-based column numbers in debuginfo * Use byte offsets instead of char position offsets. Resolves #67360. * Use 1-based offsets instead of 0-based ones. Resolves #65437. * Consistently omit column information for msvc targets, matching clang behaviour (previously columns have been omitted from `DILocation`, but not from `DILexicalBlock`).
2 parents 7cdbc87 + 8e93a01 commit 62c0579

File tree

7 files changed

+97
-43
lines changed

7 files changed

+97
-43
lines changed

Diff for: src/librustc_codegen_llvm/debuginfo/create_scope_map.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
use super::metadata::file_metadata;
2-
use super::utils::{span_start, DIB};
1+
use super::metadata::{file_metadata, UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
2+
use super::utils::DIB;
33
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
44

55
use crate::common::CodegenCx;
66
use crate::llvm;
77
use crate::llvm::debuginfo::{DIScope, DISubprogram};
88
use rustc::mir::{Body, SourceScope};
99

10-
use libc::c_uint;
11-
12-
use rustc_span::Pos;
13-
1410
use rustc_index::bit_set::BitSet;
1511
use rustc_index::vec::Idx;
1612

@@ -54,7 +50,7 @@ fn make_mir_scope(
5450
debug_context.scopes[parent]
5551
} else {
5652
// The root is the function itself.
57-
let loc = span_start(cx, mir.span);
53+
let loc = cx.lookup_debug_loc(mir.span.lo());
5854
debug_context.scopes[scope] = DebugScope {
5955
scope_metadata: Some(fn_metadata),
6056
file_start_pos: loc.file.start_pos,
@@ -70,16 +66,16 @@ fn make_mir_scope(
7066
return;
7167
}
7268

73-
let loc = span_start(cx, scope_data.span);
69+
let loc = cx.lookup_debug_loc(scope_data.span.lo());
7470
let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate);
7571

7672
let scope_metadata = unsafe {
7773
Some(llvm::LLVMRustDIBuilderCreateLexicalBlock(
7874
DIB(cx),
7975
parent_scope.scope_metadata.unwrap(),
8076
file_metadata,
81-
loc.line as c_uint,
82-
loc.col.to_usize() as c_uint,
77+
loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
78+
loc.col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
8379
))
8480
};
8581
debug_context.scopes[scope] = DebugScope {

Diff for: src/librustc_codegen_llvm/debuginfo/metadata.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use self::RecursiveTypeDescription::*;
55
use super::namespace::mangled_name_of_instance;
66
use super::type_names::compute_debuginfo_type_name;
77
use super::utils::{
8-
create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, span_start, DIB,
8+
create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, DIB,
99
};
1010
use super::CrateDebugContext;
1111

@@ -2309,10 +2309,10 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
23092309
let span = tcx.def_span(def_id);
23102310

23112311
let (file_metadata, line_number) = if !span.is_dummy() {
2312-
let loc = span_start(cx, span);
2313-
(file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint)
2312+
let loc = cx.lookup_debug_loc(span.lo());
2313+
(file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line)
23142314
} else {
2315-
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
2315+
(unknown_file_metadata(cx), None)
23162316
};
23172317

23182318
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
@@ -2339,7 +2339,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
23392339
linkage_name.as_ptr().cast(),
23402340
linkage_name.len(),
23412341
file_metadata,
2342-
line_number,
2342+
line_number.unwrap_or(UNKNOWN_LINE_NUMBER),
23432343
type_metadata,
23442344
is_local_to_unit,
23452345
global,

Diff for: src/librustc_codegen_llvm/debuginfo/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ mod doc;
33

44
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
55

6-
use self::metadata::{file_metadata, type_metadata, TypeMap};
6+
use self::metadata::{file_metadata, type_metadata, TypeMap, UNKNOWN_LINE_NUMBER};
77
use self::namespace::mangled_name_of_instance;
88
use self::type_names::compute_debuginfo_type_name;
9-
use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB};
9+
use self::utils::{create_DIArray, is_node_local_to_unit, DIB};
1010

1111
use crate::llvm;
1212
use crate::llvm::debuginfo::{
@@ -248,7 +248,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
248248

249249
let def_id = instance.def_id();
250250
let containing_scope = get_containing_scope(self, instance);
251-
let loc = span_start(self, span);
251+
let loc = self.lookup_debug_loc(span.lo());
252252
let file_metadata = file_metadata(self, &loc.file.name, def_id.krate);
253253

254254
let function_type_metadata = unsafe {
@@ -304,9 +304,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
304304
linkage_name.as_ptr().cast(),
305305
linkage_name.len(),
306306
file_metadata,
307-
loc.line as c_uint,
307+
loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
308308
function_type_metadata,
309-
scope_line as c_uint,
309+
scope_line.unwrap_or(UNKNOWN_LINE_NUMBER),
310310
flags,
311311
spflags,
312312
llfn,
@@ -530,7 +530,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
530530
variable_kind: VariableKind,
531531
span: Span,
532532
) -> &'ll DIVariable {
533-
let loc = span_start(self, span);
533+
let loc = self.lookup_debug_loc(span.lo());
534534
let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate);
535535

536536
let type_metadata = type_metadata(self, variable_type, span);
@@ -550,7 +550,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
550550
name.as_ptr().cast(),
551551
name.len(),
552552
file_metadata,
553-
loc.line as c_uint,
553+
loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
554554
type_metadata,
555555
true,
556556
DIFlags::FlagZero,

Diff for: src/librustc_codegen_llvm/debuginfo/source_loc.rs

+39-13
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,58 @@
1-
use super::metadata::UNKNOWN_COLUMN_NUMBER;
2-
use super::utils::{debug_context, span_start};
1+
use super::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
2+
use super::utils::debug_context;
33

44
use crate::common::CodegenCx;
55
use crate::llvm::debuginfo::DIScope;
66
use crate::llvm::{self, Value};
77
use rustc_codegen_ssa::traits::*;
88

9-
use libc::c_uint;
10-
use rustc_span::{Pos, Span};
9+
use rustc_data_structures::sync::Lrc;
10+
use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span};
11+
12+
/// A source code location used to generate debug information.
13+
pub struct DebugLoc {
14+
/// Information about the original source file.
15+
pub file: Lrc<SourceFile>,
16+
/// The (1-based) line number.
17+
pub line: Option<u32>,
18+
/// The (1-based) column number.
19+
pub col: Option<u32>,
20+
}
1121

1222
impl CodegenCx<'ll, '_> {
13-
pub fn create_debug_loc(&self, scope: &'ll DIScope, span: Span) -> &'ll Value {
14-
let loc = span_start(self, span);
23+
/// Looks up debug source information about a `BytePos`.
24+
pub fn lookup_debug_loc(&self, pos: BytePos) -> DebugLoc {
25+
let (file, line, col) = match self.sess().source_map().lookup_line(pos) {
26+
Ok(SourceFileAndLine { sf: file, line }) => {
27+
let line_pos = file.line_begin_pos(pos);
28+
29+
// Use 1-based indexing.
30+
let line = (line + 1) as u32;
31+
let col = (pos - line_pos).to_u32() + 1;
32+
33+
(file, Some(line), Some(col))
34+
}
35+
Err(file) => (file, None, None),
36+
};
1537

16-
// For MSVC, set the column number to zero.
38+
// For MSVC, omit the column number.
1739
// Otherwise, emit it. This mimics clang behaviour.
1840
// See discussion in https://github.com/rust-lang/rust/issues/42921
19-
let col_used = if self.sess().target.target.options.is_like_msvc {
20-
UNKNOWN_COLUMN_NUMBER
41+
if self.sess().target.target.options.is_like_msvc {
42+
DebugLoc { file, line, col: None }
2143
} else {
22-
loc.col.to_usize() as c_uint
23-
};
44+
DebugLoc { file, line, col }
45+
}
46+
}
47+
48+
pub fn create_debug_loc(&self, scope: &'ll DIScope, span: Span) -> &'ll Value {
49+
let DebugLoc { line, col, .. } = self.lookup_debug_loc(span.lo());
2450

2551
unsafe {
2652
llvm::LLVMRustDIBuilderCreateDebugLocation(
2753
debug_context(self).llcontext,
28-
loc.line as c_uint,
29-
col_used,
54+
line.unwrap_or(UNKNOWN_LINE_NUMBER),
55+
col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
3056
scope,
3157
None,
3258
)

Diff for: src/librustc_codegen_llvm/debuginfo/utils.rs

-8
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ use rustc_hir::def_id::DefId;
99
use crate::common::CodegenCx;
1010
use crate::llvm;
1111
use crate::llvm::debuginfo::{DIArray, DIBuilder, DIDescriptor, DIScope};
12-
use rustc_codegen_ssa::traits::*;
13-
14-
use rustc_span::Span;
1512

1613
pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool {
1714
// The is_local_to_unit flag indicates whether a function is local to the
@@ -32,11 +29,6 @@ pub fn create_DIArray(builder: &DIBuilder<'ll>, arr: &[Option<&'ll DIDescriptor>
3229
};
3330
}
3431

35-
/// Returns rustc_span::Loc corresponding to the beginning of the span
36-
pub fn span_start(cx: &CodegenCx<'_, '_>, span: Span) -> rustc_span::Loc {
37-
cx.sess().source_map().lookup_char_pos(span.lo())
38-
}
39-
4032
#[inline]
4133
pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'ll, 'tcx> {
4234
cx.dbg_cx.as_ref().unwrap()

Diff for: src/test/codegen/debug-column-msvc.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Verify that no column information is emitted for MSVC targets
2+
//
3+
// only-msvc
4+
// compile-flags: -C debuginfo=2
5+
6+
// CHECK-NOT: !DILexicalBlock({{.*}}column: {{.*}})
7+
// CHECK-NOT: !DILocation({{.*}}column: {{.*}})
8+
9+
pub fn add(a: u32, b: u32) -> u32 {
10+
a + b
11+
}
12+
13+
fn main() {
14+
let c = add(1, 2);
15+
println!("{}", c);
16+
}

Diff for: src/test/codegen/debug-column.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Verify that debuginfo column nubmers are 1-based byte offsets.
2+
//
3+
// ignore-windows
4+
// compile-flags: -C debuginfo=2
5+
6+
fn main() {
7+
unsafe {
8+
// Column numbers are 1-based. Regression test for #65437.
9+
// CHECK: call void @giraffe(), !dbg [[A:!.*]]
10+
giraffe();
11+
12+
// Column numbers use byte offests. Regression test for #67360
13+
// CHECK: call void @turtle(), !dbg [[B:!.*]]
14+
/* ż */ turtle();
15+
16+
// CHECK: [[A]] = !DILocation(line: 10, column: 9,
17+
// CHECK: [[B]] = !DILocation(line: 14, column: 10,
18+
}
19+
}
20+
21+
extern {
22+
fn giraffe();
23+
fn turtle();
24+
}

0 commit comments

Comments
 (0)