15ffd83dbSDimitry Andric //===-- SymbolFileNativePDB.cpp -------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "SymbolFileNativePDB.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "clang/AST/Attr.h" 120b57cec5SDimitry Andric #include "clang/AST/CharUnits.h" 130b57cec5SDimitry Andric #include "clang/AST/Decl.h" 140b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 150b57cec5SDimitry Andric #include "clang/AST/Type.h" 160b57cec5SDimitry Andric 175ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangUtil.h" 180b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" 19e8d8bef9SDimitry Andric #include "Plugins/ObjectFile/PDB/ObjectFilePDB.h" 205ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 210b57cec5SDimitry Andric #include "lldb/Core/Module.h" 220b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 230b57cec5SDimitry Andric #include "lldb/Core/StreamBuffer.h" 240b57cec5SDimitry Andric #include "lldb/Core/StreamFile.h" 250b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h" 260b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h" 270b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 280b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h" 290b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h" 300b57cec5SDimitry Andric #include "lldb/Symbol/Variable.h" 310b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h" 329dba64beSDimitry Andric #include "lldb/Utility/Log.h" 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVRecord.h" 350b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 360b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" 370b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" 380b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordName.h" 390b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 400b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" 410b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 420b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiStream.h" 430b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" 440b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/InfoStream.h" 450b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" 46e8d8bef9SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeSession.h" 470b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 480b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/SymbolStream.h" 490b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/TpiStream.h" 50e8d8bef9SDimitry Andric #include "llvm/DebugInfo/PDB/PDB.h" 510b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBTypes.h" 520b57cec5SDimitry Andric #include "llvm/Demangle/MicrosoftDemangle.h" 530b57cec5SDimitry Andric #include "llvm/Object/COFF.h" 540b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 550b57cec5SDimitry Andric #include "llvm/Support/BinaryStreamReader.h" 560b57cec5SDimitry Andric #include "llvm/Support/Error.h" 570b57cec5SDimitry Andric #include "llvm/Support/ErrorOr.h" 580b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric #include "DWARFLocationExpression.h" 610b57cec5SDimitry Andric #include "PdbAstBuilder.h" 620b57cec5SDimitry Andric #include "PdbSymUid.h" 630b57cec5SDimitry Andric #include "PdbUtil.h" 640b57cec5SDimitry Andric #include "UdtRecordCompleter.h" 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric using namespace lldb; 670b57cec5SDimitry Andric using namespace lldb_private; 680b57cec5SDimitry Andric using namespace npdb; 690b57cec5SDimitry Andric using namespace llvm::codeview; 700b57cec5SDimitry Andric using namespace llvm::pdb; 710b57cec5SDimitry Andric 72480093f4SDimitry Andric char SymbolFileNativePDB::ID; 73480093f4SDimitry Andric 740b57cec5SDimitry Andric static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { 750b57cec5SDimitry Andric switch (lang) { 760b57cec5SDimitry Andric case PDB_Lang::Cpp: 770b57cec5SDimitry Andric return lldb::LanguageType::eLanguageTypeC_plus_plus; 780b57cec5SDimitry Andric case PDB_Lang::C: 790b57cec5SDimitry Andric return lldb::LanguageType::eLanguageTypeC; 800b57cec5SDimitry Andric case PDB_Lang::Swift: 810b57cec5SDimitry Andric return lldb::LanguageType::eLanguageTypeSwift; 820b57cec5SDimitry Andric default: 830b57cec5SDimitry Andric return lldb::LanguageType::eLanguageTypeUnknown; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric static std::unique_ptr<PDBFile> 880b57cec5SDimitry Andric loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { 890b57cec5SDimitry Andric // Try to find a matching PDB for an EXE. 900b57cec5SDimitry Andric using namespace llvm::object; 910b57cec5SDimitry Andric auto expected_binary = createBinary(exe_path); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric // If the file isn't a PE/COFF executable, fail. 940b57cec5SDimitry Andric if (!expected_binary) { 950b57cec5SDimitry Andric llvm::consumeError(expected_binary.takeError()); 960b57cec5SDimitry Andric return nullptr; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric OwningBinary<Binary> binary = std::move(*expected_binary); 990b57cec5SDimitry Andric 1009dba64beSDimitry Andric // TODO: Avoid opening the PE/COFF binary twice by reading this information 1019dba64beSDimitry Andric // directly from the lldb_private::ObjectFile. 1020b57cec5SDimitry Andric auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary()); 1030b57cec5SDimitry Andric if (!obj) 1040b57cec5SDimitry Andric return nullptr; 1050b57cec5SDimitry Andric const llvm::codeview::DebugInfo *pdb_info = nullptr; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric // If it doesn't have a debug directory, fail. 1080b57cec5SDimitry Andric llvm::StringRef pdb_file; 1095ffd83dbSDimitry Andric if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) { 1105ffd83dbSDimitry Andric consumeError(std::move(e)); 1110b57cec5SDimitry Andric return nullptr; 1125ffd83dbSDimitry Andric } 1130b57cec5SDimitry Andric 114e8d8bef9SDimitry Andric // If the file doesn't exist, perhaps the path specified at build time 115e8d8bef9SDimitry Andric // doesn't match the PDB's current location, so check the location of the 116e8d8bef9SDimitry Andric // executable. 117e8d8bef9SDimitry Andric if (!FileSystem::Instance().Exists(pdb_file)) { 118e8d8bef9SDimitry Andric const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent(); 119e8d8bef9SDimitry Andric const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString(); 120e8d8bef9SDimitry Andric pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetCString(); 121e8d8bef9SDimitry Andric } 122e8d8bef9SDimitry Andric 123e8d8bef9SDimitry Andric // If the file is not a PDB or if it doesn't have a matching GUID, fail. 124e8d8bef9SDimitry Andric auto pdb = ObjectFilePDB::loadPDBFile(std::string(pdb_file), allocator); 1250b57cec5SDimitry Andric if (!pdb) 1260b57cec5SDimitry Andric return nullptr; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric auto expected_info = pdb->getPDBInfoStream(); 1290b57cec5SDimitry Andric if (!expected_info) { 1300b57cec5SDimitry Andric llvm::consumeError(expected_info.takeError()); 1310b57cec5SDimitry Andric return nullptr; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric llvm::codeview::GUID guid; 1340b57cec5SDimitry Andric memcpy(&guid, pdb_info->PDB70.Signature, 16); 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric if (expected_info->getGuid() != guid) 1370b57cec5SDimitry Andric return nullptr; 1380b57cec5SDimitry Andric return pdb; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric static bool IsFunctionPrologue(const CompilandIndexItem &cci, 1420b57cec5SDimitry Andric lldb::addr_t addr) { 1430b57cec5SDimitry Andric // FIXME: Implement this. 1440b57cec5SDimitry Andric return false; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric static bool IsFunctionEpilogue(const CompilandIndexItem &cci, 1480b57cec5SDimitry Andric lldb::addr_t addr) { 1490b57cec5SDimitry Andric // FIXME: Implement this. 1500b57cec5SDimitry Andric return false; 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) { 1540b57cec5SDimitry Andric switch (kind) { 1550b57cec5SDimitry Andric case SimpleTypeKind::Boolean128: 1560b57cec5SDimitry Andric case SimpleTypeKind::Boolean16: 1570b57cec5SDimitry Andric case SimpleTypeKind::Boolean32: 1580b57cec5SDimitry Andric case SimpleTypeKind::Boolean64: 1590b57cec5SDimitry Andric case SimpleTypeKind::Boolean8: 1600b57cec5SDimitry Andric return "bool"; 1610b57cec5SDimitry Andric case SimpleTypeKind::Byte: 1620b57cec5SDimitry Andric case SimpleTypeKind::UnsignedCharacter: 1630b57cec5SDimitry Andric return "unsigned char"; 1640b57cec5SDimitry Andric case SimpleTypeKind::NarrowCharacter: 1650b57cec5SDimitry Andric return "char"; 1660b57cec5SDimitry Andric case SimpleTypeKind::SignedCharacter: 1670b57cec5SDimitry Andric case SimpleTypeKind::SByte: 1680b57cec5SDimitry Andric return "signed char"; 1690b57cec5SDimitry Andric case SimpleTypeKind::Character16: 1700b57cec5SDimitry Andric return "char16_t"; 1710b57cec5SDimitry Andric case SimpleTypeKind::Character32: 1720b57cec5SDimitry Andric return "char32_t"; 1730b57cec5SDimitry Andric case SimpleTypeKind::Complex80: 1740b57cec5SDimitry Andric case SimpleTypeKind::Complex64: 1750b57cec5SDimitry Andric case SimpleTypeKind::Complex32: 1760b57cec5SDimitry Andric return "complex"; 1770b57cec5SDimitry Andric case SimpleTypeKind::Float128: 1780b57cec5SDimitry Andric case SimpleTypeKind::Float80: 1790b57cec5SDimitry Andric return "long double"; 1800b57cec5SDimitry Andric case SimpleTypeKind::Float64: 1810b57cec5SDimitry Andric return "double"; 1820b57cec5SDimitry Andric case SimpleTypeKind::Float32: 1830b57cec5SDimitry Andric return "float"; 1840b57cec5SDimitry Andric case SimpleTypeKind::Float16: 1850b57cec5SDimitry Andric return "single"; 1860b57cec5SDimitry Andric case SimpleTypeKind::Int128: 1870b57cec5SDimitry Andric return "__int128"; 1880b57cec5SDimitry Andric case SimpleTypeKind::Int64: 1890b57cec5SDimitry Andric case SimpleTypeKind::Int64Quad: 1900b57cec5SDimitry Andric return "int64_t"; 1910b57cec5SDimitry Andric case SimpleTypeKind::Int32: 1920b57cec5SDimitry Andric return "int"; 1930b57cec5SDimitry Andric case SimpleTypeKind::Int16: 1940b57cec5SDimitry Andric return "short"; 1950b57cec5SDimitry Andric case SimpleTypeKind::UInt128: 1960b57cec5SDimitry Andric return "unsigned __int128"; 1970b57cec5SDimitry Andric case SimpleTypeKind::UInt64: 1980b57cec5SDimitry Andric case SimpleTypeKind::UInt64Quad: 1990b57cec5SDimitry Andric return "uint64_t"; 2000b57cec5SDimitry Andric case SimpleTypeKind::HResult: 2010b57cec5SDimitry Andric return "HRESULT"; 2020b57cec5SDimitry Andric case SimpleTypeKind::UInt32: 2030b57cec5SDimitry Andric return "unsigned"; 2040b57cec5SDimitry Andric case SimpleTypeKind::UInt16: 2050b57cec5SDimitry Andric case SimpleTypeKind::UInt16Short: 2060b57cec5SDimitry Andric return "unsigned short"; 2070b57cec5SDimitry Andric case SimpleTypeKind::Int32Long: 2080b57cec5SDimitry Andric return "long"; 2090b57cec5SDimitry Andric case SimpleTypeKind::UInt32Long: 2100b57cec5SDimitry Andric return "unsigned long"; 2110b57cec5SDimitry Andric case SimpleTypeKind::Void: 2120b57cec5SDimitry Andric return "void"; 2130b57cec5SDimitry Andric case SimpleTypeKind::WideCharacter: 2140b57cec5SDimitry Andric return "wchar_t"; 2150b57cec5SDimitry Andric default: 2160b57cec5SDimitry Andric return ""; 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric static bool IsClassRecord(TypeLeafKind kind) { 2210b57cec5SDimitry Andric switch (kind) { 2220b57cec5SDimitry Andric case LF_STRUCTURE: 2230b57cec5SDimitry Andric case LF_CLASS: 2240b57cec5SDimitry Andric case LF_INTERFACE: 2250b57cec5SDimitry Andric return true; 2260b57cec5SDimitry Andric default: 2270b57cec5SDimitry Andric return false; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric void SymbolFileNativePDB::Initialize() { 2320b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(), 2330b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance, 2340b57cec5SDimitry Andric DebuggerInitialize); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric void SymbolFileNativePDB::Terminate() { 2380b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {} 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric ConstString SymbolFileNativePDB::GetPluginNameStatic() { 2440b57cec5SDimitry Andric static ConstString g_name("native-pdb"); 2450b57cec5SDimitry Andric return g_name; 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric const char *SymbolFileNativePDB::GetPluginDescriptionStatic() { 2490b57cec5SDimitry Andric return "Microsoft PDB debug symbol cross-platform file reader."; 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2529dba64beSDimitry Andric SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) { 2539dba64beSDimitry Andric return new SymbolFileNativePDB(std::move(objfile_sp)); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2569dba64beSDimitry Andric SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp) 2579dba64beSDimitry Andric : SymbolFile(std::move(objfile_sp)) {} 2580b57cec5SDimitry Andric 259fe6060f1SDimitry Andric SymbolFileNativePDB::~SymbolFileNativePDB() = default; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::CalculateAbilities() { 2620b57cec5SDimitry Andric uint32_t abilities = 0; 2639dba64beSDimitry Andric if (!m_objfile_sp) 2640b57cec5SDimitry Andric return 0; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric if (!m_index) { 2670b57cec5SDimitry Andric // Lazily load and match the PDB file, but only do this once. 268e8d8bef9SDimitry Andric PDBFile *pdb_file; 269e8d8bef9SDimitry Andric if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) { 270e8d8bef9SDimitry Andric pdb_file = &pdb->GetPDBFile(); 271e8d8bef9SDimitry Andric } else { 272e8d8bef9SDimitry Andric m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), 273e8d8bef9SDimitry Andric m_allocator); 274e8d8bef9SDimitry Andric pdb_file = m_file_up.get(); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 277e8d8bef9SDimitry Andric if (!pdb_file) 2780b57cec5SDimitry Andric return 0; 2790b57cec5SDimitry Andric 280e8d8bef9SDimitry Andric auto expected_index = PdbIndex::create(pdb_file); 2810b57cec5SDimitry Andric if (!expected_index) { 2820b57cec5SDimitry Andric llvm::consumeError(expected_index.takeError()); 2830b57cec5SDimitry Andric return 0; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric m_index = std::move(*expected_index); 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric if (!m_index) 2880b57cec5SDimitry Andric return 0; 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric // We don't especially have to be precise here. We only distinguish between 2910b57cec5SDimitry Andric // stripped and not stripped. 2920b57cec5SDimitry Andric abilities = kAllAbilities; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric if (m_index->dbi().isStripped()) 2950b57cec5SDimitry Andric abilities &= ~(Blocks | LocalVariables); 2960b57cec5SDimitry Andric return abilities; 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric void SymbolFileNativePDB::InitializeObject() { 300e8d8bef9SDimitry Andric m_obj_load_address = m_objfile_sp->GetModule() 301e8d8bef9SDimitry Andric ->GetObjectFile() 302e8d8bef9SDimitry Andric ->GetBaseAddress() 303e8d8bef9SDimitry Andric .GetFileAddress(); 3040b57cec5SDimitry Andric m_index->SetLoadAddress(m_obj_load_address); 3050b57cec5SDimitry Andric m_index->ParseSectionContribs(); 3060b57cec5SDimitry Andric 3079dba64beSDimitry Andric auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage( 3080b57cec5SDimitry Andric lldb::eLanguageTypeC_plus_plus); 3099dba64beSDimitry Andric if (auto err = ts_or_err.takeError()) { 3109dba64beSDimitry Andric LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 3119dba64beSDimitry Andric std::move(err), "Failed to initialize"); 3129dba64beSDimitry Andric } else { 3139dba64beSDimitry Andric ts_or_err->SetSymbolFile(this); 3145ffd83dbSDimitry Andric auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get()); 3159dba64beSDimitry Andric lldbassert(clang); 3169dba64beSDimitry Andric m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang); 3179dba64beSDimitry Andric } 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3209dba64beSDimitry Andric uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() { 3210b57cec5SDimitry Andric const DbiModuleList &modules = m_index->dbi().modules(); 3220b57cec5SDimitry Andric uint32_t count = modules.getModuleCount(); 3230b57cec5SDimitry Andric if (count == 0) 3240b57cec5SDimitry Andric return count; 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric // The linker can inject an additional "dummy" compilation unit into the 3270b57cec5SDimitry Andric // PDB. Ignore this special compile unit for our purposes, if it is there. 3280b57cec5SDimitry Andric // It is always the last one. 3290b57cec5SDimitry Andric DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1); 3300b57cec5SDimitry Andric if (last.getModuleName() == "* Linker *") 3310b57cec5SDimitry Andric --count; 3320b57cec5SDimitry Andric return count; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { 3360b57cec5SDimitry Andric CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 3370b57cec5SDimitry Andric CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) { 3400b57cec5SDimitry Andric // This is a function. It must be global. Creating the Function entry for 3410b57cec5SDimitry Andric // it automatically creates a block for it. 3420b57cec5SDimitry Andric CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); 3430b57cec5SDimitry Andric return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false); 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric lldbassert(sym.kind() == S_BLOCK32); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric // This is a block. Its parent is either a function or another block. In 3490b57cec5SDimitry Andric // either case, its parent can be viewed as a block (e.g. a function contains 3500b57cec5SDimitry Andric // 1 big block. So just get the parent block and add this block to it. 3510b57cec5SDimitry Andric BlockSym block(static_cast<SymbolRecordKind>(sym.kind())); 3520b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block)); 3530b57cec5SDimitry Andric lldbassert(block.Parent != 0); 3540b57cec5SDimitry Andric PdbCompilandSymId parent_id(block_id.modi, block.Parent); 3550b57cec5SDimitry Andric Block &parent_block = GetOrCreateBlock(parent_id); 3560b57cec5SDimitry Andric lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id); 3570b57cec5SDimitry Andric BlockSP child_block = std::make_shared<Block>(opaque_block_uid); 3580b57cec5SDimitry Andric parent_block.AddChild(child_block); 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric m_ast->GetOrCreateBlockDecl(block_id); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric m_blocks.insert({opaque_block_uid, child_block}); 3630b57cec5SDimitry Andric return *child_block; 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, 3670b57cec5SDimitry Andric CompileUnit &comp_unit) { 3680b57cec5SDimitry Andric const CompilandIndexItem *cci = 3690b57cec5SDimitry Andric m_index->compilands().GetCompiland(func_id.modi); 3700b57cec5SDimitry Andric lldbassert(cci); 3710b57cec5SDimitry Andric CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset); 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); 3740b57cec5SDimitry Andric SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric auto file_vm_addr = m_index->MakeVirtualAddress(sol.so); 3770b57cec5SDimitry Andric if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 3780b57cec5SDimitry Andric return nullptr; 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric AddressRange func_range(file_vm_addr, sol.length, 3810b57cec5SDimitry Andric comp_unit.GetModule()->GetSectionList()); 3820b57cec5SDimitry Andric if (!func_range.GetBaseAddress().IsValid()) 3830b57cec5SDimitry Andric return nullptr; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind())); 3860b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)); 3870b57cec5SDimitry Andric if (proc.FunctionType == TypeIndex::None()) 3880b57cec5SDimitry Andric return nullptr; 3890b57cec5SDimitry Andric TypeSP func_type = GetOrCreateType(proc.FunctionType); 3900b57cec5SDimitry Andric if (!func_type) 3910b57cec5SDimitry Andric return nullptr; 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric PdbTypeSymId sig_id(proc.FunctionType, false); 3940b57cec5SDimitry Andric Mangled mangled(proc.Name); 3950b57cec5SDimitry Andric FunctionSP func_sp = std::make_shared<Function>( 3960b57cec5SDimitry Andric &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled, 3970b57cec5SDimitry Andric func_type.get(), func_range); 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric comp_unit.AddFunction(func_sp); 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric m_ast->GetOrCreateFunctionDecl(func_id); 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric return func_sp; 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric CompUnitSP 4070b57cec5SDimitry Andric SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { 4080b57cec5SDimitry Andric lldb::LanguageType lang = 4090b57cec5SDimitry Andric cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage()) 4100b57cec5SDimitry Andric : lldb::eLanguageTypeUnknown; 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric LazyBool optimized = eLazyBoolNo; 4130b57cec5SDimitry Andric if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations()) 4140b57cec5SDimitry Andric optimized = eLazyBoolYes; 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric llvm::SmallString<64> source_file_name = 4170b57cec5SDimitry Andric m_index->compilands().GetMainSourceFile(cci); 4180b57cec5SDimitry Andric FileSpec fs(source_file_name); 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric CompUnitSP cu_sp = 4219dba64beSDimitry Andric std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs, 4220b57cec5SDimitry Andric toOpaqueUid(cci.m_id), lang, optimized); 4230b57cec5SDimitry Andric 4249dba64beSDimitry Andric SetCompileUnitAtIndex(cci.m_id.modi, cu_sp); 4250b57cec5SDimitry Andric return cu_sp; 4260b57cec5SDimitry Andric } 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, 4290b57cec5SDimitry Andric const ModifierRecord &mr, 4300b57cec5SDimitry Andric CompilerType ct) { 4310b57cec5SDimitry Andric TpiStream &stream = m_index->tpi(); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric std::string name; 4340b57cec5SDimitry Andric if (mr.ModifiedType.isSimple()) 4355ffd83dbSDimitry Andric name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind())); 4360b57cec5SDimitry Andric else 4370b57cec5SDimitry Andric name = computeTypeName(stream.typeCollection(), mr.ModifiedType); 4380b57cec5SDimitry Andric Declaration decl; 4390b57cec5SDimitry Andric lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType); 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(name), 442e8d8bef9SDimitry Andric modified_type->GetByteSize(nullptr), nullptr, 4430b57cec5SDimitry Andric LLDB_INVALID_UID, Type::eEncodingIsUID, decl, 444480093f4SDimitry Andric ct, Type::ResolveState::Full); 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric lldb::TypeSP 4480b57cec5SDimitry Andric SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id, 4490b57cec5SDimitry Andric const llvm::codeview::PointerRecord &pr, 4500b57cec5SDimitry Andric CompilerType ct) { 4510b57cec5SDimitry Andric TypeSP pointee = GetOrCreateType(pr.ReferentType); 4520b57cec5SDimitry Andric if (!pointee) 4530b57cec5SDimitry Andric return nullptr; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric if (pr.isPointerToMember()) { 4560b57cec5SDimitry Andric MemberPointerInfo mpi = pr.getMemberInfo(); 4570b57cec5SDimitry Andric GetOrCreateType(mpi.ContainingType); 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric Declaration decl; 4610b57cec5SDimitry Andric return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(), 4620b57cec5SDimitry Andric pr.getSize(), nullptr, LLDB_INVALID_UID, 4630b57cec5SDimitry Andric Type::eEncodingIsUID, decl, ct, 464480093f4SDimitry Andric Type::ResolveState::Full); 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti, 4680b57cec5SDimitry Andric CompilerType ct) { 4690b57cec5SDimitry Andric uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false)); 4700b57cec5SDimitry Andric if (ti == TypeIndex::NullptrT()) { 4710b57cec5SDimitry Andric Declaration decl; 4720b57cec5SDimitry Andric return std::make_shared<Type>( 4730b57cec5SDimitry Andric uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID, 474480093f4SDimitry Andric Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full); 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric if (ti.getSimpleMode() != SimpleTypeMode::Direct) { 4780b57cec5SDimitry Andric TypeSP direct_sp = GetOrCreateType(ti.makeDirect()); 4790b57cec5SDimitry Andric uint32_t pointer_size = 0; 4800b57cec5SDimitry Andric switch (ti.getSimpleMode()) { 4810b57cec5SDimitry Andric case SimpleTypeMode::FarPointer32: 4820b57cec5SDimitry Andric case SimpleTypeMode::NearPointer32: 4830b57cec5SDimitry Andric pointer_size = 4; 4840b57cec5SDimitry Andric break; 4850b57cec5SDimitry Andric case SimpleTypeMode::NearPointer64: 4860b57cec5SDimitry Andric pointer_size = 8; 4870b57cec5SDimitry Andric break; 4880b57cec5SDimitry Andric default: 4890b57cec5SDimitry Andric // 128-bit and 16-bit pointers unsupported. 4900b57cec5SDimitry Andric return nullptr; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric Declaration decl; 4930b57cec5SDimitry Andric return std::make_shared<Type>( 4940b57cec5SDimitry Andric uid, this, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID, 495480093f4SDimitry Andric Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full); 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) 4990b57cec5SDimitry Andric return nullptr; 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind()); 5020b57cec5SDimitry Andric llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind()); 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric Declaration decl; 5050b57cec5SDimitry Andric return std::make_shared<Type>(uid, this, ConstString(type_name), size, 5060b57cec5SDimitry Andric nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, 507480093f4SDimitry Andric decl, ct, Type::ResolveState::Full); 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric static std::string GetUnqualifiedTypeName(const TagRecord &record) { 5110b57cec5SDimitry Andric if (!record.hasUniqueName()) { 5120b57cec5SDimitry Andric MSVCUndecoratedNameParser parser(record.Name); 5130b57cec5SDimitry Andric llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 5140b57cec5SDimitry Andric 5155ffd83dbSDimitry Andric return std::string(specs.back().GetBaseName()); 5160b57cec5SDimitry Andric } 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric llvm::ms_demangle::Demangler demangler; 5190b57cec5SDimitry Andric StringView sv(record.UniqueName.begin(), record.UniqueName.size()); 5200b57cec5SDimitry Andric llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); 5210b57cec5SDimitry Andric if (demangler.Error) 5225ffd83dbSDimitry Andric return std::string(record.Name); 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric llvm::ms_demangle::IdentifierNode *idn = 5250b57cec5SDimitry Andric ttn->QualifiedName->getUnqualifiedIdentifier(); 5260b57cec5SDimitry Andric return idn->toString(); 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric lldb::TypeSP 5300b57cec5SDimitry Andric SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id, 5310b57cec5SDimitry Andric const TagRecord &record, 5320b57cec5SDimitry Andric size_t size, CompilerType ct) { 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric std::string uname = GetUnqualifiedTypeName(record); 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE. 5370b57cec5SDimitry Andric Declaration decl; 5380b57cec5SDimitry Andric return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(uname), 5390b57cec5SDimitry Andric size, nullptr, LLDB_INVALID_UID, 5400b57cec5SDimitry Andric Type::eEncodingIsUID, decl, ct, 541480093f4SDimitry Andric Type::ResolveState::Forward); 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 5450b57cec5SDimitry Andric const ClassRecord &cr, 5460b57cec5SDimitry Andric CompilerType ct) { 5470b57cec5SDimitry Andric return CreateClassStructUnion(type_id, cr, cr.getSize(), ct); 5480b57cec5SDimitry Andric } 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 5510b57cec5SDimitry Andric const UnionRecord &ur, 5520b57cec5SDimitry Andric CompilerType ct) { 5530b57cec5SDimitry Andric return CreateClassStructUnion(type_id, ur, ur.getSize(), ct); 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 5570b57cec5SDimitry Andric const EnumRecord &er, 5580b57cec5SDimitry Andric CompilerType ct) { 5590b57cec5SDimitry Andric std::string uname = GetUnqualifiedTypeName(er); 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric Declaration decl; 5620b57cec5SDimitry Andric TypeSP underlying_type = GetOrCreateType(er.UnderlyingType); 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 5650b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(uname), 566e8d8bef9SDimitry Andric underlying_type->GetByteSize(nullptr), nullptr, LLDB_INVALID_UID, 5670b57cec5SDimitry Andric lldb_private::Type::eEncodingIsUID, decl, ct, 568480093f4SDimitry Andric lldb_private::Type::ResolveState::Forward); 5690b57cec5SDimitry Andric } 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id, 5720b57cec5SDimitry Andric const ArrayRecord &ar, 5730b57cec5SDimitry Andric CompilerType ct) { 5740b57cec5SDimitry Andric TypeSP element_type = GetOrCreateType(ar.ElementType); 5750b57cec5SDimitry Andric 5760b57cec5SDimitry Andric Declaration decl; 5770b57cec5SDimitry Andric TypeSP array_sp = std::make_shared<lldb_private::Type>( 5780b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(), ar.Size, nullptr, 5790b57cec5SDimitry Andric LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct, 580480093f4SDimitry Andric lldb_private::Type::ResolveState::Full); 5810b57cec5SDimitry Andric array_sp->SetEncodingType(element_type.get()); 5820b57cec5SDimitry Andric return array_sp; 5830b57cec5SDimitry Andric } 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id, 5870b57cec5SDimitry Andric const MemberFunctionRecord &mfr, 5880b57cec5SDimitry Andric CompilerType ct) { 5890b57cec5SDimitry Andric Declaration decl; 5900b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 5910b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, 5920b57cec5SDimitry Andric lldb_private::Type::eEncodingIsUID, decl, ct, 593480093f4SDimitry Andric lldb_private::Type::ResolveState::Full); 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, 5970b57cec5SDimitry Andric const ProcedureRecord &pr, 5980b57cec5SDimitry Andric CompilerType ct) { 5990b57cec5SDimitry Andric Declaration decl; 6000b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 6010b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, 6020b57cec5SDimitry Andric lldb_private::Type::eEncodingIsUID, decl, ct, 603480093f4SDimitry Andric lldb_private::Type::ResolveState::Full); 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { 6070b57cec5SDimitry Andric if (type_id.index.isSimple()) 6080b57cec5SDimitry Andric return CreateSimpleType(type_id.index, ct); 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi(); 6110b57cec5SDimitry Andric CVType cvt = stream.getType(type_id.index); 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric if (cvt.kind() == LF_MODIFIER) { 6140b57cec5SDimitry Andric ModifierRecord modifier; 6150b57cec5SDimitry Andric llvm::cantFail( 6160b57cec5SDimitry Andric TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)); 6170b57cec5SDimitry Andric return CreateModifierType(type_id, modifier, ct); 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric if (cvt.kind() == LF_POINTER) { 6210b57cec5SDimitry Andric PointerRecord pointer; 6220b57cec5SDimitry Andric llvm::cantFail( 6230b57cec5SDimitry Andric TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)); 6240b57cec5SDimitry Andric return CreatePointerType(type_id, pointer, ct); 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric if (IsClassRecord(cvt.kind())) { 6280b57cec5SDimitry Andric ClassRecord cr; 6290b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 6300b57cec5SDimitry Andric return CreateTagType(type_id, cr, ct); 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric if (cvt.kind() == LF_ENUM) { 6340b57cec5SDimitry Andric EnumRecord er; 6350b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 6360b57cec5SDimitry Andric return CreateTagType(type_id, er, ct); 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric if (cvt.kind() == LF_UNION) { 6400b57cec5SDimitry Andric UnionRecord ur; 6410b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 6420b57cec5SDimitry Andric return CreateTagType(type_id, ur, ct); 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric if (cvt.kind() == LF_ARRAY) { 6460b57cec5SDimitry Andric ArrayRecord ar; 6470b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)); 6480b57cec5SDimitry Andric return CreateArrayType(type_id, ar, ct); 6490b57cec5SDimitry Andric } 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric if (cvt.kind() == LF_PROCEDURE) { 6520b57cec5SDimitry Andric ProcedureRecord pr; 6530b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)); 6540b57cec5SDimitry Andric return CreateProcedureType(type_id, pr, ct); 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric if (cvt.kind() == LF_MFUNCTION) { 6570b57cec5SDimitry Andric MemberFunctionRecord mfr; 6580b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)); 6590b57cec5SDimitry Andric return CreateFunctionType(type_id, mfr, ct); 6600b57cec5SDimitry Andric } 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric return nullptr; 6630b57cec5SDimitry Andric } 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { 6660b57cec5SDimitry Andric // If they search for a UDT which is a forward ref, try and resolve the full 6670b57cec5SDimitry Andric // decl and just map the forward ref uid to the full decl record. 6680b57cec5SDimitry Andric llvm::Optional<PdbTypeSymId> full_decl_uid; 6690b57cec5SDimitry Andric if (IsForwardRefUdt(type_id, m_index->tpi())) { 6700b57cec5SDimitry Andric auto expected_full_ti = 6710b57cec5SDimitry Andric m_index->tpi().findFullDeclForForwardRef(type_id.index); 6720b57cec5SDimitry Andric if (!expected_full_ti) 6730b57cec5SDimitry Andric llvm::consumeError(expected_full_ti.takeError()); 6740b57cec5SDimitry Andric else if (*expected_full_ti != type_id.index) { 6750b57cec5SDimitry Andric full_decl_uid = PdbTypeSymId(*expected_full_ti, false); 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric // It's possible that a lookup would occur for the full decl causing it 6780b57cec5SDimitry Andric // to be cached, then a second lookup would occur for the forward decl. 6790b57cec5SDimitry Andric // We don't want to create a second full decl, so make sure the full 6800b57cec5SDimitry Andric // decl hasn't already been cached. 6810b57cec5SDimitry Andric auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid)); 6820b57cec5SDimitry Andric if (full_iter != m_types.end()) { 6830b57cec5SDimitry Andric TypeSP result = full_iter->second; 6840b57cec5SDimitry Andric // Map the forward decl to the TypeSP for the full decl so we can take 6850b57cec5SDimitry Andric // the fast path next time. 6860b57cec5SDimitry Andric m_types[toOpaqueUid(type_id)] = result; 6870b57cec5SDimitry Andric return result; 6880b57cec5SDimitry Andric } 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric clang::QualType qt = m_ast->GetOrCreateType(best_decl_id); 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt)); 6970b57cec5SDimitry Andric if (!result) 6980b57cec5SDimitry Andric return nullptr; 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric uint64_t best_uid = toOpaqueUid(best_decl_id); 7010b57cec5SDimitry Andric m_types[best_uid] = result; 7020b57cec5SDimitry Andric // If we had both a forward decl and a full decl, make both point to the new 7030b57cec5SDimitry Andric // type. 7040b57cec5SDimitry Andric if (full_decl_uid) 7050b57cec5SDimitry Andric m_types[toOpaqueUid(type_id)] = result; 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric return result; 7080b57cec5SDimitry Andric } 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) { 7110b57cec5SDimitry Andric // We can't use try_emplace / overwrite here because the process of creating 7120b57cec5SDimitry Andric // a type could create nested types, which could invalidate iterators. So 7130b57cec5SDimitry Andric // we have to do a 2-phase lookup / insert. 7140b57cec5SDimitry Andric auto iter = m_types.find(toOpaqueUid(type_id)); 7150b57cec5SDimitry Andric if (iter != m_types.end()) 7160b57cec5SDimitry Andric return iter->second; 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric TypeSP type = CreateAndCacheType(type_id); 7190b57cec5SDimitry Andric if (type) 7209dba64beSDimitry Andric GetTypeList().Insert(type); 7210b57cec5SDimitry Andric return type; 7220b57cec5SDimitry Andric } 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { 7250b57cec5SDimitry Andric CVSymbol sym = m_index->symrecords().readRecord(var_id.offset); 7260b57cec5SDimitry Andric if (sym.kind() == S_CONSTANT) 7270b57cec5SDimitry Andric return CreateConstantSymbol(var_id, sym); 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric lldb::ValueType scope = eValueTypeInvalid; 7300b57cec5SDimitry Andric TypeIndex ti; 7310b57cec5SDimitry Andric llvm::StringRef name; 7320b57cec5SDimitry Andric lldb::addr_t addr = 0; 7330b57cec5SDimitry Andric uint16_t section = 0; 7340b57cec5SDimitry Andric uint32_t offset = 0; 7350b57cec5SDimitry Andric bool is_external = false; 7360b57cec5SDimitry Andric switch (sym.kind()) { 7370b57cec5SDimitry Andric case S_GDATA32: 7380b57cec5SDimitry Andric is_external = true; 7390b57cec5SDimitry Andric LLVM_FALLTHROUGH; 7400b57cec5SDimitry Andric case S_LDATA32: { 7410b57cec5SDimitry Andric DataSym ds(sym.kind()); 7420b57cec5SDimitry Andric llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds)); 7430b57cec5SDimitry Andric ti = ds.Type; 7440b57cec5SDimitry Andric scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal 7450b57cec5SDimitry Andric : eValueTypeVariableStatic; 7460b57cec5SDimitry Andric name = ds.Name; 7470b57cec5SDimitry Andric section = ds.Segment; 7480b57cec5SDimitry Andric offset = ds.DataOffset; 7490b57cec5SDimitry Andric addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset); 7500b57cec5SDimitry Andric break; 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric case S_GTHREAD32: 7530b57cec5SDimitry Andric is_external = true; 7540b57cec5SDimitry Andric LLVM_FALLTHROUGH; 7550b57cec5SDimitry Andric case S_LTHREAD32: { 7560b57cec5SDimitry Andric ThreadLocalDataSym tlds(sym.kind()); 7570b57cec5SDimitry Andric llvm::cantFail( 7580b57cec5SDimitry Andric SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)); 7590b57cec5SDimitry Andric ti = tlds.Type; 7600b57cec5SDimitry Andric name = tlds.Name; 7610b57cec5SDimitry Andric section = tlds.Segment; 7620b57cec5SDimitry Andric offset = tlds.DataOffset; 7630b57cec5SDimitry Andric addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset); 7640b57cec5SDimitry Andric scope = eValueTypeVariableThreadLocal; 7650b57cec5SDimitry Andric break; 7660b57cec5SDimitry Andric } 7670b57cec5SDimitry Andric default: 7680b57cec5SDimitry Andric llvm_unreachable("unreachable!"); 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric CompUnitSP comp_unit; 7720b57cec5SDimitry Andric llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr); 7730b57cec5SDimitry Andric if (modi) { 7740b57cec5SDimitry Andric CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); 7750b57cec5SDimitry Andric comp_unit = GetOrCreateCompileUnit(cci); 7760b57cec5SDimitry Andric } 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric Declaration decl; 7790b57cec5SDimitry Andric PdbTypeSymId tid(ti, false); 7800b57cec5SDimitry Andric SymbolFileTypeSP type_sp = 7810b57cec5SDimitry Andric std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 7820b57cec5SDimitry Andric Variable::RangeList ranges; 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric m_ast->GetOrCreateVariableDecl(var_id); 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric DWARFExpression location = MakeGlobalLocationExpression( 7870b57cec5SDimitry Andric section, offset, GetObjectFile()->GetModule()); 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric std::string global_name("::"); 7900b57cec5SDimitry Andric global_name += name; 791e8d8bef9SDimitry Andric bool artificial = false; 792e8d8bef9SDimitry Andric bool location_is_constant_data = false; 793e8d8bef9SDimitry Andric bool static_member = false; 7940b57cec5SDimitry Andric VariableSP var_sp = std::make_shared<Variable>( 7950b57cec5SDimitry Andric toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, 796e8d8bef9SDimitry Andric scope, comp_unit.get(), ranges, &decl, location, is_external, artificial, 797e8d8bef9SDimitry Andric location_is_constant_data, static_member); 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric return var_sp; 8000b57cec5SDimitry Andric } 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric lldb::VariableSP 8030b57cec5SDimitry Andric SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, 8040b57cec5SDimitry Andric const CVSymbol &cvs) { 8050b57cec5SDimitry Andric TpiStream &tpi = m_index->tpi(); 8060b57cec5SDimitry Andric ConstantSym constant(cvs.kind()); 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)); 8090b57cec5SDimitry Andric std::string global_name("::"); 8100b57cec5SDimitry Andric global_name += constant.Name; 8110b57cec5SDimitry Andric PdbTypeSymId tid(constant.Type, false); 8120b57cec5SDimitry Andric SymbolFileTypeSP type_sp = 8130b57cec5SDimitry Andric std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 8140b57cec5SDimitry Andric 8150b57cec5SDimitry Andric Declaration decl; 8160b57cec5SDimitry Andric Variable::RangeList ranges; 8170b57cec5SDimitry Andric ModuleSP module = GetObjectFile()->GetModule(); 8180b57cec5SDimitry Andric DWARFExpression location = MakeConstantLocationExpression( 8190b57cec5SDimitry Andric constant.Type, tpi, constant.Value, module); 8200b57cec5SDimitry Andric 821e8d8bef9SDimitry Andric bool external = false; 822e8d8bef9SDimitry Andric bool artificial = false; 823e8d8bef9SDimitry Andric bool location_is_constant_data = true; 824e8d8bef9SDimitry Andric bool static_member = false; 8250b57cec5SDimitry Andric VariableSP var_sp = std::make_shared<Variable>( 8260b57cec5SDimitry Andric toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), 8270b57cec5SDimitry Andric type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, 828e8d8bef9SDimitry Andric external, artificial, location_is_constant_data, static_member); 8290b57cec5SDimitry Andric return var_sp; 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric VariableSP 8330b57cec5SDimitry Andric SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { 8340b57cec5SDimitry Andric auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); 8350b57cec5SDimitry Andric if (emplace_result.second) 8360b57cec5SDimitry Andric emplace_result.first->second = CreateGlobalVariable(var_id); 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric return emplace_result.first->second; 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) { 8420b57cec5SDimitry Andric return GetOrCreateType(PdbTypeSymId(ti, false)); 8430b57cec5SDimitry Andric } 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id, 8460b57cec5SDimitry Andric CompileUnit &comp_unit) { 8470b57cec5SDimitry Andric auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr); 8480b57cec5SDimitry Andric if (emplace_result.second) 8490b57cec5SDimitry Andric emplace_result.first->second = CreateFunction(func_id, comp_unit); 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric return emplace_result.first->second; 8520b57cec5SDimitry Andric } 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric CompUnitSP 8550b57cec5SDimitry Andric SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) { 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric auto emplace_result = 8580b57cec5SDimitry Andric m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr); 8590b57cec5SDimitry Andric if (emplace_result.second) 8600b57cec5SDimitry Andric emplace_result.first->second = CreateCompileUnit(cci); 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric lldbassert(emplace_result.first->second); 8630b57cec5SDimitry Andric return emplace_result.first->second; 8640b57cec5SDimitry Andric } 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andric Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) { 8670b57cec5SDimitry Andric auto iter = m_blocks.find(toOpaqueUid(block_id)); 8680b57cec5SDimitry Andric if (iter != m_blocks.end()) 8690b57cec5SDimitry Andric return *iter->second; 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric return CreateBlock(block_id); 8720b57cec5SDimitry Andric } 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric void SymbolFileNativePDB::ParseDeclsForContext( 8750b57cec5SDimitry Andric lldb_private::CompilerDeclContext decl_ctx) { 8760b57cec5SDimitry Andric clang::DeclContext *context = m_ast->FromCompilerDeclContext(decl_ctx); 8770b57cec5SDimitry Andric if (!context) 8780b57cec5SDimitry Andric return; 8790b57cec5SDimitry Andric m_ast->ParseDeclsForContext(*context); 8800b57cec5SDimitry Andric } 8810b57cec5SDimitry Andric 8820b57cec5SDimitry Andric lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) { 8830b57cec5SDimitry Andric if (index >= GetNumCompileUnits()) 8840b57cec5SDimitry Andric return CompUnitSP(); 8850b57cec5SDimitry Andric lldbassert(index < UINT16_MAX); 8860b57cec5SDimitry Andric if (index >= UINT16_MAX) 8870b57cec5SDimitry Andric return nullptr; 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index); 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric return GetOrCreateCompileUnit(item); 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) { 8959dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 8960b57cec5SDimitry Andric PdbSymUid uid(comp_unit.GetID()); 8970b57cec5SDimitry Andric lldbassert(uid.kind() == PdbSymUidKind::Compiland); 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric CompilandIndexItem *item = 9000b57cec5SDimitry Andric m_index->compilands().GetCompiland(uid.asCompiland().modi); 9010b57cec5SDimitry Andric lldbassert(item); 9020b57cec5SDimitry Andric if (!item->m_compile_opts) 9030b57cec5SDimitry Andric return lldb::eLanguageTypeUnknown; 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric return TranslateLanguage(item->m_compile_opts->getLanguage()); 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; } 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) { 9119dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 9120b57cec5SDimitry Andric PdbSymUid uid{comp_unit.GetID()}; 9130b57cec5SDimitry Andric lldbassert(uid.kind() == PdbSymUidKind::Compiland); 9140b57cec5SDimitry Andric uint16_t modi = uid.asCompiland().modi; 9150b57cec5SDimitry Andric CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi); 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric size_t count = comp_unit.GetNumFunctions(); 9180b57cec5SDimitry Andric const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray(); 9190b57cec5SDimitry Andric for (auto iter = syms.begin(); iter != syms.end(); ++iter) { 9200b57cec5SDimitry Andric if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) 9210b57cec5SDimitry Andric continue; 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric PdbCompilandSymId sym_id{modi, iter.offset()}; 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andric FunctionSP func = GetOrCreateFunction(sym_id, comp_unit); 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric size_t new_count = comp_unit.GetNumFunctions(); 9290b57cec5SDimitry Andric lldbassert(new_count >= count); 9300b57cec5SDimitry Andric return new_count - count; 9310b57cec5SDimitry Andric } 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) { 9340b57cec5SDimitry Andric // If any of these flags are set, we need to resolve the compile unit. 9350b57cec5SDimitry Andric uint32_t flags = eSymbolContextCompUnit; 9360b57cec5SDimitry Andric flags |= eSymbolContextVariable; 9370b57cec5SDimitry Andric flags |= eSymbolContextFunction; 9380b57cec5SDimitry Andric flags |= eSymbolContextBlock; 9390b57cec5SDimitry Andric flags |= eSymbolContextLineEntry; 9400b57cec5SDimitry Andric return (resolve_scope & flags) != 0; 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::ResolveSymbolContext( 9440b57cec5SDimitry Andric const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) { 9459dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 9460b57cec5SDimitry Andric uint32_t resolved_flags = 0; 9470b57cec5SDimitry Andric lldb::addr_t file_addr = addr.GetFileAddress(); 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric if (NeedsResolvedCompileUnit(resolve_scope)) { 9500b57cec5SDimitry Andric llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr); 9510b57cec5SDimitry Andric if (!modi) 9520b57cec5SDimitry Andric return 0; 9530b57cec5SDimitry Andric CompilandIndexItem *cci = m_index->compilands().GetCompiland(*modi); 9540b57cec5SDimitry Andric if (!cci) 9550b57cec5SDimitry Andric return 0; 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric sc.comp_unit = GetOrCreateCompileUnit(*cci).get(); 9580b57cec5SDimitry Andric resolved_flags |= eSymbolContextCompUnit; 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric if (resolve_scope & eSymbolContextFunction || 9620b57cec5SDimitry Andric resolve_scope & eSymbolContextBlock) { 9630b57cec5SDimitry Andric lldbassert(sc.comp_unit); 9640b57cec5SDimitry Andric std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr); 9650b57cec5SDimitry Andric // Search the matches in reverse. This way if there are multiple matches 9660b57cec5SDimitry Andric // (for example we are 3 levels deep in a nested scope) it will find the 9670b57cec5SDimitry Andric // innermost one first. 9680b57cec5SDimitry Andric for (const auto &match : llvm::reverse(matches)) { 9690b57cec5SDimitry Andric if (match.uid.kind() != PdbSymUidKind::CompilandSym) 9700b57cec5SDimitry Andric continue; 9710b57cec5SDimitry Andric 9720b57cec5SDimitry Andric PdbCompilandSymId csid = match.uid.asCompilandSym(); 9730b57cec5SDimitry Andric CVSymbol cvs = m_index->ReadSymbolRecord(csid); 9740b57cec5SDimitry Andric PDB_SymType type = CVSymToPDBSym(cvs.kind()); 9750b57cec5SDimitry Andric if (type != PDB_SymType::Function && type != PDB_SymType::Block) 9760b57cec5SDimitry Andric continue; 9770b57cec5SDimitry Andric if (type == PDB_SymType::Function) { 9780b57cec5SDimitry Andric sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get(); 9790b57cec5SDimitry Andric sc.block = sc.GetFunctionBlock(); 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric 9820b57cec5SDimitry Andric if (type == PDB_SymType::Block) { 9830b57cec5SDimitry Andric sc.block = &GetOrCreateBlock(csid); 9840b57cec5SDimitry Andric sc.function = sc.block->CalculateSymbolContextFunction(); 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric resolved_flags |= eSymbolContextFunction; 9870b57cec5SDimitry Andric resolved_flags |= eSymbolContextBlock; 9880b57cec5SDimitry Andric break; 9890b57cec5SDimitry Andric } 9900b57cec5SDimitry Andric } 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric if (resolve_scope & eSymbolContextLineEntry) { 9930b57cec5SDimitry Andric lldbassert(sc.comp_unit); 9940b57cec5SDimitry Andric if (auto *line_table = sc.comp_unit->GetLineTable()) { 9950b57cec5SDimitry Andric if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) 9960b57cec5SDimitry Andric resolved_flags |= eSymbolContextLineEntry; 9970b57cec5SDimitry Andric } 9980b57cec5SDimitry Andric } 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric return resolved_flags; 10010b57cec5SDimitry Andric } 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::ResolveSymbolContext( 1004fe6060f1SDimitry Andric const SourceLocationSpec &src_location_spec, 10050b57cec5SDimitry Andric lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { 10060b57cec5SDimitry Andric return 0; 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence, 10100b57cec5SDimitry Andric const CompilandIndexItem &cci, 10110b57cec5SDimitry Andric lldb::addr_t base_addr, 10120b57cec5SDimitry Andric uint32_t file_number, 10130b57cec5SDimitry Andric const LineFragmentHeader &block, 10140b57cec5SDimitry Andric const LineNumberEntry &cur) { 10150b57cec5SDimitry Andric LineInfo cur_info(cur.Flags); 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) 10180b57cec5SDimitry Andric return; 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andric uint64_t addr = base_addr + cur.Offset; 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric bool is_statement = cur_info.isStatement(); 10230b57cec5SDimitry Andric bool is_prologue = IsFunctionPrologue(cci, addr); 10240b57cec5SDimitry Andric bool is_epilogue = IsFunctionEpilogue(cci, addr); 10250b57cec5SDimitry Andric 10260b57cec5SDimitry Andric uint32_t lno = cur_info.getStartLine(); 10270b57cec5SDimitry Andric 10280b57cec5SDimitry Andric table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number, 10290b57cec5SDimitry Andric is_statement, false, is_prologue, is_epilogue, 10300b57cec5SDimitry Andric false); 10310b57cec5SDimitry Andric } 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric static void TerminateLineSequence(LineTable &table, 10340b57cec5SDimitry Andric const LineFragmentHeader &block, 10350b57cec5SDimitry Andric lldb::addr_t base_addr, uint32_t file_number, 10360b57cec5SDimitry Andric uint32_t last_line, 10370b57cec5SDimitry Andric std::unique_ptr<LineSequence> seq) { 10380b57cec5SDimitry Andric // The end is always a terminal entry, so insert it regardless. 10390b57cec5SDimitry Andric table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize, 10400b57cec5SDimitry Andric last_line, 0, file_number, false, false, 10410b57cec5SDimitry Andric false, false, true); 1042fe6060f1SDimitry Andric table.InsertSequence(seq.get()); 10430b57cec5SDimitry Andric } 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { 10460b57cec5SDimitry Andric // Unfortunately LLDB is set up to parse the entire compile unit line table 10470b57cec5SDimitry Andric // all at once, even if all it really needs is line info for a specific 10480b57cec5SDimitry Andric // function. In the future it would be nice if it could set the sc.m_function 10490b57cec5SDimitry Andric // member, and we could only get the line info for the function in question. 10509dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 10510b57cec5SDimitry Andric PdbSymUid cu_id(comp_unit.GetID()); 10520b57cec5SDimitry Andric lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 10530b57cec5SDimitry Andric CompilandIndexItem *cci = 10540b57cec5SDimitry Andric m_index->compilands().GetCompiland(cu_id.asCompiland().modi); 10550b57cec5SDimitry Andric lldbassert(cci); 10569dba64beSDimitry Andric auto line_table = std::make_unique<LineTable>(&comp_unit); 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric // This is basically a copy of the .debug$S subsections from all original COFF 10590b57cec5SDimitry Andric // object files merged together with address relocations applied. We are 10600b57cec5SDimitry Andric // looking for all DEBUG_S_LINES subsections. 10610b57cec5SDimitry Andric for (const DebugSubsectionRecord &dssr : 10620b57cec5SDimitry Andric cci->m_debug_stream.getSubsectionsArray()) { 10630b57cec5SDimitry Andric if (dssr.kind() != DebugSubsectionKind::Lines) 10640b57cec5SDimitry Andric continue; 10650b57cec5SDimitry Andric 10660b57cec5SDimitry Andric DebugLinesSubsectionRef lines; 10670b57cec5SDimitry Andric llvm::BinaryStreamReader reader(dssr.getRecordData()); 10680b57cec5SDimitry Andric if (auto EC = lines.initialize(reader)) { 10690b57cec5SDimitry Andric llvm::consumeError(std::move(EC)); 10700b57cec5SDimitry Andric return false; 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric const LineFragmentHeader *lfh = lines.header(); 10740b57cec5SDimitry Andric uint64_t virtual_addr = 10750b57cec5SDimitry Andric m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric const auto &checksums = cci->m_strings.checksums().getArray(); 10780b57cec5SDimitry Andric const auto &strings = cci->m_strings.strings(); 10790b57cec5SDimitry Andric for (const LineColumnEntry &group : lines) { 10800b57cec5SDimitry Andric // Indices in this structure are actually offsets of records in the 10810b57cec5SDimitry Andric // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index 10820b57cec5SDimitry Andric // into the global PDB string table. 10830b57cec5SDimitry Andric auto iter = checksums.at(group.NameIndex); 10840b57cec5SDimitry Andric if (iter == checksums.end()) 10850b57cec5SDimitry Andric continue; 10860b57cec5SDimitry Andric 10870b57cec5SDimitry Andric llvm::Expected<llvm::StringRef> efn = 10880b57cec5SDimitry Andric strings.getString(iter->FileNameOffset); 10890b57cec5SDimitry Andric if (!efn) { 10900b57cec5SDimitry Andric llvm::consumeError(efn.takeError()); 10910b57cec5SDimitry Andric continue; 10920b57cec5SDimitry Andric } 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric // LLDB wants the index of the file in the list of support files. 10950b57cec5SDimitry Andric auto fn_iter = llvm::find(cci->m_file_list, *efn); 10960b57cec5SDimitry Andric lldbassert(fn_iter != cci->m_file_list.end()); 1097480093f4SDimitry Andric uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter); 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andric std::unique_ptr<LineSequence> sequence( 11000b57cec5SDimitry Andric line_table->CreateLineSequenceContainer()); 11010b57cec5SDimitry Andric lldbassert(!group.LineNumbers.empty()); 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric for (const LineNumberEntry &entry : group.LineNumbers) { 11040b57cec5SDimitry Andric AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr, 11050b57cec5SDimitry Andric file_index, *lfh, entry); 11060b57cec5SDimitry Andric } 11070b57cec5SDimitry Andric LineInfo last_line(group.LineNumbers.back().Flags); 11080b57cec5SDimitry Andric TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index, 11090b57cec5SDimitry Andric last_line.getEndLine(), std::move(sequence)); 11100b57cec5SDimitry Andric } 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric 11130b57cec5SDimitry Andric if (line_table->GetSize() == 0) 11140b57cec5SDimitry Andric return false; 11150b57cec5SDimitry Andric 11160b57cec5SDimitry Andric comp_unit.SetLineTable(line_table.release()); 11170b57cec5SDimitry Andric return true; 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { 11210b57cec5SDimitry Andric // PDB doesn't contain information about macros 11220b57cec5SDimitry Andric return false; 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric 11250b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, 11260b57cec5SDimitry Andric FileSpecList &support_files) { 11279dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11280b57cec5SDimitry Andric PdbSymUid cu_id(comp_unit.GetID()); 11290b57cec5SDimitry Andric lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 11300b57cec5SDimitry Andric CompilandIndexItem *cci = 11310b57cec5SDimitry Andric m_index->compilands().GetCompiland(cu_id.asCompiland().modi); 11320b57cec5SDimitry Andric lldbassert(cci); 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric for (llvm::StringRef f : cci->m_file_list) { 11350b57cec5SDimitry Andric FileSpec::Style style = 11360b57cec5SDimitry Andric f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows; 11370b57cec5SDimitry Andric FileSpec spec(f, style); 11380b57cec5SDimitry Andric support_files.Append(spec); 11390b57cec5SDimitry Andric } 11400b57cec5SDimitry Andric return true; 11410b57cec5SDimitry Andric } 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseImportedModules( 11440b57cec5SDimitry Andric const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 11450b57cec5SDimitry Andric // PDB does not yet support module debug info 11460b57cec5SDimitry Andric return false; 11470b57cec5SDimitry Andric } 11480b57cec5SDimitry Andric 11490b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { 11509dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11510b57cec5SDimitry Andric GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym()); 11520b57cec5SDimitry Andric // FIXME: Parse child blocks 11530b57cec5SDimitry Andric return 1; 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); } 11570b57cec5SDimitry Andric 11589dba64beSDimitry Andric void SymbolFileNativePDB::FindGlobalVariables( 11595ffd83dbSDimitry Andric ConstString name, const CompilerDeclContext &parent_decl_ctx, 11600b57cec5SDimitry Andric uint32_t max_matches, VariableList &variables) { 11619dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11620b57cec5SDimitry Andric using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName( 11650b57cec5SDimitry Andric name.GetStringRef(), m_index->symrecords()); 11660b57cec5SDimitry Andric for (const SymbolAndOffset &result : results) { 11670b57cec5SDimitry Andric VariableSP var; 11680b57cec5SDimitry Andric switch (result.second.kind()) { 11690b57cec5SDimitry Andric case SymbolKind::S_GDATA32: 11700b57cec5SDimitry Andric case SymbolKind::S_LDATA32: 11710b57cec5SDimitry Andric case SymbolKind::S_GTHREAD32: 11720b57cec5SDimitry Andric case SymbolKind::S_LTHREAD32: 11730b57cec5SDimitry Andric case SymbolKind::S_CONSTANT: { 11740b57cec5SDimitry Andric PdbGlobalSymId global(result.first, false); 11750b57cec5SDimitry Andric var = GetOrCreateGlobalVariable(global); 11760b57cec5SDimitry Andric variables.AddVariable(var); 11770b57cec5SDimitry Andric break; 11780b57cec5SDimitry Andric } 11790b57cec5SDimitry Andric default: 11800b57cec5SDimitry Andric continue; 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric } 11830b57cec5SDimitry Andric } 11840b57cec5SDimitry Andric 11859dba64beSDimitry Andric void SymbolFileNativePDB::FindFunctions( 11865ffd83dbSDimitry Andric ConstString name, const CompilerDeclContext &parent_decl_ctx, 11879dba64beSDimitry Andric FunctionNameType name_type_mask, bool include_inlines, 11880b57cec5SDimitry Andric SymbolContextList &sc_list) { 11899dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11900b57cec5SDimitry Andric // For now we only support lookup by method name. 11910b57cec5SDimitry Andric if (!(name_type_mask & eFunctionNameTypeMethod)) 11929dba64beSDimitry Andric return; 11930b57cec5SDimitry Andric 11940b57cec5SDimitry Andric using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName( 11970b57cec5SDimitry Andric name.GetStringRef(), m_index->symrecords()); 11980b57cec5SDimitry Andric for (const SymbolAndOffset &match : matches) { 11990b57cec5SDimitry Andric if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF) 12000b57cec5SDimitry Andric continue; 12010b57cec5SDimitry Andric ProcRefSym proc(match.second.kind()); 12020b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc)); 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric if (!IsValidRecord(proc)) 12050b57cec5SDimitry Andric continue; 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andric CompilandIndexItem &cci = 12080b57cec5SDimitry Andric m_index->compilands().GetOrCreateCompiland(proc.modi()); 12090b57cec5SDimitry Andric SymbolContext sc; 12100b57cec5SDimitry Andric 12110b57cec5SDimitry Andric sc.comp_unit = GetOrCreateCompileUnit(cci).get(); 12120b57cec5SDimitry Andric PdbCompilandSymId func_id(proc.modi(), proc.SymOffset); 12130b57cec5SDimitry Andric sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get(); 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric sc_list.Append(sc); 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric } 12180b57cec5SDimitry Andric 12199dba64beSDimitry Andric void SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, 12209dba64beSDimitry Andric bool include_inlines, 12219dba64beSDimitry Andric SymbolContextList &sc_list) {} 12220b57cec5SDimitry Andric 12239dba64beSDimitry Andric void SymbolFileNativePDB::FindTypes( 12245ffd83dbSDimitry Andric ConstString name, const CompilerDeclContext &parent_decl_ctx, 12259dba64beSDimitry Andric uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, 12269dba64beSDimitry Andric TypeMap &types) { 12279dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 12280b57cec5SDimitry Andric if (!name) 12299dba64beSDimitry Andric return; 12300b57cec5SDimitry Andric 12310b57cec5SDimitry Andric searched_symbol_files.clear(); 12320b57cec5SDimitry Andric searched_symbol_files.insert(this); 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andric // There is an assumption 'name' is not a regex 12359dba64beSDimitry Andric FindTypesByName(name.GetStringRef(), max_matches, types); 12360b57cec5SDimitry Andric } 12370b57cec5SDimitry Andric 1238480093f4SDimitry Andric void SymbolFileNativePDB::FindTypes( 1239480093f4SDimitry Andric llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, 1240480093f4SDimitry Andric llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {} 12410b57cec5SDimitry Andric 12429dba64beSDimitry Andric void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name, 12430b57cec5SDimitry Andric uint32_t max_matches, 12440b57cec5SDimitry Andric TypeMap &types) { 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andric std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name); 12470b57cec5SDimitry Andric if (max_matches > 0 && max_matches < matches.size()) 12480b57cec5SDimitry Andric matches.resize(max_matches); 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric for (TypeIndex ti : matches) { 12510b57cec5SDimitry Andric TypeSP type = GetOrCreateType(ti); 12520b57cec5SDimitry Andric if (!type) 12530b57cec5SDimitry Andric continue; 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andric types.Insert(type); 12560b57cec5SDimitry Andric } 12570b57cec5SDimitry Andric } 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) { 12609dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 12610b57cec5SDimitry Andric // Only do the full type scan the first time. 12620b57cec5SDimitry Andric if (m_done_full_type_scan) 12630b57cec5SDimitry Andric return 0; 12640b57cec5SDimitry Andric 12659dba64beSDimitry Andric const size_t old_count = GetTypeList().GetSize(); 12660b57cec5SDimitry Andric LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric // First process the entire TPI stream. 12690b57cec5SDimitry Andric for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { 12700b57cec5SDimitry Andric TypeSP type = GetOrCreateType(*ti); 12710b57cec5SDimitry Andric if (type) 12720b57cec5SDimitry Andric (void)type->GetFullCompilerType(); 12730b57cec5SDimitry Andric } 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric // Next look for S_UDT records in the globals stream. 12760b57cec5SDimitry Andric for (const uint32_t gid : m_index->globals().getGlobalsTable()) { 12770b57cec5SDimitry Andric PdbGlobalSymId global{gid, false}; 12780b57cec5SDimitry Andric CVSymbol sym = m_index->ReadSymbolRecord(global); 12790b57cec5SDimitry Andric if (sym.kind() != S_UDT) 12800b57cec5SDimitry Andric continue; 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); 12830b57cec5SDimitry Andric bool is_typedef = true; 12840b57cec5SDimitry Andric if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) { 12850b57cec5SDimitry Andric CVType cvt = m_index->tpi().getType(udt.Type); 12860b57cec5SDimitry Andric llvm::StringRef name = CVTagRecord::create(cvt).name(); 12870b57cec5SDimitry Andric if (name == udt.Name) 12880b57cec5SDimitry Andric is_typedef = false; 12890b57cec5SDimitry Andric } 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric if (is_typedef) 12920b57cec5SDimitry Andric GetOrCreateTypedef(global); 12930b57cec5SDimitry Andric } 12940b57cec5SDimitry Andric 12959dba64beSDimitry Andric const size_t new_count = GetTypeList().GetSize(); 12960b57cec5SDimitry Andric 12970b57cec5SDimitry Andric m_done_full_type_scan = true; 12980b57cec5SDimitry Andric 12990b57cec5SDimitry Andric return new_count - old_count; 13000b57cec5SDimitry Andric } 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric size_t 13030b57cec5SDimitry Andric SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit, 13040b57cec5SDimitry Andric VariableList &variables) { 13050b57cec5SDimitry Andric PdbSymUid sym_uid(comp_unit.GetID()); 13060b57cec5SDimitry Andric lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland); 13070b57cec5SDimitry Andric return 0; 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, 13110b57cec5SDimitry Andric PdbCompilandSymId var_id, 13120b57cec5SDimitry Andric bool is_param) { 13130b57cec5SDimitry Andric ModuleSP module = GetObjectFile()->GetModule(); 13140b57cec5SDimitry Andric Block &block = GetOrCreateBlock(scope_id); 13150b57cec5SDimitry Andric VariableInfo var_info = 13160b57cec5SDimitry Andric GetVariableLocationInfo(*m_index, var_id, block, module); 13170b57cec5SDimitry Andric if (!var_info.location || !var_info.ranges) 13180b57cec5SDimitry Andric return nullptr; 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi); 13210b57cec5SDimitry Andric CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii); 13220b57cec5SDimitry Andric TypeSP type_sp = GetOrCreateType(var_info.type); 13230b57cec5SDimitry Andric std::string name = var_info.name.str(); 13240b57cec5SDimitry Andric Declaration decl; 13250b57cec5SDimitry Andric SymbolFileTypeSP sftype = 13260b57cec5SDimitry Andric std::make_shared<SymbolFileType>(*this, type_sp->GetID()); 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric ValueType var_scope = 13290b57cec5SDimitry Andric is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal; 1330e8d8bef9SDimitry Andric bool external = false; 1331e8d8bef9SDimitry Andric bool artificial = false; 1332e8d8bef9SDimitry Andric bool location_is_constant_data = false; 1333e8d8bef9SDimitry Andric bool static_member = false; 13340b57cec5SDimitry Andric VariableSP var_sp = std::make_shared<Variable>( 13350b57cec5SDimitry Andric toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, 1336e8d8bef9SDimitry Andric comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, external, 1337e8d8bef9SDimitry Andric artificial, location_is_constant_data, static_member); 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric if (!is_param) 13400b57cec5SDimitry Andric m_ast->GetOrCreateVariableDecl(scope_id, var_id); 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric m_local_variables[toOpaqueUid(var_id)] = var_sp; 13430b57cec5SDimitry Andric return var_sp; 13440b57cec5SDimitry Andric } 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable( 13470b57cec5SDimitry Andric PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) { 13480b57cec5SDimitry Andric auto iter = m_local_variables.find(toOpaqueUid(var_id)); 13490b57cec5SDimitry Andric if (iter != m_local_variables.end()) 13500b57cec5SDimitry Andric return iter->second; 13510b57cec5SDimitry Andric 13520b57cec5SDimitry Andric return CreateLocalVariable(scope_id, var_id, is_param); 13530b57cec5SDimitry Andric } 13540b57cec5SDimitry Andric 13550b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) { 13560b57cec5SDimitry Andric CVSymbol sym = m_index->ReadSymbolRecord(id); 13570b57cec5SDimitry Andric lldbassert(sym.kind() == SymbolKind::S_UDT); 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); 13600b57cec5SDimitry Andric 13610b57cec5SDimitry Andric TypeSP target_type = GetOrCreateType(udt.Type); 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric (void)m_ast->GetOrCreateTypedefDecl(id); 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric Declaration decl; 13660b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 1367e8d8bef9SDimitry Andric toOpaqueUid(id), this, ConstString(udt.Name), 1368e8d8bef9SDimitry Andric target_type->GetByteSize(nullptr), nullptr, target_type->GetID(), 1369e8d8bef9SDimitry Andric lldb_private::Type::eEncodingIsTypedefUID, decl, 1370e8d8bef9SDimitry Andric target_type->GetForwardCompilerType(), 1371480093f4SDimitry Andric lldb_private::Type::ResolveState::Forward); 13720b57cec5SDimitry Andric } 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) { 13750b57cec5SDimitry Andric auto iter = m_types.find(toOpaqueUid(id)); 13760b57cec5SDimitry Andric if (iter != m_types.end()) 13770b57cec5SDimitry Andric return iter->second; 13780b57cec5SDimitry Andric 13790b57cec5SDimitry Andric return CreateTypedef(id); 13800b57cec5SDimitry Andric } 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { 13830b57cec5SDimitry Andric Block &block = GetOrCreateBlock(block_id); 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric size_t count = 0; 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 13880b57cec5SDimitry Andric CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 13890b57cec5SDimitry Andric uint32_t params_remaining = 0; 13900b57cec5SDimitry Andric switch (sym.kind()) { 13910b57cec5SDimitry Andric case S_GPROC32: 13920b57cec5SDimitry Andric case S_LPROC32: { 13930b57cec5SDimitry Andric ProcSym proc(static_cast<SymbolRecordKind>(sym.kind())); 13940b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)); 13950b57cec5SDimitry Andric CVType signature = m_index->tpi().getType(proc.FunctionType); 13960b57cec5SDimitry Andric ProcedureRecord sig; 13970b57cec5SDimitry Andric cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(signature, sig)); 13980b57cec5SDimitry Andric params_remaining = sig.getParameterCount(); 13990b57cec5SDimitry Andric break; 14000b57cec5SDimitry Andric } 14010b57cec5SDimitry Andric case S_BLOCK32: 14020b57cec5SDimitry Andric break; 14030b57cec5SDimitry Andric default: 14040b57cec5SDimitry Andric lldbassert(false && "Symbol is not a block!"); 14050b57cec5SDimitry Andric return 0; 14060b57cec5SDimitry Andric } 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric VariableListSP variables = block.GetBlockVariableList(false); 14090b57cec5SDimitry Andric if (!variables) { 14100b57cec5SDimitry Andric variables = std::make_shared<VariableList>(); 14110b57cec5SDimitry Andric block.SetVariableList(variables); 14120b57cec5SDimitry Andric } 14130b57cec5SDimitry Andric 14140b57cec5SDimitry Andric CVSymbolArray syms = limitSymbolArrayToScope( 14150b57cec5SDimitry Andric cii->m_debug_stream.getSymbolArray(), block_id.offset); 14160b57cec5SDimitry Andric 14170b57cec5SDimitry Andric // Skip the first record since it's a PROC32 or BLOCK32, and there's 14180b57cec5SDimitry Andric // no point examining it since we know it's not a local variable. 14190b57cec5SDimitry Andric syms.drop_front(); 14200b57cec5SDimitry Andric auto iter = syms.begin(); 14210b57cec5SDimitry Andric auto end = syms.end(); 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric while (iter != end) { 14240b57cec5SDimitry Andric uint32_t record_offset = iter.offset(); 14250b57cec5SDimitry Andric CVSymbol variable_cvs = *iter; 14260b57cec5SDimitry Andric PdbCompilandSymId child_sym_id(block_id.modi, record_offset); 14270b57cec5SDimitry Andric ++iter; 14280b57cec5SDimitry Andric 14290b57cec5SDimitry Andric // If this is a block, recurse into its children and then skip it. 14300b57cec5SDimitry Andric if (variable_cvs.kind() == S_BLOCK32) { 14310b57cec5SDimitry Andric uint32_t block_end = getScopeEndOffset(variable_cvs); 14320b57cec5SDimitry Andric count += ParseVariablesForBlock(child_sym_id); 14330b57cec5SDimitry Andric iter = syms.at(block_end); 14340b57cec5SDimitry Andric continue; 14350b57cec5SDimitry Andric } 14360b57cec5SDimitry Andric 14370b57cec5SDimitry Andric bool is_param = params_remaining > 0; 14380b57cec5SDimitry Andric VariableSP variable; 14390b57cec5SDimitry Andric switch (variable_cvs.kind()) { 14400b57cec5SDimitry Andric case S_REGREL32: 14410b57cec5SDimitry Andric case S_REGISTER: 14420b57cec5SDimitry Andric case S_LOCAL: 14430b57cec5SDimitry Andric variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param); 14440b57cec5SDimitry Andric if (is_param) 14450b57cec5SDimitry Andric --params_remaining; 14460b57cec5SDimitry Andric if (variable) 14470b57cec5SDimitry Andric variables->AddVariableIfUnique(variable); 14480b57cec5SDimitry Andric break; 14490b57cec5SDimitry Andric default: 14500b57cec5SDimitry Andric break; 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric } 14530b57cec5SDimitry Andric 14540b57cec5SDimitry Andric // Pass false for set_children, since we call this recursively so that the 14550b57cec5SDimitry Andric // children will call this for themselves. 14560b57cec5SDimitry Andric block.SetDidParseVariables(true, false); 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andric return count; 14590b57cec5SDimitry Andric } 14600b57cec5SDimitry Andric 14610b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) { 14629dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 14630b57cec5SDimitry Andric lldbassert(sc.function || sc.comp_unit); 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andric VariableListSP variables; 14660b57cec5SDimitry Andric if (sc.block) { 14670b57cec5SDimitry Andric PdbSymUid block_id(sc.block->GetID()); 14680b57cec5SDimitry Andric 14690b57cec5SDimitry Andric size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 14700b57cec5SDimitry Andric return count; 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andric if (sc.function) { 14740b57cec5SDimitry Andric PdbSymUid block_id(sc.function->GetID()); 14750b57cec5SDimitry Andric 14760b57cec5SDimitry Andric size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 14770b57cec5SDimitry Andric return count; 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric if (sc.comp_unit) { 14810b57cec5SDimitry Andric variables = sc.comp_unit->GetVariableList(false); 14820b57cec5SDimitry Andric if (!variables) { 14830b57cec5SDimitry Andric variables = std::make_shared<VariableList>(); 14840b57cec5SDimitry Andric sc.comp_unit->SetVariableList(variables); 14850b57cec5SDimitry Andric } 14860b57cec5SDimitry Andric return ParseVariablesForCompileUnit(*sc.comp_unit, *variables); 14870b57cec5SDimitry Andric } 14880b57cec5SDimitry Andric 14890b57cec5SDimitry Andric llvm_unreachable("Unreachable!"); 14900b57cec5SDimitry Andric } 14910b57cec5SDimitry Andric 14920b57cec5SDimitry Andric CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) { 14939dba64beSDimitry Andric if (auto decl = m_ast->GetOrCreateDeclForUid(uid)) 14949dba64beSDimitry Andric return decl.getValue(); 14959dba64beSDimitry Andric else 14969dba64beSDimitry Andric return CompilerDecl(); 14970b57cec5SDimitry Andric } 14980b57cec5SDimitry Andric 14990b57cec5SDimitry Andric CompilerDeclContext 15000b57cec5SDimitry Andric SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) { 15010b57cec5SDimitry Andric clang::DeclContext *context = 15020b57cec5SDimitry Andric m_ast->GetOrCreateDeclContextForUid(PdbSymUid(uid)); 15030b57cec5SDimitry Andric if (!context) 15040b57cec5SDimitry Andric return {}; 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andric return m_ast->ToCompilerDeclContext(*context); 15070b57cec5SDimitry Andric } 15080b57cec5SDimitry Andric 15090b57cec5SDimitry Andric CompilerDeclContext 15100b57cec5SDimitry Andric SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { 15110b57cec5SDimitry Andric clang::DeclContext *context = m_ast->GetParentDeclContext(PdbSymUid(uid)); 15120b57cec5SDimitry Andric return m_ast->ToCompilerDeclContext(*context); 15130b57cec5SDimitry Andric } 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andric Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) { 15169dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 15170b57cec5SDimitry Andric auto iter = m_types.find(type_uid); 15180b57cec5SDimitry Andric // lldb should not be passing us non-sensical type uids. the only way it 15190b57cec5SDimitry Andric // could have a type uid in the first place is if we handed it out, in which 15200b57cec5SDimitry Andric // case we should know about the type. However, that doesn't mean we've 15210b57cec5SDimitry Andric // instantiated it yet. We can vend out a UID for a future type. So if the 15220b57cec5SDimitry Andric // type doesn't exist, let's instantiate it now. 15230b57cec5SDimitry Andric if (iter != m_types.end()) 15240b57cec5SDimitry Andric return &*iter->second; 15250b57cec5SDimitry Andric 15260b57cec5SDimitry Andric PdbSymUid uid(type_uid); 15270b57cec5SDimitry Andric lldbassert(uid.kind() == PdbSymUidKind::Type); 15280b57cec5SDimitry Andric PdbTypeSymId type_id = uid.asTypeSym(); 15290b57cec5SDimitry Andric if (type_id.index.isNoneType()) 15300b57cec5SDimitry Andric return nullptr; 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andric TypeSP type_sp = CreateAndCacheType(type_id); 15330b57cec5SDimitry Andric return &*type_sp; 15340b57cec5SDimitry Andric } 15350b57cec5SDimitry Andric 15360b57cec5SDimitry Andric llvm::Optional<SymbolFile::ArrayInfo> 15370b57cec5SDimitry Andric SymbolFileNativePDB::GetDynamicArrayInfoForUID( 15380b57cec5SDimitry Andric lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 15390b57cec5SDimitry Andric return llvm::None; 15400b57cec5SDimitry Andric } 15410b57cec5SDimitry Andric 15420b57cec5SDimitry Andric 15430b57cec5SDimitry Andric bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { 15440b57cec5SDimitry Andric clang::QualType qt = 15450b57cec5SDimitry Andric clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType()); 15460b57cec5SDimitry Andric 15470b57cec5SDimitry Andric return m_ast->CompleteType(qt); 15480b57cec5SDimitry Andric } 15490b57cec5SDimitry Andric 15509dba64beSDimitry Andric void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, 15510b57cec5SDimitry Andric TypeClass type_mask, 15529dba64beSDimitry Andric lldb_private::TypeList &type_list) {} 15530b57cec5SDimitry Andric 15540b57cec5SDimitry Andric CompilerDeclContext 15550b57cec5SDimitry Andric SymbolFileNativePDB::FindNamespace(ConstString name, 15565ffd83dbSDimitry Andric const CompilerDeclContext &parent_decl_ctx) { 15570b57cec5SDimitry Andric return {}; 15580b57cec5SDimitry Andric } 15590b57cec5SDimitry Andric 15609dba64beSDimitry Andric llvm::Expected<TypeSystem &> 15610b57cec5SDimitry Andric SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { 15629dba64beSDimitry Andric auto type_system_or_err = 15639dba64beSDimitry Andric m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); 15649dba64beSDimitry Andric if (type_system_or_err) { 15659dba64beSDimitry Andric type_system_or_err->SetSymbolFile(this); 15669dba64beSDimitry Andric } 15679dba64beSDimitry Andric return type_system_or_err; 15680b57cec5SDimitry Andric } 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric ConstString SymbolFileNativePDB::GetPluginName() { 15710b57cec5SDimitry Andric static ConstString g_name("pdb"); 15720b57cec5SDimitry Andric return g_name; 15730b57cec5SDimitry Andric } 15740b57cec5SDimitry Andric 15750b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::GetPluginVersion() { return 1; } 1576