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 @@ -175,6 +175,7 @@ // CHECK-NEXT: } // CHECK-NEXT: (lldb) type lookup -- Class // CHECK-NEXT: class Class { +// CHECK-NEXT: public: // CHECK-NEXT: bool *PB; // CHECK-NEXT: char *PC; // CHECK-NEXT: signed char *PSC; @@ -217,7 +218,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;