@@ -1655,22 +1655,62 @@ void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) {
16551655 clang->GetNativePDBParser ()->Dump (s, filter);
16561656}
16571657
1658- void SymbolFileNativePDB::CacheFunctionNames () {
1659- if (!m_func_full_names.IsEmpty ())
1658+ void SymbolFileNativePDB::CacheGlobalBaseNames () {
1659+ if (!m_func_full_names.IsEmpty () || !m_global_variable_base_names. IsEmpty () )
16601660 return ;
16611661
16621662 // (segment, code offset) -> gid
1663- std::map<std::pair<uint16_t , uint32_t >, uint32_t > addr_ids ;
1663+ std::map<std::pair<uint16_t , uint32_t >, uint32_t > func_addr_ids ;
16641664
1665- // First, find all function references in the globals table.
1665+ // First, look through all items in the globals table.
16661666 for (const uint32_t gid : m_index->globals ().getGlobalsTable ()) {
1667- CVSymbol ref_sym = m_index->symrecords ().readRecord (gid);
1668- auto kind = ref_sym.kind ();
1667+ CVSymbol sym = m_index->symrecords ().readRecord (gid);
1668+ auto kind = sym.kind ();
1669+
1670+ // If this is a global variable, we only need to look at the name
1671+ llvm::StringRef name;
1672+ switch (kind) {
1673+ case SymbolKind::S_GDATA32:
1674+ case SymbolKind::S_LDATA32: {
1675+ DataSym data =
1676+ llvm::cantFail (SymbolDeserializer::deserializeAs<DataSym>(sym));
1677+ name = data.Name ;
1678+ break ;
1679+ }
1680+ case SymbolKind::S_GTHREAD32:
1681+ case SymbolKind::S_LTHREAD32: {
1682+ ThreadLocalDataSym data = llvm::cantFail (
1683+ SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym));
1684+ name = data.Name ;
1685+ break ;
1686+ }
1687+ case SymbolKind::S_CONSTANT: {
1688+ ConstantSym data =
1689+ llvm::cantFail (SymbolDeserializer::deserializeAs<ConstantSym>(sym));
1690+ name = data.Name ;
1691+ break ;
1692+ }
1693+ default :
1694+ break ;
1695+ }
1696+
1697+ if (!name.empty ()) {
1698+ llvm::StringRef base = MSVCUndecoratedNameParser::DropScope (name);
1699+ if (base.empty ())
1700+ base = name;
1701+
1702+ m_global_variable_base_names.Append (ConstString (base), gid);
1703+ continue ;
1704+ }
1705+
16691706 if (kind != S_PROCREF && kind != S_LPROCREF)
16701707 continue ;
16711708
1709+ // For functions, we need to follow the reference to the procedure and look
1710+ // at the type
1711+
16721712 ProcRefSym ref =
1673- llvm::cantFail (SymbolDeserializer::deserializeAs<ProcRefSym>(ref_sym ));
1713+ llvm::cantFail (SymbolDeserializer::deserializeAs<ProcRefSym>(sym ));
16741714 if (ref.Name .empty ())
16751715 continue ;
16761716
@@ -1694,7 +1734,7 @@ void SymbolFileNativePDB::CacheFunctionNames() {
16941734 // The function/procedure symbol only contains the demangled name.
16951735 // The mangled names are in the publics table. Save the address of this
16961736 // function to lookup the mangled name later.
1697- addr_ids .emplace (std::make_pair (proc.Segment , proc.CodeOffset ), gid);
1737+ func_addr_ids .emplace (std::make_pair (proc.Segment , proc.CodeOffset ), gid);
16981738
16991739 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope (proc.Name );
17001740 if (basename.empty ())
@@ -1729,8 +1769,8 @@ void SymbolFileNativePDB::CacheFunctionNames() {
17291769 continue ;
17301770
17311771 // Check if this symbol is for one of our functions.
1732- auto it = addr_ids .find ({pub.Segment , pub.Offset });
1733- if (it != addr_ids .end ())
1772+ auto it = func_addr_ids .find ({pub.Segment , pub.Offset });
1773+ if (it != func_addr_ids .end ())
17341774 m_func_full_names.Append (ConstString (pub.Name ), it->second );
17351775 }
17361776
@@ -1741,31 +1781,35 @@ void SymbolFileNativePDB::CacheFunctionNames() {
17411781 m_func_method_names.SizeToFit ();
17421782 m_func_base_names.Sort (std::less<uint32_t >());
17431783 m_func_base_names.SizeToFit ();
1784+ m_global_variable_base_names.Sort (std::less<uint32_t >());
1785+ m_global_variable_base_names.SizeToFit ();
17441786}
17451787
17461788void SymbolFileNativePDB::FindGlobalVariables (
17471789 ConstString name, const CompilerDeclContext &parent_decl_ctx,
17481790 uint32_t max_matches, VariableList &variables) {
17491791 std::lock_guard<std::recursive_mutex> guard (GetModuleMutex ());
1750- using SymbolAndOffset = std::pair<uint32_t , llvm::codeview::CVSymbol>;
17511792
1752- std::vector<SymbolAndOffset> results = m_index->globals ().findRecordsByName (
1753- name.GetStringRef (), m_index->symrecords ());
1754- for (const SymbolAndOffset &result : results) {
1755- switch (result.second .kind ()) {
1756- case SymbolKind::S_GDATA32:
1757- case SymbolKind::S_LDATA32:
1758- case SymbolKind::S_GTHREAD32:
1759- case SymbolKind::S_LTHREAD32:
1760- case SymbolKind::S_CONSTANT: {
1761- PdbGlobalSymId global (result.first , false );
1762- if (VariableSP var = GetOrCreateGlobalVariable (global))
1763- variables.AddVariable (var);
1764- break ;
1765- }
1766- default :
1793+ CacheGlobalBaseNames ();
1794+
1795+ std::vector<uint32_t > results;
1796+ m_global_variable_base_names.GetValues (name, results);
1797+
1798+ size_t n_matches = 0 ;
1799+ for (uint32_t gid : results) {
1800+ PdbGlobalSymId global (gid, false );
1801+
1802+ if (parent_decl_ctx.IsValid () &&
1803+ GetDeclContextContainingUID (toOpaqueUid (global)) != parent_decl_ctx)
17671804 continue ;
1768- }
1805+
1806+ VariableSP var = GetOrCreateGlobalVariable (global);
1807+ if (!var)
1808+ continue ;
1809+ variables.AddVariable (var);
1810+
1811+ if (++n_matches >= max_matches)
1812+ break ;
17691813 }
17701814}
17711815
@@ -1783,7 +1827,7 @@ void SymbolFileNativePDB::FindFunctions(
17831827 name_type_mask & eFunctionNameTypeBase ||
17841828 name_type_mask & eFunctionNameTypeMethod))
17851829 return ;
1786- CacheFunctionNames ();
1830+ CacheGlobalBaseNames ();
17871831
17881832 std::set<uint32_t > resolved_ids; // avoid duplicate lookups
17891833 auto resolve_from = [&](UniqueCStringMap<uint32_t > &Names) {
0 commit comments