Use byte offsets when emitting debuginfo columns
This commit is contained in:
parent
e1a5472508
commit
0c51f2f5a5
6 changed files with 68 additions and 48 deletions
|
@ -1,5 +1,5 @@
|
||||||
use super::metadata::file_metadata;
|
use super::metadata::{file_metadata, UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
|
||||||
use super::utils::{span_start, DIB};
|
use super::utils::DIB;
|
||||||
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
|
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
|
||||||
|
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
|
@ -7,10 +7,6 @@ use crate::llvm;
|
||||||
use crate::llvm::debuginfo::{DIScope, DISubprogram};
|
use crate::llvm::debuginfo::{DIScope, DISubprogram};
|
||||||
use rustc::mir::{Body, SourceScope};
|
use rustc::mir::{Body, SourceScope};
|
||||||
|
|
||||||
use libc::c_uint;
|
|
||||||
|
|
||||||
use rustc_span::Pos;
|
|
||||||
|
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
|
|
||||||
|
@ -54,7 +50,7 @@ fn make_mir_scope(
|
||||||
debug_context.scopes[parent]
|
debug_context.scopes[parent]
|
||||||
} else {
|
} else {
|
||||||
// The root is the function itself.
|
// The root is the function itself.
|
||||||
let loc = span_start(cx, mir.span);
|
let loc = cx.lookup_debug_loc(mir.span.lo());
|
||||||
debug_context.scopes[scope] = DebugScope {
|
debug_context.scopes[scope] = DebugScope {
|
||||||
scope_metadata: Some(fn_metadata),
|
scope_metadata: Some(fn_metadata),
|
||||||
file_start_pos: loc.file.start_pos,
|
file_start_pos: loc.file.start_pos,
|
||||||
|
@ -70,7 +66,7 @@ fn make_mir_scope(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let loc = span_start(cx, scope_data.span);
|
let loc = cx.lookup_debug_loc(scope_data.span.lo());
|
||||||
let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate);
|
let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate);
|
||||||
|
|
||||||
let scope_metadata = unsafe {
|
let scope_metadata = unsafe {
|
||||||
|
@ -78,9 +74,8 @@ fn make_mir_scope(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
parent_scope.scope_metadata.unwrap(),
|
parent_scope.scope_metadata.unwrap(),
|
||||||
file_metadata,
|
file_metadata,
|
||||||
loc.line as c_uint,
|
loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
|
||||||
// Loc column is 0-based while debug one is 1-based.
|
loc.col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
|
||||||
loc.col.to_usize() as c_uint + 1,
|
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
debug_context.scopes[scope] = DebugScope {
|
debug_context.scopes[scope] = DebugScope {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use self::RecursiveTypeDescription::*;
|
||||||
use super::namespace::mangled_name_of_instance;
|
use super::namespace::mangled_name_of_instance;
|
||||||
use super::type_names::compute_debuginfo_type_name;
|
use super::type_names::compute_debuginfo_type_name;
|
||||||
use super::utils::{
|
use super::utils::{
|
||||||
create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, span_start, DIB,
|
create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, DIB,
|
||||||
};
|
};
|
||||||
use super::CrateDebugContext;
|
use super::CrateDebugContext;
|
||||||
|
|
||||||
|
@ -2280,10 +2280,10 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
|
||||||
let span = tcx.def_span(def_id);
|
let span = tcx.def_span(def_id);
|
||||||
|
|
||||||
let (file_metadata, line_number) = if !span.is_dummy() {
|
let (file_metadata, line_number) = if !span.is_dummy() {
|
||||||
let loc = span_start(cx, span);
|
let loc = cx.lookup_debug_loc(span.lo());
|
||||||
(file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint)
|
(file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line)
|
||||||
} else {
|
} else {
|
||||||
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
|
(unknown_file_metadata(cx), None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
|
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
|
||||||
|
@ -2308,7 +2308,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
|
||||||
// which is what we want for no_mangle statics
|
// which is what we want for no_mangle statics
|
||||||
linkage_name.as_ref().map_or(ptr::null(), |name| name.as_ptr()),
|
linkage_name.as_ref().map_or(ptr::null(), |name| name.as_ptr()),
|
||||||
file_metadata,
|
file_metadata,
|
||||||
line_number,
|
line_number.unwrap_or(UNKNOWN_LINE_NUMBER),
|
||||||
type_metadata,
|
type_metadata,
|
||||||
is_local_to_unit,
|
is_local_to_unit,
|
||||||
global,
|
global,
|
||||||
|
|
|
@ -3,10 +3,10 @@ mod doc;
|
||||||
|
|
||||||
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
||||||
|
|
||||||
use self::metadata::{file_metadata, type_metadata, TypeMap};
|
use self::metadata::{file_metadata, type_metadata, TypeMap, UNKNOWN_LINE_NUMBER};
|
||||||
use self::namespace::mangled_name_of_instance;
|
use self::namespace::mangled_name_of_instance;
|
||||||
use self::type_names::compute_debuginfo_type_name;
|
use self::type_names::compute_debuginfo_type_name;
|
||||||
use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB};
|
use self::utils::{create_DIArray, is_node_local_to_unit, DIB};
|
||||||
|
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
use crate::llvm::debuginfo::{
|
use crate::llvm::debuginfo::{
|
||||||
|
@ -257,7 +257,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
|
|
||||||
let def_id = instance.def_id();
|
let def_id = instance.def_id();
|
||||||
let containing_scope = get_containing_scope(self, instance);
|
let containing_scope = get_containing_scope(self, instance);
|
||||||
let loc = span_start(self, span);
|
let loc = self.lookup_debug_loc(span.lo());
|
||||||
let file_metadata = file_metadata(self, &loc.file.name, def_id.krate);
|
let file_metadata = file_metadata(self, &loc.file.name, def_id.krate);
|
||||||
|
|
||||||
let function_type_metadata = unsafe {
|
let function_type_metadata = unsafe {
|
||||||
|
@ -313,9 +313,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
function_name.as_ptr(),
|
function_name.as_ptr(),
|
||||||
linkage_name.as_ptr(),
|
linkage_name.as_ptr(),
|
||||||
file_metadata,
|
file_metadata,
|
||||||
loc.line as c_uint,
|
loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
|
||||||
function_type_metadata,
|
function_type_metadata,
|
||||||
scope_line as c_uint,
|
scope_line.unwrap_or(UNKNOWN_LINE_NUMBER),
|
||||||
flags,
|
flags,
|
||||||
spflags,
|
spflags,
|
||||||
llfn,
|
llfn,
|
||||||
|
@ -538,7 +538,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
variable_kind: VariableKind,
|
variable_kind: VariableKind,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> &'ll DIVariable {
|
) -> &'ll DIVariable {
|
||||||
let loc = span_start(self, span);
|
let loc = self.lookup_debug_loc(span.lo());
|
||||||
let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate);
|
let file_metadata = file_metadata(self, &loc.file.name, dbg_context.defining_crate);
|
||||||
|
|
||||||
let type_metadata = type_metadata(self, variable_type, span);
|
let type_metadata = type_metadata(self, variable_type, span);
|
||||||
|
@ -557,7 +557,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
scope_metadata,
|
scope_metadata,
|
||||||
name.as_ptr(),
|
name.as_ptr(),
|
||||||
file_metadata,
|
file_metadata,
|
||||||
loc.line as c_uint,
|
loc.line.unwrap_or(UNKNOWN_LINE_NUMBER),
|
||||||
type_metadata,
|
type_metadata,
|
||||||
true,
|
true,
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
|
|
|
@ -1,33 +1,58 @@
|
||||||
use super::metadata::UNKNOWN_COLUMN_NUMBER;
|
use super::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
|
||||||
use super::utils::{debug_context, span_start};
|
use super::utils::debug_context;
|
||||||
|
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
use crate::llvm::debuginfo::DIScope;
|
use crate::llvm::debuginfo::DIScope;
|
||||||
use crate::llvm::{self, Value};
|
use crate::llvm::{self, Value};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
|
|
||||||
use libc::c_uint;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_span::{Pos, Span};
|
use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span};
|
||||||
|
|
||||||
|
/// A source code location used to generate debug information.
|
||||||
|
pub struct DebugLoc {
|
||||||
|
/// Information about the original source file.
|
||||||
|
pub file: Lrc<SourceFile>,
|
||||||
|
/// The (1-based) line number.
|
||||||
|
pub line: Option<u32>,
|
||||||
|
/// The (1-based) column number.
|
||||||
|
pub col: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
impl CodegenCx<'ll, '_> {
|
impl CodegenCx<'ll, '_> {
|
||||||
pub fn create_debug_loc(&self, scope: &'ll DIScope, span: Span) -> &'ll Value {
|
/// Looks up debug source information about a `BytePos`.
|
||||||
let loc = span_start(self, span);
|
pub fn lookup_debug_loc(&self, pos: BytePos) -> DebugLoc {
|
||||||
|
let (file, line, col) = match self.sess().source_map().lookup_line(pos) {
|
||||||
|
Ok(SourceFileAndLine { sf: file, line }) => {
|
||||||
|
let line_pos = file.line_begin_pos(pos);
|
||||||
|
|
||||||
// For MSVC, set the column number to zero.
|
// Use 1-based indexing.
|
||||||
|
let line = (line + 1) as u32;
|
||||||
|
let col = (pos - line_pos).to_u32() + 1;
|
||||||
|
|
||||||
|
(file, Some(line), Some(col))
|
||||||
|
}
|
||||||
|
Err(file) => (file, None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
// For MSVC, omit the column number.
|
||||||
// Otherwise, emit it. This mimics clang behaviour.
|
// Otherwise, emit it. This mimics clang behaviour.
|
||||||
// See discussion in https://github.com/rust-lang/rust/issues/42921
|
// See discussion in https://github.com/rust-lang/rust/issues/42921
|
||||||
let col_used = if self.sess().target.target.options.is_like_msvc {
|
if self.sess().target.target.options.is_like_msvc {
|
||||||
UNKNOWN_COLUMN_NUMBER
|
DebugLoc { file, line, col: None }
|
||||||
} else {
|
} else {
|
||||||
// Loc column is 0-based while debug one is 1-based.
|
DebugLoc { file, line, col }
|
||||||
loc.col.to_usize() as c_uint + 1
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
pub fn create_debug_loc(&self, scope: &'ll DIScope, span: Span) -> &'ll Value {
|
||||||
|
let DebugLoc { line, col, .. } = self.lookup_debug_loc(span.lo());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateDebugLocation(
|
llvm::LLVMRustDIBuilderCreateDebugLocation(
|
||||||
debug_context(self).llcontext,
|
debug_context(self).llcontext,
|
||||||
loc.line as c_uint,
|
line.unwrap_or(UNKNOWN_LINE_NUMBER),
|
||||||
col_used,
|
col.unwrap_or(UNKNOWN_COLUMN_NUMBER),
|
||||||
scope,
|
scope,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,9 +9,6 @@ use rustc_hir::def_id::DefId;
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
use crate::llvm::debuginfo::{DIArray, DIBuilder, DIDescriptor, DIScope};
|
use crate::llvm::debuginfo::{DIArray, DIBuilder, DIDescriptor, DIScope};
|
||||||
use rustc_codegen_ssa::traits::*;
|
|
||||||
|
|
||||||
use rustc_span::Span;
|
|
||||||
|
|
||||||
pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool {
|
pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool {
|
||||||
// The is_local_to_unit flag indicates whether a function is local to the
|
// 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>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns rustc_span::Loc corresponding to the beginning of the span
|
|
||||||
pub fn span_start(cx: &CodegenCx<'_, '_>, span: Span) -> rustc_span::Loc {
|
|
||||||
cx.sess().source_map().lookup_char_pos(span.lo())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'ll, 'tcx> {
|
pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'ll, 'tcx> {
|
||||||
cx.dbg_cx.as_ref().unwrap()
|
cx.dbg_cx.as_ref().unwrap()
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
// Verify that emitted debuginfo column nubmers are 1-based. Regression test for issue #65437.
|
// Verify that debuginfo column nubmers are 1-based byte offsets.
|
||||||
//
|
//
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// compile-flags: -C debuginfo=2
|
// compile-flags: -C debuginfo=2
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
// CHECK: call void @giraffe(), !dbg [[DBG:!.*]]
|
// Column numbers are 1-based. Regression test for #65437.
|
||||||
// CHECK: [[DBG]] = !DILocation(line: 10, column: 9
|
// CHECK: call void @giraffe(), !dbg [[A:!.*]]
|
||||||
giraffe();
|
giraffe();
|
||||||
|
|
||||||
|
// Column numbers use byte offests. Regression test for #67360
|
||||||
|
// CHECK: call void @turtle(), !dbg [[B:!.*]]
|
||||||
|
/* ż */ turtle();
|
||||||
|
|
||||||
|
// CHECK: [[A]] = !DILocation(line: 10, column: 9,
|
||||||
|
// CHECK: [[B]] = !DILocation(line: 14, column: 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn giraffe();
|
fn giraffe();
|
||||||
|
fn turtle();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue