[Lldb-commits] [lldb] d5b6e30 - [LLDB][Clang] add AccessSpecDecl for methods and fields in RecordType

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Tue Jan 4 13:50:44 PST 2022


Author: Zequan Wu
Date: 2022-01-04T13:50:24-08:00
New Revision: d5b6e30ed3acad794dd0aec400e617daffc6cc3d

URL: https://github.com/llvm/llvm-project/commit/d5b6e30ed3acad794dd0aec400e617daffc6cc3d
DIFF: https://github.com/llvm/llvm-project/commit/d5b6e30ed3acad794dd0aec400e617daffc6cc3d.diff

LOG: [LLDB][Clang] add AccessSpecDecl for methods and fields in RecordType

This allows access type be printed when running `lldb-test -dump-ast` and
`lldb-test -dump-clang-ast`.

Differential Revision: https://reviews.llvm.org/D115062

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 88c3aedb4c6b5..f8f0689ee2ac4 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1345,7 +1345,30 @@ namespace {
 bool IsValueParam(const clang::TemplateArgument &argument) {
   return argument.getKind() == TemplateArgument::Integral;
 }
+
+void AddAccessSpecifierDecl(clang::CXXRecordDecl *cxx_record_decl,
+                            ASTContext &ct,
+                            clang::AccessSpecifier previous_access,
+                            clang::AccessSpecifier access_specifier) {
+  if (!cxx_record_decl->isClass() && !cxx_record_decl->isStruct())
+    return;
+  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,
@@ -2552,6 +2575,22 @@ ClangASTMetadata *TypeSystemClang::GetMetadata(const clang::Type *object) {
   return nullptr;
 }
 
+void TypeSystemClang::SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object,
+                                             clang::AccessSpecifier access) {
+  if (access == clang::AccessSpecifier::AS_none)
+    m_cxx_record_decl_access.erase(object);
+  else
+    m_cxx_record_decl_access[object] = access;
+}
+
+clang::AccessSpecifier
+TypeSystemClang::GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object) {
+  auto It = m_cxx_record_decl_access.find(object);
+  if (It != m_cxx_record_decl_access.end())
+    return It->second;
+  return clang::AccessSpecifier::AS_none;
+}
+
 clang::DeclContext *
 TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
   return GetDeclContextForType(ClangUtil::GetQualType(type));
@@ -7276,9 +7315,17 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
     }
 
     if (field) {
-      field->setAccess(
-          TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access));
-
+      clang::AccessSpecifier access_specifier =
+          TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access);
+      field->setAccess(access_specifier);
+
+      if (clang::CXXRecordDecl *cxx_record_decl =
+              llvm::dyn_cast<CXXRecordDecl>(record_decl)) {
+        AddAccessSpecifierDecl(cxx_record_decl, ast->getASTContext(),
+                               ast->GetCXXRecordDeclAccess(cxx_record_decl),
+                               access_specifier);
+        ast->SetCXXRecordDeclAccess(cxx_record_decl, access_specifier);
+      }
       record_decl->addDecl(field);
 
       VerifyDecl(field);
@@ -7657,6 +7704,11 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType(
 
   cxx_method_decl->setParams(llvm::ArrayRef<clang::ParmVarDecl *>(params));
 
+  AddAccessSpecifierDecl(cxx_record_decl, getASTContext(),
+                         GetCXXRecordDeclAccess(cxx_record_decl),
+                         access_specifier);
+  SetCXXRecordDeclAccess(cxx_record_decl, access_specifier);
+
   cxx_record_decl->addDecl(cxx_method_decl);
 
   // Sometimes the debug info will mention a constructor (default/copy/move),
@@ -8190,6 +8242,11 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition(
   if (qual_type.isNull())
     return false;
 
+  TypeSystemClang *lldb_ast =
+      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  if (lldb_ast == nullptr)
+    return false;
+
   // Make sure we use the same methodology as
   // TypeSystemClang::StartTagDeclarationDefinition() as to how we start/end
   // the definition.
@@ -8220,6 +8277,8 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition(
       cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true);
       cxx_record_decl->setHasExternalLexicalStorage(false);
       cxx_record_decl->setHasExternalVisibleStorage(false);
+      lldb_ast->SetCXXRecordDeclAccess(cxx_record_decl,
+                                       clang::AccessSpecifier::AS_none);
       return true;
     }
   }
@@ -8233,10 +8292,6 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition(
   if (enum_decl->isCompleteDefinition())
     return true;
 
-  TypeSystemClang *lldb_ast =
-      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
-  if (lldb_ast == nullptr)
-    return false;
   clang::ASTContext &ast = lldb_ast->getASTContext();
 
   /// TODO This really needs to be fixed.

diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index f3a07397ec440..e0f5906778a13 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -196,6 +196,11 @@ class TypeSystemClang : public TypeSystem {
   ClangASTMetadata *GetMetadata(const clang::Decl *object);
   ClangASTMetadata *GetMetadata(const clang::Type *object);
 
+  void SetCXXRecordDeclAccess(const clang::CXXRecordDecl *object,
+                              clang::AccessSpecifier access);
+  clang::AccessSpecifier
+  GetCXXRecordDeclAccess(const clang::CXXRecordDecl *object);
+
   // Basic Types
   CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
                                                    size_t bit_size) override;
@@ -1080,6 +1085,12 @@ class TypeSystemClang : public TypeSystem {
   /// Maps Types to their associated ClangASTMetadata.
   TypeMetadataMap m_type_metadata;
 
+  typedef llvm::DenseMap<const clang::CXXRecordDecl *, clang::AccessSpecifier>
+      CXXRecordDeclAccessMap;
+  /// Maps CXXRecordDecl to their most recent added method/field's
+  /// AccessSpecifier.
+  CXXRecordDeclAccessMap m_cxx_record_decl_access;
+
   /// The sema associated that is currently used to build this ASTContext.
   /// May be null if we are already done parsing this ASTContext or the
   /// ASTContext wasn't created by parsing source code.

diff  --git a/lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp
index df00f15c1a036..2073cecfc670c 100644
--- 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 @@ struct Struct {
 
 // Test class
 class Class {
-public:
   // Test pointers to builtin types, which are represented by 
diff erent 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 @@ int main(int argc, char **argv) {
 // 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 @@ int main(int argc, char **argv) {
 // 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 @@ int main(int argc, char **argv) {
 // 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;


        


More information about the lldb-commits mailing list