summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile
diff options
context:
space:
mode:
authorMingming Liu <mingmingl@google.com>2025-09-10 15:25:31 -0700
committerGitHub <noreply@github.com>2025-09-10 15:25:31 -0700
commit1417dafa1db9cb1b2b09438aa9f53ea5ab6e36e2 (patch)
tree57f4b1f313c8cf74eed8819870f39c36ea263c68 /lldb/source/Plugins/SymbolFile
parent898b813bc8a6d0276bf0f4769f5f2f64b34e632d (diff)
parentb8cefcb601ddaa18482555c4ff363c01a270c2fe (diff)
Merge branch 'main' into users/mingmingl-llvm/samplefdo-profile-formatusers/mingmingl-llvm/samplefdo-profile-format
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp18
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp185
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h15
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp4
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp1
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp110
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h8
8 files changed, 269 insertions, 74 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index a429ea848b7f..5ffb4423969c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -252,7 +252,7 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram,
}
static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
- char const *name = die.GetMangledName(/*substitute_name_allowed*/ false);
+ const char *name = die.GetMangledName(/*substitute_name_allowed*/ false);
if (!name)
return {};
@@ -286,7 +286,9 @@ static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
if (die_id == LLDB_INVALID_UID)
return {};
- return FunctionCallLabel{/*module_id=*/module_id,
+ // Note, discriminator is added by Clang during mangling.
+ return FunctionCallLabel{/*discriminator=*/{},
+ /*module_id=*/module_id,
/*symbol_id=*/die_id,
/*.lookup_name=*/name}
.toString();
@@ -2230,6 +2232,18 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
for (DelayedAddObjCClassProperty &property : delayed_properties)
property.Finalize();
}
+ } else if (Language::LanguageIsObjC(
+ static_cast<LanguageType>(die.GetAttributeValueAsUnsigned(
+ DW_AT_APPLE_runtime_class, eLanguageTypeUnknown)))) {
+ /// The forward declaration was C++ but the definition is Objective-C.
+ /// We currently don't handle such situations. In such cases, keep the
+ /// forward declaration without a definition to avoid violating Clang AST
+ /// invariants.
+ LLDB_LOG(GetLog(LLDBLog::Expressions),
+ "WARNING: Type completion aborted because forward declaration for "
+ "'{0}' is C++ while definition is Objective-C.",
+ llvm::StringRef(die.GetName()));
+ return {};
}
if (!bases.empty()) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b15e0c15fedb..d3d0110d5e30 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -7,11 +7,14 @@
//===----------------------------------------------------------------------===//
#include "SymbolFileDWARF.h"
+#include "clang/Basic/ABI.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/Threading.h"
@@ -23,6 +26,7 @@
#include "lldb/Core/Progress.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Value.h"
+#include "lldb/Expression/Expression.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/RegularExpression.h"
@@ -79,6 +83,7 @@
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
@@ -2484,34 +2489,148 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
return false;
}
-DWARFDIE
-SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel &label) {
- DWARFDIE definition;
- Module::LookupInfo info(ConstString(label.lookup_name),
- lldb::eFunctionNameTypeFull,
- lldb::eLanguageTypeUnknown);
-
- m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {
- if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
- return IterationAction::Continue;
+static llvm::StringRef ClangToItaniumCtorKind(clang::CXXCtorType kind) {
+ switch (kind) {
+ case clang::CXXCtorType::Ctor_Complete:
+ return "C1";
+ case clang::CXXCtorType::Ctor_Base:
+ return "C2";
+ case clang::CXXCtorType::Ctor_Unified:
+ return "C4";
+ case clang::CXXCtorType::Ctor_CopyingClosure:
+ case clang::CXXCtorType::Ctor_DefaultClosure:
+ case clang::CXXCtorType::Ctor_Comdat:
+ llvm_unreachable("Unexpected constructor kind.");
+ }
+}
- // We don't check whether the specification DIE for this function
- // corresponds to the declaration DIE because the declaration might be in
- // a type-unit but the definition in the compile-unit (and it's
- // specifcation would point to the declaration in the compile-unit). We
- // rely on the mangled name within the module to be enough to find us the
- // unique definition.
- definition = entry;
- return IterationAction::Stop;
- });
+static llvm::StringRef ClangToItaniumDtorKind(clang::CXXDtorType kind) {
+ switch (kind) {
+ case clang::CXXDtorType::Dtor_Deleting:
+ return "D0";
+ case clang::CXXDtorType::Dtor_Complete:
+ return "D1";
+ case clang::CXXDtorType::Dtor_Base:
+ return "D2";
+ case clang::CXXDtorType::Dtor_Unified:
+ return "D4";
+ case clang::CXXDtorType::Dtor_Comdat:
+ llvm_unreachable("Unexpected destructor kind.");
+ }
+}
+
+static llvm::StringRef
+GetItaniumCtorDtorVariant(llvm::StringRef discriminator) {
+ const bool is_ctor = discriminator.consume_front("C");
+ if (!is_ctor && !discriminator.consume_front("D"))
+ return {};
+
+ uint64_t structor_kind;
+ if (!llvm::to_integer(discriminator, structor_kind))
+ return {};
+
+ if (is_ctor) {
+ if (structor_kind > clang::CXXCtorType::Ctor_Unified)
+ return {};
+
+ return ClangToItaniumCtorKind(
+ static_cast<clang::CXXCtorType>(structor_kind));
+ }
+
+ if (structor_kind > clang::CXXDtorType::Dtor_Unified)
+ return {};
+
+ return ClangToItaniumDtorKind(static_cast<clang::CXXDtorType>(structor_kind));
+}
+
+llvm::Expected<DWARFDIE>
+SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel &label,
+ const DWARFDIE &declaration) {
+ auto do_lookup = [this](llvm::StringRef lookup_name) -> DWARFDIE {
+ DWARFDIE found;
+ Module::LookupInfo info(ConstString(lookup_name),
+ lldb::eFunctionNameTypeFull,
+ lldb::eLanguageTypeUnknown);
+
+ m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {
+ if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
+ return IterationAction::Continue;
+
+ found = entry;
+ return IterationAction::Stop;
+ });
+
+ return found;
+ };
+
+ DWARFDIE definition = do_lookup(label.lookup_name);
+ if (definition.IsValid())
+ return definition;
+
+ // This is not a structor lookup. Nothing else to be done here.
+ if (label.discriminator.empty())
+ return llvm::createStringError(
+ "no definition DIE found in this SymbolFile");
+
+ // We're doing a structor lookup. Maybe we didn't find the structor variant
+ // because the complete object structor was aliased to the base object
+ // structor. Try finding the alias instead.
+ //
+ // TODO: there are other reasons for why a subprogram definition might be
+ // missing. Ideally DWARF would tell us more details about which structor
+ // variant a DIE corresponds to and whether it's an alias.
+ auto subst_or_err =
+ CPlusPlusLanguage::SubstituteStructorAliases_ItaniumMangle(
+ label.lookup_name);
+ if (!subst_or_err)
+ return subst_or_err.takeError();
+
+ definition = do_lookup(*subst_or_err);
+
+ if (!definition.IsValid())
+ return llvm::createStringError(
+ "failed to find definition DIE for structor alias in fallback lookup");
return definition;
}
llvm::Expected<SymbolContext>
-SymbolFileDWARF::ResolveFunctionCallLabel(const FunctionCallLabel &label) {
+SymbolFileDWARF::ResolveFunctionCallLabel(FunctionCallLabel &label) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ if (!label.discriminator.empty()) {
+ llvm::StringRef from = label.discriminator[0] == 'C' ? "C4" : "D4";
+
+ llvm::StringRef variant = GetItaniumCtorDtorVariant(label.discriminator);
+ if (variant.empty())
+ return llvm::createStringError(
+ "failed to get Itanium variant for discriminator");
+
+ if (from == variant)
+ return llvm::createStringError(
+ "tried substituting unified structor variant into label");
+
+ // If we failed to substitute unified mangled name, don't try to do a lookup
+ // using the unified name because there may be multiple definitions for it
+ // in the index, and we wouldn't know which one to choose.
+ auto subst_or_err = CPlusPlusLanguage::SubstituteStructor_ItaniumMangle(
+ label.lookup_name, from, variant);
+ if (!subst_or_err)
+ return llvm::joinErrors(
+ llvm::createStringError(llvm::formatv(
+ "failed to substitute {0} for {1} in mangled name {2}:", from,
+ variant, label.lookup_name)),
+ subst_or_err.takeError());
+
+ if (!*subst_or_err)
+ return llvm::createStringError(
+ llvm::formatv("got invalid substituted mangled named (substituted "
+ "{0} for {1} in mangled name {2})",
+ from, variant, label.lookup_name));
+
+ label.lookup_name = subst_or_err->GetStringRef();
+ }
+
DWARFDIE die = GetDIE(label.symbol_id);
if (!die.IsValid())
return llvm::createStringError(
@@ -2520,11 +2639,13 @@ SymbolFileDWARF::ResolveFunctionCallLabel(const FunctionCallLabel &label) {
// Label was created using a declaration DIE. Need to fetch the definition
// to resolve the function call.
if (die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0)) {
- auto definition = FindFunctionDefinition(label);
- if (!definition)
- return llvm::createStringError("failed to find definition DIE");
+ auto die_or_err = FindFunctionDefinition(label, die);
+ if (!die_or_err)
+ return llvm::joinErrors(
+ llvm::createStringError("failed to find definition DIE:"),
+ die_or_err.takeError());
- die = std::move(definition);
+ die = std::move(*die_or_err);
}
SymbolContextList sc_list;
@@ -4502,9 +4623,8 @@ void SymbolFileDWARF::GetCompileOptions(
}
}
-std::pair<uint32_t, uint32_t> SymbolFileDWARF::GetDwoFileCounts() {
- uint32_t total_dwo_count = 0;
- uint32_t loaded_dwo_count = 0;
+DWOStats SymbolFileDWARF::GetDwoStats() {
+ DWOStats stats;
DWARFDebugInfo &info = DebugInfo();
const size_t num_cus = info.GetNumUnits();
@@ -4517,16 +4637,21 @@ std::pair<uint32_t, uint32_t> SymbolFileDWARF::GetDwoFileCounts() {
if (!dwarf_cu->GetDWOId().has_value())
continue;
- total_dwo_count++;
+ stats.dwo_file_count++;
// If we have a DWO symbol file, that means we were able to successfully
// load it.
SymbolFile *dwo_symfile =
dwarf_cu->GetDwoSymbolFile(/*load_all_debug_info=*/false);
if (dwo_symfile) {
- loaded_dwo_count++;
+ stats.loaded_dwo_file_count++;
}
+
+ // Check if this unit has a DWO load error, false by default.
+ const Status &dwo_error = dwarf_cu->GetDwoError();
+ if (dwo_error.Fail())
+ stats.dwo_error_count++;
}
- return {loaded_dwo_count, total_dwo_count};
+ return stats;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index d7db8a3c0869..85306d8b4fb5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -283,10 +283,11 @@ public:
bool GetSeparateDebugInfo(StructuredData::Dictionary &d, bool errors_only,
bool load_all_debug_info = false) override;
- // Gets a pair of loaded and total dwo file counts.
- // For split-dwarf files, this reports the counts for successfully loaded DWO
- // CUs and total DWO CUs. For non-split-dwarf files, this reports 0 for both.
- std::pair<uint32_t, uint32_t> GetDwoFileCounts() override;
+ /// Gets statistics about dwo files associated with this symbol file.
+ /// For split-dwarf files, this reports the counts for successfully loaded DWO
+ /// CUs, total DWO CUs, and the number of DWO CUs with loading errors.
+ /// For non-split-dwarf files, this reports 0 for all.
+ DWOStats GetDwoStats() override;
DWARFContext &GetDWARFContext() { return m_context; }
@@ -378,7 +379,9 @@ private:
/// SymbolFile.
///
/// \returns A valid definition DIE on success.
- DWARFDIE FindFunctionDefinition(const FunctionCallLabel &label);
+ llvm::Expected<DWARFDIE>
+ FindFunctionDefinition(const FunctionCallLabel &label,
+ const DWARFDIE &declaration);
protected:
SymbolFileDWARF(const SymbolFileDWARF &) = delete;
@@ -445,7 +448,7 @@ protected:
DIEArray &&variable_dies);
llvm::Expected<SymbolContext>
- ResolveFunctionCallLabel(const FunctionCallLabel &label) override;
+ ResolveFunctionCallLabel(FunctionCallLabel &label) override;
// Given a die_offset, figure out the symbol context representing that die.
bool ResolveFunction(const DWARFDIE &die, bool include_inlines,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 9d7452a1988f..8b8229a7020c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1603,8 +1603,8 @@ void SymbolFileDWARFDebugMap::GetCompileOptions(
});
}
-llvm::Expected<SymbolContext> SymbolFileDWARFDebugMap::ResolveFunctionCallLabel(
- const FunctionCallLabel &label) {
+llvm::Expected<SymbolContext>
+SymbolFileDWARFDebugMap::ResolveFunctionCallLabel(FunctionCallLabel &label) {
const uint64_t oso_idx = GetOSOIndexFromUserID(label.symbol_id);
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
if (!oso_dwarf)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index e1f1df23951c..bce1ed2671af 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -145,7 +145,7 @@ public:
GetCompileOptions(std::unordered_map<lldb::CompUnitSP, Args> &args) override;
llvm::Expected<SymbolContext>
- ResolveFunctionCallLabel(const FunctionCallLabel &label) override;
+ ResolveFunctionCallLabel(FunctionCallLabel &label) override;
protected:
enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 709281cb3270..933c4361d93d 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1169,6 +1169,7 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
clang::QualType element_type = GetOrCreateType(ar.ElementType);
+ TypeSystemClang::RequireCompleteType(ToCompilerType(element_type));
SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
m_clang.GetSymbolFile()->GetBackingSymbolFile());
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 112eb06e462f..e99c585d7eb1 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1624,6 +1624,8 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
for (uint64_t uid : remove_uids) {
m_inline_sites.erase(uid);
}
+
+ func.GetBlock(false).SetBlockInfoHasBeenParsed(true, true);
return count;
}
@@ -1655,22 +1657,62 @@ void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) {
clang->GetNativePDBParser()->Dump(s, filter);
}
-void SymbolFileNativePDB::CacheFunctionNames() {
- if (!m_func_full_names.IsEmpty())
+void SymbolFileNativePDB::CacheGlobalBaseNames() {
+ if (!m_func_full_names.IsEmpty() || !m_global_variable_base_names.IsEmpty())
return;
// (segment, code offset) -> gid
- std::map<std::pair<uint16_t, uint32_t>, uint32_t> addr_ids;
+ std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids;
- // First, find all function references in the globals table.
+ // First, look through all items in the globals table.
for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
- CVSymbol ref_sym = m_index->symrecords().readRecord(gid);
- auto kind = ref_sym.kind();
+ CVSymbol sym = m_index->symrecords().readRecord(gid);
+ auto kind = sym.kind();
+
+ // If this is a global variable, we only need to look at the name
+ llvm::StringRef name;
+ switch (kind) {
+ case SymbolKind::S_GDATA32:
+ case SymbolKind::S_LDATA32: {
+ DataSym data =
+ llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym));
+ name = data.Name;
+ break;
+ }
+ case SymbolKind::S_GTHREAD32:
+ case SymbolKind::S_LTHREAD32: {
+ ThreadLocalDataSym data = llvm::cantFail(
+ SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym));
+ name = data.Name;
+ break;
+ }
+ case SymbolKind::S_CONSTANT: {
+ ConstantSym data =
+ llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym));
+ name = data.Name;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!name.empty()) {
+ llvm::StringRef base = MSVCUndecoratedNameParser::DropScope(name);
+ if (base.empty())
+ base = name;
+
+ m_global_variable_base_names.Append(ConstString(base), gid);
+ continue;
+ }
+
if (kind != S_PROCREF && kind != S_LPROCREF)
continue;
+ // For functions, we need to follow the reference to the procedure and look
+ // at the type
+
ProcRefSym ref =
- llvm::cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(ref_sym));
+ llvm::cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(sym));
if (ref.Name.empty())
continue;
@@ -1694,7 +1736,7 @@ void SymbolFileNativePDB::CacheFunctionNames() {
// The function/procedure symbol only contains the demangled name.
// The mangled names are in the publics table. Save the address of this
// function to lookup the mangled name later.
- addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
+ func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(proc.Name);
if (basename.empty())
@@ -1729,43 +1771,47 @@ void SymbolFileNativePDB::CacheFunctionNames() {
continue;
// Check if this symbol is for one of our functions.
- auto it = addr_ids.find({pub.Segment, pub.Offset});
- if (it != addr_ids.end())
+ auto it = func_addr_ids.find({pub.Segment, pub.Offset});
+ if (it != func_addr_ids.end())
m_func_full_names.Append(ConstString(pub.Name), it->second);
}
// Sort them before value searching is working properly.
- m_func_full_names.Sort();
+ m_func_full_names.Sort(std::less<uint32_t>());
m_func_full_names.SizeToFit();
- m_func_method_names.Sort();
+ m_func_method_names.Sort(std::less<uint32_t>());
m_func_method_names.SizeToFit();
- m_func_base_names.Sort();
+ m_func_base_names.Sort(std::less<uint32_t>());
m_func_base_names.SizeToFit();
+ m_global_variable_base_names.Sort(std::less<uint32_t>());
+ m_global_variable_base_names.SizeToFit();
}
void SymbolFileNativePDB::FindGlobalVariables(
ConstString name, const CompilerDeclContext &parent_decl_ctx,
uint32_t max_matches, VariableList &variables) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
- std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
- name.GetStringRef(), m_index->symrecords());
- for (const SymbolAndOffset &result : results) {
- switch (result.second.kind()) {
- case SymbolKind::S_GDATA32:
- case SymbolKind::S_LDATA32:
- case SymbolKind::S_GTHREAD32:
- case SymbolKind::S_LTHREAD32:
- case SymbolKind::S_CONSTANT: {
- PdbGlobalSymId global(result.first, false);
- if (VariableSP var = GetOrCreateGlobalVariable(global))
- variables.AddVariable(var);
- break;
- }
- default:
+ CacheGlobalBaseNames();
+
+ std::vector<uint32_t> results;
+ m_global_variable_base_names.GetValues(name, results);
+
+ size_t n_matches = 0;
+ for (uint32_t gid : results) {
+ PdbGlobalSymId global(gid, false);
+
+ if (parent_decl_ctx.IsValid() &&
+ GetDeclContextContainingUID(toOpaqueUid(global)) != parent_decl_ctx)
continue;
- }
+
+ VariableSP var = GetOrCreateGlobalVariable(global);
+ if (!var)
+ continue;
+ variables.AddVariable(var);
+
+ if (++n_matches >= max_matches)
+ break;
}
}
@@ -1783,7 +1829,7 @@ void SymbolFileNativePDB::FindFunctions(
name_type_mask & eFunctionNameTypeBase ||
name_type_mask & eFunctionNameTypeMethod))
return;
- CacheFunctionNames();
+ CacheGlobalBaseNames();
std::set<uint32_t> resolved_ids; // avoid duplicate lookups
auto resolve_from = [&](UniqueCStringMap<uint32_t> &Names) {
@@ -2426,7 +2472,7 @@ void SymbolFileNativePDB::BuildParentMap() {
// After calling Append(), the type-name map needs to be sorted again to be
// able to look up a type by its name.
- m_type_base_names.Sort();
+ m_type_base_names.Sort(std::less<uint32_t>());
// Now that we know the forward -> full mapping of all type indices, we can
// re-write all the indices. At the end of this process, we want a mapping
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index cfa00416d967..095b40c72c52 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -260,7 +260,10 @@ private:
std::vector<CompilerContext> GetContextForType(llvm::codeview::TypeIndex ti);
- void CacheFunctionNames();
+ /// Caches the basenames of symbols found in the globals stream.
+ ///
+ /// This includes functions and global variables
+ void CacheGlobalBaseNames();
void CacheUdtDeclarations();
llvm::Expected<Declaration> ResolveUdtDeclaration(PdbTypeSymId type_id);
@@ -306,6 +309,9 @@ private:
lldb_private::UniqueCStringMap<uint32_t> m_func_base_names;
/// method basename -> Global ID(s)
lldb_private::UniqueCStringMap<uint32_t> m_func_method_names;
+
+ /// global variable basename -> Global ID(s)
+ lldb_private::UniqueCStringMap<uint32_t> m_global_variable_base_names;
};
} // namespace npdb