summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
diff options
context:
space:
mode:
authorMehdi Amini <joker.eph@gmail.com>2025-08-14 15:36:46 +0200
committerGitHub <noreply@github.com>2025-08-14 15:36:46 +0200
commitdf57d6a01e85ca78da2febab21b268d9fd6955a0 (patch)
tree19b0aab453e6bc7e2b15d3220024dfdacd4fa57e /lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
parentdf86ea61b7ed484ca797f96d7ad40fd9ada7ba30 (diff)
parent7bda76367f19cfc19086f68d9dd5ac019a9ceccd (diff)
Merge branch 'main' into users/joker-eph-python-bindings-maintainersusers/joker-eph-python-bindings-maintainers
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp84
1 files changed, 82 insertions, 2 deletions
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 986d647b4de2..112eb06e462f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -644,8 +644,14 @@ SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id,
std::string uname = GetUnqualifiedTypeName(record);
- // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
+ llvm::Expected<Declaration> maybeDecl = ResolveUdtDeclaration(type_id);
Declaration decl;
+ if (maybeDecl)
+ decl = std::move(*maybeDecl);
+ else
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), maybeDecl.takeError(),
+ "Failed to resolve declaration for '{1}': {0}", uname);
+
return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr,
LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
Type::ResolveState::Forward);
@@ -668,7 +674,14 @@ lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
CompilerType ct) {
std::string uname = GetUnqualifiedTypeName(er);
+ llvm::Expected<Declaration> maybeDecl = ResolveUdtDeclaration(type_id);
Declaration decl;
+ if (maybeDecl)
+ decl = std::move(*maybeDecl);
+ else
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), maybeDecl.takeError(),
+ "Failed to resolve declaration for '{1}': {0}", uname);
+
TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
return MakeType(
@@ -1675,7 +1688,7 @@ void SymbolFileNativePDB::CacheFunctionNames() {
llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*iter));
if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)
continue;
- if (proc.Name.empty())
+ if (proc.Name.empty() || proc.FunctionType.isSimple())
continue;
// The function/procedure symbol only contains the demangled name.
@@ -2556,3 +2569,70 @@ SymbolFileNativePDB::GetContextForType(TypeIndex ti) {
}
return ctx;
}
+
+void SymbolFileNativePDB::CacheUdtDeclarations() {
+ for (CVType cvt : m_index->ipi().typeArray()) {
+ switch (cvt.kind()) {
+ case LF_UDT_SRC_LINE: {
+ UdtSourceLineRecord udt_src;
+ llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_src));
+ m_udt_declarations.try_emplace(
+ udt_src.UDT, UdtDeclaration{/*FileNameIndex=*/udt_src.SourceFile,
+ /*IsIpiIndex=*/true,
+ /*Line=*/udt_src.LineNumber});
+ } break;
+ case LF_UDT_MOD_SRC_LINE: {
+ UdtModSourceLineRecord udt_mod_src;
+ llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_mod_src));
+ // Some types might be contributed by multiple modules. We assume that
+ // they all point to the same file and line because we can only provide
+ // one location.
+ m_udt_declarations.try_emplace(
+ udt_mod_src.UDT,
+ UdtDeclaration{/*FileNameIndex=*/udt_mod_src.SourceFile,
+ /*IsIpiIndex=*/false,
+ /*Line=*/udt_mod_src.LineNumber});
+ } break;
+ default:
+ break;
+ }
+ }
+}
+
+llvm::Expected<Declaration>
+SymbolFileNativePDB::ResolveUdtDeclaration(PdbTypeSymId type_id) {
+ std::call_once(m_cached_udt_declarations, [this] { CacheUdtDeclarations(); });
+
+ auto it = m_udt_declarations.find(type_id.index);
+ if (it == m_udt_declarations.end())
+ return llvm::createStringError("No UDT declaration found");
+
+ llvm::StringRef file_name;
+ if (it->second.IsIpiIndex) {
+ CVType cvt = m_index->ipi().getType(it->second.FileNameIndex);
+ if (cvt.kind() != LF_STRING_ID)
+ return llvm::createStringError("File name was not a LF_STRING_ID");
+
+ StringIdRecord sid;
+ llvm::cantFail(TypeDeserializer::deserializeAs(cvt, sid));
+ file_name = sid.String;
+ } else {
+ // The file name index is an index into the string table
+ auto string_table = m_index->pdb().getStringTable();
+ if (!string_table)
+ return string_table.takeError();
+
+ llvm::Expected<llvm::StringRef> string =
+ string_table->getStringTable().getString(
+ it->second.FileNameIndex.getIndex());
+ if (!string)
+ return string.takeError();
+ file_name = *string;
+ }
+
+ // rustc sets the filename to "<unknown>" for some files
+ if (file_name == "\\<unknown>")
+ return Declaration();
+
+ return Declaration(FileSpec(file_name), it->second.Line);
+}