auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (results && results->getChildCount()) {
while (auto result = results->getNext()) {
- auto cu_id = result->getCompilandId();
+ auto cu_id = GetCompilandId(*result);
// FIXME: We are not able to determine variable's compile unit.
if (cu_id == 0)
continue;
}
std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) {
- std::string decorated_name;
- auto vm_addr = pdb_data.getVirtualAddress();
- if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) {
- auto result_up =
- m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol);
- if (result_up) {
- while (auto symbol_up = result_up->getNext()) {
- if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) {
- decorated_name = symbol_up->getRawSymbol().getName();
- break;
- }
- }
- }
- }
- if (!decorated_name.empty())
- return decorated_name;
-
- return std::string();
+ // Cache public names at first
+ if (m_public_names.empty())
+ if (auto result_up =
+ m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol))
+ while (auto symbol_up = result_up->getNext())
+ if (auto addr = symbol_up->getRawSymbol().getVirtualAddress())
+ m_public_names[addr] = symbol_up->getRawSymbol().getName();
+
+ // Look up the name in the cache
+ return m_public_names.lookup(pdb_data.getVirtualAddress());
}
VariableSP SymbolFilePDB::ParseVariableForPDBData(
sc.module_sp = m_obj_file->GetModule();
lldbassert(sc.module_sp.get());
- sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get();
- // FIXME: We are not able to determine the compile unit.
- if (sc.comp_unit == nullptr)
- continue;
-
if (!name.GetStringRef().equals(
PDBASTParser::PDBNameDropScope(pdb_data->getName())))
continue;
+ sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
+ // FIXME: We are not able to determine the compile unit.
+ if (sc.comp_unit == nullptr)
+ continue;
+
auto actual_parent_decl_ctx =
GetDeclContextContainingUID(result->getSymIndexId());
if (actual_parent_decl_ctx != *parent_decl_ctx)
sc.module_sp = m_obj_file->GetModule();
lldbassert(sc.module_sp.get());
- sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get();
+ sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
// FIXME: We are not able to determine the compile unit.
if (sc.comp_unit == nullptr)
continue;
return false;
}
+
+uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) {
+ static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) {
+ return lhs < rhs.Offset;
+ };
+
+ // Cache section contributions
+ if (m_sec_contribs.empty()) {
+ if (auto SecContribs = m_session_up->getSectionContribs()) {
+ while (auto SectionContrib = SecContribs->getNext()) {
+ auto comp_id = SectionContrib->getCompilandId();
+ if (!comp_id)
+ continue;
+
+ auto sec = SectionContrib->getAddressSection();
+ auto &sec_cs = m_sec_contribs[sec];
+
+ auto offset = SectionContrib->getAddressOffset();
+ auto it =
+ std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper);
+
+ auto size = SectionContrib->getLength();
+ sec_cs.insert(it, {offset, size, comp_id});
+ }
+ }
+ }
+
+ // Check by line number
+ if (auto Lines = data.getLineNumbers()) {
+ if (auto FirstLine = Lines->getNext())
+ return FirstLine->getCompilandId();
+ }
+
+ // Retrieve section + offset
+ uint32_t DataSection = data.getAddressSection();
+ uint32_t DataOffset = data.getAddressOffset();
+ if (DataSection == 0) {
+ if (auto RVA = data.getRelativeVirtualAddress())
+ m_session_up->addressForRVA(RVA, DataSection, DataOffset);
+ }
+
+ if (DataSection) {
+ // Search by section contributions
+ auto &sec_cs = m_sec_contribs[DataSection];
+ auto it =
+ std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper);
+ if (it != sec_cs.begin()) {
+ --it;
+ if (DataOffset < it->Offset + it->Size)
+ return it->CompilandId;
+ }
+ } else {
+ // Search in lexical tree
+ auto LexParentId = data.getLexicalParentId();
+ while (auto LexParent = m_session_up->getSymbolById(LexParentId)) {
+ if (LexParent->getSymTag() == PDB_SymType::Exe)
+ break;
+ if (LexParent->getSymTag() == PDB_SymType::Compiland)
+ return LexParentId;
+ LexParentId = LexParent->getRawSymbol().getLexicalParentId();
+ }
+ }
+
+ return 0;
+}
const llvm::pdb::IPDBSession &GetPDBSession() const;
private:
+ struct SecContribInfo {
+ uint32_t Offset;
+ uint32_t Size;
+ uint32_t CompilandId;
+ };
+ using SecContribsMap = std::map<uint32_t, std::vector<SecContribInfo>>;
+
lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id,
uint32_t index = UINT32_MAX);
bool DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx);
+ uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data);
+
llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
llvm::DenseMap<uint32_t, lldb::VariableSP> m_variables;
+ llvm::DenseMap<uint64_t, std::string> m_public_names;
+
+ SecContribsMap m_sec_contribs;
std::vector<lldb::TypeSP> m_builtin_types;
std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;