From b8cf916b89d4502569680b8b4cb284db5b7e8c4d Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Tue, 19 Jul 2022 12:58:56 -0700 Subject: [PATCH] [LLDB][NativePDB] Add MSInheritanceAttr when creating pointer type that is a pointer to member. Differential Revision: https://reviews.llvm.org/D129807 --- .../Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp | 34 ++++++++++++++++++++++ .../SymbolFile/NativePDB/Inputs/ast-types.lldbinit | 2 ++ lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp | 34 ++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 6dcce73..25425f9 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -816,6 +816,40 @@ clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) { clang::QualType class_type = GetOrCreateType(mpi.ContainingType); if (class_type.isNull()) return {}; + if (clang::TagDecl *tag = class_type->getAsTagDecl()) { + clang::MSInheritanceAttr::Spelling spelling; + switch (mpi.Representation) { + case llvm::codeview::PointerToMemberRepresentation::SingleInheritanceData: + case llvm::codeview::PointerToMemberRepresentation:: + SingleInheritanceFunction: + spelling = + clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance; + break; + case llvm::codeview::PointerToMemberRepresentation:: + MultipleInheritanceData: + case llvm::codeview::PointerToMemberRepresentation:: + MultipleInheritanceFunction: + spelling = + clang::MSInheritanceAttr::Spelling::Keyword_multiple_inheritance; + break; + case llvm::codeview::PointerToMemberRepresentation:: + VirtualInheritanceData: + case llvm::codeview::PointerToMemberRepresentation:: + VirtualInheritanceFunction: + spelling = + clang::MSInheritanceAttr::Spelling::Keyword_virtual_inheritance; + break; + case llvm::codeview::PointerToMemberRepresentation::Unknown: + spelling = + clang::MSInheritanceAttr::Spelling::Keyword_unspecified_inheritance; + break; + default: + spelling = clang::MSInheritanceAttr::Spelling::SpellingNotCalculated; + break; + } + tag->addAttr(clang::MSInheritanceAttr::CreateImplicit( + m_clang.getASTContext(), spelling)); + } return m_clang.getASTContext().getMemberPointerType( pointee_type, class_type.getTypePtr()); } diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit index b317c4a..a79d18f 100644 --- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit +++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit @@ -20,6 +20,8 @@ target variable AnonInt target variable AnonABCVoid target variable AnonABCVoidD +target variable mp1 mp2 mp3 mp4 mp5 mp6 mp7 mp8 mp9 + target modules dump ast quit diff --git a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp index f3afa5d..a210ce0 100644 --- a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp +++ b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp @@ -86,6 +86,31 @@ Anonymous AnonInt; Anonymous> AnonABCVoid; Anonymous>::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 MI2 : MI { int mi2; }; +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 (MI2::*MI2TYPE)(); +typedef void (VI::*VITYPE)(); +typedef void (VI2::*VI2TYPE)(); +typedef void (UI::*UITYPE)(); +SITYPE mp1 = nullptr; +MITYPE mp2 = nullptr; +MI2TYPE mp3 = nullptr; +VITYPE mp4 = nullptr; +VI2TYPE mp5 = nullptr; +UITYPE mp6 = nullptr; +MITYPE *mp7 = nullptr; +VI2TYPE *mp8 = nullptr; +int SI::*mp9 = nullptr; + // FIXME: Enum size isn't being correctly determined. // FIXME: Can't read memory for variable values. @@ -106,6 +131,15 @@ Anonymous>::D AnonABCVoidD; // CHECK: (Anonymous) AnonInt = (AnonymousMember = 0) // CHECK: (Anonymous>) AnonABCVoid = (AnonymousMember = 0) // CHECK: (Anonymous>::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: (void (MI2::*)()) mp3 = 00 00 00 00 00 00 00 00 +// CHECK: (void (VI::*)()) mp4 = 00 00 00 00 00 00 00 00 +// CHECK: (void (VI2::*)()) mp5 = 00 00 00 00 00 00 00 00 +// CHECK: (void (UI::*)()) mp6 = 00 00 00 00 00 00 00 00 +// CHECK: (void (MI::**)()) mp7 = 0x0000000000000000 +// CHECK: (void (VI2::**)()) mp8 = 0x0000000000000000 +// CHECK: (int SI::*) mp9 = ff ff ff ff // CHECK: Dumping clang ast for 1 modules. // CHECK: TranslationUnitDecl {{.*}} // CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition -- 2.7.4