diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1345,7 +1345,38 @@ bool IsValueParam(const clang::TemplateArgument &argument) { return argument.getKind() == TemplateArgument::Integral; } + +void AddAccessSpecifierDecl(clang::RecordDecl *record_decl, ASTContext &ct, + clang::AccessSpecifier access_specifier) { + if (!record_decl->isClass() && !record_decl->isStruct()) + return; + if (clang::CXXRecordDecl *cxx_record_decl = + llvm::dyn_cast(record_decl)) { + clang::AccessSpecifier previous_access = clang::AccessSpecifier::AS_none; + for (DeclContext::decl_iterator I = cxx_record_decl->decls_begin(), + E = cxx_record_decl->decls_end(); + I != E; ++I) { + if (clang::AccessSpecDecl *asd = llvm::dyn_cast(*I)) + previous_access = asd->getAccess(); + } + if (previous_access != access_specifier) { + // For struct, don't add AS_public if it's the first AccessSpecDecl. + // For class, don't add AS_private if it's the first AccessSpecDecl. + if ((cxx_record_decl->isStruct() && + previous_access == clang::AccessSpecifier::AS_none && + access_specifier == clang::AccessSpecifier::AS_public) || + (cxx_record_decl->isClass() && + previous_access == clang::AccessSpecifier::AS_none && + access_specifier == clang::AccessSpecifier::AS_private)) { + return; + } + cxx_record_decl->addDecl( + AccessSpecDecl::Create(ct, access_specifier, cxx_record_decl, + SourceLocation(), SourceLocation())); + } + } } +} // namespace static TemplateParameterList *CreateTemplateParameterList( ASTContext &ast, @@ -7270,9 +7301,12 @@ } if (field) { - field->setAccess( - TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access)); + clang::AccessSpecifier access_specifier = + TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); + field->setAccess(access_specifier); + AddAccessSpecifierDecl(record_decl, ast->getASTContext(), + access_specifier); record_decl->addDecl(field); VerifyDecl(field); @@ -7651,6 +7685,8 @@ cxx_method_decl->setParams(llvm::ArrayRef(params)); + AddAccessSpecifierDecl(cxx_record_decl, getASTContext(), access_specifier); + cxx_record_decl->addDecl(cxx_method_decl); // Sometimes the debug info will mention a constructor (default/copy/move), diff --git a/lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp --- a/lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp +++ b/lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp @@ -11,16 +11,23 @@ struct Struct { // Test builtin types, which are represented by special CodeView type indices. bool B; +private: char C; +public: signed char SC; +protected: unsigned char UC; char16_t C16; char32_t C32; +protected: wchar_t WC; short S; unsigned short US; +public: int I; +private: unsigned int UI; +public: long L; unsigned long UL; long long LL; @@ -32,15 +39,20 @@ // Test class class Class { -public: // Test pointers to builtin types, which are represented by different special // CodeView type indices. bool *PB; +public: char *PC; +private: signed char *PSC; +protected: unsigned char *PUC; +private: char16_t *PC16; +public: char32_t *PC32; +private: wchar_t *PWC; short *PS; unsigned short *PUS; @@ -155,16 +167,22 @@ // CHECK-NEXT: (lldb) type lookup -- Struct // CHECK-NEXT: struct Struct { // CHECK-NEXT: bool B; +// CHECK-NEXT: private: // CHECK-NEXT: char C; +// CHECK-NEXT: public: // CHECK-NEXT: signed char SC; +// CHECK-NEXT: protected: // CHECK-NEXT: unsigned char UC; // CHECK-NEXT: char16_t C16; // CHECK-NEXT: char32_t C32; // CHECK-NEXT: wchar_t WC; // CHECK-NEXT: short S; // CHECK-NEXT: unsigned short US; +// CHECK-NEXT: public: // CHECK-NEXT: int I; +// CHECK-NEXT: private: // CHECK-NEXT: unsigned int UI; +// CHECK-NEXT: public: // CHECK-NEXT: long L; // CHECK-NEXT: unsigned long UL; // CHECK-NEXT: long long LL; @@ -176,11 +194,17 @@ // CHECK-NEXT: (lldb) type lookup -- Class // CHECK-NEXT: class Class { // CHECK-NEXT: bool *PB; +// CHECK-NEXT: public: // CHECK-NEXT: char *PC; +// CHECK-NEXT: private: // CHECK-NEXT: signed char *PSC; +// CHECK-NEXT: protected: // CHECK-NEXT: unsigned char *PUC; +// CHECK-NEXT: private: // CHECK-NEXT: char16_t *PC16; +// CHECK-NEXT: public: // CHECK-NEXT: char32_t *PC32; +// CHECK-NEXT: private: // CHECK-NEXT: wchar_t *PWC; // CHECK-NEXT: short *PS; // CHECK-NEXT: unsigned short *PUS; @@ -217,7 +241,8 @@ // CHECK-NEXT: } // CHECK-NEXT: (lldb) type lookup -- Derived // CHECK-NEXT: class Derived : public Class { -// CHECK: Derived &Reference; +// CHECK-NEXT: public: +// CHECK-NEXT: Derived &Reference; // CHECK-NEXT: OneMember Member; // CHECK-NEXT: const OneMember ConstMember; // CHECK-NEXT: volatile OneMember VolatileMember;