174e08ca0SZachary Turner //===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===// 274e08ca0SZachary Turner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 674e08ca0SZachary Turner // 774e08ca0SZachary Turner //===----------------------------------------------------------------------===// 874e08ca0SZachary Turner 974e08ca0SZachary Turner #include "SymbolFilePDB.h" 1074e08ca0SZachary Turner 11c1e530eeSAleksandr Urakov #include "PDBASTParser.h" 12c1e530eeSAleksandr Urakov #include "PDBLocationToDWARFExpression.h" 13c1e530eeSAleksandr Urakov 1442dff790SZachary Turner #include "clang/Lex/Lexer.h" 1542dff790SZachary Turner 1674e08ca0SZachary Turner #include "lldb/Core/Module.h" 1774e08ca0SZachary Turner #include "lldb/Core/PluginManager.h" 1842dff790SZachary Turner #include "lldb/Symbol/ClangASTContext.h" 1974e08ca0SZachary Turner #include "lldb/Symbol/CompileUnit.h" 2074e08ca0SZachary Turner #include "lldb/Symbol/LineTable.h" 2174e08ca0SZachary Turner #include "lldb/Symbol/ObjectFile.h" 2274e08ca0SZachary Turner #include "lldb/Symbol/SymbolContext.h" 2310a02577SAaron Smith #include "lldb/Symbol/SymbolVendor.h" 24ec40f818SAaron Smith #include "lldb/Symbol/TypeList.h" 25308e39caSAaron Smith #include "lldb/Symbol/TypeMap.h" 26cab0d23fSAaron Smith #include "lldb/Symbol/Variable.h" 270e252e38SAlex Langford #include "lldb/Utility/Log.h" 2886e9434dSAaron Smith #include "lldb/Utility/RegularExpression.h" 2974e08ca0SZachary Turner 30b8d8c62bSPavel Labath #include "llvm/DebugInfo/PDB/GenericError.h" 311f8552abSAaron Smith #include "llvm/DebugInfo/PDB/IPDBDataStream.h" 3274e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 3374e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" 34308e39caSAaron Smith #include "llvm/DebugInfo/PDB/IPDBSectionContrib.h" 3574e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 361f8552abSAaron Smith #include "llvm/DebugInfo/PDB/IPDBTable.h" 3774e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbol.h" 387ac1c780SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolBlock.h" 3974e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 4074e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" 411f8552abSAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolData.h" 4274e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 4374e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 4474e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" 4574e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" 467ac1c780SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" 4742dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 4842dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" 4942dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 5042dff790SZachary Turner 51672d2c12SJonas Devlieghere #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" 52c1e530eeSAleksandr Urakov #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" 53307f5ae8SZachary Turner #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" 5442dff790SZachary Turner 5542dff790SZachary Turner #include <regex> 5674e08ca0SZachary Turner 5710a02577SAaron Smith using namespace lldb; 5874e08ca0SZachary Turner using namespace lldb_private; 5954fd7ff6SZachary Turner using namespace llvm::pdb; 6074e08ca0SZachary Turner 61b9c1b51eSKate Stone namespace { 62b9c1b51eSKate Stone lldb::LanguageType TranslateLanguage(PDB_Lang lang) { 63b9c1b51eSKate Stone switch (lang) { 6454fd7ff6SZachary Turner case PDB_Lang::Cpp: 6574e08ca0SZachary Turner return lldb::LanguageType::eLanguageTypeC_plus_plus; 6654fd7ff6SZachary Turner case PDB_Lang::C: 6774e08ca0SZachary Turner return lldb::LanguageType::eLanguageTypeC; 680561be6cSNathan Lanza case PDB_Lang::Swift: 690561be6cSNathan Lanza return lldb::LanguageType::eLanguageTypeSwift; 7074e08ca0SZachary Turner default: 7174e08ca0SZachary Turner return lldb::LanguageType::eLanguageTypeUnknown; 7274e08ca0SZachary Turner } 7374e08ca0SZachary Turner } 747e8c7beaSZachary Turner 75b9c1b51eSKate Stone bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, 76b9c1b51eSKate Stone uint32_t addr_length) { 77b9c1b51eSKate Stone return ((requested_line == 0 || actual_line == requested_line) && 78b9c1b51eSKate Stone addr_length > 0); 797e8c7beaSZachary Turner } 80c8316ed2SAaron Smith } // namespace 8174e08ca0SZachary Turner 82307f5ae8SZachary Turner static bool ShouldUseNativeReader() { 8371970b72SGreg Clayton #if defined(_WIN32) 84307f5ae8SZachary Turner llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER"); 85307f5ae8SZachary Turner return use_native.equals_lower("on") || use_native.equals_lower("yes") || 86307f5ae8SZachary Turner use_native.equals_lower("1") || use_native.equals_lower("true"); 8771970b72SGreg Clayton #else 8871970b72SGreg Clayton return true; 8971970b72SGreg Clayton #endif 90307f5ae8SZachary Turner } 91307f5ae8SZachary Turner 92b9c1b51eSKate Stone void SymbolFilePDB::Initialize() { 93307f5ae8SZachary Turner if (ShouldUseNativeReader()) { 94307f5ae8SZachary Turner npdb::SymbolFileNativePDB::Initialize(); 95307f5ae8SZachary Turner } else { 96b9c1b51eSKate Stone PluginManager::RegisterPlugin(GetPluginNameStatic(), 97b9c1b51eSKate Stone GetPluginDescriptionStatic(), CreateInstance, 9874e08ca0SZachary Turner DebuggerInitialize); 9974e08ca0SZachary Turner } 100307f5ae8SZachary Turner } 10174e08ca0SZachary Turner 102b9c1b51eSKate Stone void SymbolFilePDB::Terminate() { 103307f5ae8SZachary Turner if (ShouldUseNativeReader()) { 104307f5ae8SZachary Turner npdb::SymbolFileNativePDB::Terminate(); 105307f5ae8SZachary Turner } else { 10674e08ca0SZachary Turner PluginManager::UnregisterPlugin(CreateInstance); 10774e08ca0SZachary Turner } 108307f5ae8SZachary Turner } 10974e08ca0SZachary Turner 110b9c1b51eSKate Stone void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} 11174e08ca0SZachary Turner 112b9c1b51eSKate Stone lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() { 11374e08ca0SZachary Turner static ConstString g_name("pdb"); 11474e08ca0SZachary Turner return g_name; 11574e08ca0SZachary Turner } 11674e08ca0SZachary Turner 117b9c1b51eSKate Stone const char *SymbolFilePDB::GetPluginDescriptionStatic() { 11874e08ca0SZachary Turner return "Microsoft PDB debug symbol file reader."; 11974e08ca0SZachary Turner } 12074e08ca0SZachary Turner 12174e08ca0SZachary Turner lldb_private::SymbolFile * 122b9c1b51eSKate Stone SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) { 12374e08ca0SZachary Turner return new SymbolFilePDB(obj_file); 12474e08ca0SZachary Turner } 12574e08ca0SZachary Turner 12674e08ca0SZachary Turner SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file) 127e0119909SPavel Labath : SymbolFile(object_file), m_session_up(), m_global_scope_up() {} 12874e08ca0SZachary Turner 129b9c1b51eSKate Stone SymbolFilePDB::~SymbolFilePDB() {} 13074e08ca0SZachary Turner 131b9c1b51eSKate Stone uint32_t SymbolFilePDB::CalculateAbilities() { 1321f8552abSAaron Smith uint32_t abilities = 0; 1331f8552abSAaron Smith if (!m_obj_file) 1341f8552abSAaron Smith return 0; 1351f8552abSAaron Smith 136b9c1b51eSKate Stone if (!m_session_up) { 13774e08ca0SZachary Turner // Lazily load and match the PDB file, but only do this once. 13874e08ca0SZachary Turner std::string exePath = m_obj_file->GetFileSpec().GetPath(); 139b9c1b51eSKate Stone auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), 140b9c1b51eSKate Stone m_session_up); 141b9c1b51eSKate Stone if (error) { 1424fd6a960SZachary Turner llvm::consumeError(std::move(error)); 1431f8552abSAaron Smith auto module_sp = m_obj_file->GetModule(); 1441f8552abSAaron Smith if (!module_sp) 1451f8552abSAaron Smith return 0; 1461f8552abSAaron Smith // See if any symbol file is specified through `--symfile` option. 1471f8552abSAaron Smith FileSpec symfile = module_sp->GetSymbolFileFileSpec(); 1481f8552abSAaron Smith if (!symfile) 1491f8552abSAaron Smith return 0; 1501f8552abSAaron Smith error = loadDataForPDB(PDB_ReaderType::DIA, 151c8316ed2SAaron Smith llvm::StringRef(symfile.GetPath()), m_session_up); 1521f8552abSAaron Smith if (error) { 1531f8552abSAaron Smith llvm::consumeError(std::move(error)); 15474e08ca0SZachary Turner return 0; 15574e08ca0SZachary Turner } 156b8d8c62bSPavel Labath } 1571f8552abSAaron Smith } 158d5a925f4SAaron Smith if (!m_session_up) 1591f8552abSAaron Smith return 0; 1601f8552abSAaron Smith 1611f8552abSAaron Smith auto enum_tables_up = m_session_up->getEnumTables(); 1621f8552abSAaron Smith if (!enum_tables_up) 1631f8552abSAaron Smith return 0; 1641f8552abSAaron Smith while (auto table_up = enum_tables_up->getNext()) { 1651f8552abSAaron Smith if (table_up->getItemCount() == 0) 1661f8552abSAaron Smith continue; 1671f8552abSAaron Smith auto type = table_up->getTableType(); 1681f8552abSAaron Smith switch (type) { 1691f8552abSAaron Smith case PDB_TableType::Symbols: 1701f8552abSAaron Smith // This table represents a store of symbols with types listed in 1711f8552abSAaron Smith // PDBSym_Type 172c8316ed2SAaron Smith abilities |= (CompileUnits | Functions | Blocks | GlobalVariables | 173c8316ed2SAaron Smith LocalVariables | VariableTypes); 1741f8552abSAaron Smith break; 1751f8552abSAaron Smith case PDB_TableType::LineNumbers: 1761f8552abSAaron Smith abilities |= LineTables; 1771f8552abSAaron Smith break; 178c8316ed2SAaron Smith default: 179c8316ed2SAaron Smith break; 1801f8552abSAaron Smith } 1811f8552abSAaron Smith } 1821f8552abSAaron Smith return abilities; 18374e08ca0SZachary Turner } 18474e08ca0SZachary Turner 185b9c1b51eSKate Stone void SymbolFilePDB::InitializeObject() { 186d1304bbaSPavel Labath lldb::addr_t obj_load_address = m_obj_file->GetBaseAddress().GetFileAddress(); 187c8316ed2SAaron Smith lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS); 18874e08ca0SZachary Turner m_session_up->setLoadAddress(obj_load_address); 18910a02577SAaron Smith if (!m_global_scope_up) 19010a02577SAaron Smith m_global_scope_up = m_session_up->getGlobalScope(); 19110a02577SAaron Smith lldbassert(m_global_scope_up.get()); 19274e08ca0SZachary Turner } 19374e08ca0SZachary Turner 194e0119909SPavel Labath uint32_t SymbolFilePDB::CalculateNumCompileUnits() { 19510a02577SAaron Smith auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>(); 19610a02577SAaron Smith if (!compilands) 19710a02577SAaron Smith return 0; 19810a02577SAaron Smith 19910a02577SAaron Smith // The linker could link *.dll (compiland language = LINK), or import 20005097246SAdrian Prantl // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be 20105097246SAdrian Prantl // found as a child of the global scope (PDB executable). Usually, such 20205097246SAdrian Prantl // compilands contain `thunk` symbols in which we are not interested for 20305097246SAdrian Prantl // now. However we still count them in the compiland list. If we perform 20405097246SAdrian Prantl // any compiland related activity, like finding symbols through 20505097246SAdrian Prantl // llvm::pdb::IPDBSession methods, such compilands will all be searched 20605097246SAdrian Prantl // automatically no matter whether we include them or not. 207e0119909SPavel Labath uint32_t compile_unit_count = compilands->getChildCount(); 20874e08ca0SZachary Turner 209b9c1b51eSKate Stone // The linker can inject an additional "dummy" compilation unit into the 2109d0eb996SAdrian McCarthy // PDB. Ignore this special compile unit for our purposes, if it is there. 2119d0eb996SAdrian McCarthy // It is always the last one. 212e0119909SPavel Labath auto last_compiland_up = compilands->getChildAtIndex(compile_unit_count - 1); 21310a02577SAaron Smith lldbassert(last_compiland_up.get()); 21410a02577SAaron Smith std::string name = last_compiland_up->getName(); 21574e08ca0SZachary Turner if (name == "* Linker *") 216e0119909SPavel Labath --compile_unit_count; 217e0119909SPavel Labath return compile_unit_count; 21874e08ca0SZachary Turner } 21974e08ca0SZachary Turner 22010a02577SAaron Smith void SymbolFilePDB::GetCompileUnitIndex( 221c8316ed2SAaron Smith const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index) { 22210a02577SAaron Smith auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>(); 22310a02577SAaron Smith if (!results_up) 22410a02577SAaron Smith return; 225e664b5dcSAaron Smith auto uid = pdb_compiland.getSymIndexId(); 226fbdf0b93SRaphael Isemann for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) { 22710a02577SAaron Smith auto compiland_up = results_up->getChildAtIndex(cu_idx); 22810a02577SAaron Smith if (!compiland_up) 22910a02577SAaron Smith continue; 23010a02577SAaron Smith if (compiland_up->getSymIndexId() == uid) { 23110a02577SAaron Smith index = cu_idx; 23210a02577SAaron Smith return; 23310a02577SAaron Smith } 23410a02577SAaron Smith } 23510a02577SAaron Smith index = UINT32_MAX; 23610a02577SAaron Smith return; 23710a02577SAaron Smith } 23810a02577SAaron Smith 23910a02577SAaron Smith std::unique_ptr<llvm::pdb::PDBSymbolCompiland> 24010a02577SAaron Smith SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) { 24110a02577SAaron Smith return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid); 24210a02577SAaron Smith } 24310a02577SAaron Smith 244b9c1b51eSKate Stone lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) { 24510a02577SAaron Smith if (index >= GetNumCompileUnits()) 24610a02577SAaron Smith return CompUnitSP(); 24774e08ca0SZachary Turner 24810a02577SAaron Smith // Assuming we always retrieve same compilands listed in same order through 24910a02577SAaron Smith // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a 25010a02577SAaron Smith // compile unit makes no sense. 25110a02577SAaron Smith auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>(); 25210a02577SAaron Smith if (!results) 25310a02577SAaron Smith return CompUnitSP(); 25410a02577SAaron Smith auto compiland_up = results->getChildAtIndex(index); 25510a02577SAaron Smith if (!compiland_up) 25610a02577SAaron Smith return CompUnitSP(); 25710a02577SAaron Smith return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index); 25874e08ca0SZachary Turner } 25974e08ca0SZachary Turner 260863f8c18SZachary Turner lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) { 261656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 262863f8c18SZachary Turner auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); 26310a02577SAaron Smith if (!compiland_up) 26474e08ca0SZachary Turner return lldb::eLanguageTypeUnknown; 26510a02577SAaron Smith auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>(); 26674e08ca0SZachary Turner if (!details) 26774e08ca0SZachary Turner return lldb::eLanguageTypeUnknown; 26874e08ca0SZachary Turner return TranslateLanguage(details->getLanguage()); 26974e08ca0SZachary Turner } 27074e08ca0SZachary Turner 271863f8c18SZachary Turner lldb_private::Function * 272863f8c18SZachary Turner SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, 273863f8c18SZachary Turner CompileUnit &comp_unit) { 274863f8c18SZachary Turner if (FunctionSP result = comp_unit.FindFunctionByUID(pdb_func.getSymIndexId())) 275a5235af9SAleksandr Urakov return result.get(); 276a5235af9SAleksandr Urakov 277e664b5dcSAaron Smith auto file_vm_addr = pdb_func.getVirtualAddress(); 278308e39caSAaron Smith if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 2797ac1c780SAaron Smith return nullptr; 2807ac1c780SAaron Smith 281e664b5dcSAaron Smith auto func_length = pdb_func.getLength(); 282c8316ed2SAaron Smith AddressRange func_range = 283863f8c18SZachary Turner AddressRange(file_vm_addr, func_length, 284863f8c18SZachary Turner GetObjectFile()->GetModule()->GetSectionList()); 2857ac1c780SAaron Smith if (!func_range.GetBaseAddress().IsValid()) 2867ac1c780SAaron Smith return nullptr; 2877ac1c780SAaron Smith 288e664b5dcSAaron Smith lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId()); 2897ac1c780SAaron Smith if (!func_type) 2907ac1c780SAaron Smith return nullptr; 2917ac1c780SAaron Smith 292e664b5dcSAaron Smith user_id_t func_type_uid = pdb_func.getSignatureId(); 293f76fe682SAaron Smith 2947ac1c780SAaron Smith Mangled mangled = GetMangledForPDBFunc(pdb_func); 2957ac1c780SAaron Smith 296c8316ed2SAaron Smith FunctionSP func_sp = 297863f8c18SZachary Turner std::make_shared<Function>(&comp_unit, pdb_func.getSymIndexId(), 298c8316ed2SAaron Smith func_type_uid, mangled, func_type, func_range); 2997ac1c780SAaron Smith 300863f8c18SZachary Turner comp_unit.AddFunction(func_sp); 301c68925abSZachary Turner 302d0050d1bSNathan Lanza LanguageType lang = ParseLanguage(comp_unit); 3030e252e38SAlex Langford auto type_system_or_err = GetTypeSystemForLanguage(lang); 3040e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 3050e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 3060e252e38SAlex Langford std::move(err), "Unable to parse PDBFunc"); 307c68925abSZachary Turner return nullptr; 3080e252e38SAlex Langford } 3090e252e38SAlex Langford 310c68925abSZachary Turner ClangASTContext *clang_type_system = 3110e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 312c68925abSZachary Turner if (!clang_type_system) 313c68925abSZachary Turner return nullptr; 314c68925abSZachary Turner clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func); 315c68925abSZachary Turner 3167ac1c780SAaron Smith return func_sp.get(); 3177ac1c780SAaron Smith } 3187ac1c780SAaron Smith 319863f8c18SZachary Turner size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) { 320656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 3217ac1c780SAaron Smith size_t func_added = 0; 322863f8c18SZachary Turner auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); 3237ac1c780SAaron Smith if (!compiland_up) 3247ac1c780SAaron Smith return 0; 3257ac1c780SAaron Smith auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>(); 3267ac1c780SAaron Smith if (!results_up) 3277ac1c780SAaron Smith return 0; 3287ac1c780SAaron Smith while (auto pdb_func_up = results_up->getNext()) { 329863f8c18SZachary Turner auto func_sp = comp_unit.FindFunctionByUID(pdb_func_up->getSymIndexId()); 3307ac1c780SAaron Smith if (!func_sp) { 331863f8c18SZachary Turner if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, comp_unit)) 3327ac1c780SAaron Smith ++func_added; 3337ac1c780SAaron Smith } 3347ac1c780SAaron Smith } 3357ac1c780SAaron Smith return func_added; 33674e08ca0SZachary Turner } 33774e08ca0SZachary Turner 338863f8c18SZachary Turner bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) { 339656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 340863f8c18SZachary Turner if (comp_unit.GetLineTable()) 34110a02577SAaron Smith return true; 342863f8c18SZachary Turner return ParseCompileUnitLineTable(comp_unit, 0); 34374e08ca0SZachary Turner } 34474e08ca0SZachary Turner 345863f8c18SZachary Turner bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) { 34674e08ca0SZachary Turner // PDB doesn't contain information about macros 34774e08ca0SZachary Turner return false; 34874e08ca0SZachary Turner } 34974e08ca0SZachary Turner 350863f8c18SZachary Turner bool SymbolFilePDB::ParseSupportFiles( 351863f8c18SZachary Turner CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) { 35274e08ca0SZachary Turner 353b9c1b51eSKate Stone // In theory this is unnecessary work for us, because all of this information 3549d0eb996SAdrian McCarthy // is easily (and quickly) accessible from DebugInfoPDB, so caching it a 3559d0eb996SAdrian McCarthy // second time seems like a waste. Unfortunately, there's no good way around 3569d0eb996SAdrian McCarthy // this short of a moderate refactor since SymbolVendor depends on being able 3579d0eb996SAdrian McCarthy // to cache this list. 358656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 359863f8c18SZachary Turner auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); 36010a02577SAaron Smith if (!compiland_up) 36174e08ca0SZachary Turner return false; 36210a02577SAaron Smith auto files = m_session_up->getSourceFilesForCompiland(*compiland_up); 36374e08ca0SZachary Turner if (!files || files->getChildCount() == 0) 36474e08ca0SZachary Turner return false; 36574e08ca0SZachary Turner 366b9c1b51eSKate Stone while (auto file = files->getNext()) { 3678f3be7a3SJonas Devlieghere FileSpec spec(file->getFileName(), FileSpec::Style::windows); 36810a02577SAaron Smith support_files.AppendIfUnique(spec); 36974e08ca0SZachary Turner } 3709ea80d25SPavel Labath 3719ea80d25SPavel Labath // LLDB uses the DWARF-like file numeration (one based), 3729ea80d25SPavel Labath // the zeroth file is the compile unit itself 373863f8c18SZachary Turner support_files.Insert(0, comp_unit); 3749ea80d25SPavel Labath 37574e08ca0SZachary Turner return true; 37674e08ca0SZachary Turner } 37774e08ca0SZachary Turner 378b9c1b51eSKate Stone bool SymbolFilePDB::ParseImportedModules( 379b9c1b51eSKate Stone const lldb_private::SymbolContext &sc, 3800f30a3b6SAdrian Prantl std::vector<SourceModule> &imported_modules) { 38174e08ca0SZachary Turner // PDB does not yet support module debug info 38274e08ca0SZachary Turner return false; 38374e08ca0SZachary Turner } 38474e08ca0SZachary Turner 385c8316ed2SAaron Smith static size_t ParseFunctionBlocksForPDBSymbol( 386ffc1b8fdSZachary Turner uint64_t func_file_vm_addr, const llvm::pdb::PDBSymbol *pdb_symbol, 387ffc1b8fdSZachary Turner lldb_private::Block *parent_block, bool is_top_parent) { 3887ac1c780SAaron Smith assert(pdb_symbol && parent_block); 3897ac1c780SAaron Smith 3907ac1c780SAaron Smith size_t num_added = 0; 3917ac1c780SAaron Smith switch (pdb_symbol->getSymTag()) { 3927ac1c780SAaron Smith case PDB_SymType::Block: 3937ac1c780SAaron Smith case PDB_SymType::Function: { 3947ac1c780SAaron Smith Block *block = nullptr; 3957ac1c780SAaron Smith auto &raw_sym = pdb_symbol->getRawSymbol(); 3967ac1c780SAaron Smith if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) { 3977ac1c780SAaron Smith if (pdb_func->hasNoInlineAttribute()) 3987ac1c780SAaron Smith break; 3997ac1c780SAaron Smith if (is_top_parent) 4007ac1c780SAaron Smith block = parent_block; 4017ac1c780SAaron Smith else 4027ac1c780SAaron Smith break; 4037ac1c780SAaron Smith } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) { 4047ac1c780SAaron Smith auto uid = pdb_symbol->getSymIndexId(); 4057ac1c780SAaron Smith if (parent_block->FindBlockByID(uid)) 4067ac1c780SAaron Smith break; 4077ac1c780SAaron Smith if (raw_sym.getVirtualAddress() < func_file_vm_addr) 4087ac1c780SAaron Smith break; 4097ac1c780SAaron Smith 4107ac1c780SAaron Smith auto block_sp = std::make_shared<Block>(pdb_symbol->getSymIndexId()); 4117ac1c780SAaron Smith parent_block->AddChild(block_sp); 4127ac1c780SAaron Smith block = block_sp.get(); 4137ac1c780SAaron Smith } else 4147ac1c780SAaron Smith llvm_unreachable("Unexpected PDB symbol!"); 4157ac1c780SAaron Smith 416c8316ed2SAaron Smith block->AddRange(Block::Range( 417c8316ed2SAaron Smith raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength())); 4187ac1c780SAaron Smith block->FinalizeRanges(); 4197ac1c780SAaron Smith ++num_added; 4207ac1c780SAaron Smith 4217ac1c780SAaron Smith auto results_up = pdb_symbol->findAllChildren(); 4227ac1c780SAaron Smith if (!results_up) 4237ac1c780SAaron Smith break; 4247ac1c780SAaron Smith while (auto symbol_up = results_up->getNext()) { 425c8316ed2SAaron Smith num_added += ParseFunctionBlocksForPDBSymbol( 426ffc1b8fdSZachary Turner func_file_vm_addr, symbol_up.get(), block, false); 4277ac1c780SAaron Smith } 4287ac1c780SAaron Smith } break; 429c8316ed2SAaron Smith default: 430c8316ed2SAaron Smith break; 4317ac1c780SAaron Smith } 4327ac1c780SAaron Smith return num_added; 4337ac1c780SAaron Smith } 4347ac1c780SAaron Smith 435ffc1b8fdSZachary Turner size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) { 436656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 4377ac1c780SAaron Smith size_t num_added = 0; 438ffc1b8fdSZachary Turner auto uid = func.GetID(); 4397ac1c780SAaron Smith auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid); 4407ac1c780SAaron Smith if (!pdb_func_up) 4417ac1c780SAaron Smith return 0; 442ffc1b8fdSZachary Turner Block &parent_block = func.GetBlock(false); 443ffc1b8fdSZachary Turner num_added = ParseFunctionBlocksForPDBSymbol( 444ffc1b8fdSZachary Turner pdb_func_up->getVirtualAddress(), pdb_func_up.get(), &parent_block, true); 4457ac1c780SAaron Smith return num_added; 446b9c1b51eSKate Stone } 447b9c1b51eSKate Stone 448863f8c18SZachary Turner size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) { 449656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 45066b84079SAaron Smith 45166b84079SAaron Smith size_t num_added = 0; 452ac0d41c7SZachary Turner auto compiland = GetPDBCompilandByUID(comp_unit.GetID()); 45366b84079SAaron Smith if (!compiland) 45466b84079SAaron Smith return 0; 45566b84079SAaron Smith 45666b84079SAaron Smith auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) { 45766b84079SAaron Smith std::unique_ptr<IPDBEnumSymbols> results; 45866b84079SAaron Smith PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, 45966b84079SAaron Smith PDB_SymType::UDT}; 46066b84079SAaron Smith for (auto tag : tags_to_search) { 46166b84079SAaron Smith results = raw_sym.findAllChildren(tag); 46266b84079SAaron Smith if (!results || results->getChildCount() == 0) 46366b84079SAaron Smith continue; 46466b84079SAaron Smith while (auto symbol = results->getNext()) { 46566b84079SAaron Smith switch (symbol->getSymTag()) { 466ec40f818SAaron Smith case PDB_SymType::Enum: 467ec40f818SAaron Smith case PDB_SymType::UDT: 468ec40f818SAaron Smith case PDB_SymType::Typedef: 469ec40f818SAaron Smith break; 470ec40f818SAaron Smith default: 471ec40f818SAaron Smith continue; 472ec40f818SAaron Smith } 473ec40f818SAaron Smith 474ec40f818SAaron Smith // This should cause the type to get cached and stored in the `m_types` 475ec40f818SAaron Smith // lookup. 4767d2a74fcSAleksandr Urakov if (auto type = ResolveTypeUID(symbol->getSymIndexId())) { 4777d2a74fcSAleksandr Urakov // Resolve the type completely to avoid a completion 4787d2a74fcSAleksandr Urakov // (and so a list change, which causes an iterators invalidation) 4797d2a74fcSAleksandr Urakov // during a TypeList dumping 4807d2a74fcSAleksandr Urakov type->GetFullCompilerType(); 481ec40f818SAaron Smith ++num_added; 482ec40f818SAaron Smith } 48366b84079SAaron Smith } 4847d2a74fcSAleksandr Urakov } 48566b84079SAaron Smith }; 48666b84079SAaron Smith 48766b84079SAaron Smith ParseTypesByTagFn(*compiland); 48866b84079SAaron Smith 48966b84079SAaron Smith // Also parse global types particularly coming from this compiland. 49005097246SAdrian Prantl // Unfortunately, PDB has no compiland information for each global type. We 49105097246SAdrian Prantl // have to parse them all. But ensure we only do this once. 49266b84079SAaron Smith static bool parse_all_global_types = false; 49366b84079SAaron Smith if (!parse_all_global_types) { 49466b84079SAaron Smith ParseTypesByTagFn(*m_global_scope_up); 49566b84079SAaron Smith parse_all_global_types = true; 49666b84079SAaron Smith } 497ec40f818SAaron Smith return num_added; 49874e08ca0SZachary Turner } 49974e08ca0SZachary Turner 50074e08ca0SZachary Turner size_t 501b9c1b51eSKate Stone SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) { 502656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 503cab0d23fSAaron Smith if (!sc.comp_unit) 504cab0d23fSAaron Smith return 0; 505cab0d23fSAaron Smith 506cab0d23fSAaron Smith size_t num_added = 0; 507cab0d23fSAaron Smith if (sc.function) { 508cab0d23fSAaron Smith auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>( 509cab0d23fSAaron Smith sc.function->GetID()); 510cab0d23fSAaron Smith if (!pdb_func) 511cab0d23fSAaron Smith return 0; 512cab0d23fSAaron Smith 513cab0d23fSAaron Smith num_added += ParseVariables(sc, *pdb_func); 514cab0d23fSAaron Smith sc.function->GetBlock(false).SetDidParseVariables(true, true); 515cab0d23fSAaron Smith } else if (sc.comp_unit) { 516cab0d23fSAaron Smith auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID()); 517cab0d23fSAaron Smith if (!compiland) 518cab0d23fSAaron Smith return 0; 519cab0d23fSAaron Smith 520cab0d23fSAaron Smith if (sc.comp_unit->GetVariableList(false)) 521cab0d23fSAaron Smith return 0; 522cab0d23fSAaron Smith 523cab0d23fSAaron Smith auto results = m_global_scope_up->findAllChildren<PDBSymbolData>(); 524cab0d23fSAaron Smith if (results && results->getChildCount()) { 525cab0d23fSAaron Smith while (auto result = results->getNext()) { 526356aa4a9SAleksandr Urakov auto cu_id = GetCompilandId(*result); 527cab0d23fSAaron Smith // FIXME: We are not able to determine variable's compile unit. 528cab0d23fSAaron Smith if (cu_id == 0) 529cab0d23fSAaron Smith continue; 530cab0d23fSAaron Smith 531cab0d23fSAaron Smith if (cu_id == sc.comp_unit->GetID()) 532cab0d23fSAaron Smith num_added += ParseVariables(sc, *result); 533cab0d23fSAaron Smith } 534cab0d23fSAaron Smith } 535cab0d23fSAaron Smith 536cab0d23fSAaron Smith // FIXME: A `file static` or `global constant` variable appears both in 537cab0d23fSAaron Smith // compiland's children and global scope's children with unexpectedly 538cab0d23fSAaron Smith // different symbol's Id making it ambiguous. 539cab0d23fSAaron Smith 540cab0d23fSAaron Smith // FIXME: 'local constant', for example, const char var[] = "abc", declared 541cab0d23fSAaron Smith // in a function scope, can't be found in PDB. 542cab0d23fSAaron Smith 543cab0d23fSAaron Smith // Parse variables in this compiland. 544cab0d23fSAaron Smith num_added += ParseVariables(sc, *compiland); 545cab0d23fSAaron Smith } 546cab0d23fSAaron Smith 547cab0d23fSAaron Smith return num_added; 54874e08ca0SZachary Turner } 54974e08ca0SZachary Turner 550b9c1b51eSKate Stone lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { 551656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 55242dff790SZachary Turner auto find_result = m_types.find(type_uid); 55342dff790SZachary Turner if (find_result != m_types.end()) 55442dff790SZachary Turner return find_result->second.get(); 55542dff790SZachary Turner 5560e252e38SAlex Langford auto type_system_or_err = 557b9c1b51eSKate Stone GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 5580e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 5590e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 5600e252e38SAlex Langford std::move(err), "Unable to ResolveTypeUID"); 5610e252e38SAlex Langford return nullptr; 5620e252e38SAlex Langford } 5630e252e38SAlex Langford 564b9c1b51eSKate Stone ClangASTContext *clang_type_system = 5650e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 56642dff790SZachary Turner if (!clang_type_system) 56774e08ca0SZachary Turner return nullptr; 568709426b3SAleksandr Urakov PDBASTParser *pdb = clang_type_system->GetPDBParser(); 56942dff790SZachary Turner if (!pdb) 57042dff790SZachary Turner return nullptr; 57142dff790SZachary Turner 57242dff790SZachary Turner auto pdb_type = m_session_up->getSymbolById(type_uid); 57342dff790SZachary Turner if (pdb_type == nullptr) 57442dff790SZachary Turner return nullptr; 57542dff790SZachary Turner 57642dff790SZachary Turner lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type); 577d5a925f4SAaron Smith if (result) { 57842dff790SZachary Turner m_types.insert(std::make_pair(type_uid, result)); 579f46e8974SPavel Labath GetTypeList().Insert(result); 580ec40f818SAaron Smith } 58142dff790SZachary Turner return result.get(); 58274e08ca0SZachary Turner } 58374e08ca0SZachary Turner 584eca07c59SAdrian Prantl llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID( 585eca07c59SAdrian Prantl lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 586eca07c59SAdrian Prantl return llvm::None; 587eca07c59SAdrian Prantl } 588eca07c59SAdrian Prantl 589b9c1b51eSKate Stone bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { 5907d2a74fcSAleksandr Urakov std::lock_guard<std::recursive_mutex> guard( 5917d2a74fcSAleksandr Urakov GetObjectFile()->GetModule()->GetMutex()); 5927d2a74fcSAleksandr Urakov 5930e252e38SAlex Langford auto type_system_or_err = 5940e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 5950e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 5960e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 5970e252e38SAlex Langford std::move(err), "Unable to get dynamic array info for UID"); 5980e252e38SAlex Langford return false; 5990e252e38SAlex Langford } 6000e252e38SAlex Langford 6010e252e38SAlex Langford ClangASTContext *clang_ast_ctx = 6020e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 6030e252e38SAlex Langford 6047d2a74fcSAleksandr Urakov if (!clang_ast_ctx) 60574e08ca0SZachary Turner return false; 6067d2a74fcSAleksandr Urakov 607709426b3SAleksandr Urakov PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); 6087d2a74fcSAleksandr Urakov if (!pdb) 6097d2a74fcSAleksandr Urakov return false; 6107d2a74fcSAleksandr Urakov 6117d2a74fcSAleksandr Urakov return pdb->CompleteTypeFromPDB(compiler_type); 61274e08ca0SZachary Turner } 61374e08ca0SZachary Turner 614b9c1b51eSKate Stone lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { 6150e252e38SAlex Langford auto type_system_or_err = 6160e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 6170e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 6180e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 6190e252e38SAlex Langford std::move(err), "Unable to get decl for UID"); 6200e252e38SAlex Langford return CompilerDecl(); 6210e252e38SAlex Langford } 6220e252e38SAlex Langford 6230e252e38SAlex Langford ClangASTContext *clang_ast_ctx = 6240e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 625709426b3SAleksandr Urakov if (!clang_ast_ctx) 626709426b3SAleksandr Urakov return CompilerDecl(); 627709426b3SAleksandr Urakov 628709426b3SAleksandr Urakov PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); 629709426b3SAleksandr Urakov if (!pdb) 630709426b3SAleksandr Urakov return CompilerDecl(); 631709426b3SAleksandr Urakov 632709426b3SAleksandr Urakov auto symbol = m_session_up->getSymbolById(uid); 633709426b3SAleksandr Urakov if (!symbol) 634709426b3SAleksandr Urakov return CompilerDecl(); 635709426b3SAleksandr Urakov 636709426b3SAleksandr Urakov auto decl = pdb->GetDeclForSymbol(*symbol); 637709426b3SAleksandr Urakov if (!decl) 638709426b3SAleksandr Urakov return CompilerDecl(); 639709426b3SAleksandr Urakov 640709426b3SAleksandr Urakov return CompilerDecl(clang_ast_ctx, decl); 64174e08ca0SZachary Turner } 64274e08ca0SZachary Turner 64374e08ca0SZachary Turner lldb_private::CompilerDeclContext 644b9c1b51eSKate Stone SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { 6450e252e38SAlex Langford auto type_system_or_err = 6460e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 6470e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 6480e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 6490e252e38SAlex Langford std::move(err), "Unable to get DeclContext for UID"); 6500e252e38SAlex Langford return CompilerDeclContext(); 6510e252e38SAlex Langford } 6520e252e38SAlex Langford 6530e252e38SAlex Langford ClangASTContext *clang_ast_ctx = 6540e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 655709426b3SAleksandr Urakov if (!clang_ast_ctx) 656709426b3SAleksandr Urakov return CompilerDeclContext(); 657709426b3SAleksandr Urakov 658709426b3SAleksandr Urakov PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); 659709426b3SAleksandr Urakov if (!pdb) 660709426b3SAleksandr Urakov return CompilerDeclContext(); 661709426b3SAleksandr Urakov 662709426b3SAleksandr Urakov auto symbol = m_session_up->getSymbolById(uid); 663709426b3SAleksandr Urakov if (!symbol) 664709426b3SAleksandr Urakov return CompilerDeclContext(); 665709426b3SAleksandr Urakov 666709426b3SAleksandr Urakov auto decl_context = pdb->GetDeclContextForSymbol(*symbol); 667709426b3SAleksandr Urakov if (!decl_context) 668709426b3SAleksandr Urakov return GetDeclContextContainingUID(uid); 669709426b3SAleksandr Urakov 670709426b3SAleksandr Urakov return CompilerDeclContext(clang_ast_ctx, decl_context); 67174e08ca0SZachary Turner } 67274e08ca0SZachary Turner 67374e08ca0SZachary Turner lldb_private::CompilerDeclContext 674b9c1b51eSKate Stone SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { 6750e252e38SAlex Langford auto type_system_or_err = 6760e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 6770e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 6780e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 6790e252e38SAlex Langford std::move(err), "Unable to get DeclContext containing UID"); 6800e252e38SAlex Langford return CompilerDeclContext(); 6810e252e38SAlex Langford } 6820e252e38SAlex Langford 6830e252e38SAlex Langford ClangASTContext *clang_ast_ctx = 6840e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 685709426b3SAleksandr Urakov if (!clang_ast_ctx) 686709426b3SAleksandr Urakov return CompilerDeclContext(); 687709426b3SAleksandr Urakov 688709426b3SAleksandr Urakov PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); 689709426b3SAleksandr Urakov if (!pdb) 690709426b3SAleksandr Urakov return CompilerDeclContext(); 691709426b3SAleksandr Urakov 692709426b3SAleksandr Urakov auto symbol = m_session_up->getSymbolById(uid); 693709426b3SAleksandr Urakov if (!symbol) 694709426b3SAleksandr Urakov return CompilerDeclContext(); 695709426b3SAleksandr Urakov 696709426b3SAleksandr Urakov auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol); 697709426b3SAleksandr Urakov assert(decl_context); 698709426b3SAleksandr Urakov 699709426b3SAleksandr Urakov return CompilerDeclContext(clang_ast_ctx, decl_context); 70074e08ca0SZachary Turner } 70174e08ca0SZachary Turner 702b9c1b51eSKate Stone void SymbolFilePDB::ParseDeclsForContext( 703709426b3SAleksandr Urakov lldb_private::CompilerDeclContext decl_ctx) { 7040e252e38SAlex Langford auto type_system_or_err = 7050e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 7060e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 7070e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 7080e252e38SAlex Langford std::move(err), "Unable to parse decls for context"); 7090e252e38SAlex Langford return; 7100e252e38SAlex Langford } 7110e252e38SAlex Langford 7120e252e38SAlex Langford ClangASTContext *clang_ast_ctx = 7130e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 714709426b3SAleksandr Urakov if (!clang_ast_ctx) 715709426b3SAleksandr Urakov return; 716709426b3SAleksandr Urakov 717709426b3SAleksandr Urakov PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); 718709426b3SAleksandr Urakov if (!pdb) 719709426b3SAleksandr Urakov return; 720709426b3SAleksandr Urakov 721709426b3SAleksandr Urakov pdb->ParseDeclsForDeclContext( 722709426b3SAleksandr Urakov static_cast<clang::DeclContext *>(decl_ctx.GetOpaqueDeclContext())); 723709426b3SAleksandr Urakov } 72474e08ca0SZachary Turner 72574e08ca0SZachary Turner uint32_t 726b9c1b51eSKate Stone SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, 727991e4453SZachary Turner SymbolContextItem resolve_scope, 728b9c1b51eSKate Stone lldb_private::SymbolContext &sc) { 729656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 7307ac1c780SAaron Smith uint32_t resolved_flags = 0; 7314d4d63eeSPavel Labath if (resolve_scope & eSymbolContextCompUnit || 7324d4d63eeSPavel Labath resolve_scope & eSymbolContextVariable || 7334d4d63eeSPavel Labath resolve_scope & eSymbolContextFunction || 7344d4d63eeSPavel Labath resolve_scope & eSymbolContextBlock || 7357ac1c780SAaron Smith resolve_scope & eSymbolContextLineEntry) { 7367ac1c780SAaron Smith auto cu_sp = GetCompileUnitContainsAddress(so_addr); 7377ac1c780SAaron Smith if (!cu_sp) { 738*33cdbff2SRichard Trieu if (resolved_flags & eSymbolContextVariable) { 7397ac1c780SAaron Smith // TODO: Resolve variables 7407ac1c780SAaron Smith } 7417ac1c780SAaron Smith return 0; 7427ac1c780SAaron Smith } 7437ac1c780SAaron Smith sc.comp_unit = cu_sp.get(); 7447ac1c780SAaron Smith resolved_flags |= eSymbolContextCompUnit; 7457ac1c780SAaron Smith lldbassert(sc.module_sp == cu_sp->GetModule()); 7469ea80d25SPavel Labath } 7477ac1c780SAaron Smith 748398f81b3SAleksandr Urakov if (resolve_scope & eSymbolContextFunction || 749398f81b3SAleksandr Urakov resolve_scope & eSymbolContextBlock) { 7509ea80d25SPavel Labath addr_t file_vm_addr = so_addr.GetFileAddress(); 7519ea80d25SPavel Labath auto symbol_up = 7529ea80d25SPavel Labath m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function); 7539ea80d25SPavel Labath if (symbol_up) { 7547ac1c780SAaron Smith auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get()); 7557ac1c780SAaron Smith assert(pdb_func); 7567ac1c780SAaron Smith auto func_uid = pdb_func->getSymIndexId(); 7577ac1c780SAaron Smith sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get(); 7587ac1c780SAaron Smith if (sc.function == nullptr) 759863f8c18SZachary Turner sc.function = 760863f8c18SZachary Turner ParseCompileUnitFunctionForPDBFunc(*pdb_func, *sc.comp_unit); 7617ac1c780SAaron Smith if (sc.function) { 7627ac1c780SAaron Smith resolved_flags |= eSymbolContextFunction; 7637ac1c780SAaron Smith if (resolve_scope & eSymbolContextBlock) { 764398f81b3SAleksandr Urakov auto block_symbol = m_session_up->findSymbolByAddress( 765398f81b3SAleksandr Urakov file_vm_addr, PDB_SymType::Block); 766398f81b3SAleksandr Urakov auto block_id = block_symbol ? block_symbol->getSymIndexId() 767398f81b3SAleksandr Urakov : sc.function->GetID(); 768398f81b3SAleksandr Urakov sc.block = sc.function->GetBlock(true).FindBlockByID(block_id); 7697ac1c780SAaron Smith if (sc.block) 7707ac1c780SAaron Smith resolved_flags |= eSymbolContextBlock; 7717ac1c780SAaron Smith } 7727ac1c780SAaron Smith } 7737ac1c780SAaron Smith } 7747ac1c780SAaron Smith } 7757ac1c780SAaron Smith 7767ac1c780SAaron Smith if (resolve_scope & eSymbolContextLineEntry) { 7777ac1c780SAaron Smith if (auto *line_table = sc.comp_unit->GetLineTable()) { 7787ac1c780SAaron Smith Address addr(so_addr); 7797ac1c780SAaron Smith if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) 7807ac1c780SAaron Smith resolved_flags |= eSymbolContextLineEntry; 7817ac1c780SAaron Smith } 7827ac1c780SAaron Smith } 7839ea80d25SPavel Labath 7847ac1c780SAaron Smith return resolved_flags; 78574e08ca0SZachary Turner } 78674e08ca0SZachary Turner 787b9c1b51eSKate Stone uint32_t SymbolFilePDB::ResolveSymbolContext( 788b9c1b51eSKate Stone const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, 789991e4453SZachary Turner SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) { 790656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 79110a02577SAaron Smith const size_t old_size = sc_list.GetSize(); 792b9c1b51eSKate Stone if (resolve_scope & lldb::eSymbolContextCompUnit) { 793b9c1b51eSKate Stone // Locate all compilation units with line numbers referencing the specified 7949d0eb996SAdrian McCarthy // file. For example, if `file_spec` is <vector>, then this should return 7959d0eb996SAdrian McCarthy // all source files and header files that reference <vector>, either 7969d0eb996SAdrian McCarthy // directly or indirectly. 797b9c1b51eSKate Stone auto compilands = m_session_up->findCompilandsForSourceFile( 798b9c1b51eSKate Stone file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive); 79974e08ca0SZachary Turner 80010a02577SAaron Smith if (!compilands) 80110a02577SAaron Smith return 0; 80210a02577SAaron Smith 8039d0eb996SAdrian McCarthy // For each one, either find its previously parsed data or parse it afresh 8049d0eb996SAdrian McCarthy // and add it to the symbol context list. 805b9c1b51eSKate Stone while (auto compiland = compilands->getNext()) { 80605097246SAdrian Prantl // If we're not checking inlines, then don't add line information for 80705097246SAdrian Prantl // this file unless the FileSpec matches. For inline functions, we don't 80805097246SAdrian Prantl // have to match the FileSpec since they could be defined in headers 80905097246SAdrian Prantl // other than file specified in FileSpec. 810b9c1b51eSKate Stone if (!check_inlines) { 811487b0c6bSAaron Smith std::string source_file = compiland->getSourceFileFullPath(); 81210a02577SAaron Smith if (source_file.empty()) 81310a02577SAaron Smith continue; 8148f3be7a3SJonas Devlieghere FileSpec this_spec(source_file, FileSpec::Style::windows); 81510a02577SAaron Smith bool need_full_match = !file_spec.GetDirectory().IsEmpty(); 81610a02577SAaron Smith if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0) 81774e08ca0SZachary Turner continue; 81874e08ca0SZachary Turner } 81974e08ca0SZachary Turner 82074e08ca0SZachary Turner SymbolContext sc; 82110a02577SAaron Smith auto cu = ParseCompileUnitForUID(compiland->getSymIndexId()); 822d5a925f4SAaron Smith if (!cu) 82310a02577SAaron Smith continue; 82474e08ca0SZachary Turner sc.comp_unit = cu.get(); 82574e08ca0SZachary Turner sc.module_sp = cu->GetModule(); 82674e08ca0SZachary Turner 827b9c1b51eSKate Stone // If we were asked to resolve line entries, add all entries to the line 8289d0eb996SAdrian McCarthy // table that match the requested line (or all lines if `line` == 0). 8297ac1c780SAaron Smith if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock | 8307ac1c780SAaron Smith eSymbolContextLineEntry)) { 831863f8c18SZachary Turner bool has_line_table = ParseCompileUnitLineTable(*sc.comp_unit, line); 8327ac1c780SAaron Smith 8337ac1c780SAaron Smith if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) { 8347ac1c780SAaron Smith // The query asks for line entries, but we can't get them for the 83505097246SAdrian Prantl // compile unit. This is not normal for `line` = 0. So just assert 83605097246SAdrian Prantl // it. 837f76fe682SAaron Smith assert(line && "Couldn't get all line entries!\n"); 8387ac1c780SAaron Smith 8397ac1c780SAaron Smith // Current compiland does not have the requested line. Search next. 8407ac1c780SAaron Smith continue; 8417ac1c780SAaron Smith } 8427ac1c780SAaron Smith 8437ac1c780SAaron Smith if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) { 8447ac1c780SAaron Smith if (!has_line_table) 8457ac1c780SAaron Smith continue; 8467ac1c780SAaron Smith 8477ac1c780SAaron Smith auto *line_table = sc.comp_unit->GetLineTable(); 8487ac1c780SAaron Smith lldbassert(line_table); 8497ac1c780SAaron Smith 8507ac1c780SAaron Smith uint32_t num_line_entries = line_table->GetSize(); 8517ac1c780SAaron Smith // Skip the terminal line entry. 8527ac1c780SAaron Smith --num_line_entries; 8537ac1c780SAaron Smith 85405097246SAdrian Prantl // If `line `!= 0, see if we can resolve function for each line entry 85505097246SAdrian Prantl // in the line table. 8567ac1c780SAaron Smith for (uint32_t line_idx = 0; line && line_idx < num_line_entries; 8577ac1c780SAaron Smith ++line_idx) { 8587ac1c780SAaron Smith if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry)) 8597ac1c780SAaron Smith continue; 8607ac1c780SAaron Smith 8617ac1c780SAaron Smith auto file_vm_addr = 8627ac1c780SAaron Smith sc.line_entry.range.GetBaseAddress().GetFileAddress(); 863308e39caSAaron Smith if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 8647ac1c780SAaron Smith continue; 8657ac1c780SAaron Smith 866c8316ed2SAaron Smith auto symbol_up = m_session_up->findSymbolByAddress( 867c8316ed2SAaron Smith file_vm_addr, PDB_SymType::Function); 8687ac1c780SAaron Smith if (symbol_up) { 8697ac1c780SAaron Smith auto func_uid = symbol_up->getSymIndexId(); 8707ac1c780SAaron Smith sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get(); 8717ac1c780SAaron Smith if (sc.function == nullptr) { 8727ac1c780SAaron Smith auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get()); 8737ac1c780SAaron Smith assert(pdb_func); 874863f8c18SZachary Turner sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, 875863f8c18SZachary Turner *sc.comp_unit); 8767ac1c780SAaron Smith } 8777ac1c780SAaron Smith if (sc.function && (resolve_scope & eSymbolContextBlock)) { 8787ac1c780SAaron Smith Block &block = sc.function->GetBlock(true); 8797ac1c780SAaron Smith sc.block = block.FindBlockByID(sc.function->GetID()); 8807ac1c780SAaron Smith } 8817ac1c780SAaron Smith } 8827ac1c780SAaron Smith sc_list.Append(sc); 8837ac1c780SAaron Smith } 8847ac1c780SAaron Smith } else if (has_line_table) { 8857ac1c780SAaron Smith // We can parse line table for the compile unit. But no query to 8867ac1c780SAaron Smith // resolve function or block. We append `sc` to the list anyway. 8877ac1c780SAaron Smith sc_list.Append(sc); 8887ac1c780SAaron Smith } 8897ac1c780SAaron Smith } else { 8907ac1c780SAaron Smith // No query for line entry, function or block. But we have a valid 8917ac1c780SAaron Smith // compile unit, append `sc` to the list. 8927ac1c780SAaron Smith sc_list.Append(sc); 8937ac1c780SAaron Smith } 89474e08ca0SZachary Turner } 89574e08ca0SZachary Turner } 89610a02577SAaron Smith return sc_list.GetSize() - old_size; 89774e08ca0SZachary Turner } 89874e08ca0SZachary Turner 899cab0d23fSAaron Smith std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) { 900356aa4a9SAleksandr Urakov // Cache public names at first 901356aa4a9SAleksandr Urakov if (m_public_names.empty()) 902356aa4a9SAleksandr Urakov if (auto result_up = 903356aa4a9SAleksandr Urakov m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol)) 904356aa4a9SAleksandr Urakov while (auto symbol_up = result_up->getNext()) 905356aa4a9SAleksandr Urakov if (auto addr = symbol_up->getRawSymbol().getVirtualAddress()) 906356aa4a9SAleksandr Urakov m_public_names[addr] = symbol_up->getRawSymbol().getName(); 907cab0d23fSAaron Smith 908356aa4a9SAleksandr Urakov // Look up the name in the cache 909356aa4a9SAleksandr Urakov return m_public_names.lookup(pdb_data.getVirtualAddress()); 910cab0d23fSAaron Smith } 911cab0d23fSAaron Smith 912cab0d23fSAaron Smith VariableSP SymbolFilePDB::ParseVariableForPDBData( 913cab0d23fSAaron Smith const lldb_private::SymbolContext &sc, 914cab0d23fSAaron Smith const llvm::pdb::PDBSymbolData &pdb_data) { 915cab0d23fSAaron Smith VariableSP var_sp; 916cab0d23fSAaron Smith uint32_t var_uid = pdb_data.getSymIndexId(); 917cab0d23fSAaron Smith auto result = m_variables.find(var_uid); 918cab0d23fSAaron Smith if (result != m_variables.end()) 919cab0d23fSAaron Smith return result->second; 920cab0d23fSAaron Smith 921cab0d23fSAaron Smith ValueType scope = eValueTypeInvalid; 922cab0d23fSAaron Smith bool is_static_member = false; 923cab0d23fSAaron Smith bool is_external = false; 924cab0d23fSAaron Smith bool is_artificial = false; 925cab0d23fSAaron Smith 926cab0d23fSAaron Smith switch (pdb_data.getDataKind()) { 927cab0d23fSAaron Smith case PDB_DataKind::Global: 928cab0d23fSAaron Smith scope = eValueTypeVariableGlobal; 929cab0d23fSAaron Smith is_external = true; 930cab0d23fSAaron Smith break; 931cab0d23fSAaron Smith case PDB_DataKind::Local: 932cab0d23fSAaron Smith scope = eValueTypeVariableLocal; 933cab0d23fSAaron Smith break; 934cab0d23fSAaron Smith case PDB_DataKind::FileStatic: 935cab0d23fSAaron Smith scope = eValueTypeVariableStatic; 936cab0d23fSAaron Smith break; 937cab0d23fSAaron Smith case PDB_DataKind::StaticMember: 938cab0d23fSAaron Smith is_static_member = true; 939cab0d23fSAaron Smith scope = eValueTypeVariableStatic; 940cab0d23fSAaron Smith break; 941cab0d23fSAaron Smith case PDB_DataKind::Member: 942cab0d23fSAaron Smith scope = eValueTypeVariableStatic; 943cab0d23fSAaron Smith break; 944cab0d23fSAaron Smith case PDB_DataKind::Param: 945cab0d23fSAaron Smith scope = eValueTypeVariableArgument; 946cab0d23fSAaron Smith break; 947cab0d23fSAaron Smith case PDB_DataKind::Constant: 948cab0d23fSAaron Smith scope = eValueTypeConstResult; 949cab0d23fSAaron Smith break; 950cab0d23fSAaron Smith default: 951cab0d23fSAaron Smith break; 952cab0d23fSAaron Smith } 953cab0d23fSAaron Smith 954cab0d23fSAaron Smith switch (pdb_data.getLocationType()) { 955cab0d23fSAaron Smith case PDB_LocType::TLS: 956cab0d23fSAaron Smith scope = eValueTypeVariableThreadLocal; 957cab0d23fSAaron Smith break; 958cab0d23fSAaron Smith case PDB_LocType::RegRel: { 959cab0d23fSAaron Smith // It is a `this` pointer. 960cab0d23fSAaron Smith if (pdb_data.getDataKind() == PDB_DataKind::ObjectPtr) { 961cab0d23fSAaron Smith scope = eValueTypeVariableArgument; 962cab0d23fSAaron Smith is_artificial = true; 963cab0d23fSAaron Smith } 964cab0d23fSAaron Smith } break; 965cab0d23fSAaron Smith default: 966cab0d23fSAaron Smith break; 967cab0d23fSAaron Smith } 968cab0d23fSAaron Smith 969cab0d23fSAaron Smith Declaration decl; 970cab0d23fSAaron Smith if (!is_artificial && !pdb_data.isCompilerGenerated()) { 971cab0d23fSAaron Smith if (auto lines = pdb_data.getLineNumbers()) { 972cab0d23fSAaron Smith if (auto first_line = lines->getNext()) { 973cab0d23fSAaron Smith uint32_t src_file_id = first_line->getSourceFileId(); 974cab0d23fSAaron Smith auto src_file = m_session_up->getSourceFileById(src_file_id); 975cab0d23fSAaron Smith if (src_file) { 9768f3be7a3SJonas Devlieghere FileSpec spec(src_file->getFileName()); 977cab0d23fSAaron Smith decl.SetFile(spec); 978cab0d23fSAaron Smith decl.SetColumn(first_line->getColumnNumber()); 979cab0d23fSAaron Smith decl.SetLine(first_line->getLineNumber()); 980cab0d23fSAaron Smith } 981cab0d23fSAaron Smith } 982cab0d23fSAaron Smith } 983cab0d23fSAaron Smith } 984cab0d23fSAaron Smith 985cab0d23fSAaron Smith Variable::RangeList ranges; 986cab0d23fSAaron Smith SymbolContextScope *context_scope = sc.comp_unit; 987758657e5SAleksandr Urakov if (scope == eValueTypeVariableLocal || scope == eValueTypeVariableArgument) { 988cab0d23fSAaron Smith if (sc.function) { 989758657e5SAleksandr Urakov Block &function_block = sc.function->GetBlock(true); 990758657e5SAleksandr Urakov Block *block = 991758657e5SAleksandr Urakov function_block.FindBlockByID(pdb_data.getLexicalParentId()); 992758657e5SAleksandr Urakov if (!block) 993758657e5SAleksandr Urakov block = &function_block; 994758657e5SAleksandr Urakov 995758657e5SAleksandr Urakov context_scope = block; 996758657e5SAleksandr Urakov 997758657e5SAleksandr Urakov for (size_t i = 0, num_ranges = block->GetNumRanges(); i < num_ranges; 998758657e5SAleksandr Urakov ++i) { 999758657e5SAleksandr Urakov AddressRange range; 1000758657e5SAleksandr Urakov if (!block->GetRangeAtIndex(i, range)) 1001758657e5SAleksandr Urakov continue; 1002758657e5SAleksandr Urakov 1003758657e5SAleksandr Urakov ranges.Append(range.GetBaseAddress().GetFileAddress(), 1004758657e5SAleksandr Urakov range.GetByteSize()); 1005758657e5SAleksandr Urakov } 1006cab0d23fSAaron Smith } 1007cab0d23fSAaron Smith } 1008cab0d23fSAaron Smith 1009cab0d23fSAaron Smith SymbolFileTypeSP type_sp = 1010cab0d23fSAaron Smith std::make_shared<SymbolFileType>(*this, pdb_data.getTypeId()); 1011cab0d23fSAaron Smith 1012cab0d23fSAaron Smith auto var_name = pdb_data.getName(); 1013cab0d23fSAaron Smith auto mangled = GetMangledForPDBData(pdb_data); 1014cab0d23fSAaron Smith auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str(); 1015cab0d23fSAaron Smith 1016924d5608SJonas Devlieghere bool is_constant; 1017924d5608SJonas Devlieghere DWARFExpression location = ConvertPDBLocationToDWARFExpression( 1018758657e5SAleksandr Urakov GetObjectFile()->GetModule(), pdb_data, ranges, is_constant); 1019cab0d23fSAaron Smith 1020cab0d23fSAaron Smith var_sp = std::make_shared<Variable>( 1021cab0d23fSAaron Smith var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope, 1022cab0d23fSAaron Smith ranges, &decl, location, is_external, is_artificial, is_static_member); 1023924d5608SJonas Devlieghere var_sp->SetLocationIsConstantValueData(is_constant); 1024cab0d23fSAaron Smith 1025cab0d23fSAaron Smith m_variables.insert(std::make_pair(var_uid, var_sp)); 1026cab0d23fSAaron Smith return var_sp; 1027cab0d23fSAaron Smith } 1028cab0d23fSAaron Smith 1029cab0d23fSAaron Smith size_t 1030cab0d23fSAaron Smith SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc, 1031cab0d23fSAaron Smith const llvm::pdb::PDBSymbol &pdb_symbol, 1032cab0d23fSAaron Smith lldb_private::VariableList *variable_list) { 1033cab0d23fSAaron Smith size_t num_added = 0; 1034cab0d23fSAaron Smith 1035cab0d23fSAaron Smith if (auto pdb_data = llvm::dyn_cast<PDBSymbolData>(&pdb_symbol)) { 1036cab0d23fSAaron Smith VariableListSP local_variable_list_sp; 1037cab0d23fSAaron Smith 1038cab0d23fSAaron Smith auto result = m_variables.find(pdb_data->getSymIndexId()); 1039cab0d23fSAaron Smith if (result != m_variables.end()) { 1040cab0d23fSAaron Smith if (variable_list) 1041cab0d23fSAaron Smith variable_list->AddVariableIfUnique(result->second); 1042cab0d23fSAaron Smith } else { 1043cab0d23fSAaron Smith // Prepare right VariableList for this variable. 1044cab0d23fSAaron Smith if (auto lexical_parent = pdb_data->getLexicalParent()) { 1045cab0d23fSAaron Smith switch (lexical_parent->getSymTag()) { 1046cab0d23fSAaron Smith case PDB_SymType::Exe: 1047cab0d23fSAaron Smith assert(sc.comp_unit); 1048cab0d23fSAaron Smith LLVM_FALLTHROUGH; 1049cab0d23fSAaron Smith case PDB_SymType::Compiland: { 1050cab0d23fSAaron Smith if (sc.comp_unit) { 1051cab0d23fSAaron Smith local_variable_list_sp = sc.comp_unit->GetVariableList(false); 1052cab0d23fSAaron Smith if (!local_variable_list_sp) { 1053cab0d23fSAaron Smith local_variable_list_sp = std::make_shared<VariableList>(); 1054cab0d23fSAaron Smith sc.comp_unit->SetVariableList(local_variable_list_sp); 1055cab0d23fSAaron Smith } 1056cab0d23fSAaron Smith } 1057cab0d23fSAaron Smith } break; 1058cab0d23fSAaron Smith case PDB_SymType::Block: 1059cab0d23fSAaron Smith case PDB_SymType::Function: { 1060cab0d23fSAaron Smith if (sc.function) { 1061cab0d23fSAaron Smith Block *block = sc.function->GetBlock(true).FindBlockByID( 1062cab0d23fSAaron Smith lexical_parent->getSymIndexId()); 1063cab0d23fSAaron Smith if (block) { 1064cab0d23fSAaron Smith local_variable_list_sp = block->GetBlockVariableList(false); 1065cab0d23fSAaron Smith if (!local_variable_list_sp) { 1066cab0d23fSAaron Smith local_variable_list_sp = std::make_shared<VariableList>(); 1067cab0d23fSAaron Smith block->SetVariableList(local_variable_list_sp); 1068cab0d23fSAaron Smith } 1069cab0d23fSAaron Smith } 1070cab0d23fSAaron Smith } 1071cab0d23fSAaron Smith } break; 1072cab0d23fSAaron Smith default: 1073cab0d23fSAaron Smith break; 1074cab0d23fSAaron Smith } 1075cab0d23fSAaron Smith } 1076cab0d23fSAaron Smith 1077cab0d23fSAaron Smith if (local_variable_list_sp) { 1078cab0d23fSAaron Smith if (auto var_sp = ParseVariableForPDBData(sc, *pdb_data)) { 1079cab0d23fSAaron Smith local_variable_list_sp->AddVariableIfUnique(var_sp); 1080cab0d23fSAaron Smith if (variable_list) 1081cab0d23fSAaron Smith variable_list->AddVariableIfUnique(var_sp); 1082cab0d23fSAaron Smith ++num_added; 1083c68925abSZachary Turner PDBASTParser *ast = GetPDBAstParser(); 1084c68925abSZachary Turner if (ast) 1085c68925abSZachary Turner ast->GetDeclForSymbol(*pdb_data); 1086cab0d23fSAaron Smith } 1087cab0d23fSAaron Smith } 1088cab0d23fSAaron Smith } 1089cab0d23fSAaron Smith } 1090cab0d23fSAaron Smith 1091cab0d23fSAaron Smith if (auto results = pdb_symbol.findAllChildren()) { 1092cab0d23fSAaron Smith while (auto result = results->getNext()) 1093cab0d23fSAaron Smith num_added += ParseVariables(sc, *result, variable_list); 1094cab0d23fSAaron Smith } 1095cab0d23fSAaron Smith 1096cab0d23fSAaron Smith return num_added; 1097cab0d23fSAaron Smith } 1098cab0d23fSAaron Smith 1099b9c1b51eSKate Stone uint32_t SymbolFilePDB::FindGlobalVariables( 11000e4c4821SAdrian Prantl lldb_private::ConstString name, 110134cda14bSPavel Labath const lldb_private::CompilerDeclContext *parent_decl_ctx, 1102b9c1b51eSKate Stone uint32_t max_matches, lldb_private::VariableList &variables) { 1103656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1104cab0d23fSAaron Smith if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 1105cab0d23fSAaron Smith return 0; 1106cab0d23fSAaron Smith if (name.IsEmpty()) 1107cab0d23fSAaron Smith return 0; 1108cab0d23fSAaron Smith 1109709426b3SAleksandr Urakov auto results = m_global_scope_up->findAllChildren<PDBSymbolData>(); 1110cab0d23fSAaron Smith if (!results) 1111cab0d23fSAaron Smith return 0; 1112cab0d23fSAaron Smith 1113cab0d23fSAaron Smith uint32_t matches = 0; 1114cab0d23fSAaron Smith size_t old_size = variables.GetSize(); 1115cab0d23fSAaron Smith while (auto result = results->getNext()) { 1116cab0d23fSAaron Smith auto pdb_data = llvm::dyn_cast<PDBSymbolData>(result.get()); 1117cab0d23fSAaron Smith if (max_matches > 0 && matches >= max_matches) 1118cab0d23fSAaron Smith break; 1119cab0d23fSAaron Smith 1120cab0d23fSAaron Smith SymbolContext sc; 1121cab0d23fSAaron Smith sc.module_sp = m_obj_file->GetModule(); 1122cab0d23fSAaron Smith lldbassert(sc.module_sp.get()); 1123cab0d23fSAaron Smith 1124709426b3SAleksandr Urakov if (!name.GetStringRef().equals( 1125c1e530eeSAleksandr Urakov MSVCUndecoratedNameParser::DropScope(pdb_data->getName()))) 1126709426b3SAleksandr Urakov continue; 1127709426b3SAleksandr Urakov 1128356aa4a9SAleksandr Urakov sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); 1129356aa4a9SAleksandr Urakov // FIXME: We are not able to determine the compile unit. 1130356aa4a9SAleksandr Urakov if (sc.comp_unit == nullptr) 1131356aa4a9SAleksandr Urakov continue; 1132356aa4a9SAleksandr Urakov 1133a5235af9SAleksandr Urakov if (parent_decl_ctx && GetDeclContextContainingUID( 1134a5235af9SAleksandr Urakov result->getSymIndexId()) != *parent_decl_ctx) 1135709426b3SAleksandr Urakov continue; 1136709426b3SAleksandr Urakov 1137cab0d23fSAaron Smith ParseVariables(sc, *pdb_data, &variables); 1138cab0d23fSAaron Smith matches = variables.GetSize() - old_size; 1139cab0d23fSAaron Smith } 1140cab0d23fSAaron Smith 1141cab0d23fSAaron Smith return matches; 114274e08ca0SZachary Turner } 114374e08ca0SZachary Turner 114474e08ca0SZachary Turner uint32_t 1145b9c1b51eSKate Stone SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, 114634cda14bSPavel Labath uint32_t max_matches, 1147b9c1b51eSKate Stone lldb_private::VariableList &variables) { 1148656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1149cab0d23fSAaron Smith if (!regex.IsValid()) 1150cab0d23fSAaron Smith return 0; 1151cab0d23fSAaron Smith auto results = m_global_scope_up->findAllChildren<PDBSymbolData>(); 1152cab0d23fSAaron Smith if (!results) 1153cab0d23fSAaron Smith return 0; 1154cab0d23fSAaron Smith 1155cab0d23fSAaron Smith uint32_t matches = 0; 1156cab0d23fSAaron Smith size_t old_size = variables.GetSize(); 1157cab0d23fSAaron Smith while (auto pdb_data = results->getNext()) { 1158cab0d23fSAaron Smith if (max_matches > 0 && matches >= max_matches) 1159cab0d23fSAaron Smith break; 1160cab0d23fSAaron Smith 1161cab0d23fSAaron Smith auto var_name = pdb_data->getName(); 1162cab0d23fSAaron Smith if (var_name.empty()) 1163cab0d23fSAaron Smith continue; 1164cab0d23fSAaron Smith if (!regex.Execute(var_name)) 1165cab0d23fSAaron Smith continue; 1166cab0d23fSAaron Smith SymbolContext sc; 1167cab0d23fSAaron Smith sc.module_sp = m_obj_file->GetModule(); 1168cab0d23fSAaron Smith lldbassert(sc.module_sp.get()); 1169cab0d23fSAaron Smith 1170356aa4a9SAleksandr Urakov sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); 1171cab0d23fSAaron Smith // FIXME: We are not able to determine the compile unit. 1172cab0d23fSAaron Smith if (sc.comp_unit == nullptr) 1173cab0d23fSAaron Smith continue; 1174cab0d23fSAaron Smith 1175cab0d23fSAaron Smith ParseVariables(sc, *pdb_data, &variables); 1176cab0d23fSAaron Smith matches = variables.GetSize() - old_size; 1177cab0d23fSAaron Smith } 1178cab0d23fSAaron Smith 1179cab0d23fSAaron Smith return matches; 1180b9c1b51eSKate Stone } 1181b9c1b51eSKate Stone 1182e664b5dcSAaron Smith bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func, 11837ac1c780SAaron Smith bool include_inlines, 11847ac1c780SAaron Smith lldb_private::SymbolContextList &sc_list) { 11857ac1c780SAaron Smith lldb_private::SymbolContext sc; 1186a3a8cc80SAaron Smith sc.comp_unit = ParseCompileUnitForUID(pdb_func.getCompilandId()).get(); 11877ac1c780SAaron Smith if (!sc.comp_unit) 11887ac1c780SAaron Smith return false; 11897ac1c780SAaron Smith sc.module_sp = sc.comp_unit->GetModule(); 1190863f8c18SZachary Turner sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, *sc.comp_unit); 11917ac1c780SAaron Smith if (!sc.function) 11927ac1c780SAaron Smith return false; 11937ac1c780SAaron Smith 11947ac1c780SAaron Smith sc_list.Append(sc); 11957ac1c780SAaron Smith return true; 11967ac1c780SAaron Smith } 11977ac1c780SAaron Smith 11987ac1c780SAaron Smith bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines, 11997ac1c780SAaron Smith lldb_private::SymbolContextList &sc_list) { 1200c8316ed2SAaron Smith auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid); 12017ac1c780SAaron Smith if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute())) 12027ac1c780SAaron Smith return false; 1203e664b5dcSAaron Smith return ResolveFunction(*pdb_func_up, include_inlines, sc_list); 12047ac1c780SAaron Smith } 12057ac1c780SAaron Smith 12067ac1c780SAaron Smith void SymbolFilePDB::CacheFunctionNames() { 12077ac1c780SAaron Smith if (!m_func_full_names.IsEmpty()) 12087ac1c780SAaron Smith return; 12097ac1c780SAaron Smith 12107ac1c780SAaron Smith std::map<uint64_t, uint32_t> addr_ids; 12117ac1c780SAaron Smith 12127ac1c780SAaron Smith if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) { 12137ac1c780SAaron Smith while (auto pdb_func_up = results_up->getNext()) { 1214f76fe682SAaron Smith if (pdb_func_up->isCompilerGenerated()) 1215f76fe682SAaron Smith continue; 1216f76fe682SAaron Smith 12177ac1c780SAaron Smith auto name = pdb_func_up->getName(); 12187ac1c780SAaron Smith auto demangled_name = pdb_func_up->getUndecoratedName(); 12197ac1c780SAaron Smith if (name.empty() && demangled_name.empty()) 12207ac1c780SAaron Smith continue; 12217ac1c780SAaron Smith 1222f76fe682SAaron Smith auto uid = pdb_func_up->getSymIndexId(); 12237ac1c780SAaron Smith if (!demangled_name.empty() && pdb_func_up->getVirtualAddress()) 12247ac1c780SAaron Smith addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid)); 12257ac1c780SAaron Smith 12267ac1c780SAaron Smith if (auto parent = pdb_func_up->getClassParent()) { 12277ac1c780SAaron Smith 12287ac1c780SAaron Smith // PDB have symbols for class/struct methods or static methods in Enum 12297ac1c780SAaron Smith // Class. We won't bother to check if the parent is UDT or Enum here. 12307ac1c780SAaron Smith m_func_method_names.Append(ConstString(name), uid); 12317ac1c780SAaron Smith 123205097246SAdrian Prantl // To search a method name, like NS::Class:MemberFunc, LLDB searches 123305097246SAdrian Prantl // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does 123405097246SAdrian Prantl // not have inforamtion of this, we extract base names and cache them 123505097246SAdrian Prantl // by our own effort. 1236c1e530eeSAleksandr Urakov llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); 12377ac1c780SAaron Smith if (!basename.empty()) 12387ac1c780SAaron Smith m_func_base_names.Append(ConstString(basename), uid); 12397ac1c780SAaron Smith else { 12407ac1c780SAaron Smith m_func_base_names.Append(ConstString(name), uid); 12417ac1c780SAaron Smith } 12427ac1c780SAaron Smith 12437ac1c780SAaron Smith if (!demangled_name.empty()) 12447ac1c780SAaron Smith m_func_full_names.Append(ConstString(demangled_name), uid); 12457ac1c780SAaron Smith 12467ac1c780SAaron Smith } else { 12477ac1c780SAaron Smith // Handle not-method symbols. 12487ac1c780SAaron Smith 1249c1e530eeSAleksandr Urakov // The function name might contain namespace, or its lexical scope. 1250c1e530eeSAleksandr Urakov llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); 1251c1e530eeSAleksandr Urakov if (!basename.empty()) 1252c1e530eeSAleksandr Urakov m_func_base_names.Append(ConstString(basename), uid); 1253c1e530eeSAleksandr Urakov else 12547ac1c780SAaron Smith m_func_base_names.Append(ConstString(name), uid); 12557ac1c780SAaron Smith 12567ac1c780SAaron Smith if (name == "main") { 12577ac1c780SAaron Smith m_func_full_names.Append(ConstString(name), uid); 12587ac1c780SAaron Smith 12597ac1c780SAaron Smith if (!demangled_name.empty() && name != demangled_name) { 12607ac1c780SAaron Smith m_func_full_names.Append(ConstString(demangled_name), uid); 12617ac1c780SAaron Smith m_func_base_names.Append(ConstString(demangled_name), uid); 12627ac1c780SAaron Smith } 12637ac1c780SAaron Smith } else if (!demangled_name.empty()) { 12647ac1c780SAaron Smith m_func_full_names.Append(ConstString(demangled_name), uid); 12657ac1c780SAaron Smith } else { 12667ac1c780SAaron Smith m_func_full_names.Append(ConstString(name), uid); 12677ac1c780SAaron Smith } 12687ac1c780SAaron Smith } 12697ac1c780SAaron Smith } 12707ac1c780SAaron Smith } 12717ac1c780SAaron Smith 12727ac1c780SAaron Smith if (auto results_up = 12737ac1c780SAaron Smith m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) { 12747ac1c780SAaron Smith while (auto pub_sym_up = results_up->getNext()) { 12757ac1c780SAaron Smith if (!pub_sym_up->isFunction()) 12767ac1c780SAaron Smith continue; 12777ac1c780SAaron Smith auto name = pub_sym_up->getName(); 12787ac1c780SAaron Smith if (name.empty()) 12797ac1c780SAaron Smith continue; 12807ac1c780SAaron Smith 12817ac1c780SAaron Smith if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) { 12827ac1c780SAaron Smith auto vm_addr = pub_sym_up->getVirtualAddress(); 12837ac1c780SAaron Smith 12847ac1c780SAaron Smith // PDB public symbol has mangled name for its associated function. 12857ac1c780SAaron Smith if (vm_addr && addr_ids.find(vm_addr) != addr_ids.end()) { 12867ac1c780SAaron Smith // Cache mangled name. 12877ac1c780SAaron Smith m_func_full_names.Append(ConstString(name), addr_ids[vm_addr]); 12887ac1c780SAaron Smith } 12897ac1c780SAaron Smith } 12907ac1c780SAaron Smith } 12917ac1c780SAaron Smith } 12927ac1c780SAaron Smith // Sort them before value searching is working properly 12937ac1c780SAaron Smith m_func_full_names.Sort(); 12947ac1c780SAaron Smith m_func_full_names.SizeToFit(); 12957ac1c780SAaron Smith m_func_method_names.Sort(); 12967ac1c780SAaron Smith m_func_method_names.SizeToFit(); 12977ac1c780SAaron Smith m_func_base_names.Sort(); 12987ac1c780SAaron Smith m_func_base_names.SizeToFit(); 12997ac1c780SAaron Smith } 13007ac1c780SAaron Smith 1301b9c1b51eSKate Stone uint32_t SymbolFilePDB::FindFunctions( 13020e4c4821SAdrian Prantl lldb_private::ConstString name, 1303b9c1b51eSKate Stone const lldb_private::CompilerDeclContext *parent_decl_ctx, 1304117b1fa1SZachary Turner FunctionNameType name_type_mask, bool include_inlines, bool append, 1305b9c1b51eSKate Stone lldb_private::SymbolContextList &sc_list) { 1306656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 13077ac1c780SAaron Smith if (!append) 13087ac1c780SAaron Smith sc_list.Clear(); 13097ac1c780SAaron Smith lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0); 13107ac1c780SAaron Smith 13117ac1c780SAaron Smith if (name_type_mask == eFunctionNameTypeNone) 13127ac1c780SAaron Smith return 0; 13137ac1c780SAaron Smith if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 13147ac1c780SAaron Smith return 0; 13157ac1c780SAaron Smith if (name.IsEmpty()) 13167ac1c780SAaron Smith return 0; 13177ac1c780SAaron Smith 13187ac1c780SAaron Smith auto old_size = sc_list.GetSize(); 13194d4d63eeSPavel Labath if (name_type_mask & eFunctionNameTypeFull || 13204d4d63eeSPavel Labath name_type_mask & eFunctionNameTypeBase || 13217ac1c780SAaron Smith name_type_mask & eFunctionNameTypeMethod) { 13227ac1c780SAaron Smith CacheFunctionNames(); 13237ac1c780SAaron Smith 13247ac1c780SAaron Smith std::set<uint32_t> resolved_ids; 1325a5235af9SAleksandr Urakov auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list, 1326a5235af9SAleksandr Urakov &resolved_ids](UniqueCStringMap<uint32_t> &Names) { 13277ac1c780SAaron Smith std::vector<uint32_t> ids; 1328a5235af9SAleksandr Urakov if (!Names.GetValues(name, ids)) 1329a5235af9SAleksandr Urakov return; 1330a5235af9SAleksandr Urakov 1331a5235af9SAleksandr Urakov for (uint32_t id : ids) { 1332a5235af9SAleksandr Urakov if (resolved_ids.find(id) != resolved_ids.end()) 1333a5235af9SAleksandr Urakov continue; 1334a5235af9SAleksandr Urakov 1335a5235af9SAleksandr Urakov if (parent_decl_ctx && 1336a5235af9SAleksandr Urakov GetDeclContextContainingUID(id) != *parent_decl_ctx) 1337a5235af9SAleksandr Urakov continue; 1338a5235af9SAleksandr Urakov 13397ac1c780SAaron Smith if (ResolveFunction(id, include_inlines, sc_list)) 13407ac1c780SAaron Smith resolved_ids.insert(id); 13417ac1c780SAaron Smith } 13427ac1c780SAaron Smith }; 13437ac1c780SAaron Smith if (name_type_mask & eFunctionNameTypeFull) { 13447ac1c780SAaron Smith ResolveFn(m_func_full_names); 1345a5235af9SAleksandr Urakov ResolveFn(m_func_base_names); 1346a5235af9SAleksandr Urakov ResolveFn(m_func_method_names); 13477ac1c780SAaron Smith } 13487ac1c780SAaron Smith if (name_type_mask & eFunctionNameTypeBase) { 13497ac1c780SAaron Smith ResolveFn(m_func_base_names); 13507ac1c780SAaron Smith } 13517ac1c780SAaron Smith if (name_type_mask & eFunctionNameTypeMethod) { 13527ac1c780SAaron Smith ResolveFn(m_func_method_names); 13537ac1c780SAaron Smith } 13547ac1c780SAaron Smith } 13557ac1c780SAaron Smith return sc_list.GetSize() - old_size; 135674e08ca0SZachary Turner } 135774e08ca0SZachary Turner 135874e08ca0SZachary Turner uint32_t 1359b9c1b51eSKate Stone SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, 1360b9c1b51eSKate Stone bool include_inlines, bool append, 1361b9c1b51eSKate Stone lldb_private::SymbolContextList &sc_list) { 1362656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 13637ac1c780SAaron Smith if (!append) 13647ac1c780SAaron Smith sc_list.Clear(); 13657ac1c780SAaron Smith if (!regex.IsValid()) 13667ac1c780SAaron Smith return 0; 13677ac1c780SAaron Smith 13687ac1c780SAaron Smith auto old_size = sc_list.GetSize(); 13697ac1c780SAaron Smith CacheFunctionNames(); 13707ac1c780SAaron Smith 13717ac1c780SAaron Smith std::set<uint32_t> resolved_ids; 1372c8316ed2SAaron Smith auto ResolveFn = [®ex, include_inlines, &sc_list, &resolved_ids, 1373c8316ed2SAaron Smith this](UniqueCStringMap<uint32_t> &Names) { 13747ac1c780SAaron Smith std::vector<uint32_t> ids; 13757ac1c780SAaron Smith if (Names.GetValues(regex, ids)) { 13767ac1c780SAaron Smith for (auto id : ids) { 13777ac1c780SAaron Smith if (resolved_ids.find(id) == resolved_ids.end()) 13787ac1c780SAaron Smith if (ResolveFunction(id, include_inlines, sc_list)) 13797ac1c780SAaron Smith resolved_ids.insert(id); 13807ac1c780SAaron Smith } 13817ac1c780SAaron Smith } 13827ac1c780SAaron Smith }; 13837ac1c780SAaron Smith ResolveFn(m_func_full_names); 13847ac1c780SAaron Smith ResolveFn(m_func_base_names); 13857ac1c780SAaron Smith 13867ac1c780SAaron Smith return sc_list.GetSize() - old_size; 138774e08ca0SZachary Turner } 138874e08ca0SZachary Turner 1389b9c1b51eSKate Stone void SymbolFilePDB::GetMangledNamesForFunction( 1390b9c1b51eSKate Stone const std::string &scope_qualified_name, 1391b9c1b51eSKate Stone std::vector<lldb_private::ConstString> &mangled_names) {} 139274e08ca0SZachary Turner 13938cfb12b9SAleksandr Urakov void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { 13948cfb12b9SAleksandr Urakov std::set<lldb::addr_t> sym_addresses; 13958cfb12b9SAleksandr Urakov for (size_t i = 0; i < symtab.GetNumSymbols(); i++) 13968cfb12b9SAleksandr Urakov sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress()); 13978cfb12b9SAleksandr Urakov 13988cfb12b9SAleksandr Urakov auto results = m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>(); 13998cfb12b9SAleksandr Urakov if (!results) 14008cfb12b9SAleksandr Urakov return; 14018cfb12b9SAleksandr Urakov 14028cfb12b9SAleksandr Urakov auto section_list = m_obj_file->GetSectionList(); 14038cfb12b9SAleksandr Urakov if (!section_list) 14048cfb12b9SAleksandr Urakov return; 14058cfb12b9SAleksandr Urakov 14068cfb12b9SAleksandr Urakov while (auto pub_symbol = results->getNext()) { 14077db8b5c4SPavel Labath auto section_id = pub_symbol->getAddressSection(); 14088cfb12b9SAleksandr Urakov 14097db8b5c4SPavel Labath auto section = section_list->FindSectionByID(section_id); 14108cfb12b9SAleksandr Urakov if (!section) 14118cfb12b9SAleksandr Urakov continue; 14128cfb12b9SAleksandr Urakov 14138cfb12b9SAleksandr Urakov auto offset = pub_symbol->getAddressOffset(); 14148cfb12b9SAleksandr Urakov 14158cfb12b9SAleksandr Urakov auto file_addr = section->GetFileAddress() + offset; 14168cfb12b9SAleksandr Urakov if (sym_addresses.find(file_addr) != sym_addresses.end()) 14178cfb12b9SAleksandr Urakov continue; 14188cfb12b9SAleksandr Urakov sym_addresses.insert(file_addr); 14198cfb12b9SAleksandr Urakov 14208cfb12b9SAleksandr Urakov auto size = pub_symbol->getLength(); 14218cfb12b9SAleksandr Urakov symtab.AddSymbol( 14228cfb12b9SAleksandr Urakov Symbol(pub_symbol->getSymIndexId(), // symID 14238cfb12b9SAleksandr Urakov pub_symbol->getName().c_str(), // name 14248cfb12b9SAleksandr Urakov true, // name_is_mangled 14258cfb12b9SAleksandr Urakov pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type 14268cfb12b9SAleksandr Urakov true, // external 14278cfb12b9SAleksandr Urakov false, // is_debug 14288cfb12b9SAleksandr Urakov false, // is_trampoline 14298cfb12b9SAleksandr Urakov false, // is_artificial 14308cfb12b9SAleksandr Urakov section, // section_sp 14318cfb12b9SAleksandr Urakov offset, // value 14328cfb12b9SAleksandr Urakov size, // size 14338cfb12b9SAleksandr Urakov size != 0, // size_is_valid 14348cfb12b9SAleksandr Urakov false, // contains_linker_annotations 14358cfb12b9SAleksandr Urakov 0 // flags 14368cfb12b9SAleksandr Urakov )); 14378cfb12b9SAleksandr Urakov } 14388cfb12b9SAleksandr Urakov 14398cfb12b9SAleksandr Urakov symtab.CalculateSymbolSizes(); 14408cfb12b9SAleksandr Urakov symtab.Finalize(); 14418cfb12b9SAleksandr Urakov } 14428cfb12b9SAleksandr Urakov 1443b9c1b51eSKate Stone uint32_t SymbolFilePDB::FindTypes( 14440e4c4821SAdrian Prantl lldb_private::ConstString name, 1445b9c1b51eSKate Stone const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, 1446b9c1b51eSKate Stone uint32_t max_matches, 144774e08ca0SZachary Turner llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 1448b9c1b51eSKate Stone lldb_private::TypeMap &types) { 1449656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 145042dff790SZachary Turner if (!append) 145142dff790SZachary Turner types.Clear(); 145242dff790SZachary Turner if (!name) 145342dff790SZachary Turner return 0; 14547ac1c780SAaron Smith if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 14557ac1c780SAaron Smith return 0; 145642dff790SZachary Turner 145742dff790SZachary Turner searched_symbol_files.clear(); 145842dff790SZachary Turner searched_symbol_files.insert(this); 145942dff790SZachary Turner 146086e9434dSAaron Smith // There is an assumption 'name' is not a regex 1461c1e530eeSAleksandr Urakov FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types); 146286e9434dSAaron Smith 146342dff790SZachary Turner return types.GetSize(); 146442dff790SZachary Turner } 146542dff790SZachary Turner 14664911023fSZachary Turner void SymbolFilePDB::DumpClangAST(Stream &s) { 14670e252e38SAlex Langford auto type_system_or_err = 14680e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 14690e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 14700e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 14710e252e38SAlex Langford std::move(err), "Unable to dump ClangAST"); 14724911023fSZachary Turner return; 14730e252e38SAlex Langford } 14740e252e38SAlex Langford 14750e252e38SAlex Langford auto *clang_type_system = 14760e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 14770e252e38SAlex Langford if (!clang_type_system) 14780e252e38SAlex Langford return; 14790e252e38SAlex Langford clang_type_system->Dump(s); 14804911023fSZachary Turner } 14814911023fSZachary Turner 1482c8316ed2SAaron Smith void SymbolFilePDB::FindTypesByRegex( 1483c8316ed2SAaron Smith const lldb_private::RegularExpression ®ex, uint32_t max_matches, 1484b9c1b51eSKate Stone lldb_private::TypeMap &types) { 1485b9c1b51eSKate Stone // When searching by regex, we need to go out of our way to limit the search 14869d0eb996SAdrian McCarthy // space as much as possible since this searches EVERYTHING in the PDB, 14879d0eb996SAdrian McCarthy // manually doing regex comparisons. PDB library isn't optimized for regex 14889d0eb996SAdrian McCarthy // searches or searches across multiple symbol types at the same time, so the 1489b9c1b51eSKate Stone // best we can do is to search enums, then typedefs, then classes one by one, 14909d0eb996SAdrian McCarthy // and do a regex comparison against each of them. 1491b9c1b51eSKate Stone PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, 1492b9c1b51eSKate Stone PDB_SymType::UDT}; 149354fd7ff6SZachary Turner std::unique_ptr<IPDBEnumSymbols> results; 149442dff790SZachary Turner 149542dff790SZachary Turner uint32_t matches = 0; 149642dff790SZachary Turner 1497b9c1b51eSKate Stone for (auto tag : tags_to_search) { 149810a02577SAaron Smith results = m_global_scope_up->findAllChildren(tag); 149910a02577SAaron Smith if (!results) 150010a02577SAaron Smith continue; 150110a02577SAaron Smith 1502b9c1b51eSKate Stone while (auto result = results->getNext()) { 150342dff790SZachary Turner if (max_matches > 0 && matches >= max_matches) 150442dff790SZachary Turner break; 150542dff790SZachary Turner 150642dff790SZachary Turner std::string type_name; 150754fd7ff6SZachary Turner if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get())) 150842dff790SZachary Turner type_name = enum_type->getName(); 1509b9c1b51eSKate Stone else if (auto typedef_type = 1510b9c1b51eSKate Stone llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get())) 151142dff790SZachary Turner type_name = typedef_type->getName(); 151254fd7ff6SZachary Turner else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get())) 151342dff790SZachary Turner type_name = class_type->getName(); 1514b9c1b51eSKate Stone else { 15159d0eb996SAdrian McCarthy // We're looking only for types that have names. Skip symbols, as well 15169d0eb996SAdrian McCarthy // as unnamed types such as arrays, pointers, etc. 151742dff790SZachary Turner continue; 151842dff790SZachary Turner } 151942dff790SZachary Turner 152086e9434dSAaron Smith if (!regex.Execute(type_name)) 152142dff790SZachary Turner continue; 152242dff790SZachary Turner 1523b9c1b51eSKate Stone // This should cause the type to get cached and stored in the `m_types` 1524b9c1b51eSKate Stone // lookup. 152542dff790SZachary Turner if (!ResolveTypeUID(result->getSymIndexId())) 152642dff790SZachary Turner continue; 152742dff790SZachary Turner 152842dff790SZachary Turner auto iter = m_types.find(result->getSymIndexId()); 152942dff790SZachary Turner if (iter == m_types.end()) 153042dff790SZachary Turner continue; 153142dff790SZachary Turner types.Insert(iter->second); 153242dff790SZachary Turner ++matches; 153342dff790SZachary Turner } 153442dff790SZachary Turner } 153542dff790SZachary Turner } 153642dff790SZachary Turner 1537709426b3SAleksandr Urakov void SymbolFilePDB::FindTypesByName( 1538c1e530eeSAleksandr Urakov llvm::StringRef name, 1539709426b3SAleksandr Urakov const lldb_private::CompilerDeclContext *parent_decl_ctx, 1540709426b3SAleksandr Urakov uint32_t max_matches, lldb_private::TypeMap &types) { 154154fd7ff6SZachary Turner std::unique_ptr<IPDBEnumSymbols> results; 1542f76fe682SAaron Smith if (name.empty()) 1543f76fe682SAaron Smith return; 1544709426b3SAleksandr Urakov results = m_global_scope_up->findAllChildren(PDB_SymType::None); 154510a02577SAaron Smith if (!results) 154610a02577SAaron Smith return; 154742dff790SZachary Turner 154842dff790SZachary Turner uint32_t matches = 0; 154942dff790SZachary Turner 1550b9c1b51eSKate Stone while (auto result = results->getNext()) { 155142dff790SZachary Turner if (max_matches > 0 && matches >= max_matches) 155242dff790SZachary Turner break; 1553709426b3SAleksandr Urakov 1554c1e530eeSAleksandr Urakov if (MSVCUndecoratedNameParser::DropScope( 1555c1e530eeSAleksandr Urakov result->getRawSymbol().getName()) != name) 1556709426b3SAleksandr Urakov continue; 1557709426b3SAleksandr Urakov 1558b9c1b51eSKate Stone switch (result->getSymTag()) { 155954fd7ff6SZachary Turner case PDB_SymType::Enum: 156054fd7ff6SZachary Turner case PDB_SymType::UDT: 156154fd7ff6SZachary Turner case PDB_SymType::Typedef: 156242dff790SZachary Turner break; 156342dff790SZachary Turner default: 156405097246SAdrian Prantl // We're looking only for types that have names. Skip symbols, as well 156505097246SAdrian Prantl // as unnamed types such as arrays, pointers, etc. 156642dff790SZachary Turner continue; 156742dff790SZachary Turner } 156842dff790SZachary Turner 1569b9c1b51eSKate Stone // This should cause the type to get cached and stored in the `m_types` 1570b9c1b51eSKate Stone // lookup. 157142dff790SZachary Turner if (!ResolveTypeUID(result->getSymIndexId())) 157242dff790SZachary Turner continue; 157342dff790SZachary Turner 1574a5235af9SAleksandr Urakov if (parent_decl_ctx && GetDeclContextContainingUID( 1575a5235af9SAleksandr Urakov result->getSymIndexId()) != *parent_decl_ctx) 1576709426b3SAleksandr Urakov continue; 1577709426b3SAleksandr Urakov 157842dff790SZachary Turner auto iter = m_types.find(result->getSymIndexId()); 157942dff790SZachary Turner if (iter == m_types.end()) 158042dff790SZachary Turner continue; 158142dff790SZachary Turner types.Insert(iter->second); 158242dff790SZachary Turner ++matches; 158342dff790SZachary Turner } 158474e08ca0SZachary Turner } 158574e08ca0SZachary Turner 1586b9c1b51eSKate Stone size_t SymbolFilePDB::FindTypes( 1587b9c1b51eSKate Stone const std::vector<lldb_private::CompilerContext> &contexts, bool append, 1588b9c1b51eSKate Stone lldb_private::TypeMap &types) { 158942dff790SZachary Turner return 0; 159074e08ca0SZachary Turner } 159174e08ca0SZachary Turner 1592c8316ed2SAaron Smith void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol, 15937ac1c780SAaron Smith uint32_t type_mask, 15947ac1c780SAaron Smith TypeCollection &type_collection) { 15957ac1c780SAaron Smith bool can_parse = false; 1596e664b5dcSAaron Smith switch (pdb_symbol.getSymTag()) { 15977ac1c780SAaron Smith case PDB_SymType::ArrayType: 15987ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassArray) != 0); 15997ac1c780SAaron Smith break; 16007ac1c780SAaron Smith case PDB_SymType::BuiltinType: 16017ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassBuiltin) != 0); 16027ac1c780SAaron Smith break; 16037ac1c780SAaron Smith case PDB_SymType::Enum: 16047ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassEnumeration) != 0); 16057ac1c780SAaron Smith break; 16067ac1c780SAaron Smith case PDB_SymType::Function: 16077ac1c780SAaron Smith case PDB_SymType::FunctionSig: 16087ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassFunction) != 0); 16097ac1c780SAaron Smith break; 16107ac1c780SAaron Smith case PDB_SymType::PointerType: 16117ac1c780SAaron Smith can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer | 16127ac1c780SAaron Smith eTypeClassMemberPointer)) != 0); 16137ac1c780SAaron Smith break; 16147ac1c780SAaron Smith case PDB_SymType::Typedef: 16157ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassTypedef) != 0); 16167ac1c780SAaron Smith break; 16177ac1c780SAaron Smith case PDB_SymType::UDT: { 1618e664b5dcSAaron Smith auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol); 16197ac1c780SAaron Smith assert(udt); 16207ac1c780SAaron Smith can_parse = (udt->getUdtKind() != PDB_UdtType::Interface && 16217ac1c780SAaron Smith ((type_mask & (eTypeClassClass | eTypeClassStruct | 16227ac1c780SAaron Smith eTypeClassUnion)) != 0)); 16237ac1c780SAaron Smith } break; 1624c8316ed2SAaron Smith default: 1625c8316ed2SAaron Smith break; 16267ac1c780SAaron Smith } 16277ac1c780SAaron Smith 16287ac1c780SAaron Smith if (can_parse) { 1629e664b5dcSAaron Smith if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) { 16307ac1c780SAaron Smith auto result = 16317ac1c780SAaron Smith std::find(type_collection.begin(), type_collection.end(), type); 16327ac1c780SAaron Smith if (result == type_collection.end()) 16337ac1c780SAaron Smith type_collection.push_back(type); 16347ac1c780SAaron Smith } 16357ac1c780SAaron Smith } 16367ac1c780SAaron Smith 1637e664b5dcSAaron Smith auto results_up = pdb_symbol.findAllChildren(); 16387ac1c780SAaron Smith while (auto symbol_up = results_up->getNext()) 1639e664b5dcSAaron Smith GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection); 16407ac1c780SAaron Smith } 16417ac1c780SAaron Smith 1642b9c1b51eSKate Stone size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, 1643117b1fa1SZachary Turner TypeClass type_mask, 1644b9c1b51eSKate Stone lldb_private::TypeList &type_list) { 1645656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 16467ac1c780SAaron Smith TypeCollection type_collection; 16477ac1c780SAaron Smith uint32_t old_size = type_list.GetSize(); 1648c8316ed2SAaron Smith CompileUnit *cu = 1649c8316ed2SAaron Smith sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr; 16507ac1c780SAaron Smith if (cu) { 16517ac1c780SAaron Smith auto compiland_up = GetPDBCompilandByUID(cu->GetID()); 1652e664b5dcSAaron Smith if (!compiland_up) 1653e664b5dcSAaron Smith return 0; 1654e664b5dcSAaron Smith GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection); 16557ac1c780SAaron Smith } else { 16567ac1c780SAaron Smith for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) { 16577ac1c780SAaron Smith auto cu_sp = ParseCompileUnitAtIndex(cu_idx); 1658d5a925f4SAaron Smith if (cu_sp) { 1659e664b5dcSAaron Smith if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID())) 1660e664b5dcSAaron Smith GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection); 16617ac1c780SAaron Smith } 16627ac1c780SAaron Smith } 16637ac1c780SAaron Smith } 16647ac1c780SAaron Smith 16657ac1c780SAaron Smith for (auto type : type_collection) { 16667ac1c780SAaron Smith type->GetForwardCompilerType(); 16677ac1c780SAaron Smith type_list.Insert(type->shared_from_this()); 16687ac1c780SAaron Smith } 16697ac1c780SAaron Smith return type_list.GetSize() - old_size; 167074e08ca0SZachary Turner } 167174e08ca0SZachary Turner 16720e252e38SAlex Langford llvm::Expected<lldb_private::TypeSystem &> 1673b9c1b51eSKate Stone SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { 16740e252e38SAlex Langford auto type_system_or_err = 1675b9c1b51eSKate Stone m_obj_file->GetModule()->GetTypeSystemForLanguage(language); 16760e252e38SAlex Langford if (type_system_or_err) { 16770e252e38SAlex Langford type_system_or_err->SetSymbolFile(this); 16780e252e38SAlex Langford } 16790e252e38SAlex Langford return type_system_or_err; 168074e08ca0SZachary Turner } 168174e08ca0SZachary Turner 1682c68925abSZachary Turner PDBASTParser *SymbolFilePDB::GetPDBAstParser() { 16830e252e38SAlex Langford auto type_system_or_err = 16840e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 16850e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 16860e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 16870e252e38SAlex Langford std::move(err), "Unable to get PDB AST parser"); 16880e252e38SAlex Langford return nullptr; 16890e252e38SAlex Langford } 16900e252e38SAlex Langford 16910e252e38SAlex Langford auto *clang_type_system = 16920e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 1693c68925abSZachary Turner if (!clang_type_system) 1694c68925abSZachary Turner return nullptr; 1695c68925abSZachary Turner 1696c68925abSZachary Turner return clang_type_system->GetPDBParser(); 1697c68925abSZachary Turner } 1698c68925abSZachary Turner 1699c68925abSZachary Turner 1700b9c1b51eSKate Stone lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( 17010e4c4821SAdrian Prantl lldb_private::ConstString name, 1702b9c1b51eSKate Stone const lldb_private::CompilerDeclContext *parent_decl_ctx) { 1703656ddeb2SPavel Labath std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 17040e252e38SAlex Langford auto type_system_or_err = 17050e252e38SAlex Langford GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 17060e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 17070e252e38SAlex Langford LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 17080e252e38SAlex Langford std::move(err), "Unable to find namespace {}", 17090e252e38SAlex Langford name.AsCString()); 17100e252e38SAlex Langford return CompilerDeclContext(); 17110e252e38SAlex Langford } 17120e252e38SAlex Langford 17130e252e38SAlex Langford auto *clang_type_system = 17140e252e38SAlex Langford llvm::dyn_cast_or_null<ClangASTContext>(&type_system_or_err.get()); 1715709426b3SAleksandr Urakov if (!clang_type_system) 1716709426b3SAleksandr Urakov return CompilerDeclContext(); 1717709426b3SAleksandr Urakov 1718709426b3SAleksandr Urakov PDBASTParser *pdb = clang_type_system->GetPDBParser(); 1719709426b3SAleksandr Urakov if (!pdb) 1720709426b3SAleksandr Urakov return CompilerDeclContext(); 1721709426b3SAleksandr Urakov 1722709426b3SAleksandr Urakov clang::DeclContext *decl_context = nullptr; 1723709426b3SAleksandr Urakov if (parent_decl_ctx) 1724709426b3SAleksandr Urakov decl_context = static_cast<clang::DeclContext *>( 1725709426b3SAleksandr Urakov parent_decl_ctx->GetOpaqueDeclContext()); 1726709426b3SAleksandr Urakov 1727709426b3SAleksandr Urakov auto namespace_decl = 1728709426b3SAleksandr Urakov pdb->FindNamespaceDecl(decl_context, name.GetStringRef()); 1729709426b3SAleksandr Urakov if (!namespace_decl) 1730709426b3SAleksandr Urakov return CompilerDeclContext(); 1731709426b3SAleksandr Urakov 17320e252e38SAlex Langford return CompilerDeclContext(clang_type_system, 1733709426b3SAleksandr Urakov static_cast<clang::DeclContext *>(namespace_decl)); 173474e08ca0SZachary Turner } 173574e08ca0SZachary Turner 1736b9c1b51eSKate Stone lldb_private::ConstString SymbolFilePDB::GetPluginName() { 173774e08ca0SZachary Turner static ConstString g_name("pdb"); 173874e08ca0SZachary Turner return g_name; 173974e08ca0SZachary Turner } 174074e08ca0SZachary Turner 1741b9c1b51eSKate Stone uint32_t SymbolFilePDB::GetPluginVersion() { return 1; } 174274e08ca0SZachary Turner 1743b9c1b51eSKate Stone IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; } 1744b9c1b51eSKate Stone 1745b9c1b51eSKate Stone const IPDBSession &SymbolFilePDB::GetPDBSession() const { 174642dff790SZachary Turner return *m_session_up; 174742dff790SZachary Turner } 174842dff790SZachary Turner 1749c8316ed2SAaron Smith lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id, 1750c8316ed2SAaron Smith uint32_t index) { 175174e08ca0SZachary Turner auto found_cu = m_comp_units.find(id); 175274e08ca0SZachary Turner if (found_cu != m_comp_units.end()) 175374e08ca0SZachary Turner return found_cu->second; 175474e08ca0SZachary Turner 175510a02577SAaron Smith auto compiland_up = GetPDBCompilandByUID(id); 175610a02577SAaron Smith if (!compiland_up) 175710a02577SAaron Smith return CompUnitSP(); 175874e08ca0SZachary Turner 175974e08ca0SZachary Turner lldb::LanguageType lang; 176010a02577SAaron Smith auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>(); 176174e08ca0SZachary Turner if (!details) 176274e08ca0SZachary Turner lang = lldb::eLanguageTypeC_plus_plus; 176374e08ca0SZachary Turner else 176474e08ca0SZachary Turner lang = TranslateLanguage(details->getLanguage()); 176574e08ca0SZachary Turner 1766f76fe682SAaron Smith if (lang == lldb::LanguageType::eLanguageTypeUnknown) 1767f76fe682SAaron Smith return CompUnitSP(); 1768f76fe682SAaron Smith 1769487b0c6bSAaron Smith std::string path = compiland_up->getSourceFileFullPath(); 1770f76fe682SAaron Smith if (path.empty()) 1771f76fe682SAaron Smith return CompUnitSP(); 1772f76fe682SAaron Smith 1773b9c1b51eSKate Stone // Don't support optimized code for now, DebugInfoPDB does not return this 1774b9c1b51eSKate Stone // information. 1775ad2b63cbSGreg Clayton LazyBool optimized = eLazyBoolNo; 1776c8316ed2SAaron Smith auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, 1777c8316ed2SAaron Smith path.c_str(), id, lang, optimized); 177810a02577SAaron Smith 177910a02577SAaron Smith if (!cu_sp) 178010a02577SAaron Smith return CompUnitSP(); 178110a02577SAaron Smith 178210a02577SAaron Smith m_comp_units.insert(std::make_pair(id, cu_sp)); 178310a02577SAaron Smith if (index == UINT32_MAX) 1784e664b5dcSAaron Smith GetCompileUnitIndex(*compiland_up, index); 178510a02577SAaron Smith lldbassert(index != UINT32_MAX); 1786e0119909SPavel Labath SetCompileUnitAtIndex(index, cu_sp); 178710a02577SAaron Smith return cu_sp; 178874e08ca0SZachary Turner } 178974e08ca0SZachary Turner 1790863f8c18SZachary Turner bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, 1791863f8c18SZachary Turner uint32_t match_line) { 1792863f8c18SZachary Turner auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); 179310a02577SAaron Smith if (!compiland_up) 179410a02577SAaron Smith return false; 179574e08ca0SZachary Turner 1796b9c1b51eSKate Stone // LineEntry needs the *index* of the file into the list of support files 17979d0eb996SAdrian McCarthy // returned by ParseCompileUnitSupportFiles. But the underlying SDK gives us 179805097246SAdrian Prantl // a globally unique idenfitifier in the namespace of the PDB. So, we have 179905097246SAdrian Prantl // to do a mapping so that we can hand out indices. 180042dff790SZachary Turner llvm::DenseMap<uint32_t, uint32_t> index_map; 180110a02577SAaron Smith BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map); 1802863f8c18SZachary Turner auto line_table = llvm::make_unique<LineTable>(&comp_unit); 180374e08ca0SZachary Turner 180410a02577SAaron Smith // Find contributions to `compiland` from all source and header files. 1805863f8c18SZachary Turner std::string path = comp_unit.GetPath(); 180610a02577SAaron Smith auto files = m_session_up->getSourceFilesForCompiland(*compiland_up); 180710a02577SAaron Smith if (!files) 180810a02577SAaron Smith return false; 180974e08ca0SZachary Turner 181005097246SAdrian Prantl // For each source and header file, create a LineSequence for contributions 181105097246SAdrian Prantl // to the compiland from that file, and add the sequence. 1812b9c1b51eSKate Stone while (auto file = files->getNext()) { 1813b9c1b51eSKate Stone std::unique_ptr<LineSequence> sequence( 1814b9c1b51eSKate Stone line_table->CreateLineSequenceContainer()); 181510a02577SAaron Smith auto lines = m_session_up->findLineNumbers(*compiland_up, *file); 181610a02577SAaron Smith if (!lines) 181710a02577SAaron Smith continue; 181874e08ca0SZachary Turner int entry_count = lines->getChildCount(); 181974e08ca0SZachary Turner 18207e8c7beaSZachary Turner uint64_t prev_addr; 18217e8c7beaSZachary Turner uint32_t prev_length; 18227e8c7beaSZachary Turner uint32_t prev_line; 18237e8c7beaSZachary Turner uint32_t prev_source_idx; 18247e8c7beaSZachary Turner 1825b9c1b51eSKate Stone for (int i = 0; i < entry_count; ++i) { 182674e08ca0SZachary Turner auto line = lines->getChildAtIndex(i); 182774e08ca0SZachary Turner 18287e8c7beaSZachary Turner uint64_t lno = line->getLineNumber(); 18297e8c7beaSZachary Turner uint64_t addr = line->getVirtualAddress(); 18307e8c7beaSZachary Turner uint32_t length = line->getLength(); 183174e08ca0SZachary Turner uint32_t source_id = line->getSourceFileId(); 18327e8c7beaSZachary Turner uint32_t col = line->getColumnNumber(); 183374e08ca0SZachary Turner uint32_t source_idx = index_map[source_id]; 183474e08ca0SZachary Turner 183505097246SAdrian Prantl // There was a gap between the current entry and the previous entry if 183605097246SAdrian Prantl // the addresses don't perfectly line up. 18377e8c7beaSZachary Turner bool is_gap = (i > 0) && (prev_addr + prev_length < addr); 18387e8c7beaSZachary Turner 1839b9c1b51eSKate Stone // Before inserting the current entry, insert a terminal entry at the end 18409d0eb996SAdrian McCarthy // of the previous entry's address range if the current entry resulted in 18419d0eb996SAdrian McCarthy // a gap from the previous entry. 1842b9c1b51eSKate Stone if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) { 1843b9c1b51eSKate Stone line_table->AppendLineEntryToSequence( 1844b9c1b51eSKate Stone sequence.get(), prev_addr + prev_length, prev_line, 0, 18457e8c7beaSZachary Turner prev_source_idx, false, false, false, false, true); 1846010edd37SAaron Smith 1847010edd37SAaron Smith line_table->InsertSequence(sequence.release()); 1848010edd37SAaron Smith sequence.reset(line_table->CreateLineSequenceContainer()); 18497e8c7beaSZachary Turner } 18507e8c7beaSZachary Turner 1851b9c1b51eSKate Stone if (ShouldAddLine(match_line, lno, length)) { 18527e8c7beaSZachary Turner bool is_statement = line->isStatement(); 185374e08ca0SZachary Turner bool is_prologue = false; 185474e08ca0SZachary Turner bool is_epilogue = false; 1855b9c1b51eSKate Stone auto func = 1856b9c1b51eSKate Stone m_session_up->findSymbolByAddress(addr, PDB_SymType::Function); 1857b9c1b51eSKate Stone if (func) { 185854fd7ff6SZachary Turner auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>(); 185910a02577SAaron Smith if (prologue) 18607e8c7beaSZachary Turner is_prologue = (addr == prologue->getVirtualAddress()); 186174e08ca0SZachary Turner 186254fd7ff6SZachary Turner auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>(); 186310a02577SAaron Smith if (epilogue) 18647e8c7beaSZachary Turner is_epilogue = (addr == epilogue->getVirtualAddress()); 18657e8c7beaSZachary Turner } 186674e08ca0SZachary Turner 1867b9c1b51eSKate Stone line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, 1868b9c1b51eSKate Stone source_idx, is_statement, false, 18697e8c7beaSZachary Turner is_prologue, is_epilogue, false); 18707e8c7beaSZachary Turner } 18717e8c7beaSZachary Turner 18727e8c7beaSZachary Turner prev_addr = addr; 18737e8c7beaSZachary Turner prev_length = length; 18747e8c7beaSZachary Turner prev_line = lno; 18757e8c7beaSZachary Turner prev_source_idx = source_idx; 18767e8c7beaSZachary Turner } 18777e8c7beaSZachary Turner 1878b9c1b51eSKate Stone if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) { 18797e8c7beaSZachary Turner // The end is always a terminal entry, so insert it regardless. 1880b9c1b51eSKate Stone line_table->AppendLineEntryToSequence( 1881b9c1b51eSKate Stone sequence.get(), prev_addr + prev_length, prev_line, 0, 18827e8c7beaSZachary Turner prev_source_idx, false, false, false, false, true); 188374e08ca0SZachary Turner } 188474e08ca0SZachary Turner 18857e8c7beaSZachary Turner line_table->InsertSequence(sequence.release()); 188674e08ca0SZachary Turner } 188774e08ca0SZachary Turner 188810a02577SAaron Smith if (line_table->GetSize()) { 1889863f8c18SZachary Turner comp_unit.SetLineTable(line_table.release()); 189074e08ca0SZachary Turner return true; 189174e08ca0SZachary Turner } 189210a02577SAaron Smith return false; 189310a02577SAaron Smith } 189474e08ca0SZachary Turner 1895b9c1b51eSKate Stone void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap( 189610a02577SAaron Smith const PDBSymbolCompiland &compiland, 1897b9c1b51eSKate Stone llvm::DenseMap<uint32_t, uint32_t> &index_map) const { 189805097246SAdrian Prantl // This is a hack, but we need to convert the source id into an index into 189905097246SAdrian Prantl // the support files array. We don't want to do path comparisons to avoid 19009d0eb996SAdrian McCarthy // basename / full path issues that may or may not even be a problem, so we 19019d0eb996SAdrian McCarthy // use the globally unique source file identifiers. Ideally we could use the 19029d0eb996SAdrian McCarthy // global identifiers everywhere, but LineEntry currently assumes indices. 190310a02577SAaron Smith auto source_files = m_session_up->getSourceFilesForCompiland(compiland); 190410a02577SAaron Smith if (!source_files) 190510a02577SAaron Smith return; 19069ea80d25SPavel Labath 19079ea80d25SPavel Labath // LLDB uses the DWARF-like file numeration (one based) 19089ea80d25SPavel Labath int index = 1; 190974e08ca0SZachary Turner 1910b9c1b51eSKate Stone while (auto file = source_files->getNext()) { 191174e08ca0SZachary Turner uint32_t source_id = file->getUniqueId(); 191274e08ca0SZachary Turner index_map[source_id] = index++; 191374e08ca0SZachary Turner } 191474e08ca0SZachary Turner } 19157ac1c780SAaron Smith 19167ac1c780SAaron Smith lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress( 19177ac1c780SAaron Smith const lldb_private::Address &so_addr) { 19187ac1c780SAaron Smith lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1919308e39caSAaron Smith if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 19207ac1c780SAaron Smith return nullptr; 19217ac1c780SAaron Smith 1922308e39caSAaron Smith // If it is a PDB function's vm addr, this is the first sure bet. 1923308e39caSAaron Smith if (auto lines = 1924308e39caSAaron Smith m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/1)) { 1925308e39caSAaron Smith if (auto first_line = lines->getNext()) 1926308e39caSAaron Smith return ParseCompileUnitForUID(first_line->getCompilandId()); 19277ac1c780SAaron Smith } 19287ac1c780SAaron Smith 1929308e39caSAaron Smith // Otherwise we resort to section contributions. 1930308e39caSAaron Smith if (auto sec_contribs = m_session_up->getSectionContribs()) { 1931308e39caSAaron Smith while (auto section = sec_contribs->getNext()) { 1932308e39caSAaron Smith auto va = section->getVirtualAddress(); 1933308e39caSAaron Smith if (file_vm_addr >= va && file_vm_addr < va + section->getLength()) 1934308e39caSAaron Smith return ParseCompileUnitForUID(section->getCompilandId()); 1935308e39caSAaron Smith } 1936308e39caSAaron Smith } 19377ac1c780SAaron Smith return nullptr; 19387ac1c780SAaron Smith } 19397ac1c780SAaron Smith 19407ac1c780SAaron Smith Mangled 1941e664b5dcSAaron Smith SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { 19427ac1c780SAaron Smith Mangled mangled; 1943e664b5dcSAaron Smith auto func_name = pdb_func.getName(); 1944e664b5dcSAaron Smith auto func_undecorated_name = pdb_func.getUndecoratedName(); 19457ac1c780SAaron Smith std::string func_decorated_name; 19467ac1c780SAaron Smith 19477ac1c780SAaron Smith // Seek from public symbols for non-static function's decorated name if any. 19487ac1c780SAaron Smith // For static functions, they don't have undecorated names and aren't exposed 19497ac1c780SAaron Smith // in Public Symbols either. 19507ac1c780SAaron Smith if (!func_undecorated_name.empty()) { 1951c8316ed2SAaron Smith auto result_up = m_global_scope_up->findChildren( 1952c8316ed2SAaron Smith PDB_SymType::PublicSymbol, func_undecorated_name, 19537ac1c780SAaron Smith PDB_NameSearchFlags::NS_UndecoratedName); 19547ac1c780SAaron Smith if (result_up) { 19557ac1c780SAaron Smith while (auto symbol_up = result_up->getNext()) { 19567ac1c780SAaron Smith // For a public symbol, it is unique. 19577ac1c780SAaron Smith lldbassert(result_up->getChildCount() == 1); 19587ac1c780SAaron Smith if (auto *pdb_public_sym = 1959c8316ed2SAaron Smith llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>( 1960c8316ed2SAaron Smith symbol_up.get())) { 19617ac1c780SAaron Smith if (pdb_public_sym->isFunction()) { 19627ac1c780SAaron Smith func_decorated_name = pdb_public_sym->getName(); 1963f76fe682SAaron Smith break; 19647ac1c780SAaron Smith } 19657ac1c780SAaron Smith } 19667ac1c780SAaron Smith } 19677ac1c780SAaron Smith } 19687ac1c780SAaron Smith } 19697ac1c780SAaron Smith if (!func_decorated_name.empty()) { 19707ac1c780SAaron Smith mangled.SetMangledName(ConstString(func_decorated_name)); 19717ac1c780SAaron Smith 19727ac1c780SAaron Smith // For MSVC, format of C funciton's decorated name depends on calling 19737ac1c780SAaron Smith // conventon. Unfortunately none of the format is recognized by current 19747ac1c780SAaron Smith // LLDB. For example, `_purecall` is a __cdecl C function. From PDB, 197505097246SAdrian Prantl // `__purecall` is retrieved as both its decorated and undecorated name 197605097246SAdrian Prantl // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall` 197705097246SAdrian Prantl // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix). 197805097246SAdrian Prantl // Mangled::GetDemangledName method will fail internally and caches an 197905097246SAdrian Prantl // empty string as its undecorated name. So we will face a contradition 198005097246SAdrian Prantl // here for the same symbol: 19817ac1c780SAaron Smith // non-empty undecorated name from PDB 19827ac1c780SAaron Smith // empty undecorated name from LLDB 19837ac1c780SAaron Smith if (!func_undecorated_name.empty() && 19847ac1c780SAaron Smith mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty()) 19857ac1c780SAaron Smith mangled.SetDemangledName(ConstString(func_undecorated_name)); 19867ac1c780SAaron Smith 19877ac1c780SAaron Smith // LLDB uses several flags to control how a C++ decorated name is 198805097246SAdrian Prantl // undecorated for MSVC. See `safeUndecorateName` in Class Mangled. So the 198905097246SAdrian Prantl // yielded name could be different from what we retrieve from 19907ac1c780SAaron Smith // PDB source unless we also apply same flags in getting undecorated 19917ac1c780SAaron Smith // name through PDBSymbolFunc::getUndecoratedNameEx method. 19927ac1c780SAaron Smith if (!func_undecorated_name.empty() && 19937ac1c780SAaron Smith mangled.GetDemangledName(mangled.GuessLanguage()) != 19947ac1c780SAaron Smith ConstString(func_undecorated_name)) 19957ac1c780SAaron Smith mangled.SetDemangledName(ConstString(func_undecorated_name)); 19967ac1c780SAaron Smith } else if (!func_undecorated_name.empty()) { 19977ac1c780SAaron Smith mangled.SetDemangledName(ConstString(func_undecorated_name)); 19987ac1c780SAaron Smith } else if (!func_name.empty()) 19997ac1c780SAaron Smith mangled.SetValue(ConstString(func_name), false); 20007ac1c780SAaron Smith 20017ac1c780SAaron Smith return mangled; 20027ac1c780SAaron Smith } 20037ac1c780SAaron Smith 20047ac1c780SAaron Smith bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( 20057ac1c780SAaron Smith const lldb_private::CompilerDeclContext *decl_ctx) { 20067ac1c780SAaron Smith if (decl_ctx == nullptr || !decl_ctx->IsValid()) 20077ac1c780SAaron Smith return true; 20087ac1c780SAaron Smith 20097ac1c780SAaron Smith TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); 20107ac1c780SAaron Smith if (!decl_ctx_type_system) 20117ac1c780SAaron Smith return false; 20120e252e38SAlex Langford auto type_system_or_err = GetTypeSystemForLanguage( 20137ac1c780SAaron Smith decl_ctx_type_system->GetMinimumLanguage(nullptr)); 20140e252e38SAlex Langford if (auto err = type_system_or_err.takeError()) { 20150e252e38SAlex Langford LLDB_LOG_ERROR( 20160e252e38SAlex Langford lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 20170e252e38SAlex Langford std::move(err), 20180e252e38SAlex Langford "Unable to determine if DeclContext matches this symbol file"); 20190e252e38SAlex Langford return false; 20200e252e38SAlex Langford } 20210e252e38SAlex Langford 20220e252e38SAlex Langford if (decl_ctx_type_system == &type_system_or_err.get()) 20237ac1c780SAaron Smith return true; // The type systems match, return true 20247ac1c780SAaron Smith 20257ac1c780SAaron Smith return false; 20267ac1c780SAaron Smith } 2027356aa4a9SAleksandr Urakov 2028356aa4a9SAleksandr Urakov uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) { 2029356aa4a9SAleksandr Urakov static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) { 2030356aa4a9SAleksandr Urakov return lhs < rhs.Offset; 2031356aa4a9SAleksandr Urakov }; 2032356aa4a9SAleksandr Urakov 2033356aa4a9SAleksandr Urakov // Cache section contributions 2034356aa4a9SAleksandr Urakov if (m_sec_contribs.empty()) { 2035356aa4a9SAleksandr Urakov if (auto SecContribs = m_session_up->getSectionContribs()) { 2036356aa4a9SAleksandr Urakov while (auto SectionContrib = SecContribs->getNext()) { 2037356aa4a9SAleksandr Urakov auto comp_id = SectionContrib->getCompilandId(); 2038356aa4a9SAleksandr Urakov if (!comp_id) 2039356aa4a9SAleksandr Urakov continue; 2040356aa4a9SAleksandr Urakov 2041356aa4a9SAleksandr Urakov auto sec = SectionContrib->getAddressSection(); 2042356aa4a9SAleksandr Urakov auto &sec_cs = m_sec_contribs[sec]; 2043356aa4a9SAleksandr Urakov 2044356aa4a9SAleksandr Urakov auto offset = SectionContrib->getAddressOffset(); 2045356aa4a9SAleksandr Urakov auto it = 2046356aa4a9SAleksandr Urakov std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper); 2047356aa4a9SAleksandr Urakov 2048356aa4a9SAleksandr Urakov auto size = SectionContrib->getLength(); 2049356aa4a9SAleksandr Urakov sec_cs.insert(it, {offset, size, comp_id}); 2050356aa4a9SAleksandr Urakov } 2051356aa4a9SAleksandr Urakov } 2052356aa4a9SAleksandr Urakov } 2053356aa4a9SAleksandr Urakov 2054356aa4a9SAleksandr Urakov // Check by line number 2055356aa4a9SAleksandr Urakov if (auto Lines = data.getLineNumbers()) { 2056356aa4a9SAleksandr Urakov if (auto FirstLine = Lines->getNext()) 2057356aa4a9SAleksandr Urakov return FirstLine->getCompilandId(); 2058356aa4a9SAleksandr Urakov } 2059356aa4a9SAleksandr Urakov 2060356aa4a9SAleksandr Urakov // Retrieve section + offset 2061356aa4a9SAleksandr Urakov uint32_t DataSection = data.getAddressSection(); 2062356aa4a9SAleksandr Urakov uint32_t DataOffset = data.getAddressOffset(); 2063356aa4a9SAleksandr Urakov if (DataSection == 0) { 2064356aa4a9SAleksandr Urakov if (auto RVA = data.getRelativeVirtualAddress()) 2065356aa4a9SAleksandr Urakov m_session_up->addressForRVA(RVA, DataSection, DataOffset); 2066356aa4a9SAleksandr Urakov } 2067356aa4a9SAleksandr Urakov 2068356aa4a9SAleksandr Urakov if (DataSection) { 2069356aa4a9SAleksandr Urakov // Search by section contributions 2070356aa4a9SAleksandr Urakov auto &sec_cs = m_sec_contribs[DataSection]; 2071356aa4a9SAleksandr Urakov auto it = 2072356aa4a9SAleksandr Urakov std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper); 2073356aa4a9SAleksandr Urakov if (it != sec_cs.begin()) { 2074356aa4a9SAleksandr Urakov --it; 2075356aa4a9SAleksandr Urakov if (DataOffset < it->Offset + it->Size) 2076356aa4a9SAleksandr Urakov return it->CompilandId; 2077356aa4a9SAleksandr Urakov } 2078356aa4a9SAleksandr Urakov } else { 2079356aa4a9SAleksandr Urakov // Search in lexical tree 2080356aa4a9SAleksandr Urakov auto LexParentId = data.getLexicalParentId(); 2081356aa4a9SAleksandr Urakov while (auto LexParent = m_session_up->getSymbolById(LexParentId)) { 2082356aa4a9SAleksandr Urakov if (LexParent->getSymTag() == PDB_SymType::Exe) 2083356aa4a9SAleksandr Urakov break; 2084356aa4a9SAleksandr Urakov if (LexParent->getSymTag() == PDB_SymType::Compiland) 2085356aa4a9SAleksandr Urakov return LexParentId; 2086356aa4a9SAleksandr Urakov LexParentId = LexParent->getRawSymbol().getLexicalParentId(); 2087356aa4a9SAleksandr Urakov } 2088356aa4a9SAleksandr Urakov } 2089356aa4a9SAleksandr Urakov 2090356aa4a9SAleksandr Urakov return 0; 2091356aa4a9SAleksandr Urakov } 2092