Skip to content

[Debug Info] Generate typedef nodes for ptr/ref types (and msvc arrays) #144394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>(
unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) };

let subscripts = create_DIArray(DIB(cx), &[subrange]);
let di_node = unsafe {
let mut di_node = unsafe {
llvm::LLVMRustDIBuilderCreateArrayType(
DIB(cx),
size.bits(),
Expand All @@ -130,6 +130,21 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>(
)
};

if cpp_like_debuginfo(cx.tcx) {
let array_type_name = compute_debuginfo_type_name(cx.tcx, array_type, false);
di_node = unsafe {
llvm::LLVMRustDIBuilderCreateTypedef(
DIB(cx),
di_node,
array_type_name.as_c_char_ptr(),
array_type_name.len(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
None,
)
};
}

DINodeCreationResult::new(di_node, false)
}

Expand Down Expand Up @@ -183,8 +198,19 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
ptr_type_debuginfo_name.len(),
)
};
let typedefed_ptr = unsafe {
llvm::LLVMRustDIBuilderCreateTypedef(
DIB(cx),
di_node,
ptr_type_debuginfo_name.as_c_char_ptr(),
ptr_type_debuginfo_name.len(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
None,
)
};

DINodeCreationResult { di_node, already_stored_in_typemap: false }
DINodeCreationResult { di_node: typedefed_ptr, already_stored_in_typemap: false }
}
Some(wide_pointer_kind) => {
type_map::build_type_with_children(
Expand Down
13 changes: 9 additions & 4 deletions src/etc/gdb_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ def unwrap_unique_or_non_null(unique_or_nonnull):
# BACKCOMPAT: rust 1.60
# https://github.com/rust-lang/rust/commit/2a91eeac1a2d27dd3de1bf55515d765da20fd86f
ptr = unique_or_nonnull["pointer"]
if ptr.type.code == gdb.TYPE_CODE_TYPEDEF:
ptr = ptr.cast(ptr.type.strip_typedefs())

return ptr if ptr.type.code == gdb.TYPE_CODE_PTR else ptr[ptr.type.fields()[0]]


Expand Down Expand Up @@ -138,8 +141,9 @@ def __init__(self, valobj):
self._valobj = valobj
self._length = int(valobj["len"])
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)
self._data_ptr = self._data_ptr.cast(self._data_ptr.type.strip_typedefs())
ptr_ty = valobj.type.template_argument(0).pointer()
self._data_ptr = self._data_ptr.cast(ptr_ty)

def to_string(self):
return "Vec(size={})".format(self._length)
Expand All @@ -165,8 +169,9 @@ def __init__(self, valobj):
cap = cap[ZERO_FIELD]
self._cap = int(cap)
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)
self._data_ptr = self._data_ptr.cast(self._data_ptr.type.strip_typedefs())
ptr_ty = valobj.type.template_argument(0).pointer()
self._data_ptr = self._data_ptr.cast(ptr_ty)

def to_string(self):
return "VecDeque(size={})".format(self._size)
Expand Down
18 changes: 10 additions & 8 deletions tests/codegen-llvm/debug-vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,39 @@

// NONMSVC: ![[USIZE:[0-9]+]] = !DIBasicType(name: "usize"
// MSVC: ![[USIZE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "usize"
// NONMSVC: ![[PTR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()"
// MSVC: ![[PTR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptr_const$<tuple$<> >"
// NONMSVC: ![[PTR_TYPEDEF:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "*const ()", file: {{.*}}, baseType: ![[PTR:[0-9]+]])
// MSVC: ![[PTR_TYPEDEF:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "ptr_const$<tuple$<> >", file: {{.*}}, baseType: ![[PTR:[0-9]+]])
// NONMSVC: ![[PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()"
// MSVC: ![[PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptr_const$<tuple$<> >"

// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTrait>::{vtable}"
// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTrait>::vtable$"

// NONMSVC: ![[VTABLE_TY0:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "<debug_vtable::Foo as debug_vtable::SomeTrait>::{vtable_type}", {{.*}} size: {{320|160}}, align: {{64|32}}, flags: DIFlagArtificial, {{.*}} vtableHolder: ![[FOO_TYPE:[0-9]+]],
// MSVC: ![[VTABLE_TY0:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "impl$<debug_vtable::Foo, debug_vtable::SomeTrait>::vtable_type$", {{.*}} size: {{320|160}}, align: {{64|32}}, flags: DIFlagArtificial, {{.*}} vtableHolder: ![[FOO_TYPE:[0-9]+]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "drop_in_place", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[PTR]], size: {{64|32}}, align: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "drop_in_place", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[PTR_TYPEDEF]], size: {{64|32}}, align: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "size", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__method3", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[PTR]], size: {{64|32}}, align: {{64|32}}, offset: {{192|96}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__method4", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[PTR]], size: {{64|32}}, align: {{64|32}}, offset: {{256|128}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__method3", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[PTR_TYPEDEF]], size: {{64|32}}, align: {{64|32}}, offset: {{192|96}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__method4", scope: ![[VTABLE_TY0]], {{.*}} baseType: ![[PTR_TYPEDEF]], size: {{64|32}}, align: {{64|32}}, offset: {{256|128}})
// CHECK: ![[FOO_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo",

// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTraitWithGenerics<u64, i8>>::{vtable}"
// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTraitWithGenerics<u64,i8> >::vtable$"

