Auto merge of #89597 - michaelwoerister:improve-vtable-debuginfo, r=wesleywiser

Create more accurate debuginfo for vtables.

Before this PR all vtables would have the same name (`"vtable"`) in debuginfo. Now they get an unambiguous name that identifies the implementing type and the trait that is being implemented.

This is only one of several possible improvements:
- This PR describes vtables as arrays of `*const u8` pointers. It would nice to describe them as structs where function pointer is represented by a field with a name indicative of the method it maps to. However, this requires coming up with a naming scheme that avoids clashes between methods with the same name (which is possible if the vtable contains multiple traits).
- The PR does not update the debuginfo we generate for the vtable-pointer field in a fat `dyn` pointer. Right now there does not seem to be an easy way of getting ahold of a vtable-layout without also knowing the concrete self-type of a trait object.

r? `@wesleywiser`
This commit is contained in:
bors 2021-10-11 04:31:47 +00:00
commit 9a757817c3
8 changed files with 163 additions and 62 deletions

View file

@ -0,0 +1,47 @@
// compile-flags: -Cdebuginfo=2 -Copt-level=0 -Ccodegen-units=1
// ignore-tidy-linelength
// This test checks the debuginfo for the expected 3 vtables is generated for correct names and number
// of entries.
// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTrait>::{vtable}"
// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTrait>::vtable$"
// NONMSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()",
// MSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptr_const$<tuple$<> >",
// CHECK: !DISubrange(count: 5
// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTraitWithGenerics<u64, i8>>::{vtable}"
// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTraitWithGenerics<u64,i8> >::vtable$"
// CHECK: !DISubrange(count: 4
// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as _>::{vtable}"
// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, _>::vtable$"
// CHECK: !DISubrange(count: 3
#![crate_type = "lib"]
pub struct Foo;
pub trait SomeTrait {
fn method1(&self) -> u32;
fn method2(&self) -> u32;
}
impl SomeTrait for Foo {
fn method1(&self) -> u32 { 1 }
fn method2(&self) -> u32 { 2 }
}
pub trait SomeTraitWithGenerics<T, U> {
fn method1(&self) -> (T, U);
}
impl SomeTraitWithGenerics<u64, i8> for Foo {
fn method1(&self) -> (u64, i8) { (1, 2) }
}
pub fn foo(x: &Foo) -> (u32, (u64, i8), &dyn Send) {
let y: &dyn SomeTrait = x;
let z: &dyn SomeTraitWithGenerics<u64, i8> = x;
(y.method1(), z.method1(), x as &dyn Send)
}

View file

@ -1,21 +0,0 @@
// This test depends on a patch that was committed to upstream LLVM
// after 5.0, then backported to the Rust LLVM fork.
// ignore-windows
// ignore-macos
// compile-flags: -g -C no-prepopulate-passes
// CHECK-LABEL: @main
// CHECK: {{.*}}DICompositeType{{.*}}name: "vtable",{{.*}}vtableHolder:{{.*}}
pub trait T {
}
impl T for f64 {
}
pub fn main() {
let d = 23.0f64;
let td = &d as &T;
}