14bb0738eSEd Maste //===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===//
24bb0738eSEd Maste //
34bb0738eSEd Maste //                     The LLVM Compiler Infrastructure
44bb0738eSEd Maste //
54bb0738eSEd Maste // This file is distributed under the University of Illinois Open Source
64bb0738eSEd Maste // License. See LICENSE.TXT for details.
74bb0738eSEd Maste //
84bb0738eSEd Maste //===----------------------------------------------------------------------===//
94bb0738eSEd Maste 
104bb0738eSEd Maste #include "SymbolFilePDB.h"
114bb0738eSEd Maste 
12*b5893f02SDimitry Andric #include "PDBASTParser.h"
13*b5893f02SDimitry Andric #include "PDBLocationToDWARFExpression.h"
14*b5893f02SDimitry Andric 
154bb0738eSEd Maste #include "clang/Lex/Lexer.h"
164bb0738eSEd Maste 
174bb0738eSEd Maste #include "lldb/Core/Module.h"
184bb0738eSEd Maste #include "lldb/Core/PluginManager.h"
194bb0738eSEd Maste #include "lldb/Symbol/ClangASTContext.h"
204bb0738eSEd Maste #include "lldb/Symbol/CompileUnit.h"
214bb0738eSEd Maste #include "lldb/Symbol/LineTable.h"
224bb0738eSEd Maste #include "lldb/Symbol/ObjectFile.h"
234bb0738eSEd Maste #include "lldb/Symbol/SymbolContext.h"
244ba319b5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h"
254ba319b5SDimitry Andric #include "lldb/Symbol/TypeList.h"
264bb0738eSEd Maste #include "lldb/Symbol/TypeMap.h"
274ba319b5SDimitry Andric #include "lldb/Symbol/Variable.h"
2838638513SDimitry Andric #include "lldb/Utility/RegularExpression.h"
294bb0738eSEd Maste 
304bb0738eSEd Maste #include "llvm/DebugInfo/PDB/GenericError.h"
3138638513SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBDataStream.h"
324bb0738eSEd Maste #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
334bb0738eSEd Maste #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
344ba319b5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
354bb0738eSEd Maste #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
3638638513SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBTable.h"
374bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbol.h"
384ba319b5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
394bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
404bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
4138638513SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
424bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
434bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
444bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
454bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
464ba319b5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
474bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
484bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
494bb0738eSEd Maste #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
504bb0738eSEd Maste 
514ba319b5SDimitry Andric #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
52*b5893f02SDimitry Andric #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
53*b5893f02SDimitry Andric #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h"
544bb0738eSEd Maste 
554bb0738eSEd Maste #include <regex>
564bb0738eSEd Maste 
574ba319b5SDimitry Andric using namespace lldb;
584bb0738eSEd Maste using namespace lldb_private;
594bb0738eSEd Maste using namespace llvm::pdb;
604bb0738eSEd Maste 
61435933ddSDimitry Andric namespace {
TranslateLanguage(PDB_Lang lang)62435933ddSDimitry Andric lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
63435933ddSDimitry Andric   switch (lang) {
644bb0738eSEd Maste   case PDB_Lang::Cpp:
654bb0738eSEd Maste     return lldb::LanguageType::eLanguageTypeC_plus_plus;
664bb0738eSEd Maste   case PDB_Lang::C:
674bb0738eSEd Maste     return lldb::LanguageType::eLanguageTypeC;
684bb0738eSEd Maste   default:
694bb0738eSEd Maste     return lldb::LanguageType::eLanguageTypeUnknown;
704bb0738eSEd Maste   }
714bb0738eSEd Maste }
724bb0738eSEd Maste 
ShouldAddLine(uint32_t requested_line,uint32_t actual_line,uint32_t addr_length)73435933ddSDimitry Andric bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
74435933ddSDimitry Andric                    uint32_t addr_length) {
75435933ddSDimitry Andric   return ((requested_line == 0 || actual_line == requested_line) &&
76435933ddSDimitry Andric           addr_length > 0);
774bb0738eSEd Maste }
784ba319b5SDimitry Andric } // namespace
794bb0738eSEd Maste 
ShouldUseNativeReader()80*b5893f02SDimitry Andric static bool ShouldUseNativeReader() {
81*b5893f02SDimitry Andric #if defined(_WIN32)
82*b5893f02SDimitry Andric   llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER");
83*b5893f02SDimitry Andric   return use_native.equals_lower("on") || use_native.equals_lower("yes") ||
84*b5893f02SDimitry Andric          use_native.equals_lower("1") || use_native.equals_lower("true");
85*b5893f02SDimitry Andric #else
86*b5893f02SDimitry Andric   return true;
87*b5893f02SDimitry Andric #endif
88*b5893f02SDimitry Andric }
89*b5893f02SDimitry Andric 
Initialize()90435933ddSDimitry Andric void SymbolFilePDB::Initialize() {
91*b5893f02SDimitry Andric   if (ShouldUseNativeReader()) {
92*b5893f02SDimitry Andric     npdb::SymbolFileNativePDB::Initialize();
93*b5893f02SDimitry Andric   } else {
94435933ddSDimitry Andric     PluginManager::RegisterPlugin(GetPluginNameStatic(),
95435933ddSDimitry Andric                                   GetPluginDescriptionStatic(), CreateInstance,
964bb0738eSEd Maste                                   DebuggerInitialize);
974bb0738eSEd Maste   }
98*b5893f02SDimitry Andric }
994bb0738eSEd Maste 
Terminate()100435933ddSDimitry Andric void SymbolFilePDB::Terminate() {
101*b5893f02SDimitry Andric   if (ShouldUseNativeReader()) {
102*b5893f02SDimitry Andric     npdb::SymbolFileNativePDB::Terminate();
103*b5893f02SDimitry Andric   } else {
1044bb0738eSEd Maste     PluginManager::UnregisterPlugin(CreateInstance);
1054bb0738eSEd Maste   }
106*b5893f02SDimitry Andric }
1074bb0738eSEd Maste 
DebuggerInitialize(lldb_private::Debugger & debugger)108435933ddSDimitry Andric void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
1094bb0738eSEd Maste 
GetPluginNameStatic()110435933ddSDimitry Andric lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() {
1114bb0738eSEd Maste   static ConstString g_name("pdb");
1124bb0738eSEd Maste   return g_name;
1134bb0738eSEd Maste }
1144bb0738eSEd Maste 
GetPluginDescriptionStatic()115435933ddSDimitry Andric const char *SymbolFilePDB::GetPluginDescriptionStatic() {
1164bb0738eSEd Maste   return "Microsoft PDB debug symbol file reader.";
1174bb0738eSEd Maste }
1184bb0738eSEd Maste 
1194bb0738eSEd Maste lldb_private::SymbolFile *
CreateInstance(lldb_private::ObjectFile * obj_file)120435933ddSDimitry Andric SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
1214bb0738eSEd Maste   return new SymbolFilePDB(obj_file);
1224bb0738eSEd Maste }
1234bb0738eSEd Maste 
SymbolFilePDB(lldb_private::ObjectFile * object_file)1244bb0738eSEd Maste SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file)
1254ba319b5SDimitry Andric     : SymbolFile(object_file), m_session_up(), m_global_scope_up(),
1264ba319b5SDimitry Andric       m_cached_compile_unit_count(0), m_tu_decl_ctx_up() {}
1274bb0738eSEd Maste 
~SymbolFilePDB()128435933ddSDimitry Andric SymbolFilePDB::~SymbolFilePDB() {}
1294bb0738eSEd Maste 
CalculateAbilities()130435933ddSDimitry Andric uint32_t SymbolFilePDB::CalculateAbilities() {
13138638513SDimitry Andric   uint32_t abilities = 0;
13238638513SDimitry Andric   if (!m_obj_file)
13338638513SDimitry Andric     return 0;
13438638513SDimitry Andric 
135435933ddSDimitry Andric   if (!m_session_up) {
1364bb0738eSEd Maste     // Lazily load and match the PDB file, but only do this once.
1374bb0738eSEd Maste     std::string exePath = m_obj_file->GetFileSpec().GetPath();
138435933ddSDimitry Andric     auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
139435933ddSDimitry Andric                                 m_session_up);
140435933ddSDimitry Andric     if (error) {
1414bb0738eSEd Maste       llvm::consumeError(std::move(error));
14238638513SDimitry Andric       auto module_sp = m_obj_file->GetModule();
14338638513SDimitry Andric       if (!module_sp)
14438638513SDimitry Andric         return 0;
14538638513SDimitry Andric       // See if any symbol file is specified through `--symfile` option.
14638638513SDimitry Andric       FileSpec symfile = module_sp->GetSymbolFileFileSpec();
14738638513SDimitry Andric       if (!symfile)
14838638513SDimitry Andric         return 0;
14938638513SDimitry Andric       error = loadDataForPDB(PDB_ReaderType::DIA,
1504ba319b5SDimitry Andric                              llvm::StringRef(symfile.GetPath()), m_session_up);
15138638513SDimitry Andric       if (error) {
15238638513SDimitry Andric         llvm::consumeError(std::move(error));
1534bb0738eSEd Maste         return 0;
1544bb0738eSEd Maste       }
1554bb0738eSEd Maste     }
15638638513SDimitry Andric   }
1574ba319b5SDimitry Andric   if (!m_session_up)
15838638513SDimitry Andric     return 0;
15938638513SDimitry Andric 
16038638513SDimitry Andric   auto enum_tables_up = m_session_up->getEnumTables();
16138638513SDimitry Andric   if (!enum_tables_up)
16238638513SDimitry Andric     return 0;
16338638513SDimitry Andric   while (auto table_up = enum_tables_up->getNext()) {
16438638513SDimitry Andric     if (table_up->getItemCount() == 0)
16538638513SDimitry Andric       continue;
16638638513SDimitry Andric     auto type = table_up->getTableType();
16738638513SDimitry Andric     switch (type) {
16838638513SDimitry Andric     case PDB_TableType::Symbols:
16938638513SDimitry Andric       // This table represents a store of symbols with types listed in
17038638513SDimitry Andric       // PDBSym_Type
1714ba319b5SDimitry Andric       abilities |= (CompileUnits | Functions | Blocks | GlobalVariables |
1724ba319b5SDimitry Andric                     LocalVariables | VariableTypes);
17338638513SDimitry Andric       break;
17438638513SDimitry Andric     case PDB_TableType::LineNumbers:
17538638513SDimitry Andric       abilities |= LineTables;
17638638513SDimitry Andric       break;
1774ba319b5SDimitry Andric     default:
1784ba319b5SDimitry Andric       break;
17938638513SDimitry Andric     }
18038638513SDimitry Andric   }
18138638513SDimitry Andric   return abilities;
1824bb0738eSEd Maste }
1834bb0738eSEd Maste 
InitializeObject()184435933ddSDimitry Andric void SymbolFilePDB::InitializeObject() {
1854bb0738eSEd Maste   lldb::addr_t obj_load_address = m_obj_file->GetFileOffset();
1864ba319b5SDimitry Andric   lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);
1874bb0738eSEd Maste   m_session_up->setLoadAddress(obj_load_address);
1884ba319b5SDimitry Andric   if (!m_global_scope_up)
1894ba319b5SDimitry Andric     m_global_scope_up = m_session_up->getGlobalScope();
1904ba319b5SDimitry Andric   lldbassert(m_global_scope_up.get());
1914bb0738eSEd Maste 
192435933ddSDimitry Andric   TypeSystem *type_system =
193435933ddSDimitry Andric       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
194435933ddSDimitry Andric   ClangASTContext *clang_type_system =
195435933ddSDimitry Andric       llvm::dyn_cast_or_null<ClangASTContext>(type_system);
1964ba319b5SDimitry Andric   lldbassert(clang_type_system);
197435933ddSDimitry Andric   m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>(
198435933ddSDimitry Andric       type_system, clang_type_system->GetTranslationUnitDecl());
1994bb0738eSEd Maste }
2004bb0738eSEd Maste 
GetNumCompileUnits()201435933ddSDimitry Andric uint32_t SymbolFilePDB::GetNumCompileUnits() {
202435933ddSDimitry Andric   if (m_cached_compile_unit_count == 0) {
2034ba319b5SDimitry Andric     auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
2044ba319b5SDimitry Andric     if (!compilands)
2054ba319b5SDimitry Andric       return 0;
2064ba319b5SDimitry Andric 
2074ba319b5SDimitry Andric     // The linker could link *.dll (compiland language = LINK), or import
2084ba319b5SDimitry Andric     // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
2094ba319b5SDimitry Andric     // found as a child of the global scope (PDB executable). Usually, such
2104ba319b5SDimitry Andric     // compilands contain `thunk` symbols in which we are not interested for
2114ba319b5SDimitry Andric     // now. However we still count them in the compiland list. If we perform
2124ba319b5SDimitry Andric     // any compiland related activity, like finding symbols through
2134ba319b5SDimitry Andric     // llvm::pdb::IPDBSession methods, such compilands will all be searched
2144ba319b5SDimitry Andric     // automatically no matter whether we include them or not.
2154bb0738eSEd Maste     m_cached_compile_unit_count = compilands->getChildCount();
2164bb0738eSEd Maste 
217435933ddSDimitry Andric     // The linker can inject an additional "dummy" compilation unit into the
218f678e45dSDimitry Andric     // PDB. Ignore this special compile unit for our purposes, if it is there.
219f678e45dSDimitry Andric     // It is always the last one.
2204ba319b5SDimitry Andric     auto last_compiland_up =
2214ba319b5SDimitry Andric         compilands->getChildAtIndex(m_cached_compile_unit_count - 1);
2224ba319b5SDimitry Andric     lldbassert(last_compiland_up.get());
2234ba319b5SDimitry Andric     std::string name = last_compiland_up->getName();
2244bb0738eSEd Maste     if (name == "* Linker *")
2254bb0738eSEd Maste       --m_cached_compile_unit_count;
2264bb0738eSEd Maste   }
2274bb0738eSEd Maste   return m_cached_compile_unit_count;
2284bb0738eSEd Maste }
2294bb0738eSEd Maste 
GetCompileUnitIndex(const llvm::pdb::PDBSymbolCompiland & pdb_compiland,uint32_t & index)2304ba319b5SDimitry Andric void SymbolFilePDB::GetCompileUnitIndex(
2314ba319b5SDimitry Andric     const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index) {
2324ba319b5SDimitry Andric   auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
2334ba319b5SDimitry Andric   if (!results_up)
2344ba319b5SDimitry Andric     return;
2354ba319b5SDimitry Andric   auto uid = pdb_compiland.getSymIndexId();
2364ba319b5SDimitry Andric   for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
2374ba319b5SDimitry Andric     auto compiland_up = results_up->getChildAtIndex(cu_idx);
2384ba319b5SDimitry Andric     if (!compiland_up)
2394ba319b5SDimitry Andric       continue;
2404ba319b5SDimitry Andric     if (compiland_up->getSymIndexId() == uid) {
2414ba319b5SDimitry Andric       index = cu_idx;
2424ba319b5SDimitry Andric       return;
2434ba319b5SDimitry Andric     }
2444ba319b5SDimitry Andric   }
2454ba319b5SDimitry Andric   index = UINT32_MAX;
2464ba319b5SDimitry Andric   return;
2474ba319b5SDimitry Andric }
2484ba319b5SDimitry Andric 
2494ba319b5SDimitry Andric std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
GetPDBCompilandByUID(uint32_t uid)2504ba319b5SDimitry Andric SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) {
2514ba319b5SDimitry Andric   return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid);
2524ba319b5SDimitry Andric }
2534ba319b5SDimitry Andric 
ParseCompileUnitAtIndex(uint32_t index)254435933ddSDimitry Andric lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
2554ba319b5SDimitry Andric   if (index >= GetNumCompileUnits())
2564ba319b5SDimitry Andric     return CompUnitSP();
2574bb0738eSEd Maste 
2584ba319b5SDimitry Andric   // Assuming we always retrieve same compilands listed in same order through
2594ba319b5SDimitry Andric   // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a
2604ba319b5SDimitry Andric   // compile unit makes no sense.
2614ba319b5SDimitry Andric   auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
2624ba319b5SDimitry Andric   if (!results)
2634ba319b5SDimitry Andric     return CompUnitSP();
2644ba319b5SDimitry Andric   auto compiland_up = results->getChildAtIndex(index);
2654ba319b5SDimitry Andric   if (!compiland_up)
2664ba319b5SDimitry Andric     return CompUnitSP();
2674ba319b5SDimitry Andric   return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);
2684bb0738eSEd Maste }
2694bb0738eSEd Maste 
ParseLanguage(CompileUnit & comp_unit)270*b5893f02SDimitry Andric lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) {
271*b5893f02SDimitry Andric   auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
2724ba319b5SDimitry Andric   if (!compiland_up)
2734bb0738eSEd Maste     return lldb::eLanguageTypeUnknown;
2744ba319b5SDimitry Andric   auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
2754bb0738eSEd Maste   if (!details)
2764bb0738eSEd Maste     return lldb::eLanguageTypeUnknown;
2774bb0738eSEd Maste   return TranslateLanguage(details->getLanguage());
2784bb0738eSEd Maste }
2794bb0738eSEd Maste 
280*b5893f02SDimitry Andric lldb_private::Function *
ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc & pdb_func,CompileUnit & comp_unit)281*b5893f02SDimitry Andric SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
282*b5893f02SDimitry Andric                                                   CompileUnit &comp_unit) {
283*b5893f02SDimitry Andric   if (FunctionSP result = comp_unit.FindFunctionByUID(pdb_func.getSymIndexId()))
284*b5893f02SDimitry Andric     return result.get();
2854ba319b5SDimitry Andric 
2864ba319b5SDimitry Andric   auto file_vm_addr = pdb_func.getVirtualAddress();
2874ba319b5SDimitry Andric   if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
2884ba319b5SDimitry Andric     return nullptr;
2894ba319b5SDimitry Andric 
2904ba319b5SDimitry Andric   auto func_length = pdb_func.getLength();
2914ba319b5SDimitry Andric   AddressRange func_range =
292*b5893f02SDimitry Andric       AddressRange(file_vm_addr, func_length,
293*b5893f02SDimitry Andric                    GetObjectFile()->GetModule()->GetSectionList());
2944ba319b5SDimitry Andric   if (!func_range.GetBaseAddress().IsValid())
2954ba319b5SDimitry Andric     return nullptr;
2964ba319b5SDimitry Andric 
2974ba319b5SDimitry Andric   lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId());
2984ba319b5SDimitry Andric   if (!func_type)
2994ba319b5SDimitry Andric     return nullptr;
3004ba319b5SDimitry Andric 
3014ba319b5SDimitry Andric   user_id_t func_type_uid = pdb_func.getSignatureId();
3024ba319b5SDimitry Andric 
3034ba319b5SDimitry Andric   Mangled mangled = GetMangledForPDBFunc(pdb_func);
3044ba319b5SDimitry Andric 
3054ba319b5SDimitry Andric   FunctionSP func_sp =
306*b5893f02SDimitry Andric       std::make_shared<Function>(&comp_unit, pdb_func.getSymIndexId(),
3074ba319b5SDimitry Andric                                  func_type_uid, mangled, func_type, func_range);
3084ba319b5SDimitry Andric 
309*b5893f02SDimitry Andric   comp_unit.AddFunction(func_sp);
310*b5893f02SDimitry Andric 
311*b5893f02SDimitry Andric   TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
312*b5893f02SDimitry Andric   if (!type_system)
313*b5893f02SDimitry Andric     return nullptr;
314*b5893f02SDimitry Andric   ClangASTContext *clang_type_system =
315*b5893f02SDimitry Andric     llvm::dyn_cast_or_null<ClangASTContext>(type_system);
316*b5893f02SDimitry Andric   if (!clang_type_system)
317*b5893f02SDimitry Andric     return nullptr;
318*b5893f02SDimitry Andric   clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
319*b5893f02SDimitry Andric 
3204ba319b5SDimitry Andric   return func_sp.get();
3214ba319b5SDimitry Andric }
3224ba319b5SDimitry Andric 
ParseFunctions(CompileUnit & comp_unit)323*b5893f02SDimitry Andric size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
3244ba319b5SDimitry Andric   size_t func_added = 0;
325*b5893f02SDimitry Andric   auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
3264ba319b5SDimitry Andric   if (!compiland_up)
3274ba319b5SDimitry Andric     return 0;
3284ba319b5SDimitry Andric   auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();
3294ba319b5SDimitry Andric   if (!results_up)
3304ba319b5SDimitry Andric     return 0;
3314ba319b5SDimitry Andric   while (auto pdb_func_up = results_up->getNext()) {
332*b5893f02SDimitry Andric     auto func_sp = comp_unit.FindFunctionByUID(pdb_func_up->getSymIndexId());
3334ba319b5SDimitry Andric     if (!func_sp) {
334*b5893f02SDimitry Andric       if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, comp_unit))
3354ba319b5SDimitry Andric         ++func_added;
3364ba319b5SDimitry Andric     }
3374ba319b5SDimitry Andric   }
3384ba319b5SDimitry Andric   return func_added;
3394bb0738eSEd Maste }
3404bb0738eSEd Maste 
ParseLineTable(CompileUnit & comp_unit)341*b5893f02SDimitry Andric bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) {
342*b5893f02SDimitry Andric   if (comp_unit.GetLineTable())
3434ba319b5SDimitry Andric     return true;
344*b5893f02SDimitry Andric   return ParseCompileUnitLineTable(comp_unit, 0);
3454bb0738eSEd Maste }
3464bb0738eSEd Maste 
ParseDebugMacros(CompileUnit & comp_unit)347*b5893f02SDimitry Andric bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) {
3484bb0738eSEd Maste   // PDB doesn't contain information about macros
3494bb0738eSEd Maste   return false;
3504bb0738eSEd Maste }
3514bb0738eSEd Maste 
ParseSupportFiles(CompileUnit & comp_unit,lldb_private::FileSpecList & support_files)352*b5893f02SDimitry Andric bool SymbolFilePDB::ParseSupportFiles(
353*b5893f02SDimitry Andric     CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) {
3544bb0738eSEd Maste 
355435933ddSDimitry Andric   // In theory this is unnecessary work for us, because all of this information
356f678e45dSDimitry Andric   // is easily (and quickly) accessible from DebugInfoPDB, so caching it a
357f678e45dSDimitry Andric   // second time seems like a waste.  Unfortunately, there's no good way around
358f678e45dSDimitry Andric   // this short of a moderate refactor since SymbolVendor depends on being able
359f678e45dSDimitry Andric   // to cache this list.
360*b5893f02SDimitry Andric   auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
3614ba319b5SDimitry Andric   if (!compiland_up)
3624bb0738eSEd Maste     return false;
3634ba319b5SDimitry Andric   auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
3644bb0738eSEd Maste   if (!files || files->getChildCount() == 0)
3654bb0738eSEd Maste     return false;
3664bb0738eSEd Maste 
367435933ddSDimitry Andric   while (auto file = files->getNext()) {
368*b5893f02SDimitry Andric     FileSpec spec(file->getFileName(), FileSpec::Style::windows);
3694ba319b5SDimitry Andric     support_files.AppendIfUnique(spec);
3704bb0738eSEd Maste   }
3714ba319b5SDimitry Andric 
3724ba319b5SDimitry Andric   // LLDB uses the DWARF-like file numeration (one based),
3734ba319b5SDimitry Andric   // the zeroth file is the compile unit itself
374*b5893f02SDimitry Andric   support_files.Insert(0, comp_unit);
3754ba319b5SDimitry Andric 
3764bb0738eSEd Maste   return true;
3774bb0738eSEd Maste }
3784bb0738eSEd Maste 
ParseImportedModules(const lldb_private::SymbolContext & sc,std::vector<lldb_private::ConstString> & imported_modules)379435933ddSDimitry Andric bool SymbolFilePDB::ParseImportedModules(
380435933ddSDimitry Andric     const lldb_private::SymbolContext &sc,
381435933ddSDimitry Andric     std::vector<lldb_private::ConstString> &imported_modules) {
3824bb0738eSEd Maste   // PDB does not yet support module debug info
3834bb0738eSEd Maste   return false;
3844bb0738eSEd Maste }
3854bb0738eSEd Maste 
ParseFunctionBlocksForPDBSymbol(uint64_t func_file_vm_addr,const llvm::pdb::PDBSymbol * pdb_symbol,lldb_private::Block * parent_block,bool is_top_parent)3864ba319b5SDimitry Andric static size_t ParseFunctionBlocksForPDBSymbol(
387*b5893f02SDimitry Andric     uint64_t func_file_vm_addr, const llvm::pdb::PDBSymbol *pdb_symbol,
388*b5893f02SDimitry Andric     lldb_private::Block *parent_block, bool is_top_parent) {
3894ba319b5SDimitry Andric   assert(pdb_symbol && parent_block);
3904ba319b5SDimitry Andric 
3914ba319b5SDimitry Andric   size_t num_added = 0;
3924ba319b5SDimitry Andric   switch (pdb_symbol->getSymTag()) {
3934ba319b5SDimitry Andric   case PDB_SymType::Block:
3944ba319b5SDimitry Andric   case PDB_SymType::Function: {
3954ba319b5SDimitry Andric     Block *block = nullptr;
3964ba319b5SDimitry Andric     auto &raw_sym = pdb_symbol->getRawSymbol();
3974ba319b5SDimitry Andric     if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) {
3984ba319b5SDimitry Andric       if (pdb_func->hasNoInlineAttribute())
3994ba319b5SDimitry Andric         break;
4004ba319b5SDimitry Andric       if (is_top_parent)
4014ba319b5SDimitry Andric         block = parent_block;
4024ba319b5SDimitry Andric       else
4034ba319b5SDimitry Andric         break;
4044ba319b5SDimitry Andric     } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) {
4054ba319b5SDimitry Andric       auto uid = pdb_symbol->getSymIndexId();
4064ba319b5SDimitry Andric       if (parent_block->FindBlockByID(uid))
4074ba319b5SDimitry Andric         break;
4084ba319b5SDimitry Andric       if (raw_sym.getVirtualAddress() < func_file_vm_addr)
4094ba319b5SDimitry Andric         break;
4104ba319b5SDimitry Andric 
4114ba319b5SDimitry Andric       auto block_sp = std::make_shared<Block>(pdb_symbol->getSymIndexId());
4124ba319b5SDimitry Andric       parent_block->AddChild(block_sp);
4134ba319b5SDimitry Andric       block = block_sp.get();
4144ba319b5SDimitry Andric     } else
4154ba319b5SDimitry Andric       llvm_unreachable("Unexpected PDB symbol!");
4164ba319b5SDimitry Andric 
4174ba319b5SDimitry Andric     block->AddRange(Block::Range(
4184ba319b5SDimitry Andric         raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength()));
4194ba319b5SDimitry Andric     block->FinalizeRanges();
4204ba319b5SDimitry Andric     ++num_added;
4214ba319b5SDimitry Andric 
4224ba319b5SDimitry Andric     auto results_up = pdb_symbol->findAllChildren();
4234ba319b5SDimitry Andric     if (!results_up)
4244ba319b5SDimitry Andric       break;
4254ba319b5SDimitry Andric     while (auto symbol_up = results_up->getNext()) {
4264ba319b5SDimitry Andric       num_added += ParseFunctionBlocksForPDBSymbol(
427*b5893f02SDimitry Andric           func_file_vm_addr, symbol_up.get(), block, false);
4284ba319b5SDimitry Andric     }
4294ba319b5SDimitry Andric   } break;
4304ba319b5SDimitry Andric   default:
4314ba319b5SDimitry Andric     break;
4324ba319b5SDimitry Andric   }
4334ba319b5SDimitry Andric   return num_added;
4344ba319b5SDimitry Andric }
4354ba319b5SDimitry Andric 
ParseBlocksRecursive(Function & func)436*b5893f02SDimitry Andric size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
4374ba319b5SDimitry Andric   size_t num_added = 0;
438*b5893f02SDimitry Andric   auto uid = func.GetID();
4394ba319b5SDimitry Andric   auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
4404ba319b5SDimitry Andric   if (!pdb_func_up)
4414ba319b5SDimitry Andric     return 0;
442*b5893f02SDimitry Andric   Block &parent_block = func.GetBlock(false);
443*b5893f02SDimitry Andric   num_added = ParseFunctionBlocksForPDBSymbol(
444*b5893f02SDimitry Andric       pdb_func_up->getVirtualAddress(), pdb_func_up.get(), &parent_block, true);
4454ba319b5SDimitry Andric   return num_added;
446435933ddSDimitry Andric }
447435933ddSDimitry Andric 
ParseTypes(CompileUnit & comp_unit)448*b5893f02SDimitry Andric size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
4494ba319b5SDimitry Andric 
4504ba319b5SDimitry Andric   size_t num_added = 0;
451*b5893f02SDimitry Andric   auto compiland = GetPDBCompilandByUID(comp_unit.GetID());
4524ba319b5SDimitry Andric   if (!compiland)
4534ba319b5SDimitry Andric     return 0;
4544ba319b5SDimitry Andric 
4554ba319b5SDimitry Andric   auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) {
4564ba319b5SDimitry Andric     std::unique_ptr<IPDBEnumSymbols> results;
4574ba319b5SDimitry Andric     PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
4584ba319b5SDimitry Andric                                     PDB_SymType::UDT};
4594ba319b5SDimitry Andric     for (auto tag : tags_to_search) {
4604ba319b5SDimitry Andric       results = raw_sym.findAllChildren(tag);
4614ba319b5SDimitry Andric       if (!results || results->getChildCount() == 0)
4624ba319b5SDimitry Andric         continue;
4634ba319b5SDimitry Andric       while (auto symbol = results->getNext()) {
4644ba319b5SDimitry Andric         switch (symbol->getSymTag()) {
4654ba319b5SDimitry Andric         case PDB_SymType::Enum:
4664ba319b5SDimitry Andric         case PDB_SymType::UDT:
4674ba319b5SDimitry Andric         case PDB_SymType::Typedef:
4684ba319b5SDimitry Andric           break;
4694ba319b5SDimitry Andric         default:
4704ba319b5SDimitry Andric           continue;
4714ba319b5SDimitry Andric         }
4724ba319b5SDimitry Andric 
4734ba319b5SDimitry Andric         // This should cause the type to get cached and stored in the `m_types`
4744ba319b5SDimitry Andric         // lookup.
475*b5893f02SDimitry Andric         if (auto type = ResolveTypeUID(symbol->getSymIndexId())) {
476*b5893f02SDimitry Andric           // Resolve the type completely to avoid a completion
477*b5893f02SDimitry Andric           // (and so a list change, which causes an iterators invalidation)
478*b5893f02SDimitry Andric           // during a TypeList dumping
479*b5893f02SDimitry Andric           type->GetFullCompilerType();
4804ba319b5SDimitry Andric           ++num_added;
4814ba319b5SDimitry Andric         }
4824ba319b5SDimitry Andric       }
483*b5893f02SDimitry Andric     }
4844ba319b5SDimitry Andric   };
4854ba319b5SDimitry Andric 
4864ba319b5SDimitry Andric   ParseTypesByTagFn(*compiland);
4874ba319b5SDimitry Andric 
4884ba319b5SDimitry Andric   // Also parse global types particularly coming from this compiland.
4894ba319b5SDimitry Andric   // Unfortunately, PDB has no compiland information for each global type. We
4904ba319b5SDimitry Andric   // have to parse them all. But ensure we only do this once.
4914ba319b5SDimitry Andric   static bool parse_all_global_types = false;
4924ba319b5SDimitry Andric   if (!parse_all_global_types) {
4934ba319b5SDimitry Andric     ParseTypesByTagFn(*m_global_scope_up);
4944ba319b5SDimitry Andric     parse_all_global_types = true;
4954ba319b5SDimitry Andric   }
4964ba319b5SDimitry Andric   return num_added;
4974bb0738eSEd Maste }
4984bb0738eSEd Maste 
4994bb0738eSEd Maste size_t
ParseVariablesForContext(const lldb_private::SymbolContext & sc)500435933ddSDimitry Andric SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
5014ba319b5SDimitry Andric   if (!sc.comp_unit)
5024ba319b5SDimitry Andric     return 0;
5034ba319b5SDimitry Andric 
5044ba319b5SDimitry Andric   size_t num_added = 0;
5054ba319b5SDimitry Andric   if (sc.function) {
5064ba319b5SDimitry Andric     auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(
5074ba319b5SDimitry Andric         sc.function->GetID());
5084ba319b5SDimitry Andric     if (!pdb_func)
5094ba319b5SDimitry Andric       return 0;
5104ba319b5SDimitry Andric 
5114ba319b5SDimitry Andric     num_added += ParseVariables(sc, *pdb_func);
5124ba319b5SDimitry Andric     sc.function->GetBlock(false).SetDidParseVariables(true, true);
5134ba319b5SDimitry Andric   } else if (sc.comp_unit) {
5144ba319b5SDimitry Andric     auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
5154ba319b5SDimitry Andric     if (!compiland)
5164ba319b5SDimitry Andric       return 0;
5174ba319b5SDimitry Andric 
5184ba319b5SDimitry Andric     if (sc.comp_unit->GetVariableList(false))
5194ba319b5SDimitry Andric       return 0;
5204ba319b5SDimitry Andric 
5214ba319b5SDimitry Andric     auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
5224ba319b5SDimitry Andric     if (results && results->getChildCount()) {
5234ba319b5SDimitry Andric       while (auto result = results->getNext()) {
524*b5893f02SDimitry Andric         auto cu_id = GetCompilandId(*result);
5254ba319b5SDimitry Andric         // FIXME: We are not able to determine variable's compile unit.
5264ba319b5SDimitry Andric         if (cu_id == 0)
5274ba319b5SDimitry Andric           continue;
5284ba319b5SDimitry Andric 
5294ba319b5SDimitry Andric         if (cu_id == sc.comp_unit->GetID())
5304ba319b5SDimitry Andric           num_added += ParseVariables(sc, *result);
5314ba319b5SDimitry Andric       }
5324ba319b5SDimitry Andric     }
5334ba319b5SDimitry Andric 
5344ba319b5SDimitry Andric     // FIXME: A `file static` or `global constant` variable appears both in
5354ba319b5SDimitry Andric     // compiland's children and global scope's children with unexpectedly
5364ba319b5SDimitry Andric     // different symbol's Id making it ambiguous.
5374ba319b5SDimitry Andric 
5384ba319b5SDimitry Andric     // FIXME: 'local constant', for example, const char var[] = "abc", declared
5394ba319b5SDimitry Andric     // in a function scope, can't be found in PDB.
5404ba319b5SDimitry Andric 
5414ba319b5SDimitry Andric     // Parse variables in this compiland.
5424ba319b5SDimitry Andric     num_added += ParseVariables(sc, *compiland);
5434ba319b5SDimitry Andric   }
5444ba319b5SDimitry Andric 
5454ba319b5SDimitry Andric   return num_added;
5464bb0738eSEd Maste }
5474bb0738eSEd Maste 
ResolveTypeUID(lldb::user_id_t type_uid)548435933ddSDimitry Andric lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
5494bb0738eSEd Maste   auto find_result = m_types.find(type_uid);
5504bb0738eSEd Maste   if (find_result != m_types.end())
5514bb0738eSEd Maste     return find_result->second.get();
5524bb0738eSEd Maste 
553435933ddSDimitry Andric   TypeSystem *type_system =
554435933ddSDimitry Andric       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
555435933ddSDimitry Andric   ClangASTContext *clang_type_system =
556435933ddSDimitry Andric       llvm::dyn_cast_or_null<ClangASTContext>(type_system);
5574bb0738eSEd Maste   if (!clang_type_system)
5584bb0738eSEd Maste     return nullptr;
559*b5893f02SDimitry Andric   PDBASTParser *pdb = clang_type_system->GetPDBParser();
5604bb0738eSEd Maste   if (!pdb)
5614bb0738eSEd Maste     return nullptr;
5624bb0738eSEd Maste 
5634bb0738eSEd Maste   auto pdb_type = m_session_up->getSymbolById(type_uid);
5644bb0738eSEd Maste   if (pdb_type == nullptr)
5654bb0738eSEd Maste     return nullptr;
5664bb0738eSEd Maste 
5674bb0738eSEd Maste   lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
5684ba319b5SDimitry Andric   if (result) {
5694bb0738eSEd Maste     m_types.insert(std::make_pair(type_uid, result));
5704ba319b5SDimitry Andric     auto type_list = GetTypeList();
5714ba319b5SDimitry Andric     if (type_list)
5724ba319b5SDimitry Andric       type_list->Insert(result);
5734ba319b5SDimitry Andric   }
5744bb0738eSEd Maste   return result.get();
5754bb0738eSEd Maste }
5764bb0738eSEd Maste 
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)577*b5893f02SDimitry Andric llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID(
578*b5893f02SDimitry Andric     lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
579*b5893f02SDimitry Andric   return llvm::None;
580*b5893f02SDimitry Andric }
581*b5893f02SDimitry Andric 
CompleteType(lldb_private::CompilerType & compiler_type)582435933ddSDimitry Andric bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
583*b5893f02SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
584*b5893f02SDimitry Andric       GetObjectFile()->GetModule()->GetMutex());
585*b5893f02SDimitry Andric 
586*b5893f02SDimitry Andric   ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
587*b5893f02SDimitry Andric       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
588*b5893f02SDimitry Andric   if (!clang_ast_ctx)
5894bb0738eSEd Maste     return false;
590*b5893f02SDimitry Andric 
591*b5893f02SDimitry Andric   PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
592*b5893f02SDimitry Andric   if (!pdb)
593*b5893f02SDimitry Andric     return false;
594*b5893f02SDimitry Andric 
595*b5893f02SDimitry Andric   return pdb->CompleteTypeFromPDB(compiler_type);
5964bb0738eSEd Maste }
5974bb0738eSEd Maste 
GetDeclForUID(lldb::user_id_t uid)598435933ddSDimitry Andric lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
599*b5893f02SDimitry Andric   ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
600*b5893f02SDimitry Andric       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
601*b5893f02SDimitry Andric   if (!clang_ast_ctx)
602*b5893f02SDimitry Andric     return CompilerDecl();
603*b5893f02SDimitry Andric 
604*b5893f02SDimitry Andric   PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
605*b5893f02SDimitry Andric   if (!pdb)
606*b5893f02SDimitry Andric     return CompilerDecl();
607*b5893f02SDimitry Andric 
608*b5893f02SDimitry Andric   auto symbol = m_session_up->getSymbolById(uid);
609*b5893f02SDimitry Andric   if (!symbol)
610*b5893f02SDimitry Andric     return CompilerDecl();
611*b5893f02SDimitry Andric 
612*b5893f02SDimitry Andric   auto decl = pdb->GetDeclForSymbol(*symbol);
613*b5893f02SDimitry Andric   if (!decl)
614*b5893f02SDimitry Andric     return CompilerDecl();
615*b5893f02SDimitry Andric 
616*b5893f02SDimitry Andric   return CompilerDecl(clang_ast_ctx, decl);
6174bb0738eSEd Maste }
6184bb0738eSEd Maste 
6194bb0738eSEd Maste lldb_private::CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t uid)620435933ddSDimitry Andric SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
621*b5893f02SDimitry Andric   ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
622*b5893f02SDimitry Andric       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
623*b5893f02SDimitry Andric   if (!clang_ast_ctx)
624*b5893f02SDimitry Andric     return CompilerDeclContext();
625*b5893f02SDimitry Andric 
626*b5893f02SDimitry Andric   PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
627*b5893f02SDimitry Andric   if (!pdb)
628*b5893f02SDimitry Andric     return CompilerDeclContext();
629*b5893f02SDimitry Andric 
630*b5893f02SDimitry Andric   auto symbol = m_session_up->getSymbolById(uid);
631*b5893f02SDimitry Andric   if (!symbol)
632*b5893f02SDimitry Andric     return CompilerDeclContext();
633*b5893f02SDimitry Andric 
634*b5893f02SDimitry Andric   auto decl_context = pdb->GetDeclContextForSymbol(*symbol);
635*b5893f02SDimitry Andric   if (!decl_context)
636*b5893f02SDimitry Andric     return GetDeclContextContainingUID(uid);
637*b5893f02SDimitry Andric 
638*b5893f02SDimitry Andric   return CompilerDeclContext(clang_ast_ctx, decl_context);
6394bb0738eSEd Maste }
6404bb0738eSEd Maste 
6414bb0738eSEd Maste lldb_private::CompilerDeclContext
GetDeclContextContainingUID(lldb::user_id_t uid)642435933ddSDimitry Andric SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
643*b5893f02SDimitry Andric   ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
644*b5893f02SDimitry Andric       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
645*b5893f02SDimitry Andric   if (!clang_ast_ctx)
646*b5893f02SDimitry Andric     return CompilerDeclContext();
647*b5893f02SDimitry Andric 
648*b5893f02SDimitry Andric   PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
649*b5893f02SDimitry Andric   if (!pdb)
650*b5893f02SDimitry Andric     return CompilerDeclContext();
651*b5893f02SDimitry Andric 
652*b5893f02SDimitry Andric   auto symbol = m_session_up->getSymbolById(uid);
653*b5893f02SDimitry Andric   if (!symbol)
654*b5893f02SDimitry Andric     return CompilerDeclContext();
655*b5893f02SDimitry Andric 
656*b5893f02SDimitry Andric   auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol);
657*b5893f02SDimitry Andric   assert(decl_context);
658*b5893f02SDimitry Andric 
659*b5893f02SDimitry Andric   return CompilerDeclContext(clang_ast_ctx, decl_context);
6604bb0738eSEd Maste }
6614bb0738eSEd Maste 
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)662435933ddSDimitry Andric void SymbolFilePDB::ParseDeclsForContext(
663*b5893f02SDimitry Andric     lldb_private::CompilerDeclContext decl_ctx) {
664*b5893f02SDimitry Andric   ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
665*b5893f02SDimitry Andric       GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
666*b5893f02SDimitry Andric   if (!clang_ast_ctx)
667*b5893f02SDimitry Andric     return;
668*b5893f02SDimitry Andric 
669*b5893f02SDimitry Andric   PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
670*b5893f02SDimitry Andric   if (!pdb)
671*b5893f02SDimitry Andric     return;
672*b5893f02SDimitry Andric 
673*b5893f02SDimitry Andric   pdb->ParseDeclsForDeclContext(
674*b5893f02SDimitry Andric       static_cast<clang::DeclContext *>(decl_ctx.GetOpaqueDeclContext()));
675*b5893f02SDimitry Andric }
6764bb0738eSEd Maste 
6774bb0738eSEd Maste uint32_t
ResolveSymbolContext(const lldb_private::Address & so_addr,SymbolContextItem resolve_scope,lldb_private::SymbolContext & sc)678435933ddSDimitry Andric SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
679*b5893f02SDimitry Andric                                     SymbolContextItem resolve_scope,
680435933ddSDimitry Andric                                     lldb_private::SymbolContext &sc) {
6814ba319b5SDimitry Andric   uint32_t resolved_flags = 0;
6824ba319b5SDimitry Andric   if (resolve_scope & eSymbolContextCompUnit ||
6834ba319b5SDimitry Andric       resolve_scope & eSymbolContextVariable ||
6844ba319b5SDimitry Andric       resolve_scope & eSymbolContextFunction ||
6854ba319b5SDimitry Andric       resolve_scope & eSymbolContextBlock ||
6864ba319b5SDimitry Andric       resolve_scope & eSymbolContextLineEntry) {
6874ba319b5SDimitry Andric     auto cu_sp = GetCompileUnitContainsAddress(so_addr);
6884ba319b5SDimitry Andric     if (!cu_sp) {
6894ba319b5SDimitry Andric       if (resolved_flags | eSymbolContextVariable) {
6904ba319b5SDimitry Andric         // TODO: Resolve variables
6914ba319b5SDimitry Andric       }
6924ba319b5SDimitry Andric       return 0;
6934ba319b5SDimitry Andric     }
6944ba319b5SDimitry Andric     sc.comp_unit = cu_sp.get();
6954ba319b5SDimitry Andric     resolved_flags |= eSymbolContextCompUnit;
6964ba319b5SDimitry Andric     lldbassert(sc.module_sp == cu_sp->GetModule());
6974ba319b5SDimitry Andric   }
6984ba319b5SDimitry Andric 
699*b5893f02SDimitry Andric   if (resolve_scope & eSymbolContextFunction ||
700*b5893f02SDimitry Andric       resolve_scope & eSymbolContextBlock) {
7014ba319b5SDimitry Andric     addr_t file_vm_addr = so_addr.GetFileAddress();
7024ba319b5SDimitry Andric     auto symbol_up =
7034ba319b5SDimitry Andric         m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);
7044ba319b5SDimitry Andric     if (symbol_up) {
7054ba319b5SDimitry Andric       auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
7064ba319b5SDimitry Andric       assert(pdb_func);
7074ba319b5SDimitry Andric       auto func_uid = pdb_func->getSymIndexId();
7084ba319b5SDimitry Andric       sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
7094ba319b5SDimitry Andric       if (sc.function == nullptr)
710*b5893f02SDimitry Andric         sc.function =
711*b5893f02SDimitry Andric             ParseCompileUnitFunctionForPDBFunc(*pdb_func, *sc.comp_unit);
7124ba319b5SDimitry Andric       if (sc.function) {
7134ba319b5SDimitry Andric         resolved_flags |= eSymbolContextFunction;
7144ba319b5SDimitry Andric         if (resolve_scope & eSymbolContextBlock) {
715*b5893f02SDimitry Andric           auto block_symbol = m_session_up->findSymbolByAddress(
716*b5893f02SDimitry Andric               file_vm_addr, PDB_SymType::Block);
717*b5893f02SDimitry Andric           auto block_id = block_symbol ? block_symbol->getSymIndexId()
718*b5893f02SDimitry Andric                                        : sc.function->GetID();
719*b5893f02SDimitry Andric           sc.block = sc.function->GetBlock(true).FindBlockByID(block_id);
7204ba319b5SDimitry Andric           if (sc.block)
7214ba319b5SDimitry Andric             resolved_flags |= eSymbolContextBlock;
7224ba319b5SDimitry Andric         }
7234ba319b5SDimitry Andric       }
7244ba319b5SDimitry Andric     }
7254ba319b5SDimitry Andric   }
7264ba319b5SDimitry Andric 
7274ba319b5SDimitry Andric   if (resolve_scope & eSymbolContextLineEntry) {
7284ba319b5SDimitry Andric     if (auto *line_table = sc.comp_unit->GetLineTable()) {
7294ba319b5SDimitry Andric       Address addr(so_addr);
7304ba319b5SDimitry Andric       if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
7314ba319b5SDimitry Andric         resolved_flags |= eSymbolContextLineEntry;
7324ba319b5SDimitry Andric     }
7334ba319b5SDimitry Andric   }
7344ba319b5SDimitry Andric 
7354ba319b5SDimitry Andric   return resolved_flags;
7364bb0738eSEd Maste }
7374bb0738eSEd Maste 
ResolveSymbolContext(const lldb_private::FileSpec & file_spec,uint32_t line,bool check_inlines,SymbolContextItem resolve_scope,lldb_private::SymbolContextList & sc_list)738435933ddSDimitry Andric uint32_t SymbolFilePDB::ResolveSymbolContext(
739435933ddSDimitry Andric     const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
740*b5893f02SDimitry Andric     SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
7414ba319b5SDimitry Andric   const size_t old_size = sc_list.GetSize();
742435933ddSDimitry Andric   if (resolve_scope & lldb::eSymbolContextCompUnit) {
743435933ddSDimitry Andric     // Locate all compilation units with line numbers referencing the specified
744f678e45dSDimitry Andric     // file.  For example, if `file_spec` is <vector>, then this should return
745f678e45dSDimitry Andric     // all source files and header files that reference <vector>, either
746f678e45dSDimitry Andric     // directly or indirectly.
747435933ddSDimitry Andric     auto compilands = m_session_up->findCompilandsForSourceFile(
748435933ddSDimitry Andric         file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
7494bb0738eSEd Maste 
7504ba319b5SDimitry Andric     if (!compilands)
7514ba319b5SDimitry Andric       return 0;
7524ba319b5SDimitry Andric 
753f678e45dSDimitry Andric     // For each one, either find its previously parsed data or parse it afresh
754f678e45dSDimitry Andric     // and add it to the symbol context list.
755435933ddSDimitry Andric     while (auto compiland = compilands->getNext()) {
7564ba319b5SDimitry Andric       // If we're not checking inlines, then don't add line information for
7574ba319b5SDimitry Andric       // this file unless the FileSpec matches. For inline functions, we don't
7584ba319b5SDimitry Andric       // have to match the FileSpec since they could be defined in headers
7594ba319b5SDimitry Andric       // other than file specified in FileSpec.
760435933ddSDimitry Andric       if (!check_inlines) {
7614ba319b5SDimitry Andric         std::string source_file = compiland->getSourceFileFullPath();
7624ba319b5SDimitry Andric         if (source_file.empty())
7634ba319b5SDimitry Andric           continue;
764*b5893f02SDimitry Andric         FileSpec this_spec(source_file, FileSpec::Style::windows);
7654ba319b5SDimitry Andric         bool need_full_match = !file_spec.GetDirectory().IsEmpty();
7664ba319b5SDimitry Andric         if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)
7674bb0738eSEd Maste           continue;
7684bb0738eSEd Maste       }
7694bb0738eSEd Maste 
7704bb0738eSEd Maste       SymbolContext sc;
7714ba319b5SDimitry Andric       auto cu = ParseCompileUnitForUID(compiland->getSymIndexId());
7724ba319b5SDimitry Andric       if (!cu)
7734ba319b5SDimitry Andric         continue;
7744bb0738eSEd Maste       sc.comp_unit = cu.get();
7754bb0738eSEd Maste       sc.module_sp = cu->GetModule();
7764bb0738eSEd Maste 
777435933ddSDimitry Andric       // If we were asked to resolve line entries, add all entries to the line
778f678e45dSDimitry Andric       // table that match the requested line (or all lines if `line` == 0).
7794ba319b5SDimitry Andric       if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |
7804ba319b5SDimitry Andric                            eSymbolContextLineEntry)) {
781*b5893f02SDimitry Andric         bool has_line_table = ParseCompileUnitLineTable(*sc.comp_unit, line);
7824ba319b5SDimitry Andric 
7834ba319b5SDimitry Andric         if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {
7844ba319b5SDimitry Andric           // The query asks for line entries, but we can't get them for the
7854ba319b5SDimitry Andric           // compile unit. This is not normal for `line` = 0. So just assert
7864ba319b5SDimitry Andric           // it.
7874ba319b5SDimitry Andric           assert(line && "Couldn't get all line entries!\n");
7884ba319b5SDimitry Andric 
7894ba319b5SDimitry Andric           // Current compiland does not have the requested line. Search next.
7904ba319b5SDimitry Andric           continue;
7914ba319b5SDimitry Andric         }
7924ba319b5SDimitry Andric 
7934ba319b5SDimitry Andric         if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
7944ba319b5SDimitry Andric           if (!has_line_table)
7954ba319b5SDimitry Andric             continue;
7964ba319b5SDimitry Andric 
7974ba319b5SDimitry Andric           auto *line_table = sc.comp_unit->GetLineTable();
7984ba319b5SDimitry Andric           lldbassert(line_table);
7994ba319b5SDimitry Andric 
8004ba319b5SDimitry Andric           uint32_t num_line_entries = line_table->GetSize();
8014ba319b5SDimitry Andric           // Skip the terminal line entry.
8024ba319b5SDimitry Andric           --num_line_entries;
8034ba319b5SDimitry Andric 
8044ba319b5SDimitry Andric           // If `line `!= 0, see if we can resolve function for each line entry
8054ba319b5SDimitry Andric           // in the line table.
8064ba319b5SDimitry Andric           for (uint32_t line_idx = 0; line && line_idx < num_line_entries;
8074ba319b5SDimitry Andric                ++line_idx) {
8084ba319b5SDimitry Andric             if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry))
8094ba319b5SDimitry Andric               continue;
8104ba319b5SDimitry Andric 
8114ba319b5SDimitry Andric             auto file_vm_addr =
8124ba319b5SDimitry Andric                 sc.line_entry.range.GetBaseAddress().GetFileAddress();
8134ba319b5SDimitry Andric             if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
8144ba319b5SDimitry Andric               continue;
8154ba319b5SDimitry Andric 
8164ba319b5SDimitry Andric             auto symbol_up = m_session_up->findSymbolByAddress(
8174ba319b5SDimitry Andric                 file_vm_addr, PDB_SymType::Function);
8184ba319b5SDimitry Andric             if (symbol_up) {
8194ba319b5SDimitry Andric               auto func_uid = symbol_up->getSymIndexId();
8204ba319b5SDimitry Andric               sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
8214ba319b5SDimitry Andric               if (sc.function == nullptr) {
8224ba319b5SDimitry Andric                 auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
8234ba319b5SDimitry Andric                 assert(pdb_func);
824*b5893f02SDimitry Andric                 sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func,
825*b5893f02SDimitry Andric                                                                  *sc.comp_unit);
8264ba319b5SDimitry Andric               }
8274ba319b5SDimitry Andric               if (sc.function && (resolve_scope & eSymbolContextBlock)) {
8284ba319b5SDimitry Andric                 Block &block = sc.function->GetBlock(true);
8294ba319b5SDimitry Andric                 sc.block = block.FindBlockByID(sc.function->GetID());
8304bb0738eSEd Maste               }
8314bb0738eSEd Maste             }
8324ba319b5SDimitry Andric             sc_list.Append(sc);
8334ba319b5SDimitry Andric           }
8344ba319b5SDimitry Andric         } else if (has_line_table) {
8354ba319b5SDimitry Andric           // We can parse line table for the compile unit. But no query to
8364ba319b5SDimitry Andric           // resolve function or block. We append `sc` to the list anyway.
8374ba319b5SDimitry Andric           sc_list.Append(sc);
8384ba319b5SDimitry Andric         }
8394ba319b5SDimitry Andric       } else {
8404ba319b5SDimitry Andric         // No query for line entry, function or block. But we have a valid
8414ba319b5SDimitry Andric         // compile unit, append `sc` to the list.
8424ba319b5SDimitry Andric         sc_list.Append(sc);
8434ba319b5SDimitry Andric       }
8444ba319b5SDimitry Andric     }
8454ba319b5SDimitry Andric   }
8464ba319b5SDimitry Andric   return sc_list.GetSize() - old_size;
8474ba319b5SDimitry Andric }
8484ba319b5SDimitry Andric 
GetMangledForPDBData(const PDBSymbolData & pdb_data)8494ba319b5SDimitry Andric std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) {
850*b5893f02SDimitry Andric   // Cache public names at first
851*b5893f02SDimitry Andric   if (m_public_names.empty())
852*b5893f02SDimitry Andric     if (auto result_up =
853*b5893f02SDimitry Andric             m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol))
854*b5893f02SDimitry Andric       while (auto symbol_up = result_up->getNext())
855*b5893f02SDimitry Andric         if (auto addr = symbol_up->getRawSymbol().getVirtualAddress())
856*b5893f02SDimitry Andric           m_public_names[addr] = symbol_up->getRawSymbol().getName();
8574ba319b5SDimitry Andric 
858*b5893f02SDimitry Andric   // Look up the name in the cache
859*b5893f02SDimitry Andric   return m_public_names.lookup(pdb_data.getVirtualAddress());
8604ba319b5SDimitry Andric }
8614ba319b5SDimitry Andric 
ParseVariableForPDBData(const lldb_private::SymbolContext & sc,const llvm::pdb::PDBSymbolData & pdb_data)8624ba319b5SDimitry Andric VariableSP SymbolFilePDB::ParseVariableForPDBData(
8634ba319b5SDimitry Andric     const lldb_private::SymbolContext &sc,
8644ba319b5SDimitry Andric     const llvm::pdb::PDBSymbolData &pdb_data) {
8654ba319b5SDimitry Andric   VariableSP var_sp;
8664ba319b5SDimitry Andric   uint32_t var_uid = pdb_data.getSymIndexId();
8674ba319b5SDimitry Andric   auto result = m_variables.find(var_uid);
8684ba319b5SDimitry Andric   if (result != m_variables.end())
8694ba319b5SDimitry Andric     return result->second;
8704ba319b5SDimitry Andric 
8714ba319b5SDimitry Andric   ValueType scope = eValueTypeInvalid;
8724ba319b5SDimitry Andric   bool is_static_member = false;
8734ba319b5SDimitry Andric   bool is_external = false;
8744ba319b5SDimitry Andric   bool is_artificial = false;
8754ba319b5SDimitry Andric 
8764ba319b5SDimitry Andric   switch (pdb_data.getDataKind()) {
8774ba319b5SDimitry Andric   case PDB_DataKind::Global:
8784ba319b5SDimitry Andric     scope = eValueTypeVariableGlobal;
8794ba319b5SDimitry Andric     is_external = true;
8804ba319b5SDimitry Andric     break;
8814ba319b5SDimitry Andric   case PDB_DataKind::Local:
8824ba319b5SDimitry Andric     scope = eValueTypeVariableLocal;
8834ba319b5SDimitry Andric     break;
8844ba319b5SDimitry Andric   case PDB_DataKind::FileStatic:
8854ba319b5SDimitry Andric     scope = eValueTypeVariableStatic;
8864ba319b5SDimitry Andric     break;
8874ba319b5SDimitry Andric   case PDB_DataKind::StaticMember:
8884ba319b5SDimitry Andric     is_static_member = true;
8894ba319b5SDimitry Andric     scope = eValueTypeVariableStatic;
8904ba319b5SDimitry Andric     break;
8914ba319b5SDimitry Andric   case PDB_DataKind::Member:
8924ba319b5SDimitry Andric     scope = eValueTypeVariableStatic;
8934ba319b5SDimitry Andric     break;
8944ba319b5SDimitry Andric   case PDB_DataKind::Param:
8954ba319b5SDimitry Andric     scope = eValueTypeVariableArgument;
8964ba319b5SDimitry Andric     break;
8974ba319b5SDimitry Andric   case PDB_DataKind::Constant:
8984ba319b5SDimitry Andric     scope = eValueTypeConstResult;
8994ba319b5SDimitry Andric     break;
9004ba319b5SDimitry Andric   default:
9014ba319b5SDimitry Andric     break;
9024ba319b5SDimitry Andric   }
9034ba319b5SDimitry Andric 
9044ba319b5SDimitry Andric   switch (pdb_data.getLocationType()) {
9054ba319b5SDimitry Andric   case PDB_LocType::TLS:
9064ba319b5SDimitry Andric     scope = eValueTypeVariableThreadLocal;
9074ba319b5SDimitry Andric     break;
9084ba319b5SDimitry Andric   case PDB_LocType::RegRel: {
9094ba319b5SDimitry Andric     // It is a `this` pointer.
9104ba319b5SDimitry Andric     if (pdb_data.getDataKind() == PDB_DataKind::ObjectPtr) {
9114ba319b5SDimitry Andric       scope = eValueTypeVariableArgument;
9124ba319b5SDimitry Andric       is_artificial = true;
9134ba319b5SDimitry Andric     }
9144ba319b5SDimitry Andric   } break;
9154ba319b5SDimitry Andric   default:
9164ba319b5SDimitry Andric     break;
9174ba319b5SDimitry Andric   }
9184ba319b5SDimitry Andric 
9194ba319b5SDimitry Andric   Declaration decl;
9204ba319b5SDimitry Andric   if (!is_artificial && !pdb_data.isCompilerGenerated()) {
9214ba319b5SDimitry Andric     if (auto lines = pdb_data.getLineNumbers()) {
9224ba319b5SDimitry Andric       if (auto first_line = lines->getNext()) {
9234ba319b5SDimitry Andric         uint32_t src_file_id = first_line->getSourceFileId();
9244ba319b5SDimitry Andric         auto src_file = m_session_up->getSourceFileById(src_file_id);
9254ba319b5SDimitry Andric         if (src_file) {
926*b5893f02SDimitry Andric           FileSpec spec(src_file->getFileName());
9274ba319b5SDimitry Andric           decl.SetFile(spec);
9284ba319b5SDimitry Andric           decl.SetColumn(first_line->getColumnNumber());
9294ba319b5SDimitry Andric           decl.SetLine(first_line->getLineNumber());
9304ba319b5SDimitry Andric         }
9314ba319b5SDimitry Andric       }
9324ba319b5SDimitry Andric     }
9334ba319b5SDimitry Andric   }
9344ba319b5SDimitry Andric 
9354ba319b5SDimitry Andric   Variable::RangeList ranges;
9364ba319b5SDimitry Andric   SymbolContextScope *context_scope = sc.comp_unit;
9374ba319b5SDimitry Andric   if (scope == eValueTypeVariableLocal) {
9384ba319b5SDimitry Andric     if (sc.function) {
9394ba319b5SDimitry Andric       context_scope = sc.function->GetBlock(true).FindBlockByID(
940*b5893f02SDimitry Andric           pdb_data.getLexicalParentId());
9414ba319b5SDimitry Andric       if (context_scope == nullptr)
9424ba319b5SDimitry Andric         context_scope = sc.function;
9434ba319b5SDimitry Andric     }
9444ba319b5SDimitry Andric   }
9454ba319b5SDimitry Andric 
9464ba319b5SDimitry Andric   SymbolFileTypeSP type_sp =
9474ba319b5SDimitry Andric       std::make_shared<SymbolFileType>(*this, pdb_data.getTypeId());
9484ba319b5SDimitry Andric 
9494ba319b5SDimitry Andric   auto var_name = pdb_data.getName();
9504ba319b5SDimitry Andric   auto mangled = GetMangledForPDBData(pdb_data);
9514ba319b5SDimitry Andric   auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();
9524ba319b5SDimitry Andric 
9534ba319b5SDimitry Andric   bool is_constant;
9544ba319b5SDimitry Andric   DWARFExpression location = ConvertPDBLocationToDWARFExpression(
9554ba319b5SDimitry Andric       GetObjectFile()->GetModule(), pdb_data, is_constant);
9564ba319b5SDimitry Andric 
9574ba319b5SDimitry Andric   var_sp = std::make_shared<Variable>(
9584ba319b5SDimitry Andric       var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
9594ba319b5SDimitry Andric       ranges, &decl, location, is_external, is_artificial, is_static_member);
9604ba319b5SDimitry Andric   var_sp->SetLocationIsConstantValueData(is_constant);
9614ba319b5SDimitry Andric 
9624ba319b5SDimitry Andric   m_variables.insert(std::make_pair(var_uid, var_sp));
9634ba319b5SDimitry Andric   return var_sp;
9644ba319b5SDimitry Andric }
9654ba319b5SDimitry Andric 
9664ba319b5SDimitry Andric size_t
ParseVariables(const lldb_private::SymbolContext & sc,const llvm::pdb::PDBSymbol & pdb_symbol,lldb_private::VariableList * variable_list)9674ba319b5SDimitry Andric SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
9684ba319b5SDimitry Andric                               const llvm::pdb::PDBSymbol &pdb_symbol,
9694ba319b5SDimitry Andric                               lldb_private::VariableList *variable_list) {
9704ba319b5SDimitry Andric   size_t num_added = 0;
9714ba319b5SDimitry Andric 
9724ba319b5SDimitry Andric   if (auto pdb_data = llvm::dyn_cast<PDBSymbolData>(&pdb_symbol)) {
9734ba319b5SDimitry Andric     VariableListSP local_variable_list_sp;
9744ba319b5SDimitry Andric 
9754ba319b5SDimitry Andric     auto result = m_variables.find(pdb_data->getSymIndexId());
9764ba319b5SDimitry Andric     if (result != m_variables.end()) {
9774ba319b5SDimitry Andric       if (variable_list)
9784ba319b5SDimitry Andric         variable_list->AddVariableIfUnique(result->second);
9794ba319b5SDimitry Andric     } else {
9804ba319b5SDimitry Andric       // Prepare right VariableList for this variable.
9814ba319b5SDimitry Andric       if (auto lexical_parent = pdb_data->getLexicalParent()) {
9824ba319b5SDimitry Andric         switch (lexical_parent->getSymTag()) {
9834ba319b5SDimitry Andric         case PDB_SymType::Exe:
9844ba319b5SDimitry Andric           assert(sc.comp_unit);
9854ba319b5SDimitry Andric           LLVM_FALLTHROUGH;
9864ba319b5SDimitry Andric         case PDB_SymType::Compiland: {
9874ba319b5SDimitry Andric           if (sc.comp_unit) {
9884ba319b5SDimitry Andric             local_variable_list_sp = sc.comp_unit->GetVariableList(false);
9894ba319b5SDimitry Andric             if (!local_variable_list_sp) {
9904ba319b5SDimitry Andric               local_variable_list_sp = std::make_shared<VariableList>();
9914ba319b5SDimitry Andric               sc.comp_unit->SetVariableList(local_variable_list_sp);
9924ba319b5SDimitry Andric             }
9934ba319b5SDimitry Andric           }
9944ba319b5SDimitry Andric         } break;
9954ba319b5SDimitry Andric         case PDB_SymType::Block:
9964ba319b5SDimitry Andric         case PDB_SymType::Function: {
9974ba319b5SDimitry Andric           if (sc.function) {
9984ba319b5SDimitry Andric             Block *block = sc.function->GetBlock(true).FindBlockByID(
9994ba319b5SDimitry Andric                 lexical_parent->getSymIndexId());
10004ba319b5SDimitry Andric             if (block) {
10014ba319b5SDimitry Andric               local_variable_list_sp = block->GetBlockVariableList(false);
10024ba319b5SDimitry Andric               if (!local_variable_list_sp) {
10034ba319b5SDimitry Andric                 local_variable_list_sp = std::make_shared<VariableList>();
10044ba319b5SDimitry Andric                 block->SetVariableList(local_variable_list_sp);
10054ba319b5SDimitry Andric               }
10064ba319b5SDimitry Andric             }
10074ba319b5SDimitry Andric           }
10084ba319b5SDimitry Andric         } break;
10094ba319b5SDimitry Andric         default:
10104ba319b5SDimitry Andric           break;
10114ba319b5SDimitry Andric         }
10124ba319b5SDimitry Andric       }
10134ba319b5SDimitry Andric 
10144ba319b5SDimitry Andric       if (local_variable_list_sp) {
10154ba319b5SDimitry Andric         if (auto var_sp = ParseVariableForPDBData(sc, *pdb_data)) {
10164ba319b5SDimitry Andric           local_variable_list_sp->AddVariableIfUnique(var_sp);
10174ba319b5SDimitry Andric           if (variable_list)
10184ba319b5SDimitry Andric             variable_list->AddVariableIfUnique(var_sp);
10194ba319b5SDimitry Andric           ++num_added;
1020*b5893f02SDimitry Andric           PDBASTParser *ast = GetPDBAstParser();
1021*b5893f02SDimitry Andric           if (ast)
1022*b5893f02SDimitry Andric             ast->GetDeclForSymbol(*pdb_data);
10234ba319b5SDimitry Andric         }
10244ba319b5SDimitry Andric       }
10254ba319b5SDimitry Andric     }
10264ba319b5SDimitry Andric   }
10274ba319b5SDimitry Andric 
10284ba319b5SDimitry Andric   if (auto results = pdb_symbol.findAllChildren()) {
10294ba319b5SDimitry Andric     while (auto result = results->getNext())
10304ba319b5SDimitry Andric       num_added += ParseVariables(sc, *result, variable_list);
10314ba319b5SDimitry Andric   }
10324ba319b5SDimitry Andric 
10334ba319b5SDimitry Andric   return num_added;
10344bb0738eSEd Maste }
10354bb0738eSEd Maste 
FindGlobalVariables(const lldb_private::ConstString & name,const lldb_private::CompilerDeclContext * parent_decl_ctx,uint32_t max_matches,lldb_private::VariableList & variables)1036435933ddSDimitry Andric uint32_t SymbolFilePDB::FindGlobalVariables(
1037435933ddSDimitry Andric     const lldb_private::ConstString &name,
10384ba319b5SDimitry Andric     const lldb_private::CompilerDeclContext *parent_decl_ctx,
1039435933ddSDimitry Andric     uint32_t max_matches, lldb_private::VariableList &variables) {
10404ba319b5SDimitry Andric   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
10414ba319b5SDimitry Andric     return 0;
10424ba319b5SDimitry Andric   if (name.IsEmpty())
10434ba319b5SDimitry Andric     return 0;
10444ba319b5SDimitry Andric 
1045*b5893f02SDimitry Andric   auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
10464ba319b5SDimitry Andric   if (!results)
10474ba319b5SDimitry Andric     return 0;
10484ba319b5SDimitry Andric 
10494ba319b5SDimitry Andric   uint32_t matches = 0;
10504ba319b5SDimitry Andric   size_t old_size = variables.GetSize();
10514ba319b5SDimitry Andric   while (auto result = results->getNext()) {
10524ba319b5SDimitry Andric     auto pdb_data = llvm::dyn_cast<PDBSymbolData>(result.get());
10534ba319b5SDimitry Andric     if (max_matches > 0 && matches >= max_matches)
10544ba319b5SDimitry Andric       break;
10554ba319b5SDimitry Andric 
10564ba319b5SDimitry Andric     SymbolContext sc;
10574ba319b5SDimitry Andric     sc.module_sp = m_obj_file->GetModule();
10584ba319b5SDimitry Andric     lldbassert(sc.module_sp.get());
10594ba319b5SDimitry Andric 
1060*b5893f02SDimitry Andric     if (!name.GetStringRef().equals(
1061*b5893f02SDimitry Andric             MSVCUndecoratedNameParser::DropScope(pdb_data->getName())))
1062*b5893f02SDimitry Andric       continue;
1063*b5893f02SDimitry Andric 
1064*b5893f02SDimitry Andric     sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
10654ba319b5SDimitry Andric     // FIXME: We are not able to determine the compile unit.
10664ba319b5SDimitry Andric     if (sc.comp_unit == nullptr)
10674ba319b5SDimitry Andric       continue;
10684ba319b5SDimitry Andric 
1069*b5893f02SDimitry Andric     if (parent_decl_ctx && GetDeclContextContainingUID(
1070*b5893f02SDimitry Andric                                result->getSymIndexId()) != *parent_decl_ctx)
1071*b5893f02SDimitry Andric       continue;
1072*b5893f02SDimitry Andric 
10734ba319b5SDimitry Andric     ParseVariables(sc, *pdb_data, &variables);
10744ba319b5SDimitry Andric     matches = variables.GetSize() - old_size;
10754ba319b5SDimitry Andric   }
10764ba319b5SDimitry Andric 
10774ba319b5SDimitry Andric   return matches;
10784bb0738eSEd Maste }
10794bb0738eSEd Maste 
10804bb0738eSEd Maste uint32_t
FindGlobalVariables(const lldb_private::RegularExpression & regex,uint32_t max_matches,lldb_private::VariableList & variables)1081435933ddSDimitry Andric SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
10824ba319b5SDimitry Andric                                    uint32_t max_matches,
1083435933ddSDimitry Andric                                    lldb_private::VariableList &variables) {
10844ba319b5SDimitry Andric   if (!regex.IsValid())
10854ba319b5SDimitry Andric     return 0;
10864ba319b5SDimitry Andric   auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
10874ba319b5SDimitry Andric   if (!results)
10884ba319b5SDimitry Andric     return 0;
10894ba319b5SDimitry Andric 
10904ba319b5SDimitry Andric   uint32_t matches = 0;
10914ba319b5SDimitry Andric   size_t old_size = variables.GetSize();
10924ba319b5SDimitry Andric   while (auto pdb_data = results->getNext()) {
10934ba319b5SDimitry Andric     if (max_matches > 0 && matches >= max_matches)
10944ba319b5SDimitry Andric       break;
10954ba319b5SDimitry Andric 
10964ba319b5SDimitry Andric     auto var_name = pdb_data->getName();
10974ba319b5SDimitry Andric     if (var_name.empty())
10984ba319b5SDimitry Andric       continue;
10994ba319b5SDimitry Andric     if (!regex.Execute(var_name))
11004ba319b5SDimitry Andric       continue;
11014ba319b5SDimitry Andric     SymbolContext sc;
11024ba319b5SDimitry Andric     sc.module_sp = m_obj_file->GetModule();
11034ba319b5SDimitry Andric     lldbassert(sc.module_sp.get());
11044ba319b5SDimitry Andric 
1105*b5893f02SDimitry Andric     sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
11064ba319b5SDimitry Andric     // FIXME: We are not able to determine the compile unit.
11074ba319b5SDimitry Andric     if (sc.comp_unit == nullptr)
11084ba319b5SDimitry Andric       continue;
11094ba319b5SDimitry Andric 
11104ba319b5SDimitry Andric     ParseVariables(sc, *pdb_data, &variables);
11114ba319b5SDimitry Andric     matches = variables.GetSize() - old_size;
11124ba319b5SDimitry Andric   }
11134ba319b5SDimitry Andric 
11144ba319b5SDimitry Andric   return matches;
11154ba319b5SDimitry Andric }
11164ba319b5SDimitry Andric 
ResolveFunction(const llvm::pdb::PDBSymbolFunc & pdb_func,bool include_inlines,lldb_private::SymbolContextList & sc_list)11174ba319b5SDimitry Andric bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
11184ba319b5SDimitry Andric                                     bool include_inlines,
11194ba319b5SDimitry Andric                                     lldb_private::SymbolContextList &sc_list) {
11204ba319b5SDimitry Andric   lldb_private::SymbolContext sc;
11214ba319b5SDimitry Andric   sc.comp_unit = ParseCompileUnitForUID(pdb_func.getCompilandId()).get();
11224ba319b5SDimitry Andric   if (!sc.comp_unit)
11234ba319b5SDimitry Andric     return false;
11244ba319b5SDimitry Andric   sc.module_sp = sc.comp_unit->GetModule();
1125*b5893f02SDimitry Andric   sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, *sc.comp_unit);
11264ba319b5SDimitry Andric   if (!sc.function)
11274ba319b5SDimitry Andric     return false;
11284ba319b5SDimitry Andric 
11294ba319b5SDimitry Andric   sc_list.Append(sc);
11304ba319b5SDimitry Andric   return true;
11314ba319b5SDimitry Andric }
11324ba319b5SDimitry Andric 
ResolveFunction(uint32_t uid,bool include_inlines,lldb_private::SymbolContextList & sc_list)11334ba319b5SDimitry Andric bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines,
11344ba319b5SDimitry Andric                                     lldb_private::SymbolContextList &sc_list) {
11354ba319b5SDimitry Andric   auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
11364ba319b5SDimitry Andric   if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute()))
11374ba319b5SDimitry Andric     return false;
11384ba319b5SDimitry Andric   return ResolveFunction(*pdb_func_up, include_inlines, sc_list);
11394ba319b5SDimitry Andric }
11404ba319b5SDimitry Andric 
CacheFunctionNames()11414ba319b5SDimitry Andric void SymbolFilePDB::CacheFunctionNames() {
11424ba319b5SDimitry Andric   if (!m_func_full_names.IsEmpty())
11434ba319b5SDimitry Andric     return;
11444ba319b5SDimitry Andric 
11454ba319b5SDimitry Andric   std::map<uint64_t, uint32_t> addr_ids;
11464ba319b5SDimitry Andric 
11474ba319b5SDimitry Andric   if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) {
11484ba319b5SDimitry Andric     while (auto pdb_func_up = results_up->getNext()) {
11494ba319b5SDimitry Andric       if (pdb_func_up->isCompilerGenerated())
11504ba319b5SDimitry Andric         continue;
11514ba319b5SDimitry Andric 
11524ba319b5SDimitry Andric       auto name = pdb_func_up->getName();
11534ba319b5SDimitry Andric       auto demangled_name = pdb_func_up->getUndecoratedName();
11544ba319b5SDimitry Andric       if (name.empty() && demangled_name.empty())
11554ba319b5SDimitry Andric         continue;
11564ba319b5SDimitry Andric 
11574ba319b5SDimitry Andric       auto uid = pdb_func_up->getSymIndexId();
11584ba319b5SDimitry Andric       if (!demangled_name.empty() && pdb_func_up->getVirtualAddress())
11594ba319b5SDimitry Andric         addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid));
11604ba319b5SDimitry Andric 
11614ba319b5SDimitry Andric       if (auto parent = pdb_func_up->getClassParent()) {
11624ba319b5SDimitry Andric 
11634ba319b5SDimitry Andric         // PDB have symbols for class/struct methods or static methods in Enum
11644ba319b5SDimitry Andric         // Class. We won't bother to check if the parent is UDT or Enum here.
11654ba319b5SDimitry Andric         m_func_method_names.Append(ConstString(name), uid);
11664ba319b5SDimitry Andric 
11674ba319b5SDimitry Andric         // To search a method name, like NS::Class:MemberFunc, LLDB searches
11684ba319b5SDimitry Andric         // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does
11694ba319b5SDimitry Andric         // not have inforamtion of this, we extract base names and cache them
11704ba319b5SDimitry Andric         // by our own effort.
1171*b5893f02SDimitry Andric         llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
11724ba319b5SDimitry Andric         if (!basename.empty())
11734ba319b5SDimitry Andric           m_func_base_names.Append(ConstString(basename), uid);
11744ba319b5SDimitry Andric         else {
11754ba319b5SDimitry Andric           m_func_base_names.Append(ConstString(name), uid);
11764ba319b5SDimitry Andric         }
11774ba319b5SDimitry Andric 
11784ba319b5SDimitry Andric         if (!demangled_name.empty())
11794ba319b5SDimitry Andric           m_func_full_names.Append(ConstString(demangled_name), uid);
11804ba319b5SDimitry Andric 
11814ba319b5SDimitry Andric       } else {
11824ba319b5SDimitry Andric         // Handle not-method symbols.
11834ba319b5SDimitry Andric 
1184*b5893f02SDimitry Andric         // The function name might contain namespace, or its lexical scope.
1185*b5893f02SDimitry Andric         llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
1186*b5893f02SDimitry Andric         if (!basename.empty())
1187*b5893f02SDimitry Andric           m_func_base_names.Append(ConstString(basename), uid);
1188*b5893f02SDimitry Andric         else
11894ba319b5SDimitry Andric           m_func_base_names.Append(ConstString(name), uid);
11904ba319b5SDimitry Andric 
11914ba319b5SDimitry Andric         if (name == "main") {
11924ba319b5SDimitry Andric           m_func_full_names.Append(ConstString(name), uid);
11934ba319b5SDimitry Andric 
11944ba319b5SDimitry Andric           if (!demangled_name.empty() && name != demangled_name) {
11954ba319b5SDimitry Andric             m_func_full_names.Append(ConstString(demangled_name), uid);
11964ba319b5SDimitry Andric             m_func_base_names.Append(ConstString(demangled_name), uid);
11974ba319b5SDimitry Andric           }
11984ba319b5SDimitry Andric         } else if (!demangled_name.empty()) {
11994ba319b5SDimitry Andric           m_func_full_names.Append(ConstString(demangled_name), uid);
12004ba319b5SDimitry Andric         } else {
12014ba319b5SDimitry Andric           m_func_full_names.Append(ConstString(name), uid);
12024ba319b5SDimitry Andric         }
12034ba319b5SDimitry Andric       }
12044ba319b5SDimitry Andric     }
12054ba319b5SDimitry Andric   }
12064ba319b5SDimitry Andric 
12074ba319b5SDimitry Andric   if (auto results_up =
12084ba319b5SDimitry Andric           m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) {
12094ba319b5SDimitry Andric     while (auto pub_sym_up = results_up->getNext()) {
12104ba319b5SDimitry Andric       if (!pub_sym_up->isFunction())
12114ba319b5SDimitry Andric         continue;
12124ba319b5SDimitry Andric       auto name = pub_sym_up->getName();
12134ba319b5SDimitry Andric       if (name.empty())
12144ba319b5SDimitry Andric         continue;
12154ba319b5SDimitry Andric 
12164ba319b5SDimitry Andric       if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) {
12174ba319b5SDimitry Andric         auto vm_addr = pub_sym_up->getVirtualAddress();
12184ba319b5SDimitry Andric 
12194ba319b5SDimitry Andric         // PDB public symbol has mangled name for its associated function.
12204ba319b5SDimitry Andric         if (vm_addr && addr_ids.find(vm_addr) != addr_ids.end()) {
12214ba319b5SDimitry Andric           // Cache mangled name.
12224ba319b5SDimitry Andric           m_func_full_names.Append(ConstString(name), addr_ids[vm_addr]);
12234ba319b5SDimitry Andric         }
12244ba319b5SDimitry Andric       }
12254ba319b5SDimitry Andric     }
12264ba319b5SDimitry Andric   }
12274ba319b5SDimitry Andric   // Sort them before value searching is working properly
12284ba319b5SDimitry Andric   m_func_full_names.Sort();
12294ba319b5SDimitry Andric   m_func_full_names.SizeToFit();
12304ba319b5SDimitry Andric   m_func_method_names.Sort();
12314ba319b5SDimitry Andric   m_func_method_names.SizeToFit();
12324ba319b5SDimitry Andric   m_func_base_names.Sort();
12334ba319b5SDimitry Andric   m_func_base_names.SizeToFit();
1234435933ddSDimitry Andric }
1235435933ddSDimitry Andric 
FindFunctions(const lldb_private::ConstString & name,const lldb_private::CompilerDeclContext * parent_decl_ctx,FunctionNameType name_type_mask,bool include_inlines,bool append,lldb_private::SymbolContextList & sc_list)1236435933ddSDimitry Andric uint32_t SymbolFilePDB::FindFunctions(
1237435933ddSDimitry Andric     const lldb_private::ConstString &name,
1238435933ddSDimitry Andric     const lldb_private::CompilerDeclContext *parent_decl_ctx,
1239*b5893f02SDimitry Andric     FunctionNameType name_type_mask, bool include_inlines, bool append,
1240435933ddSDimitry Andric     lldb_private::SymbolContextList &sc_list) {
12414ba319b5SDimitry Andric   if (!append)
12424ba319b5SDimitry Andric     sc_list.Clear();
12434ba319b5SDimitry Andric   lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);
12444ba319b5SDimitry Andric 
12454ba319b5SDimitry Andric   if (name_type_mask == eFunctionNameTypeNone)
12464ba319b5SDimitry Andric     return 0;
12474ba319b5SDimitry Andric   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
12484ba319b5SDimitry Andric     return 0;
12494ba319b5SDimitry Andric   if (name.IsEmpty())
12504ba319b5SDimitry Andric     return 0;
12514ba319b5SDimitry Andric 
12524ba319b5SDimitry Andric   auto old_size = sc_list.GetSize();
12534ba319b5SDimitry Andric   if (name_type_mask & eFunctionNameTypeFull ||
12544ba319b5SDimitry Andric       name_type_mask & eFunctionNameTypeBase ||
12554ba319b5SDimitry Andric       name_type_mask & eFunctionNameTypeMethod) {
12564ba319b5SDimitry Andric     CacheFunctionNames();
12574ba319b5SDimitry Andric 
12584ba319b5SDimitry Andric     std::set<uint32_t> resolved_ids;
1259*b5893f02SDimitry Andric     auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list,
1260*b5893f02SDimitry Andric                       &resolved_ids](UniqueCStringMap<uint32_t> &Names) {
12614ba319b5SDimitry Andric       std::vector<uint32_t> ids;
1262*b5893f02SDimitry Andric       if (!Names.GetValues(name, ids))
1263*b5893f02SDimitry Andric         return;
1264*b5893f02SDimitry Andric 
1265*b5893f02SDimitry Andric       for (uint32_t id : ids) {
1266*b5893f02SDimitry Andric         if (resolved_ids.find(id) != resolved_ids.end())
1267*b5893f02SDimitry Andric           continue;
1268*b5893f02SDimitry Andric 
1269*b5893f02SDimitry Andric         if (parent_decl_ctx &&
1270*b5893f02SDimitry Andric             GetDeclContextContainingUID(id) != *parent_decl_ctx)
1271*b5893f02SDimitry Andric           continue;
1272*b5893f02SDimitry Andric 
12734ba319b5SDimitry Andric         if (ResolveFunction(id, include_inlines, sc_list))
12744ba319b5SDimitry Andric           resolved_ids.insert(id);
12754ba319b5SDimitry Andric       }
12764ba319b5SDimitry Andric     };
12774ba319b5SDimitry Andric     if (name_type_mask & eFunctionNameTypeFull) {
12784ba319b5SDimitry Andric       ResolveFn(m_func_full_names);
1279*b5893f02SDimitry Andric       ResolveFn(m_func_base_names);
1280*b5893f02SDimitry Andric       ResolveFn(m_func_method_names);
12814ba319b5SDimitry Andric     }
12824ba319b5SDimitry Andric     if (name_type_mask & eFunctionNameTypeBase) {
12834ba319b5SDimitry Andric       ResolveFn(m_func_base_names);
12844ba319b5SDimitry Andric     }
12854ba319b5SDimitry Andric     if (name_type_mask & eFunctionNameTypeMethod) {
12864ba319b5SDimitry Andric       ResolveFn(m_func_method_names);
12874ba319b5SDimitry Andric     }
12884ba319b5SDimitry Andric   }
12894ba319b5SDimitry Andric   return sc_list.GetSize() - old_size;
12904bb0738eSEd Maste }
12914bb0738eSEd Maste 
12924bb0738eSEd Maste uint32_t
FindFunctions(const lldb_private::RegularExpression & regex,bool include_inlines,bool append,lldb_private::SymbolContextList & sc_list)1293435933ddSDimitry Andric SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
1294435933ddSDimitry Andric                              bool include_inlines, bool append,
1295435933ddSDimitry Andric                              lldb_private::SymbolContextList &sc_list) {
12964ba319b5SDimitry Andric   if (!append)
12974ba319b5SDimitry Andric     sc_list.Clear();
12984ba319b5SDimitry Andric   if (!regex.IsValid())
12994ba319b5SDimitry Andric     return 0;
13004ba319b5SDimitry Andric 
13014ba319b5SDimitry Andric   auto old_size = sc_list.GetSize();
13024ba319b5SDimitry Andric   CacheFunctionNames();
13034ba319b5SDimitry Andric 
13044ba319b5SDimitry Andric   std::set<uint32_t> resolved_ids;
13054ba319b5SDimitry Andric   auto ResolveFn = [&regex, include_inlines, &sc_list, &resolved_ids,
13064ba319b5SDimitry Andric                     this](UniqueCStringMap<uint32_t> &Names) {
13074ba319b5SDimitry Andric     std::vector<uint32_t> ids;
13084ba319b5SDimitry Andric     if (Names.GetValues(regex, ids)) {
13094ba319b5SDimitry Andric       for (auto id : ids) {
13104ba319b5SDimitry Andric         if (resolved_ids.find(id) == resolved_ids.end())
13114ba319b5SDimitry Andric           if (ResolveFunction(id, include_inlines, sc_list))
13124ba319b5SDimitry Andric             resolved_ids.insert(id);
13134ba319b5SDimitry Andric       }
13144ba319b5SDimitry Andric     }
13154ba319b5SDimitry Andric   };
13164ba319b5SDimitry Andric   ResolveFn(m_func_full_names);
13174ba319b5SDimitry Andric   ResolveFn(m_func_base_names);
13184ba319b5SDimitry Andric 
13194ba319b5SDimitry Andric   return sc_list.GetSize() - old_size;
13204bb0738eSEd Maste }
13214bb0738eSEd Maste 
GetMangledNamesForFunction(const std::string & scope_qualified_name,std::vector<lldb_private::ConstString> & mangled_names)1322435933ddSDimitry Andric void SymbolFilePDB::GetMangledNamesForFunction(
1323435933ddSDimitry Andric     const std::string &scope_qualified_name,
1324435933ddSDimitry Andric     std::vector<lldb_private::ConstString> &mangled_names) {}
13254bb0738eSEd Maste 
AddSymbols(lldb_private::Symtab & symtab)1326*b5893f02SDimitry Andric void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
1327*b5893f02SDimitry Andric   std::set<lldb::addr_t> sym_addresses;
1328*b5893f02SDimitry Andric   for (size_t i = 0; i < symtab.GetNumSymbols(); i++)
1329*b5893f02SDimitry Andric     sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress());
1330*b5893f02SDimitry Andric 
1331*b5893f02SDimitry Andric   auto results = m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>();
1332*b5893f02SDimitry Andric   if (!results)
1333*b5893f02SDimitry Andric     return;
1334*b5893f02SDimitry Andric 
1335*b5893f02SDimitry Andric   auto section_list = m_obj_file->GetSectionList();
1336*b5893f02SDimitry Andric   if (!section_list)
1337*b5893f02SDimitry Andric     return;
1338*b5893f02SDimitry Andric 
1339*b5893f02SDimitry Andric   while (auto pub_symbol = results->getNext()) {
1340*b5893f02SDimitry Andric     auto section_idx = pub_symbol->getAddressSection() - 1;
1341*b5893f02SDimitry Andric     if (section_idx >= section_list->GetSize())
1342*b5893f02SDimitry Andric       continue;
1343*b5893f02SDimitry Andric 
1344*b5893f02SDimitry Andric     auto section = section_list->GetSectionAtIndex(section_idx);
1345*b5893f02SDimitry Andric     if (!section)
1346*b5893f02SDimitry Andric       continue;
1347*b5893f02SDimitry Andric 
1348*b5893f02SDimitry Andric     auto offset = pub_symbol->getAddressOffset();
1349*b5893f02SDimitry Andric 
1350*b5893f02SDimitry Andric     auto file_addr = section->GetFileAddress() + offset;
1351*b5893f02SDimitry Andric     if (sym_addresses.find(file_addr) != sym_addresses.end())
1352*b5893f02SDimitry Andric       continue;
1353*b5893f02SDimitry Andric     sym_addresses.insert(file_addr);
1354*b5893f02SDimitry Andric 
1355*b5893f02SDimitry Andric     auto size = pub_symbol->getLength();
1356*b5893f02SDimitry Andric     symtab.AddSymbol(
1357*b5893f02SDimitry Andric         Symbol(pub_symbol->getSymIndexId(),   // symID
1358*b5893f02SDimitry Andric                pub_symbol->getName().c_str(), // name
1359*b5893f02SDimitry Andric                true,                          // name_is_mangled
1360*b5893f02SDimitry Andric                pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type
1361*b5893f02SDimitry Andric                true,      // external
1362*b5893f02SDimitry Andric                false,     // is_debug
1363*b5893f02SDimitry Andric                false,     // is_trampoline
1364*b5893f02SDimitry Andric                false,     // is_artificial
1365*b5893f02SDimitry Andric                section,   // section_sp
1366*b5893f02SDimitry Andric                offset,    // value
1367*b5893f02SDimitry Andric                size,      // size
1368*b5893f02SDimitry Andric                size != 0, // size_is_valid
1369*b5893f02SDimitry Andric                false,     // contains_linker_annotations
1370*b5893f02SDimitry Andric                0          // flags
1371*b5893f02SDimitry Andric                ));
1372*b5893f02SDimitry Andric   }
1373*b5893f02SDimitry Andric 
1374*b5893f02SDimitry Andric   symtab.CalculateSymbolSizes();
1375*b5893f02SDimitry Andric   symtab.Finalize();
1376*b5893f02SDimitry Andric }
1377*b5893f02SDimitry Andric 
FindTypes(const lldb_private::ConstString & name,const lldb_private::CompilerDeclContext * parent_decl_ctx,bool append,uint32_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,lldb_private::TypeMap & types)1378435933ddSDimitry Andric uint32_t SymbolFilePDB::FindTypes(
1379435933ddSDimitry Andric     const lldb_private::ConstString &name,
1380435933ddSDimitry Andric     const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
1381435933ddSDimitry Andric     uint32_t max_matches,
13824bb0738eSEd Maste     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1383435933ddSDimitry Andric     lldb_private::TypeMap &types) {
13844bb0738eSEd Maste   if (!append)
13854bb0738eSEd Maste     types.Clear();
13864bb0738eSEd Maste   if (!name)
13874bb0738eSEd Maste     return 0;
13884ba319b5SDimitry Andric   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
13894ba319b5SDimitry Andric     return 0;
13904bb0738eSEd Maste 
13914bb0738eSEd Maste   searched_symbol_files.clear();
13924bb0738eSEd Maste   searched_symbol_files.insert(this);
13934bb0738eSEd Maste 
139438638513SDimitry Andric   // There is an assumption 'name' is not a regex
1395*b5893f02SDimitry Andric   FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
139638638513SDimitry Andric 
13974bb0738eSEd Maste   return types.GetSize();
13984bb0738eSEd Maste }
13994bb0738eSEd Maste 
DumpClangAST(Stream & s)1400*b5893f02SDimitry Andric void SymbolFilePDB::DumpClangAST(Stream &s) {
1401*b5893f02SDimitry Andric   auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1402*b5893f02SDimitry Andric   auto clang = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
1403*b5893f02SDimitry Andric   if (!clang)
1404*b5893f02SDimitry Andric     return;
1405*b5893f02SDimitry Andric   clang->Dump(s);
1406*b5893f02SDimitry Andric }
1407*b5893f02SDimitry Andric 
FindTypesByRegex(const lldb_private::RegularExpression & regex,uint32_t max_matches,lldb_private::TypeMap & types)14084ba319b5SDimitry Andric void SymbolFilePDB::FindTypesByRegex(
14094ba319b5SDimitry Andric     const lldb_private::RegularExpression &regex, uint32_t max_matches,
1410435933ddSDimitry Andric     lldb_private::TypeMap &types) {
1411435933ddSDimitry Andric   // When searching by regex, we need to go out of our way to limit the search
1412f678e45dSDimitry Andric   // space as much as possible since this searches EVERYTHING in the PDB,
1413f678e45dSDimitry Andric   // manually doing regex comparisons.  PDB library isn't optimized for regex
1414f678e45dSDimitry Andric   // searches or searches across multiple symbol types at the same time, so the
1415435933ddSDimitry Andric   // best we can do is to search enums, then typedefs, then classes one by one,
1416f678e45dSDimitry Andric   // and do a regex comparison against each of them.
1417435933ddSDimitry Andric   PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
1418435933ddSDimitry Andric                                   PDB_SymType::UDT};
14194bb0738eSEd Maste   std::unique_ptr<IPDBEnumSymbols> results;
14204bb0738eSEd Maste 
14214bb0738eSEd Maste   uint32_t matches = 0;
14224bb0738eSEd Maste 
1423435933ddSDimitry Andric   for (auto tag : tags_to_search) {
14244ba319b5SDimitry Andric     results = m_global_scope_up->findAllChildren(tag);
14254ba319b5SDimitry Andric     if (!results)
14264ba319b5SDimitry Andric       continue;
14274ba319b5SDimitry Andric 
1428435933ddSDimitry Andric     while (auto result = results->getNext()) {
14294bb0738eSEd Maste       if (max_matches > 0 && matches >= max_matches)
14304bb0738eSEd Maste         break;
14314bb0738eSEd Maste 
14324bb0738eSEd Maste       std::string type_name;
14334bb0738eSEd Maste       if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
14344bb0738eSEd Maste         type_name = enum_type->getName();
1435435933ddSDimitry Andric       else if (auto typedef_type =
1436435933ddSDimitry Andric                    llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
14374bb0738eSEd Maste         type_name = typedef_type->getName();
14384bb0738eSEd Maste       else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
14394bb0738eSEd Maste         type_name = class_type->getName();
1440435933ddSDimitry Andric       else {
1441f678e45dSDimitry Andric         // We're looking only for types that have names.  Skip symbols, as well
1442f678e45dSDimitry Andric         // as unnamed types such as arrays, pointers, etc.
14434bb0738eSEd Maste         continue;
14444bb0738eSEd Maste       }
14454bb0738eSEd Maste 
144638638513SDimitry Andric       if (!regex.Execute(type_name))
14474bb0738eSEd Maste         continue;
14484bb0738eSEd Maste 
1449435933ddSDimitry Andric       // This should cause the type to get cached and stored in the `m_types`
1450435933ddSDimitry Andric       // lookup.
14514bb0738eSEd Maste       if (!ResolveTypeUID(result->getSymIndexId()))
14524bb0738eSEd Maste         continue;
14534bb0738eSEd Maste 
14544bb0738eSEd Maste       auto iter = m_types.find(result->getSymIndexId());
14554bb0738eSEd Maste       if (iter == m_types.end())
14564bb0738eSEd Maste         continue;
14574bb0738eSEd Maste       types.Insert(iter->second);
14584bb0738eSEd Maste       ++matches;
14594bb0738eSEd Maste     }
14604bb0738eSEd Maste   }
14614bb0738eSEd Maste }
14624bb0738eSEd Maste 
FindTypesByName(llvm::StringRef name,const lldb_private::CompilerDeclContext * parent_decl_ctx,uint32_t max_matches,lldb_private::TypeMap & types)1463*b5893f02SDimitry Andric void SymbolFilePDB::FindTypesByName(
1464*b5893f02SDimitry Andric     llvm::StringRef name,
1465*b5893f02SDimitry Andric     const lldb_private::CompilerDeclContext *parent_decl_ctx,
1466*b5893f02SDimitry Andric     uint32_t max_matches, lldb_private::TypeMap &types) {
14674bb0738eSEd Maste   std::unique_ptr<IPDBEnumSymbols> results;
14684ba319b5SDimitry Andric   if (name.empty())
14694ba319b5SDimitry Andric     return;
1470*b5893f02SDimitry Andric   results = m_global_scope_up->findAllChildren(PDB_SymType::None);
14714ba319b5SDimitry Andric   if (!results)
14724ba319b5SDimitry Andric     return;
14734bb0738eSEd Maste 
14744bb0738eSEd Maste   uint32_t matches = 0;
14754bb0738eSEd Maste 
1476435933ddSDimitry Andric   while (auto result = results->getNext()) {
14774bb0738eSEd Maste     if (max_matches > 0 && matches >= max_matches)
14784bb0738eSEd Maste       break;
1479*b5893f02SDimitry Andric 
1480*b5893f02SDimitry Andric     if (MSVCUndecoratedNameParser::DropScope(
1481*b5893f02SDimitry Andric             result->getRawSymbol().getName()) != name)
1482*b5893f02SDimitry Andric       continue;
1483*b5893f02SDimitry Andric 
1484435933ddSDimitry Andric     switch (result->getSymTag()) {
14854bb0738eSEd Maste     case PDB_SymType::Enum:
14864bb0738eSEd Maste     case PDB_SymType::UDT:
14874bb0738eSEd Maste     case PDB_SymType::Typedef:
14884bb0738eSEd Maste       break;
14894bb0738eSEd Maste     default:
14904ba319b5SDimitry Andric       // We're looking only for types that have names.  Skip symbols, as well
14914ba319b5SDimitry Andric       // as unnamed types such as arrays, pointers, etc.
14924bb0738eSEd Maste       continue;
14934bb0738eSEd Maste     }
14944bb0738eSEd Maste 
1495435933ddSDimitry Andric     // This should cause the type to get cached and stored in the `m_types`
1496435933ddSDimitry Andric     // lookup.
14974bb0738eSEd Maste     if (!ResolveTypeUID(result->getSymIndexId()))
14984bb0738eSEd Maste       continue;
14994bb0738eSEd Maste 
1500*b5893f02SDimitry Andric     if (parent_decl_ctx && GetDeclContextContainingUID(
1501*b5893f02SDimitry Andric                                result->getSymIndexId()) != *parent_decl_ctx)
1502*b5893f02SDimitry Andric       continue;
1503*b5893f02SDimitry Andric 
15044bb0738eSEd Maste     auto iter = m_types.find(result->getSymIndexId());
15054bb0738eSEd Maste     if (iter == m_types.end())
15064bb0738eSEd Maste       continue;
15074bb0738eSEd Maste     types.Insert(iter->second);
15084bb0738eSEd Maste     ++matches;
15094bb0738eSEd Maste   }
15104bb0738eSEd Maste }
15114bb0738eSEd Maste 
FindTypes(const std::vector<lldb_private::CompilerContext> & contexts,bool append,lldb_private::TypeMap & types)1512435933ddSDimitry Andric size_t SymbolFilePDB::FindTypes(
1513435933ddSDimitry Andric     const std::vector<lldb_private::CompilerContext> &contexts, bool append,
1514435933ddSDimitry Andric     lldb_private::TypeMap &types) {
15154bb0738eSEd Maste   return 0;
15164bb0738eSEd Maste }
15174bb0738eSEd Maste 
GetTypeList()15184ba319b5SDimitry Andric lldb_private::TypeList *SymbolFilePDB::GetTypeList() {
15194ba319b5SDimitry Andric   return m_obj_file->GetModule()->GetTypeList();
15204ba319b5SDimitry Andric }
15214ba319b5SDimitry Andric 
GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol & pdb_symbol,uint32_t type_mask,TypeCollection & type_collection)15224ba319b5SDimitry Andric void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
15234ba319b5SDimitry Andric                                          uint32_t type_mask,
15244ba319b5SDimitry Andric                                          TypeCollection &type_collection) {
15254ba319b5SDimitry Andric   bool can_parse = false;
15264ba319b5SDimitry Andric   switch (pdb_symbol.getSymTag()) {
15274ba319b5SDimitry Andric   case PDB_SymType::ArrayType:
15284ba319b5SDimitry Andric     can_parse = ((type_mask & eTypeClassArray) != 0);
15294ba319b5SDimitry Andric     break;
15304ba319b5SDimitry Andric   case PDB_SymType::BuiltinType:
15314ba319b5SDimitry Andric     can_parse = ((type_mask & eTypeClassBuiltin) != 0);
15324ba319b5SDimitry Andric     break;
15334ba319b5SDimitry Andric   case PDB_SymType::Enum:
15344ba319b5SDimitry Andric     can_parse = ((type_mask & eTypeClassEnumeration) != 0);
15354ba319b5SDimitry Andric     break;
15364ba319b5SDimitry Andric   case PDB_SymType::Function:
15374ba319b5SDimitry Andric   case PDB_SymType::FunctionSig:
15384ba319b5SDimitry Andric     can_parse = ((type_mask & eTypeClassFunction) != 0);
15394ba319b5SDimitry Andric     break;
15404ba319b5SDimitry Andric   case PDB_SymType::PointerType:
15414ba319b5SDimitry Andric     can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer |
15424ba319b5SDimitry Andric                                eTypeClassMemberPointer)) != 0);
15434ba319b5SDimitry Andric     break;
15444ba319b5SDimitry Andric   case PDB_SymType::Typedef:
15454ba319b5SDimitry Andric     can_parse = ((type_mask & eTypeClassTypedef) != 0);
15464ba319b5SDimitry Andric     break;
15474ba319b5SDimitry Andric   case PDB_SymType::UDT: {
15484ba319b5SDimitry Andric     auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol);
15494ba319b5SDimitry Andric     assert(udt);
15504ba319b5SDimitry Andric     can_parse = (udt->getUdtKind() != PDB_UdtType::Interface &&
15514ba319b5SDimitry Andric                  ((type_mask & (eTypeClassClass | eTypeClassStruct |
15524ba319b5SDimitry Andric                                 eTypeClassUnion)) != 0));
15534ba319b5SDimitry Andric   } break;
15544ba319b5SDimitry Andric   default:
15554ba319b5SDimitry Andric     break;
15564ba319b5SDimitry Andric   }
15574ba319b5SDimitry Andric 
15584ba319b5SDimitry Andric   if (can_parse) {
15594ba319b5SDimitry Andric     if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) {
15604ba319b5SDimitry Andric       auto result =
15614ba319b5SDimitry Andric           std::find(type_collection.begin(), type_collection.end(), type);
15624ba319b5SDimitry Andric       if (result == type_collection.end())
15634ba319b5SDimitry Andric         type_collection.push_back(type);
15644ba319b5SDimitry Andric     }
15654ba319b5SDimitry Andric   }
15664ba319b5SDimitry Andric 
15674ba319b5SDimitry Andric   auto results_up = pdb_symbol.findAllChildren();
15684ba319b5SDimitry Andric   while (auto symbol_up = results_up->getNext())
15694ba319b5SDimitry Andric     GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
15704ba319b5SDimitry Andric }
15714bb0738eSEd Maste 
GetTypes(lldb_private::SymbolContextScope * sc_scope,TypeClass type_mask,lldb_private::TypeList & type_list)1572435933ddSDimitry Andric size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
1573*b5893f02SDimitry Andric                                TypeClass type_mask,
1574435933ddSDimitry Andric                                lldb_private::TypeList &type_list) {
15754ba319b5SDimitry Andric   TypeCollection type_collection;
15764ba319b5SDimitry Andric   uint32_t old_size = type_list.GetSize();
15774ba319b5SDimitry Andric   CompileUnit *cu =
15784ba319b5SDimitry Andric       sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
15794ba319b5SDimitry Andric   if (cu) {
15804ba319b5SDimitry Andric     auto compiland_up = GetPDBCompilandByUID(cu->GetID());
15814ba319b5SDimitry Andric     if (!compiland_up)
15824ba319b5SDimitry Andric       return 0;
15834ba319b5SDimitry Andric     GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
15844ba319b5SDimitry Andric   } else {
15854ba319b5SDimitry Andric     for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
15864ba319b5SDimitry Andric       auto cu_sp = ParseCompileUnitAtIndex(cu_idx);
15874ba319b5SDimitry Andric       if (cu_sp) {
15884ba319b5SDimitry Andric         if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID()))
15894ba319b5SDimitry Andric           GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
15904ba319b5SDimitry Andric       }
15914ba319b5SDimitry Andric     }
15924ba319b5SDimitry Andric   }
15934ba319b5SDimitry Andric 
15944ba319b5SDimitry Andric   for (auto type : type_collection) {
15954ba319b5SDimitry Andric     type->GetForwardCompilerType();
15964ba319b5SDimitry Andric     type_list.Insert(type->shared_from_this());
15974ba319b5SDimitry Andric   }
15984ba319b5SDimitry Andric   return type_list.GetSize() - old_size;
15994bb0738eSEd Maste }
16004bb0738eSEd Maste 
16014bb0738eSEd Maste lldb_private::TypeSystem *
GetTypeSystemForLanguage(lldb::LanguageType language)1602435933ddSDimitry Andric SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
1603435933ddSDimitry Andric   auto type_system =
1604435933ddSDimitry Andric       m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
16054bb0738eSEd Maste   if (type_system)
16064bb0738eSEd Maste     type_system->SetSymbolFile(this);
16074bb0738eSEd Maste   return type_system;
16084bb0738eSEd Maste }
16094bb0738eSEd Maste 
GetPDBAstParser()1610*b5893f02SDimitry Andric PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
1611*b5893f02SDimitry Andric   auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1612*b5893f02SDimitry Andric   auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
1613*b5893f02SDimitry Andric   if (!clang_type_system)
1614*b5893f02SDimitry Andric     return nullptr;
1615*b5893f02SDimitry Andric 
1616*b5893f02SDimitry Andric   return clang_type_system->GetPDBParser();
1617*b5893f02SDimitry Andric }
1618*b5893f02SDimitry Andric 
1619*b5893f02SDimitry Andric 
FindNamespace(const lldb_private::ConstString & name,const lldb_private::CompilerDeclContext * parent_decl_ctx)1620435933ddSDimitry Andric lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
1621435933ddSDimitry Andric     const lldb_private::ConstString &name,
1622435933ddSDimitry Andric     const lldb_private::CompilerDeclContext *parent_decl_ctx) {
1623*b5893f02SDimitry Andric   auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1624*b5893f02SDimitry Andric   auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
1625*b5893f02SDimitry Andric   if (!clang_type_system)
1626*b5893f02SDimitry Andric     return CompilerDeclContext();
1627*b5893f02SDimitry Andric 
1628*b5893f02SDimitry Andric   PDBASTParser *pdb = clang_type_system->GetPDBParser();
1629*b5893f02SDimitry Andric   if (!pdb)
1630*b5893f02SDimitry Andric     return CompilerDeclContext();
1631*b5893f02SDimitry Andric 
1632*b5893f02SDimitry Andric   clang::DeclContext *decl_context = nullptr;
1633*b5893f02SDimitry Andric   if (parent_decl_ctx)
1634*b5893f02SDimitry Andric     decl_context = static_cast<clang::DeclContext *>(
1635*b5893f02SDimitry Andric         parent_decl_ctx->GetOpaqueDeclContext());
1636*b5893f02SDimitry Andric 
1637*b5893f02SDimitry Andric   auto namespace_decl =
1638*b5893f02SDimitry Andric       pdb->FindNamespaceDecl(decl_context, name.GetStringRef());
1639*b5893f02SDimitry Andric   if (!namespace_decl)
1640*b5893f02SDimitry Andric     return CompilerDeclContext();
1641*b5893f02SDimitry Andric 
1642*b5893f02SDimitry Andric   return CompilerDeclContext(type_system,
1643*b5893f02SDimitry Andric                              static_cast<clang::DeclContext *>(namespace_decl));
16444bb0738eSEd Maste }
16454bb0738eSEd Maste 
GetPluginName()1646435933ddSDimitry Andric lldb_private::ConstString SymbolFilePDB::GetPluginName() {
16474bb0738eSEd Maste   static ConstString g_name("pdb");
16484bb0738eSEd Maste   return g_name;
16494bb0738eSEd Maste }
16504bb0738eSEd Maste 
GetPluginVersion()1651435933ddSDimitry Andric uint32_t SymbolFilePDB::GetPluginVersion() { return 1; }
16524bb0738eSEd Maste 
GetPDBSession()1653435933ddSDimitry Andric IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }
1654435933ddSDimitry Andric 
GetPDBSession() const1655435933ddSDimitry Andric const IPDBSession &SymbolFilePDB::GetPDBSession() const {
16564bb0738eSEd Maste   return *m_session_up;
16574bb0738eSEd Maste }
16584bb0738eSEd Maste 
ParseCompileUnitForUID(uint32_t id,uint32_t index)16594ba319b5SDimitry Andric lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
16604ba319b5SDimitry Andric                                                        uint32_t index) {
16614bb0738eSEd Maste   auto found_cu = m_comp_units.find(id);
16624bb0738eSEd Maste   if (found_cu != m_comp_units.end())
16634bb0738eSEd Maste     return found_cu->second;
16644bb0738eSEd Maste 
16654ba319b5SDimitry Andric   auto compiland_up = GetPDBCompilandByUID(id);
16664ba319b5SDimitry Andric   if (!compiland_up)
16674ba319b5SDimitry Andric     return CompUnitSP();
16684bb0738eSEd Maste 
16694bb0738eSEd Maste   lldb::LanguageType lang;
16704ba319b5SDimitry Andric   auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
16714bb0738eSEd Maste   if (!details)
16724bb0738eSEd Maste     lang = lldb::eLanguageTypeC_plus_plus;
16734bb0738eSEd Maste   else
16744bb0738eSEd Maste     lang = TranslateLanguage(details->getLanguage());
16754bb0738eSEd Maste 
16764ba319b5SDimitry Andric   if (lang == lldb::LanguageType::eLanguageTypeUnknown)
16774ba319b5SDimitry Andric     return CompUnitSP();
16784ba319b5SDimitry Andric 
16794ba319b5SDimitry Andric   std::string path = compiland_up->getSourceFileFullPath();
16804ba319b5SDimitry Andric   if (path.empty())
16814ba319b5SDimitry Andric     return CompUnitSP();
16824ba319b5SDimitry Andric 
1683435933ddSDimitry Andric   // Don't support optimized code for now, DebugInfoPDB does not return this
1684435933ddSDimitry Andric   // information.
16854bb0738eSEd Maste   LazyBool optimized = eLazyBoolNo;
16864ba319b5SDimitry Andric   auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr,
16874ba319b5SDimitry Andric                                              path.c_str(), id, lang, optimized);
16884ba319b5SDimitry Andric 
16894ba319b5SDimitry Andric   if (!cu_sp)
16904ba319b5SDimitry Andric     return CompUnitSP();
16914ba319b5SDimitry Andric 
16924ba319b5SDimitry Andric   m_comp_units.insert(std::make_pair(id, cu_sp));
16934ba319b5SDimitry Andric   if (index == UINT32_MAX)
16944ba319b5SDimitry Andric     GetCompileUnitIndex(*compiland_up, index);
16954ba319b5SDimitry Andric   lldbassert(index != UINT32_MAX);
16964ba319b5SDimitry Andric   m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(index,
16974ba319b5SDimitry Andric                                                                     cu_sp);
16984ba319b5SDimitry Andric   return cu_sp;
16994bb0738eSEd Maste }
17004bb0738eSEd Maste 
ParseCompileUnitLineTable(CompileUnit & comp_unit,uint32_t match_line)1701*b5893f02SDimitry Andric bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
1702*b5893f02SDimitry Andric                                               uint32_t match_line) {
1703*b5893f02SDimitry Andric   auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
17044ba319b5SDimitry Andric   if (!compiland_up)
17054ba319b5SDimitry Andric     return false;
17064bb0738eSEd Maste 
1707435933ddSDimitry Andric   // LineEntry needs the *index* of the file into the list of support files
1708f678e45dSDimitry Andric   // returned by ParseCompileUnitSupportFiles.  But the underlying SDK gives us
17094ba319b5SDimitry Andric   // a globally unique idenfitifier in the namespace of the PDB.  So, we have
17104ba319b5SDimitry Andric   // to do a mapping so that we can hand out indices.
17114bb0738eSEd Maste   llvm::DenseMap<uint32_t, uint32_t> index_map;
17124ba319b5SDimitry Andric   BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
1713*b5893f02SDimitry Andric   auto line_table = llvm::make_unique<LineTable>(&comp_unit);
17144bb0738eSEd Maste 
17154ba319b5SDimitry Andric   // Find contributions to `compiland` from all source and header files.
1716*b5893f02SDimitry Andric   std::string path = comp_unit.GetPath();
17174ba319b5SDimitry Andric   auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
17184ba319b5SDimitry Andric   if (!files)
17194ba319b5SDimitry Andric     return false;
17204bb0738eSEd Maste 
17214ba319b5SDimitry Andric   // For each source and header file, create a LineSequence for contributions
17224ba319b5SDimitry Andric   // to the compiland from that file, and add the sequence.
1723435933ddSDimitry Andric   while (auto file = files->getNext()) {
1724435933ddSDimitry Andric     std::unique_ptr<LineSequence> sequence(
1725435933ddSDimitry Andric         line_table->CreateLineSequenceContainer());
17264ba319b5SDimitry Andric     auto lines = m_session_up->findLineNumbers(*compiland_up, *file);
17274ba319b5SDimitry Andric     if (!lines)
17284ba319b5SDimitry Andric       continue;
17294bb0738eSEd Maste     int entry_count = lines->getChildCount();
17304bb0738eSEd Maste 
17314bb0738eSEd Maste     uint64_t prev_addr;
17324bb0738eSEd Maste     uint32_t prev_length;
17334bb0738eSEd Maste     uint32_t prev_line;
17344bb0738eSEd Maste     uint32_t prev_source_idx;
17354bb0738eSEd Maste 
1736435933ddSDimitry Andric     for (int i = 0; i < entry_count; ++i) {
17374bb0738eSEd Maste       auto line = lines->getChildAtIndex(i);
17384bb0738eSEd Maste 
17394bb0738eSEd Maste       uint64_t lno = line->getLineNumber();
17404bb0738eSEd Maste       uint64_t addr = line->getVirtualAddress();
17414bb0738eSEd Maste       uint32_t length = line->getLength();
17424bb0738eSEd Maste       uint32_t source_id = line->getSourceFileId();
17434bb0738eSEd Maste       uint32_t col = line->getColumnNumber();
17444bb0738eSEd Maste       uint32_t source_idx = index_map[source_id];
17454bb0738eSEd Maste 
17464ba319b5SDimitry Andric       // There was a gap between the current entry and the previous entry if
17474ba319b5SDimitry Andric       // the addresses don't perfectly line up.
17484bb0738eSEd Maste       bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
17494bb0738eSEd Maste 
1750435933ddSDimitry Andric       // Before inserting the current entry, insert a terminal entry at the end
1751f678e45dSDimitry Andric       // of the previous entry's address range if the current entry resulted in
1752f678e45dSDimitry Andric       // a gap from the previous entry.
1753435933ddSDimitry Andric       if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {
1754435933ddSDimitry Andric         line_table->AppendLineEntryToSequence(
1755435933ddSDimitry Andric             sequence.get(), prev_addr + prev_length, prev_line, 0,
17564bb0738eSEd Maste             prev_source_idx, false, false, false, false, true);
17574ba319b5SDimitry Andric 
17584ba319b5SDimitry Andric         line_table->InsertSequence(sequence.release());
17594ba319b5SDimitry Andric         sequence.reset(line_table->CreateLineSequenceContainer());
17604bb0738eSEd Maste       }
17614bb0738eSEd Maste 
1762435933ddSDimitry Andric       if (ShouldAddLine(match_line, lno, length)) {
17634bb0738eSEd Maste         bool is_statement = line->isStatement();
17644bb0738eSEd Maste         bool is_prologue = false;
17654bb0738eSEd Maste         bool is_epilogue = false;
1766435933ddSDimitry Andric         auto func =
1767435933ddSDimitry Andric             m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
1768435933ddSDimitry Andric         if (func) {
17694bb0738eSEd Maste           auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
17704ba319b5SDimitry Andric           if (prologue)
17714bb0738eSEd Maste             is_prologue = (addr == prologue->getVirtualAddress());
17724bb0738eSEd Maste 
17734bb0738eSEd Maste           auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
17744ba319b5SDimitry Andric           if (epilogue)
17754bb0738eSEd Maste             is_epilogue = (addr == epilogue->getVirtualAddress());
17764bb0738eSEd Maste         }
17774bb0738eSEd Maste 
1778435933ddSDimitry Andric         line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
1779435933ddSDimitry Andric                                               source_idx, is_statement, false,
17804bb0738eSEd Maste                                               is_prologue, is_epilogue, false);
17814bb0738eSEd Maste       }
17824bb0738eSEd Maste 
17834bb0738eSEd Maste       prev_addr = addr;
17844bb0738eSEd Maste       prev_length = length;
17854bb0738eSEd Maste       prev_line = lno;
17864bb0738eSEd Maste       prev_source_idx = source_idx;
17874bb0738eSEd Maste     }
17884bb0738eSEd Maste 
1789435933ddSDimitry Andric     if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {
17904bb0738eSEd Maste       // The end is always a terminal entry, so insert it regardless.
1791435933ddSDimitry Andric       line_table->AppendLineEntryToSequence(
1792435933ddSDimitry Andric           sequence.get(), prev_addr + prev_length, prev_line, 0,
17934bb0738eSEd Maste           prev_source_idx, false, false, false, false, true);
17944bb0738eSEd Maste     }
17954bb0738eSEd Maste 
17964bb0738eSEd Maste     line_table->InsertSequence(sequence.release());
17974bb0738eSEd Maste   }
17984bb0738eSEd Maste 
17994ba319b5SDimitry Andric   if (line_table->GetSize()) {
1800*b5893f02SDimitry Andric     comp_unit.SetLineTable(line_table.release());
18014bb0738eSEd Maste     return true;
18024bb0738eSEd Maste   }
18034ba319b5SDimitry Andric   return false;
18044ba319b5SDimitry Andric }
18054bb0738eSEd Maste 
BuildSupportFileIdToSupportFileIndexMap(const PDBSymbolCompiland & compiland,llvm::DenseMap<uint32_t,uint32_t> & index_map) const1806435933ddSDimitry Andric void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
18074ba319b5SDimitry Andric     const PDBSymbolCompiland &compiland,
1808435933ddSDimitry Andric     llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
18094ba319b5SDimitry Andric   // This is a hack, but we need to convert the source id into an index into
18104ba319b5SDimitry Andric   // the support files array.  We don't want to do path comparisons to avoid
1811f678e45dSDimitry Andric   // basename / full path issues that may or may not even be a problem, so we
1812f678e45dSDimitry Andric   // use the globally unique source file identifiers.  Ideally we could use the
1813f678e45dSDimitry Andric   // global identifiers everywhere, but LineEntry currently assumes indices.
18144ba319b5SDimitry Andric   auto source_files = m_session_up->getSourceFilesForCompiland(compiland);
18154ba319b5SDimitry Andric   if (!source_files)
18164ba319b5SDimitry Andric     return;
18174ba319b5SDimitry Andric 
18184ba319b5SDimitry Andric   // LLDB uses the DWARF-like file numeration (one based)
18194ba319b5SDimitry Andric   int index = 1;
18204bb0738eSEd Maste 
1821435933ddSDimitry Andric   while (auto file = source_files->getNext()) {
18224bb0738eSEd Maste     uint32_t source_id = file->getUniqueId();
18234bb0738eSEd Maste     index_map[source_id] = index++;
18244bb0738eSEd Maste   }
18254bb0738eSEd Maste }
18264ba319b5SDimitry Andric 
GetCompileUnitContainsAddress(const lldb_private::Address & so_addr)18274ba319b5SDimitry Andric lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress(
18284ba319b5SDimitry Andric     const lldb_private::Address &so_addr) {
18294ba319b5SDimitry Andric   lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
18304ba319b5SDimitry Andric   if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
18314ba319b5SDimitry Andric     return nullptr;
18324ba319b5SDimitry Andric 
18334ba319b5SDimitry Andric   // If it is a PDB function's vm addr, this is the first sure bet.
18344ba319b5SDimitry Andric   if (auto lines =
18354ba319b5SDimitry Andric           m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/1)) {
18364ba319b5SDimitry Andric     if (auto first_line = lines->getNext())
18374ba319b5SDimitry Andric       return ParseCompileUnitForUID(first_line->getCompilandId());
18384ba319b5SDimitry Andric   }
18394ba319b5SDimitry Andric 
18404ba319b5SDimitry Andric   // Otherwise we resort to section contributions.
18414ba319b5SDimitry Andric   if (auto sec_contribs = m_session_up->getSectionContribs()) {
18424ba319b5SDimitry Andric     while (auto section = sec_contribs->getNext()) {
18434ba319b5SDimitry Andric       auto va = section->getVirtualAddress();
18444ba319b5SDimitry Andric       if (file_vm_addr >= va && file_vm_addr < va + section->getLength())
18454ba319b5SDimitry Andric         return ParseCompileUnitForUID(section->getCompilandId());
18464ba319b5SDimitry Andric     }
18474ba319b5SDimitry Andric   }
18484ba319b5SDimitry Andric   return nullptr;
18494ba319b5SDimitry Andric }
18504ba319b5SDimitry Andric 
18514ba319b5SDimitry Andric Mangled
GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc & pdb_func)18524ba319b5SDimitry Andric SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
18534ba319b5SDimitry Andric   Mangled mangled;
18544ba319b5SDimitry Andric   auto func_name = pdb_func.getName();
18554ba319b5SDimitry Andric   auto func_undecorated_name = pdb_func.getUndecoratedName();
18564ba319b5SDimitry Andric   std::string func_decorated_name;
18574ba319b5SDimitry Andric 
18584ba319b5SDimitry Andric   // Seek from public symbols for non-static function's decorated name if any.
18594ba319b5SDimitry Andric   // For static functions, they don't have undecorated names and aren't exposed
18604ba319b5SDimitry Andric   // in Public Symbols either.
18614ba319b5SDimitry Andric   if (!func_undecorated_name.empty()) {
18624ba319b5SDimitry Andric     auto result_up = m_global_scope_up->findChildren(
18634ba319b5SDimitry Andric         PDB_SymType::PublicSymbol, func_undecorated_name,
18644ba319b5SDimitry Andric         PDB_NameSearchFlags::NS_UndecoratedName);
18654ba319b5SDimitry Andric     if (result_up) {
18664ba319b5SDimitry Andric       while (auto symbol_up = result_up->getNext()) {
18674ba319b5SDimitry Andric         // For a public symbol, it is unique.
18684ba319b5SDimitry Andric         lldbassert(result_up->getChildCount() == 1);
18694ba319b5SDimitry Andric         if (auto *pdb_public_sym =
18704ba319b5SDimitry Andric                 llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>(
18714ba319b5SDimitry Andric                     symbol_up.get())) {
18724ba319b5SDimitry Andric           if (pdb_public_sym->isFunction()) {
18734ba319b5SDimitry Andric             func_decorated_name = pdb_public_sym->getName();
18744ba319b5SDimitry Andric             break;
18754ba319b5SDimitry Andric           }
18764ba319b5SDimitry Andric         }
18774ba319b5SDimitry Andric       }
18784ba319b5SDimitry Andric     }
18794ba319b5SDimitry Andric   }
18804ba319b5SDimitry Andric   if (!func_decorated_name.empty()) {
18814ba319b5SDimitry Andric     mangled.SetMangledName(ConstString(func_decorated_name));
18824ba319b5SDimitry Andric 
18834ba319b5SDimitry Andric     // For MSVC, format of C funciton's decorated name depends on calling
18844ba319b5SDimitry Andric     // conventon. Unfortunately none of the format is recognized by current
18854ba319b5SDimitry Andric     // LLDB. For example, `_purecall` is a __cdecl C function. From PDB,
18864ba319b5SDimitry Andric     // `__purecall` is retrieved as both its decorated and undecorated name
18874ba319b5SDimitry Andric     // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall`
18884ba319b5SDimitry Andric     // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix).
18894ba319b5SDimitry Andric     // Mangled::GetDemangledName method will fail internally and caches an
18904ba319b5SDimitry Andric     // empty string as its undecorated name. So we will face a contradition
18914ba319b5SDimitry Andric     // here for the same symbol:
18924ba319b5SDimitry Andric     //   non-empty undecorated name from PDB
18934ba319b5SDimitry Andric     //   empty undecorated name from LLDB
18944ba319b5SDimitry Andric     if (!func_undecorated_name.empty() &&
18954ba319b5SDimitry Andric         mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty())
18964ba319b5SDimitry Andric       mangled.SetDemangledName(ConstString(func_undecorated_name));
18974ba319b5SDimitry Andric 
18984ba319b5SDimitry Andric     // LLDB uses several flags to control how a C++ decorated name is
18994ba319b5SDimitry Andric     // undecorated for MSVC. See `safeUndecorateName` in Class Mangled. So the
19004ba319b5SDimitry Andric     // yielded name could be different from what we retrieve from
19014ba319b5SDimitry Andric     // PDB source unless we also apply same flags in getting undecorated
19024ba319b5SDimitry Andric     // name through PDBSymbolFunc::getUndecoratedNameEx method.
19034ba319b5SDimitry Andric     if (!func_undecorated_name.empty() &&
19044ba319b5SDimitry Andric         mangled.GetDemangledName(mangled.GuessLanguage()) !=
19054ba319b5SDimitry Andric             ConstString(func_undecorated_name))
19064ba319b5SDimitry Andric       mangled.SetDemangledName(ConstString(func_undecorated_name));
19074ba319b5SDimitry Andric   } else if (!func_undecorated_name.empty()) {
19084ba319b5SDimitry Andric     mangled.SetDemangledName(ConstString(func_undecorated_name));
19094ba319b5SDimitry Andric   } else if (!func_name.empty())
19104ba319b5SDimitry Andric     mangled.SetValue(ConstString(func_name), false);
19114ba319b5SDimitry Andric 
19124ba319b5SDimitry Andric   return mangled;
19134ba319b5SDimitry Andric }
19144ba319b5SDimitry Andric 
DeclContextMatchesThisSymbolFile(const lldb_private::CompilerDeclContext * decl_ctx)19154ba319b5SDimitry Andric bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
19164ba319b5SDimitry Andric     const lldb_private::CompilerDeclContext *decl_ctx) {
19174ba319b5SDimitry Andric   if (decl_ctx == nullptr || !decl_ctx->IsValid())
19184ba319b5SDimitry Andric     return true;
19194ba319b5SDimitry Andric 
19204ba319b5SDimitry Andric   TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem();
19214ba319b5SDimitry Andric   if (!decl_ctx_type_system)
19224ba319b5SDimitry Andric     return false;
19234ba319b5SDimitry Andric   TypeSystem *type_system = GetTypeSystemForLanguage(
19244ba319b5SDimitry Andric       decl_ctx_type_system->GetMinimumLanguage(nullptr));
19254ba319b5SDimitry Andric   if (decl_ctx_type_system == type_system)
19264ba319b5SDimitry Andric     return true; // The type systems match, return true
19274ba319b5SDimitry Andric 
19284ba319b5SDimitry Andric   return false;
19294ba319b5SDimitry Andric }
1930*b5893f02SDimitry Andric 
GetCompilandId(const llvm::pdb::PDBSymbolData & data)1931*b5893f02SDimitry Andric uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) {
1932*b5893f02SDimitry Andric   static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) {
1933*b5893f02SDimitry Andric     return lhs < rhs.Offset;
1934*b5893f02SDimitry Andric   };
1935*b5893f02SDimitry Andric 
1936*b5893f02SDimitry Andric   // Cache section contributions
1937*b5893f02SDimitry Andric   if (m_sec_contribs.empty()) {
1938*b5893f02SDimitry Andric     if (auto SecContribs = m_session_up->getSectionContribs()) {
1939*b5893f02SDimitry Andric       while (auto SectionContrib = SecContribs->getNext()) {
1940*b5893f02SDimitry Andric         auto comp_id = SectionContrib->getCompilandId();
1941*b5893f02SDimitry Andric         if (!comp_id)
1942*b5893f02SDimitry Andric           continue;
1943*b5893f02SDimitry Andric 
1944*b5893f02SDimitry Andric         auto sec = SectionContrib->getAddressSection();
1945*b5893f02SDimitry Andric         auto &sec_cs = m_sec_contribs[sec];
1946*b5893f02SDimitry Andric 
1947*b5893f02SDimitry Andric         auto offset = SectionContrib->getAddressOffset();
1948*b5893f02SDimitry Andric         auto it =
1949*b5893f02SDimitry Andric             std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper);
1950*b5893f02SDimitry Andric 
1951*b5893f02SDimitry Andric         auto size = SectionContrib->getLength();
1952*b5893f02SDimitry Andric         sec_cs.insert(it, {offset, size, comp_id});
1953*b5893f02SDimitry Andric       }
1954*b5893f02SDimitry Andric     }
1955*b5893f02SDimitry Andric   }
1956*b5893f02SDimitry Andric 
1957*b5893f02SDimitry Andric   // Check by line number
1958*b5893f02SDimitry Andric   if (auto Lines = data.getLineNumbers()) {
1959*b5893f02SDimitry Andric     if (auto FirstLine = Lines->getNext())
1960*b5893f02SDimitry Andric       return FirstLine->getCompilandId();
1961*b5893f02SDimitry Andric   }
1962*b5893f02SDimitry Andric 
1963*b5893f02SDimitry Andric   // Retrieve section + offset
1964*b5893f02SDimitry Andric   uint32_t DataSection = data.getAddressSection();
1965*b5893f02SDimitry Andric   uint32_t DataOffset = data.getAddressOffset();
1966*b5893f02SDimitry Andric   if (DataSection == 0) {
1967*b5893f02SDimitry Andric     if (auto RVA = data.getRelativeVirtualAddress())
1968*b5893f02SDimitry Andric       m_session_up->addressForRVA(RVA, DataSection, DataOffset);
1969*b5893f02SDimitry Andric   }
1970*b5893f02SDimitry Andric 
1971*b5893f02SDimitry Andric   if (DataSection) {
1972*b5893f02SDimitry Andric     // Search by section contributions
1973*b5893f02SDimitry Andric     auto &sec_cs = m_sec_contribs[DataSection];
1974*b5893f02SDimitry Andric     auto it =
1975*b5893f02SDimitry Andric         std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper);
1976*b5893f02SDimitry Andric     if (it != sec_cs.begin()) {
1977*b5893f02SDimitry Andric       --it;
1978*b5893f02SDimitry Andric       if (DataOffset < it->Offset + it->Size)
1979*b5893f02SDimitry Andric         return it->CompilandId;
1980*b5893f02SDimitry Andric     }
1981*b5893f02SDimitry Andric   } else {
1982*b5893f02SDimitry Andric     // Search in lexical tree
1983*b5893f02SDimitry Andric     auto LexParentId = data.getLexicalParentId();
1984*b5893f02SDimitry Andric     while (auto LexParent = m_session_up->getSymbolById(LexParentId)) {
1985*b5893f02SDimitry Andric       if (LexParent->getSymTag() == PDB_SymType::Exe)
1986*b5893f02SDimitry Andric         break;
1987*b5893f02SDimitry Andric       if (LexParent->getSymTag() == PDB_SymType::Compiland)
1988*b5893f02SDimitry Andric         return LexParentId;
1989*b5893f02SDimitry Andric       LexParentId = LexParent->getRawSymbol().getLexicalParentId();
1990*b5893f02SDimitry Andric     }
1991*b5893f02SDimitry Andric   }
1992*b5893f02SDimitry Andric 
1993*b5893f02SDimitry Andric   return 0;
1994*b5893f02SDimitry Andric }
1995