diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1743,6 +1743,18 @@ } } + // Microsoft abi requires tag decl to have MSInheritanceAttr. + if (m_ast.getASTContext().getTargetInfo().getCXXABI().isMicrosoft() && + clang_type_was_created) { + clang::QualType class_qt = + clang::QualType::getFromOpaquePtr(clang_type.GetOpaqueQualType()); + if (clang::CXXRecordDecl *record_decl = class_qt->getAsCXXRecordDecl()) { + record_decl->addAttr(clang::MSInheritanceAttr::CreateImplicit( + m_ast.getASTContext(), + clang::MSInheritanceAttr::Spelling::Keyword_unspecified_inheritance)); + } + } + // Store a forward declaration to this class type in case any // parameters in any class methods need it for the clang types for // function prototypes. diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -816,7 +816,7 @@ clang::QualType class_type = GetOrCreateType(mpi.ContainingType); if (class_type.isNull()) return {}; - if (clang::TagDecl *tag = class_type->getAsTagDecl()) { + if (clang::CXXRecordDecl *record_decl = class_type->getAsCXXRecordDecl()) { clang::MSInheritanceAttr::Spelling spelling; switch (mpi.Representation) { case llvm::codeview::PointerToMemberRepresentation::SingleInheritanceData: @@ -847,7 +847,7 @@ spelling = clang::MSInheritanceAttr::Spelling::SpellingNotCalculated; break; } - tag->addAttr(clang::MSInheritanceAttr::CreateImplicit( + record_decl->addAttr(clang::MSInheritanceAttr::CreateImplicit( m_clang.getASTContext(), spelling)); } return m_clang.getASTContext().getMemberPointerType( diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/ms_abi.cpp b/lldb/test/Shell/SymbolFile/DWARF/x86/ms_abi.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/ms_abi.cpp @@ -0,0 +1,56 @@ +// REQUIRES: lld + +// RUN: %clang -c --target=x86_64-windows-msvc -gdwarf %s -o %t.obj +// RUN: lld-link /out:%t.exe %t.obj /nodefaultlib /entry:main /debug +// RUN: %lldb -f %t.exe \ +// RUN: -o "target variable mp1 mp2 mp3 mp4 mp5 mp6 mp7 mp8 mp9" -o "exit" \ +// RUN: | FileCheck %s + +// 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; + +// CHECK: (SITYPE) mp1 = 00 00 00 00 00 00 00 00 +// CHECK: (MITYPE) mp2 = 00 00 00 00 00 00 00 00 +// CHECK: (MI2TYPE) mp3 = 00 00 00 00 00 00 00 00 +// CHECK: (VITYPE) mp4 = 00 00 00 00 00 00 00 00 +// CHECK: (VI2TYPE) mp5 = 00 00 00 00 00 00 00 00 +// CHECK: (UITYPE) mp6 = 00 00 00 00 00 00 00 00 +// CHECK: (MITYPE *) mp7 = 0x0000000000000000 +// CHECK: (VI2TYPE *) mp8 = 0x0000000000000000 +// CHECK: (int SI::*) mp9 = ff ff ff ff + +int main() {}