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 
115ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
120b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
13e8d8bef9SDimitry Andric #include "Plugins/ObjectFile/PDB/ObjectFilePDB.h"
145ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
150b57cec5SDimitry Andric #include "lldb/Core/Module.h"
160b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h"
170b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
180b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h"
190b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
200b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
210b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h"
220b57cec5SDimitry Andric #include "lldb/Symbol/Variable.h"
230b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h"
2481ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
259dba64beSDimitry Andric #include "lldb/Utility/Log.h"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVRecord.h"
280b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
290b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
300b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
310b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordName.h"
320b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
330b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
340b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
350b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
360b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
370b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
380b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
39e8d8bef9SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
400b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
410b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
420b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
43e8d8bef9SDimitry Andric #include "llvm/DebugInfo/PDB/PDB.h"
440b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBTypes.h"
450b57cec5SDimitry Andric #include "llvm/Demangle/MicrosoftDemangle.h"
460b57cec5SDimitry Andric #include "llvm/Object/COFF.h"
470b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
480b57cec5SDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
490b57cec5SDimitry Andric #include "llvm/Support/Error.h"
500b57cec5SDimitry Andric #include "llvm/Support/ErrorOr.h"
510b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric #include "DWARFLocationExpression.h"
540b57cec5SDimitry Andric #include "PdbSymUid.h"
550b57cec5SDimitry Andric #include "PdbUtil.h"
560b57cec5SDimitry Andric #include "UdtRecordCompleter.h"
57bdd1243dSDimitry Andric #include <optional>
5806c3fb27SDimitry Andric #include <string_view>
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric using namespace lldb;
610b57cec5SDimitry Andric using namespace lldb_private;
620b57cec5SDimitry Andric using namespace npdb;
630b57cec5SDimitry Andric using namespace llvm::codeview;
640b57cec5SDimitry Andric using namespace llvm::pdb;
650b57cec5SDimitry Andric 
66480093f4SDimitry Andric char SymbolFileNativePDB::ID;
67480093f4SDimitry Andric 
TranslateLanguage(PDB_Lang lang)680b57cec5SDimitry Andric static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
690b57cec5SDimitry Andric   switch (lang) {
700b57cec5SDimitry Andric   case PDB_Lang::Cpp:
710b57cec5SDimitry Andric     return lldb::LanguageType::eLanguageTypeC_plus_plus;
720b57cec5SDimitry Andric   case PDB_Lang::C:
730b57cec5SDimitry Andric     return lldb::LanguageType::eLanguageTypeC;
740b57cec5SDimitry Andric   case PDB_Lang::Swift:
750b57cec5SDimitry Andric     return lldb::LanguageType::eLanguageTypeSwift;
7681ad6265SDimitry Andric   case PDB_Lang::Rust:
7781ad6265SDimitry Andric     return lldb::LanguageType::eLanguageTypeRust;
7806c3fb27SDimitry Andric   case PDB_Lang::ObjC:
7906c3fb27SDimitry Andric     return lldb::LanguageType::eLanguageTypeObjC;
8006c3fb27SDimitry Andric   case PDB_Lang::ObjCpp:
8106c3fb27SDimitry Andric     return lldb::LanguageType::eLanguageTypeObjC_plus_plus;
820b57cec5SDimitry Andric   default:
830b57cec5SDimitry Andric     return lldb::LanguageType::eLanguageTypeUnknown;
840b57cec5SDimitry Andric   }
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric static std::unique_ptr<PDBFile>
loadMatchingPDBFile(std::string exe_path,llvm::BumpPtrAllocator & allocator)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();
120bdd1243dSDimitry Andric     pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetPathAsConstString().GetStringRef();
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 
IsFunctionPrologue(const CompilandIndexItem & cci,lldb::addr_t addr)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 
IsFunctionEpilogue(const CompilandIndexItem & cci,lldb::addr_t addr)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 
GetSimpleTypeName(SimpleTypeKind kind)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";
17381ad6265SDimitry Andric   case SimpleTypeKind::Character8:
17481ad6265SDimitry Andric     return "char8_t";
1750b57cec5SDimitry Andric   case SimpleTypeKind::Complex80:
1760b57cec5SDimitry Andric   case SimpleTypeKind::Complex64:
1770b57cec5SDimitry Andric   case SimpleTypeKind::Complex32:
1780b57cec5SDimitry Andric     return "complex";
1790b57cec5SDimitry Andric   case SimpleTypeKind::Float128:
1800b57cec5SDimitry Andric   case SimpleTypeKind::Float80:
1810b57cec5SDimitry Andric     return "long double";
1820b57cec5SDimitry Andric   case SimpleTypeKind::Float64:
1830b57cec5SDimitry Andric     return "double";
1840b57cec5SDimitry Andric   case SimpleTypeKind::Float32:
1850b57cec5SDimitry Andric     return "float";
1860b57cec5SDimitry Andric   case SimpleTypeKind::Float16:
1870b57cec5SDimitry Andric     return "single";
1880b57cec5SDimitry Andric   case SimpleTypeKind::Int128:
1890b57cec5SDimitry Andric     return "__int128";
1900b57cec5SDimitry Andric   case SimpleTypeKind::Int64:
1910b57cec5SDimitry Andric   case SimpleTypeKind::Int64Quad:
1920b57cec5SDimitry Andric     return "int64_t";
1930b57cec5SDimitry Andric   case SimpleTypeKind::Int32:
1940b57cec5SDimitry Andric     return "int";
1950b57cec5SDimitry Andric   case SimpleTypeKind::Int16:
1960b57cec5SDimitry Andric     return "short";
1970b57cec5SDimitry Andric   case SimpleTypeKind::UInt128:
1980b57cec5SDimitry Andric     return "unsigned __int128";
1990b57cec5SDimitry Andric   case SimpleTypeKind::UInt64:
2000b57cec5SDimitry Andric   case SimpleTypeKind::UInt64Quad:
2010b57cec5SDimitry Andric     return "uint64_t";
2020b57cec5SDimitry Andric   case SimpleTypeKind::HResult:
2030b57cec5SDimitry Andric     return "HRESULT";
2040b57cec5SDimitry Andric   case SimpleTypeKind::UInt32:
2050b57cec5SDimitry Andric     return "unsigned";
2060b57cec5SDimitry Andric   case SimpleTypeKind::UInt16:
2070b57cec5SDimitry Andric   case SimpleTypeKind::UInt16Short:
2080b57cec5SDimitry Andric     return "unsigned short";
2090b57cec5SDimitry Andric   case SimpleTypeKind::Int32Long:
2100b57cec5SDimitry Andric     return "long";
2110b57cec5SDimitry Andric   case SimpleTypeKind::UInt32Long:
2120b57cec5SDimitry Andric     return "unsigned long";
2130b57cec5SDimitry Andric   case SimpleTypeKind::Void:
2140b57cec5SDimitry Andric     return "void";
2150b57cec5SDimitry Andric   case SimpleTypeKind::WideCharacter:
2160b57cec5SDimitry Andric     return "wchar_t";
2170b57cec5SDimitry Andric   default:
2180b57cec5SDimitry Andric     return "";
2190b57cec5SDimitry Andric   }
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric 
IsClassRecord(TypeLeafKind kind)2220b57cec5SDimitry Andric static bool IsClassRecord(TypeLeafKind kind) {
2230b57cec5SDimitry Andric   switch (kind) {
2240b57cec5SDimitry Andric   case LF_STRUCTURE:
2250b57cec5SDimitry Andric   case LF_CLASS:
2260b57cec5SDimitry Andric   case LF_INTERFACE:
2270b57cec5SDimitry Andric     return true;
2280b57cec5SDimitry Andric   default:
2290b57cec5SDimitry Andric     return false;
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
233bdd1243dSDimitry Andric static std::optional<CVTagRecord>
GetNestedTagDefinition(const NestedTypeRecord & Record,const CVTagRecord & parent,TpiStream & tpi)234bdd1243dSDimitry Andric GetNestedTagDefinition(const NestedTypeRecord &Record,
235bdd1243dSDimitry Andric                        const CVTagRecord &parent, TpiStream &tpi) {
236bdd1243dSDimitry Andric   // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it
237bdd1243dSDimitry Andric   // is also used to indicate the primary definition of a nested class.  That is
238bdd1243dSDimitry Andric   // to say, if you have:
239bdd1243dSDimitry Andric   // struct A {
240bdd1243dSDimitry Andric   //   struct B {};
241bdd1243dSDimitry Andric   //   using C = B;
242bdd1243dSDimitry Andric   // };
243bdd1243dSDimitry Andric   // Then in the debug info, this will appear as:
244bdd1243dSDimitry Andric   // LF_STRUCTURE `A::B` [type index = N]
245bdd1243dSDimitry Andric   // LF_STRUCTURE `A`
246bdd1243dSDimitry Andric   //   LF_NESTTYPE [name = `B`, index = N]
247bdd1243dSDimitry Andric   //   LF_NESTTYPE [name = `C`, index = N]
248bdd1243dSDimitry Andric   // In order to accurately reconstruct the decl context hierarchy, we need to
249bdd1243dSDimitry Andric   // know which ones are actual definitions and which ones are just aliases.
250bdd1243dSDimitry Andric 
251bdd1243dSDimitry Andric   // If it's a simple type, then this is something like `using foo = int`.
252bdd1243dSDimitry Andric   if (Record.Type.isSimple())
253bdd1243dSDimitry Andric     return std::nullopt;
254bdd1243dSDimitry Andric 
255bdd1243dSDimitry Andric   CVType cvt = tpi.getType(Record.Type);
256bdd1243dSDimitry Andric 
257bdd1243dSDimitry Andric   if (!IsTagRecord(cvt))
258bdd1243dSDimitry Andric     return std::nullopt;
259bdd1243dSDimitry Andric 
260bdd1243dSDimitry Andric   // If it's an inner definition, then treat whatever name we have here as a
261bdd1243dSDimitry Andric   // single component of a mangled name.  So we can inject it into the parent's
262bdd1243dSDimitry Andric   // mangled name to see if it matches.
263bdd1243dSDimitry Andric   CVTagRecord child = CVTagRecord::create(cvt);
264bdd1243dSDimitry Andric   std::string qname = std::string(parent.asTag().getUniqueName());
265bdd1243dSDimitry Andric   if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
266bdd1243dSDimitry Andric     return std::nullopt;
267bdd1243dSDimitry Andric 
268bdd1243dSDimitry Andric   // qname[3] is the tag type identifier (struct, class, union, etc).  Since the
269bdd1243dSDimitry Andric   // inner tag type is not necessarily the same as the outer tag type, re-write
270bdd1243dSDimitry Andric   // it to match the inner tag type.
271bdd1243dSDimitry Andric   qname[3] = child.asTag().getUniqueName()[3];
272bdd1243dSDimitry Andric   std::string piece;
273bdd1243dSDimitry Andric   if (qname[3] == 'W')
274bdd1243dSDimitry Andric     piece = "4";
275bdd1243dSDimitry Andric   piece += Record.Name;
276bdd1243dSDimitry Andric   piece.push_back('@');
277bdd1243dSDimitry Andric   qname.insert(4, std::move(piece));
278bdd1243dSDimitry Andric   if (qname != child.asTag().UniqueName)
279bdd1243dSDimitry Andric     return std::nullopt;
280bdd1243dSDimitry Andric 
281bdd1243dSDimitry Andric   return std::move(child);
282bdd1243dSDimitry Andric }
283bdd1243dSDimitry Andric 
Initialize()2840b57cec5SDimitry Andric void SymbolFileNativePDB::Initialize() {
2850b57cec5SDimitry Andric   PluginManager::RegisterPlugin(GetPluginNameStatic(),
2860b57cec5SDimitry Andric                                 GetPluginDescriptionStatic(), CreateInstance,
2870b57cec5SDimitry Andric                                 DebuggerInitialize);
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
Terminate()2900b57cec5SDimitry Andric void SymbolFileNativePDB::Terminate() {
2910b57cec5SDimitry Andric   PluginManager::UnregisterPlugin(CreateInstance);
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
DebuggerInitialize(Debugger & debugger)2940b57cec5SDimitry Andric void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {}
2950b57cec5SDimitry Andric 
GetPluginDescriptionStatic()296349cc55cSDimitry Andric llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() {
2970b57cec5SDimitry Andric   return "Microsoft PDB debug symbol cross-platform file reader.";
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
CreateInstance(ObjectFileSP objfile_sp)3009dba64beSDimitry Andric SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
3019dba64beSDimitry Andric   return new SymbolFileNativePDB(std::move(objfile_sp));
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric 
SymbolFileNativePDB(ObjectFileSP objfile_sp)3049dba64beSDimitry Andric SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
30581ad6265SDimitry Andric     : SymbolFileCommon(std::move(objfile_sp)) {}
3060b57cec5SDimitry Andric 
307fe6060f1SDimitry Andric SymbolFileNativePDB::~SymbolFileNativePDB() = default;
3080b57cec5SDimitry Andric 
CalculateAbilities()3090b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::CalculateAbilities() {
3100b57cec5SDimitry Andric   uint32_t abilities = 0;
3119dba64beSDimitry Andric   if (!m_objfile_sp)
3120b57cec5SDimitry Andric     return 0;
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   if (!m_index) {
3150b57cec5SDimitry Andric     // Lazily load and match the PDB file, but only do this once.
316e8d8bef9SDimitry Andric     PDBFile *pdb_file;
317e8d8bef9SDimitry Andric     if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) {
318e8d8bef9SDimitry Andric       pdb_file = &pdb->GetPDBFile();
319e8d8bef9SDimitry Andric     } else {
320e8d8bef9SDimitry Andric       m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(),
321e8d8bef9SDimitry Andric                                       m_allocator);
322e8d8bef9SDimitry Andric       pdb_file = m_file_up.get();
3230b57cec5SDimitry Andric     }
3240b57cec5SDimitry Andric 
325e8d8bef9SDimitry Andric     if (!pdb_file)
3260b57cec5SDimitry Andric       return 0;
3270b57cec5SDimitry Andric 
328e8d8bef9SDimitry Andric     auto expected_index = PdbIndex::create(pdb_file);
3290b57cec5SDimitry Andric     if (!expected_index) {
3300b57cec5SDimitry Andric       llvm::consumeError(expected_index.takeError());
3310b57cec5SDimitry Andric       return 0;
3320b57cec5SDimitry Andric     }
3330b57cec5SDimitry Andric     m_index = std::move(*expected_index);
3340b57cec5SDimitry Andric   }
3350b57cec5SDimitry Andric   if (!m_index)
3360b57cec5SDimitry Andric     return 0;
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   // We don't especially have to be precise here.  We only distinguish between
3390b57cec5SDimitry Andric   // stripped and not stripped.
3400b57cec5SDimitry Andric   abilities = kAllAbilities;
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   if (m_index->dbi().isStripped())
3430b57cec5SDimitry Andric     abilities &= ~(Blocks | LocalVariables);
3440b57cec5SDimitry Andric   return abilities;
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
InitializeObject()3470b57cec5SDimitry Andric void SymbolFileNativePDB::InitializeObject() {
348e8d8bef9SDimitry Andric   m_obj_load_address = m_objfile_sp->GetModule()
349e8d8bef9SDimitry Andric                            ->GetObjectFile()
350e8d8bef9SDimitry Andric                            ->GetBaseAddress()
351e8d8bef9SDimitry Andric                            .GetFileAddress();
3520b57cec5SDimitry Andric   m_index->SetLoadAddress(m_obj_load_address);
3530b57cec5SDimitry Andric   m_index->ParseSectionContribs();
3540b57cec5SDimitry Andric 
3559dba64beSDimitry Andric   auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
3560b57cec5SDimitry Andric       lldb::eLanguageTypeC_plus_plus);
3579dba64beSDimitry Andric   if (auto err = ts_or_err.takeError()) {
35881ad6265SDimitry Andric     LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
35906c3fb27SDimitry Andric                    "Failed to initialize: {0}");
3609dba64beSDimitry Andric   } else {
361bdd1243dSDimitry Andric     if (auto ts = *ts_or_err)
362bdd1243dSDimitry Andric       ts->SetSymbolFile(this);
363bdd1243dSDimitry Andric     BuildParentMap();
3649dba64beSDimitry Andric   }
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric 
CalculateNumCompileUnits()3679dba64beSDimitry Andric uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
3680b57cec5SDimitry Andric   const DbiModuleList &modules = m_index->dbi().modules();
3690b57cec5SDimitry Andric   uint32_t count = modules.getModuleCount();
3700b57cec5SDimitry Andric   if (count == 0)
3710b57cec5SDimitry Andric     return count;
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   // The linker can inject an additional "dummy" compilation unit into the
3740b57cec5SDimitry Andric   // PDB. Ignore this special compile unit for our purposes, if it is there.
3750b57cec5SDimitry Andric   // It is always the last one.
3760b57cec5SDimitry Andric   DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
3770b57cec5SDimitry Andric   if (last.getModuleName() == "* Linker *")
3780b57cec5SDimitry Andric     --count;
3790b57cec5SDimitry Andric   return count;
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
CreateBlock(PdbCompilandSymId block_id)3820b57cec5SDimitry Andric Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
3830b57cec5SDimitry Andric   CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
3840b57cec5SDimitry Andric   CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
3850b57cec5SDimitry Andric   CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
38604eeddc0SDimitry Andric   lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
38704eeddc0SDimitry Andric   BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
388bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
389bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
390bdd1243dSDimitry Andric     return *child_block;
391bdd1243dSDimitry Andric   auto ts = *ts_or_err;
392bdd1243dSDimitry Andric   if (!ts)
393bdd1243dSDimitry Andric     return *child_block;
394bdd1243dSDimitry Andric   PdbAstBuilder* ast_builder = ts->GetNativePDBParser();
39504eeddc0SDimitry Andric 
39604eeddc0SDimitry Andric   switch (sym.kind()) {
39704eeddc0SDimitry Andric   case S_GPROC32:
39804eeddc0SDimitry Andric   case S_LPROC32: {
39904eeddc0SDimitry Andric     // This is a function.  It must be global.  Creating the Function entry
40004eeddc0SDimitry Andric     // for it automatically creates a block for it.
40104eeddc0SDimitry Andric     FunctionSP func = GetOrCreateFunction(block_id, *comp_unit);
402bdd1243dSDimitry Andric     if (func) {
40304eeddc0SDimitry Andric       Block &block = func->GetBlock(false);
40404eeddc0SDimitry Andric       if (block.GetNumRanges() == 0)
40504eeddc0SDimitry Andric         block.AddRange(Block::Range(0, func->GetAddressRange().GetByteSize()));
40604eeddc0SDimitry Andric       return block;
4070b57cec5SDimitry Andric     }
408bdd1243dSDimitry Andric     break;
409bdd1243dSDimitry Andric   }
41004eeddc0SDimitry Andric   case S_BLOCK32: {
4110b57cec5SDimitry Andric     // This is a block.  Its parent is either a function or another block.  In
41204eeddc0SDimitry Andric     // either case, its parent can be viewed as a block (e.g. a function
41304eeddc0SDimitry Andric     // contains 1 big block.  So just get the parent block and add this block
41404eeddc0SDimitry Andric     // to it.
4150b57cec5SDimitry Andric     BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
4160b57cec5SDimitry Andric     cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
4170b57cec5SDimitry Andric     lldbassert(block.Parent != 0);
4180b57cec5SDimitry Andric     PdbCompilandSymId parent_id(block_id.modi, block.Parent);
4190b57cec5SDimitry Andric     Block &parent_block = GetOrCreateBlock(parent_id);
420bdd1243dSDimitry Andric     Function *func = parent_block.CalculateSymbolContextFunction();
421bdd1243dSDimitry Andric     lldbassert(func);
422bdd1243dSDimitry Andric     lldb::addr_t block_base =
423bdd1243dSDimitry Andric         m_index->MakeVirtualAddress(block.Segment, block.CodeOffset);
424bdd1243dSDimitry Andric     lldb::addr_t func_base =
425bdd1243dSDimitry Andric         func->GetAddressRange().GetBaseAddress().GetFileAddress();
426bdd1243dSDimitry Andric     if (block_base >= func_base)
427bdd1243dSDimitry Andric       child_block->AddRange(Block::Range(block_base - func_base, block.CodeSize));
428bdd1243dSDimitry Andric     else {
429bdd1243dSDimitry Andric       GetObjectFile()->GetModule()->ReportError(
430bdd1243dSDimitry Andric           "S_BLOCK32 at modi: {0:d} offset: {1:d}: adding range "
431bdd1243dSDimitry Andric           "[{2:x16}-{3:x16}) which has a base that is less than the "
432bdd1243dSDimitry Andric           "function's "
433bdd1243dSDimitry Andric           "low PC 0x%" PRIx64 ". Please file a bug and attach the file at the "
434bdd1243dSDimitry Andric           "start of this error message",
435bdd1243dSDimitry Andric           block_id.modi, block_id.offset, block_base,
436bdd1243dSDimitry Andric           block_base + block.CodeSize, func_base);
437bdd1243dSDimitry Andric     }
43804eeddc0SDimitry Andric     parent_block.AddChild(child_block);
439bdd1243dSDimitry Andric     ast_builder->GetOrCreateBlockDecl(block_id);
44004eeddc0SDimitry Andric     m_blocks.insert({opaque_block_uid, child_block});
44104eeddc0SDimitry Andric     break;
44204eeddc0SDimitry Andric   }
44304eeddc0SDimitry Andric   case S_INLINESITE: {
44404eeddc0SDimitry Andric     // This ensures line table is parsed first so we have inline sites info.
44504eeddc0SDimitry Andric     comp_unit->GetLineTable();
44604eeddc0SDimitry Andric 
44704eeddc0SDimitry Andric     std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid];
44804eeddc0SDimitry Andric     Block &parent_block = GetOrCreateBlock(inline_site->parent_id);
4490b57cec5SDimitry Andric     parent_block.AddChild(child_block);
450bdd1243dSDimitry Andric     ast_builder->GetOrCreateInlinedFunctionDecl(block_id);
45104eeddc0SDimitry Andric     // Copy ranges from InlineSite to Block.
45204eeddc0SDimitry Andric     for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
45304eeddc0SDimitry Andric       auto *entry = inline_site->ranges.GetEntryAtIndex(i);
45404eeddc0SDimitry Andric       child_block->AddRange(
45504eeddc0SDimitry Andric           Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
45604eeddc0SDimitry Andric     }
45704eeddc0SDimitry Andric     child_block->FinalizeRanges();
4580b57cec5SDimitry Andric 
45904eeddc0SDimitry Andric     // Get the inlined function callsite info.
46004eeddc0SDimitry Andric     Declaration &decl = inline_site->inline_function_info->GetDeclaration();
46104eeddc0SDimitry Andric     Declaration &callsite = inline_site->inline_function_info->GetCallSite();
46204eeddc0SDimitry Andric     child_block->SetInlinedFunctionInfo(
46304eeddc0SDimitry Andric         inline_site->inline_function_info->GetName().GetCString(), nullptr,
46404eeddc0SDimitry Andric         &decl, &callsite);
4650b57cec5SDimitry Andric     m_blocks.insert({opaque_block_uid, child_block});
46604eeddc0SDimitry Andric     break;
46704eeddc0SDimitry Andric   }
46804eeddc0SDimitry Andric   default:
46904eeddc0SDimitry Andric     lldbassert(false && "Symbol is not a block!");
47004eeddc0SDimitry Andric   }
47104eeddc0SDimitry Andric 
4720b57cec5SDimitry Andric   return *child_block;
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric 
CreateFunction(PdbCompilandSymId func_id,CompileUnit & comp_unit)4750b57cec5SDimitry Andric lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
4760b57cec5SDimitry Andric                                                      CompileUnit &comp_unit) {
4770b57cec5SDimitry Andric   const CompilandIndexItem *cci =
4780b57cec5SDimitry Andric       m_index->compilands().GetCompiland(func_id.modi);
4790b57cec5SDimitry Andric   lldbassert(cci);
4800b57cec5SDimitry Andric   CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);
4830b57cec5SDimitry Andric   SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record);
4840b57cec5SDimitry Andric 
48581ad6265SDimitry Andric   auto file_vm_addr =
48681ad6265SDimitry Andric       m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
4870b57cec5SDimitry Andric   if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
4880b57cec5SDimitry Andric     return nullptr;
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   AddressRange func_range(file_vm_addr, sol.length,
4910b57cec5SDimitry Andric                           comp_unit.GetModule()->GetSectionList());
4920b57cec5SDimitry Andric   if (!func_range.GetBaseAddress().IsValid())
4930b57cec5SDimitry Andric     return nullptr;
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric   ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
4960b57cec5SDimitry Andric   cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
4970b57cec5SDimitry Andric   if (proc.FunctionType == TypeIndex::None())
4980b57cec5SDimitry Andric     return nullptr;
4990b57cec5SDimitry Andric   TypeSP func_type = GetOrCreateType(proc.FunctionType);
5000b57cec5SDimitry Andric   if (!func_type)
5010b57cec5SDimitry Andric     return nullptr;
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   PdbTypeSymId sig_id(proc.FunctionType, false);
5040b57cec5SDimitry Andric   Mangled mangled(proc.Name);
5050b57cec5SDimitry Andric   FunctionSP func_sp = std::make_shared<Function>(
5060b57cec5SDimitry Andric       &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
5070b57cec5SDimitry Andric       func_type.get(), func_range);
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   comp_unit.AddFunction(func_sp);
5100b57cec5SDimitry Andric 
511bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage());
512bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
513bdd1243dSDimitry Andric     return func_sp;
514bdd1243dSDimitry Andric   auto ts = *ts_or_err;
515bdd1243dSDimitry Andric   if (!ts)
516bdd1243dSDimitry Andric     return func_sp;
517bdd1243dSDimitry Andric   ts->GetNativePDBParser()->GetOrCreateFunctionDecl(func_id);
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   return func_sp;
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric CompUnitSP
CreateCompileUnit(const CompilandIndexItem & cci)5230b57cec5SDimitry Andric SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
5240b57cec5SDimitry Andric   lldb::LanguageType lang =
5250b57cec5SDimitry Andric       cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())
5260b57cec5SDimitry Andric                          : lldb::eLanguageTypeUnknown;
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric   LazyBool optimized = eLazyBoolNo;
5290b57cec5SDimitry Andric   if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())
5300b57cec5SDimitry Andric     optimized = eLazyBoolYes;
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   llvm::SmallString<64> source_file_name =
5330b57cec5SDimitry Andric       m_index->compilands().GetMainSourceFile(cci);
53481ad6265SDimitry Andric   FileSpec fs(llvm::sys::path::convert_to_slash(
53581ad6265SDimitry Andric       source_file_name, llvm::sys::path::Style::windows_backslash));
5360b57cec5SDimitry Andric 
5377a6dacacSDimitry Andric   CompUnitSP cu_sp = std::make_shared<CompileUnit>(
5387a6dacacSDimitry Andric       m_objfile_sp->GetModule(), nullptr, std::make_shared<SupportFile>(fs),
5390b57cec5SDimitry Andric       toOpaqueUid(cci.m_id), lang, optimized);
5400b57cec5SDimitry Andric 
5419dba64beSDimitry Andric   SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
5420b57cec5SDimitry Andric   return cu_sp;
5430b57cec5SDimitry Andric }
5440b57cec5SDimitry Andric 
CreateModifierType(PdbTypeSymId type_id,const ModifierRecord & mr,CompilerType ct)5450b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id,
5460b57cec5SDimitry Andric                                                      const ModifierRecord &mr,
5470b57cec5SDimitry Andric                                                      CompilerType ct) {
5480b57cec5SDimitry Andric   TpiStream &stream = m_index->tpi();
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric   std::string name;
5510b57cec5SDimitry Andric   if (mr.ModifiedType.isSimple())
5525ffd83dbSDimitry Andric     name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind()));
5530b57cec5SDimitry Andric   else
5540b57cec5SDimitry Andric     name = computeTypeName(stream.typeCollection(), mr.ModifiedType);
5550b57cec5SDimitry Andric   Declaration decl;
5560b57cec5SDimitry Andric   lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);
5570b57cec5SDimitry Andric 
558bdd1243dSDimitry Andric   return MakeType(toOpaqueUid(type_id), ConstString(name),
559e8d8bef9SDimitry Andric                   modified_type->GetByteSize(nullptr), nullptr,
560bdd1243dSDimitry Andric                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
561bdd1243dSDimitry Andric                   Type::ResolveState::Full);
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric lldb::TypeSP
CreatePointerType(PdbTypeSymId type_id,const llvm::codeview::PointerRecord & pr,CompilerType ct)5650b57cec5SDimitry Andric SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id,
5660b57cec5SDimitry Andric                                        const llvm::codeview::PointerRecord &pr,
5670b57cec5SDimitry Andric                                        CompilerType ct) {
5680b57cec5SDimitry Andric   TypeSP pointee = GetOrCreateType(pr.ReferentType);
5690b57cec5SDimitry Andric   if (!pointee)
5700b57cec5SDimitry Andric     return nullptr;
5710b57cec5SDimitry Andric 
5720b57cec5SDimitry Andric   if (pr.isPointerToMember()) {
5730b57cec5SDimitry Andric     MemberPointerInfo mpi = pr.getMemberInfo();
5740b57cec5SDimitry Andric     GetOrCreateType(mpi.ContainingType);
5750b57cec5SDimitry Andric   }
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric   Declaration decl;
578bdd1243dSDimitry Andric   return MakeType(toOpaqueUid(type_id), ConstString(), pr.getSize(), nullptr,
579bdd1243dSDimitry Andric                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
580480093f4SDimitry Andric                   Type::ResolveState::Full);
5810b57cec5SDimitry Andric }
5820b57cec5SDimitry Andric 
CreateSimpleType(TypeIndex ti,CompilerType ct)5830b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti,
5840b57cec5SDimitry Andric                                                    CompilerType ct) {
5850b57cec5SDimitry Andric   uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));
5860b57cec5SDimitry Andric   if (ti == TypeIndex::NullptrT()) {
5870b57cec5SDimitry Andric     Declaration decl;
588bdd1243dSDimitry Andric     return MakeType(uid, ConstString("std::nullptr_t"), 0, nullptr,
589bdd1243dSDimitry Andric                     LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
590bdd1243dSDimitry Andric                     Type::ResolveState::Full);
5910b57cec5SDimitry Andric   }
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric   if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
5940b57cec5SDimitry Andric     TypeSP direct_sp = GetOrCreateType(ti.makeDirect());
5950b57cec5SDimitry Andric     uint32_t pointer_size = 0;
5960b57cec5SDimitry Andric     switch (ti.getSimpleMode()) {
5970b57cec5SDimitry Andric     case SimpleTypeMode::FarPointer32:
5980b57cec5SDimitry Andric     case SimpleTypeMode::NearPointer32:
5990b57cec5SDimitry Andric       pointer_size = 4;
6000b57cec5SDimitry Andric       break;
6010b57cec5SDimitry Andric     case SimpleTypeMode::NearPointer64:
6020b57cec5SDimitry Andric       pointer_size = 8;
6030b57cec5SDimitry Andric       break;
6040b57cec5SDimitry Andric     default:
6050b57cec5SDimitry Andric       // 128-bit and 16-bit pointers unsupported.
6060b57cec5SDimitry Andric       return nullptr;
6070b57cec5SDimitry Andric     }
6080b57cec5SDimitry Andric     Declaration decl;
609bdd1243dSDimitry Andric     return MakeType(uid, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID,
610480093f4SDimitry Andric                     Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);
6110b57cec5SDimitry Andric   }
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
6140b57cec5SDimitry Andric     return nullptr;
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind());
6170b57cec5SDimitry Andric   llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric   Declaration decl;
620bdd1243dSDimitry Andric   return MakeType(uid, ConstString(type_name), size, nullptr, LLDB_INVALID_UID,
621bdd1243dSDimitry Andric                   Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric 
GetUnqualifiedTypeName(const TagRecord & record)6240b57cec5SDimitry Andric static std::string GetUnqualifiedTypeName(const TagRecord &record) {
6250b57cec5SDimitry Andric   if (!record.hasUniqueName()) {
6260b57cec5SDimitry Andric     MSVCUndecoratedNameParser parser(record.Name);
6270b57cec5SDimitry Andric     llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
6280b57cec5SDimitry Andric 
6295ffd83dbSDimitry Andric     return std::string(specs.back().GetBaseName());
6300b57cec5SDimitry Andric   }
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric   llvm::ms_demangle::Demangler demangler;
63306c3fb27SDimitry Andric   std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());
6340b57cec5SDimitry Andric   llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
6350b57cec5SDimitry Andric   if (demangler.Error)
6365ffd83dbSDimitry Andric     return std::string(record.Name);
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric   llvm::ms_demangle::IdentifierNode *idn =
6390b57cec5SDimitry Andric       ttn->QualifiedName->getUnqualifiedIdentifier();
6400b57cec5SDimitry Andric   return idn->toString();
6410b57cec5SDimitry Andric }
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric lldb::TypeSP
CreateClassStructUnion(PdbTypeSymId type_id,const TagRecord & record,size_t size,CompilerType ct)6440b57cec5SDimitry Andric SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id,
6450b57cec5SDimitry Andric                                             const TagRecord &record,
6460b57cec5SDimitry Andric                                             size_t size, CompilerType ct) {
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   std::string uname = GetUnqualifiedTypeName(record);
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
6510b57cec5SDimitry Andric   Declaration decl;
652bdd1243dSDimitry Andric   return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr,
653bdd1243dSDimitry Andric                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
654480093f4SDimitry Andric                   Type::ResolveState::Forward);
6550b57cec5SDimitry Andric }
6560b57cec5SDimitry Andric 
CreateTagType(PdbTypeSymId type_id,const ClassRecord & cr,CompilerType ct)6570b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
6580b57cec5SDimitry Andric                                                 const ClassRecord &cr,
6590b57cec5SDimitry Andric                                                 CompilerType ct) {
6600b57cec5SDimitry Andric   return CreateClassStructUnion(type_id, cr, cr.getSize(), ct);
6610b57cec5SDimitry Andric }
6620b57cec5SDimitry Andric 
CreateTagType(PdbTypeSymId type_id,const UnionRecord & ur,CompilerType ct)6630b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
6640b57cec5SDimitry Andric                                                 const UnionRecord &ur,
6650b57cec5SDimitry Andric                                                 CompilerType ct) {
6660b57cec5SDimitry Andric   return CreateClassStructUnion(type_id, ur, ur.getSize(), ct);
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
CreateTagType(PdbTypeSymId type_id,const EnumRecord & er,CompilerType ct)6690b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
6700b57cec5SDimitry Andric                                                 const EnumRecord &er,
6710b57cec5SDimitry Andric                                                 CompilerType ct) {
6720b57cec5SDimitry Andric   std::string uname = GetUnqualifiedTypeName(er);
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   Declaration decl;
6750b57cec5SDimitry Andric   TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
6760b57cec5SDimitry Andric 
677bdd1243dSDimitry Andric   return MakeType(toOpaqueUid(type_id), ConstString(uname),
678bdd1243dSDimitry Andric                   underlying_type->GetByteSize(nullptr), nullptr,
679bdd1243dSDimitry Andric                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
680bdd1243dSDimitry Andric                   ct, lldb_private::Type::ResolveState::Forward);
6810b57cec5SDimitry Andric }
6820b57cec5SDimitry Andric 
CreateArrayType(PdbTypeSymId type_id,const ArrayRecord & ar,CompilerType ct)6830b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id,
6840b57cec5SDimitry Andric                                             const ArrayRecord &ar,
6850b57cec5SDimitry Andric                                             CompilerType ct) {
6860b57cec5SDimitry Andric   TypeSP element_type = GetOrCreateType(ar.ElementType);
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   Declaration decl;
689bdd1243dSDimitry Andric   TypeSP array_sp =
690bdd1243dSDimitry Andric       MakeType(toOpaqueUid(type_id), ConstString(), ar.Size, nullptr,
6910b57cec5SDimitry Andric                LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct,
692480093f4SDimitry Andric                lldb_private::Type::ResolveState::Full);
6930b57cec5SDimitry Andric   array_sp->SetEncodingType(element_type.get());
6940b57cec5SDimitry Andric   return array_sp;
6950b57cec5SDimitry Andric }
6960b57cec5SDimitry Andric 
CreateFunctionType(PdbTypeSymId type_id,const MemberFunctionRecord & mfr,CompilerType ct)6970b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
6980b57cec5SDimitry Andric                                                const MemberFunctionRecord &mfr,
6990b57cec5SDimitry Andric                                                CompilerType ct) {
7000b57cec5SDimitry Andric   Declaration decl;
701bdd1243dSDimitry Andric   return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
702bdd1243dSDimitry Andric                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
703bdd1243dSDimitry Andric                   ct, lldb_private::Type::ResolveState::Full);
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric 
CreateProcedureType(PdbTypeSymId type_id,const ProcedureRecord & pr,CompilerType ct)7060b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
7070b57cec5SDimitry Andric                                                 const ProcedureRecord &pr,
7080b57cec5SDimitry Andric                                                 CompilerType ct) {
7090b57cec5SDimitry Andric   Declaration decl;
710bdd1243dSDimitry Andric   return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
711bdd1243dSDimitry Andric                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
712bdd1243dSDimitry Andric                   ct, lldb_private::Type::ResolveState::Full);
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric 
CreateType(PdbTypeSymId type_id,CompilerType ct)7150b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
7160b57cec5SDimitry Andric   if (type_id.index.isSimple())
7170b57cec5SDimitry Andric     return CreateSimpleType(type_id.index, ct);
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric   TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi();
7200b57cec5SDimitry Andric   CVType cvt = stream.getType(type_id.index);
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   if (cvt.kind() == LF_MODIFIER) {
7230b57cec5SDimitry Andric     ModifierRecord modifier;
7240b57cec5SDimitry Andric     llvm::cantFail(
7250b57cec5SDimitry Andric         TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
7260b57cec5SDimitry Andric     return CreateModifierType(type_id, modifier, ct);
7270b57cec5SDimitry Andric   }
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric   if (cvt.kind() == LF_POINTER) {
7300b57cec5SDimitry Andric     PointerRecord pointer;
7310b57cec5SDimitry Andric     llvm::cantFail(
7320b57cec5SDimitry Andric         TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
7330b57cec5SDimitry Andric     return CreatePointerType(type_id, pointer, ct);
7340b57cec5SDimitry Andric   }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric   if (IsClassRecord(cvt.kind())) {
7370b57cec5SDimitry Andric     ClassRecord cr;
7380b57cec5SDimitry Andric     llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
7390b57cec5SDimitry Andric     return CreateTagType(type_id, cr, ct);
7400b57cec5SDimitry Andric   }
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric   if (cvt.kind() == LF_ENUM) {
7430b57cec5SDimitry Andric     EnumRecord er;
7440b57cec5SDimitry Andric     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
7450b57cec5SDimitry Andric     return CreateTagType(type_id, er, ct);
7460b57cec5SDimitry Andric   }
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric   if (cvt.kind() == LF_UNION) {
7490b57cec5SDimitry Andric     UnionRecord ur;
7500b57cec5SDimitry Andric     llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
7510b57cec5SDimitry Andric     return CreateTagType(type_id, ur, ct);
7520b57cec5SDimitry Andric   }
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric   if (cvt.kind() == LF_ARRAY) {
7550b57cec5SDimitry Andric     ArrayRecord ar;
7560b57cec5SDimitry Andric     llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
7570b57cec5SDimitry Andric     return CreateArrayType(type_id, ar, ct);
7580b57cec5SDimitry Andric   }
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric   if (cvt.kind() == LF_PROCEDURE) {
7610b57cec5SDimitry Andric     ProcedureRecord pr;
7620b57cec5SDimitry Andric     llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
7630b57cec5SDimitry Andric     return CreateProcedureType(type_id, pr, ct);
7640b57cec5SDimitry Andric   }
7650b57cec5SDimitry Andric   if (cvt.kind() == LF_MFUNCTION) {
7660b57cec5SDimitry Andric     MemberFunctionRecord mfr;
7670b57cec5SDimitry Andric     llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
7680b57cec5SDimitry Andric     return CreateFunctionType(type_id, mfr, ct);
7690b57cec5SDimitry Andric   }
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   return nullptr;
7720b57cec5SDimitry Andric }
7730b57cec5SDimitry Andric 
CreateAndCacheType(PdbTypeSymId type_id)7740b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) {
7750b57cec5SDimitry Andric   // If they search for a UDT which is a forward ref, try and resolve the full
7760b57cec5SDimitry Andric   // decl and just map the forward ref uid to the full decl record.
777bdd1243dSDimitry Andric   std::optional<PdbTypeSymId> full_decl_uid;
7780b57cec5SDimitry Andric   if (IsForwardRefUdt(type_id, m_index->tpi())) {
7790b57cec5SDimitry Andric     auto expected_full_ti =
7800b57cec5SDimitry Andric         m_index->tpi().findFullDeclForForwardRef(type_id.index);
7810b57cec5SDimitry Andric     if (!expected_full_ti)
7820b57cec5SDimitry Andric       llvm::consumeError(expected_full_ti.takeError());
7830b57cec5SDimitry Andric     else if (*expected_full_ti != type_id.index) {
7840b57cec5SDimitry Andric       full_decl_uid = PdbTypeSymId(*expected_full_ti, false);
7850b57cec5SDimitry Andric 
7860b57cec5SDimitry Andric       // It's possible that a lookup would occur for the full decl causing it
7870b57cec5SDimitry Andric       // to be cached, then a second lookup would occur for the forward decl.
7880b57cec5SDimitry Andric       // We don't want to create a second full decl, so make sure the full
7890b57cec5SDimitry Andric       // decl hasn't already been cached.
7900b57cec5SDimitry Andric       auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid));
7910b57cec5SDimitry Andric       if (full_iter != m_types.end()) {
7920b57cec5SDimitry Andric         TypeSP result = full_iter->second;
7930b57cec5SDimitry Andric         // Map the forward decl to the TypeSP for the full decl so we can take
7940b57cec5SDimitry Andric         // the fast path next time.
7950b57cec5SDimitry Andric         m_types[toOpaqueUid(type_id)] = result;
7960b57cec5SDimitry Andric         return result;
7970b57cec5SDimitry Andric       }
7980b57cec5SDimitry Andric     }
7990b57cec5SDimitry Andric   }
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
802bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
803bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
804bdd1243dSDimitry Andric     return nullptr;
805bdd1243dSDimitry Andric   auto ts = *ts_or_err;
806bdd1243dSDimitry Andric   if (!ts)
807bdd1243dSDimitry Andric     return nullptr;
8080b57cec5SDimitry Andric 
809bdd1243dSDimitry Andric   PdbAstBuilder* ast_builder = ts->GetNativePDBParser();
810bdd1243dSDimitry Andric   clang::QualType qt = ast_builder->GetOrCreateType(best_decl_id);
81181ad6265SDimitry Andric   if (qt.isNull())
81281ad6265SDimitry Andric     return nullptr;
8130b57cec5SDimitry Andric 
814bdd1243dSDimitry Andric   TypeSP result = CreateType(best_decl_id, ast_builder->ToCompilerType(qt));
8150b57cec5SDimitry Andric   if (!result)
8160b57cec5SDimitry Andric     return nullptr;
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   uint64_t best_uid = toOpaqueUid(best_decl_id);
8190b57cec5SDimitry Andric   m_types[best_uid] = result;
8200b57cec5SDimitry Andric   // If we had both a forward decl and a full decl, make both point to the new
8210b57cec5SDimitry Andric   // type.
8220b57cec5SDimitry Andric   if (full_decl_uid)
8230b57cec5SDimitry Andric     m_types[toOpaqueUid(type_id)] = result;
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric   return result;
8260b57cec5SDimitry Andric }
8270b57cec5SDimitry Andric 
GetOrCreateType(PdbTypeSymId type_id)8280b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
8290b57cec5SDimitry Andric   // We can't use try_emplace / overwrite here because the process of creating
8300b57cec5SDimitry Andric   // a type could create nested types, which could invalidate iterators.  So
8310b57cec5SDimitry Andric   // we have to do a 2-phase lookup / insert.
8320b57cec5SDimitry Andric   auto iter = m_types.find(toOpaqueUid(type_id));
8330b57cec5SDimitry Andric   if (iter != m_types.end())
8340b57cec5SDimitry Andric     return iter->second;
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric   TypeSP type = CreateAndCacheType(type_id);
8370b57cec5SDimitry Andric   if (type)
8389dba64beSDimitry Andric     GetTypeList().Insert(type);
8390b57cec5SDimitry Andric   return type;
8400b57cec5SDimitry Andric }
8410b57cec5SDimitry Andric 
CreateGlobalVariable(PdbGlobalSymId var_id)8420b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
8430b57cec5SDimitry Andric   CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
8440b57cec5SDimitry Andric   if (sym.kind() == S_CONSTANT)
8450b57cec5SDimitry Andric     return CreateConstantSymbol(var_id, sym);
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric   lldb::ValueType scope = eValueTypeInvalid;
8480b57cec5SDimitry Andric   TypeIndex ti;
8490b57cec5SDimitry Andric   llvm::StringRef name;
8500b57cec5SDimitry Andric   lldb::addr_t addr = 0;
8510b57cec5SDimitry Andric   uint16_t section = 0;
8520b57cec5SDimitry Andric   uint32_t offset = 0;
8530b57cec5SDimitry Andric   bool is_external = false;
8540b57cec5SDimitry Andric   switch (sym.kind()) {
8550b57cec5SDimitry Andric   case S_GDATA32:
8560b57cec5SDimitry Andric     is_external = true;
857bdd1243dSDimitry Andric     [[fallthrough]];
8580b57cec5SDimitry Andric   case S_LDATA32: {
8590b57cec5SDimitry Andric     DataSym ds(sym.kind());
8600b57cec5SDimitry Andric     llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds));
8610b57cec5SDimitry Andric     ti = ds.Type;
8620b57cec5SDimitry Andric     scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal
8630b57cec5SDimitry Andric                                       : eValueTypeVariableStatic;
8640b57cec5SDimitry Andric     name = ds.Name;
8650b57cec5SDimitry Andric     section = ds.Segment;
8660b57cec5SDimitry Andric     offset = ds.DataOffset;
8670b57cec5SDimitry Andric     addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
8680b57cec5SDimitry Andric     break;
8690b57cec5SDimitry Andric   }
8700b57cec5SDimitry Andric   case S_GTHREAD32:
8710b57cec5SDimitry Andric     is_external = true;
872bdd1243dSDimitry Andric     [[fallthrough]];
8730b57cec5SDimitry Andric   case S_LTHREAD32: {
8740b57cec5SDimitry Andric     ThreadLocalDataSym tlds(sym.kind());
8750b57cec5SDimitry Andric     llvm::cantFail(
8760b57cec5SDimitry Andric         SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds));
8770b57cec5SDimitry Andric     ti = tlds.Type;
8780b57cec5SDimitry Andric     name = tlds.Name;
8790b57cec5SDimitry Andric     section = tlds.Segment;
8800b57cec5SDimitry Andric     offset = tlds.DataOffset;
8810b57cec5SDimitry Andric     addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
8820b57cec5SDimitry Andric     scope = eValueTypeVariableThreadLocal;
8830b57cec5SDimitry Andric     break;
8840b57cec5SDimitry Andric   }
8850b57cec5SDimitry Andric   default:
8860b57cec5SDimitry Andric     llvm_unreachable("unreachable!");
8870b57cec5SDimitry Andric   }
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   CompUnitSP comp_unit;
890bdd1243dSDimitry Andric   std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);
89181ad6265SDimitry Andric   if (!modi) {
89281ad6265SDimitry Andric     return nullptr;
89381ad6265SDimitry Andric   }
89481ad6265SDimitry Andric 
8950b57cec5SDimitry Andric   CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);
8960b57cec5SDimitry Andric   comp_unit = GetOrCreateCompileUnit(cci);
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric   Declaration decl;
8990b57cec5SDimitry Andric   PdbTypeSymId tid(ti, false);
9000b57cec5SDimitry Andric   SymbolFileTypeSP type_sp =
9010b57cec5SDimitry Andric       std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
9020b57cec5SDimitry Andric   Variable::RangeList ranges;
903bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
904bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
905bdd1243dSDimitry Andric     return nullptr;
906bdd1243dSDimitry Andric   auto ts = *ts_or_err;
907bdd1243dSDimitry Andric   if (!ts)
908bdd1243dSDimitry Andric     return nullptr;
9090b57cec5SDimitry Andric 
910bdd1243dSDimitry Andric   ts->GetNativePDBParser()->GetOrCreateVariableDecl(var_id);
9110b57cec5SDimitry Andric 
912753f127fSDimitry Andric   ModuleSP module_sp = GetObjectFile()->GetModule();
913753f127fSDimitry Andric   DWARFExpressionList location(
914753f127fSDimitry Andric       module_sp, MakeGlobalLocationExpression(section, offset, module_sp),
915753f127fSDimitry Andric       nullptr);
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric   std::string global_name("::");
9180b57cec5SDimitry Andric   global_name += name;
919e8d8bef9SDimitry Andric   bool artificial = false;
920e8d8bef9SDimitry Andric   bool location_is_constant_data = false;
921e8d8bef9SDimitry Andric   bool static_member = false;
9220b57cec5SDimitry Andric   VariableSP var_sp = std::make_shared<Variable>(
9230b57cec5SDimitry Andric       toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
924e8d8bef9SDimitry Andric       scope, comp_unit.get(), ranges, &decl, location, is_external, artificial,
925e8d8bef9SDimitry Andric       location_is_constant_data, static_member);
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric   return var_sp;
9280b57cec5SDimitry Andric }
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric lldb::VariableSP
CreateConstantSymbol(PdbGlobalSymId var_id,const CVSymbol & cvs)9310b57cec5SDimitry Andric SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
9320b57cec5SDimitry Andric                                           const CVSymbol &cvs) {
9330b57cec5SDimitry Andric   TpiStream &tpi = m_index->tpi();
9340b57cec5SDimitry Andric   ConstantSym constant(cvs.kind());
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric   llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant));
9370b57cec5SDimitry Andric   std::string global_name("::");
9380b57cec5SDimitry Andric   global_name += constant.Name;
9390b57cec5SDimitry Andric   PdbTypeSymId tid(constant.Type, false);
9400b57cec5SDimitry Andric   SymbolFileTypeSP type_sp =
9410b57cec5SDimitry Andric       std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   Declaration decl;
9440b57cec5SDimitry Andric   Variable::RangeList ranges;
9450b57cec5SDimitry Andric   ModuleSP module = GetObjectFile()->GetModule();
946753f127fSDimitry Andric   DWARFExpressionList location(module,
947753f127fSDimitry Andric                                MakeConstantLocationExpression(
948753f127fSDimitry Andric                                    constant.Type, tpi, constant.Value, module),
949753f127fSDimitry Andric                                nullptr);
9500b57cec5SDimitry Andric 
951e8d8bef9SDimitry Andric   bool external = false;
952e8d8bef9SDimitry Andric   bool artificial = false;
953e8d8bef9SDimitry Andric   bool location_is_constant_data = true;
954e8d8bef9SDimitry Andric   bool static_member = false;
9550b57cec5SDimitry Andric   VariableSP var_sp = std::make_shared<Variable>(
9560b57cec5SDimitry Andric       toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
9570b57cec5SDimitry Andric       type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
958e8d8bef9SDimitry Andric       external, artificial, location_is_constant_data, static_member);
9590b57cec5SDimitry Andric   return var_sp;
9600b57cec5SDimitry Andric }
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric VariableSP
GetOrCreateGlobalVariable(PdbGlobalSymId var_id)9630b57cec5SDimitry Andric SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) {
9640b57cec5SDimitry Andric   auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr);
96581ad6265SDimitry Andric   if (emplace_result.second) {
96681ad6265SDimitry Andric     if (VariableSP var_sp = CreateGlobalVariable(var_id))
96781ad6265SDimitry Andric       emplace_result.first->second = var_sp;
96881ad6265SDimitry Andric     else
96981ad6265SDimitry Andric       return nullptr;
97081ad6265SDimitry Andric   }
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric   return emplace_result.first->second;
9730b57cec5SDimitry Andric }
9740b57cec5SDimitry Andric 
GetOrCreateType(TypeIndex ti)9750b57cec5SDimitry Andric lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) {
9760b57cec5SDimitry Andric   return GetOrCreateType(PdbTypeSymId(ti, false));
9770b57cec5SDimitry Andric }
9780b57cec5SDimitry Andric 
GetOrCreateFunction(PdbCompilandSymId func_id,CompileUnit & comp_unit)9790b57cec5SDimitry Andric FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id,
9800b57cec5SDimitry Andric                                                     CompileUnit &comp_unit) {
9810b57cec5SDimitry Andric   auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);
9820b57cec5SDimitry Andric   if (emplace_result.second)
9830b57cec5SDimitry Andric     emplace_result.first->second = CreateFunction(func_id, comp_unit);
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   return emplace_result.first->second;
9860b57cec5SDimitry Andric }
9870b57cec5SDimitry Andric 
9880b57cec5SDimitry Andric CompUnitSP
GetOrCreateCompileUnit(const CompilandIndexItem & cci)9890b57cec5SDimitry Andric SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) {
9900b57cec5SDimitry Andric 
9910b57cec5SDimitry Andric   auto emplace_result =
9920b57cec5SDimitry Andric       m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr);
9930b57cec5SDimitry Andric   if (emplace_result.second)
9940b57cec5SDimitry Andric     emplace_result.first->second = CreateCompileUnit(cci);
9950b57cec5SDimitry Andric 
9960b57cec5SDimitry Andric   lldbassert(emplace_result.first->second);
9970b57cec5SDimitry Andric   return emplace_result.first->second;
9980b57cec5SDimitry Andric }
9990b57cec5SDimitry Andric 
GetOrCreateBlock(PdbCompilandSymId block_id)10000b57cec5SDimitry Andric Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) {
10010b57cec5SDimitry Andric   auto iter = m_blocks.find(toOpaqueUid(block_id));
10020b57cec5SDimitry Andric   if (iter != m_blocks.end())
10030b57cec5SDimitry Andric     return *iter->second;
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric   return CreateBlock(block_id);
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric 
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx)10080b57cec5SDimitry Andric void SymbolFileNativePDB::ParseDeclsForContext(
10090b57cec5SDimitry Andric     lldb_private::CompilerDeclContext decl_ctx) {
1010bdd1243dSDimitry Andric   TypeSystem* ts_or_err = decl_ctx.GetTypeSystem();
1011bdd1243dSDimitry Andric   if (!ts_or_err)
1012bdd1243dSDimitry Andric     return;
1013bdd1243dSDimitry Andric   PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();
1014bdd1243dSDimitry Andric   clang::DeclContext *context = ast_builder->FromCompilerDeclContext(decl_ctx);
10150b57cec5SDimitry Andric   if (!context)
10160b57cec5SDimitry Andric     return;
1017bdd1243dSDimitry Andric   ast_builder->ParseDeclsForContext(*context);
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
ParseCompileUnitAtIndex(uint32_t index)10200b57cec5SDimitry Andric lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
10210b57cec5SDimitry Andric   if (index >= GetNumCompileUnits())
10220b57cec5SDimitry Andric     return CompUnitSP();
10230b57cec5SDimitry Andric   lldbassert(index < UINT16_MAX);
10240b57cec5SDimitry Andric   if (index >= UINT16_MAX)
10250b57cec5SDimitry Andric     return nullptr;
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric   CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);
10280b57cec5SDimitry Andric 
10290b57cec5SDimitry Andric   return GetOrCreateCompileUnit(item);
10300b57cec5SDimitry Andric }
10310b57cec5SDimitry Andric 
ParseLanguage(CompileUnit & comp_unit)10320b57cec5SDimitry Andric lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
10339dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
10340b57cec5SDimitry Andric   PdbSymUid uid(comp_unit.GetID());
10350b57cec5SDimitry Andric   lldbassert(uid.kind() == PdbSymUidKind::Compiland);
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric   CompilandIndexItem *item =
10380b57cec5SDimitry Andric       m_index->compilands().GetCompiland(uid.asCompiland().modi);
10390b57cec5SDimitry Andric   lldbassert(item);
10400b57cec5SDimitry Andric   if (!item->m_compile_opts)
10410b57cec5SDimitry Andric     return lldb::eLanguageTypeUnknown;
10420b57cec5SDimitry Andric 
10430b57cec5SDimitry Andric   return TranslateLanguage(item->m_compile_opts->getLanguage());
10440b57cec5SDimitry Andric }
10450b57cec5SDimitry Andric 
AddSymbols(Symtab & symtab)10460eae32dcSDimitry Andric void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {}
10470b57cec5SDimitry Andric 
ParseFunctions(CompileUnit & comp_unit)10480b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
10499dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
10500b57cec5SDimitry Andric   PdbSymUid uid{comp_unit.GetID()};
10510b57cec5SDimitry Andric   lldbassert(uid.kind() == PdbSymUidKind::Compiland);
10520b57cec5SDimitry Andric   uint16_t modi = uid.asCompiland().modi;
10530b57cec5SDimitry Andric   CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric   size_t count = comp_unit.GetNumFunctions();
10560b57cec5SDimitry Andric   const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
10570b57cec5SDimitry Andric   for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
10580b57cec5SDimitry Andric     if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
10590b57cec5SDimitry Andric       continue;
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric     PdbCompilandSymId sym_id{modi, iter.offset()};
10620b57cec5SDimitry Andric 
10630b57cec5SDimitry Andric     FunctionSP func = GetOrCreateFunction(sym_id, comp_unit);
10640b57cec5SDimitry Andric   }
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric   size_t new_count = comp_unit.GetNumFunctions();
10670b57cec5SDimitry Andric   lldbassert(new_count >= count);
10680b57cec5SDimitry Andric   return new_count - count;
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric 
NeedsResolvedCompileUnit(uint32_t resolve_scope)10710b57cec5SDimitry Andric static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
10720b57cec5SDimitry Andric   // If any of these flags are set, we need to resolve the compile unit.
10730b57cec5SDimitry Andric   uint32_t flags = eSymbolContextCompUnit;
10740b57cec5SDimitry Andric   flags |= eSymbolContextVariable;
10750b57cec5SDimitry Andric   flags |= eSymbolContextFunction;
10760b57cec5SDimitry Andric   flags |= eSymbolContextBlock;
10770b57cec5SDimitry Andric   flags |= eSymbolContextLineEntry;
10780b57cec5SDimitry Andric   return (resolve_scope & flags) != 0;
10790b57cec5SDimitry Andric }
10800b57cec5SDimitry Andric 
ResolveSymbolContext(const Address & addr,SymbolContextItem resolve_scope,SymbolContext & sc)10810b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::ResolveSymbolContext(
10820b57cec5SDimitry Andric     const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
10839dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
10840b57cec5SDimitry Andric   uint32_t resolved_flags = 0;
10850b57cec5SDimitry Andric   lldb::addr_t file_addr = addr.GetFileAddress();
10860b57cec5SDimitry Andric 
10870b57cec5SDimitry Andric   if (NeedsResolvedCompileUnit(resolve_scope)) {
1088bdd1243dSDimitry Andric     std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);
10890b57cec5SDimitry Andric     if (!modi)
10900b57cec5SDimitry Andric       return 0;
109181ad6265SDimitry Andric     CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi);
1092349cc55cSDimitry Andric     if (!cu_sp)
10930b57cec5SDimitry Andric       return 0;
10940b57cec5SDimitry Andric 
1095349cc55cSDimitry Andric     sc.comp_unit = cu_sp.get();
10960b57cec5SDimitry Andric     resolved_flags |= eSymbolContextCompUnit;
10970b57cec5SDimitry Andric   }
10980b57cec5SDimitry Andric 
10990b57cec5SDimitry Andric   if (resolve_scope & eSymbolContextFunction ||
11000b57cec5SDimitry Andric       resolve_scope & eSymbolContextBlock) {
11010b57cec5SDimitry Andric     lldbassert(sc.comp_unit);
11020b57cec5SDimitry Andric     std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
11030b57cec5SDimitry Andric     // Search the matches in reverse.  This way if there are multiple matches
11040b57cec5SDimitry Andric     // (for example we are 3 levels deep in a nested scope) it will find the
11050b57cec5SDimitry Andric     // innermost one first.
11060b57cec5SDimitry Andric     for (const auto &match : llvm::reverse(matches)) {
11070b57cec5SDimitry Andric       if (match.uid.kind() != PdbSymUidKind::CompilandSym)
11080b57cec5SDimitry Andric         continue;
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric       PdbCompilandSymId csid = match.uid.asCompilandSym();
11110b57cec5SDimitry Andric       CVSymbol cvs = m_index->ReadSymbolRecord(csid);
11120b57cec5SDimitry Andric       PDB_SymType type = CVSymToPDBSym(cvs.kind());
11130b57cec5SDimitry Andric       if (type != PDB_SymType::Function && type != PDB_SymType::Block)
11140b57cec5SDimitry Andric         continue;
11150b57cec5SDimitry Andric       if (type == PDB_SymType::Function) {
11160b57cec5SDimitry Andric         sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
1117bdd1243dSDimitry Andric         if (sc.function) {
111804eeddc0SDimitry Andric           Block &block = sc.function->GetBlock(true);
111904eeddc0SDimitry Andric           addr_t func_base =
112004eeddc0SDimitry Andric               sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
112104eeddc0SDimitry Andric           addr_t offset = file_addr - func_base;
112204eeddc0SDimitry Andric           sc.block = block.FindInnermostBlockByOffset(offset);
11230b57cec5SDimitry Andric         }
1124bdd1243dSDimitry Andric       }
11250b57cec5SDimitry Andric 
11260b57cec5SDimitry Andric       if (type == PDB_SymType::Block) {
1127bdd1243dSDimitry Andric         Block &block = GetOrCreateBlock(csid);
1128bdd1243dSDimitry Andric         sc.function = block.CalculateSymbolContextFunction();
1129bdd1243dSDimitry Andric         if (sc.function) {
1130bdd1243dSDimitry Andric           sc.function->GetBlock(true);
1131bdd1243dSDimitry Andric           addr_t func_base =
1132bdd1243dSDimitry Andric               sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
1133bdd1243dSDimitry Andric           addr_t offset = file_addr - func_base;
1134bdd1243dSDimitry Andric           sc.block = block.FindInnermostBlockByOffset(offset);
1135bdd1243dSDimitry Andric         }
11360b57cec5SDimitry Andric       }
113704eeddc0SDimitry Andric       if (sc.function)
11380b57cec5SDimitry Andric         resolved_flags |= eSymbolContextFunction;
113904eeddc0SDimitry Andric       if (sc.block)
11400b57cec5SDimitry Andric         resolved_flags |= eSymbolContextBlock;
11410b57cec5SDimitry Andric       break;
11420b57cec5SDimitry Andric     }
11430b57cec5SDimitry Andric   }
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric   if (resolve_scope & eSymbolContextLineEntry) {
11460b57cec5SDimitry Andric     lldbassert(sc.comp_unit);
11470b57cec5SDimitry Andric     if (auto *line_table = sc.comp_unit->GetLineTable()) {
11480b57cec5SDimitry Andric       if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
11490b57cec5SDimitry Andric         resolved_flags |= eSymbolContextLineEntry;
11500b57cec5SDimitry Andric     }
11510b57cec5SDimitry Andric   }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric   return resolved_flags;
11540b57cec5SDimitry Andric }
11550b57cec5SDimitry Andric 
ResolveSymbolContext(const SourceLocationSpec & src_location_spec,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)11560b57cec5SDimitry Andric uint32_t SymbolFileNativePDB::ResolveSymbolContext(
1157fe6060f1SDimitry Andric     const SourceLocationSpec &src_location_spec,
11580b57cec5SDimitry Andric     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
115904eeddc0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
116004eeddc0SDimitry Andric   const uint32_t prev_size = sc_list.GetSize();
116104eeddc0SDimitry Andric   if (resolve_scope & eSymbolContextCompUnit) {
116204eeddc0SDimitry Andric     for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
116304eeddc0SDimitry Andric          ++cu_idx) {
116404eeddc0SDimitry Andric       CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get();
116504eeddc0SDimitry Andric       if (!cu)
116604eeddc0SDimitry Andric         continue;
116704eeddc0SDimitry Andric 
116804eeddc0SDimitry Andric       bool file_spec_matches_cu_file_spec = FileSpec::Match(
116904eeddc0SDimitry Andric           src_location_spec.GetFileSpec(), cu->GetPrimaryFile());
117004eeddc0SDimitry Andric       if (file_spec_matches_cu_file_spec) {
117104eeddc0SDimitry Andric         cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
117204eeddc0SDimitry Andric         break;
11730b57cec5SDimitry Andric       }
11740b57cec5SDimitry Andric     }
117504eeddc0SDimitry Andric   }
117604eeddc0SDimitry Andric   return sc_list.GetSize() - prev_size;
11770b57cec5SDimitry Andric }
11780b57cec5SDimitry Andric 
ParseLineTable(CompileUnit & comp_unit)11790b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
11800b57cec5SDimitry Andric   // Unfortunately LLDB is set up to parse the entire compile unit line table
11810b57cec5SDimitry Andric   // all at once, even if all it really needs is line info for a specific
11820b57cec5SDimitry Andric   // function.  In the future it would be nice if it could set the sc.m_function
11830b57cec5SDimitry Andric   // member, and we could only get the line info for the function in question.
11849dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
11850b57cec5SDimitry Andric   PdbSymUid cu_id(comp_unit.GetID());
11860b57cec5SDimitry Andric   lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
118704eeddc0SDimitry Andric   uint16_t modi = cu_id.asCompiland().modi;
118804eeddc0SDimitry Andric   CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi);
118904eeddc0SDimitry Andric   lldbassert(cii);
119004eeddc0SDimitry Andric 
119104eeddc0SDimitry Andric   // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records
119204eeddc0SDimitry Andric   // in this CU. Add line entries into the set first so that if there are line
119304eeddc0SDimitry Andric   // entries with same addres, the later is always more accurate than the
119404eeddc0SDimitry Andric   // former.
119504eeddc0SDimitry Andric   std::set<LineTable::Entry, LineTableEntryComparator> line_set;
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric   // This is basically a copy of the .debug$S subsections from all original COFF
11980b57cec5SDimitry Andric   // object files merged together with address relocations applied.  We are
11990b57cec5SDimitry Andric   // looking for all DEBUG_S_LINES subsections.
12000b57cec5SDimitry Andric   for (const DebugSubsectionRecord &dssr :
120104eeddc0SDimitry Andric        cii->m_debug_stream.getSubsectionsArray()) {
12020b57cec5SDimitry Andric     if (dssr.kind() != DebugSubsectionKind::Lines)
12030b57cec5SDimitry Andric       continue;
12040b57cec5SDimitry Andric 
12050b57cec5SDimitry Andric     DebugLinesSubsectionRef lines;
12060b57cec5SDimitry Andric     llvm::BinaryStreamReader reader(dssr.getRecordData());
12070b57cec5SDimitry Andric     if (auto EC = lines.initialize(reader)) {
12080b57cec5SDimitry Andric       llvm::consumeError(std::move(EC));
12090b57cec5SDimitry Andric       return false;
12100b57cec5SDimitry Andric     }
12110b57cec5SDimitry Andric 
12120b57cec5SDimitry Andric     const LineFragmentHeader *lfh = lines.header();
12130b57cec5SDimitry Andric     uint64_t virtual_addr =
12140b57cec5SDimitry Andric         m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
121581ad6265SDimitry Andric     if (virtual_addr == LLDB_INVALID_ADDRESS)
121681ad6265SDimitry Andric       continue;
12170b57cec5SDimitry Andric 
12180b57cec5SDimitry Andric     for (const LineColumnEntry &group : lines) {
121904eeddc0SDimitry Andric       llvm::Expected<uint32_t> file_index_or_err =
122004eeddc0SDimitry Andric           GetFileIndex(*cii, group.NameIndex);
122104eeddc0SDimitry Andric       if (!file_index_or_err)
12220b57cec5SDimitry Andric         continue;
122304eeddc0SDimitry Andric       uint32_t file_index = file_index_or_err.get();
12240b57cec5SDimitry Andric       lldbassert(!group.LineNumbers.empty());
122504eeddc0SDimitry Andric       CompilandIndexItem::GlobalLineTable::Entry line_entry(
122604eeddc0SDimitry Andric           LLDB_INVALID_ADDRESS, 0);
12270b57cec5SDimitry Andric       for (const LineNumberEntry &entry : group.LineNumbers) {
122804eeddc0SDimitry Andric         LineInfo cur_info(entry.Flags);
122904eeddc0SDimitry Andric 
123004eeddc0SDimitry Andric         if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
123104eeddc0SDimitry Andric           continue;
123204eeddc0SDimitry Andric 
123304eeddc0SDimitry Andric         uint64_t addr = virtual_addr + entry.Offset;
123404eeddc0SDimitry Andric 
123504eeddc0SDimitry Andric         bool is_statement = cur_info.isStatement();
123604eeddc0SDimitry Andric         bool is_prologue = IsFunctionPrologue(*cii, addr);
123704eeddc0SDimitry Andric         bool is_epilogue = IsFunctionEpilogue(*cii, addr);
123804eeddc0SDimitry Andric 
123904eeddc0SDimitry Andric         uint32_t lno = cur_info.getStartLine();
124004eeddc0SDimitry Andric 
124181ad6265SDimitry Andric         LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false,
124204eeddc0SDimitry Andric                                  is_prologue, is_epilogue, false);
124381ad6265SDimitry Andric         // Terminal entry has lower precedence than new entry.
124481ad6265SDimitry Andric         auto iter = line_set.find(new_entry);
124581ad6265SDimitry Andric         if (iter != line_set.end() && iter->is_terminal_entry)
124681ad6265SDimitry Andric           line_set.erase(iter);
124781ad6265SDimitry Andric         line_set.insert(new_entry);
124804eeddc0SDimitry Andric 
124904eeddc0SDimitry Andric         if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
125004eeddc0SDimitry Andric           line_entry.SetRangeEnd(addr);
125104eeddc0SDimitry Andric           cii->m_global_line_table.Append(line_entry);
125204eeddc0SDimitry Andric         }
125304eeddc0SDimitry Andric         line_entry.SetRangeBase(addr);
125404eeddc0SDimitry Andric         line_entry.data = {file_index, lno};
12550b57cec5SDimitry Andric       }
12560b57cec5SDimitry Andric       LineInfo last_line(group.LineNumbers.back().Flags);
125704eeddc0SDimitry Andric       line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
125804eeddc0SDimitry Andric                        file_index, false, false, false, false, true);
125904eeddc0SDimitry Andric 
126004eeddc0SDimitry Andric       if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
126104eeddc0SDimitry Andric         line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize);
126204eeddc0SDimitry Andric         cii->m_global_line_table.Append(line_entry);
12630b57cec5SDimitry Andric       }
12640b57cec5SDimitry Andric     }
126504eeddc0SDimitry Andric   }
126604eeddc0SDimitry Andric 
126704eeddc0SDimitry Andric   cii->m_global_line_table.Sort();
126804eeddc0SDimitry Andric 
126904eeddc0SDimitry Andric   // Parse all S_INLINESITE in this CU.
127004eeddc0SDimitry Andric   const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray();
127104eeddc0SDimitry Andric   for (auto iter = syms.begin(); iter != syms.end();) {
127204eeddc0SDimitry Andric     if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
127304eeddc0SDimitry Andric       ++iter;
127404eeddc0SDimitry Andric       continue;
127504eeddc0SDimitry Andric     }
127604eeddc0SDimitry Andric 
127704eeddc0SDimitry Andric     uint32_t record_offset = iter.offset();
127804eeddc0SDimitry Andric     CVSymbol func_record =
127904eeddc0SDimitry Andric         cii->m_debug_stream.readSymbolAtOffset(record_offset);
128004eeddc0SDimitry Andric     SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record);
128181ad6265SDimitry Andric     addr_t file_vm_addr =
128281ad6265SDimitry Andric         m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
128381ad6265SDimitry Andric     if (file_vm_addr == LLDB_INVALID_ADDRESS)
128481ad6265SDimitry Andric       continue;
128581ad6265SDimitry Andric 
128604eeddc0SDimitry Andric     AddressRange func_range(file_vm_addr, sol.length,
128704eeddc0SDimitry Andric                             comp_unit.GetModule()->GetSectionList());
128804eeddc0SDimitry Andric     Address func_base = func_range.GetBaseAddress();
128904eeddc0SDimitry Andric     PdbCompilandSymId func_id{modi, record_offset};
129004eeddc0SDimitry Andric 
129104eeddc0SDimitry Andric     // Iterate all S_INLINESITEs in the function.
129204eeddc0SDimitry Andric     auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) {
129304eeddc0SDimitry Andric       if (kind != S_INLINESITE)
129404eeddc0SDimitry Andric         return false;
129504eeddc0SDimitry Andric 
129604eeddc0SDimitry Andric       ParseInlineSite(id, func_base);
129704eeddc0SDimitry Andric 
129804eeddc0SDimitry Andric       for (const auto &line_entry :
129904eeddc0SDimitry Andric            m_inline_sites[toOpaqueUid(id)]->line_entries) {
130004eeddc0SDimitry Andric         // If line_entry is not terminal entry, remove previous line entry at
130104eeddc0SDimitry Andric         // the same address and insert new one. Terminal entry inside an inline
130204eeddc0SDimitry Andric         // site might not be terminal entry for its parent.
130304eeddc0SDimitry Andric         if (!line_entry.is_terminal_entry)
130404eeddc0SDimitry Andric           line_set.erase(line_entry);
130504eeddc0SDimitry Andric         line_set.insert(line_entry);
130604eeddc0SDimitry Andric       }
130704eeddc0SDimitry Andric       // No longer useful after adding to line_set.
130804eeddc0SDimitry Andric       m_inline_sites[toOpaqueUid(id)]->line_entries.clear();
130904eeddc0SDimitry Andric       return true;
131004eeddc0SDimitry Andric     };
131104eeddc0SDimitry Andric     ParseSymbolArrayInScope(func_id, parse_inline_sites);
131204eeddc0SDimitry Andric     // Jump to the end of the function record.
131304eeddc0SDimitry Andric     iter = syms.at(getScopeEndOffset(func_record));
131404eeddc0SDimitry Andric   }
131504eeddc0SDimitry Andric 
131604eeddc0SDimitry Andric   cii->m_global_line_table.Clear();
131704eeddc0SDimitry Andric 
131804eeddc0SDimitry Andric   // Add line entries in line_set to line_table.
131904eeddc0SDimitry Andric   auto line_table = std::make_unique<LineTable>(&comp_unit);
132004eeddc0SDimitry Andric   std::unique_ptr<LineSequence> sequence(
132104eeddc0SDimitry Andric       line_table->CreateLineSequenceContainer());
132204eeddc0SDimitry Andric   for (const auto &line_entry : line_set) {
132304eeddc0SDimitry Andric     line_table->AppendLineEntryToSequence(
132404eeddc0SDimitry Andric         sequence.get(), line_entry.file_addr, line_entry.line,
132504eeddc0SDimitry Andric         line_entry.column, line_entry.file_idx,
132604eeddc0SDimitry Andric         line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
132704eeddc0SDimitry Andric         line_entry.is_prologue_end, line_entry.is_epilogue_begin,
132804eeddc0SDimitry Andric         line_entry.is_terminal_entry);
132904eeddc0SDimitry Andric   }
133004eeddc0SDimitry Andric   line_table->InsertSequence(sequence.get());
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric   if (line_table->GetSize() == 0)
13330b57cec5SDimitry Andric     return false;
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric   comp_unit.SetLineTable(line_table.release());
13360b57cec5SDimitry Andric   return true;
13370b57cec5SDimitry Andric }
13380b57cec5SDimitry Andric 
ParseDebugMacros(CompileUnit & comp_unit)13390b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
13400b57cec5SDimitry Andric   // PDB doesn't contain information about macros
13410b57cec5SDimitry Andric   return false;
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric 
134404eeddc0SDimitry Andric llvm::Expected<uint32_t>
GetFileIndex(const CompilandIndexItem & cii,uint32_t file_id)134504eeddc0SDimitry Andric SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii,
134604eeddc0SDimitry Andric                                   uint32_t file_id) {
134706c3fb27SDimitry Andric   if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings())
134806c3fb27SDimitry Andric     return llvm::make_error<RawError>(raw_error_code::no_entry);
134906c3fb27SDimitry Andric 
135004eeddc0SDimitry Andric   const auto &checksums = cii.m_strings.checksums().getArray();
135104eeddc0SDimitry Andric   const auto &strings = cii.m_strings.strings();
135204eeddc0SDimitry Andric   // Indices in this structure are actually offsets of records in the
135304eeddc0SDimitry Andric   // DEBUG_S_FILECHECKSUMS subsection.  Those entries then have an index
135404eeddc0SDimitry Andric   // into the global PDB string table.
135504eeddc0SDimitry Andric   auto iter = checksums.at(file_id);
135604eeddc0SDimitry Andric   if (iter == checksums.end())
135704eeddc0SDimitry Andric     return llvm::make_error<RawError>(raw_error_code::no_entry);
135804eeddc0SDimitry Andric 
135904eeddc0SDimitry Andric   llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
136004eeddc0SDimitry Andric   if (!efn) {
136104eeddc0SDimitry Andric     return efn.takeError();
136204eeddc0SDimitry Andric   }
136304eeddc0SDimitry Andric 
136404eeddc0SDimitry Andric   // LLDB wants the index of the file in the list of support files.
136504eeddc0SDimitry Andric   auto fn_iter = llvm::find(cii.m_file_list, *efn);
136681ad6265SDimitry Andric   if (fn_iter != cii.m_file_list.end())
136781ad6265SDimitry Andric     return std::distance(cii.m_file_list.begin(), fn_iter);
136881ad6265SDimitry Andric   return llvm::make_error<RawError>(raw_error_code::no_entry);
136904eeddc0SDimitry Andric }
137004eeddc0SDimitry Andric 
ParseSupportFiles(CompileUnit & comp_unit,SupportFileList & support_files)13710b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
13721db9f3b2SDimitry Andric                                             SupportFileList &support_files) {
13739dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
13740b57cec5SDimitry Andric   PdbSymUid cu_id(comp_unit.GetID());
13750b57cec5SDimitry Andric   lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
13760b57cec5SDimitry Andric   CompilandIndexItem *cci =
13770b57cec5SDimitry Andric       m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
13780b57cec5SDimitry Andric   lldbassert(cci);
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric   for (llvm::StringRef f : cci->m_file_list) {
13810b57cec5SDimitry Andric     FileSpec::Style style =
13825f757f3fSDimitry Andric         f.starts_with("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
13830b57cec5SDimitry Andric     FileSpec spec(f, style);
13840b57cec5SDimitry Andric     support_files.Append(spec);
13850b57cec5SDimitry Andric   }
13860b57cec5SDimitry Andric   return true;
13870b57cec5SDimitry Andric }
13880b57cec5SDimitry Andric 
ParseImportedModules(const SymbolContext & sc,std::vector<SourceModule> & imported_modules)13890b57cec5SDimitry Andric bool SymbolFileNativePDB::ParseImportedModules(
13900b57cec5SDimitry Andric     const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
13910b57cec5SDimitry Andric   // PDB does not yet support module debug info
13920b57cec5SDimitry Andric   return false;
13930b57cec5SDimitry Andric }
13940b57cec5SDimitry Andric 
ParseInlineSite(PdbCompilandSymId id,Address func_addr)139504eeddc0SDimitry Andric void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
139604eeddc0SDimitry Andric                                           Address func_addr) {
139704eeddc0SDimitry Andric   lldb::user_id_t opaque_uid = toOpaqueUid(id);
139806c3fb27SDimitry Andric   if (m_inline_sites.contains(opaque_uid))
139904eeddc0SDimitry Andric     return;
140004eeddc0SDimitry Andric 
140104eeddc0SDimitry Andric   addr_t func_base = func_addr.GetFileAddress();
140204eeddc0SDimitry Andric   CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi);
140304eeddc0SDimitry Andric   CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset);
140404eeddc0SDimitry Andric   CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
140504eeddc0SDimitry Andric 
140604eeddc0SDimitry Andric   InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
140704eeddc0SDimitry Andric   cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
140804eeddc0SDimitry Andric   PdbCompilandSymId parent_id(id.modi, inline_site.Parent);
140904eeddc0SDimitry Andric 
141004eeddc0SDimitry Andric   std::shared_ptr<InlineSite> inline_site_sp =
141104eeddc0SDimitry Andric       std::make_shared<InlineSite>(parent_id);
141204eeddc0SDimitry Andric 
141304eeddc0SDimitry Andric   // Get the inlined function declaration info.
141404eeddc0SDimitry Andric   auto iter = cii->m_inline_map.find(inline_site.Inlinee);
141504eeddc0SDimitry Andric   if (iter == cii->m_inline_map.end())
141604eeddc0SDimitry Andric     return;
141704eeddc0SDimitry Andric   InlineeSourceLine inlinee_line = iter->second;
141804eeddc0SDimitry Andric 
14191db9f3b2SDimitry Andric   const SupportFileList &files = comp_unit->GetSupportFiles();
142004eeddc0SDimitry Andric   FileSpec decl_file;
142104eeddc0SDimitry Andric   llvm::Expected<uint32_t> file_index_or_err =
142204eeddc0SDimitry Andric       GetFileIndex(*cii, inlinee_line.Header->FileID);
142304eeddc0SDimitry Andric   if (!file_index_or_err)
142404eeddc0SDimitry Andric     return;
142581ad6265SDimitry Andric   uint32_t file_offset = file_index_or_err.get();
142681ad6265SDimitry Andric   decl_file = files.GetFileSpecAtIndex(file_offset);
142704eeddc0SDimitry Andric   uint32_t decl_line = inlinee_line.Header->SourceLineNum;
142804eeddc0SDimitry Andric   std::unique_ptr<Declaration> decl_up =
142904eeddc0SDimitry Andric       std::make_unique<Declaration>(decl_file, decl_line);
143004eeddc0SDimitry Andric 
143104eeddc0SDimitry Andric   // Parse range and line info.
143204eeddc0SDimitry Andric   uint32_t code_offset = 0;
143304eeddc0SDimitry Andric   int32_t line_offset = 0;
1434bdd1243dSDimitry Andric   std::optional<uint32_t> code_offset_base;
1435bdd1243dSDimitry Andric   std::optional<uint32_t> code_offset_end;
1436bdd1243dSDimitry Andric   std::optional<int32_t> cur_line_offset;
1437bdd1243dSDimitry Andric   std::optional<int32_t> next_line_offset;
1438bdd1243dSDimitry Andric   std::optional<uint32_t> next_file_offset;
143904eeddc0SDimitry Andric 
144081ad6265SDimitry Andric   bool is_terminal_entry = false;
144181ad6265SDimitry Andric   bool is_start_of_statement = true;
144204eeddc0SDimitry Andric   // The first instruction is the prologue end.
144304eeddc0SDimitry Andric   bool is_prologue_end = true;
144404eeddc0SDimitry Andric 
144581ad6265SDimitry Andric   auto update_code_offset = [&](uint32_t code_delta) {
144681ad6265SDimitry Andric     if (!code_offset_base)
144781ad6265SDimitry Andric       code_offset_base = code_offset;
144881ad6265SDimitry Andric     else if (!code_offset_end)
144981ad6265SDimitry Andric       code_offset_end = *code_offset_base + code_delta;
145004eeddc0SDimitry Andric   };
145181ad6265SDimitry Andric   auto update_line_offset = [&](int32_t line_delta) {
145204eeddc0SDimitry Andric     line_offset += line_delta;
145381ad6265SDimitry Andric     if (!code_offset_base || !cur_line_offset)
145481ad6265SDimitry Andric       cur_line_offset = line_offset;
145581ad6265SDimitry Andric     else
145681ad6265SDimitry Andric       next_line_offset = line_offset;
145781ad6265SDimitry Andric     ;
145881ad6265SDimitry Andric   };
145981ad6265SDimitry Andric   auto update_file_offset = [&](uint32_t offset) {
146081ad6265SDimitry Andric     if (!code_offset_base)
146181ad6265SDimitry Andric       file_offset = offset;
146281ad6265SDimitry Andric     else
146381ad6265SDimitry Andric       next_file_offset = offset;
146404eeddc0SDimitry Andric   };
146504eeddc0SDimitry Andric 
146604eeddc0SDimitry Andric   for (auto &annot : inline_site.annotations()) {
146704eeddc0SDimitry Andric     switch (annot.OpCode) {
146804eeddc0SDimitry Andric     case BinaryAnnotationsOpCode::CodeOffset:
146904eeddc0SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeOffset:
147004eeddc0SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
147181ad6265SDimitry Andric       code_offset += annot.U1;
147281ad6265SDimitry Andric       update_code_offset(annot.U1);
147304eeddc0SDimitry Andric       break;
147404eeddc0SDimitry Andric     case BinaryAnnotationsOpCode::ChangeLineOffset:
147581ad6265SDimitry Andric       update_line_offset(annot.S1);
147604eeddc0SDimitry Andric       break;
147704eeddc0SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeLength:
147881ad6265SDimitry Andric       update_code_offset(annot.U1);
147904eeddc0SDimitry Andric       code_offset += annot.U1;
148081ad6265SDimitry Andric       is_terminal_entry = true;
148104eeddc0SDimitry Andric       break;
148204eeddc0SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
148381ad6265SDimitry Andric       code_offset += annot.U1;
148481ad6265SDimitry Andric       update_code_offset(annot.U1);
148581ad6265SDimitry Andric       update_line_offset(annot.S1);
148604eeddc0SDimitry Andric       break;
148704eeddc0SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
148881ad6265SDimitry Andric       code_offset += annot.U2;
148981ad6265SDimitry Andric       update_code_offset(annot.U2);
149081ad6265SDimitry Andric       update_code_offset(annot.U1);
149181ad6265SDimitry Andric       code_offset += annot.U1;
149281ad6265SDimitry Andric       is_terminal_entry = true;
149381ad6265SDimitry Andric       break;
149481ad6265SDimitry Andric     case BinaryAnnotationsOpCode::ChangeFile:
149581ad6265SDimitry Andric       update_file_offset(annot.U1);
149604eeddc0SDimitry Andric       break;
149704eeddc0SDimitry Andric     default:
149804eeddc0SDimitry Andric       break;
149904eeddc0SDimitry Andric     }
150081ad6265SDimitry Andric 
150181ad6265SDimitry Andric     // Add range if current range is finished.
150281ad6265SDimitry Andric     if (code_offset_base && code_offset_end && cur_line_offset) {
150381ad6265SDimitry Andric       inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
150481ad6265SDimitry Andric           *code_offset_base, *code_offset_end - *code_offset_base,
150581ad6265SDimitry Andric           decl_line + *cur_line_offset));
150681ad6265SDimitry Andric       // Set base, end, file offset and line offset for next range.
150781ad6265SDimitry Andric       if (next_file_offset)
150881ad6265SDimitry Andric         file_offset = *next_file_offset;
150981ad6265SDimitry Andric       if (next_line_offset) {
151081ad6265SDimitry Andric         cur_line_offset = next_line_offset;
1511bdd1243dSDimitry Andric         next_line_offset = std::nullopt;
151281ad6265SDimitry Andric       }
1513bdd1243dSDimitry Andric       code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;
1514bdd1243dSDimitry Andric       code_offset_end = next_file_offset = std::nullopt;
151581ad6265SDimitry Andric     }
151681ad6265SDimitry Andric     if (code_offset_base && cur_line_offset) {
151781ad6265SDimitry Andric       if (is_terminal_entry) {
151881ad6265SDimitry Andric         LineTable::Entry line_entry(
151981ad6265SDimitry Andric             func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
152081ad6265SDimitry Andric             file_offset, false, false, false, false, true);
152181ad6265SDimitry Andric         inline_site_sp->line_entries.push_back(line_entry);
152281ad6265SDimitry Andric       } else {
152381ad6265SDimitry Andric         LineTable::Entry line_entry(func_base + *code_offset_base,
152481ad6265SDimitry Andric                                     decl_line + *cur_line_offset, 0,
152581ad6265SDimitry Andric                                     file_offset, is_start_of_statement, false,
152681ad6265SDimitry Andric                                     is_prologue_end, false, false);
152781ad6265SDimitry Andric         inline_site_sp->line_entries.push_back(line_entry);
152881ad6265SDimitry Andric         is_prologue_end = false;
152981ad6265SDimitry Andric         is_start_of_statement = false;
153081ad6265SDimitry Andric       }
153181ad6265SDimitry Andric     }
153281ad6265SDimitry Andric     if (is_terminal_entry)
153381ad6265SDimitry Andric       is_start_of_statement = true;
153481ad6265SDimitry Andric     is_terminal_entry = false;
153504eeddc0SDimitry Andric   }
153604eeddc0SDimitry Andric 
153704eeddc0SDimitry Andric   inline_site_sp->ranges.Sort();
153804eeddc0SDimitry Andric 
153904eeddc0SDimitry Andric   // Get the inlined function callsite info.
154004eeddc0SDimitry Andric   std::unique_ptr<Declaration> callsite_up;
154104eeddc0SDimitry Andric   if (!inline_site_sp->ranges.IsEmpty()) {
154204eeddc0SDimitry Andric     auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
154304eeddc0SDimitry Andric     addr_t base_offset = entry->GetRangeBase();
154404eeddc0SDimitry Andric     if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() ==
154504eeddc0SDimitry Andric         S_INLINESITE) {
154604eeddc0SDimitry Andric       // Its parent is another inline site, lookup parent site's range vector
154704eeddc0SDimitry Andric       // for callsite line.
154804eeddc0SDimitry Andric       ParseInlineSite(parent_id, func_base);
154904eeddc0SDimitry Andric       std::shared_ptr<InlineSite> parent_site =
155004eeddc0SDimitry Andric           m_inline_sites[toOpaqueUid(parent_id)];
155104eeddc0SDimitry Andric       FileSpec &parent_decl_file =
155204eeddc0SDimitry Andric           parent_site->inline_function_info->GetDeclaration().GetFile();
155304eeddc0SDimitry Andric       if (auto *parent_entry =
155404eeddc0SDimitry Andric               parent_site->ranges.FindEntryThatContains(base_offset)) {
155504eeddc0SDimitry Andric         callsite_up =
155604eeddc0SDimitry Andric             std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
155704eeddc0SDimitry Andric       }
155804eeddc0SDimitry Andric     } else {
155904eeddc0SDimitry Andric       // Its parent is a function, lookup global line table for callsite.
156004eeddc0SDimitry Andric       if (auto *entry = cii->m_global_line_table.FindEntryThatContains(
156104eeddc0SDimitry Andric               func_base + base_offset)) {
156204eeddc0SDimitry Andric         const FileSpec &callsite_file =
156304eeddc0SDimitry Andric             files.GetFileSpecAtIndex(entry->data.first);
156404eeddc0SDimitry Andric         callsite_up =
156504eeddc0SDimitry Andric             std::make_unique<Declaration>(callsite_file, entry->data.second);
156604eeddc0SDimitry Andric       }
156704eeddc0SDimitry Andric     }
156804eeddc0SDimitry Andric   }
156904eeddc0SDimitry Andric 
157004eeddc0SDimitry Andric   // Get the inlined function name.
157104eeddc0SDimitry Andric   CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee);
157204eeddc0SDimitry Andric   std::string inlinee_name;
157304eeddc0SDimitry Andric   if (inlinee_cvt.kind() == LF_MFUNC_ID) {
157404eeddc0SDimitry Andric     MemberFuncIdRecord mfr;
157504eeddc0SDimitry Andric     cantFail(
157604eeddc0SDimitry Andric         TypeDeserializer::deserializeAs<MemberFuncIdRecord>(inlinee_cvt, mfr));
157704eeddc0SDimitry Andric     LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
157804eeddc0SDimitry Andric     inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
157904eeddc0SDimitry Andric     inlinee_name.append("::");
158004eeddc0SDimitry Andric     inlinee_name.append(mfr.getName().str());
158104eeddc0SDimitry Andric   } else if (inlinee_cvt.kind() == LF_FUNC_ID) {
158204eeddc0SDimitry Andric     FuncIdRecord fir;
158304eeddc0SDimitry Andric     cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(inlinee_cvt, fir));
158404eeddc0SDimitry Andric     TypeIndex parent_idx = fir.getParentScope();
158504eeddc0SDimitry Andric     if (!parent_idx.isNoneType()) {
158604eeddc0SDimitry Andric       LazyRandomTypeCollection &ids = m_index->ipi().typeCollection();
158704eeddc0SDimitry Andric       inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
158804eeddc0SDimitry Andric       inlinee_name.append("::");
158904eeddc0SDimitry Andric     }
159004eeddc0SDimitry Andric     inlinee_name.append(fir.getName().str());
159104eeddc0SDimitry Andric   }
159204eeddc0SDimitry Andric   inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
159304eeddc0SDimitry Andric       inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
159404eeddc0SDimitry Andric       callsite_up.get());
159504eeddc0SDimitry Andric 
159604eeddc0SDimitry Andric   m_inline_sites[opaque_uid] = inline_site_sp;
159704eeddc0SDimitry Andric }
159804eeddc0SDimitry Andric 
ParseBlocksRecursive(Function & func)15990b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
16009dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
160104eeddc0SDimitry Andric   PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym();
160204eeddc0SDimitry Andric   // After we iterate through inline sites inside the function, we already get
160304eeddc0SDimitry Andric   // all the info needed, removing from the map to save memory.
160404eeddc0SDimitry Andric   std::set<uint64_t> remove_uids;
160504eeddc0SDimitry Andric   auto parse_blocks = [&](SymbolKind kind, PdbCompilandSymId id) {
160604eeddc0SDimitry Andric     if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
160704eeddc0SDimitry Andric         kind == S_INLINESITE) {
160804eeddc0SDimitry Andric       GetOrCreateBlock(id);
160904eeddc0SDimitry Andric       if (kind == S_INLINESITE)
161004eeddc0SDimitry Andric         remove_uids.insert(toOpaqueUid(id));
161104eeddc0SDimitry Andric       return true;
161204eeddc0SDimitry Andric     }
161304eeddc0SDimitry Andric     return false;
161404eeddc0SDimitry Andric   };
161504eeddc0SDimitry Andric   size_t count = ParseSymbolArrayInScope(func_id, parse_blocks);
161604eeddc0SDimitry Andric   for (uint64_t uid : remove_uids) {
161704eeddc0SDimitry Andric     m_inline_sites.erase(uid);
161804eeddc0SDimitry Andric   }
161904eeddc0SDimitry Andric   return count;
162004eeddc0SDimitry Andric }
162104eeddc0SDimitry Andric 
ParseSymbolArrayInScope(PdbCompilandSymId parent_id,llvm::function_ref<bool (SymbolKind,PdbCompilandSymId)> fn)162204eeddc0SDimitry Andric size_t SymbolFileNativePDB::ParseSymbolArrayInScope(
162304eeddc0SDimitry Andric     PdbCompilandSymId parent_id,
162404eeddc0SDimitry Andric     llvm::function_ref<bool(SymbolKind, PdbCompilandSymId)> fn) {
162504eeddc0SDimitry Andric   CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi);
162604eeddc0SDimitry Andric   CVSymbolArray syms =
162704eeddc0SDimitry Andric       cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset);
162804eeddc0SDimitry Andric 
162904eeddc0SDimitry Andric   size_t count = 1;
163004eeddc0SDimitry Andric   for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
163104eeddc0SDimitry Andric     PdbCompilandSymId child_id(parent_id.modi, iter.offset());
163204eeddc0SDimitry Andric     if (fn(iter->kind(), child_id))
163304eeddc0SDimitry Andric       ++count;
163404eeddc0SDimitry Andric   }
163504eeddc0SDimitry Andric 
163604eeddc0SDimitry Andric   return count;
16370b57cec5SDimitry Andric }
16380b57cec5SDimitry Andric 
DumpClangAST(Stream & s)1639bdd1243dSDimitry Andric void SymbolFileNativePDB::DumpClangAST(Stream &s) {
1640bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
1641bdd1243dSDimitry Andric   if (!ts_or_err)
1642bdd1243dSDimitry Andric     return;
1643bdd1243dSDimitry Andric   auto ts = *ts_or_err;
1644bdd1243dSDimitry Andric   TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
1645bdd1243dSDimitry Andric   if (!clang)
1646bdd1243dSDimitry Andric     return;
1647bdd1243dSDimitry Andric   clang->GetNativePDBParser()->Dump(s);
1648bdd1243dSDimitry Andric }
16490b57cec5SDimitry Andric 
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,uint32_t max_matches,VariableList & variables)16509dba64beSDimitry Andric void SymbolFileNativePDB::FindGlobalVariables(
16515ffd83dbSDimitry Andric     ConstString name, const CompilerDeclContext &parent_decl_ctx,
16520b57cec5SDimitry Andric     uint32_t max_matches, VariableList &variables) {
16539dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
16540b57cec5SDimitry Andric   using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
16550b57cec5SDimitry Andric 
16560b57cec5SDimitry Andric   std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
16570b57cec5SDimitry Andric       name.GetStringRef(), m_index->symrecords());
16580b57cec5SDimitry Andric   for (const SymbolAndOffset &result : results) {
16590b57cec5SDimitry Andric     switch (result.second.kind()) {
16600b57cec5SDimitry Andric     case SymbolKind::S_GDATA32:
16610b57cec5SDimitry Andric     case SymbolKind::S_LDATA32:
16620b57cec5SDimitry Andric     case SymbolKind::S_GTHREAD32:
16630b57cec5SDimitry Andric     case SymbolKind::S_LTHREAD32:
16640b57cec5SDimitry Andric     case SymbolKind::S_CONSTANT: {
16650b57cec5SDimitry Andric       PdbGlobalSymId global(result.first, false);
166681ad6265SDimitry Andric       if (VariableSP var = GetOrCreateGlobalVariable(global))
16670b57cec5SDimitry Andric         variables.AddVariable(var);
16680b57cec5SDimitry Andric       break;
16690b57cec5SDimitry Andric     }
16700b57cec5SDimitry Andric     default:
16710b57cec5SDimitry Andric       continue;
16720b57cec5SDimitry Andric     }
16730b57cec5SDimitry Andric   }
16740b57cec5SDimitry Andric }
16750b57cec5SDimitry Andric 
FindFunctions(const Module::LookupInfo & lookup_info,const CompilerDeclContext & parent_decl_ctx,bool include_inlines,SymbolContextList & sc_list)16769dba64beSDimitry Andric void SymbolFileNativePDB::FindFunctions(
1677bdd1243dSDimitry Andric     const Module::LookupInfo &lookup_info,
1678bdd1243dSDimitry Andric     const CompilerDeclContext &parent_decl_ctx, bool include_inlines,
16790b57cec5SDimitry Andric     SymbolContextList &sc_list) {
16809dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1681bdd1243dSDimitry Andric   ConstString name = lookup_info.GetLookupName();
1682bdd1243dSDimitry Andric   FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
1683bdd1243dSDimitry Andric   if (name_type_mask & eFunctionNameTypeFull)
1684bdd1243dSDimitry Andric     name = lookup_info.GetName();
1685bdd1243dSDimitry Andric 
16864824e7fdSDimitry Andric   // For now we only support lookup by method name or full name.
16874824e7fdSDimitry Andric   if (!(name_type_mask & eFunctionNameTypeFull ||
16884824e7fdSDimitry Andric         name_type_mask & eFunctionNameTypeMethod))
16899dba64beSDimitry Andric     return;
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric   using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
16920b57cec5SDimitry Andric 
16930b57cec5SDimitry Andric   std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName(
16940b57cec5SDimitry Andric       name.GetStringRef(), m_index->symrecords());
16950b57cec5SDimitry Andric   for (const SymbolAndOffset &match : matches) {
16960b57cec5SDimitry Andric     if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
16970b57cec5SDimitry Andric       continue;
16980b57cec5SDimitry Andric     ProcRefSym proc(match.second.kind());
16990b57cec5SDimitry Andric     cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc));
17000b57cec5SDimitry Andric 
17010b57cec5SDimitry Andric     if (!IsValidRecord(proc))
17020b57cec5SDimitry Andric       continue;
17030b57cec5SDimitry Andric 
17040b57cec5SDimitry Andric     CompilandIndexItem &cci =
17050b57cec5SDimitry Andric         m_index->compilands().GetOrCreateCompiland(proc.modi());
17060b57cec5SDimitry Andric     SymbolContext sc;
17070b57cec5SDimitry Andric 
17080b57cec5SDimitry Andric     sc.comp_unit = GetOrCreateCompileUnit(cci).get();
17090b57cec5SDimitry Andric     PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
17100b57cec5SDimitry Andric     sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
17110b57cec5SDimitry Andric 
17120b57cec5SDimitry Andric     sc_list.Append(sc);
17130b57cec5SDimitry Andric   }
17140b57cec5SDimitry Andric }
17150b57cec5SDimitry Andric 
FindFunctions(const RegularExpression & regex,bool include_inlines,SymbolContextList & sc_list)17169dba64beSDimitry Andric void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
17179dba64beSDimitry Andric                                         bool include_inlines,
17189dba64beSDimitry Andric                                         SymbolContextList &sc_list) {}
17190b57cec5SDimitry Andric 
FindTypes(const lldb_private::TypeQuery & query,lldb_private::TypeResults & results)17205f757f3fSDimitry Andric void SymbolFileNativePDB::FindTypes(const lldb_private::TypeQuery &query,
17215f757f3fSDimitry Andric                                     lldb_private::TypeResults &results) {
17225f757f3fSDimitry Andric 
17235f757f3fSDimitry Andric   // Make sure we haven't already searched this SymbolFile before.
17245f757f3fSDimitry Andric   if (results.AlreadySearched(this))
17259dba64beSDimitry Andric     return;
17260b57cec5SDimitry Andric 
17275f757f3fSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
17280b57cec5SDimitry Andric 
17295f757f3fSDimitry Andric   std::vector<TypeIndex> matches =
17305f757f3fSDimitry Andric       m_index->tpi().findRecordsByName(query.GetTypeBasename().GetStringRef());
17315f757f3fSDimitry Andric 
17325f757f3fSDimitry Andric   for (TypeIndex type_idx : matches) {
17335f757f3fSDimitry Andric     TypeSP type_sp = GetOrCreateType(type_idx);
17345f757f3fSDimitry Andric     if (!type_sp)
17355f757f3fSDimitry Andric       continue;
17365f757f3fSDimitry Andric 
17375f757f3fSDimitry Andric     // We resolved a type. Get the fully qualified name to ensure it matches.
17385f757f3fSDimitry Andric     ConstString name = type_sp->GetQualifiedName();
17395f757f3fSDimitry Andric     TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match);
17405f757f3fSDimitry Andric     if (query.ContextMatches(type_match.GetContextRef())) {
17415f757f3fSDimitry Andric       results.InsertUnique(type_sp);
17425f757f3fSDimitry Andric       if (results.Done(query))
17435f757f3fSDimitry Andric         return;
17440b57cec5SDimitry Andric     }
17455f757f3fSDimitry Andric   }
17465f757f3fSDimitry Andric }
17470b57cec5SDimitry Andric 
FindTypesByName(llvm::StringRef name,uint32_t max_matches,TypeMap & types)17489dba64beSDimitry Andric void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
17490b57cec5SDimitry Andric                                           uint32_t max_matches,
17500b57cec5SDimitry Andric                                           TypeMap &types) {
17510b57cec5SDimitry Andric 
17520b57cec5SDimitry Andric   std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
17530b57cec5SDimitry Andric   if (max_matches > 0 && max_matches < matches.size())
17540b57cec5SDimitry Andric     matches.resize(max_matches);
17550b57cec5SDimitry Andric 
17560b57cec5SDimitry Andric   for (TypeIndex ti : matches) {
17570b57cec5SDimitry Andric     TypeSP type = GetOrCreateType(ti);
17580b57cec5SDimitry Andric     if (!type)
17590b57cec5SDimitry Andric       continue;
17600b57cec5SDimitry Andric 
17610b57cec5SDimitry Andric     types.Insert(type);
17620b57cec5SDimitry Andric   }
17630b57cec5SDimitry Andric }
17640b57cec5SDimitry Andric 
ParseTypes(CompileUnit & comp_unit)17650b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
17669dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
17670b57cec5SDimitry Andric   // Only do the full type scan the first time.
17680b57cec5SDimitry Andric   if (m_done_full_type_scan)
17690b57cec5SDimitry Andric     return 0;
17700b57cec5SDimitry Andric 
17719dba64beSDimitry Andric   const size_t old_count = GetTypeList().GetSize();
17720b57cec5SDimitry Andric   LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
17730b57cec5SDimitry Andric 
17740b57cec5SDimitry Andric   // First process the entire TPI stream.
17750b57cec5SDimitry Andric   for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
17760b57cec5SDimitry Andric     TypeSP type = GetOrCreateType(*ti);
17770b57cec5SDimitry Andric     if (type)
17780b57cec5SDimitry Andric       (void)type->GetFullCompilerType();
17790b57cec5SDimitry Andric   }
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric   // Next look for S_UDT records in the globals stream.
17820b57cec5SDimitry Andric   for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
17830b57cec5SDimitry Andric     PdbGlobalSymId global{gid, false};
17840b57cec5SDimitry Andric     CVSymbol sym = m_index->ReadSymbolRecord(global);
17850b57cec5SDimitry Andric     if (sym.kind() != S_UDT)
17860b57cec5SDimitry Andric       continue;
17870b57cec5SDimitry Andric 
17880b57cec5SDimitry Andric     UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
17890b57cec5SDimitry Andric     bool is_typedef = true;
17900b57cec5SDimitry Andric     if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {
17910b57cec5SDimitry Andric       CVType cvt = m_index->tpi().getType(udt.Type);
17920b57cec5SDimitry Andric       llvm::StringRef name = CVTagRecord::create(cvt).name();
17930b57cec5SDimitry Andric       if (name == udt.Name)
17940b57cec5SDimitry Andric         is_typedef = false;
17950b57cec5SDimitry Andric     }
17960b57cec5SDimitry Andric 
17970b57cec5SDimitry Andric     if (is_typedef)
17980b57cec5SDimitry Andric       GetOrCreateTypedef(global);
17990b57cec5SDimitry Andric   }
18000b57cec5SDimitry Andric 
18019dba64beSDimitry Andric   const size_t new_count = GetTypeList().GetSize();
18020b57cec5SDimitry Andric 
18030b57cec5SDimitry Andric   m_done_full_type_scan = true;
18040b57cec5SDimitry Andric 
18050b57cec5SDimitry Andric   return new_count - old_count;
18060b57cec5SDimitry Andric }
18070b57cec5SDimitry Andric 
18080b57cec5SDimitry Andric size_t
ParseVariablesForCompileUnit(CompileUnit & comp_unit,VariableList & variables)18090b57cec5SDimitry Andric SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
18100b57cec5SDimitry Andric                                                   VariableList &variables) {
18110b57cec5SDimitry Andric   PdbSymUid sym_uid(comp_unit.GetID());
18120b57cec5SDimitry Andric   lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);
18130b57cec5SDimitry Andric   return 0;
18140b57cec5SDimitry Andric }
18150b57cec5SDimitry Andric 
CreateLocalVariable(PdbCompilandSymId scope_id,PdbCompilandSymId var_id,bool is_param)18160b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
18170b57cec5SDimitry Andric                                                     PdbCompilandSymId var_id,
18180b57cec5SDimitry Andric                                                     bool is_param) {
18190b57cec5SDimitry Andric   ModuleSP module = GetObjectFile()->GetModule();
18200b57cec5SDimitry Andric   Block &block = GetOrCreateBlock(scope_id);
1821753f127fSDimitry Andric   // Get function block.
1822753f127fSDimitry Andric   Block *func_block = &block;
1823753f127fSDimitry Andric   while (func_block->GetParent()) {
1824753f127fSDimitry Andric     func_block = func_block->GetParent();
1825753f127fSDimitry Andric   }
1826753f127fSDimitry Andric   Address addr;
1827753f127fSDimitry Andric   func_block->GetStartAddress(addr);
18280b57cec5SDimitry Andric   VariableInfo var_info =
1829753f127fSDimitry Andric       GetVariableLocationInfo(*m_index, var_id, *func_block, module);
1830bdd1243dSDimitry Andric   Function *func = func_block->CalculateSymbolContextFunction();
1831bdd1243dSDimitry Andric   if (!func)
18320b57cec5SDimitry Andric     return nullptr;
1833bdd1243dSDimitry Andric   // Use empty dwarf expr if optimized away so that it won't be filtered out
1834bdd1243dSDimitry Andric   // when lookuping local variables in this scope.
1835bdd1243dSDimitry Andric   if (!var_info.location.IsValid())
1836bdd1243dSDimitry Andric     var_info.location = DWARFExpressionList(module, DWARFExpression(), nullptr);
1837bdd1243dSDimitry Andric   var_info.location.SetFuncFileAddress(
1838bdd1243dSDimitry Andric       func->GetAddressRange().GetBaseAddress().GetFileAddress());
18390b57cec5SDimitry Andric   CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
18400b57cec5SDimitry Andric   CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
18410b57cec5SDimitry Andric   TypeSP type_sp = GetOrCreateType(var_info.type);
1842bdd1243dSDimitry Andric   if (!type_sp)
1843bdd1243dSDimitry Andric     return nullptr;
18440b57cec5SDimitry Andric   std::string name = var_info.name.str();
18450b57cec5SDimitry Andric   Declaration decl;
18460b57cec5SDimitry Andric   SymbolFileTypeSP sftype =
18470b57cec5SDimitry Andric       std::make_shared<SymbolFileType>(*this, type_sp->GetID());
18480b57cec5SDimitry Andric 
184981ad6265SDimitry Andric   is_param |= var_info.is_param;
18500b57cec5SDimitry Andric   ValueType var_scope =
18510b57cec5SDimitry Andric       is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;
1852e8d8bef9SDimitry Andric   bool external = false;
1853e8d8bef9SDimitry Andric   bool artificial = false;
1854e8d8bef9SDimitry Andric   bool location_is_constant_data = false;
1855e8d8bef9SDimitry Andric   bool static_member = false;
1856bdd1243dSDimitry Andric   Variable::RangeList scope_ranges;
18570b57cec5SDimitry Andric   VariableSP var_sp = std::make_shared<Variable>(
18580b57cec5SDimitry Andric       toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
1859bdd1243dSDimitry Andric       &block, scope_ranges, &decl, var_info.location, external, artificial,
1860753f127fSDimitry Andric       location_is_constant_data, static_member);
1861bdd1243dSDimitry Andric   if (!is_param) {
1862bdd1243dSDimitry Andric     auto ts_or_err = GetTypeSystemForLanguage(comp_unit_sp->GetLanguage());
1863bdd1243dSDimitry Andric     if (auto err = ts_or_err.takeError())
1864bdd1243dSDimitry Andric       return nullptr;
1865bdd1243dSDimitry Andric     auto ts = *ts_or_err;
1866bdd1243dSDimitry Andric     if (!ts)
1867bdd1243dSDimitry Andric       return nullptr;
18680b57cec5SDimitry Andric 
1869bdd1243dSDimitry Andric     ts->GetNativePDBParser()->GetOrCreateVariableDecl(scope_id, var_id);
1870bdd1243dSDimitry Andric   }
18710b57cec5SDimitry Andric   m_local_variables[toOpaqueUid(var_id)] = var_sp;
18720b57cec5SDimitry Andric   return var_sp;
18730b57cec5SDimitry Andric }
18740b57cec5SDimitry Andric 
GetOrCreateLocalVariable(PdbCompilandSymId scope_id,PdbCompilandSymId var_id,bool is_param)18750b57cec5SDimitry Andric VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable(
18760b57cec5SDimitry Andric     PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
18770b57cec5SDimitry Andric   auto iter = m_local_variables.find(toOpaqueUid(var_id));
18780b57cec5SDimitry Andric   if (iter != m_local_variables.end())
18790b57cec5SDimitry Andric     return iter->second;
18800b57cec5SDimitry Andric 
18810b57cec5SDimitry Andric   return CreateLocalVariable(scope_id, var_id, is_param);
18820b57cec5SDimitry Andric }
18830b57cec5SDimitry Andric 
CreateTypedef(PdbGlobalSymId id)18840b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
18850b57cec5SDimitry Andric   CVSymbol sym = m_index->ReadSymbolRecord(id);
18860b57cec5SDimitry Andric   lldbassert(sym.kind() == SymbolKind::S_UDT);
18870b57cec5SDimitry Andric 
18880b57cec5SDimitry Andric   UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric   TypeSP target_type = GetOrCreateType(udt.Type);
18910b57cec5SDimitry Andric 
1892bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1893bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
1894bdd1243dSDimitry Andric     return nullptr;
1895bdd1243dSDimitry Andric   auto ts = *ts_or_err;
1896bdd1243dSDimitry Andric   if (!ts)
1897bdd1243dSDimitry Andric     return nullptr;
1898bdd1243dSDimitry Andric 
1899bdd1243dSDimitry Andric   ts->GetNativePDBParser()->GetOrCreateTypedefDecl(id);
19000b57cec5SDimitry Andric 
19010b57cec5SDimitry Andric   Declaration decl;
1902bdd1243dSDimitry Andric   return MakeType(
1903bdd1243dSDimitry Andric       toOpaqueUid(id), ConstString(udt.Name), target_type->GetByteSize(nullptr),
1904bdd1243dSDimitry Andric       nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID,
1905bdd1243dSDimitry Andric       decl, target_type->GetForwardCompilerType(),
1906480093f4SDimitry Andric       lldb_private::Type::ResolveState::Forward);
19070b57cec5SDimitry Andric }
19080b57cec5SDimitry Andric 
GetOrCreateTypedef(PdbGlobalSymId id)19090b57cec5SDimitry Andric TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) {
19100b57cec5SDimitry Andric   auto iter = m_types.find(toOpaqueUid(id));
19110b57cec5SDimitry Andric   if (iter != m_types.end())
19120b57cec5SDimitry Andric     return iter->second;
19130b57cec5SDimitry Andric 
19140b57cec5SDimitry Andric   return CreateTypedef(id);
19150b57cec5SDimitry Andric }
19160b57cec5SDimitry Andric 
ParseVariablesForBlock(PdbCompilandSymId block_id)19170b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
19180b57cec5SDimitry Andric   Block &block = GetOrCreateBlock(block_id);
19190b57cec5SDimitry Andric 
19200b57cec5SDimitry Andric   size_t count = 0;
19210b57cec5SDimitry Andric 
19220b57cec5SDimitry Andric   CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
19230b57cec5SDimitry Andric   CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
19240b57cec5SDimitry Andric   uint32_t params_remaining = 0;
19250b57cec5SDimitry Andric   switch (sym.kind()) {
19260b57cec5SDimitry Andric   case S_GPROC32:
19270b57cec5SDimitry Andric   case S_LPROC32: {
19280b57cec5SDimitry Andric     ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));
19290b57cec5SDimitry Andric     cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));
19300b57cec5SDimitry Andric     CVType signature = m_index->tpi().getType(proc.FunctionType);
1931bdd1243dSDimitry Andric     if (signature.kind() == LF_PROCEDURE) {
19320b57cec5SDimitry Andric       ProcedureRecord sig;
1933bdd1243dSDimitry Andric       if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(
1934bdd1243dSDimitry Andric               signature, sig)) {
1935bdd1243dSDimitry Andric         llvm::consumeError(std::move(e));
1936bdd1243dSDimitry Andric         return 0;
1937bdd1243dSDimitry Andric       }
19380b57cec5SDimitry Andric       params_remaining = sig.getParameterCount();
1939bdd1243dSDimitry Andric     } else if (signature.kind() == LF_MFUNCTION) {
1940bdd1243dSDimitry Andric       MemberFunctionRecord sig;
1941bdd1243dSDimitry Andric       if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
1942bdd1243dSDimitry Andric               signature, sig)) {
1943bdd1243dSDimitry Andric         llvm::consumeError(std::move(e));
1944bdd1243dSDimitry Andric         return 0;
1945bdd1243dSDimitry Andric       }
1946bdd1243dSDimitry Andric       params_remaining = sig.getParameterCount();
1947bdd1243dSDimitry Andric     } else
1948bdd1243dSDimitry Andric       return 0;
19490b57cec5SDimitry Andric     break;
19500b57cec5SDimitry Andric   }
19510b57cec5SDimitry Andric   case S_BLOCK32:
19520b57cec5SDimitry Andric     break;
195304eeddc0SDimitry Andric   case S_INLINESITE:
195481ad6265SDimitry Andric     break;
19550b57cec5SDimitry Andric   default:
19560b57cec5SDimitry Andric     lldbassert(false && "Symbol is not a block!");
19570b57cec5SDimitry Andric     return 0;
19580b57cec5SDimitry Andric   }
19590b57cec5SDimitry Andric 
19600b57cec5SDimitry Andric   VariableListSP variables = block.GetBlockVariableList(false);
19610b57cec5SDimitry Andric   if (!variables) {
19620b57cec5SDimitry Andric     variables = std::make_shared<VariableList>();
19630b57cec5SDimitry Andric     block.SetVariableList(variables);
19640b57cec5SDimitry Andric   }
19650b57cec5SDimitry Andric 
19660b57cec5SDimitry Andric   CVSymbolArray syms = limitSymbolArrayToScope(
19670b57cec5SDimitry Andric       cii->m_debug_stream.getSymbolArray(), block_id.offset);
19680b57cec5SDimitry Andric 
19690b57cec5SDimitry Andric   // Skip the first record since it's a PROC32 or BLOCK32, and there's
19700b57cec5SDimitry Andric   // no point examining it since we know it's not a local variable.
19710b57cec5SDimitry Andric   syms.drop_front();
19720b57cec5SDimitry Andric   auto iter = syms.begin();
19730b57cec5SDimitry Andric   auto end = syms.end();
19740b57cec5SDimitry Andric 
19750b57cec5SDimitry Andric   while (iter != end) {
19760b57cec5SDimitry Andric     uint32_t record_offset = iter.offset();
19770b57cec5SDimitry Andric     CVSymbol variable_cvs = *iter;
19780b57cec5SDimitry Andric     PdbCompilandSymId child_sym_id(block_id.modi, record_offset);
19790b57cec5SDimitry Andric     ++iter;
19800b57cec5SDimitry Andric 
198181ad6265SDimitry Andric     // If this is a block or inline site, recurse into its children and then
198281ad6265SDimitry Andric     // skip it.
198381ad6265SDimitry Andric     if (variable_cvs.kind() == S_BLOCK32 ||
198481ad6265SDimitry Andric         variable_cvs.kind() == S_INLINESITE) {
19850b57cec5SDimitry Andric       uint32_t block_end = getScopeEndOffset(variable_cvs);
19860b57cec5SDimitry Andric       count += ParseVariablesForBlock(child_sym_id);
19870b57cec5SDimitry Andric       iter = syms.at(block_end);
19880b57cec5SDimitry Andric       continue;
19890b57cec5SDimitry Andric     }
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric     bool is_param = params_remaining > 0;
19920b57cec5SDimitry Andric     VariableSP variable;
19930b57cec5SDimitry Andric     switch (variable_cvs.kind()) {
19940b57cec5SDimitry Andric     case S_REGREL32:
19950b57cec5SDimitry Andric     case S_REGISTER:
19960b57cec5SDimitry Andric     case S_LOCAL:
19970b57cec5SDimitry Andric       variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
19980b57cec5SDimitry Andric       if (is_param)
19990b57cec5SDimitry Andric         --params_remaining;
20000b57cec5SDimitry Andric       if (variable)
20010b57cec5SDimitry Andric         variables->AddVariableIfUnique(variable);
20020b57cec5SDimitry Andric       break;
20030b57cec5SDimitry Andric     default:
20040b57cec5SDimitry Andric       break;
20050b57cec5SDimitry Andric     }
20060b57cec5SDimitry Andric   }
20070b57cec5SDimitry Andric 
20080b57cec5SDimitry Andric   // Pass false for set_children, since we call this recursively so that the
20090b57cec5SDimitry Andric   // children will call this for themselves.
20100b57cec5SDimitry Andric   block.SetDidParseVariables(true, false);
20110b57cec5SDimitry Andric 
20120b57cec5SDimitry Andric   return count;
20130b57cec5SDimitry Andric }
20140b57cec5SDimitry Andric 
ParseVariablesForContext(const SymbolContext & sc)20150b57cec5SDimitry Andric size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
20169dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
20170b57cec5SDimitry Andric   lldbassert(sc.function || sc.comp_unit);
20180b57cec5SDimitry Andric 
20190b57cec5SDimitry Andric   VariableListSP variables;
20200b57cec5SDimitry Andric   if (sc.block) {
20210b57cec5SDimitry Andric     PdbSymUid block_id(sc.block->GetID());
20220b57cec5SDimitry Andric 
20230b57cec5SDimitry Andric     size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
20240b57cec5SDimitry Andric     return count;
20250b57cec5SDimitry Andric   }
20260b57cec5SDimitry Andric 
20270b57cec5SDimitry Andric   if (sc.function) {
20280b57cec5SDimitry Andric     PdbSymUid block_id(sc.function->GetID());
20290b57cec5SDimitry Andric 
20300b57cec5SDimitry Andric     size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
20310b57cec5SDimitry Andric     return count;
20320b57cec5SDimitry Andric   }
20330b57cec5SDimitry Andric 
20340b57cec5SDimitry Andric   if (sc.comp_unit) {
20350b57cec5SDimitry Andric     variables = sc.comp_unit->GetVariableList(false);
20360b57cec5SDimitry Andric     if (!variables) {
20370b57cec5SDimitry Andric       variables = std::make_shared<VariableList>();
20380b57cec5SDimitry Andric       sc.comp_unit->SetVariableList(variables);
20390b57cec5SDimitry Andric     }
20400b57cec5SDimitry Andric     return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);
20410b57cec5SDimitry Andric   }
20420b57cec5SDimitry Andric 
20430b57cec5SDimitry Andric   llvm_unreachable("Unreachable!");
20440b57cec5SDimitry Andric }
20450b57cec5SDimitry Andric 
GetDeclForUID(lldb::user_id_t uid)20460b57cec5SDimitry Andric CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
2047bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
2048bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
2049bdd1243dSDimitry Andric     return CompilerDecl();
2050bdd1243dSDimitry Andric   auto ts = *ts_or_err;
2051bdd1243dSDimitry Andric   if (!ts)
2052bdd1243dSDimitry Andric     return {};
2053bdd1243dSDimitry Andric 
2054bdd1243dSDimitry Andric   if (auto decl = ts->GetNativePDBParser()->GetOrCreateDeclForUid(uid))
205581ad6265SDimitry Andric     return *decl;
20569dba64beSDimitry Andric   return CompilerDecl();
20570b57cec5SDimitry Andric }
20580b57cec5SDimitry Andric 
20590b57cec5SDimitry Andric CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t uid)20600b57cec5SDimitry Andric SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {
2061bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
2062bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
2063bdd1243dSDimitry Andric     return {};
2064bdd1243dSDimitry Andric   auto ts = *ts_or_err;
2065bdd1243dSDimitry Andric   if (!ts)
2066bdd1243dSDimitry Andric     return {};
2067bdd1243dSDimitry Andric 
2068bdd1243dSDimitry Andric   PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
20690b57cec5SDimitry Andric   clang::DeclContext *context =
2070bdd1243dSDimitry Andric       ast_builder->GetOrCreateDeclContextForUid(PdbSymUid(uid));
20710b57cec5SDimitry Andric   if (!context)
20720b57cec5SDimitry Andric     return {};
20730b57cec5SDimitry Andric 
2074bdd1243dSDimitry Andric   return ast_builder->ToCompilerDeclContext(*context);
20750b57cec5SDimitry Andric }
20760b57cec5SDimitry Andric 
20770b57cec5SDimitry Andric CompilerDeclContext
GetDeclContextContainingUID(lldb::user_id_t uid)20780b57cec5SDimitry Andric SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
2079bdd1243dSDimitry Andric   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
2080bdd1243dSDimitry Andric   if (auto err = ts_or_err.takeError())
2081bdd1243dSDimitry Andric     return CompilerDeclContext();
2082bdd1243dSDimitry Andric   auto ts = *ts_or_err;
2083bdd1243dSDimitry Andric   if (!ts)
2084bdd1243dSDimitry Andric     return {};
2085bdd1243dSDimitry Andric 
2086bdd1243dSDimitry Andric   PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2087bdd1243dSDimitry Andric   clang::DeclContext *context = ast_builder->GetParentDeclContext(PdbSymUid(uid));
2088bdd1243dSDimitry Andric   if (!context)
2089bdd1243dSDimitry Andric     return CompilerDeclContext();
2090bdd1243dSDimitry Andric   return ast_builder->ToCompilerDeclContext(*context);
20910b57cec5SDimitry Andric }
20920b57cec5SDimitry Andric 
ResolveTypeUID(lldb::user_id_t type_uid)20930b57cec5SDimitry Andric Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
20949dba64beSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
20950b57cec5SDimitry Andric   auto iter = m_types.find(type_uid);
20960b57cec5SDimitry Andric   // lldb should not be passing us non-sensical type uids.  the only way it
20970b57cec5SDimitry Andric   // could have a type uid in the first place is if we handed it out, in which
20980b57cec5SDimitry Andric   // case we should know about the type.  However, that doesn't mean we've
20990b57cec5SDimitry Andric   // instantiated it yet.  We can vend out a UID for a future type.  So if the
21000b57cec5SDimitry Andric   // type doesn't exist, let's instantiate it now.
21010b57cec5SDimitry Andric   if (iter != m_types.end())
21020b57cec5SDimitry Andric     return &*iter->second;
21030b57cec5SDimitry Andric 
21040b57cec5SDimitry Andric   PdbSymUid uid(type_uid);
21050b57cec5SDimitry Andric   lldbassert(uid.kind() == PdbSymUidKind::Type);
21060b57cec5SDimitry Andric   PdbTypeSymId type_id = uid.asTypeSym();
21070b57cec5SDimitry Andric   if (type_id.index.isNoneType())
21080b57cec5SDimitry Andric     return nullptr;
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric   TypeSP type_sp = CreateAndCacheType(type_id);
2111bdd1243dSDimitry Andric   if (!type_sp)
2112bdd1243dSDimitry Andric     return nullptr;
21130b57cec5SDimitry Andric   return &*type_sp;
21140b57cec5SDimitry Andric }
21150b57cec5SDimitry Andric 
2116bdd1243dSDimitry Andric std::optional<SymbolFile::ArrayInfo>
GetDynamicArrayInfoForUID(lldb::user_id_t type_uid,const lldb_private::ExecutionContext * exe_ctx)21170b57cec5SDimitry Andric SymbolFileNativePDB::GetDynamicArrayInfoForUID(
21180b57cec5SDimitry Andric     lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
2119bdd1243dSDimitry Andric   return std::nullopt;
21200b57cec5SDimitry Andric }
21210b57cec5SDimitry Andric 
CompleteType(CompilerType & compiler_type)21220b57cec5SDimitry Andric bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
2123bdd1243dSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2124bdd1243dSDimitry Andric   auto ts = compiler_type.GetTypeSystem();
2125bdd1243dSDimitry Andric   auto clang_type_system = ts.dyn_cast_or_null<TypeSystemClang>();
2126bdd1243dSDimitry Andric   if (!clang_type_system)
2127bdd1243dSDimitry Andric     return false;
2128bdd1243dSDimitry Andric 
2129bdd1243dSDimitry Andric   PdbAstBuilder *ast_builder =
2130bdd1243dSDimitry Andric       static_cast<PdbAstBuilder *>(clang_type_system->GetNativePDBParser());
2131bdd1243dSDimitry Andric   if (ast_builder &&
2132bdd1243dSDimitry Andric       ast_builder->GetClangASTImporter().CanImport(compiler_type))
2133bdd1243dSDimitry Andric     return ast_builder->GetClangASTImporter().CompleteType(compiler_type);
21340b57cec5SDimitry Andric   clang::QualType qt =
21350b57cec5SDimitry Andric       clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType());
21360b57cec5SDimitry Andric 
2137bdd1243dSDimitry Andric   return ast_builder->CompleteType(qt);
21380b57cec5SDimitry Andric }
21390b57cec5SDimitry Andric 
GetTypes(lldb_private::SymbolContextScope * sc_scope,TypeClass type_mask,lldb_private::TypeList & type_list)21409dba64beSDimitry Andric void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
21410b57cec5SDimitry Andric                                    TypeClass type_mask,
21429dba64beSDimitry Andric                                    lldb_private::TypeList &type_list) {}
21430b57cec5SDimitry Andric 
FindNamespace(ConstString name,const CompilerDeclContext & parent_decl_ctx,bool)214406c3fb27SDimitry Andric CompilerDeclContext SymbolFileNativePDB::FindNamespace(
214506c3fb27SDimitry Andric     ConstString name, const CompilerDeclContext &parent_decl_ctx, bool) {
21460b57cec5SDimitry Andric   return {};
21470b57cec5SDimitry Andric }
21480b57cec5SDimitry Andric 
2149bdd1243dSDimitry Andric llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(lldb::LanguageType language)21500b57cec5SDimitry Andric SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
21519dba64beSDimitry Andric   auto type_system_or_err =
21529dba64beSDimitry Andric       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
2153bdd1243dSDimitry Andric   if (type_system_or_err)
2154bdd1243dSDimitry Andric     if (auto ts = *type_system_or_err)
2155bdd1243dSDimitry Andric       ts->SetSymbolFile(this);
21569dba64beSDimitry Andric   return type_system_or_err;
21570b57cec5SDimitry Andric }
21580b57cec5SDimitry Andric 
GetDebugInfoSize()2159349cc55cSDimitry Andric uint64_t SymbolFileNativePDB::GetDebugInfoSize() {
2160349cc55cSDimitry Andric   // PDB files are a separate file that contains all debug info.
2161349cc55cSDimitry Andric   return m_index->pdb().getFileSize();
21620b57cec5SDimitry Andric }
2163bdd1243dSDimitry Andric 
BuildParentMap()2164bdd1243dSDimitry Andric void SymbolFileNativePDB::BuildParentMap() {
2165bdd1243dSDimitry Andric   LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
2166bdd1243dSDimitry Andric 
2167bdd1243dSDimitry Andric   llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
2168bdd1243dSDimitry Andric   llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
2169bdd1243dSDimitry Andric 
2170bdd1243dSDimitry Andric   struct RecordIndices {
2171bdd1243dSDimitry Andric     TypeIndex forward;
2172bdd1243dSDimitry Andric     TypeIndex full;
2173bdd1243dSDimitry Andric   };
2174bdd1243dSDimitry Andric 
2175bdd1243dSDimitry Andric   llvm::StringMap<RecordIndices> record_indices;
2176bdd1243dSDimitry Andric 
2177bdd1243dSDimitry Andric   for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2178bdd1243dSDimitry Andric     CVType type = types.getType(*ti);
2179bdd1243dSDimitry Andric     if (!IsTagRecord(type))
2180bdd1243dSDimitry Andric       continue;
2181bdd1243dSDimitry Andric 
2182bdd1243dSDimitry Andric     CVTagRecord tag = CVTagRecord::create(type);
2183bdd1243dSDimitry Andric 
2184bdd1243dSDimitry Andric     RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
2185bdd1243dSDimitry Andric     if (tag.asTag().isForwardRef())
2186bdd1243dSDimitry Andric       indices.forward = *ti;
2187bdd1243dSDimitry Andric     else
2188bdd1243dSDimitry Andric       indices.full = *ti;
2189bdd1243dSDimitry Andric 
2190bdd1243dSDimitry Andric     if (indices.full != TypeIndex::None() &&
2191bdd1243dSDimitry Andric         indices.forward != TypeIndex::None()) {
2192bdd1243dSDimitry Andric       forward_to_full[indices.forward] = indices.full;
2193bdd1243dSDimitry Andric       full_to_forward[indices.full] = indices.forward;
2194bdd1243dSDimitry Andric     }
2195bdd1243dSDimitry Andric 
2196bdd1243dSDimitry Andric     // We're looking for LF_NESTTYPE records in the field list, so ignore
2197bdd1243dSDimitry Andric     // forward references (no field list), and anything without a nested class
2198bdd1243dSDimitry Andric     // (since there won't be any LF_NESTTYPE records).
2199bdd1243dSDimitry Andric     if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())
2200bdd1243dSDimitry Andric       continue;
2201bdd1243dSDimitry Andric 
2202bdd1243dSDimitry Andric     struct ProcessTpiStream : public TypeVisitorCallbacks {
2203bdd1243dSDimitry Andric       ProcessTpiStream(PdbIndex &index, TypeIndex parent,
2204bdd1243dSDimitry Andric                        const CVTagRecord &parent_cvt,
2205bdd1243dSDimitry Andric                        llvm::DenseMap<TypeIndex, TypeIndex> &parents)
2206bdd1243dSDimitry Andric           : index(index), parents(parents), parent(parent),
2207bdd1243dSDimitry Andric             parent_cvt(parent_cvt) {}
2208bdd1243dSDimitry Andric 
2209bdd1243dSDimitry Andric       PdbIndex &index;
2210bdd1243dSDimitry Andric       llvm::DenseMap<TypeIndex, TypeIndex> &parents;
2211bdd1243dSDimitry Andric 
2212bdd1243dSDimitry Andric       unsigned unnamed_type_index = 1;
2213bdd1243dSDimitry Andric       TypeIndex parent;
2214bdd1243dSDimitry Andric       const CVTagRecord &parent_cvt;
2215bdd1243dSDimitry Andric 
2216bdd1243dSDimitry Andric       llvm::Error visitKnownMember(CVMemberRecord &CVR,
2217bdd1243dSDimitry Andric                                    NestedTypeRecord &Record) override {
2218bdd1243dSDimitry Andric         std::string unnamed_type_name;
2219bdd1243dSDimitry Andric         if (Record.Name.empty()) {
2220bdd1243dSDimitry Andric           unnamed_type_name =
2221bdd1243dSDimitry Andric               llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();
2222bdd1243dSDimitry Andric           Record.Name = unnamed_type_name;
2223bdd1243dSDimitry Andric           ++unnamed_type_index;
2224bdd1243dSDimitry Andric         }
2225bdd1243dSDimitry Andric         std::optional<CVTagRecord> tag =
2226bdd1243dSDimitry Andric             GetNestedTagDefinition(Record, parent_cvt, index.tpi());
2227bdd1243dSDimitry Andric         if (!tag)
2228bdd1243dSDimitry Andric           return llvm::ErrorSuccess();
2229bdd1243dSDimitry Andric 
2230bdd1243dSDimitry Andric         parents[Record.Type] = parent;
2231bdd1243dSDimitry Andric         return llvm::ErrorSuccess();
2232bdd1243dSDimitry Andric       }
2233bdd1243dSDimitry Andric     };
2234bdd1243dSDimitry Andric 
2235bdd1243dSDimitry Andric     CVType field_list_cvt = m_index->tpi().getType(tag.asTag().FieldList);
2236bdd1243dSDimitry Andric     ProcessTpiStream process(*m_index, *ti, tag, m_parent_types);
2237bdd1243dSDimitry Andric     FieldListRecord field_list;
2238bdd1243dSDimitry Andric     if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
2239bdd1243dSDimitry Andric             field_list_cvt, field_list))
2240bdd1243dSDimitry Andric       llvm::consumeError(std::move(error));
2241bdd1243dSDimitry Andric     if (llvm::Error error = visitMemberRecordStream(field_list.Data, process))
2242bdd1243dSDimitry Andric       llvm::consumeError(std::move(error));
2243bdd1243dSDimitry Andric   }
2244bdd1243dSDimitry Andric 
2245bdd1243dSDimitry Andric   // Now that we know the forward -> full mapping of all type indices, we can
2246bdd1243dSDimitry Andric   // re-write all the indices.  At the end of this process, we want a mapping
2247bdd1243dSDimitry Andric   // consisting of fwd -> full and full -> full for all child -> parent indices.
2248bdd1243dSDimitry Andric   // We can re-write the values in place, but for the keys, we must save them
2249bdd1243dSDimitry Andric   // off so that we don't modify the map in place while also iterating it.
2250bdd1243dSDimitry Andric   std::vector<TypeIndex> full_keys;
2251bdd1243dSDimitry Andric   std::vector<TypeIndex> fwd_keys;
2252bdd1243dSDimitry Andric   for (auto &entry : m_parent_types) {
2253bdd1243dSDimitry Andric     TypeIndex key = entry.first;
2254bdd1243dSDimitry Andric     TypeIndex value = entry.second;
2255bdd1243dSDimitry Andric 
2256bdd1243dSDimitry Andric     auto iter = forward_to_full.find(value);
2257bdd1243dSDimitry Andric     if (iter != forward_to_full.end())
2258bdd1243dSDimitry Andric       entry.second = iter->second;
2259bdd1243dSDimitry Andric 
2260bdd1243dSDimitry Andric     iter = forward_to_full.find(key);
2261bdd1243dSDimitry Andric     if (iter != forward_to_full.end())
2262bdd1243dSDimitry Andric       fwd_keys.push_back(key);
2263bdd1243dSDimitry Andric     else
2264bdd1243dSDimitry Andric       full_keys.push_back(key);
2265bdd1243dSDimitry Andric   }
2266bdd1243dSDimitry Andric   for (TypeIndex fwd : fwd_keys) {
2267bdd1243dSDimitry Andric     TypeIndex full = forward_to_full[fwd];
22681db9f3b2SDimitry Andric     TypeIndex parent_idx = m_parent_types[fwd];
22691db9f3b2SDimitry Andric     m_parent_types[full] = parent_idx;
2270bdd1243dSDimitry Andric   }
2271bdd1243dSDimitry Andric   for (TypeIndex full : full_keys) {
2272bdd1243dSDimitry Andric     TypeIndex fwd = full_to_forward[full];
2273bdd1243dSDimitry Andric     m_parent_types[fwd] = m_parent_types[full];
2274bdd1243dSDimitry Andric   }
2275bdd1243dSDimitry Andric }
2276bdd1243dSDimitry Andric 
2277bdd1243dSDimitry Andric std::optional<PdbCompilandSymId>
FindSymbolScope(PdbCompilandSymId id)2278bdd1243dSDimitry Andric SymbolFileNativePDB::FindSymbolScope(PdbCompilandSymId id) {
2279bdd1243dSDimitry Andric   CVSymbol sym = m_index->ReadSymbolRecord(id);
2280bdd1243dSDimitry Andric   if (symbolOpensScope(sym.kind())) {
2281bdd1243dSDimitry Andric     // If this exact symbol opens a scope, we can just directly access its
2282bdd1243dSDimitry Andric     // parent.
2283bdd1243dSDimitry Andric     id.offset = getScopeParentOffset(sym);
2284bdd1243dSDimitry Andric     // Global symbols have parent offset of 0.  Return std::nullopt to indicate
2285bdd1243dSDimitry Andric     // this.
2286bdd1243dSDimitry Andric     if (id.offset == 0)
2287bdd1243dSDimitry Andric       return std::nullopt;
2288bdd1243dSDimitry Andric     return id;
2289bdd1243dSDimitry Andric   }
2290bdd1243dSDimitry Andric 
2291bdd1243dSDimitry Andric   // Otherwise we need to start at the beginning and iterate forward until we
2292bdd1243dSDimitry Andric   // reach (or pass) this particular symbol
2293bdd1243dSDimitry Andric   CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(id.modi);
2294bdd1243dSDimitry Andric   const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
2295bdd1243dSDimitry Andric 
2296bdd1243dSDimitry Andric   auto begin = syms.begin();
2297bdd1243dSDimitry Andric   auto end = syms.at(id.offset);
2298bdd1243dSDimitry Andric   std::vector<PdbCompilandSymId> scope_stack;
2299bdd1243dSDimitry Andric 
2300bdd1243dSDimitry Andric   while (begin != end) {
2301bdd1243dSDimitry Andric     if (begin.offset() > id.offset) {
2302bdd1243dSDimitry Andric       // We passed it.  We couldn't even find this symbol record.
2303bdd1243dSDimitry Andric       lldbassert(false && "Invalid compiland symbol id!");
2304bdd1243dSDimitry Andric       return std::nullopt;
2305bdd1243dSDimitry Andric     }
2306bdd1243dSDimitry Andric 
2307bdd1243dSDimitry Andric     // We haven't found the symbol yet.  Check if we need to open or close the
2308bdd1243dSDimitry Andric     // scope stack.
2309bdd1243dSDimitry Andric     if (symbolOpensScope(begin->kind())) {
2310bdd1243dSDimitry Andric       // We can use the end offset of the scope to determine whether or not
2311bdd1243dSDimitry Andric       // we can just outright skip this entire scope.
2312bdd1243dSDimitry Andric       uint32_t scope_end = getScopeEndOffset(*begin);
2313bdd1243dSDimitry Andric       if (scope_end < id.offset) {
2314bdd1243dSDimitry Andric         begin = syms.at(scope_end);
2315bdd1243dSDimitry Andric       } else {
2316bdd1243dSDimitry Andric         // The symbol we're looking for is somewhere in this scope.
2317bdd1243dSDimitry Andric         scope_stack.emplace_back(id.modi, begin.offset());
2318bdd1243dSDimitry Andric       }
2319bdd1243dSDimitry Andric     } else if (symbolEndsScope(begin->kind())) {
2320bdd1243dSDimitry Andric       scope_stack.pop_back();
2321bdd1243dSDimitry Andric     }
2322bdd1243dSDimitry Andric     ++begin;
2323bdd1243dSDimitry Andric   }
2324bdd1243dSDimitry Andric   if (scope_stack.empty())
2325bdd1243dSDimitry Andric     return std::nullopt;
2326bdd1243dSDimitry Andric   // We have a match!  Return the top of the stack
2327bdd1243dSDimitry Andric   return scope_stack.back();
2328bdd1243dSDimitry Andric }
2329bdd1243dSDimitry Andric 
2330bdd1243dSDimitry Andric std::optional<llvm::codeview::TypeIndex>
GetParentType(llvm::codeview::TypeIndex ti)2331bdd1243dSDimitry Andric SymbolFileNativePDB::GetParentType(llvm::codeview::TypeIndex ti) {
2332bdd1243dSDimitry Andric   auto parent_iter = m_parent_types.find(ti);
2333bdd1243dSDimitry Andric   if (parent_iter == m_parent_types.end())
2334bdd1243dSDimitry Andric     return std::nullopt;
2335bdd1243dSDimitry Andric   return parent_iter->second;
2336bdd1243dSDimitry Andric }
2337