zequanwu updated this revision to Diff 445081.
zequanwu added a reviewer: rnk.
zequanwu added a comment.

add testscase.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129807/new/

https://reviews.llvm.org/D129807

Files:
  lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
  lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
  lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp

Index: lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
===================================================================
--- lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
+++ lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
@@ -4,7 +4,8 @@
 // Test various interesting cases for AST reconstruction.
 // RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -c /Fo%t.obj -- %s
 // RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb
-// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
+// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -o \
+// RUN:     "settings set interpreter.stop-command-source-on-error false" -s \
 // RUN:     %p/Inputs/ast-types.lldbinit 2>&1 | FileCheck %s
 
 // Test trivial versions of each tag type.
@@ -86,6 +87,28 @@
 Anonymous<A::B::C<void>> AnonABCVoid;
 Anonymous<A::B::C<void>>::D AnonABCVoidD;
 
+// The following tests that MSInheritanceAttr are set for record decls.
+class  SI { int si; };
+struct SI2 { int si2; };
+class  MI : SI, SI2 { int mi; };
+class VI : virtual MI { int vi; };
+class VI2 : virtual SI, virtual SI2 { int vi; };
+class/* __unspecified_inheritance*/ UI;
+
+typedef void (SI::*SITYPE)();
+typedef void (MI::*MITYPE)();
+typedef void (VI::*VITYPE)();
+typedef void (VI2::*VI2TYPE)();
+typedef void (UI::*UITYPE)();
+SITYPE mp1 = nullptr;
+MITYPE mp2 = nullptr;
+VITYPE mp3 = nullptr;
+VI2 vi2;
+VI2TYPE mp4 = nullptr;
+UITYPE mp5 = nullptr;
+MITYPE *mp6 = nullptr;
+VI2TYPE *mp7 = nullptr;
+
 // FIXME: Enum size isn't being correctly determined.
 // FIXME: Can't read memory for variable values.
 
@@ -106,6 +129,13 @@
 // CHECK: (Anonymous<int>) AnonInt = (AnonymousMember = 0)
 // CHECK: (Anonymous<A::B::C<void>>) AnonABCVoid = (AnonymousMember = 0)
 // CHECK: (Anonymous<A::B::C<void>>::D) AnonABCVoidD = (AnonymousDMember = 0)
+// CHECK: (void (SI::*)()) mp1 = 00 00 00 00 00 00 00 00
+// CHECK: (void (MI::*)()) mp2 = 00 00 00 00 00 00 00 00
+// CHECK: error: can't find global variable 'mp3'
+// CHECK: (void (VI2::*)()) mp4 = 00 00 00 00 00 00 00 00
+// CHECK: error: can't find global variable 'mp5'
+// CHECK: (void (MI::**)()) mp6 = 0x0000000000000000
+// CHECK: (void (VI2::**)()) mp7 = 0x0000000000000000
 // CHECK: Dumping clang ast for 1 modules.
 // CHECK: TranslationUnitDecl {{.*}}
 // CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition
Index: lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
===================================================================
--- lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
+++ lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
@@ -20,6 +20,14 @@
 target variable AnonABCVoid
 target variable AnonABCVoidD
 
+target variable mp1
+target variable mp2
+target variable mp3
+target variable mp4
+target variable mp5
+target variable mp6
+target variable mp7
+
 target modules dump ast
 
 quit
Index: lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -57,6 +57,7 @@
   llvm::DenseMap<lldb::opaque_compiler_type_t,
                  llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
       &m_cxx_record_map;
+  bool has_virtual_base = false;
 
 public:
   UdtRecordCompleter(
Index: lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -123,6 +123,7 @@
 
 Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
                                            VirtualBaseClassRecord &base) {
+  has_virtual_base = true;
   AddBaseClassForTypeIndex(base.BaseType, base.getAccess(), base.VTableIndex);
 
   return Error::success();
@@ -312,6 +313,17 @@
   TypeSystemClang::CompleteTagDeclarationDefinition(m_derived_ct);
 
   if (auto *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(&m_tag_decl)) {
+    clang::MSInheritanceAttr::Spelling spelling;
+    if (has_virtual_base)
+      spelling = clang::MSInheritanceAttr::Keyword_virtual_inheritance;
+    else if (bases.size() > 1)
+      spelling = clang::MSInheritanceAttr::Keyword_multiple_inheritance;
+    else
+      spelling = clang::MSInheritanceAttr::Keyword_single_inheritance;
+    clang::MSInheritanceAttr *inheritance_attr =
+        clang::MSInheritanceAttr::CreateImplicit(
+            m_ast_builder.clang().getASTContext(), spelling);
+    record_decl->addAttr(inheritance_attr);
     m_ast_builder.importer().SetRecordLayout(record_decl, m_layout);
   }
 }
Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -811,12 +811,27 @@
   if (!modi) {
     return nullptr;
   }
+  // Complete the tag type if it's a pointer to the tag member type.
+  // Incomplete tag records don't have MSInheritanceAttr set and that will cause
+  // crash at clang when trying to get the value of a variable whose type is a
+  // member pointer of this record.
+  PdbTypeSymId tid(ti, false);
+  if (llvm::Optional<PdbTypeSymId> record_tid =
+          GetReferringMemberPointerRecordType(tid, m_index->tpi())) {
+    CompilerType ct = GetOrCreateType(*record_tid)->GetFullCompilerType();
+    if (!ct.IsDefined()) {
+      // This means that it's trying to create global variable whose type is
+      // pointer to a member type. The member belongs to a class that doesn't
+      // have definition.
+      return nullptr;
+    }
+  }
+
 
   CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);
   comp_unit = GetOrCreateCompileUnit(cci);
 
   Declaration decl;
-  PdbTypeSymId tid(ti, false);
   SymbolFileTypeSP type_sp =
       std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
   Variable::RangeList ranges;
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
@@ -133,6 +133,9 @@
 
 bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
 bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
+llvm::Optional<PdbTypeSymId>
+GetReferringMemberPointerRecordType(const PdbTypeSymId &id,
+                                    llvm::pdb::TpiStream &tpi);
 
 lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
 llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -424,6 +424,31 @@
   return IsTagRecord(tpi.getType(id.index));
 }
 
+llvm::Optional<PdbTypeSymId>
+lldb_private::npdb::GetReferringMemberPointerRecordType(
+    const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi) {
+  if (id.is_ipi || id.index.isSimple())
+    return llvm::None;
+  llvm::codeview::CVType cvt = tpi.getType(id.index);
+  switch (cvt.kind()) {
+    case LF_MODIFIER: {
+      PdbTypeSymId modified_type(LookThroughModifierRecord(cvt));
+      return GetReferringMemberPointerRecordType(modified_type, tpi);
+    }
+    case LF_POINTER: {
+      PointerRecord pr;
+      llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr));
+      if (pr.isPointerToMember()) {
+        PdbTypeSymId record_tid(pr.getMemberInfo().ContainingType);
+        return record_tid;
+      }
+      return llvm::None;
+    }
+    default:
+      return llvm::None;
+  }
+}
+
 lldb::AccessType
 lldb_private::npdb::TranslateMemberAccess(MemberAccess access) {
   switch (access) {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to