zequanwu updated this revision to Diff 391734.
zequanwu added a comment.

Add tests for alternating access.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D115062

Files:
  lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
  lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp

Index: lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp
===================================================================
--- lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp
+++ 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;
Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
===================================================================
--- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ 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<CXXRecordDecl>(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<AccessSpecDecl>(*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<clang::ParmVarDecl *>(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),
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to