Index: lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h =================================================================== --- lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h +++ lldb/source/Plugins/SymbolFile/CTF/CTFTypes.h @@ -163,6 +163,11 @@ : CTFRecord(eUnion, uid, name, nfields, size, fields){}; }; +struct CTFForward : public CTFType { + CTFForward(lldb::user_id_t uid, llvm::StringRef name) + : CTFType(eForward, uid, name) {} +}; + } // namespace lldb_private #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_CTFTYPES_H Index: lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h =================================================================== --- lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h +++ lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h @@ -225,6 +225,7 @@ llvm::Expected CreateEnum(const CTFEnum &ctf_enum); llvm::Expected CreateFunction(const CTFFunction &ctf_function); llvm::Expected CreateRecord(const CTFRecord &ctf_record); + llvm::Expected CreateForward(const CTFForward &ctf_forward); llvm::StringRef ReadString(lldb::offset_t offset) const; Index: lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp +++ lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp @@ -524,6 +524,17 @@ decl, record_type, lldb_private::Type::ResolveState::Full); } +llvm::Expected +SymbolFileCTF::CreateForward(const CTFForward &ctf_forward) { + CompilerType forward_compiler_type = m_ast->CreateRecordType( + nullptr, OptionalClangModuleID(), eAccessPublic, ctf_forward.name.data(), + clang::TTK_Struct, eLanguageTypeC); + Declaration decl; + return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr, + LLDB_INVALID_UID, Type::eEncodingIsUID, decl, + forward_compiler_type, Type::ResolveState::Forward); +} + llvm::Expected SymbolFileCTF::CreateType(CTFType *ctf_type) { if (!ctf_type) return llvm::make_error( @@ -548,9 +559,10 @@ case CTFType::Kind::eStruct: case CTFType::Kind::eUnion: return CreateRecord(*static_cast(ctf_type)); + case CTFType::Kind::eForward: + return CreateForward(*static_cast(ctf_type)); case CTFType::Kind::eUnknown: case CTFType::Kind::eFloat: - case CTFType::Kind::eForward: case CTFType::Kind::eSlice: return llvm::make_error( llvm::formatv("unsupported type (uid = {0}, name = {1}, kind = {2})", @@ -636,11 +648,12 @@ return std::make_unique(static_cast(kind), uid, name, variable_length, size, fields); } + case TypeKind::eForward: + return std::make_unique(uid, name); case TypeKind::eUnknown: return std::make_unique(static_cast(kind), uid, name); case TypeKind::eFloat: - case TypeKind::eForward: case TypeKind::eSlice: offset += (variable_length * sizeof(uint32_t)); break; Index: lldb/test/API/macosx/ctf/TestCTF.py =================================================================== --- lldb/test/API/macosx/ctf/TestCTF.py +++ lldb/test/API/macosx/ctf/TestCTF.py @@ -78,3 +78,5 @@ "target variable foo.f", substrs=["(void (*)(int)) foo.f = 0x0000000000000000"], ) + + self.expect(" type lookup ForwardDecl", substrs=["struct ForwardDecl"]) Index: lldb/test/API/macosx/ctf/test.c =================================================================== --- lldb/test/API/macosx/ctf/test.c +++ lldb/test/API/macosx/ctf/test.c @@ -1,5 +1,7 @@ #include +struct ForwardDecl; + typedef int MyInt; void populate(MyInt i); @@ -30,6 +32,7 @@ } MyStructT; MyStructT foo; +struct ForwardDecl *forward; void populate(MyInt i) { foo.n.i = i; @@ -41,6 +44,7 @@ foo.n.a[3] = 'd'; foo.n.e = eOne; foo.f = NULL; + forward = NULL; } int main(int argc, char** argv) {