[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