[Lldb-commits] [lldb] r353806 - [NativePDB] Process virtual bases in the correct order

Aleksandr Urakov via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 12 00:17:12 PST 2019


Author: aleksandr.urakov
Date: Tue Feb 12 00:17:11 2019
New Revision: 353806

URL: http://llvm.org/viewvc/llvm-project?rev=353806&view=rev
Log:
[NativePDB] Process virtual bases in the correct order

Summary:
This patch makes virtual bases to be added in the correct order to the bases
list. It is important because `VTableContext` (`MicrosoftVTableContext` in our
case) uses then the order of virtual bases in the list to restore the virtual
table indexes. These indexes are used then to resolve the layout of the virtual
bases.

We haven't enough information about offsets of virtual bases regarding to the
object (moreover, in a common case we can't rely on such information, see the
example here: https://reviews.llvm.org/D53506#1272306 ), but there should be
enough information to restore the layout of the virtual bases from the indexes
in runtime. After D53506 this information is used whenever possible, so there
should be no problems with virtual bases' fields reading.

Reviewers: zturner, rnk, stella.stamenova

Subscribers: abidh, teemperor, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D56904

Modified:
    lldb/trunk/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit
    lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h

Modified: lldb/trunk/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit?rev=353806&r1=353805&r2=353806&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit (original)
+++ lldb/trunk/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit Tue Feb 12 00:17:11 2019
@@ -3,6 +3,8 @@ type lookup -- Class
 type lookup -- Union
 type lookup -- Derived
 type lookup -- Derived2
+type lookup -- DerivedVirtual1
+type lookup -- DerivedVirtual2
 type lookup -- EnumInt
 type lookup -- EnumShort
 type lookup -- InvalidType

Modified: lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp?rev=353806&r1=353805&r2=353806&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp (original)
+++ lldb/trunk/lit/SymbolFile/NativePDB/tag-types.cpp Tue Feb 12 00:17:11 2019
@@ -2,7 +2,7 @@
 // REQUIRES: lld
 
 // Test that we can display tag types.
-// RUN: %build --compiler=clang-cl --nodefaultlib -o %t.exe -- %s 
+// RUN: %build --compiler=clang-cl --nodefaultlib -o %t.exe -- %s
 // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
 // RUN:     %p/Inputs/tag-types.lldbinit | FileCheck %s
 
@@ -115,6 +115,12 @@ public:
 
 unsigned Derived2::StaticDataMember = 0;
 
+// Test virtual inheritance.
+class DerivedVirtual1 : public virtual Class {};
+
+// Test the correctness of the virtual bases order.
+class DerivedVirtual2 : public DerivedVirtual1, public virtual OneMember {};
+
 // Test scoped enums and unscoped enums.
 enum class EnumInt {
   A = 1,
@@ -133,6 +139,8 @@ int main(int argc, char **argv) {
   Union U;
   Derived D;
   Derived2 D2;
+  DerivedVirtual1 DV1;
+  DerivedVirtual2 DV2;
   EnumInt EI;
   EnumShort ES;
   
@@ -221,6 +229,12 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: class Derived2 : protected Class, private Struct {
 // CHECK-NEXT:     static unsigned int StaticDataMember;
 // CHECK-NEXT: }
+// CHECK-NEXT: (lldb) type lookup -- DerivedVirtual1
+// CHECK-NEXT: class DerivedVirtual1 : virtual public Class {
+// CHECK-NEXT: }
+// CHECK-NEXT: (lldb) type lookup -- DerivedVirtual2
+// CHECK-NEXT: class DerivedVirtual2 : public DerivedVirtual1, virtual public Class, virtual public OneMember {
+// CHECK-NEXT: }
 // CHECK-NEXT: (lldb) type lookup -- EnumInt
 // CHECK-NEXT: enum EnumInt {
 // CHECK-NEXT:     A,

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp?rev=353806&r1=353805&r2=353806&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp Tue Feb 12 00:17:11 2019
@@ -50,7 +50,8 @@ UdtRecordCompleter::UdtRecordCompleter(P
 }
 
 clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex(
-    llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access) {
+    llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access,
+    llvm::Optional<uint64_t> vtable_idx) {
   PdbTypeSymId type_id(ti);
   clang::QualType qt = m_ast_builder.GetOrCreateType(type_id);
 
@@ -58,10 +59,13 @@ clang::QualType UdtRecordCompleter::AddB
 
   std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
       m_ast_builder.clang().CreateBaseClassSpecifier(
-          qt.getAsOpaquePtr(), TranslateMemberAccess(access), false,
-          udt_cvt.kind() == LF_CLASS);
+          qt.getAsOpaquePtr(), TranslateMemberAccess(access),
+          vtable_idx.hasValue(), udt_cvt.kind() == LF_CLASS);
   lldbassert(base_spec);
-  m_bases.push_back(std::move(base_spec));
+
+  m_bases.push_back(
+      std::make_pair(vtable_idx.getValueOr(0), std::move(base_spec)));
+
   return qt;
 }
 
@@ -98,9 +102,8 @@ Error UdtRecordCompleter::visitKnownMemb
 
 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
                                            VirtualBaseClassRecord &base) {
-  AddBaseClassForTypeIndex(base.BaseType, base.getAccess());
+  AddBaseClassForTypeIndex(base.BaseType, base.getAccess(), base.VTableIndex);
 
-  // FIXME: Handle virtual base offsets.
   return Error::success();
 }
 
@@ -209,9 +212,19 @@ Error UdtRecordCompleter::visitKnownMemb
 }
 
 void UdtRecordCompleter::complete() {
+  // Ensure the correct order for virtual bases.
+  std::stable_sort(m_bases.begin(), m_bases.end(),
+                   [](const IndexedBase &lhs, const IndexedBase &rhs) {
+                     return lhs.first < rhs.first;
+                   });
+
+  std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
+  bases.reserve(m_bases.size());
+  for (auto &ib : m_bases)
+    bases.push_back(std::move(ib.second));
+
   ClangASTContext &clang = m_ast_builder.clang();
-  clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(),
-                            std::move(m_bases));
+  clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), std::move(bases));
 
   clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType());
   ClangASTContext::BuildIndirectFields(m_derived_ct);

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h?rev=353806&r1=353805&r2=353806&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h Tue Feb 12 00:17:11 2019
@@ -35,6 +35,9 @@ namespace npdb {
 class PdbAstBuilder;
 
 class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
+  using IndexedBase =
+      std::pair<uint64_t, std::unique_ptr<clang::CXXBaseSpecifier>>;
+
   union UdtTagRecord {
     UdtTagRecord() {}
     llvm::codeview::UnionRecord ur;
@@ -47,7 +50,7 @@ class UdtRecordCompleter : public llvm::
   clang::TagDecl &m_tag_decl;
   PdbAstBuilder &m_ast_builder;
   llvm::pdb::TpiStream &m_tpi;
-  std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> m_bases;
+  std::vector<IndexedBase> m_bases;
   ClangASTImporter::LayoutInfo m_layout;
 
 public:
@@ -64,8 +67,9 @@ public:
   void complete();
 
 private:
-  clang::QualType AddBaseClassForTypeIndex(llvm::codeview::TypeIndex ti,
-                                           llvm::codeview::MemberAccess access);
+  clang::QualType AddBaseClassForTypeIndex(
+      llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access,
+      llvm::Optional<uint64_t> vtable_idx = llvm::Optional<uint64_t>());
   void AddMethod(llvm::StringRef name, llvm::codeview::TypeIndex type_idx,
                  llvm::codeview::MemberAccess access,
                  llvm::codeview::MethodOptions options,




More information about the lldb-commits mailing list