From a75f8f56bcc841149f662cf50e95d3fdd505a39f Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 16 Jun 2016 20:08:51 +0000 Subject: [PATCH] [DebugInfo] Put the vftable index in the debug info This won't always be enough info to call a virtual method from the debugger, but it's a start. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@272944 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 25 +++++++++++++++++-------- test/CodeGenCXX/debug-info-ms-abi.cpp | 8 +++++++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 36d2240672..85dae5847b 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1185,14 +1185,23 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( else Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual; - // It doesn't make sense to give a virtual destructor a vtable index, - // since a single destructor has two entries in the vtable. - // FIXME: Add proper support for debug info for virtual calls in - // the Microsoft ABI, where we may use multiple vptrs to make a vftable - // lookup if we have multiple or virtual inheritance. - if (!isa(Method) && - !CGM.getTarget().getCXXABI().isMicrosoft()) - VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method); + if (CGM.getTarget().getCXXABI().isItaniumFamily()) { + // It doesn't make sense to give a virtual destructor a vtable index, + // since a single destructor has two entries in the vtable. + if (!isa(Method)) + VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method); + } else { + // Emit MS ABI vftable information. There is only one entry for the + // deleting dtor. + const auto *DD = dyn_cast(Method); + GlobalDecl GD = DD ? GlobalDecl(DD, Dtor_Deleting) : GlobalDecl(Method); + MicrosoftVTableContext::MethodVFTableLocation ML = + CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); + VIndex = ML.Index; + // FIXME: Pass down ML.VFPtrOffset and ML.VBTableIndex. The debugger needs + // these to synthesize a call to a virtual method in a complex inheritance + // hierarchy. + } ContainingType = RecordTy; } diff --git a/test/CodeGenCXX/debug-info-ms-abi.cpp b/test/CodeGenCXX/debug-info-ms-abi.cpp index 78979952b4..1664da38a8 100644 --- a/test/CodeGenCXX/debug-info-ms-abi.cpp +++ b/test/CodeGenCXX/debug-info-ms-abi.cpp @@ -3,11 +3,17 @@ // Tests that certain miscellaneous features work in the MS ABI. struct Foo { + virtual void f(); + virtual void g(); + virtual void h(); struct Nested {}; }; Foo f; Foo::Nested n; -// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", +// CHECK: ![[Foo:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", // CHECK-SAME: identifier: ".?AUFoo@@" +// CHECK: !DISubprogram(name: "f", {{.*}} containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, {{.*}}) +// CHECK: !DISubprogram(name: "g", {{.*}} containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 1, {{.*}}) +// CHECK: !DISubprogram(name: "h", {{.*}} containingType: ![[Foo]], virtuality: DW_VIRTUALITY_virtual, virtualIndex: 2, {{.*}}) // CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Nested", // CHECK-SAME: identifier: ".?AUNested@Foo@@" -- 2.40.0