// NONMSVC: ![[VTABLE_TY1:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "<debug_vtable::Foo as debug_vtable::SomeTraitWithGenerics<u64, i8>>::{vtable_type}", {{.*}}, size: {{256|128}}, align: {{64|32}}, flags: DIFlagArtificial, {{.*}}, vtableHolder: ![[FOO_TYPE]],
// MSVC: ![[VTABLE_TY1:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "impl$<debug_vtable::Foo, debug_vtable::SomeTraitWithGenerics<u64,i8> >::vtable_type$", {{.*}}, size: {{256|128}}, align: {{64|32}}, flags: DIFlagArtificial, {{.*}}, vtableHolder: ![[FOO_TYPE]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "drop_in_place", scope: ![[VTABLE_TY1]], {{.*}} baseType: ![[PTR]], size: {{64|32}}, align: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "drop_in_place", scope: ![[VTABLE_TY1]], {{.*}} baseType: ![[PTR_TYPEDEF]], size: {{64|32}}, align: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "size", scope: ![[VTABLE_TY1]], {{.*}} baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY1]], {{.*}} baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__method3", scope: ![[VTABLE_TY1]], {{.*}} baseType: ![[PTR]], size: {{64|32}}, align: {{64|32}}, offset: {{192|96}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__method3", scope: ![[VTABLE_TY1]], {{.*}} baseType: ![[PTR_TYPEDEF]], size: {{64|32}}, align: {{64|32}}, offset: {{192|96}})

// NONMSVC: !DIGlobalVariable(name: "<debug_vtable::Foo as _>::{vtable}"
// MSVC: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, _>::vtable$"

// NONMSVC: ![[VTABLE_TY2:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "<debug_vtable::Foo as _>::{vtable_type}", {{.*}}, size: {{192|96}}, align: {{64|32}}, flags: DIFlagArtificial, {{.*}}, vtableHolder: ![[FOO_TYPE]],
// MSVC: ![[VTABLE_TY2:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "impl$<debug_vtable::Foo, _>::vtable_type$", {{.*}}, size: {{192|96}}, align: {{64|32}}, flags: DIFlagArtificial, {{.*}}, vtableHolder: ![[FOO_TYPE]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "drop_in_place", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[PTR]], size: {{64|32}}, align: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "drop_in_place", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[PTR_TYPEDEF]], size: {{64|32}}, align: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "size", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{64|32}})
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "align", scope: ![[VTABLE_TY2]], {{.*}}, baseType: ![[USIZE]], size: {{64|32}}, align: {{64|32}}, offset: {{128|64}})

Expand Down
6 changes: 3 additions & 3 deletions tests/debuginfo/basic-types-metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@
// gdb-check: type = struct basic_types_metadata::main::{closure_env#0}
// gdb-command:ptype closure_1
// gdb-check: type = struct basic_types_metadata::main::{closure_env#1} {
// gdb-check: *mut bool,
// gdb-check: _ref__b: &bool,
// gdb-check: }
// gdb-command:ptype closure_2
// gdb-check: type = struct basic_types_metadata::main::{closure_env#2} {
// gdb-check: *mut bool,
// gdb-check: *mut isize,
// gdb-check: _ref__b: &bool,
// gdb-check: _ref__i: &isize,
// gdb-check: }

//
Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/function-call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// gdb-command:print fun(444, false)
// gdb-check:$2 = false

// gdb-command:print r.get_x()
// gdb-command: print function_call::RegularStruct::get_x(&r)
// gdb-check:$3 = 4

#![allow(dead_code, unused_variables)]
Expand Down
6 changes: 3 additions & 3 deletions tests/debuginfo/function-names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@

// Closure
// gdb-command:info functions -q function_names::.*::{closure.*
// gdb-check:[...]static fn function_names::generic_func::{closure#0}<i32>(*mut function_names::generic_func::{closure_env#0}<i32>);
// gdb-check:[...]static fn function_names::main::{closure#0}(*mut function_names::main::{closure_env#0});
// gdb-check:[...]static fn function_names::{impl#2}::impl_function::{closure#0}<i32, i32>(*mut function_names::{impl#2}::impl_function::{closure_env#0}<i32, i32>);
// gdb-check:[...]static fn function_names::generic_func::{closure#0}<i32>(&function_names::generic_func::{closure_env#0}<i32>);
// gdb-check:[...]static fn function_names::main::{closure#0}(&function_names::main::{closure_env#0});
// gdb-check:[...]static fn function_names::{impl#2}::impl_function::{closure#0}<i32, i32>(&function_names::{impl#2}::impl_function::{closure_env#0}<i32, i32>);

// Coroutine
// Coroutines don't seem to appear in GDB's symbol table.
Expand Down
4 changes: 2 additions & 2 deletions tests/debuginfo/type-names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@

// FOREIGN TYPES
// gdb-command:whatis foreign1
// gdb-check:type = *mut type_names::{extern#0}::ForeignType1
// gdb-check:type = *const type_names::{extern#0}::ForeignType1

// gdb-command:whatis foreign2
// gdb-check:type = *mut type_names::mod1::{extern#0}::ForeignType2
// gdb-check:type = *const type_names::mod1::{extern#0}::ForeignType2

// === CDB TESTS ==================================================================================

Expand Down
4 changes: 2 additions & 2 deletions tests/debuginfo/unit-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
// gdb-command: run

// gdb-command: print _ref
// gdb-check: $1 = (*mut ()) 0x[...]
// gdb-check: $1 = (&()) 0x[...]

// gdb-command: print _ptr
// gdb-check: $2 = (*mut ()) 0x[...]
// gdb-check: $2 = (*const ()) 0x[...]

// gdb-command: print _local
// gdb-check: $3 = ()
Expand Down
Loading