[Lldb-commits] [lldb] 12f3d97 - [lldb] Support recursive record types in CTF
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Sat Jul 29 22:32:46 PDT 2023
Author: Jonas Devlieghere
Date: 2023-07-29T22:32:24-07:00
New Revision: 12f3d97fc68b304e0efbe183665c0183d9a372b3
URL: https://github.com/llvm/llvm-project/commit/12f3d97fc68b304e0efbe183665c0183d9a372b3
DIFF: https://github.com/llvm/llvm-project/commit/12f3d97fc68b304e0efbe183665c0183d9a372b3.diff
LOG: [lldb] Support recursive record types in CTF
Support recursive record types in CTF, for example a struct that
contains a pointer to itself:
struct S {
struct S *n;
};
We are now more lazy when creating LLDB types. When encountering a
record type (struct or union) we create a forward declaration and only
complete it when requested.
Differential revision: https://reviews.llvm.org/D156498
Added:
Modified:
lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
lldb/test/API/macosx/ctf/TestCTF.py
lldb/test/API/macosx/ctf/test.c
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
index 1c4de94e06d7b8..55e3a1ddb96165 100644
--- a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
+++ b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
@@ -503,26 +503,59 @@ SymbolFileCTF::CreateFunction(const CTFFunction &ctf_function) {
llvm::Expected<lldb::TypeSP>
SymbolFileCTF::CreateRecord(const CTFRecord &ctf_record) {
const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
-
CompilerType record_type =
m_ast->CreateRecordType(nullptr, OptionalClangModuleID(), eAccessPublic,
ctf_record.name.data(), tag_kind, eLanguageTypeC);
+ m_compiler_types[record_type.GetOpaqueQualType()] = &ctf_record;
+ Declaration decl;
+ return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
+ nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
+ decl, record_type, lldb_private::Type::ResolveState::Forward);
+}
+
+bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
+ // Check if we have a CTF type for the given incomplete compiler type.
+ auto it = m_compiler_types.find(compiler_type.GetOpaqueQualType());
+ if (it == m_compiler_types.end())
+ return false;
+
+ const CTFType *ctf_type = it->second;
+ assert(ctf_type && "m_compiler_types should only contain valid CTF types");
+
+ // We only support resolving record types.
+ assert(ctf_type->kind == CTFType::Kind::eStruct ||
+ ctf_type->kind == CTFType::Kind::eUnion);
- m_ast->StartTagDeclarationDefinition(record_type);
- for (const CTFRecord::Field &field : ctf_record.fields) {
- if (Type *field_type = ResolveTypeUID(field.type)) {
- const uint32_t field_size = field_type->GetByteSize(nullptr).value_or(0);
- TypeSystemClang::AddFieldToRecordType(record_type, field.name,
- field_type->GetFullCompilerType(),
- eAccessPublic, field_size);
+ // Cast to the appropriate CTF type.
+ const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
+
+ // If any of the fields are incomplete, we cannot complete the type.
+ for (const CTFRecord::Field &field : ctf_record->fields) {
+ if (!ResolveTypeUID(field.type)) {
+ LLDB_LOG(GetLog(LLDBLog::Symbols),
+ "Cannot complete type {0} because field {1} is incomplete",
+ ctf_type->uid, field.type);
+ return false;
}
}
- m_ast->CompleteTagDeclarationDefinition(record_type);
- Declaration decl;
- return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
- nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
- decl, record_type, lldb_private::Type::ResolveState::Full);
+ // Complete the record type.
+ m_ast->StartTagDeclarationDefinition(compiler_type);
+ for (const CTFRecord::Field &field : ctf_record->fields) {
+ Type *field_type = ResolveTypeUID(field.type);
+ assert(field_type && "field must be complete");
+ const uint32_t field_size = field_type->GetByteSize(nullptr).value_or(0);
+ TypeSystemClang::AddFieldToRecordType(compiler_type, field.name,
+ field_type->GetFullCompilerType(),
+ eAccessPublic, field_size);
+ }
+ m_ast->CompleteTagDeclarationDefinition(compiler_type);
+
+ // Now that the compiler type is no longer incomplete we don't need to
+ // remember it anymore.
+ m_compiler_types.erase(compiler_type.GetOpaqueQualType());
+
+ return true;
}
llvm::Expected<lldb::TypeSP>
@@ -960,7 +993,6 @@ lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
if (!ctf_type)
return nullptr;
- m_types[type_uid] = TypeSP();
Log *log = GetLog(LLDBLog::Symbols);
llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
diff --git a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
index 170a6d8700516a..2b046708c6db3c 100644
--- a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
+++ b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
@@ -93,7 +93,7 @@ class SymbolFileCTF : public lldb_private::SymbolFileCommon {
return std::nullopt;
}
- bool CompleteType(CompilerType &compiler_type) override { return false; }
+ bool CompleteType(CompilerType &compiler_type) override;
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
lldb::SymbolContextItem resolve_scope,
@@ -247,6 +247,11 @@ class SymbolFileCTF : public lldb_private::SymbolFileCommon {
std::vector<std::unique_ptr<CTFType>> m_ctf_types;
+ /// To complete types, we need a way to map (imcomplete) compiler types back
+ /// to parsed CTF types.
+ llvm::DenseMap<lldb::opaque_compiler_type_t, const CTFType *>
+ m_compiler_types;
+
llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;
std::vector<lldb::FunctionSP> m_functions;
diff --git a/lldb/test/API/macosx/ctf/TestCTF.py b/lldb/test/API/macosx/ctf/TestCTF.py
index 470d35f74d1d92..f5fd29f6ed968f 100644
--- a/lldb/test/API/macosx/ctf/TestCTF.py
+++ b/lldb/test/API/macosx/ctf/TestCTF.py
@@ -91,3 +91,5 @@ def do_test(self):
"}",
],
)
+
+ self.expect("type lookup RecursiveStruct", substrs=["RecursiveStruct *n;"])
diff --git a/lldb/test/API/macosx/ctf/test.c b/lldb/test/API/macosx/ctf/test.c
index 71433e941c5b45..358006646e766e 100644
--- a/lldb/test/API/macosx/ctf/test.c
+++ b/lldb/test/API/macosx/ctf/test.c
@@ -36,9 +36,14 @@ struct LargeStruct {
int b;
};
+struct RecursiveStruct {
+ struct RecursiveStruct *n;
+};
+
MyStructT foo;
struct ForwardDecl *forward;
struct LargeStruct bar;
+struct RecursiveStruct ke;
void populate(MyInt i) {
foo.n.i = i;
@@ -52,6 +57,7 @@ void populate(MyInt i) {
foo.f = NULL;
forward = NULL;
bar.b = i;
+ ke.n = NULL;
}
int main(int argc, char** argv) {
More information about the lldb-commits
mailing list