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 243349cc55cSDimitry Andric llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() { 2440b57cec5SDimitry Andric return "Microsoft PDB debug symbol cross-platform file reader."; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 2479dba64beSDimitry Andric SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) { 2489dba64beSDimitry Andric return new SymbolFileNativePDB(std::move(objfile_sp)); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2519dba64beSDimitry Andric SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp) 2529dba64beSDimitry Andric : SymbolFile(std::move(objfile_sp)) {} 2530b57cec5SDimitry Andric 254fe6060f1SDimitry Andric SymbolFileNativePDB::~SymbolFileNativePDB() = default; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::CalculateAbilities() { 2570b57cec5SDimitry Andric uint32_t abilities = 0; 2589dba64beSDimitry Andric if (!m_objfile_sp) 2590b57cec5SDimitry Andric return 0; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric if (!m_index) { 2620b57cec5SDimitry Andric // Lazily load and match the PDB file, but only do this once. 263e8d8bef9SDimitry Andric PDBFile *pdb_file; 264e8d8bef9SDimitry Andric if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) { 265e8d8bef9SDimitry Andric pdb_file = &pdb->GetPDBFile(); 266e8d8bef9SDimitry Andric } else { 267e8d8bef9SDimitry Andric m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), 268e8d8bef9SDimitry Andric m_allocator); 269e8d8bef9SDimitry Andric pdb_file = m_file_up.get(); 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 272e8d8bef9SDimitry Andric if (!pdb_file) 2730b57cec5SDimitry Andric return 0; 2740b57cec5SDimitry Andric 275e8d8bef9SDimitry Andric auto expected_index = PdbIndex::create(pdb_file); 2760b57cec5SDimitry Andric if (!expected_index) { 2770b57cec5SDimitry Andric llvm::consumeError(expected_index.takeError()); 2780b57cec5SDimitry Andric return 0; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric m_index = std::move(*expected_index); 2810b57cec5SDimitry Andric } 2820b57cec5SDimitry Andric if (!m_index) 2830b57cec5SDimitry Andric return 0; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric // We don't especially have to be precise here. We only distinguish between 2860b57cec5SDimitry Andric // stripped and not stripped. 2870b57cec5SDimitry Andric abilities = kAllAbilities; 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric if (m_index->dbi().isStripped()) 2900b57cec5SDimitry Andric abilities &= ~(Blocks | LocalVariables); 2910b57cec5SDimitry Andric return abilities; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric void SymbolFileNativePDB::InitializeObject() { 295e8d8bef9SDimitry Andric m_obj_load_address = m_objfile_sp->GetModule() 296e8d8bef9SDimitry Andric ->GetObjectFile() 297e8d8bef9SDimitry Andric ->GetBaseAddress() 298e8d8bef9SDimitry Andric .GetFileAddress(); 2990b57cec5SDimitry Andric m_index->SetLoadAddress(m_obj_load_address); 3000b57cec5SDimitry Andric m_index->ParseSectionContribs(); 3010b57cec5SDimitry Andric 3029dba64beSDimitry Andric auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage( 3030b57cec5SDimitry Andric lldb::eLanguageTypeC_plus_plus); 3049dba64beSDimitry Andric if (auto err = ts_or_err.takeError()) { 3059dba64beSDimitry Andric LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), 3069dba64beSDimitry Andric std::move(err), "Failed to initialize"); 3079dba64beSDimitry Andric } else { 3089dba64beSDimitry Andric ts_or_err->SetSymbolFile(this); 3095ffd83dbSDimitry Andric auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get()); 3109dba64beSDimitry Andric lldbassert(clang); 3119dba64beSDimitry Andric m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang); 3129dba64beSDimitry Andric } 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 3159dba64beSDimitry Andric uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() { 3160b57cec5SDimitry Andric const DbiModuleList &modules = m_index->dbi().modules(); 3170b57cec5SDimitry Andric uint32_t count = modules.getModuleCount(); 3180b57cec5SDimitry Andric if (count == 0) 3190b57cec5SDimitry Andric return count; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric // The linker can inject an additional "dummy" compilation unit into the 3220b57cec5SDimitry Andric // PDB. Ignore this special compile unit for our purposes, if it is there. 3230b57cec5SDimitry Andric // It is always the last one. 3240b57cec5SDimitry Andric DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1); 3250b57cec5SDimitry Andric if (last.getModuleName() == "* Linker *") 3260b57cec5SDimitry Andric --count; 3270b57cec5SDimitry Andric return count; 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { 3310b57cec5SDimitry Andric CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 3320b57cec5SDimitry Andric CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) { 3350b57cec5SDimitry Andric // This is a function. It must be global. Creating the Function entry for 3360b57cec5SDimitry Andric // it automatically creates a block for it. 3370b57cec5SDimitry Andric CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); 3380b57cec5SDimitry Andric return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric lldbassert(sym.kind() == S_BLOCK32); 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric // This is a block. Its parent is either a function or another block. In 3440b57cec5SDimitry Andric // either case, its parent can be viewed as a block (e.g. a function contains 3450b57cec5SDimitry Andric // 1 big block. So just get the parent block and add this block to it. 3460b57cec5SDimitry Andric BlockSym block(static_cast<SymbolRecordKind>(sym.kind())); 3470b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block)); 3480b57cec5SDimitry Andric lldbassert(block.Parent != 0); 3490b57cec5SDimitry Andric PdbCompilandSymId parent_id(block_id.modi, block.Parent); 3500b57cec5SDimitry Andric Block &parent_block = GetOrCreateBlock(parent_id); 3510b57cec5SDimitry Andric lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id); 3520b57cec5SDimitry Andric BlockSP child_block = std::make_shared<Block>(opaque_block_uid); 3530b57cec5SDimitry Andric parent_block.AddChild(child_block); 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric m_ast->GetOrCreateBlockDecl(block_id); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric m_blocks.insert({opaque_block_uid, child_block}); 3580b57cec5SDimitry Andric return *child_block; 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, 3620b57cec5SDimitry Andric CompileUnit &comp_unit) { 3630b57cec5SDimitry Andric const CompilandIndexItem *cci = 3640b57cec5SDimitry Andric m_index->compilands().GetCompiland(func_id.modi); 3650b57cec5SDimitry Andric lldbassert(cci); 3660b57cec5SDimitry Andric CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset); 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); 3690b57cec5SDimitry Andric SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric auto file_vm_addr = m_index->MakeVirtualAddress(sol.so); 3720b57cec5SDimitry Andric if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 3730b57cec5SDimitry Andric return nullptr; 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric AddressRange func_range(file_vm_addr, sol.length, 3760b57cec5SDimitry Andric comp_unit.GetModule()->GetSectionList()); 3770b57cec5SDimitry Andric if (!func_range.GetBaseAddress().IsValid()) 3780b57cec5SDimitry Andric return nullptr; 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind())); 3810b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)); 3820b57cec5SDimitry Andric if (proc.FunctionType == TypeIndex::None()) 3830b57cec5SDimitry Andric return nullptr; 3840b57cec5SDimitry Andric TypeSP func_type = GetOrCreateType(proc.FunctionType); 3850b57cec5SDimitry Andric if (!func_type) 3860b57cec5SDimitry Andric return nullptr; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric PdbTypeSymId sig_id(proc.FunctionType, false); 3890b57cec5SDimitry Andric Mangled mangled(proc.Name); 3900b57cec5SDimitry Andric FunctionSP func_sp = std::make_shared<Function>( 3910b57cec5SDimitry Andric &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled, 3920b57cec5SDimitry Andric func_type.get(), func_range); 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric comp_unit.AddFunction(func_sp); 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric m_ast->GetOrCreateFunctionDecl(func_id); 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric return func_sp; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric CompUnitSP 4020b57cec5SDimitry Andric SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { 4030b57cec5SDimitry Andric lldb::LanguageType lang = 4040b57cec5SDimitry Andric cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage()) 4050b57cec5SDimitry Andric : lldb::eLanguageTypeUnknown; 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric LazyBool optimized = eLazyBoolNo; 4080b57cec5SDimitry Andric if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations()) 4090b57cec5SDimitry Andric optimized = eLazyBoolYes; 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric llvm::SmallString<64> source_file_name = 4120b57cec5SDimitry Andric m_index->compilands().GetMainSourceFile(cci); 4130b57cec5SDimitry Andric FileSpec fs(source_file_name); 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric CompUnitSP cu_sp = 4169dba64beSDimitry Andric std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs, 4170b57cec5SDimitry Andric toOpaqueUid(cci.m_id), lang, optimized); 4180b57cec5SDimitry Andric 4199dba64beSDimitry Andric SetCompileUnitAtIndex(cci.m_id.modi, cu_sp); 4200b57cec5SDimitry Andric return cu_sp; 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, 4240b57cec5SDimitry Andric const ModifierRecord &mr, 4250b57cec5SDimitry Andric CompilerType ct) { 4260b57cec5SDimitry Andric TpiStream &stream = m_index->tpi(); 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric std::string name; 4290b57cec5SDimitry Andric if (mr.ModifiedType.isSimple()) 4305ffd83dbSDimitry Andric name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind())); 4310b57cec5SDimitry Andric else 4320b57cec5SDimitry Andric name = computeTypeName(stream.typeCollection(), mr.ModifiedType); 4330b57cec5SDimitry Andric Declaration decl; 4340b57cec5SDimitry Andric lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType); 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(name), 437e8d8bef9SDimitry Andric modified_type->GetByteSize(nullptr), nullptr, 4380b57cec5SDimitry Andric LLDB_INVALID_UID, Type::eEncodingIsUID, decl, 439480093f4SDimitry Andric ct, Type::ResolveState::Full); 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric lldb::TypeSP 4430b57cec5SDimitry Andric SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id, 4440b57cec5SDimitry Andric const llvm::codeview::PointerRecord &pr, 4450b57cec5SDimitry Andric CompilerType ct) { 4460b57cec5SDimitry Andric TypeSP pointee = GetOrCreateType(pr.ReferentType); 4470b57cec5SDimitry Andric if (!pointee) 4480b57cec5SDimitry Andric return nullptr; 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric if (pr.isPointerToMember()) { 4510b57cec5SDimitry Andric MemberPointerInfo mpi = pr.getMemberInfo(); 4520b57cec5SDimitry Andric GetOrCreateType(mpi.ContainingType); 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric Declaration decl; 4560b57cec5SDimitry Andric return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(), 4570b57cec5SDimitry Andric pr.getSize(), nullptr, LLDB_INVALID_UID, 4580b57cec5SDimitry Andric Type::eEncodingIsUID, decl, ct, 459480093f4SDimitry Andric Type::ResolveState::Full); 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti, 4630b57cec5SDimitry Andric CompilerType ct) { 4640b57cec5SDimitry Andric uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false)); 4650b57cec5SDimitry Andric if (ti == TypeIndex::NullptrT()) { 4660b57cec5SDimitry Andric Declaration decl; 4670b57cec5SDimitry Andric return std::make_shared<Type>( 4680b57cec5SDimitry Andric uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID, 469480093f4SDimitry Andric Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full); 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric if (ti.getSimpleMode() != SimpleTypeMode::Direct) { 4730b57cec5SDimitry Andric TypeSP direct_sp = GetOrCreateType(ti.makeDirect()); 4740b57cec5SDimitry Andric uint32_t pointer_size = 0; 4750b57cec5SDimitry Andric switch (ti.getSimpleMode()) { 4760b57cec5SDimitry Andric case SimpleTypeMode::FarPointer32: 4770b57cec5SDimitry Andric case SimpleTypeMode::NearPointer32: 4780b57cec5SDimitry Andric pointer_size = 4; 4790b57cec5SDimitry Andric break; 4800b57cec5SDimitry Andric case SimpleTypeMode::NearPointer64: 4810b57cec5SDimitry Andric pointer_size = 8; 4820b57cec5SDimitry Andric break; 4830b57cec5SDimitry Andric default: 4840b57cec5SDimitry Andric // 128-bit and 16-bit pointers unsupported. 4850b57cec5SDimitry Andric return nullptr; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric Declaration decl; 4880b57cec5SDimitry Andric return std::make_shared<Type>( 4890b57cec5SDimitry Andric uid, this, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID, 490480093f4SDimitry Andric Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full); 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) 4940b57cec5SDimitry Andric return nullptr; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind()); 4970b57cec5SDimitry Andric llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind()); 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric Declaration decl; 5000b57cec5SDimitry Andric return std::make_shared<Type>(uid, this, ConstString(type_name), size, 5010b57cec5SDimitry Andric nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, 502480093f4SDimitry Andric decl, ct, Type::ResolveState::Full); 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric static std::string GetUnqualifiedTypeName(const TagRecord &record) { 5060b57cec5SDimitry Andric if (!record.hasUniqueName()) { 5070b57cec5SDimitry Andric MSVCUndecoratedNameParser parser(record.Name); 5080b57cec5SDimitry Andric llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 5090b57cec5SDimitry Andric 5105ffd83dbSDimitry Andric return std::string(specs.back().GetBaseName()); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric llvm::ms_demangle::Demangler demangler; 5140b57cec5SDimitry Andric StringView sv(record.UniqueName.begin(), record.UniqueName.size()); 5150b57cec5SDimitry Andric llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); 5160b57cec5SDimitry Andric if (demangler.Error) 5175ffd83dbSDimitry Andric return std::string(record.Name); 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric llvm::ms_demangle::IdentifierNode *idn = 5200b57cec5SDimitry Andric ttn->QualifiedName->getUnqualifiedIdentifier(); 5210b57cec5SDimitry Andric return idn->toString(); 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric lldb::TypeSP 5250b57cec5SDimitry Andric SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id, 5260b57cec5SDimitry Andric const TagRecord &record, 5270b57cec5SDimitry Andric size_t size, CompilerType ct) { 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric std::string uname = GetUnqualifiedTypeName(record); 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE. 5320b57cec5SDimitry Andric Declaration decl; 5330b57cec5SDimitry Andric return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(uname), 5340b57cec5SDimitry Andric size, nullptr, LLDB_INVALID_UID, 5350b57cec5SDimitry Andric Type::eEncodingIsUID, decl, ct, 536480093f4SDimitry Andric Type::ResolveState::Forward); 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 5400b57cec5SDimitry Andric const ClassRecord &cr, 5410b57cec5SDimitry Andric CompilerType ct) { 5420b57cec5SDimitry Andric return CreateClassStructUnion(type_id, cr, cr.getSize(), ct); 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 5460b57cec5SDimitry Andric const UnionRecord &ur, 5470b57cec5SDimitry Andric CompilerType ct) { 5480b57cec5SDimitry Andric return CreateClassStructUnion(type_id, ur, ur.getSize(), ct); 5490b57cec5SDimitry Andric } 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 5520b57cec5SDimitry Andric const EnumRecord &er, 5530b57cec5SDimitry Andric CompilerType ct) { 5540b57cec5SDimitry Andric std::string uname = GetUnqualifiedTypeName(er); 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric Declaration decl; 5570b57cec5SDimitry Andric TypeSP underlying_type = GetOrCreateType(er.UnderlyingType); 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 5600b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(uname), 561e8d8bef9SDimitry Andric underlying_type->GetByteSize(nullptr), nullptr, LLDB_INVALID_UID, 5620b57cec5SDimitry Andric lldb_private::Type::eEncodingIsUID, decl, ct, 563480093f4SDimitry Andric lldb_private::Type::ResolveState::Forward); 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id, 5670b57cec5SDimitry Andric const ArrayRecord &ar, 5680b57cec5SDimitry Andric CompilerType ct) { 5690b57cec5SDimitry Andric TypeSP element_type = GetOrCreateType(ar.ElementType); 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric Declaration decl; 5720b57cec5SDimitry Andric TypeSP array_sp = std::make_shared<lldb_private::Type>( 5730b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(), ar.Size, nullptr, 5740b57cec5SDimitry Andric LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct, 575480093f4SDimitry Andric lldb_private::Type::ResolveState::Full); 5760b57cec5SDimitry Andric array_sp->SetEncodingType(element_type.get()); 5770b57cec5SDimitry Andric return array_sp; 5780b57cec5SDimitry Andric } 5790b57cec5SDimitry Andric 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id, 5820b57cec5SDimitry Andric const MemberFunctionRecord &mfr, 5830b57cec5SDimitry Andric CompilerType ct) { 5840b57cec5SDimitry Andric Declaration decl; 5850b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 5860b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, 5870b57cec5SDimitry Andric lldb_private::Type::eEncodingIsUID, decl, ct, 588480093f4SDimitry Andric lldb_private::Type::ResolveState::Full); 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, 5920b57cec5SDimitry Andric const ProcedureRecord &pr, 5930b57cec5SDimitry Andric CompilerType ct) { 5940b57cec5SDimitry Andric Declaration decl; 5950b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 5960b57cec5SDimitry Andric toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, 5970b57cec5SDimitry Andric lldb_private::Type::eEncodingIsUID, decl, ct, 598480093f4SDimitry Andric lldb_private::Type::ResolveState::Full); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { 6020b57cec5SDimitry Andric if (type_id.index.isSimple()) 6030b57cec5SDimitry Andric return CreateSimpleType(type_id.index, ct); 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andric TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi(); 6060b57cec5SDimitry Andric CVType cvt = stream.getType(type_id.index); 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric if (cvt.kind() == LF_MODIFIER) { 6090b57cec5SDimitry Andric ModifierRecord modifier; 6100b57cec5SDimitry Andric llvm::cantFail( 6110b57cec5SDimitry Andric TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)); 6120b57cec5SDimitry Andric return CreateModifierType(type_id, modifier, ct); 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric if (cvt.kind() == LF_POINTER) { 6160b57cec5SDimitry Andric PointerRecord pointer; 6170b57cec5SDimitry Andric llvm::cantFail( 6180b57cec5SDimitry Andric TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)); 6190b57cec5SDimitry Andric return CreatePointerType(type_id, pointer, ct); 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric if (IsClassRecord(cvt.kind())) { 6230b57cec5SDimitry Andric ClassRecord cr; 6240b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 6250b57cec5SDimitry Andric return CreateTagType(type_id, cr, ct); 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric if (cvt.kind() == LF_ENUM) { 6290b57cec5SDimitry Andric EnumRecord er; 6300b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 6310b57cec5SDimitry Andric return CreateTagType(type_id, er, ct); 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric if (cvt.kind() == LF_UNION) { 6350b57cec5SDimitry Andric UnionRecord ur; 6360b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 6370b57cec5SDimitry Andric return CreateTagType(type_id, ur, ct); 6380b57cec5SDimitry Andric } 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric if (cvt.kind() == LF_ARRAY) { 6410b57cec5SDimitry Andric ArrayRecord ar; 6420b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)); 6430b57cec5SDimitry Andric return CreateArrayType(type_id, ar, ct); 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric if (cvt.kind() == LF_PROCEDURE) { 6470b57cec5SDimitry Andric ProcedureRecord pr; 6480b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)); 6490b57cec5SDimitry Andric return CreateProcedureType(type_id, pr, ct); 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric if (cvt.kind() == LF_MFUNCTION) { 6520b57cec5SDimitry Andric MemberFunctionRecord mfr; 6530b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)); 6540b57cec5SDimitry Andric return CreateFunctionType(type_id, mfr, ct); 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric return nullptr; 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { 6610b57cec5SDimitry Andric // If they search for a UDT which is a forward ref, try and resolve the full 6620b57cec5SDimitry Andric // decl and just map the forward ref uid to the full decl record. 6630b57cec5SDimitry Andric llvm::Optional<PdbTypeSymId> full_decl_uid; 6640b57cec5SDimitry Andric if (IsForwardRefUdt(type_id, m_index->tpi())) { 6650b57cec5SDimitry Andric auto expected_full_ti = 6660b57cec5SDimitry Andric m_index->tpi().findFullDeclForForwardRef(type_id.index); 6670b57cec5SDimitry Andric if (!expected_full_ti) 6680b57cec5SDimitry Andric llvm::consumeError(expected_full_ti.takeError()); 6690b57cec5SDimitry Andric else if (*expected_full_ti != type_id.index) { 6700b57cec5SDimitry Andric full_decl_uid = PdbTypeSymId(*expected_full_ti, false); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric // It's possible that a lookup would occur for the full decl causing it 6730b57cec5SDimitry Andric // to be cached, then a second lookup would occur for the forward decl. 6740b57cec5SDimitry Andric // We don't want to create a second full decl, so make sure the full 6750b57cec5SDimitry Andric // decl hasn't already been cached. 6760b57cec5SDimitry Andric auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid)); 6770b57cec5SDimitry Andric if (full_iter != m_types.end()) { 6780b57cec5SDimitry Andric TypeSP result = full_iter->second; 6790b57cec5SDimitry Andric // Map the forward decl to the TypeSP for the full decl so we can take 6800b57cec5SDimitry Andric // the fast path next time. 6810b57cec5SDimitry Andric m_types[toOpaqueUid(type_id)] = result; 6820b57cec5SDimitry Andric return result; 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric } 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric clang::QualType qt = m_ast->GetOrCreateType(best_decl_id); 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt)); 6920b57cec5SDimitry Andric if (!result) 6930b57cec5SDimitry Andric return nullptr; 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric uint64_t best_uid = toOpaqueUid(best_decl_id); 6960b57cec5SDimitry Andric m_types[best_uid] = result; 6970b57cec5SDimitry Andric // If we had both a forward decl and a full decl, make both point to the new 6980b57cec5SDimitry Andric // type. 6990b57cec5SDimitry Andric if (full_decl_uid) 7000b57cec5SDimitry Andric m_types[toOpaqueUid(type_id)] = result; 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric return result; 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) { 7060b57cec5SDimitry Andric // We can't use try_emplace / overwrite here because the process of creating 7070b57cec5SDimitry Andric // a type could create nested types, which could invalidate iterators. So 7080b57cec5SDimitry Andric // we have to do a 2-phase lookup / insert. 7090b57cec5SDimitry Andric auto iter = m_types.find(toOpaqueUid(type_id)); 7100b57cec5SDimitry Andric if (iter != m_types.end()) 7110b57cec5SDimitry Andric return iter->second; 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric TypeSP type = CreateAndCacheType(type_id); 7140b57cec5SDimitry Andric if (type) 7159dba64beSDimitry Andric GetTypeList().Insert(type); 7160b57cec5SDimitry Andric return type; 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { 7200b57cec5SDimitry Andric CVSymbol sym = m_index->symrecords().readRecord(var_id.offset); 7210b57cec5SDimitry Andric if (sym.kind() == S_CONSTANT) 7220b57cec5SDimitry Andric return CreateConstantSymbol(var_id, sym); 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric lldb::ValueType scope = eValueTypeInvalid; 7250b57cec5SDimitry Andric TypeIndex ti; 7260b57cec5SDimitry Andric llvm::StringRef name; 7270b57cec5SDimitry Andric lldb::addr_t addr = 0; 7280b57cec5SDimitry Andric uint16_t section = 0; 7290b57cec5SDimitry Andric uint32_t offset = 0; 7300b57cec5SDimitry Andric bool is_external = false; 7310b57cec5SDimitry Andric switch (sym.kind()) { 7320b57cec5SDimitry Andric case S_GDATA32: 7330b57cec5SDimitry Andric is_external = true; 7340b57cec5SDimitry Andric LLVM_FALLTHROUGH; 7350b57cec5SDimitry Andric case S_LDATA32: { 7360b57cec5SDimitry Andric DataSym ds(sym.kind()); 7370b57cec5SDimitry Andric llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds)); 7380b57cec5SDimitry Andric ti = ds.Type; 7390b57cec5SDimitry Andric scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal 7400b57cec5SDimitry Andric : eValueTypeVariableStatic; 7410b57cec5SDimitry Andric name = ds.Name; 7420b57cec5SDimitry Andric section = ds.Segment; 7430b57cec5SDimitry Andric offset = ds.DataOffset; 7440b57cec5SDimitry Andric addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset); 7450b57cec5SDimitry Andric break; 7460b57cec5SDimitry Andric } 7470b57cec5SDimitry Andric case S_GTHREAD32: 7480b57cec5SDimitry Andric is_external = true; 7490b57cec5SDimitry Andric LLVM_FALLTHROUGH; 7500b57cec5SDimitry Andric case S_LTHREAD32: { 7510b57cec5SDimitry Andric ThreadLocalDataSym tlds(sym.kind()); 7520b57cec5SDimitry Andric llvm::cantFail( 7530b57cec5SDimitry Andric SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)); 7540b57cec5SDimitry Andric ti = tlds.Type; 7550b57cec5SDimitry Andric name = tlds.Name; 7560b57cec5SDimitry Andric section = tlds.Segment; 7570b57cec5SDimitry Andric offset = tlds.DataOffset; 7580b57cec5SDimitry Andric addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset); 7590b57cec5SDimitry Andric scope = eValueTypeVariableThreadLocal; 7600b57cec5SDimitry Andric break; 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric default: 7630b57cec5SDimitry Andric llvm_unreachable("unreachable!"); 7640b57cec5SDimitry Andric } 7650b57cec5SDimitry Andric 7660b57cec5SDimitry Andric CompUnitSP comp_unit; 7670b57cec5SDimitry Andric llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr); 7680b57cec5SDimitry Andric if (modi) { 7690b57cec5SDimitry Andric CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); 7700b57cec5SDimitry Andric comp_unit = GetOrCreateCompileUnit(cci); 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric Declaration decl; 7740b57cec5SDimitry Andric PdbTypeSymId tid(ti, false); 7750b57cec5SDimitry Andric SymbolFileTypeSP type_sp = 7760b57cec5SDimitry Andric std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 7770b57cec5SDimitry Andric Variable::RangeList ranges; 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric m_ast->GetOrCreateVariableDecl(var_id); 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric DWARFExpression location = MakeGlobalLocationExpression( 7820b57cec5SDimitry Andric section, offset, GetObjectFile()->GetModule()); 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric std::string global_name("::"); 7850b57cec5SDimitry Andric global_name += name; 786e8d8bef9SDimitry Andric bool artificial = false; 787e8d8bef9SDimitry Andric bool location_is_constant_data = false; 788e8d8bef9SDimitry Andric bool static_member = false; 7890b57cec5SDimitry Andric VariableSP var_sp = std::make_shared<Variable>( 7900b57cec5SDimitry Andric toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, 791e8d8bef9SDimitry Andric scope, comp_unit.get(), ranges, &decl, location, is_external, artificial, 792e8d8bef9SDimitry Andric location_is_constant_data, static_member); 7930b57cec5SDimitry Andric 7940b57cec5SDimitry Andric return var_sp; 7950b57cec5SDimitry Andric } 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric lldb::VariableSP 7980b57cec5SDimitry Andric SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, 7990b57cec5SDimitry Andric const CVSymbol &cvs) { 8000b57cec5SDimitry Andric TpiStream &tpi = m_index->tpi(); 8010b57cec5SDimitry Andric ConstantSym constant(cvs.kind()); 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)); 8040b57cec5SDimitry Andric std::string global_name("::"); 8050b57cec5SDimitry Andric global_name += constant.Name; 8060b57cec5SDimitry Andric PdbTypeSymId tid(constant.Type, false); 8070b57cec5SDimitry Andric SymbolFileTypeSP type_sp = 8080b57cec5SDimitry Andric std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric Declaration decl; 8110b57cec5SDimitry Andric Variable::RangeList ranges; 8120b57cec5SDimitry Andric ModuleSP module = GetObjectFile()->GetModule(); 8130b57cec5SDimitry Andric DWARFExpression location = MakeConstantLocationExpression( 8140b57cec5SDimitry Andric constant.Type, tpi, constant.Value, module); 8150b57cec5SDimitry Andric 816e8d8bef9SDimitry Andric bool external = false; 817e8d8bef9SDimitry Andric bool artificial = false; 818e8d8bef9SDimitry Andric bool location_is_constant_data = true; 819e8d8bef9SDimitry Andric bool static_member = false; 8200b57cec5SDimitry Andric VariableSP var_sp = std::make_shared<Variable>( 8210b57cec5SDimitry Andric toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), 8220b57cec5SDimitry Andric type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, 823e8d8bef9SDimitry Andric external, artificial, location_is_constant_data, static_member); 8240b57cec5SDimitry Andric return var_sp; 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric VariableSP 8280b57cec5SDimitry Andric SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { 8290b57cec5SDimitry Andric auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); 8300b57cec5SDimitry Andric if (emplace_result.second) 8310b57cec5SDimitry Andric emplace_result.first->second = CreateGlobalVariable(var_id); 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric return emplace_result.first->second; 8340b57cec5SDimitry Andric } 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) { 8370b57cec5SDimitry Andric return GetOrCreateType(PdbTypeSymId(ti, false)); 8380b57cec5SDimitry Andric } 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id, 8410b57cec5SDimitry Andric CompileUnit &comp_unit) { 8420b57cec5SDimitry Andric auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr); 8430b57cec5SDimitry Andric if (emplace_result.second) 8440b57cec5SDimitry Andric emplace_result.first->second = CreateFunction(func_id, comp_unit); 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric return emplace_result.first->second; 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric CompUnitSP 8500b57cec5SDimitry Andric SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) { 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric auto emplace_result = 8530b57cec5SDimitry Andric m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr); 8540b57cec5SDimitry Andric if (emplace_result.second) 8550b57cec5SDimitry Andric emplace_result.first->second = CreateCompileUnit(cci); 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric lldbassert(emplace_result.first->second); 8580b57cec5SDimitry Andric return emplace_result.first->second; 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) { 8620b57cec5SDimitry Andric auto iter = m_blocks.find(toOpaqueUid(block_id)); 8630b57cec5SDimitry Andric if (iter != m_blocks.end()) 8640b57cec5SDimitry Andric return *iter->second; 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andric return CreateBlock(block_id); 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric void SymbolFileNativePDB::ParseDeclsForContext( 8700b57cec5SDimitry Andric lldb_private::CompilerDeclContext decl_ctx) { 8710b57cec5SDimitry Andric clang::DeclContext *context = m_ast->FromCompilerDeclContext(decl_ctx); 8720b57cec5SDimitry Andric if (!context) 8730b57cec5SDimitry Andric return; 8740b57cec5SDimitry Andric m_ast->ParseDeclsForContext(*context); 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric 8770b57cec5SDimitry Andric lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) { 8780b57cec5SDimitry Andric if (index >= GetNumCompileUnits()) 8790b57cec5SDimitry Andric return CompUnitSP(); 8800b57cec5SDimitry Andric lldbassert(index < UINT16_MAX); 8810b57cec5SDimitry Andric if (index >= UINT16_MAX) 8820b57cec5SDimitry Andric return nullptr; 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index); 8850b57cec5SDimitry Andric 8860b57cec5SDimitry Andric return GetOrCreateCompileUnit(item); 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) { 8909dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 8910b57cec5SDimitry Andric PdbSymUid uid(comp_unit.GetID()); 8920b57cec5SDimitry Andric lldbassert(uid.kind() == PdbSymUidKind::Compiland); 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric CompilandIndexItem *item = 8950b57cec5SDimitry Andric m_index->compilands().GetCompiland(uid.asCompiland().modi); 8960b57cec5SDimitry Andric lldbassert(item); 8970b57cec5SDimitry Andric if (!item->m_compile_opts) 8980b57cec5SDimitry Andric return lldb::eLanguageTypeUnknown; 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric return TranslateLanguage(item->m_compile_opts->getLanguage()); 9010b57cec5SDimitry Andric } 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; } 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) { 9069dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 9070b57cec5SDimitry Andric PdbSymUid uid{comp_unit.GetID()}; 9080b57cec5SDimitry Andric lldbassert(uid.kind() == PdbSymUidKind::Compiland); 9090b57cec5SDimitry Andric uint16_t modi = uid.asCompiland().modi; 9100b57cec5SDimitry Andric CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi); 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andric size_t count = comp_unit.GetNumFunctions(); 9130b57cec5SDimitry Andric const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray(); 9140b57cec5SDimitry Andric for (auto iter = syms.begin(); iter != syms.end(); ++iter) { 9150b57cec5SDimitry Andric if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) 9160b57cec5SDimitry Andric continue; 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric PdbCompilandSymId sym_id{modi, iter.offset()}; 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric FunctionSP func = GetOrCreateFunction(sym_id, comp_unit); 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric size_t new_count = comp_unit.GetNumFunctions(); 9240b57cec5SDimitry Andric lldbassert(new_count >= count); 9250b57cec5SDimitry Andric return new_count - count; 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) { 9290b57cec5SDimitry Andric // If any of these flags are set, we need to resolve the compile unit. 9300b57cec5SDimitry Andric uint32_t flags = eSymbolContextCompUnit; 9310b57cec5SDimitry Andric flags |= eSymbolContextVariable; 9320b57cec5SDimitry Andric flags |= eSymbolContextFunction; 9330b57cec5SDimitry Andric flags |= eSymbolContextBlock; 9340b57cec5SDimitry Andric flags |= eSymbolContextLineEntry; 9350b57cec5SDimitry Andric return (resolve_scope & flags) != 0; 9360b57cec5SDimitry Andric } 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::ResolveSymbolContext( 9390b57cec5SDimitry Andric const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) { 9409dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 9410b57cec5SDimitry Andric uint32_t resolved_flags = 0; 9420b57cec5SDimitry Andric lldb::addr_t file_addr = addr.GetFileAddress(); 9430b57cec5SDimitry Andric 9440b57cec5SDimitry Andric if (NeedsResolvedCompileUnit(resolve_scope)) { 9450b57cec5SDimitry Andric llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr); 9460b57cec5SDimitry Andric if (!modi) 9470b57cec5SDimitry Andric return 0; 948349cc55cSDimitry Andric CompUnitSP cu_sp = GetCompileUnitAtIndex(modi.getValue()); 949349cc55cSDimitry Andric if (!cu_sp) 9500b57cec5SDimitry Andric return 0; 9510b57cec5SDimitry Andric 952349cc55cSDimitry Andric sc.comp_unit = cu_sp.get(); 9530b57cec5SDimitry Andric resolved_flags |= eSymbolContextCompUnit; 9540b57cec5SDimitry Andric } 9550b57cec5SDimitry Andric 9560b57cec5SDimitry Andric if (resolve_scope & eSymbolContextFunction || 9570b57cec5SDimitry Andric resolve_scope & eSymbolContextBlock) { 9580b57cec5SDimitry Andric lldbassert(sc.comp_unit); 9590b57cec5SDimitry Andric std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr); 9600b57cec5SDimitry Andric // Search the matches in reverse. This way if there are multiple matches 9610b57cec5SDimitry Andric // (for example we are 3 levels deep in a nested scope) it will find the 9620b57cec5SDimitry Andric // innermost one first. 9630b57cec5SDimitry Andric for (const auto &match : llvm::reverse(matches)) { 9640b57cec5SDimitry Andric if (match.uid.kind() != PdbSymUidKind::CompilandSym) 9650b57cec5SDimitry Andric continue; 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric PdbCompilandSymId csid = match.uid.asCompilandSym(); 9680b57cec5SDimitry Andric CVSymbol cvs = m_index->ReadSymbolRecord(csid); 9690b57cec5SDimitry Andric PDB_SymType type = CVSymToPDBSym(cvs.kind()); 9700b57cec5SDimitry Andric if (type != PDB_SymType::Function && type != PDB_SymType::Block) 9710b57cec5SDimitry Andric continue; 9720b57cec5SDimitry Andric if (type == PDB_SymType::Function) { 9730b57cec5SDimitry Andric sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get(); 9740b57cec5SDimitry Andric sc.block = sc.GetFunctionBlock(); 9750b57cec5SDimitry Andric } 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric if (type == PDB_SymType::Block) { 9780b57cec5SDimitry Andric sc.block = &GetOrCreateBlock(csid); 9790b57cec5SDimitry Andric sc.function = sc.block->CalculateSymbolContextFunction(); 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric resolved_flags |= eSymbolContextFunction; 9820b57cec5SDimitry Andric resolved_flags |= eSymbolContextBlock; 9830b57cec5SDimitry Andric break; 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric if (resolve_scope & eSymbolContextLineEntry) { 9880b57cec5SDimitry Andric lldbassert(sc.comp_unit); 9890b57cec5SDimitry Andric if (auto *line_table = sc.comp_unit->GetLineTable()) { 9900b57cec5SDimitry Andric if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) 9910b57cec5SDimitry Andric resolved_flags |= eSymbolContextLineEntry; 9920b57cec5SDimitry Andric } 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric return resolved_flags; 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::ResolveSymbolContext( 999fe6060f1SDimitry Andric const SourceLocationSpec &src_location_spec, 10000b57cec5SDimitry Andric lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { 10010b57cec5SDimitry Andric return 0; 10020b57cec5SDimitry Andric } 10030b57cec5SDimitry Andric 10040b57cec5SDimitry Andric static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence, 10050b57cec5SDimitry Andric const CompilandIndexItem &cci, 10060b57cec5SDimitry Andric lldb::addr_t base_addr, 10070b57cec5SDimitry Andric uint32_t file_number, 10080b57cec5SDimitry Andric const LineFragmentHeader &block, 10090b57cec5SDimitry Andric const LineNumberEntry &cur) { 10100b57cec5SDimitry Andric LineInfo cur_info(cur.Flags); 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) 10130b57cec5SDimitry Andric return; 10140b57cec5SDimitry Andric 10150b57cec5SDimitry Andric uint64_t addr = base_addr + cur.Offset; 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric bool is_statement = cur_info.isStatement(); 10180b57cec5SDimitry Andric bool is_prologue = IsFunctionPrologue(cci, addr); 10190b57cec5SDimitry Andric bool is_epilogue = IsFunctionEpilogue(cci, addr); 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andric uint32_t lno = cur_info.getStartLine(); 10220b57cec5SDimitry Andric 10230b57cec5SDimitry Andric table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number, 10240b57cec5SDimitry Andric is_statement, false, is_prologue, is_epilogue, 10250b57cec5SDimitry Andric false); 10260b57cec5SDimitry Andric } 10270b57cec5SDimitry Andric 10280b57cec5SDimitry Andric static void TerminateLineSequence(LineTable &table, 10290b57cec5SDimitry Andric const LineFragmentHeader &block, 10300b57cec5SDimitry Andric lldb::addr_t base_addr, uint32_t file_number, 10310b57cec5SDimitry Andric uint32_t last_line, 10320b57cec5SDimitry Andric std::unique_ptr<LineSequence> seq) { 10330b57cec5SDimitry Andric // The end is always a terminal entry, so insert it regardless. 10340b57cec5SDimitry Andric table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize, 10350b57cec5SDimitry Andric last_line, 0, file_number, false, false, 10360b57cec5SDimitry Andric false, false, true); 1037fe6060f1SDimitry Andric table.InsertSequence(seq.get()); 10380b57cec5SDimitry Andric } 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { 10410b57cec5SDimitry Andric // Unfortunately LLDB is set up to parse the entire compile unit line table 10420b57cec5SDimitry Andric // all at once, even if all it really needs is line info for a specific 10430b57cec5SDimitry Andric // function. In the future it would be nice if it could set the sc.m_function 10440b57cec5SDimitry Andric // member, and we could only get the line info for the function in question. 10459dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 10460b57cec5SDimitry Andric PdbSymUid cu_id(comp_unit.GetID()); 10470b57cec5SDimitry Andric lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 10480b57cec5SDimitry Andric CompilandIndexItem *cci = 10490b57cec5SDimitry Andric m_index->compilands().GetCompiland(cu_id.asCompiland().modi); 10500b57cec5SDimitry Andric lldbassert(cci); 10519dba64beSDimitry Andric auto line_table = std::make_unique<LineTable>(&comp_unit); 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric // This is basically a copy of the .debug$S subsections from all original COFF 10540b57cec5SDimitry Andric // object files merged together with address relocations applied. We are 10550b57cec5SDimitry Andric // looking for all DEBUG_S_LINES subsections. 10560b57cec5SDimitry Andric for (const DebugSubsectionRecord &dssr : 10570b57cec5SDimitry Andric cci->m_debug_stream.getSubsectionsArray()) { 10580b57cec5SDimitry Andric if (dssr.kind() != DebugSubsectionKind::Lines) 10590b57cec5SDimitry Andric continue; 10600b57cec5SDimitry Andric 10610b57cec5SDimitry Andric DebugLinesSubsectionRef lines; 10620b57cec5SDimitry Andric llvm::BinaryStreamReader reader(dssr.getRecordData()); 10630b57cec5SDimitry Andric if (auto EC = lines.initialize(reader)) { 10640b57cec5SDimitry Andric llvm::consumeError(std::move(EC)); 10650b57cec5SDimitry Andric return false; 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andric const LineFragmentHeader *lfh = lines.header(); 10690b57cec5SDimitry Andric uint64_t virtual_addr = 10700b57cec5SDimitry Andric m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric const auto &checksums = cci->m_strings.checksums().getArray(); 10730b57cec5SDimitry Andric const auto &strings = cci->m_strings.strings(); 10740b57cec5SDimitry Andric for (const LineColumnEntry &group : lines) { 10750b57cec5SDimitry Andric // Indices in this structure are actually offsets of records in the 10760b57cec5SDimitry Andric // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index 10770b57cec5SDimitry Andric // into the global PDB string table. 10780b57cec5SDimitry Andric auto iter = checksums.at(group.NameIndex); 10790b57cec5SDimitry Andric if (iter == checksums.end()) 10800b57cec5SDimitry Andric continue; 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric llvm::Expected<llvm::StringRef> efn = 10830b57cec5SDimitry Andric strings.getString(iter->FileNameOffset); 10840b57cec5SDimitry Andric if (!efn) { 10850b57cec5SDimitry Andric llvm::consumeError(efn.takeError()); 10860b57cec5SDimitry Andric continue; 10870b57cec5SDimitry Andric } 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric // LLDB wants the index of the file in the list of support files. 10900b57cec5SDimitry Andric auto fn_iter = llvm::find(cci->m_file_list, *efn); 10910b57cec5SDimitry Andric lldbassert(fn_iter != cci->m_file_list.end()); 1092480093f4SDimitry Andric uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter); 10930b57cec5SDimitry Andric 10940b57cec5SDimitry Andric std::unique_ptr<LineSequence> sequence( 10950b57cec5SDimitry Andric line_table->CreateLineSequenceContainer()); 10960b57cec5SDimitry Andric lldbassert(!group.LineNumbers.empty()); 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andric for (const LineNumberEntry &entry : group.LineNumbers) { 10990b57cec5SDimitry Andric AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr, 11000b57cec5SDimitry Andric file_index, *lfh, entry); 11010b57cec5SDimitry Andric } 11020b57cec5SDimitry Andric LineInfo last_line(group.LineNumbers.back().Flags); 11030b57cec5SDimitry Andric TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index, 11040b57cec5SDimitry Andric last_line.getEndLine(), std::move(sequence)); 11050b57cec5SDimitry Andric } 11060b57cec5SDimitry Andric } 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric if (line_table->GetSize() == 0) 11090b57cec5SDimitry Andric return false; 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric comp_unit.SetLineTable(line_table.release()); 11120b57cec5SDimitry Andric return true; 11130b57cec5SDimitry Andric } 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { 11160b57cec5SDimitry Andric // PDB doesn't contain information about macros 11170b57cec5SDimitry Andric return false; 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, 11210b57cec5SDimitry Andric FileSpecList &support_files) { 11229dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11230b57cec5SDimitry Andric PdbSymUid cu_id(comp_unit.GetID()); 11240b57cec5SDimitry Andric lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 11250b57cec5SDimitry Andric CompilandIndexItem *cci = 11260b57cec5SDimitry Andric m_index->compilands().GetCompiland(cu_id.asCompiland().modi); 11270b57cec5SDimitry Andric lldbassert(cci); 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric for (llvm::StringRef f : cci->m_file_list) { 11300b57cec5SDimitry Andric FileSpec::Style style = 11310b57cec5SDimitry Andric f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows; 11320b57cec5SDimitry Andric FileSpec spec(f, style); 11330b57cec5SDimitry Andric support_files.Append(spec); 11340b57cec5SDimitry Andric } 11350b57cec5SDimitry Andric return true; 11360b57cec5SDimitry Andric } 11370b57cec5SDimitry Andric 11380b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseImportedModules( 11390b57cec5SDimitry Andric const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 11400b57cec5SDimitry Andric // PDB does not yet support module debug info 11410b57cec5SDimitry Andric return false; 11420b57cec5SDimitry Andric } 11430b57cec5SDimitry Andric 11440b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { 11459dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11460b57cec5SDimitry Andric GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym()); 11470b57cec5SDimitry Andric // FIXME: Parse child blocks 11480b57cec5SDimitry Andric return 1; 11490b57cec5SDimitry Andric } 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); } 11520b57cec5SDimitry Andric 11539dba64beSDimitry Andric void SymbolFileNativePDB::FindGlobalVariables( 11545ffd83dbSDimitry Andric ConstString name, const CompilerDeclContext &parent_decl_ctx, 11550b57cec5SDimitry Andric uint32_t max_matches, VariableList &variables) { 11569dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11570b57cec5SDimitry Andric using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 11580b57cec5SDimitry Andric 11590b57cec5SDimitry Andric std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName( 11600b57cec5SDimitry Andric name.GetStringRef(), m_index->symrecords()); 11610b57cec5SDimitry Andric for (const SymbolAndOffset &result : results) { 11620b57cec5SDimitry Andric VariableSP var; 11630b57cec5SDimitry Andric switch (result.second.kind()) { 11640b57cec5SDimitry Andric case SymbolKind::S_GDATA32: 11650b57cec5SDimitry Andric case SymbolKind::S_LDATA32: 11660b57cec5SDimitry Andric case SymbolKind::S_GTHREAD32: 11670b57cec5SDimitry Andric case SymbolKind::S_LTHREAD32: 11680b57cec5SDimitry Andric case SymbolKind::S_CONSTANT: { 11690b57cec5SDimitry Andric PdbGlobalSymId global(result.first, false); 11700b57cec5SDimitry Andric var = GetOrCreateGlobalVariable(global); 11710b57cec5SDimitry Andric variables.AddVariable(var); 11720b57cec5SDimitry Andric break; 11730b57cec5SDimitry Andric } 11740b57cec5SDimitry Andric default: 11750b57cec5SDimitry Andric continue; 11760b57cec5SDimitry Andric } 11770b57cec5SDimitry Andric } 11780b57cec5SDimitry Andric } 11790b57cec5SDimitry Andric 11809dba64beSDimitry Andric void SymbolFileNativePDB::FindFunctions( 11815ffd83dbSDimitry Andric ConstString name, const CompilerDeclContext &parent_decl_ctx, 11829dba64beSDimitry Andric FunctionNameType name_type_mask, bool include_inlines, 11830b57cec5SDimitry Andric SymbolContextList &sc_list) { 11849dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 11850b57cec5SDimitry Andric // For now we only support lookup by method name. 11860b57cec5SDimitry Andric if (!(name_type_mask & eFunctionNameTypeMethod)) 11879dba64beSDimitry Andric return; 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName( 11920b57cec5SDimitry Andric name.GetStringRef(), m_index->symrecords()); 11930b57cec5SDimitry Andric for (const SymbolAndOffset &match : matches) { 11940b57cec5SDimitry Andric if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF) 11950b57cec5SDimitry Andric continue; 11960b57cec5SDimitry Andric ProcRefSym proc(match.second.kind()); 11970b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc)); 11980b57cec5SDimitry Andric 11990b57cec5SDimitry Andric if (!IsValidRecord(proc)) 12000b57cec5SDimitry Andric continue; 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric CompilandIndexItem &cci = 12030b57cec5SDimitry Andric m_index->compilands().GetOrCreateCompiland(proc.modi()); 12040b57cec5SDimitry Andric SymbolContext sc; 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric sc.comp_unit = GetOrCreateCompileUnit(cci).get(); 12070b57cec5SDimitry Andric PdbCompilandSymId func_id(proc.modi(), proc.SymOffset); 12080b57cec5SDimitry Andric sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get(); 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric sc_list.Append(sc); 12110b57cec5SDimitry Andric } 12120b57cec5SDimitry Andric } 12130b57cec5SDimitry Andric 12149dba64beSDimitry Andric void SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, 12159dba64beSDimitry Andric bool include_inlines, 12169dba64beSDimitry Andric SymbolContextList &sc_list) {} 12170b57cec5SDimitry Andric 12189dba64beSDimitry Andric void SymbolFileNativePDB::FindTypes( 12195ffd83dbSDimitry Andric ConstString name, const CompilerDeclContext &parent_decl_ctx, 12209dba64beSDimitry Andric uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, 12219dba64beSDimitry Andric TypeMap &types) { 12229dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 12230b57cec5SDimitry Andric if (!name) 12249dba64beSDimitry Andric return; 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric searched_symbol_files.clear(); 12270b57cec5SDimitry Andric searched_symbol_files.insert(this); 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric // There is an assumption 'name' is not a regex 12309dba64beSDimitry Andric FindTypesByName(name.GetStringRef(), max_matches, types); 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric 1233480093f4SDimitry Andric void SymbolFileNativePDB::FindTypes( 1234480093f4SDimitry Andric llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, 1235480093f4SDimitry Andric llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {} 12360b57cec5SDimitry Andric 12379dba64beSDimitry Andric void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name, 12380b57cec5SDimitry Andric uint32_t max_matches, 12390b57cec5SDimitry Andric TypeMap &types) { 12400b57cec5SDimitry Andric 12410b57cec5SDimitry Andric std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name); 12420b57cec5SDimitry Andric if (max_matches > 0 && max_matches < matches.size()) 12430b57cec5SDimitry Andric matches.resize(max_matches); 12440b57cec5SDimitry Andric 12450b57cec5SDimitry Andric for (TypeIndex ti : matches) { 12460b57cec5SDimitry Andric TypeSP type = GetOrCreateType(ti); 12470b57cec5SDimitry Andric if (!type) 12480b57cec5SDimitry Andric continue; 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric types.Insert(type); 12510b57cec5SDimitry Andric } 12520b57cec5SDimitry Andric } 12530b57cec5SDimitry Andric 12540b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) { 12559dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 12560b57cec5SDimitry Andric // Only do the full type scan the first time. 12570b57cec5SDimitry Andric if (m_done_full_type_scan) 12580b57cec5SDimitry Andric return 0; 12590b57cec5SDimitry Andric 12609dba64beSDimitry Andric const size_t old_count = GetTypeList().GetSize(); 12610b57cec5SDimitry Andric LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); 12620b57cec5SDimitry Andric 12630b57cec5SDimitry Andric // First process the entire TPI stream. 12640b57cec5SDimitry Andric for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { 12650b57cec5SDimitry Andric TypeSP type = GetOrCreateType(*ti); 12660b57cec5SDimitry Andric if (type) 12670b57cec5SDimitry Andric (void)type->GetFullCompilerType(); 12680b57cec5SDimitry Andric } 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andric // Next look for S_UDT records in the globals stream. 12710b57cec5SDimitry Andric for (const uint32_t gid : m_index->globals().getGlobalsTable()) { 12720b57cec5SDimitry Andric PdbGlobalSymId global{gid, false}; 12730b57cec5SDimitry Andric CVSymbol sym = m_index->ReadSymbolRecord(global); 12740b57cec5SDimitry Andric if (sym.kind() != S_UDT) 12750b57cec5SDimitry Andric continue; 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); 12780b57cec5SDimitry Andric bool is_typedef = true; 12790b57cec5SDimitry Andric if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) { 12800b57cec5SDimitry Andric CVType cvt = m_index->tpi().getType(udt.Type); 12810b57cec5SDimitry Andric llvm::StringRef name = CVTagRecord::create(cvt).name(); 12820b57cec5SDimitry Andric if (name == udt.Name) 12830b57cec5SDimitry Andric is_typedef = false; 12840b57cec5SDimitry Andric } 12850b57cec5SDimitry Andric 12860b57cec5SDimitry Andric if (is_typedef) 12870b57cec5SDimitry Andric GetOrCreateTypedef(global); 12880b57cec5SDimitry Andric } 12890b57cec5SDimitry Andric 12909dba64beSDimitry Andric const size_t new_count = GetTypeList().GetSize(); 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric m_done_full_type_scan = true; 12930b57cec5SDimitry Andric 12940b57cec5SDimitry Andric return new_count - old_count; 12950b57cec5SDimitry Andric } 12960b57cec5SDimitry Andric 12970b57cec5SDimitry Andric size_t 12980b57cec5SDimitry Andric SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit, 12990b57cec5SDimitry Andric VariableList &variables) { 13000b57cec5SDimitry Andric PdbSymUid sym_uid(comp_unit.GetID()); 13010b57cec5SDimitry Andric lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland); 13020b57cec5SDimitry Andric return 0; 13030b57cec5SDimitry Andric } 13040b57cec5SDimitry Andric 13050b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, 13060b57cec5SDimitry Andric PdbCompilandSymId var_id, 13070b57cec5SDimitry Andric bool is_param) { 13080b57cec5SDimitry Andric ModuleSP module = GetObjectFile()->GetModule(); 13090b57cec5SDimitry Andric Block &block = GetOrCreateBlock(scope_id); 13100b57cec5SDimitry Andric VariableInfo var_info = 13110b57cec5SDimitry Andric GetVariableLocationInfo(*m_index, var_id, block, module); 13120b57cec5SDimitry Andric if (!var_info.location || !var_info.ranges) 13130b57cec5SDimitry Andric return nullptr; 13140b57cec5SDimitry Andric 13150b57cec5SDimitry Andric CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi); 13160b57cec5SDimitry Andric CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii); 13170b57cec5SDimitry Andric TypeSP type_sp = GetOrCreateType(var_info.type); 13180b57cec5SDimitry Andric std::string name = var_info.name.str(); 13190b57cec5SDimitry Andric Declaration decl; 13200b57cec5SDimitry Andric SymbolFileTypeSP sftype = 13210b57cec5SDimitry Andric std::make_shared<SymbolFileType>(*this, type_sp->GetID()); 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric ValueType var_scope = 13240b57cec5SDimitry Andric is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal; 1325e8d8bef9SDimitry Andric bool external = false; 1326e8d8bef9SDimitry Andric bool artificial = false; 1327e8d8bef9SDimitry Andric bool location_is_constant_data = false; 1328e8d8bef9SDimitry Andric bool static_member = false; 13290b57cec5SDimitry Andric VariableSP var_sp = std::make_shared<Variable>( 13300b57cec5SDimitry Andric toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, 1331e8d8bef9SDimitry Andric comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, external, 1332e8d8bef9SDimitry Andric artificial, location_is_constant_data, static_member); 13330b57cec5SDimitry Andric 13340b57cec5SDimitry Andric if (!is_param) 13350b57cec5SDimitry Andric m_ast->GetOrCreateVariableDecl(scope_id, var_id); 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andric m_local_variables[toOpaqueUid(var_id)] = var_sp; 13380b57cec5SDimitry Andric return var_sp; 13390b57cec5SDimitry Andric } 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable( 13420b57cec5SDimitry Andric PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) { 13430b57cec5SDimitry Andric auto iter = m_local_variables.find(toOpaqueUid(var_id)); 13440b57cec5SDimitry Andric if (iter != m_local_variables.end()) 13450b57cec5SDimitry Andric return iter->second; 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric return CreateLocalVariable(scope_id, var_id, is_param); 13480b57cec5SDimitry Andric } 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) { 13510b57cec5SDimitry Andric CVSymbol sym = m_index->ReadSymbolRecord(id); 13520b57cec5SDimitry Andric lldbassert(sym.kind() == SymbolKind::S_UDT); 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric TypeSP target_type = GetOrCreateType(udt.Type); 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andric (void)m_ast->GetOrCreateTypedefDecl(id); 13590b57cec5SDimitry Andric 13600b57cec5SDimitry Andric Declaration decl; 13610b57cec5SDimitry Andric return std::make_shared<lldb_private::Type>( 1362e8d8bef9SDimitry Andric toOpaqueUid(id), this, ConstString(udt.Name), 1363e8d8bef9SDimitry Andric target_type->GetByteSize(nullptr), nullptr, target_type->GetID(), 1364e8d8bef9SDimitry Andric lldb_private::Type::eEncodingIsTypedefUID, decl, 1365e8d8bef9SDimitry Andric target_type->GetForwardCompilerType(), 1366480093f4SDimitry Andric lldb_private::Type::ResolveState::Forward); 13670b57cec5SDimitry Andric } 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) { 13700b57cec5SDimitry Andric auto iter = m_types.find(toOpaqueUid(id)); 13710b57cec5SDimitry Andric if (iter != m_types.end()) 13720b57cec5SDimitry Andric return iter->second; 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andric return CreateTypedef(id); 13750b57cec5SDimitry Andric } 13760b57cec5SDimitry Andric 13770b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { 13780b57cec5SDimitry Andric Block &block = GetOrCreateBlock(block_id); 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric size_t count = 0; 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andric CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 13830b57cec5SDimitry Andric CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 13840b57cec5SDimitry Andric uint32_t params_remaining = 0; 13850b57cec5SDimitry Andric switch (sym.kind()) { 13860b57cec5SDimitry Andric case S_GPROC32: 13870b57cec5SDimitry Andric case S_LPROC32: { 13880b57cec5SDimitry Andric ProcSym proc(static_cast<SymbolRecordKind>(sym.kind())); 13890b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)); 13900b57cec5SDimitry Andric CVType signature = m_index->tpi().getType(proc.FunctionType); 13910b57cec5SDimitry Andric ProcedureRecord sig; 13920b57cec5SDimitry Andric cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(signature, sig)); 13930b57cec5SDimitry Andric params_remaining = sig.getParameterCount(); 13940b57cec5SDimitry Andric break; 13950b57cec5SDimitry Andric } 13960b57cec5SDimitry Andric case S_BLOCK32: 13970b57cec5SDimitry Andric break; 13980b57cec5SDimitry Andric default: 13990b57cec5SDimitry Andric lldbassert(false && "Symbol is not a block!"); 14000b57cec5SDimitry Andric return 0; 14010b57cec5SDimitry Andric } 14020b57cec5SDimitry Andric 14030b57cec5SDimitry Andric VariableListSP variables = block.GetBlockVariableList(false); 14040b57cec5SDimitry Andric if (!variables) { 14050b57cec5SDimitry Andric variables = std::make_shared<VariableList>(); 14060b57cec5SDimitry Andric block.SetVariableList(variables); 14070b57cec5SDimitry Andric } 14080b57cec5SDimitry Andric 14090b57cec5SDimitry Andric CVSymbolArray syms = limitSymbolArrayToScope( 14100b57cec5SDimitry Andric cii->m_debug_stream.getSymbolArray(), block_id.offset); 14110b57cec5SDimitry Andric 14120b57cec5SDimitry Andric // Skip the first record since it's a PROC32 or BLOCK32, and there's 14130b57cec5SDimitry Andric // no point examining it since we know it's not a local variable. 14140b57cec5SDimitry Andric syms.drop_front(); 14150b57cec5SDimitry Andric auto iter = syms.begin(); 14160b57cec5SDimitry Andric auto end = syms.end(); 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric while (iter != end) { 14190b57cec5SDimitry Andric uint32_t record_offset = iter.offset(); 14200b57cec5SDimitry Andric CVSymbol variable_cvs = *iter; 14210b57cec5SDimitry Andric PdbCompilandSymId child_sym_id(block_id.modi, record_offset); 14220b57cec5SDimitry Andric ++iter; 14230b57cec5SDimitry Andric 14240b57cec5SDimitry Andric // If this is a block, recurse into its children and then skip it. 14250b57cec5SDimitry Andric if (variable_cvs.kind() == S_BLOCK32) { 14260b57cec5SDimitry Andric uint32_t block_end = getScopeEndOffset(variable_cvs); 14270b57cec5SDimitry Andric count += ParseVariablesForBlock(child_sym_id); 14280b57cec5SDimitry Andric iter = syms.at(block_end); 14290b57cec5SDimitry Andric continue; 14300b57cec5SDimitry Andric } 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric bool is_param = params_remaining > 0; 14330b57cec5SDimitry Andric VariableSP variable; 14340b57cec5SDimitry Andric switch (variable_cvs.kind()) { 14350b57cec5SDimitry Andric case S_REGREL32: 14360b57cec5SDimitry Andric case S_REGISTER: 14370b57cec5SDimitry Andric case S_LOCAL: 14380b57cec5SDimitry Andric variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param); 14390b57cec5SDimitry Andric if (is_param) 14400b57cec5SDimitry Andric --params_remaining; 14410b57cec5SDimitry Andric if (variable) 14420b57cec5SDimitry Andric variables->AddVariableIfUnique(variable); 14430b57cec5SDimitry Andric break; 14440b57cec5SDimitry Andric default: 14450b57cec5SDimitry Andric break; 14460b57cec5SDimitry Andric } 14470b57cec5SDimitry Andric } 14480b57cec5SDimitry Andric 14490b57cec5SDimitry Andric // Pass false for set_children, since we call this recursively so that the 14500b57cec5SDimitry Andric // children will call this for themselves. 14510b57cec5SDimitry Andric block.SetDidParseVariables(true, false); 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric return count; 14540b57cec5SDimitry Andric } 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) { 14579dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 14580b57cec5SDimitry Andric lldbassert(sc.function || sc.comp_unit); 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric VariableListSP variables; 14610b57cec5SDimitry Andric if (sc.block) { 14620b57cec5SDimitry Andric PdbSymUid block_id(sc.block->GetID()); 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 14650b57cec5SDimitry Andric return count; 14660b57cec5SDimitry Andric } 14670b57cec5SDimitry Andric 14680b57cec5SDimitry Andric if (sc.function) { 14690b57cec5SDimitry Andric PdbSymUid block_id(sc.function->GetID()); 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andric size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 14720b57cec5SDimitry Andric return count; 14730b57cec5SDimitry Andric } 14740b57cec5SDimitry Andric 14750b57cec5SDimitry Andric if (sc.comp_unit) { 14760b57cec5SDimitry Andric variables = sc.comp_unit->GetVariableList(false); 14770b57cec5SDimitry Andric if (!variables) { 14780b57cec5SDimitry Andric variables = std::make_shared<VariableList>(); 14790b57cec5SDimitry Andric sc.comp_unit->SetVariableList(variables); 14800b57cec5SDimitry Andric } 14810b57cec5SDimitry Andric return ParseVariablesForCompileUnit(*sc.comp_unit, *variables); 14820b57cec5SDimitry Andric } 14830b57cec5SDimitry Andric 14840b57cec5SDimitry Andric llvm_unreachable("Unreachable!"); 14850b57cec5SDimitry Andric } 14860b57cec5SDimitry Andric 14870b57cec5SDimitry Andric CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) { 14889dba64beSDimitry Andric if (auto decl = m_ast->GetOrCreateDeclForUid(uid)) 14899dba64beSDimitry Andric return decl.getValue(); 14909dba64beSDimitry Andric else 14919dba64beSDimitry Andric return CompilerDecl(); 14920b57cec5SDimitry Andric } 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andric CompilerDeclContext 14950b57cec5SDimitry Andric SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) { 14960b57cec5SDimitry Andric clang::DeclContext *context = 14970b57cec5SDimitry Andric m_ast->GetOrCreateDeclContextForUid(PdbSymUid(uid)); 14980b57cec5SDimitry Andric if (!context) 14990b57cec5SDimitry Andric return {}; 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric return m_ast->ToCompilerDeclContext(*context); 15020b57cec5SDimitry Andric } 15030b57cec5SDimitry Andric 15040b57cec5SDimitry Andric CompilerDeclContext 15050b57cec5SDimitry Andric SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { 15060b57cec5SDimitry Andric clang::DeclContext *context = m_ast->GetParentDeclContext(PdbSymUid(uid)); 15070b57cec5SDimitry Andric return m_ast->ToCompilerDeclContext(*context); 15080b57cec5SDimitry Andric } 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) { 15119dba64beSDimitry Andric std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 15120b57cec5SDimitry Andric auto iter = m_types.find(type_uid); 15130b57cec5SDimitry Andric // lldb should not be passing us non-sensical type uids. the only way it 15140b57cec5SDimitry Andric // could have a type uid in the first place is if we handed it out, in which 15150b57cec5SDimitry Andric // case we should know about the type. However, that doesn't mean we've 15160b57cec5SDimitry Andric // instantiated it yet. We can vend out a UID for a future type. So if the 15170b57cec5SDimitry Andric // type doesn't exist, let's instantiate it now. 15180b57cec5SDimitry Andric if (iter != m_types.end()) 15190b57cec5SDimitry Andric return &*iter->second; 15200b57cec5SDimitry Andric 15210b57cec5SDimitry Andric PdbSymUid uid(type_uid); 15220b57cec5SDimitry Andric lldbassert(uid.kind() == PdbSymUidKind::Type); 15230b57cec5SDimitry Andric PdbTypeSymId type_id = uid.asTypeSym(); 15240b57cec5SDimitry Andric if (type_id.index.isNoneType()) 15250b57cec5SDimitry Andric return nullptr; 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andric TypeSP type_sp = CreateAndCacheType(type_id); 15280b57cec5SDimitry Andric return &*type_sp; 15290b57cec5SDimitry Andric } 15300b57cec5SDimitry Andric 15310b57cec5SDimitry Andric llvm::Optional<SymbolFile::ArrayInfo> 15320b57cec5SDimitry Andric SymbolFileNativePDB::GetDynamicArrayInfoForUID( 15330b57cec5SDimitry Andric lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 15340b57cec5SDimitry Andric return llvm::None; 15350b57cec5SDimitry Andric } 15360b57cec5SDimitry Andric 15370b57cec5SDimitry Andric 15380b57cec5SDimitry Andric bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { 15390b57cec5SDimitry Andric clang::QualType qt = 15400b57cec5SDimitry Andric clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType()); 15410b57cec5SDimitry Andric 15420b57cec5SDimitry Andric return m_ast->CompleteType(qt); 15430b57cec5SDimitry Andric } 15440b57cec5SDimitry Andric 15459dba64beSDimitry Andric void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, 15460b57cec5SDimitry Andric TypeClass type_mask, 15479dba64beSDimitry Andric lldb_private::TypeList &type_list) {} 15480b57cec5SDimitry Andric 15490b57cec5SDimitry Andric CompilerDeclContext 15500b57cec5SDimitry Andric SymbolFileNativePDB::FindNamespace(ConstString name, 15515ffd83dbSDimitry Andric const CompilerDeclContext &parent_decl_ctx) { 15520b57cec5SDimitry Andric return {}; 15530b57cec5SDimitry Andric } 15540b57cec5SDimitry Andric 15559dba64beSDimitry Andric llvm::Expected<TypeSystem &> 15560b57cec5SDimitry Andric SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { 15579dba64beSDimitry Andric auto type_system_or_err = 15589dba64beSDimitry Andric m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); 15599dba64beSDimitry Andric if (type_system_or_err) { 15609dba64beSDimitry Andric type_system_or_err->SetSymbolFile(this); 15619dba64beSDimitry Andric } 15629dba64beSDimitry Andric return type_system_or_err; 15630b57cec5SDimitry Andric } 15640b57cec5SDimitry Andric 1565349cc55cSDimitry Andric uint64_t SymbolFileNativePDB::GetDebugInfoSize() { 1566349cc55cSDimitry Andric // PDB files are a separate file that contains all debug info. 1567349cc55cSDimitry Andric return m_index->pdb().getFileSize(); 15680b57cec5SDimitry Andric } 15690b57cec5SDimitry Andric 1570