174e08ca0SZachary Turner //===-- SymbolFilePDB.cpp ---------------------------------------*- C++ -*-===// 274e08ca0SZachary Turner // 374e08ca0SZachary Turner // The LLVM Compiler Infrastructure 474e08ca0SZachary Turner // 574e08ca0SZachary Turner // This file is distributed under the University of Illinois Open Source 674e08ca0SZachary Turner // License. See LICENSE.TXT for details. 774e08ca0SZachary Turner // 874e08ca0SZachary Turner //===----------------------------------------------------------------------===// 974e08ca0SZachary Turner 1074e08ca0SZachary Turner #include "SymbolFilePDB.h" 1174e08ca0SZachary Turner 1242dff790SZachary Turner #include "clang/Lex/Lexer.h" 1342dff790SZachary Turner 1474e08ca0SZachary Turner #include "lldb/Core/Module.h" 1574e08ca0SZachary Turner #include "lldb/Core/PluginManager.h" 1642dff790SZachary Turner #include "lldb/Symbol/ClangASTContext.h" 1774e08ca0SZachary Turner #include "lldb/Symbol/CompileUnit.h" 1874e08ca0SZachary Turner #include "lldb/Symbol/LineTable.h" 1974e08ca0SZachary Turner #include "lldb/Symbol/ObjectFile.h" 2074e08ca0SZachary Turner #include "lldb/Symbol/SymbolContext.h" 2110a02577SAaron Smith #include "lldb/Symbol/SymbolVendor.h" 22ec40f818SAaron Smith #include "lldb/Symbol/TypeList.h" 23308e39caSAaron Smith #include "lldb/Symbol/TypeMap.h" 2486e9434dSAaron Smith #include "lldb/Utility/RegularExpression.h" 2574e08ca0SZachary Turner 26b8d8c62bSPavel Labath #include "llvm/DebugInfo/PDB/GenericError.h" 271f8552abSAaron Smith #include "llvm/DebugInfo/PDB/IPDBDataStream.h" 2874e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 2974e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" 30308e39caSAaron Smith #include "llvm/DebugInfo/PDB/IPDBSectionContrib.h" 3174e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 321f8552abSAaron Smith #include "llvm/DebugInfo/PDB/IPDBTable.h" 3374e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbol.h" 347ac1c780SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolBlock.h" 3574e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 3674e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" 371f8552abSAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolData.h" 3874e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 3974e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 4074e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" 4174e08ca0SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" 427ac1c780SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" 4342dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 4442dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" 4542dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 4642dff790SZachary Turner 477ac1c780SAaron Smith #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" 4842dff790SZachary Turner #include "Plugins/SymbolFile/PDB/PDBASTParser.h" 4942dff790SZachary Turner 5042dff790SZachary Turner #include <regex> 5174e08ca0SZachary Turner 5210a02577SAaron Smith using namespace lldb; 5374e08ca0SZachary Turner using namespace lldb_private; 5454fd7ff6SZachary Turner using namespace llvm::pdb; 5574e08ca0SZachary Turner 56b9c1b51eSKate Stone namespace { 57b9c1b51eSKate Stone lldb::LanguageType TranslateLanguage(PDB_Lang lang) { 58b9c1b51eSKate Stone switch (lang) { 5954fd7ff6SZachary Turner case PDB_Lang::Cpp: 6074e08ca0SZachary Turner return lldb::LanguageType::eLanguageTypeC_plus_plus; 6154fd7ff6SZachary Turner case PDB_Lang::C: 6274e08ca0SZachary Turner return lldb::LanguageType::eLanguageTypeC; 6374e08ca0SZachary Turner default: 6474e08ca0SZachary Turner return lldb::LanguageType::eLanguageTypeUnknown; 6574e08ca0SZachary Turner } 6674e08ca0SZachary Turner } 677e8c7beaSZachary Turner 68b9c1b51eSKate Stone bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, 69b9c1b51eSKate Stone uint32_t addr_length) { 70b9c1b51eSKate Stone return ((requested_line == 0 || actual_line == requested_line) && 71b9c1b51eSKate Stone addr_length > 0); 727e8c7beaSZachary Turner } 73c8316ed2SAaron Smith } // namespace 7474e08ca0SZachary Turner 75b9c1b51eSKate Stone void SymbolFilePDB::Initialize() { 76b9c1b51eSKate Stone PluginManager::RegisterPlugin(GetPluginNameStatic(), 77b9c1b51eSKate Stone GetPluginDescriptionStatic(), CreateInstance, 7874e08ca0SZachary Turner DebuggerInitialize); 7974e08ca0SZachary Turner } 8074e08ca0SZachary Turner 81b9c1b51eSKate Stone void SymbolFilePDB::Terminate() { 8274e08ca0SZachary Turner PluginManager::UnregisterPlugin(CreateInstance); 8374e08ca0SZachary Turner } 8474e08ca0SZachary Turner 85b9c1b51eSKate Stone void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} 8674e08ca0SZachary Turner 87b9c1b51eSKate Stone lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() { 8874e08ca0SZachary Turner static ConstString g_name("pdb"); 8974e08ca0SZachary Turner return g_name; 9074e08ca0SZachary Turner } 9174e08ca0SZachary Turner 92b9c1b51eSKate Stone const char *SymbolFilePDB::GetPluginDescriptionStatic() { 9374e08ca0SZachary Turner return "Microsoft PDB debug symbol file reader."; 9474e08ca0SZachary Turner } 9574e08ca0SZachary Turner 9674e08ca0SZachary Turner lldb_private::SymbolFile * 97b9c1b51eSKate Stone SymbolFilePDB::CreateInstance(lldb_private::ObjectFile *obj_file) { 9874e08ca0SZachary Turner return new SymbolFilePDB(obj_file); 9974e08ca0SZachary Turner } 10074e08ca0SZachary Turner 10174e08ca0SZachary Turner SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file) 10210a02577SAaron Smith : SymbolFile(object_file), m_session_up(), m_global_scope_up(), 10310a02577SAaron Smith m_cached_compile_unit_count(0), m_tu_decl_ctx_up() {} 10474e08ca0SZachary Turner 105b9c1b51eSKate Stone SymbolFilePDB::~SymbolFilePDB() {} 10674e08ca0SZachary Turner 107b9c1b51eSKate Stone uint32_t SymbolFilePDB::CalculateAbilities() { 1081f8552abSAaron Smith uint32_t abilities = 0; 1091f8552abSAaron Smith if (!m_obj_file) 1101f8552abSAaron Smith return 0; 1111f8552abSAaron Smith 112b9c1b51eSKate Stone if (!m_session_up) { 11374e08ca0SZachary Turner // Lazily load and match the PDB file, but only do this once. 11474e08ca0SZachary Turner std::string exePath = m_obj_file->GetFileSpec().GetPath(); 115b9c1b51eSKate Stone auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath), 116b9c1b51eSKate Stone m_session_up); 117b9c1b51eSKate Stone if (error) { 1184fd6a960SZachary Turner llvm::consumeError(std::move(error)); 1191f8552abSAaron Smith auto module_sp = m_obj_file->GetModule(); 1201f8552abSAaron Smith if (!module_sp) 1211f8552abSAaron Smith return 0; 1221f8552abSAaron Smith // See if any symbol file is specified through `--symfile` option. 1231f8552abSAaron Smith FileSpec symfile = module_sp->GetSymbolFileFileSpec(); 1241f8552abSAaron Smith if (!symfile) 1251f8552abSAaron Smith return 0; 1261f8552abSAaron Smith error = loadDataForPDB(PDB_ReaderType::DIA, 127c8316ed2SAaron Smith llvm::StringRef(symfile.GetPath()), m_session_up); 1281f8552abSAaron Smith if (error) { 1291f8552abSAaron Smith llvm::consumeError(std::move(error)); 13074e08ca0SZachary Turner return 0; 13174e08ca0SZachary Turner } 132b8d8c62bSPavel Labath } 1331f8552abSAaron Smith } 134d5a925f4SAaron Smith if (!m_session_up) 1351f8552abSAaron Smith return 0; 1361f8552abSAaron Smith 1371f8552abSAaron Smith auto enum_tables_up = m_session_up->getEnumTables(); 1381f8552abSAaron Smith if (!enum_tables_up) 1391f8552abSAaron Smith return 0; 1401f8552abSAaron Smith while (auto table_up = enum_tables_up->getNext()) { 1411f8552abSAaron Smith if (table_up->getItemCount() == 0) 1421f8552abSAaron Smith continue; 1431f8552abSAaron Smith auto type = table_up->getTableType(); 1441f8552abSAaron Smith switch (type) { 1451f8552abSAaron Smith case PDB_TableType::Symbols: 1461f8552abSAaron Smith // This table represents a store of symbols with types listed in 1471f8552abSAaron Smith // PDBSym_Type 148c8316ed2SAaron Smith abilities |= (CompileUnits | Functions | Blocks | GlobalVariables | 149c8316ed2SAaron Smith LocalVariables | VariableTypes); 1501f8552abSAaron Smith break; 1511f8552abSAaron Smith case PDB_TableType::LineNumbers: 1521f8552abSAaron Smith abilities |= LineTables; 1531f8552abSAaron Smith break; 154c8316ed2SAaron Smith default: 155c8316ed2SAaron Smith break; 1561f8552abSAaron Smith } 1571f8552abSAaron Smith } 1581f8552abSAaron Smith return abilities; 15974e08ca0SZachary Turner } 16074e08ca0SZachary Turner 161b9c1b51eSKate Stone void SymbolFilePDB::InitializeObject() { 16274e08ca0SZachary Turner lldb::addr_t obj_load_address = m_obj_file->GetFileOffset(); 163c8316ed2SAaron Smith lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS); 16474e08ca0SZachary Turner m_session_up->setLoadAddress(obj_load_address); 16510a02577SAaron Smith if (!m_global_scope_up) 16610a02577SAaron Smith m_global_scope_up = m_session_up->getGlobalScope(); 16710a02577SAaron Smith lldbassert(m_global_scope_up.get()); 16842dff790SZachary Turner 169b9c1b51eSKate Stone TypeSystem *type_system = 170b9c1b51eSKate Stone GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 171b9c1b51eSKate Stone ClangASTContext *clang_type_system = 172b9c1b51eSKate Stone llvm::dyn_cast_or_null<ClangASTContext>(type_system); 17310a02577SAaron Smith lldbassert(clang_type_system); 174b9c1b51eSKate Stone m_tu_decl_ctx_up = llvm::make_unique<CompilerDeclContext>( 175b9c1b51eSKate Stone type_system, clang_type_system->GetTranslationUnitDecl()); 17674e08ca0SZachary Turner } 17774e08ca0SZachary Turner 178b9c1b51eSKate Stone uint32_t SymbolFilePDB::GetNumCompileUnits() { 179b9c1b51eSKate Stone if (m_cached_compile_unit_count == 0) { 18010a02577SAaron Smith auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>(); 18110a02577SAaron Smith if (!compilands) 18210a02577SAaron Smith return 0; 18310a02577SAaron Smith 18410a02577SAaron Smith // The linker could link *.dll (compiland language = LINK), or import 18505097246SAdrian Prantl // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be 18605097246SAdrian Prantl // found as a child of the global scope (PDB executable). Usually, such 18705097246SAdrian Prantl // compilands contain `thunk` symbols in which we are not interested for 18805097246SAdrian Prantl // now. However we still count them in the compiland list. If we perform 18905097246SAdrian Prantl // any compiland related activity, like finding symbols through 19005097246SAdrian Prantl // llvm::pdb::IPDBSession methods, such compilands will all be searched 19105097246SAdrian Prantl // automatically no matter whether we include them or not. 19274e08ca0SZachary Turner m_cached_compile_unit_count = compilands->getChildCount(); 19374e08ca0SZachary Turner 194b9c1b51eSKate Stone // The linker can inject an additional "dummy" compilation unit into the 1959d0eb996SAdrian McCarthy // PDB. Ignore this special compile unit for our purposes, if it is there. 1969d0eb996SAdrian McCarthy // It is always the last one. 19710a02577SAaron Smith auto last_compiland_up = 19810a02577SAaron Smith compilands->getChildAtIndex(m_cached_compile_unit_count - 1); 19910a02577SAaron Smith lldbassert(last_compiland_up.get()); 20010a02577SAaron Smith std::string name = last_compiland_up->getName(); 20174e08ca0SZachary Turner if (name == "* Linker *") 20274e08ca0SZachary Turner --m_cached_compile_unit_count; 20374e08ca0SZachary Turner } 20474e08ca0SZachary Turner return m_cached_compile_unit_count; 20574e08ca0SZachary Turner } 20674e08ca0SZachary Turner 20710a02577SAaron Smith void SymbolFilePDB::GetCompileUnitIndex( 208c8316ed2SAaron Smith const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index) { 20910a02577SAaron Smith auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>(); 21010a02577SAaron Smith if (!results_up) 21110a02577SAaron Smith return; 212e664b5dcSAaron Smith auto uid = pdb_compiland.getSymIndexId(); 213fbdf0b93SRaphael Isemann for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) { 21410a02577SAaron Smith auto compiland_up = results_up->getChildAtIndex(cu_idx); 21510a02577SAaron Smith if (!compiland_up) 21610a02577SAaron Smith continue; 21710a02577SAaron Smith if (compiland_up->getSymIndexId() == uid) { 21810a02577SAaron Smith index = cu_idx; 21910a02577SAaron Smith return; 22010a02577SAaron Smith } 22110a02577SAaron Smith } 22210a02577SAaron Smith index = UINT32_MAX; 22310a02577SAaron Smith return; 22410a02577SAaron Smith } 22510a02577SAaron Smith 22610a02577SAaron Smith std::unique_ptr<llvm::pdb::PDBSymbolCompiland> 22710a02577SAaron Smith SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) { 22810a02577SAaron Smith return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid); 22910a02577SAaron Smith } 23010a02577SAaron Smith 231b9c1b51eSKate Stone lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) { 23210a02577SAaron Smith if (index >= GetNumCompileUnits()) 23310a02577SAaron Smith return CompUnitSP(); 23474e08ca0SZachary Turner 23510a02577SAaron Smith // Assuming we always retrieve same compilands listed in same order through 23610a02577SAaron Smith // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a 23710a02577SAaron Smith // compile unit makes no sense. 23810a02577SAaron Smith auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>(); 23910a02577SAaron Smith if (!results) 24010a02577SAaron Smith return CompUnitSP(); 24110a02577SAaron Smith auto compiland_up = results->getChildAtIndex(index); 24210a02577SAaron Smith if (!compiland_up) 24310a02577SAaron Smith return CompUnitSP(); 24410a02577SAaron Smith return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index); 24574e08ca0SZachary Turner } 24674e08ca0SZachary Turner 24774e08ca0SZachary Turner lldb::LanguageType 248b9c1b51eSKate Stone SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) { 24974e08ca0SZachary Turner // What fields should I expect to be filled out on the SymbolContext? Is it 25074e08ca0SZachary Turner // safe to assume that `sc.comp_unit` is valid? 25174e08ca0SZachary Turner if (!sc.comp_unit) 25274e08ca0SZachary Turner return lldb::eLanguageTypeUnknown; 25374e08ca0SZachary Turner 25410a02577SAaron Smith auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); 25510a02577SAaron Smith if (!compiland_up) 25674e08ca0SZachary Turner return lldb::eLanguageTypeUnknown; 25710a02577SAaron Smith auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>(); 25874e08ca0SZachary Turner if (!details) 25974e08ca0SZachary Turner return lldb::eLanguageTypeUnknown; 26074e08ca0SZachary Turner return TranslateLanguage(details->getLanguage()); 26174e08ca0SZachary Turner } 26274e08ca0SZachary Turner 263c8316ed2SAaron Smith lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc( 264c8316ed2SAaron Smith const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) { 2657ac1c780SAaron Smith lldbassert(sc.comp_unit && sc.module_sp.get()); 2667ac1c780SAaron Smith 267e664b5dcSAaron Smith auto file_vm_addr = pdb_func.getVirtualAddress(); 268308e39caSAaron Smith if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 2697ac1c780SAaron Smith return nullptr; 2707ac1c780SAaron Smith 271e664b5dcSAaron Smith auto func_length = pdb_func.getLength(); 272c8316ed2SAaron Smith AddressRange func_range = 273c8316ed2SAaron Smith AddressRange(file_vm_addr, func_length, sc.module_sp->GetSectionList()); 2747ac1c780SAaron Smith if (!func_range.GetBaseAddress().IsValid()) 2757ac1c780SAaron Smith return nullptr; 2767ac1c780SAaron Smith 277e664b5dcSAaron Smith lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId()); 2787ac1c780SAaron Smith if (!func_type) 2797ac1c780SAaron Smith return nullptr; 2807ac1c780SAaron Smith 281e664b5dcSAaron Smith user_id_t func_type_uid = pdb_func.getSignatureId(); 282f76fe682SAaron Smith 2837ac1c780SAaron Smith Mangled mangled = GetMangledForPDBFunc(pdb_func); 2847ac1c780SAaron Smith 285c8316ed2SAaron Smith FunctionSP func_sp = 286c8316ed2SAaron Smith std::make_shared<Function>(sc.comp_unit, pdb_func.getSymIndexId(), 287c8316ed2SAaron Smith func_type_uid, mangled, func_type, func_range); 2887ac1c780SAaron Smith 2897ac1c780SAaron Smith sc.comp_unit->AddFunction(func_sp); 2907ac1c780SAaron Smith return func_sp.get(); 2917ac1c780SAaron Smith } 2927ac1c780SAaron Smith 293b9c1b51eSKate Stone size_t SymbolFilePDB::ParseCompileUnitFunctions( 294b9c1b51eSKate Stone const lldb_private::SymbolContext &sc) { 2957ac1c780SAaron Smith lldbassert(sc.comp_unit); 2967ac1c780SAaron Smith size_t func_added = 0; 2977ac1c780SAaron Smith auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); 2987ac1c780SAaron Smith if (!compiland_up) 2997ac1c780SAaron Smith return 0; 3007ac1c780SAaron Smith auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>(); 3017ac1c780SAaron Smith if (!results_up) 3027ac1c780SAaron Smith return 0; 3037ac1c780SAaron Smith while (auto pdb_func_up = results_up->getNext()) { 3047ac1c780SAaron Smith auto func_sp = 3057ac1c780SAaron Smith sc.comp_unit->FindFunctionByUID(pdb_func_up->getSymIndexId()); 3067ac1c780SAaron Smith if (!func_sp) { 307e664b5dcSAaron Smith if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, sc)) 3087ac1c780SAaron Smith ++func_added; 3097ac1c780SAaron Smith } 3107ac1c780SAaron Smith } 3117ac1c780SAaron Smith return func_added; 31274e08ca0SZachary Turner } 31374e08ca0SZachary Turner 314b9c1b51eSKate Stone bool SymbolFilePDB::ParseCompileUnitLineTable( 315b9c1b51eSKate Stone const lldb_private::SymbolContext &sc) { 31610a02577SAaron Smith lldbassert(sc.comp_unit); 31710a02577SAaron Smith if (sc.comp_unit->GetLineTable()) 31810a02577SAaron Smith return true; 31974e08ca0SZachary Turner return ParseCompileUnitLineTable(sc, 0); 32074e08ca0SZachary Turner } 32174e08ca0SZachary Turner 322b9c1b51eSKate Stone bool SymbolFilePDB::ParseCompileUnitDebugMacros( 323b9c1b51eSKate Stone const lldb_private::SymbolContext &sc) { 32474e08ca0SZachary Turner // PDB doesn't contain information about macros 32574e08ca0SZachary Turner return false; 32674e08ca0SZachary Turner } 32774e08ca0SZachary Turner 328b9c1b51eSKate Stone bool SymbolFilePDB::ParseCompileUnitSupportFiles( 329b9c1b51eSKate Stone const lldb_private::SymbolContext &sc, 330b9c1b51eSKate Stone lldb_private::FileSpecList &support_files) { 33110a02577SAaron Smith lldbassert(sc.comp_unit); 33274e08ca0SZachary Turner 333b9c1b51eSKate Stone // In theory this is unnecessary work for us, because all of this information 3349d0eb996SAdrian McCarthy // is easily (and quickly) accessible from DebugInfoPDB, so caching it a 3359d0eb996SAdrian McCarthy // second time seems like a waste. Unfortunately, there's no good way around 3369d0eb996SAdrian McCarthy // this short of a moderate refactor since SymbolVendor depends on being able 3379d0eb996SAdrian McCarthy // to cache this list. 33810a02577SAaron Smith auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); 33910a02577SAaron Smith if (!compiland_up) 34074e08ca0SZachary Turner return false; 34110a02577SAaron Smith auto files = m_session_up->getSourceFilesForCompiland(*compiland_up); 34274e08ca0SZachary Turner if (!files || files->getChildCount() == 0) 34374e08ca0SZachary Turner return false; 34474e08ca0SZachary Turner 345b9c1b51eSKate Stone while (auto file = files->getNext()) { 346*2cb7cf8eSPavel Labath FileSpec spec(file->getFileName(), false, FileSpec::Style::windows); 34710a02577SAaron Smith support_files.AppendIfUnique(spec); 34874e08ca0SZachary Turner } 34974e08ca0SZachary Turner return true; 35074e08ca0SZachary Turner } 35174e08ca0SZachary Turner 352b9c1b51eSKate Stone bool SymbolFilePDB::ParseImportedModules( 353b9c1b51eSKate Stone const lldb_private::SymbolContext &sc, 354b9c1b51eSKate Stone std::vector<lldb_private::ConstString> &imported_modules) { 35574e08ca0SZachary Turner // PDB does not yet support module debug info 35674e08ca0SZachary Turner return false; 35774e08ca0SZachary Turner } 35874e08ca0SZachary Turner 359c8316ed2SAaron Smith static size_t ParseFunctionBlocksForPDBSymbol( 360c8316ed2SAaron Smith const lldb_private::SymbolContext &sc, uint64_t func_file_vm_addr, 361c8316ed2SAaron Smith const llvm::pdb::PDBSymbol *pdb_symbol, lldb_private::Block *parent_block, 3627ac1c780SAaron Smith bool is_top_parent) { 3637ac1c780SAaron Smith assert(pdb_symbol && parent_block); 3647ac1c780SAaron Smith 3657ac1c780SAaron Smith size_t num_added = 0; 3667ac1c780SAaron Smith switch (pdb_symbol->getSymTag()) { 3677ac1c780SAaron Smith case PDB_SymType::Block: 3687ac1c780SAaron Smith case PDB_SymType::Function: { 3697ac1c780SAaron Smith Block *block = nullptr; 3707ac1c780SAaron Smith auto &raw_sym = pdb_symbol->getRawSymbol(); 3717ac1c780SAaron Smith if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) { 3727ac1c780SAaron Smith if (pdb_func->hasNoInlineAttribute()) 3737ac1c780SAaron Smith break; 3747ac1c780SAaron Smith if (is_top_parent) 3757ac1c780SAaron Smith block = parent_block; 3767ac1c780SAaron Smith else 3777ac1c780SAaron Smith break; 3787ac1c780SAaron Smith } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) { 3797ac1c780SAaron Smith auto uid = pdb_symbol->getSymIndexId(); 3807ac1c780SAaron Smith if (parent_block->FindBlockByID(uid)) 3817ac1c780SAaron Smith break; 3827ac1c780SAaron Smith if (raw_sym.getVirtualAddress() < func_file_vm_addr) 3837ac1c780SAaron Smith break; 3847ac1c780SAaron Smith 3857ac1c780SAaron Smith auto block_sp = std::make_shared<Block>(pdb_symbol->getSymIndexId()); 3867ac1c780SAaron Smith parent_block->AddChild(block_sp); 3877ac1c780SAaron Smith block = block_sp.get(); 3887ac1c780SAaron Smith } else 3897ac1c780SAaron Smith llvm_unreachable("Unexpected PDB symbol!"); 3907ac1c780SAaron Smith 391c8316ed2SAaron Smith block->AddRange(Block::Range( 392c8316ed2SAaron Smith raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength())); 3937ac1c780SAaron Smith block->FinalizeRanges(); 3947ac1c780SAaron Smith ++num_added; 3957ac1c780SAaron Smith 3967ac1c780SAaron Smith auto results_up = pdb_symbol->findAllChildren(); 3977ac1c780SAaron Smith if (!results_up) 3987ac1c780SAaron Smith break; 3997ac1c780SAaron Smith while (auto symbol_up = results_up->getNext()) { 400c8316ed2SAaron Smith num_added += ParseFunctionBlocksForPDBSymbol( 401c8316ed2SAaron Smith sc, func_file_vm_addr, symbol_up.get(), block, false); 4027ac1c780SAaron Smith } 4037ac1c780SAaron Smith } break; 404c8316ed2SAaron Smith default: 405c8316ed2SAaron Smith break; 4067ac1c780SAaron Smith } 4077ac1c780SAaron Smith return num_added; 4087ac1c780SAaron Smith } 4097ac1c780SAaron Smith 41074e08ca0SZachary Turner size_t 411b9c1b51eSKate Stone SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) { 4127ac1c780SAaron Smith lldbassert(sc.comp_unit && sc.function); 4137ac1c780SAaron Smith size_t num_added = 0; 4147ac1c780SAaron Smith auto uid = sc.function->GetID(); 4157ac1c780SAaron Smith auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid); 4167ac1c780SAaron Smith if (!pdb_func_up) 4177ac1c780SAaron Smith return 0; 4187ac1c780SAaron Smith Block &parent_block = sc.function->GetBlock(false); 4197ac1c780SAaron Smith num_added = 4207ac1c780SAaron Smith ParseFunctionBlocksForPDBSymbol(sc, pdb_func_up->getVirtualAddress(), 4217ac1c780SAaron Smith pdb_func_up.get(), &parent_block, true); 4227ac1c780SAaron Smith return num_added; 423b9c1b51eSKate Stone } 424b9c1b51eSKate Stone 425b9c1b51eSKate Stone size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) { 426ec40f818SAaron Smith lldbassert(sc.module_sp.get()); 42766b84079SAaron Smith if (!sc.comp_unit) 428ec40f818SAaron Smith return 0; 42966b84079SAaron Smith 43066b84079SAaron Smith size_t num_added = 0; 43166b84079SAaron Smith auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID()); 43266b84079SAaron Smith if (!compiland) 43366b84079SAaron Smith return 0; 43466b84079SAaron Smith 43566b84079SAaron Smith auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) { 43666b84079SAaron Smith std::unique_ptr<IPDBEnumSymbols> results; 43766b84079SAaron Smith PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, 43866b84079SAaron Smith PDB_SymType::UDT}; 43966b84079SAaron Smith for (auto tag : tags_to_search) { 44066b84079SAaron Smith results = raw_sym.findAllChildren(tag); 44166b84079SAaron Smith if (!results || results->getChildCount() == 0) 44266b84079SAaron Smith continue; 44366b84079SAaron Smith while (auto symbol = results->getNext()) { 44466b84079SAaron Smith switch (symbol->getSymTag()) { 445ec40f818SAaron Smith case PDB_SymType::Enum: 446ec40f818SAaron Smith case PDB_SymType::UDT: 447ec40f818SAaron Smith case PDB_SymType::Typedef: 448ec40f818SAaron Smith break; 449ec40f818SAaron Smith default: 450ec40f818SAaron Smith continue; 451ec40f818SAaron Smith } 452ec40f818SAaron Smith 453ec40f818SAaron Smith // This should cause the type to get cached and stored in the `m_types` 454ec40f818SAaron Smith // lookup. 45566b84079SAaron Smith if (!ResolveTypeUID(symbol->getSymIndexId())) 456ec40f818SAaron Smith continue; 457ec40f818SAaron Smith 458ec40f818SAaron Smith ++num_added; 459ec40f818SAaron Smith } 46066b84079SAaron Smith } 46166b84079SAaron Smith }; 46266b84079SAaron Smith 46366b84079SAaron Smith if (sc.function) { 464c8316ed2SAaron Smith auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>( 465c8316ed2SAaron Smith sc.function->GetID()); 46666b84079SAaron Smith if (!pdb_func) 46766b84079SAaron Smith return 0; 46866b84079SAaron Smith ParseTypesByTagFn(*pdb_func); 46966b84079SAaron Smith } else { 47066b84079SAaron Smith ParseTypesByTagFn(*compiland); 47166b84079SAaron Smith 47266b84079SAaron Smith // Also parse global types particularly coming from this compiland. 47305097246SAdrian Prantl // Unfortunately, PDB has no compiland information for each global type. We 47405097246SAdrian Prantl // have to parse them all. But ensure we only do this once. 47566b84079SAaron Smith static bool parse_all_global_types = false; 47666b84079SAaron Smith if (!parse_all_global_types) { 47766b84079SAaron Smith ParseTypesByTagFn(*m_global_scope_up); 47866b84079SAaron Smith parse_all_global_types = true; 47966b84079SAaron Smith } 48066b84079SAaron Smith } 481ec40f818SAaron Smith return num_added; 48274e08ca0SZachary Turner } 48374e08ca0SZachary Turner 48474e08ca0SZachary Turner size_t 485b9c1b51eSKate Stone SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) { 48674e08ca0SZachary Turner // TODO: Implement this 48774e08ca0SZachary Turner return size_t(); 48874e08ca0SZachary Turner } 48974e08ca0SZachary Turner 490b9c1b51eSKate Stone lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { 49142dff790SZachary Turner auto find_result = m_types.find(type_uid); 49242dff790SZachary Turner if (find_result != m_types.end()) 49342dff790SZachary Turner return find_result->second.get(); 49442dff790SZachary Turner 495b9c1b51eSKate Stone TypeSystem *type_system = 496b9c1b51eSKate Stone GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 497b9c1b51eSKate Stone ClangASTContext *clang_type_system = 498b9c1b51eSKate Stone llvm::dyn_cast_or_null<ClangASTContext>(type_system); 49942dff790SZachary Turner if (!clang_type_system) 50074e08ca0SZachary Turner return nullptr; 501b9c1b51eSKate Stone PDBASTParser *pdb = 502b9c1b51eSKate Stone llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser()); 50342dff790SZachary Turner if (!pdb) 50442dff790SZachary Turner return nullptr; 50542dff790SZachary Turner 50642dff790SZachary Turner auto pdb_type = m_session_up->getSymbolById(type_uid); 50742dff790SZachary Turner if (pdb_type == nullptr) 50842dff790SZachary Turner return nullptr; 50942dff790SZachary Turner 51042dff790SZachary Turner lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type); 511d5a925f4SAaron Smith if (result) { 51242dff790SZachary Turner m_types.insert(std::make_pair(type_uid, result)); 513ec40f818SAaron Smith auto type_list = GetTypeList(); 514f76fe682SAaron Smith if (type_list) 515ec40f818SAaron Smith type_list->Insert(result); 516ec40f818SAaron Smith } 51742dff790SZachary Turner return result.get(); 51874e08ca0SZachary Turner } 51974e08ca0SZachary Turner 520b9c1b51eSKate Stone bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { 52174e08ca0SZachary Turner // TODO: Implement this 52274e08ca0SZachary Turner return false; 52374e08ca0SZachary Turner } 52474e08ca0SZachary Turner 525b9c1b51eSKate Stone lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { 52674e08ca0SZachary Turner return lldb_private::CompilerDecl(); 52774e08ca0SZachary Turner } 52874e08ca0SZachary Turner 52974e08ca0SZachary Turner lldb_private::CompilerDeclContext 530b9c1b51eSKate Stone SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { 531b9c1b51eSKate Stone // PDB always uses the translation unit decl context for everything. We can 5329d0eb996SAdrian McCarthy // improve this later but it's not easy because PDB doesn't provide a high 5339d0eb996SAdrian McCarthy // enough level of type fidelity in this area. 53442dff790SZachary Turner return *m_tu_decl_ctx_up; 53574e08ca0SZachary Turner } 53674e08ca0SZachary Turner 53774e08ca0SZachary Turner lldb_private::CompilerDeclContext 538b9c1b51eSKate Stone SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { 53942dff790SZachary Turner return *m_tu_decl_ctx_up; 54074e08ca0SZachary Turner } 54174e08ca0SZachary Turner 542b9c1b51eSKate Stone void SymbolFilePDB::ParseDeclsForContext( 543b9c1b51eSKate Stone lldb_private::CompilerDeclContext decl_ctx) {} 54474e08ca0SZachary Turner 54574e08ca0SZachary Turner uint32_t 546b9c1b51eSKate Stone SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, 547b9c1b51eSKate Stone uint32_t resolve_scope, 548b9c1b51eSKate Stone lldb_private::SymbolContext &sc) { 5497ac1c780SAaron Smith uint32_t resolved_flags = 0; 5504d4d63eeSPavel Labath if (resolve_scope & eSymbolContextCompUnit || 5514d4d63eeSPavel Labath resolve_scope & eSymbolContextVariable || 5524d4d63eeSPavel Labath resolve_scope & eSymbolContextFunction || 5534d4d63eeSPavel Labath resolve_scope & eSymbolContextBlock || 5547ac1c780SAaron Smith resolve_scope & eSymbolContextLineEntry) { 5557ac1c780SAaron Smith addr_t file_vm_addr = so_addr.GetFileAddress(); 5567ac1c780SAaron Smith auto symbol_up = 5577ac1c780SAaron Smith m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::None); 5587ac1c780SAaron Smith if (!symbol_up) 5597ac1c780SAaron Smith return 0; 5607ac1c780SAaron Smith 5617ac1c780SAaron Smith auto cu_sp = GetCompileUnitContainsAddress(so_addr); 5627ac1c780SAaron Smith if (!cu_sp) { 5637ac1c780SAaron Smith if (resolved_flags | eSymbolContextVariable) { 5647ac1c780SAaron Smith // TODO: Resolve variables 5657ac1c780SAaron Smith } 5667ac1c780SAaron Smith return 0; 5677ac1c780SAaron Smith } 5687ac1c780SAaron Smith sc.comp_unit = cu_sp.get(); 5697ac1c780SAaron Smith resolved_flags |= eSymbolContextCompUnit; 5707ac1c780SAaron Smith lldbassert(sc.module_sp == cu_sp->GetModule()); 5717ac1c780SAaron Smith 5727ac1c780SAaron Smith switch (symbol_up->getSymTag()) { 5737ac1c780SAaron Smith case PDB_SymType::Function: 5747ac1c780SAaron Smith if (resolve_scope & eSymbolContextFunction) { 5757ac1c780SAaron Smith auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get()); 5767ac1c780SAaron Smith assert(pdb_func); 5777ac1c780SAaron Smith auto func_uid = pdb_func->getSymIndexId(); 5787ac1c780SAaron Smith sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get(); 5797ac1c780SAaron Smith if (sc.function == nullptr) 580e664b5dcSAaron Smith sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc); 5817ac1c780SAaron Smith if (sc.function) { 5827ac1c780SAaron Smith resolved_flags |= eSymbolContextFunction; 5837ac1c780SAaron Smith if (resolve_scope & eSymbolContextBlock) { 5847ac1c780SAaron Smith Block &block = sc.function->GetBlock(true); 5857ac1c780SAaron Smith sc.block = block.FindBlockByID(sc.function->GetID()); 5867ac1c780SAaron Smith if (sc.block) 5877ac1c780SAaron Smith resolved_flags |= eSymbolContextBlock; 5887ac1c780SAaron Smith } 5897ac1c780SAaron Smith } 5907ac1c780SAaron Smith } 5917ac1c780SAaron Smith break; 5927ac1c780SAaron Smith default: 5937ac1c780SAaron Smith break; 5947ac1c780SAaron Smith } 5957ac1c780SAaron Smith 5967ac1c780SAaron Smith if (resolve_scope & eSymbolContextLineEntry) { 5977ac1c780SAaron Smith if (auto *line_table = sc.comp_unit->GetLineTable()) { 5987ac1c780SAaron Smith Address addr(so_addr); 5997ac1c780SAaron Smith if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) 6007ac1c780SAaron Smith resolved_flags |= eSymbolContextLineEntry; 6017ac1c780SAaron Smith } 6027ac1c780SAaron Smith } 6037ac1c780SAaron Smith } 6047ac1c780SAaron Smith return resolved_flags; 60574e08ca0SZachary Turner } 60674e08ca0SZachary Turner 607b9c1b51eSKate Stone uint32_t SymbolFilePDB::ResolveSymbolContext( 608b9c1b51eSKate Stone const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, 609b9c1b51eSKate Stone uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) { 61010a02577SAaron Smith const size_t old_size = sc_list.GetSize(); 611b9c1b51eSKate Stone if (resolve_scope & lldb::eSymbolContextCompUnit) { 612b9c1b51eSKate Stone // Locate all compilation units with line numbers referencing the specified 6139d0eb996SAdrian McCarthy // file. For example, if `file_spec` is <vector>, then this should return 6149d0eb996SAdrian McCarthy // all source files and header files that reference <vector>, either 6159d0eb996SAdrian McCarthy // directly or indirectly. 616b9c1b51eSKate Stone auto compilands = m_session_up->findCompilandsForSourceFile( 617b9c1b51eSKate Stone file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive); 61874e08ca0SZachary Turner 61910a02577SAaron Smith if (!compilands) 62010a02577SAaron Smith return 0; 62110a02577SAaron Smith 6229d0eb996SAdrian McCarthy // For each one, either find its previously parsed data or parse it afresh 6239d0eb996SAdrian McCarthy // and add it to the symbol context list. 624b9c1b51eSKate Stone while (auto compiland = compilands->getNext()) { 62505097246SAdrian Prantl // If we're not checking inlines, then don't add line information for 62605097246SAdrian Prantl // this file unless the FileSpec matches. For inline functions, we don't 62705097246SAdrian Prantl // have to match the FileSpec since they could be defined in headers 62805097246SAdrian Prantl // other than file specified in FileSpec. 629b9c1b51eSKate Stone if (!check_inlines) { 630487b0c6bSAaron Smith std::string source_file = compiland->getSourceFileFullPath(); 63110a02577SAaron Smith if (source_file.empty()) 63210a02577SAaron Smith continue; 633*2cb7cf8eSPavel Labath FileSpec this_spec(source_file, false, FileSpec::Style::windows); 63410a02577SAaron Smith bool need_full_match = !file_spec.GetDirectory().IsEmpty(); 63510a02577SAaron Smith if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0) 63674e08ca0SZachary Turner continue; 63774e08ca0SZachary Turner } 63874e08ca0SZachary Turner 63974e08ca0SZachary Turner SymbolContext sc; 64010a02577SAaron Smith auto cu = ParseCompileUnitForUID(compiland->getSymIndexId()); 641d5a925f4SAaron Smith if (!cu) 64210a02577SAaron Smith continue; 64374e08ca0SZachary Turner sc.comp_unit = cu.get(); 64474e08ca0SZachary Turner sc.module_sp = cu->GetModule(); 64574e08ca0SZachary Turner 646b9c1b51eSKate Stone // If we were asked to resolve line entries, add all entries to the line 6479d0eb996SAdrian McCarthy // table that match the requested line (or all lines if `line` == 0). 6487ac1c780SAaron Smith if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock | 6497ac1c780SAaron Smith eSymbolContextLineEntry)) { 6507ac1c780SAaron Smith bool has_line_table = ParseCompileUnitLineTable(sc, line); 6517ac1c780SAaron Smith 6527ac1c780SAaron Smith if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) { 6537ac1c780SAaron Smith // The query asks for line entries, but we can't get them for the 65405097246SAdrian Prantl // compile unit. This is not normal for `line` = 0. So just assert 65505097246SAdrian Prantl // it. 656f76fe682SAaron Smith assert(line && "Couldn't get all line entries!\n"); 6577ac1c780SAaron Smith 6587ac1c780SAaron Smith // Current compiland does not have the requested line. Search next. 6597ac1c780SAaron Smith continue; 6607ac1c780SAaron Smith } 6617ac1c780SAaron Smith 6627ac1c780SAaron Smith if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) { 6637ac1c780SAaron Smith if (!has_line_table) 6647ac1c780SAaron Smith continue; 6657ac1c780SAaron Smith 6667ac1c780SAaron Smith auto *line_table = sc.comp_unit->GetLineTable(); 6677ac1c780SAaron Smith lldbassert(line_table); 6687ac1c780SAaron Smith 6697ac1c780SAaron Smith uint32_t num_line_entries = line_table->GetSize(); 6707ac1c780SAaron Smith // Skip the terminal line entry. 6717ac1c780SAaron Smith --num_line_entries; 6727ac1c780SAaron Smith 67305097246SAdrian Prantl // If `line `!= 0, see if we can resolve function for each line entry 67405097246SAdrian Prantl // in the line table. 6757ac1c780SAaron Smith for (uint32_t line_idx = 0; line && line_idx < num_line_entries; 6767ac1c780SAaron Smith ++line_idx) { 6777ac1c780SAaron Smith if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry)) 6787ac1c780SAaron Smith continue; 6797ac1c780SAaron Smith 6807ac1c780SAaron Smith auto file_vm_addr = 6817ac1c780SAaron Smith sc.line_entry.range.GetBaseAddress().GetFileAddress(); 682308e39caSAaron Smith if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 6837ac1c780SAaron Smith continue; 6847ac1c780SAaron Smith 685c8316ed2SAaron Smith auto symbol_up = m_session_up->findSymbolByAddress( 686c8316ed2SAaron Smith file_vm_addr, PDB_SymType::Function); 6877ac1c780SAaron Smith if (symbol_up) { 6887ac1c780SAaron Smith auto func_uid = symbol_up->getSymIndexId(); 6897ac1c780SAaron Smith sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get(); 6907ac1c780SAaron Smith if (sc.function == nullptr) { 6917ac1c780SAaron Smith auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get()); 6927ac1c780SAaron Smith assert(pdb_func); 693e664b5dcSAaron Smith sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc); 6947ac1c780SAaron Smith } 6957ac1c780SAaron Smith if (sc.function && (resolve_scope & eSymbolContextBlock)) { 6967ac1c780SAaron Smith Block &block = sc.function->GetBlock(true); 6977ac1c780SAaron Smith sc.block = block.FindBlockByID(sc.function->GetID()); 6987ac1c780SAaron Smith } 6997ac1c780SAaron Smith } 7007ac1c780SAaron Smith sc_list.Append(sc); 7017ac1c780SAaron Smith } 7027ac1c780SAaron Smith } else if (has_line_table) { 7037ac1c780SAaron Smith // We can parse line table for the compile unit. But no query to 7047ac1c780SAaron Smith // resolve function or block. We append `sc` to the list anyway. 7057ac1c780SAaron Smith sc_list.Append(sc); 7067ac1c780SAaron Smith } 7077ac1c780SAaron Smith } else { 7087ac1c780SAaron Smith // No query for line entry, function or block. But we have a valid 7097ac1c780SAaron Smith // compile unit, append `sc` to the list. 7107ac1c780SAaron Smith sc_list.Append(sc); 7117ac1c780SAaron Smith } 71274e08ca0SZachary Turner } 71374e08ca0SZachary Turner } 71410a02577SAaron Smith return sc_list.GetSize() - old_size; 71574e08ca0SZachary Turner } 71674e08ca0SZachary Turner 717b9c1b51eSKate Stone uint32_t SymbolFilePDB::FindGlobalVariables( 718b9c1b51eSKate Stone const lldb_private::ConstString &name, 71974e08ca0SZachary Turner const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, 720b9c1b51eSKate Stone uint32_t max_matches, lldb_private::VariableList &variables) { 72174e08ca0SZachary Turner return uint32_t(); 72274e08ca0SZachary Turner } 72374e08ca0SZachary Turner 72474e08ca0SZachary Turner uint32_t 725b9c1b51eSKate Stone SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, 726b9c1b51eSKate Stone bool append, uint32_t max_matches, 727b9c1b51eSKate Stone lldb_private::VariableList &variables) { 728b9c1b51eSKate Stone return uint32_t(); 729b9c1b51eSKate Stone } 730b9c1b51eSKate Stone 731e664b5dcSAaron Smith bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func, 7327ac1c780SAaron Smith bool include_inlines, 7337ac1c780SAaron Smith lldb_private::SymbolContextList &sc_list) { 7347ac1c780SAaron Smith lldb_private::SymbolContext sc; 735a3a8cc80SAaron Smith sc.comp_unit = ParseCompileUnitForUID(pdb_func.getCompilandId()).get(); 7367ac1c780SAaron Smith if (!sc.comp_unit) 7377ac1c780SAaron Smith return false; 7387ac1c780SAaron Smith sc.module_sp = sc.comp_unit->GetModule(); 739a3a8cc80SAaron Smith sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, sc); 7407ac1c780SAaron Smith if (!sc.function) 7417ac1c780SAaron Smith return false; 7427ac1c780SAaron Smith 7437ac1c780SAaron Smith sc_list.Append(sc); 7447ac1c780SAaron Smith return true; 7457ac1c780SAaron Smith } 7467ac1c780SAaron Smith 7477ac1c780SAaron Smith bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines, 7487ac1c780SAaron Smith lldb_private::SymbolContextList &sc_list) { 749c8316ed2SAaron Smith auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid); 7507ac1c780SAaron Smith if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute())) 7517ac1c780SAaron Smith return false; 752e664b5dcSAaron Smith return ResolveFunction(*pdb_func_up, include_inlines, sc_list); 7537ac1c780SAaron Smith } 7547ac1c780SAaron Smith 7557ac1c780SAaron Smith void SymbolFilePDB::CacheFunctionNames() { 7567ac1c780SAaron Smith if (!m_func_full_names.IsEmpty()) 7577ac1c780SAaron Smith return; 7587ac1c780SAaron Smith 7597ac1c780SAaron Smith std::map<uint64_t, uint32_t> addr_ids; 7607ac1c780SAaron Smith 7617ac1c780SAaron Smith if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) { 7627ac1c780SAaron Smith while (auto pdb_func_up = results_up->getNext()) { 763f76fe682SAaron Smith if (pdb_func_up->isCompilerGenerated()) 764f76fe682SAaron Smith continue; 765f76fe682SAaron Smith 7667ac1c780SAaron Smith auto name = pdb_func_up->getName(); 7677ac1c780SAaron Smith auto demangled_name = pdb_func_up->getUndecoratedName(); 7687ac1c780SAaron Smith if (name.empty() && demangled_name.empty()) 7697ac1c780SAaron Smith continue; 7707ac1c780SAaron Smith 771f76fe682SAaron Smith auto uid = pdb_func_up->getSymIndexId(); 7727ac1c780SAaron Smith if (!demangled_name.empty() && pdb_func_up->getVirtualAddress()) 7737ac1c780SAaron Smith addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid)); 7747ac1c780SAaron Smith 7757ac1c780SAaron Smith if (auto parent = pdb_func_up->getClassParent()) { 7767ac1c780SAaron Smith 7777ac1c780SAaron Smith // PDB have symbols for class/struct methods or static methods in Enum 7787ac1c780SAaron Smith // Class. We won't bother to check if the parent is UDT or Enum here. 7797ac1c780SAaron Smith m_func_method_names.Append(ConstString(name), uid); 7807ac1c780SAaron Smith 7817ac1c780SAaron Smith ConstString cstr_name(name); 7827ac1c780SAaron Smith 78305097246SAdrian Prantl // To search a method name, like NS::Class:MemberFunc, LLDB searches 78405097246SAdrian Prantl // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does 78505097246SAdrian Prantl // not have inforamtion of this, we extract base names and cache them 78605097246SAdrian Prantl // by our own effort. 7877ac1c780SAaron Smith llvm::StringRef basename; 7887ac1c780SAaron Smith CPlusPlusLanguage::MethodName cpp_method(cstr_name); 7897ac1c780SAaron Smith if (cpp_method.IsValid()) { 7907ac1c780SAaron Smith llvm::StringRef context; 7917ac1c780SAaron Smith basename = cpp_method.GetBasename(); 7927ac1c780SAaron Smith if (basename.empty()) 7937ac1c780SAaron Smith CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(), 7947ac1c780SAaron Smith context, basename); 7957ac1c780SAaron Smith } 7967ac1c780SAaron Smith 7977ac1c780SAaron Smith if (!basename.empty()) 7987ac1c780SAaron Smith m_func_base_names.Append(ConstString(basename), uid); 7997ac1c780SAaron Smith else { 8007ac1c780SAaron Smith m_func_base_names.Append(ConstString(name), uid); 8017ac1c780SAaron Smith } 8027ac1c780SAaron Smith 8037ac1c780SAaron Smith if (!demangled_name.empty()) 8047ac1c780SAaron Smith m_func_full_names.Append(ConstString(demangled_name), uid); 8057ac1c780SAaron Smith 8067ac1c780SAaron Smith } else { 8077ac1c780SAaron Smith // Handle not-method symbols. 8087ac1c780SAaron Smith 8097ac1c780SAaron Smith // The function name might contain namespace, or its lexical scope. It 8107ac1c780SAaron Smith // is not safe to get its base name by applying same scheme as we deal 8117ac1c780SAaron Smith // with the method names. 8127ac1c780SAaron Smith // FIXME: Remove namespace if function is static in a scope. 8137ac1c780SAaron Smith m_func_base_names.Append(ConstString(name), uid); 8147ac1c780SAaron Smith 8157ac1c780SAaron Smith if (name == "main") { 8167ac1c780SAaron Smith m_func_full_names.Append(ConstString(name), uid); 8177ac1c780SAaron Smith 8187ac1c780SAaron Smith if (!demangled_name.empty() && name != demangled_name) { 8197ac1c780SAaron Smith m_func_full_names.Append(ConstString(demangled_name), uid); 8207ac1c780SAaron Smith m_func_base_names.Append(ConstString(demangled_name), uid); 8217ac1c780SAaron Smith } 8227ac1c780SAaron Smith } else if (!demangled_name.empty()) { 8237ac1c780SAaron Smith m_func_full_names.Append(ConstString(demangled_name), uid); 8247ac1c780SAaron Smith } else { 8257ac1c780SAaron Smith m_func_full_names.Append(ConstString(name), uid); 8267ac1c780SAaron Smith } 8277ac1c780SAaron Smith } 8287ac1c780SAaron Smith } 8297ac1c780SAaron Smith } 8307ac1c780SAaron Smith 8317ac1c780SAaron Smith if (auto results_up = 8327ac1c780SAaron Smith m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) { 8337ac1c780SAaron Smith while (auto pub_sym_up = results_up->getNext()) { 8347ac1c780SAaron Smith if (!pub_sym_up->isFunction()) 8357ac1c780SAaron Smith continue; 8367ac1c780SAaron Smith auto name = pub_sym_up->getName(); 8377ac1c780SAaron Smith if (name.empty()) 8387ac1c780SAaron Smith continue; 8397ac1c780SAaron Smith 8407ac1c780SAaron Smith if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) { 8417ac1c780SAaron Smith auto vm_addr = pub_sym_up->getVirtualAddress(); 8427ac1c780SAaron Smith 8437ac1c780SAaron Smith // PDB public symbol has mangled name for its associated function. 8447ac1c780SAaron Smith if (vm_addr && addr_ids.find(vm_addr) != addr_ids.end()) { 8457ac1c780SAaron Smith // Cache mangled name. 8467ac1c780SAaron Smith m_func_full_names.Append(ConstString(name), addr_ids[vm_addr]); 8477ac1c780SAaron Smith } 8487ac1c780SAaron Smith } 8497ac1c780SAaron Smith } 8507ac1c780SAaron Smith } 8517ac1c780SAaron Smith // Sort them before value searching is working properly 8527ac1c780SAaron Smith m_func_full_names.Sort(); 8537ac1c780SAaron Smith m_func_full_names.SizeToFit(); 8547ac1c780SAaron Smith m_func_method_names.Sort(); 8557ac1c780SAaron Smith m_func_method_names.SizeToFit(); 8567ac1c780SAaron Smith m_func_base_names.Sort(); 8577ac1c780SAaron Smith m_func_base_names.SizeToFit(); 8587ac1c780SAaron Smith } 8597ac1c780SAaron Smith 860b9c1b51eSKate Stone uint32_t SymbolFilePDB::FindFunctions( 861b9c1b51eSKate Stone const lldb_private::ConstString &name, 862b9c1b51eSKate Stone const lldb_private::CompilerDeclContext *parent_decl_ctx, 863b9c1b51eSKate Stone uint32_t name_type_mask, bool include_inlines, bool append, 864b9c1b51eSKate Stone lldb_private::SymbolContextList &sc_list) { 8657ac1c780SAaron Smith if (!append) 8667ac1c780SAaron Smith sc_list.Clear(); 8677ac1c780SAaron Smith lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0); 8687ac1c780SAaron Smith 8697ac1c780SAaron Smith if (name_type_mask == eFunctionNameTypeNone) 8707ac1c780SAaron Smith return 0; 8717ac1c780SAaron Smith if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 8727ac1c780SAaron Smith return 0; 8737ac1c780SAaron Smith if (name.IsEmpty()) 8747ac1c780SAaron Smith return 0; 8757ac1c780SAaron Smith 8767ac1c780SAaron Smith auto old_size = sc_list.GetSize(); 8774d4d63eeSPavel Labath if (name_type_mask & eFunctionNameTypeFull || 8784d4d63eeSPavel Labath name_type_mask & eFunctionNameTypeBase || 8797ac1c780SAaron Smith name_type_mask & eFunctionNameTypeMethod) { 8807ac1c780SAaron Smith CacheFunctionNames(); 8817ac1c780SAaron Smith 8827ac1c780SAaron Smith std::set<uint32_t> resolved_ids; 883c8316ed2SAaron Smith auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids, 884c8316ed2SAaron Smith this](UniqueCStringMap<uint32_t> &Names) { 8857ac1c780SAaron Smith std::vector<uint32_t> ids; 8867ac1c780SAaron Smith if (Names.GetValues(name, ids)) { 8877ac1c780SAaron Smith for (auto id : ids) { 8887ac1c780SAaron Smith if (resolved_ids.find(id) == resolved_ids.end()) { 8897ac1c780SAaron Smith if (ResolveFunction(id, include_inlines, sc_list)) 8907ac1c780SAaron Smith resolved_ids.insert(id); 8917ac1c780SAaron Smith } 8927ac1c780SAaron Smith } 8937ac1c780SAaron Smith } 8947ac1c780SAaron Smith }; 8957ac1c780SAaron Smith if (name_type_mask & eFunctionNameTypeFull) { 8967ac1c780SAaron Smith ResolveFn(m_func_full_names); 8977ac1c780SAaron Smith } 8987ac1c780SAaron Smith if (name_type_mask & eFunctionNameTypeBase) { 8997ac1c780SAaron Smith ResolveFn(m_func_base_names); 9007ac1c780SAaron Smith } 9017ac1c780SAaron Smith if (name_type_mask & eFunctionNameTypeMethod) { 9027ac1c780SAaron Smith ResolveFn(m_func_method_names); 9037ac1c780SAaron Smith } 9047ac1c780SAaron Smith } 9057ac1c780SAaron Smith return sc_list.GetSize() - old_size; 90674e08ca0SZachary Turner } 90774e08ca0SZachary Turner 90874e08ca0SZachary Turner uint32_t 909b9c1b51eSKate Stone SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, 910b9c1b51eSKate Stone bool include_inlines, bool append, 911b9c1b51eSKate Stone lldb_private::SymbolContextList &sc_list) { 9127ac1c780SAaron Smith if (!append) 9137ac1c780SAaron Smith sc_list.Clear(); 9147ac1c780SAaron Smith if (!regex.IsValid()) 9157ac1c780SAaron Smith return 0; 9167ac1c780SAaron Smith 9177ac1c780SAaron Smith auto old_size = sc_list.GetSize(); 9187ac1c780SAaron Smith CacheFunctionNames(); 9197ac1c780SAaron Smith 9207ac1c780SAaron Smith std::set<uint32_t> resolved_ids; 921c8316ed2SAaron Smith auto ResolveFn = [®ex, include_inlines, &sc_list, &resolved_ids, 922c8316ed2SAaron Smith this](UniqueCStringMap<uint32_t> &Names) { 9237ac1c780SAaron Smith std::vector<uint32_t> ids; 9247ac1c780SAaron Smith if (Names.GetValues(regex, ids)) { 9257ac1c780SAaron Smith for (auto id : ids) { 9267ac1c780SAaron Smith if (resolved_ids.find(id) == resolved_ids.end()) 9277ac1c780SAaron Smith if (ResolveFunction(id, include_inlines, sc_list)) 9287ac1c780SAaron Smith resolved_ids.insert(id); 9297ac1c780SAaron Smith } 9307ac1c780SAaron Smith } 9317ac1c780SAaron Smith }; 9327ac1c780SAaron Smith ResolveFn(m_func_full_names); 9337ac1c780SAaron Smith ResolveFn(m_func_base_names); 9347ac1c780SAaron Smith 9357ac1c780SAaron Smith return sc_list.GetSize() - old_size; 93674e08ca0SZachary Turner } 93774e08ca0SZachary Turner 938b9c1b51eSKate Stone void SymbolFilePDB::GetMangledNamesForFunction( 939b9c1b51eSKate Stone const std::string &scope_qualified_name, 940b9c1b51eSKate Stone std::vector<lldb_private::ConstString> &mangled_names) {} 94174e08ca0SZachary Turner 942b9c1b51eSKate Stone uint32_t SymbolFilePDB::FindTypes( 943b9c1b51eSKate Stone const lldb_private::SymbolContext &sc, 944b9c1b51eSKate Stone const lldb_private::ConstString &name, 945b9c1b51eSKate Stone const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, 946b9c1b51eSKate Stone uint32_t max_matches, 94774e08ca0SZachary Turner llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, 948b9c1b51eSKate Stone lldb_private::TypeMap &types) { 94942dff790SZachary Turner if (!append) 95042dff790SZachary Turner types.Clear(); 95142dff790SZachary Turner if (!name) 95242dff790SZachary Turner return 0; 9537ac1c780SAaron Smith if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) 9547ac1c780SAaron Smith return 0; 95542dff790SZachary Turner 95642dff790SZachary Turner searched_symbol_files.clear(); 95742dff790SZachary Turner searched_symbol_files.insert(this); 95842dff790SZachary Turner 95942dff790SZachary Turner std::string name_str = name.AsCString(); 96042dff790SZachary Turner 96186e9434dSAaron Smith // There is an assumption 'name' is not a regex 96242dff790SZachary Turner FindTypesByName(name_str, max_matches, types); 96386e9434dSAaron Smith 96442dff790SZachary Turner return types.GetSize(); 96542dff790SZachary Turner } 96642dff790SZachary Turner 967c8316ed2SAaron Smith void SymbolFilePDB::FindTypesByRegex( 968c8316ed2SAaron Smith const lldb_private::RegularExpression ®ex, uint32_t max_matches, 969b9c1b51eSKate Stone lldb_private::TypeMap &types) { 970b9c1b51eSKate Stone // When searching by regex, we need to go out of our way to limit the search 9719d0eb996SAdrian McCarthy // space as much as possible since this searches EVERYTHING in the PDB, 9729d0eb996SAdrian McCarthy // manually doing regex comparisons. PDB library isn't optimized for regex 9739d0eb996SAdrian McCarthy // searches or searches across multiple symbol types at the same time, so the 974b9c1b51eSKate Stone // best we can do is to search enums, then typedefs, then classes one by one, 9759d0eb996SAdrian McCarthy // and do a regex comparison against each of them. 976b9c1b51eSKate Stone PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef, 977b9c1b51eSKate Stone PDB_SymType::UDT}; 97854fd7ff6SZachary Turner std::unique_ptr<IPDBEnumSymbols> results; 97942dff790SZachary Turner 98042dff790SZachary Turner uint32_t matches = 0; 98142dff790SZachary Turner 982b9c1b51eSKate Stone for (auto tag : tags_to_search) { 98310a02577SAaron Smith results = m_global_scope_up->findAllChildren(tag); 98410a02577SAaron Smith if (!results) 98510a02577SAaron Smith continue; 98610a02577SAaron Smith 987b9c1b51eSKate Stone while (auto result = results->getNext()) { 98842dff790SZachary Turner if (max_matches > 0 && matches >= max_matches) 98942dff790SZachary Turner break; 99042dff790SZachary Turner 99142dff790SZachary Turner std::string type_name; 99254fd7ff6SZachary Turner if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get())) 99342dff790SZachary Turner type_name = enum_type->getName(); 994b9c1b51eSKate Stone else if (auto typedef_type = 995b9c1b51eSKate Stone llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get())) 99642dff790SZachary Turner type_name = typedef_type->getName(); 99754fd7ff6SZachary Turner else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get())) 99842dff790SZachary Turner type_name = class_type->getName(); 999b9c1b51eSKate Stone else { 10009d0eb996SAdrian McCarthy // We're looking only for types that have names. Skip symbols, as well 10019d0eb996SAdrian McCarthy // as unnamed types such as arrays, pointers, etc. 100242dff790SZachary Turner continue; 100342dff790SZachary Turner } 100442dff790SZachary Turner 100586e9434dSAaron Smith if (!regex.Execute(type_name)) 100642dff790SZachary Turner continue; 100742dff790SZachary Turner 1008b9c1b51eSKate Stone // This should cause the type to get cached and stored in the `m_types` 1009b9c1b51eSKate Stone // lookup. 101042dff790SZachary Turner if (!ResolveTypeUID(result->getSymIndexId())) 101142dff790SZachary Turner continue; 101242dff790SZachary Turner 101342dff790SZachary Turner auto iter = m_types.find(result->getSymIndexId()); 101442dff790SZachary Turner if (iter == m_types.end()) 101542dff790SZachary Turner continue; 101642dff790SZachary Turner types.Insert(iter->second); 101742dff790SZachary Turner ++matches; 101842dff790SZachary Turner } 101942dff790SZachary Turner } 102042dff790SZachary Turner } 102142dff790SZachary Turner 1022b9c1b51eSKate Stone void SymbolFilePDB::FindTypesByName(const std::string &name, 1023b9c1b51eSKate Stone uint32_t max_matches, 1024b9c1b51eSKate Stone lldb_private::TypeMap &types) { 102554fd7ff6SZachary Turner std::unique_ptr<IPDBEnumSymbols> results; 1026f76fe682SAaron Smith if (name.empty()) 1027f76fe682SAaron Smith return; 102810a02577SAaron Smith results = m_global_scope_up->findChildren(PDB_SymType::None, name, 1029b9c1b51eSKate Stone PDB_NameSearchFlags::NS_Default); 103010a02577SAaron Smith if (!results) 103110a02577SAaron Smith return; 103242dff790SZachary Turner 103342dff790SZachary Turner uint32_t matches = 0; 103442dff790SZachary Turner 1035b9c1b51eSKate Stone while (auto result = results->getNext()) { 103642dff790SZachary Turner if (max_matches > 0 && matches >= max_matches) 103742dff790SZachary Turner break; 1038b9c1b51eSKate Stone switch (result->getSymTag()) { 103954fd7ff6SZachary Turner case PDB_SymType::Enum: 104054fd7ff6SZachary Turner case PDB_SymType::UDT: 104154fd7ff6SZachary Turner case PDB_SymType::Typedef: 104242dff790SZachary Turner break; 104342dff790SZachary Turner default: 104405097246SAdrian Prantl // We're looking only for types that have names. Skip symbols, as well 104505097246SAdrian Prantl // as unnamed types such as arrays, pointers, etc. 104642dff790SZachary Turner continue; 104742dff790SZachary Turner } 104842dff790SZachary Turner 1049b9c1b51eSKate Stone // This should cause the type to get cached and stored in the `m_types` 1050b9c1b51eSKate Stone // lookup. 105142dff790SZachary Turner if (!ResolveTypeUID(result->getSymIndexId())) 105242dff790SZachary Turner continue; 105342dff790SZachary Turner 105442dff790SZachary Turner auto iter = m_types.find(result->getSymIndexId()); 105542dff790SZachary Turner if (iter == m_types.end()) 105642dff790SZachary Turner continue; 105742dff790SZachary Turner types.Insert(iter->second); 105842dff790SZachary Turner ++matches; 105942dff790SZachary Turner } 106074e08ca0SZachary Turner } 106174e08ca0SZachary Turner 1062b9c1b51eSKate Stone size_t SymbolFilePDB::FindTypes( 1063b9c1b51eSKate Stone const std::vector<lldb_private::CompilerContext> &contexts, bool append, 1064b9c1b51eSKate Stone lldb_private::TypeMap &types) { 106542dff790SZachary Turner return 0; 106674e08ca0SZachary Turner } 106774e08ca0SZachary Turner 1068ec40f818SAaron Smith lldb_private::TypeList *SymbolFilePDB::GetTypeList() { 1069ec40f818SAaron Smith return m_obj_file->GetModule()->GetTypeList(); 1070ec40f818SAaron Smith } 107174e08ca0SZachary Turner 1072c8316ed2SAaron Smith void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol, 10737ac1c780SAaron Smith uint32_t type_mask, 10747ac1c780SAaron Smith TypeCollection &type_collection) { 10757ac1c780SAaron Smith bool can_parse = false; 1076e664b5dcSAaron Smith switch (pdb_symbol.getSymTag()) { 10777ac1c780SAaron Smith case PDB_SymType::ArrayType: 10787ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassArray) != 0); 10797ac1c780SAaron Smith break; 10807ac1c780SAaron Smith case PDB_SymType::BuiltinType: 10817ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassBuiltin) != 0); 10827ac1c780SAaron Smith break; 10837ac1c780SAaron Smith case PDB_SymType::Enum: 10847ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassEnumeration) != 0); 10857ac1c780SAaron Smith break; 10867ac1c780SAaron Smith case PDB_SymType::Function: 10877ac1c780SAaron Smith case PDB_SymType::FunctionSig: 10887ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassFunction) != 0); 10897ac1c780SAaron Smith break; 10907ac1c780SAaron Smith case PDB_SymType::PointerType: 10917ac1c780SAaron Smith can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer | 10927ac1c780SAaron Smith eTypeClassMemberPointer)) != 0); 10937ac1c780SAaron Smith break; 10947ac1c780SAaron Smith case PDB_SymType::Typedef: 10957ac1c780SAaron Smith can_parse = ((type_mask & eTypeClassTypedef) != 0); 10967ac1c780SAaron Smith break; 10977ac1c780SAaron Smith case PDB_SymType::UDT: { 1098e664b5dcSAaron Smith auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol); 10997ac1c780SAaron Smith assert(udt); 11007ac1c780SAaron Smith can_parse = (udt->getUdtKind() != PDB_UdtType::Interface && 11017ac1c780SAaron Smith ((type_mask & (eTypeClassClass | eTypeClassStruct | 11027ac1c780SAaron Smith eTypeClassUnion)) != 0)); 11037ac1c780SAaron Smith } break; 1104c8316ed2SAaron Smith default: 1105c8316ed2SAaron Smith break; 11067ac1c780SAaron Smith } 11077ac1c780SAaron Smith 11087ac1c780SAaron Smith if (can_parse) { 1109e664b5dcSAaron Smith if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) { 11107ac1c780SAaron Smith auto result = 11117ac1c780SAaron Smith std::find(type_collection.begin(), type_collection.end(), type); 11127ac1c780SAaron Smith if (result == type_collection.end()) 11137ac1c780SAaron Smith type_collection.push_back(type); 11147ac1c780SAaron Smith } 11157ac1c780SAaron Smith } 11167ac1c780SAaron Smith 1117e664b5dcSAaron Smith auto results_up = pdb_symbol.findAllChildren(); 11187ac1c780SAaron Smith while (auto symbol_up = results_up->getNext()) 1119e664b5dcSAaron Smith GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection); 11207ac1c780SAaron Smith } 11217ac1c780SAaron Smith 1122b9c1b51eSKate Stone size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, 1123b9c1b51eSKate Stone uint32_t type_mask, 1124b9c1b51eSKate Stone lldb_private::TypeList &type_list) { 11257ac1c780SAaron Smith TypeCollection type_collection; 11267ac1c780SAaron Smith uint32_t old_size = type_list.GetSize(); 1127c8316ed2SAaron Smith CompileUnit *cu = 1128c8316ed2SAaron Smith sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr; 11297ac1c780SAaron Smith if (cu) { 11307ac1c780SAaron Smith auto compiland_up = GetPDBCompilandByUID(cu->GetID()); 1131e664b5dcSAaron Smith if (!compiland_up) 1132e664b5dcSAaron Smith return 0; 1133e664b5dcSAaron Smith GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection); 11347ac1c780SAaron Smith } else { 11357ac1c780SAaron Smith for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) { 11367ac1c780SAaron Smith auto cu_sp = ParseCompileUnitAtIndex(cu_idx); 1137d5a925f4SAaron Smith if (cu_sp) { 1138e664b5dcSAaron Smith if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID())) 1139e664b5dcSAaron Smith GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection); 11407ac1c780SAaron Smith } 11417ac1c780SAaron Smith } 11427ac1c780SAaron Smith } 11437ac1c780SAaron Smith 11447ac1c780SAaron Smith for (auto type : type_collection) { 11457ac1c780SAaron Smith type->GetForwardCompilerType(); 11467ac1c780SAaron Smith type_list.Insert(type->shared_from_this()); 11477ac1c780SAaron Smith } 11487ac1c780SAaron Smith return type_list.GetSize() - old_size; 114974e08ca0SZachary Turner } 115074e08ca0SZachary Turner 115174e08ca0SZachary Turner lldb_private::TypeSystem * 1152b9c1b51eSKate Stone SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { 1153b9c1b51eSKate Stone auto type_system = 1154b9c1b51eSKate Stone m_obj_file->GetModule()->GetTypeSystemForLanguage(language); 115574e08ca0SZachary Turner if (type_system) 115674e08ca0SZachary Turner type_system->SetSymbolFile(this); 115774e08ca0SZachary Turner return type_system; 115874e08ca0SZachary Turner } 115974e08ca0SZachary Turner 1160b9c1b51eSKate Stone lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( 1161b9c1b51eSKate Stone const lldb_private::SymbolContext &sc, 1162b9c1b51eSKate Stone const lldb_private::ConstString &name, 1163b9c1b51eSKate Stone const lldb_private::CompilerDeclContext *parent_decl_ctx) { 116474e08ca0SZachary Turner return lldb_private::CompilerDeclContext(); 116574e08ca0SZachary Turner } 116674e08ca0SZachary Turner 1167b9c1b51eSKate Stone lldb_private::ConstString SymbolFilePDB::GetPluginName() { 116874e08ca0SZachary Turner static ConstString g_name("pdb"); 116974e08ca0SZachary Turner return g_name; 117074e08ca0SZachary Turner } 117174e08ca0SZachary Turner 1172b9c1b51eSKate Stone uint32_t SymbolFilePDB::GetPluginVersion() { return 1; } 117374e08ca0SZachary Turner 1174b9c1b51eSKate Stone IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; } 1175b9c1b51eSKate Stone 1176b9c1b51eSKate Stone const IPDBSession &SymbolFilePDB::GetPDBSession() const { 117742dff790SZachary Turner return *m_session_up; 117842dff790SZachary Turner } 117942dff790SZachary Turner 1180c8316ed2SAaron Smith lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id, 1181c8316ed2SAaron Smith uint32_t index) { 118274e08ca0SZachary Turner auto found_cu = m_comp_units.find(id); 118374e08ca0SZachary Turner if (found_cu != m_comp_units.end()) 118474e08ca0SZachary Turner return found_cu->second; 118574e08ca0SZachary Turner 118610a02577SAaron Smith auto compiland_up = GetPDBCompilandByUID(id); 118710a02577SAaron Smith if (!compiland_up) 118810a02577SAaron Smith return CompUnitSP(); 118974e08ca0SZachary Turner 119074e08ca0SZachary Turner lldb::LanguageType lang; 119110a02577SAaron Smith auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>(); 119274e08ca0SZachary Turner if (!details) 119374e08ca0SZachary Turner lang = lldb::eLanguageTypeC_plus_plus; 119474e08ca0SZachary Turner else 119574e08ca0SZachary Turner lang = TranslateLanguage(details->getLanguage()); 119674e08ca0SZachary Turner 1197f76fe682SAaron Smith if (lang == lldb::LanguageType::eLanguageTypeUnknown) 1198f76fe682SAaron Smith return CompUnitSP(); 1199f76fe682SAaron Smith 1200487b0c6bSAaron Smith std::string path = compiland_up->getSourceFileFullPath(); 1201f76fe682SAaron Smith if (path.empty()) 1202f76fe682SAaron Smith return CompUnitSP(); 1203f76fe682SAaron Smith 1204b9c1b51eSKate Stone // Don't support optimized code for now, DebugInfoPDB does not return this 1205b9c1b51eSKate Stone // information. 1206ad2b63cbSGreg Clayton LazyBool optimized = eLazyBoolNo; 1207c8316ed2SAaron Smith auto cu_sp = std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, 1208c8316ed2SAaron Smith path.c_str(), id, lang, optimized); 120910a02577SAaron Smith 121010a02577SAaron Smith if (!cu_sp) 121110a02577SAaron Smith return CompUnitSP(); 121210a02577SAaron Smith 121310a02577SAaron Smith m_comp_units.insert(std::make_pair(id, cu_sp)); 121410a02577SAaron Smith if (index == UINT32_MAX) 1215e664b5dcSAaron Smith GetCompileUnitIndex(*compiland_up, index); 121610a02577SAaron Smith lldbassert(index != UINT32_MAX); 1217c8316ed2SAaron Smith m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(index, 1218c8316ed2SAaron Smith cu_sp); 121910a02577SAaron Smith return cu_sp; 122074e08ca0SZachary Turner } 122174e08ca0SZachary Turner 1222b9c1b51eSKate Stone bool SymbolFilePDB::ParseCompileUnitLineTable( 1223b9c1b51eSKate Stone const lldb_private::SymbolContext &sc, uint32_t match_line) { 122410a02577SAaron Smith lldbassert(sc.comp_unit); 122510a02577SAaron Smith 122610a02577SAaron Smith auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); 122710a02577SAaron Smith if (!compiland_up) 122810a02577SAaron Smith return false; 122974e08ca0SZachary Turner 1230b9c1b51eSKate Stone // LineEntry needs the *index* of the file into the list of support files 12319d0eb996SAdrian McCarthy // returned by ParseCompileUnitSupportFiles. But the underlying SDK gives us 123205097246SAdrian Prantl // a globally unique idenfitifier in the namespace of the PDB. So, we have 123305097246SAdrian Prantl // to do a mapping so that we can hand out indices. 123442dff790SZachary Turner llvm::DenseMap<uint32_t, uint32_t> index_map; 123510a02577SAaron Smith BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map); 123674e08ca0SZachary Turner auto line_table = llvm::make_unique<LineTable>(sc.comp_unit); 123774e08ca0SZachary Turner 123810a02577SAaron Smith // Find contributions to `compiland` from all source and header files. 123974e08ca0SZachary Turner std::string path = sc.comp_unit->GetPath(); 124010a02577SAaron Smith auto files = m_session_up->getSourceFilesForCompiland(*compiland_up); 124110a02577SAaron Smith if (!files) 124210a02577SAaron Smith return false; 124374e08ca0SZachary Turner 124405097246SAdrian Prantl // For each source and header file, create a LineSequence for contributions 124505097246SAdrian Prantl // to the compiland from that file, and add the sequence. 1246b9c1b51eSKate Stone while (auto file = files->getNext()) { 1247b9c1b51eSKate Stone std::unique_ptr<LineSequence> sequence( 1248b9c1b51eSKate Stone line_table->CreateLineSequenceContainer()); 124910a02577SAaron Smith auto lines = m_session_up->findLineNumbers(*compiland_up, *file); 125010a02577SAaron Smith if (!lines) 125110a02577SAaron Smith continue; 125274e08ca0SZachary Turner int entry_count = lines->getChildCount(); 125374e08ca0SZachary Turner 12547e8c7beaSZachary Turner uint64_t prev_addr; 12557e8c7beaSZachary Turner uint32_t prev_length; 12567e8c7beaSZachary Turner uint32_t prev_line; 12577e8c7beaSZachary Turner uint32_t prev_source_idx; 12587e8c7beaSZachary Turner 1259b9c1b51eSKate Stone for (int i = 0; i < entry_count; ++i) { 126074e08ca0SZachary Turner auto line = lines->getChildAtIndex(i); 126174e08ca0SZachary Turner 12627e8c7beaSZachary Turner uint64_t lno = line->getLineNumber(); 12637e8c7beaSZachary Turner uint64_t addr = line->getVirtualAddress(); 12647e8c7beaSZachary Turner uint32_t length = line->getLength(); 126574e08ca0SZachary Turner uint32_t source_id = line->getSourceFileId(); 12667e8c7beaSZachary Turner uint32_t col = line->getColumnNumber(); 126774e08ca0SZachary Turner uint32_t source_idx = index_map[source_id]; 126874e08ca0SZachary Turner 126905097246SAdrian Prantl // There was a gap between the current entry and the previous entry if 127005097246SAdrian Prantl // the addresses don't perfectly line up. 12717e8c7beaSZachary Turner bool is_gap = (i > 0) && (prev_addr + prev_length < addr); 12727e8c7beaSZachary Turner 1273b9c1b51eSKate Stone // Before inserting the current entry, insert a terminal entry at the end 12749d0eb996SAdrian McCarthy // of the previous entry's address range if the current entry resulted in 12759d0eb996SAdrian McCarthy // a gap from the previous entry. 1276b9c1b51eSKate Stone if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) { 1277b9c1b51eSKate Stone line_table->AppendLineEntryToSequence( 1278b9c1b51eSKate Stone sequence.get(), prev_addr + prev_length, prev_line, 0, 12797e8c7beaSZachary Turner prev_source_idx, false, false, false, false, true); 12807e8c7beaSZachary Turner } 12817e8c7beaSZachary Turner 1282b9c1b51eSKate Stone if (ShouldAddLine(match_line, lno, length)) { 12837e8c7beaSZachary Turner bool is_statement = line->isStatement(); 128474e08ca0SZachary Turner bool is_prologue = false; 128574e08ca0SZachary Turner bool is_epilogue = false; 1286b9c1b51eSKate Stone auto func = 1287b9c1b51eSKate Stone m_session_up->findSymbolByAddress(addr, PDB_SymType::Function); 1288b9c1b51eSKate Stone if (func) { 128954fd7ff6SZachary Turner auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>(); 129010a02577SAaron Smith if (prologue) 12917e8c7beaSZachary Turner is_prologue = (addr == prologue->getVirtualAddress()); 129274e08ca0SZachary Turner 129354fd7ff6SZachary Turner auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>(); 129410a02577SAaron Smith if (epilogue) 12957e8c7beaSZachary Turner is_epilogue = (addr == epilogue->getVirtualAddress()); 12967e8c7beaSZachary Turner } 129774e08ca0SZachary Turner 1298b9c1b51eSKate Stone line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col, 1299b9c1b51eSKate Stone source_idx, is_statement, false, 13007e8c7beaSZachary Turner is_prologue, is_epilogue, false); 13017e8c7beaSZachary Turner } 13027e8c7beaSZachary Turner 13037e8c7beaSZachary Turner prev_addr = addr; 13047e8c7beaSZachary Turner prev_length = length; 13057e8c7beaSZachary Turner prev_line = lno; 13067e8c7beaSZachary Turner prev_source_idx = source_idx; 13077e8c7beaSZachary Turner } 13087e8c7beaSZachary Turner 1309b9c1b51eSKate Stone if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) { 13107e8c7beaSZachary Turner // The end is always a terminal entry, so insert it regardless. 1311b9c1b51eSKate Stone line_table->AppendLineEntryToSequence( 1312b9c1b51eSKate Stone sequence.get(), prev_addr + prev_length, prev_line, 0, 13137e8c7beaSZachary Turner prev_source_idx, false, false, false, false, true); 131474e08ca0SZachary Turner } 131574e08ca0SZachary Turner 13167e8c7beaSZachary Turner line_table->InsertSequence(sequence.release()); 131774e08ca0SZachary Turner } 131874e08ca0SZachary Turner 131910a02577SAaron Smith if (line_table->GetSize()) { 132074e08ca0SZachary Turner sc.comp_unit->SetLineTable(line_table.release()); 132174e08ca0SZachary Turner return true; 132274e08ca0SZachary Turner } 132310a02577SAaron Smith return false; 132410a02577SAaron Smith } 132574e08ca0SZachary Turner 1326b9c1b51eSKate Stone void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap( 132710a02577SAaron Smith const PDBSymbolCompiland &compiland, 1328b9c1b51eSKate Stone llvm::DenseMap<uint32_t, uint32_t> &index_map) const { 132905097246SAdrian Prantl // This is a hack, but we need to convert the source id into an index into 133005097246SAdrian Prantl // the support files array. We don't want to do path comparisons to avoid 13319d0eb996SAdrian McCarthy // basename / full path issues that may or may not even be a problem, so we 13329d0eb996SAdrian McCarthy // use the globally unique source file identifiers. Ideally we could use the 13339d0eb996SAdrian McCarthy // global identifiers everywhere, but LineEntry currently assumes indices. 133410a02577SAaron Smith auto source_files = m_session_up->getSourceFilesForCompiland(compiland); 133510a02577SAaron Smith if (!source_files) 133610a02577SAaron Smith return; 133774e08ca0SZachary Turner int index = 0; 133874e08ca0SZachary Turner 1339b9c1b51eSKate Stone while (auto file = source_files->getNext()) { 134074e08ca0SZachary Turner uint32_t source_id = file->getUniqueId(); 134174e08ca0SZachary Turner index_map[source_id] = index++; 134274e08ca0SZachary Turner } 134374e08ca0SZachary Turner } 13447ac1c780SAaron Smith 13457ac1c780SAaron Smith lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress( 13467ac1c780SAaron Smith const lldb_private::Address &so_addr) { 13477ac1c780SAaron Smith lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1348308e39caSAaron Smith if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 13497ac1c780SAaron Smith return nullptr; 13507ac1c780SAaron Smith 1351308e39caSAaron Smith // If it is a PDB function's vm addr, this is the first sure bet. 1352308e39caSAaron Smith if (auto lines = 1353308e39caSAaron Smith m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/1)) { 1354308e39caSAaron Smith if (auto first_line = lines->getNext()) 1355308e39caSAaron Smith return ParseCompileUnitForUID(first_line->getCompilandId()); 13567ac1c780SAaron Smith } 13577ac1c780SAaron Smith 1358308e39caSAaron Smith // Otherwise we resort to section contributions. 1359308e39caSAaron Smith if (auto sec_contribs = m_session_up->getSectionContribs()) { 1360308e39caSAaron Smith while (auto section = sec_contribs->getNext()) { 1361308e39caSAaron Smith auto va = section->getVirtualAddress(); 1362308e39caSAaron Smith if (file_vm_addr >= va && file_vm_addr < va + section->getLength()) 1363308e39caSAaron Smith return ParseCompileUnitForUID(section->getCompilandId()); 1364308e39caSAaron Smith } 1365308e39caSAaron Smith } 13667ac1c780SAaron Smith return nullptr; 13677ac1c780SAaron Smith } 13687ac1c780SAaron Smith 13697ac1c780SAaron Smith Mangled 1370e664b5dcSAaron Smith SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { 13717ac1c780SAaron Smith Mangled mangled; 1372e664b5dcSAaron Smith auto func_name = pdb_func.getName(); 1373e664b5dcSAaron Smith auto func_undecorated_name = pdb_func.getUndecoratedName(); 13747ac1c780SAaron Smith std::string func_decorated_name; 13757ac1c780SAaron Smith 13767ac1c780SAaron Smith // Seek from public symbols for non-static function's decorated name if any. 13777ac1c780SAaron Smith // For static functions, they don't have undecorated names and aren't exposed 13787ac1c780SAaron Smith // in Public Symbols either. 13797ac1c780SAaron Smith if (!func_undecorated_name.empty()) { 1380c8316ed2SAaron Smith auto result_up = m_global_scope_up->findChildren( 1381c8316ed2SAaron Smith PDB_SymType::PublicSymbol, func_undecorated_name, 13827ac1c780SAaron Smith PDB_NameSearchFlags::NS_UndecoratedName); 13837ac1c780SAaron Smith if (result_up) { 13847ac1c780SAaron Smith while (auto symbol_up = result_up->getNext()) { 13857ac1c780SAaron Smith // For a public symbol, it is unique. 13867ac1c780SAaron Smith lldbassert(result_up->getChildCount() == 1); 13877ac1c780SAaron Smith if (auto *pdb_public_sym = 1388c8316ed2SAaron Smith llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>( 1389c8316ed2SAaron Smith symbol_up.get())) { 13907ac1c780SAaron Smith if (pdb_public_sym->isFunction()) { 13917ac1c780SAaron Smith func_decorated_name = pdb_public_sym->getName(); 1392f76fe682SAaron Smith break; 13937ac1c780SAaron Smith } 13947ac1c780SAaron Smith } 13957ac1c780SAaron Smith } 13967ac1c780SAaron Smith } 13977ac1c780SAaron Smith } 13987ac1c780SAaron Smith if (!func_decorated_name.empty()) { 13997ac1c780SAaron Smith mangled.SetMangledName(ConstString(func_decorated_name)); 14007ac1c780SAaron Smith 14017ac1c780SAaron Smith // For MSVC, format of C funciton's decorated name depends on calling 14027ac1c780SAaron Smith // conventon. Unfortunately none of the format is recognized by current 14037ac1c780SAaron Smith // LLDB. For example, `_purecall` is a __cdecl C function. From PDB, 140405097246SAdrian Prantl // `__purecall` is retrieved as both its decorated and undecorated name 140505097246SAdrian Prantl // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall` 140605097246SAdrian Prantl // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix). 140705097246SAdrian Prantl // Mangled::GetDemangledName method will fail internally and caches an 140805097246SAdrian Prantl // empty string as its undecorated name. So we will face a contradition 140905097246SAdrian Prantl // here for the same symbol: 14107ac1c780SAaron Smith // non-empty undecorated name from PDB 14117ac1c780SAaron Smith // empty undecorated name from LLDB 14127ac1c780SAaron Smith if (!func_undecorated_name.empty() && 14137ac1c780SAaron Smith mangled.GetDemangledName(mangled.GuessLanguage()).IsEmpty()) 14147ac1c780SAaron Smith mangled.SetDemangledName(ConstString(func_undecorated_name)); 14157ac1c780SAaron Smith 14167ac1c780SAaron Smith // LLDB uses several flags to control how a C++ decorated name is 141705097246SAdrian Prantl // undecorated for MSVC. See `safeUndecorateName` in Class Mangled. So the 141805097246SAdrian Prantl // yielded name could be different from what we retrieve from 14197ac1c780SAaron Smith // PDB source unless we also apply same flags in getting undecorated 14207ac1c780SAaron Smith // name through PDBSymbolFunc::getUndecoratedNameEx method. 14217ac1c780SAaron Smith if (!func_undecorated_name.empty() && 14227ac1c780SAaron Smith mangled.GetDemangledName(mangled.GuessLanguage()) != 14237ac1c780SAaron Smith ConstString(func_undecorated_name)) 14247ac1c780SAaron Smith mangled.SetDemangledName(ConstString(func_undecorated_name)); 14257ac1c780SAaron Smith } else if (!func_undecorated_name.empty()) { 14267ac1c780SAaron Smith mangled.SetDemangledName(ConstString(func_undecorated_name)); 14277ac1c780SAaron Smith } else if (!func_name.empty()) 14287ac1c780SAaron Smith mangled.SetValue(ConstString(func_name), false); 14297ac1c780SAaron Smith 14307ac1c780SAaron Smith return mangled; 14317ac1c780SAaron Smith } 14327ac1c780SAaron Smith 14337ac1c780SAaron Smith bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( 14347ac1c780SAaron Smith const lldb_private::CompilerDeclContext *decl_ctx) { 14357ac1c780SAaron Smith if (decl_ctx == nullptr || !decl_ctx->IsValid()) 14367ac1c780SAaron Smith return true; 14377ac1c780SAaron Smith 14387ac1c780SAaron Smith TypeSystem *decl_ctx_type_system = decl_ctx->GetTypeSystem(); 14397ac1c780SAaron Smith if (!decl_ctx_type_system) 14407ac1c780SAaron Smith return false; 14417ac1c780SAaron Smith TypeSystem *type_system = GetTypeSystemForLanguage( 14427ac1c780SAaron Smith decl_ctx_type_system->GetMinimumLanguage(nullptr)); 14437ac1c780SAaron Smith if (decl_ctx_type_system == type_system) 14447ac1c780SAaron Smith return true; // The type systems match, return true 14457ac1c780SAaron Smith 14467ac1c780SAaron Smith return false; 14477ac1c780SAaron Smith } 1448