1 //===-- SymbolFileNativePDB.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "SymbolFileNativePDB.h"
10 
11 #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
12 #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
13 #include "Plugins/ObjectFile/PDB/ObjectFilePDB.h"
14 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/StreamBuffer.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/LineTable.h"
21 #include "lldb/Symbol/ObjectFile.h"
22 #include "lldb/Symbol/SymbolContext.h"
23 #include "lldb/Symbol/SymbolVendor.h"
24 #include "lldb/Symbol/Variable.h"
25 #include "lldb/Symbol/VariableList.h"
26 #include "lldb/Utility/LLDBLog.h"
27 #include "lldb/Utility/Log.h"
28 
29 #include "llvm/DebugInfo/CodeView/CVRecord.h"
30 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
31 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
32 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
33 #include "llvm/DebugInfo/CodeView/RecordName.h"
34 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
35 #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
36 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
37 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
38 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
39 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
40 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
41 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
42 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
43 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
44 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
45 #include "llvm/DebugInfo/PDB/PDB.h"
46 #include "llvm/DebugInfo/PDB/PDBTypes.h"
47 #include "llvm/Demangle/MicrosoftDemangle.h"
48 #include "llvm/Object/COFF.h"
49 #include "llvm/Support/Allocator.h"
50 #include "llvm/Support/BinaryStreamReader.h"
51 #include "llvm/Support/Error.h"
52 #include "llvm/Support/ErrorOr.h"
53 #include "llvm/Support/MemoryBuffer.h"
54 
55 #include "DWARFLocationExpression.h"
56 #include "PdbSymUid.h"
57 #include "PdbUtil.h"
58 #include "UdtRecordCompleter.h"
59 #include <optional>
60 #include <string_view>
61 
62 using namespace lldb;
63 using namespace lldb_private;
64 using namespace npdb;
65 using namespace llvm::codeview;
66 using namespace llvm::pdb;
67 
68 char SymbolFileNativePDB::ID;
69 
70 static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
71   switch (lang) {
72   case PDB_Lang::Cpp:
73     return lldb::LanguageType::eLanguageTypeC_plus_plus;
74   case PDB_Lang::C:
75     return lldb::LanguageType::eLanguageTypeC;
76   case PDB_Lang::Swift:
77     return lldb::LanguageType::eLanguageTypeSwift;
78   case PDB_Lang::Rust:
79     return lldb::LanguageType::eLanguageTypeRust;
80   case PDB_Lang::ObjC:
81     return lldb::LanguageType::eLanguageTypeObjC;
82   case PDB_Lang::ObjCpp:
83     return lldb::LanguageType::eLanguageTypeObjC_plus_plus;
84   default:
85     return lldb::LanguageType::eLanguageTypeUnknown;
86   }
87 }
88 
89 static std::unique_ptr<PDBFile>
90 loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
91   // Try to find a matching PDB for an EXE.
92   using namespace llvm::object;
93   auto expected_binary = createBinary(exe_path);
94 
95   // If the file isn't a PE/COFF executable, fail.
96   if (!expected_binary) {
97     llvm::consumeError(expected_binary.takeError());
98     return nullptr;
99   }
100   OwningBinary<Binary> binary = std::move(*expected_binary);
101 
102   // TODO: Avoid opening the PE/COFF binary twice by reading this information
103   // directly from the lldb_private::ObjectFile.
104   auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
105   if (!obj)
106     return nullptr;
107   const llvm::codeview::DebugInfo *pdb_info = nullptr;
108 
109   // If it doesn't have a debug directory, fail.
110   llvm::StringRef pdb_file;
111   if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) {
112     consumeError(std::move(e));
113     return nullptr;
114   }
115 
116   // If the file doesn't exist, perhaps the path specified at build time
117   // doesn't match the PDB's current location, so check the location of the
118   // executable.
119   if (!FileSystem::Instance().Exists(pdb_file)) {
120     const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent();
121     const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString();
122     pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetPathAsConstString().GetStringRef();
123   }
124 
125   // If the file is not a PDB or if it doesn't have a matching GUID, fail.
126   auto pdb = ObjectFilePDB::loadPDBFile(std::string(pdb_file), allocator);
127   if (!pdb)
128     return nullptr;
129 
130   auto expected_info = pdb->getPDBInfoStream();
131   if (!expected_info) {
132     llvm::consumeError(expected_info.takeError());
133     return nullptr;
134   }
135   llvm::codeview::GUID guid;
136   memcpy(&guid, pdb_info->PDB70.Signature, 16);
137 
138   if (expected_info->getGuid() != guid)
139     return nullptr;
140   return pdb;
141 }
142 
143 static bool IsFunctionPrologue(const CompilandIndexItem &cci,
144                                lldb::addr_t addr) {
145   // FIXME: Implement this.
146   return false;
147 }
148 
149 static bool IsFunctionEpilogue(const CompilandIndexItem &cci,
150                                lldb::addr_t addr) {
151   // FIXME: Implement this.
152   return false;
153 }
154 
155 static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
156   switch (kind) {
157   case SimpleTypeKind::Boolean128:
158   case SimpleTypeKind::Boolean16:
159   case SimpleTypeKind::Boolean32:
160   case SimpleTypeKind::Boolean64:
161   case SimpleTypeKind::Boolean8:
162     return "bool";
163   case SimpleTypeKind::Byte:
164   case SimpleTypeKind::UnsignedCharacter:
165     return "unsigned char";
166   case SimpleTypeKind::NarrowCharacter:
167     return "char";
168   case SimpleTypeKind::SignedCharacter:
169   case SimpleTypeKind::SByte:
170     return "signed char";
171   case SimpleTypeKind::Character16:
172     return "char16_t";
173   case SimpleTypeKind::Character32:
174     return "char32_t";
175   case SimpleTypeKind::Character8:
176     return "char8_t";
177   case SimpleTypeKind::Complex80:
178   case SimpleTypeKind::Complex64:
179   case SimpleTypeKind::Complex32:
180     return "complex";
181   case SimpleTypeKind::Float128:
182   case SimpleTypeKind::Float80:
183     return "long double";
184   case SimpleTypeKind::Float64:
185     return "double";
186   case SimpleTypeKind::Float32:
187     return "float";
188   case SimpleTypeKind::Float16:
189     return "single";
190   case SimpleTypeKind::Int128:
191     return "__int128";
192   case SimpleTypeKind::Int64:
193   case SimpleTypeKind::Int64Quad:
194     return "int64_t";
195   case SimpleTypeKind::Int32:
196     return "int";
197   case SimpleTypeKind::Int16:
198     return "short";
199   case SimpleTypeKind::UInt128:
200     return "unsigned __int128";
201   case SimpleTypeKind::UInt64:
202   case SimpleTypeKind::UInt64Quad:
203     return "uint64_t";
204   case SimpleTypeKind::HResult:
205     return "HRESULT";
206   case SimpleTypeKind::UInt32:
207     return "unsigned";
208   case SimpleTypeKind::UInt16:
209   case SimpleTypeKind::UInt16Short:
210     return "unsigned short";
211   case SimpleTypeKind::Int32Long:
212     return "long";
213   case SimpleTypeKind::UInt32Long:
214     return "unsigned long";
215   case SimpleTypeKind::Void:
216     return "void";
217   case SimpleTypeKind::WideCharacter:
218     return "wchar_t";
219   default:
220     return "";
221   }
222 }
223 
224 static bool IsClassRecord(TypeLeafKind kind) {
225   switch (kind) {
226   case LF_STRUCTURE:
227   case LF_CLASS:
228   case LF_INTERFACE:
229     return true;
230   default:
231     return false;
232   }
233 }
234 
235 static std::optional<CVTagRecord>
236 GetNestedTagDefinition(const NestedTypeRecord &Record,
237                        const CVTagRecord &parent, TpiStream &tpi) {
238   // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it
239   // is also used to indicate the primary definition of a nested class.  That is
240   // to say, if you have:
241   // struct A {
242   //   struct B {};
243   //   using C = B;
244   // };
245   // Then in the debug info, this will appear as:
246   // LF_STRUCTURE `A::B` [type index = N]
247   // LF_STRUCTURE `A`
248   //   LF_NESTTYPE [name = `B`, index = N]
249   //   LF_NESTTYPE [name = `C`, index = N]
250   // In order to accurately reconstruct the decl context hierarchy, we need to
251   // know which ones are actual definitions and which ones are just aliases.
252 
253   // If it's a simple type, then this is something like `using foo = int`.
254   if (Record.Type.isSimple())
255     return std::nullopt;
256 
257   CVType cvt = tpi.getType(Record.Type);
258 
259   if (!IsTagRecord(cvt))
260     return std::nullopt;
261 
262   // If it's an inner definition, then treat whatever name we have here as a
263   // single component of a mangled name.  So we can inject it into the parent's
264   // mangled name to see if it matches.
265   CVTagRecord child = CVTagRecord::create(cvt);
266   std::string qname = std::string(parent.asTag().getUniqueName());
267   if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
268     return std::nullopt;
269 
270   // qname[3] is the tag type identifier (struct, class, union, etc).  Since the
271   // inner tag type is not necessarily the same as the outer tag type, re-write
272   // it to match the inner tag type.
273   qname[3] = child.asTag().getUniqueName()[3];
274   std::string piece;
275   if (qname[3] == 'W')
276     piece = "4";
277   piece += Record.Name;
278   piece.push_back('@');
279   qname.insert(4, std::move(piece));
280   if (qname != child.asTag().UniqueName)
281     return std::nullopt;
282 
283   return std::move(child);
284 }
285 
286 void SymbolFileNativePDB::Initialize() {
287   PluginManager::RegisterPlugin(GetPluginNameStatic(),
288                                 GetPluginDescriptionStatic(), CreateInstance,
289                                 DebuggerInitialize);
290 }
291 
292 void SymbolFileNativePDB::Terminate() {
293   PluginManager::UnregisterPlugin(CreateInstance);
294 }
295 
296 void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {}
297 
298 llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() {
299   return "Microsoft PDB debug symbol cross-platform file reader.";
300 }
301 
302 SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
303   return new SymbolFileNativePDB(std::move(objfile_sp));
304 }
305 
306 SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
307     : SymbolFileCommon(std::move(objfile_sp)) {}
308 
309 SymbolFileNativePDB::~SymbolFileNativePDB() = default;
310 
311 uint32_t SymbolFileNativePDB::CalculateAbilities() {
312   uint32_t abilities = 0;
313   if (!m_objfile_sp)
314     return 0;
315 
316   if (!m_index) {
317     // Lazily load and match the PDB file, but only do this once.
318     PDBFile *pdb_file;
319     if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) {
320       pdb_file = &pdb->GetPDBFile();
321     } else {
322       m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(),
323                                       m_allocator);
324       pdb_file = m_file_up.get();
325     }
326 
327     if (!pdb_file)
328       return 0;
329 
330     auto expected_index = PdbIndex::create(pdb_file);
331     if (!expected_index) {
332       llvm::consumeError(expected_index.takeError());
333       return 0;
334     }
335     m_index = std::move(*expected_index);
336   }
337   if (!m_index)
338     return 0;
339 
340   // We don't especially have to be precise here.  We only distinguish between
341   // stripped and not stripped.
342   abilities = kAllAbilities;
343 
344   if (m_index->dbi().isStripped())
345     abilities &= ~(Blocks | LocalVariables);
346   return abilities;
347 }
348 
349 void SymbolFileNativePDB::InitializeObject() {
350   m_obj_load_address = m_objfile_sp->GetModule()
351                            ->GetObjectFile()
352                            ->GetBaseAddress()
353                            .GetFileAddress();
354   m_index->SetLoadAddress(m_obj_load_address);
355   m_index->ParseSectionContribs();
356 
357   auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
358       lldb::eLanguageTypeC_plus_plus);
359   if (auto err = ts_or_err.takeError()) {
360     LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
361                    "Failed to initialize: {0}");
362   } else {
363     if (auto ts = *ts_or_err)
364       ts->SetSymbolFile(this);
365     BuildParentMap();
366   }
367 }
368 
369 uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
370   const DbiModuleList &modules = m_index->dbi().modules();
371   uint32_t count = modules.getModuleCount();
372   if (count == 0)
373     return count;
374 
375   // The linker can inject an additional "dummy" compilation unit into the
376   // PDB. Ignore this special compile unit for our purposes, if it is there.
377   // It is always the last one.
378   DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
379   if (last.getModuleName() == "* Linker *")
380     --count;
381   return count;
382 }
383 
384 Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
385   CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
386   CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
387   CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
388   lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
389   BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
390   auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
391   if (auto err = ts_or_err.takeError())
392     return *child_block;
393   auto ts = *ts_or_err;
394   if (!ts)
395     return *child_block;
396   PdbAstBuilder* ast_builder = ts->GetNativePDBParser();
397 
398   switch (sym.kind()) {
399   case S_GPROC32:
400   case S_LPROC32: {
401     // This is a function.  It must be global.  Creating the Function entry
402     // for it automatically creates a block for it.
403     FunctionSP func = GetOrCreateFunction(block_id, *comp_unit);
404     if (func) {
405       Block &block = func->GetBlock(false);
406       if (block.GetNumRanges() == 0)
407         block.AddRange(Block::Range(0, func->GetAddressRange().GetByteSize()));
408       return block;
409     }
410     break;
411   }
412   case S_BLOCK32: {
413     // This is a block.  Its parent is either a function or another block.  In
414     // either case, its parent can be viewed as a block (e.g. a function
415     // contains 1 big block.  So just get the parent block and add this block
416     // to it.
417     BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
418     cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
419     lldbassert(block.Parent != 0);
420     PdbCompilandSymId parent_id(block_id.modi, block.Parent);
421     Block &parent_block = GetOrCreateBlock(parent_id);
422     Function *func = parent_block.CalculateSymbolContextFunction();
423     lldbassert(func);
424     lldb::addr_t block_base =
425         m_index->MakeVirtualAddress(block.Segment, block.CodeOffset);
426     lldb::addr_t func_base =
427         func->GetAddressRange().GetBaseAddress().GetFileAddress();
428     if (block_base >= func_base)
429       child_block->AddRange(Block::Range(block_base - func_base, block.CodeSize));
430     else {
431       GetObjectFile()->GetModule()->ReportError(
432           "S_BLOCK32 at modi: {0:d} offset: {1:d}: adding range "
433           "[{2:x16}-{3:x16}) which has a base that is less than the "
434           "function's "
435           "low PC 0x%" PRIx64 ". Please file a bug and attach the file at the "
436           "start of this error message",
437           block_id.modi, block_id.offset, block_base,
438           block_base + block.CodeSize, func_base);
439     }
440     parent_block.AddChild(child_block);
441     ast_builder->GetOrCreateBlockDecl(block_id);
442     m_blocks.insert({opaque_block_uid, child_block});
443     break;
444   }
445   case S_INLINESITE: {
446     // This ensures line table is parsed first so we have inline sites info.
447     comp_unit->GetLineTable();
448 
449     std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid];
450     Block &parent_block = GetOrCreateBlock(inline_site->parent_id);
451     parent_block.AddChild(child_block);
452     ast_builder->GetOrCreateInlinedFunctionDecl(block_id);
453     // Copy ranges from InlineSite to Block.
454     for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
455       auto *entry = inline_site->ranges.GetEntryAtIndex(i);
456       child_block->AddRange(
457           Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
458     }
459     child_block->FinalizeRanges();
460 
461     // Get the inlined function callsite info.
462     Declaration &decl = inline_site->inline_function_info->GetDeclaration();
463     Declaration &callsite = inline_site->inline_function_info->GetCallSite();
464     child_block->SetInlinedFunctionInfo(
465         inline_site->inline_function_info->GetName().GetCString(), nullptr,
466         &decl, &callsite);
467     m_blocks.insert({opaque_block_uid, child_block});
468     break;
469   }
470   default:
471     lldbassert(false && "Symbol is not a block!");
472   }
473 
474   return *child_block;
475 }
476 
477 lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
478                                                      CompileUnit &comp_unit) {
479   const CompilandIndexItem *cci =
480       m_index->compilands().GetCompiland(func_id.modi);
481   lldbassert(cci);
482   CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
483 
484   lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);
485   SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record);
486 
487   auto file_vm_addr =
488       m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
489   if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
490     return nullptr;
491 
492   AddressRange func_range(file_vm_addr, sol.length,
493                           comp_unit.GetModule()->GetSectionList());
494   if (!func_range.GetBaseAddress().IsValid())
495     return nullptr;
496 
497   ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
498   cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
499   if (proc.FunctionType == TypeIndex::None())
500     return nullptr;
501   TypeSP func_type = GetOrCreateType(proc.FunctionType);
502   if (!func_type)
503     return nullptr;
504 
505   PdbTypeSymId sig_id(proc.FunctionType, false);
506   Mangled mangled(proc.Name);
507   FunctionSP func_sp = std::make_shared<Function>(
508       &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
509       func_type.get(), func_range);
510 
511   comp_unit.AddFunction(func_sp);
512 
513   auto ts_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage());
514   if (auto err = ts_or_err.takeError())
515     return func_sp;
516   auto ts = *ts_or_err;
517   if (!ts)
518     return func_sp;
519   ts->GetNativePDBParser()->GetOrCreateFunctionDecl(func_id);
520 
521   return func_sp;
522 }
523 
524 CompUnitSP
525 SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
526   lldb::LanguageType lang =
527       cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())
528                          : lldb::eLanguageTypeUnknown;
529 
530   LazyBool optimized = eLazyBoolNo;
531   if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())
532     optimized = eLazyBoolYes;
533 
534   llvm::SmallString<64> source_file_name =
535       m_index->compilands().GetMainSourceFile(cci);
536   FileSpec fs(llvm::sys::path::convert_to_slash(
537       source_file_name, llvm::sys::path::Style::windows_backslash));
538 
539   CompUnitSP cu_sp =
540       std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs,
541                                     toOpaqueUid(cci.m_id), lang, optimized);
542 
543   SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
544   return cu_sp;
545 }
546 
547 lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id,
548                                                      const ModifierRecord &mr,
549                                                      CompilerType ct) {
550   TpiStream &stream = m_index->tpi();
551 
552   std::string name;
553   if (mr.ModifiedType.isSimple())
554     name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind()));
555   else
556     name = computeTypeName(stream.typeCollection(), mr.ModifiedType);
557   Declaration decl;
558   lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);
559 
560   return MakeType(toOpaqueUid(type_id), ConstString(name),
561                   modified_type->GetByteSize(nullptr), nullptr,
562                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
563                   Type::ResolveState::Full);
564 }
565 
566 lldb::TypeSP
567 SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id,
568                                        const llvm::codeview::PointerRecord &pr,
569                                        CompilerType ct) {
570   TypeSP pointee = GetOrCreateType(pr.ReferentType);
571   if (!pointee)
572     return nullptr;
573 
574   if (pr.isPointerToMember()) {
575     MemberPointerInfo mpi = pr.getMemberInfo();
576     GetOrCreateType(mpi.ContainingType);
577   }
578 
579   Declaration decl;
580   return MakeType(toOpaqueUid(type_id), ConstString(), pr.getSize(), nullptr,
581                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
582                   Type::ResolveState::Full);
583 }
584 
585 lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti,
586                                                    CompilerType ct) {
587   uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));
588   if (ti == TypeIndex::NullptrT()) {
589     Declaration decl;
590     return MakeType(uid, ConstString("std::nullptr_t"), 0, nullptr,
591                     LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
592                     Type::ResolveState::Full);
593   }
594 
595   if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
596     TypeSP direct_sp = GetOrCreateType(ti.makeDirect());
597     uint32_t pointer_size = 0;
598     switch (ti.getSimpleMode()) {
599     case SimpleTypeMode::FarPointer32:
600     case SimpleTypeMode::NearPointer32:
601       pointer_size = 4;
602       break;
603     case SimpleTypeMode::NearPointer64:
604       pointer_size = 8;
605       break;
606     default:
607       // 128-bit and 16-bit pointers unsupported.
608       return nullptr;
609     }
610     Declaration decl;
611     return MakeType(uid, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID,
612                     Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);
613   }
614 
615   if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
616     return nullptr;
617 
618   size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind());
619   llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());
620 
621   Declaration decl;
622   return MakeType(uid, ConstString(type_name), size, nullptr, LLDB_INVALID_UID,
623                   Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);
624 }
625 
626 static std::string GetUnqualifiedTypeName(const TagRecord &record) {
627   if (!record.hasUniqueName()) {
628     MSVCUndecoratedNameParser parser(record.Name);
629     llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
630 
631     return std::string(specs.back().GetBaseName());
632   }
633 
634   llvm::ms_demangle::Demangler demangler;
635   std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());
636   llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
637   if (demangler.Error)
638     return std::string(record.Name);
639 
640   llvm::ms_demangle::IdentifierNode *idn =
641       ttn->QualifiedName->getUnqualifiedIdentifier();
642   return idn->toString();
643 }
644 
645 lldb::TypeSP
646 SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id,
647                                             const TagRecord &record,
648                                             size_t size, CompilerType ct) {
649 
650   std::string uname = GetUnqualifiedTypeName(record);
651 
652   // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
653   Declaration decl;
654   return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr,
655                   LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
656                   Type::ResolveState::Forward);
657 }
658 
659 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
660                                                 const ClassRecord &cr,
661                                                 CompilerType ct) {
662   return CreateClassStructUnion(type_id, cr, cr.getSize(), ct);
663 }
664 
665 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
666                                                 const UnionRecord &ur,
667                                                 CompilerType ct) {
668   return CreateClassStructUnion(type_id, ur, ur.getSize(), ct);
669 }
670 
671 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
672                                                 const EnumRecord &er,
673                                                 CompilerType ct) {
674   std::string uname = GetUnqualifiedTypeName(er);
675 
676   Declaration decl;
677   TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
678 
679   return MakeType(toOpaqueUid(type_id), ConstString(uname),
680                   underlying_type->GetByteSize(nullptr), nullptr,
681                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
682                   ct, lldb_private::Type::ResolveState::Forward);
683 }
684 
685 TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id,
686                                             const ArrayRecord &ar,
687                                             CompilerType ct) {
688   TypeSP element_type = GetOrCreateType(ar.ElementType);
689 
690   Declaration decl;
691   TypeSP array_sp =
692       MakeType(toOpaqueUid(type_id), ConstString(), ar.Size, nullptr,
693                LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct,
694                lldb_private::Type::ResolveState::Full);
695   array_sp->SetEncodingType(element_type.get());
696   return array_sp;
697 }
698 
699 TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,
700                                                const MemberFunctionRecord &mfr,
701                                                CompilerType ct) {
702   Declaration decl;
703   return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
704                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
705                   ct, lldb_private::Type::ResolveState::Full);
706 }
707 
708 TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
709                                                 const ProcedureRecord &pr,
710                                                 CompilerType ct) {
711   Declaration decl;
712   return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
713                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
714                   ct, lldb_private::Type::ResolveState::Full);
715 }
716 
717 TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
718   if (type_id.index.isSimple())
719     return CreateSimpleType(type_id.index, ct);
720 
721   TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi();
722   CVType cvt = stream.getType(type_id.index);
723 
724   if (cvt.kind() == LF_MODIFIER) {
725     ModifierRecord modifier;
726     llvm::cantFail(
727         TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
728     return CreateModifierType(type_id, modifier, ct);
729   }
730 
731   if (cvt.kind() == LF_POINTER) {
732     PointerRecord pointer;
733     llvm::cantFail(
734         TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
735     return CreatePointerType(type_id, pointer, ct);
736   }
737 
738   if (IsClassRecord(cvt.kind())) {
739     ClassRecord cr;
740     llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
741     return CreateTagType(type_id, cr, ct);
742   }
743 
744   if (cvt.kind() == LF_ENUM) {
745     EnumRecord er;
746     llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
747     return CreateTagType(type_id, er, ct);
748   }
749 
750   if (cvt.kind() == LF_UNION) {
751     UnionRecord ur;
752     llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
753     return CreateTagType(type_id, ur, ct);
754   }
755 
756   if (cvt.kind() == LF_ARRAY) {
757     ArrayRecord ar;
758     llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
759     return CreateArrayType(type_id, ar, ct);
760   }
761 
762   if (cvt.kind() == LF_PROCEDURE) {
763     ProcedureRecord pr;
764     llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
765     return CreateProcedureType(type_id, pr, ct);
766   }
767   if (cvt.kind() == LF_MFUNCTION) {
768     MemberFunctionRecord mfr;
769     llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
770     return CreateFunctionType(type_id, mfr, ct);
771   }
772 
773   return nullptr;
774 }
775 
776 TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) {
777   // If they search for a UDT which is a forward ref, try and resolve the full
778   // decl and just map the forward ref uid to the full decl record.
779   std::optional<PdbTypeSymId> full_decl_uid;
780   if (IsForwardRefUdt(type_id, m_index->tpi())) {
781     auto expected_full_ti =
782         m_index->tpi().findFullDeclForForwardRef(type_id.index);
783     if (!expected_full_ti)
784       llvm::consumeError(expected_full_ti.takeError());
785     else if (*expected_full_ti != type_id.index) {
786       full_decl_uid = PdbTypeSymId(*expected_full_ti, false);
787 
788       // It's possible that a lookup would occur for the full decl causing it
789       // to be cached, then a second lookup would occur for the forward decl.
790       // We don't want to create a second full decl, so make sure the full
791       // decl hasn't already been cached.
792       auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid));
793       if (full_iter != m_types.end()) {
794         TypeSP result = full_iter->second;
795         // Map the forward decl to the TypeSP for the full decl so we can take
796         // the fast path next time.
797         m_types[toOpaqueUid(type_id)] = result;
798         return result;
799       }
800     }
801   }
802 
803   PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
804   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
805   if (auto err = ts_or_err.takeError())
806     return nullptr;
807   auto ts = *ts_or_err;
808   if (!ts)
809     return nullptr;
810 
811   PdbAstBuilder* ast_builder = ts->GetNativePDBParser();
812   clang::QualType qt = ast_builder->GetOrCreateType(best_decl_id);
813   if (qt.isNull())
814     return nullptr;
815 
816   TypeSP result = CreateType(best_decl_id, ast_builder->ToCompilerType(qt));
817   if (!result)
818     return nullptr;
819 
820   uint64_t best_uid = toOpaqueUid(best_decl_id);
821   m_types[best_uid] = result;
822   // If we had both a forward decl and a full decl, make both point to the new
823   // type.
824   if (full_decl_uid)
825     m_types[toOpaqueUid(type_id)] = result;
826 
827   return result;
828 }
829 
830 TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
831   // We can't use try_emplace / overwrite here because the process of creating
832   // a type could create nested types, which could invalidate iterators.  So
833   // we have to do a 2-phase lookup / insert.
834   auto iter = m_types.find(toOpaqueUid(type_id));
835   if (iter != m_types.end())
836     return iter->second;
837 
838   TypeSP type = CreateAndCacheType(type_id);
839   if (type)
840     GetTypeList().Insert(type);
841   return type;
842 }
843 
844 VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
845   CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
846   if (sym.kind() == S_CONSTANT)
847     return CreateConstantSymbol(var_id, sym);
848 
849   lldb::ValueType scope = eValueTypeInvalid;
850   TypeIndex ti;
851   llvm::StringRef name;
852   lldb::addr_t addr = 0;
853   uint16_t section = 0;
854   uint32_t offset = 0;
855   bool is_external = false;
856   switch (sym.kind()) {
857   case S_GDATA32:
858     is_external = true;
859     [[fallthrough]];
860   case S_LDATA32: {
861     DataSym ds(sym.kind());
862     llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds));
863     ti = ds.Type;
864     scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal
865                                       : eValueTypeVariableStatic;
866     name = ds.Name;
867     section = ds.Segment;
868     offset = ds.DataOffset;
869     addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
870     break;
871   }
872   case S_GTHREAD32:
873     is_external = true;
874     [[fallthrough]];
875   case S_LTHREAD32: {
876     ThreadLocalDataSym tlds(sym.kind());
877     llvm::cantFail(
878         SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds));
879     ti = tlds.Type;
880     name = tlds.Name;
881     section = tlds.Segment;
882     offset = tlds.DataOffset;
883     addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
884     scope = eValueTypeVariableThreadLocal;
885     break;
886   }
887   default:
888     llvm_unreachable("unreachable!");
889   }
890 
891   CompUnitSP comp_unit;
892   std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);
893   if (!modi) {
894     return nullptr;
895   }
896 
897   CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);
898   comp_unit = GetOrCreateCompileUnit(cci);
899 
900   Declaration decl;
901   PdbTypeSymId tid(ti, false);
902   SymbolFileTypeSP type_sp =
903       std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
904   Variable::RangeList ranges;
905   auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
906   if (auto err = ts_or_err.takeError())
907     return nullptr;
908   auto ts = *ts_or_err;
909   if (!ts)
910     return nullptr;
911 
912   ts->GetNativePDBParser()->GetOrCreateVariableDecl(var_id);
913 
914   ModuleSP module_sp = GetObjectFile()->GetModule();
915   DWARFExpressionList location(
916       module_sp, MakeGlobalLocationExpression(section, offset, module_sp),
917       nullptr);
918 
919   std::string global_name("::");
920   global_name += name;
921   bool artificial = false;
922   bool location_is_constant_data = false;
923   bool static_member = false;
924   VariableSP var_sp = std::make_shared<Variable>(
925       toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
926       scope, comp_unit.get(), ranges, &decl, location, is_external, artificial,
927       location_is_constant_data, static_member);
928 
929   return var_sp;
930 }
931 
932 lldb::VariableSP
933 SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
934                                           const CVSymbol &cvs) {
935   TpiStream &tpi = m_index->tpi();
936   ConstantSym constant(cvs.kind());
937 
938   llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant));
939   std::string global_name("::");
940   global_name += constant.Name;
941   PdbTypeSymId tid(constant.Type, false);
942   SymbolFileTypeSP type_sp =
943       std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
944 
945   Declaration decl;
946   Variable::RangeList ranges;
947   ModuleSP module = GetObjectFile()->GetModule();
948   DWARFExpressionList location(module,
949                                MakeConstantLocationExpression(
950                                    constant.Type, tpi, constant.Value, module),
951                                nullptr);
952 
953   bool external = false;
954   bool artificial = false;
955   bool location_is_constant_data = true;
956   bool static_member = false;
957   VariableSP var_sp = std::make_shared<Variable>(
958       toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
959       type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
960       external, artificial, location_is_constant_data, static_member);
961   return var_sp;
962 }
963 
964 VariableSP
965 SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) {
966   auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr);
967   if (emplace_result.second) {
968     if (VariableSP var_sp = CreateGlobalVariable(var_id))
969       emplace_result.first->second = var_sp;
970     else
971       return nullptr;
972   }
973 
974   return emplace_result.first->second;
975 }
976 
977 lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) {
978   return GetOrCreateType(PdbTypeSymId(ti, false));
979 }
980 
981 FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id,
982                                                     CompileUnit &comp_unit) {
983   auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);
984   if (emplace_result.second)
985     emplace_result.first->second = CreateFunction(func_id, comp_unit);
986 
987   return emplace_result.first->second;
988 }
989 
990 CompUnitSP
991 SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) {
992 
993   auto emplace_result =
994       m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr);
995   if (emplace_result.second)
996     emplace_result.first->second = CreateCompileUnit(cci);
997 
998   lldbassert(emplace_result.first->second);
999   return emplace_result.first->second;
1000 }
1001 
1002 Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) {
1003   auto iter = m_blocks.find(toOpaqueUid(block_id));
1004   if (iter != m_blocks.end())
1005     return *iter->second;
1006 
1007   return CreateBlock(block_id);
1008 }
1009 
1010 void SymbolFileNativePDB::ParseDeclsForContext(
1011     lldb_private::CompilerDeclContext decl_ctx) {
1012   TypeSystem* ts_or_err = decl_ctx.GetTypeSystem();
1013   if (!ts_or_err)
1014     return;
1015   PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();
1016   clang::DeclContext *context = ast_builder->FromCompilerDeclContext(decl_ctx);
1017   if (!context)
1018     return;
1019   ast_builder->ParseDeclsForContext(*context);
1020 }
1021 
1022 lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
1023   if (index >= GetNumCompileUnits())
1024     return CompUnitSP();
1025   lldbassert(index < UINT16_MAX);
1026   if (index >= UINT16_MAX)
1027     return nullptr;
1028 
1029   CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);
1030 
1031   return GetOrCreateCompileUnit(item);
1032 }
1033 
1034 lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
1035   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1036   PdbSymUid uid(comp_unit.GetID());
1037   lldbassert(uid.kind() == PdbSymUidKind::Compiland);
1038 
1039   CompilandIndexItem *item =
1040       m_index->compilands().GetCompiland(uid.asCompiland().modi);
1041   lldbassert(item);
1042   if (!item->m_compile_opts)
1043     return lldb::eLanguageTypeUnknown;
1044 
1045   return TranslateLanguage(item->m_compile_opts->getLanguage());
1046 }
1047 
1048 void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {}
1049 
1050 size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
1051   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1052   PdbSymUid uid{comp_unit.GetID()};
1053   lldbassert(uid.kind() == PdbSymUidKind::Compiland);
1054   uint16_t modi = uid.asCompiland().modi;
1055   CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);
1056 
1057   size_t count = comp_unit.GetNumFunctions();
1058   const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
1059   for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
1060     if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
1061       continue;
1062 
1063     PdbCompilandSymId sym_id{modi, iter.offset()};
1064 
1065     FunctionSP func = GetOrCreateFunction(sym_id, comp_unit);
1066   }
1067 
1068   size_t new_count = comp_unit.GetNumFunctions();
1069   lldbassert(new_count >= count);
1070   return new_count - count;
1071 }
1072 
1073 static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
1074   // If any of these flags are set, we need to resolve the compile unit.
1075   uint32_t flags = eSymbolContextCompUnit;
1076   flags |= eSymbolContextVariable;
1077   flags |= eSymbolContextFunction;
1078   flags |= eSymbolContextBlock;
1079   flags |= eSymbolContextLineEntry;
1080   return (resolve_scope & flags) != 0;
1081 }
1082 
1083 uint32_t SymbolFileNativePDB::ResolveSymbolContext(
1084     const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
1085   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1086   uint32_t resolved_flags = 0;
1087   lldb::addr_t file_addr = addr.GetFileAddress();
1088 
1089   if (NeedsResolvedCompileUnit(resolve_scope)) {
1090     std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);
1091     if (!modi)
1092       return 0;
1093     CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi);
1094     if (!cu_sp)
1095       return 0;
1096 
1097     sc.comp_unit = cu_sp.get();
1098     resolved_flags |= eSymbolContextCompUnit;
1099   }
1100 
1101   if (resolve_scope & eSymbolContextFunction ||
1102       resolve_scope & eSymbolContextBlock) {
1103     lldbassert(sc.comp_unit);
1104     std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
1105     // Search the matches in reverse.  This way if there are multiple matches
1106     // (for example we are 3 levels deep in a nested scope) it will find the
1107     // innermost one first.
1108     for (const auto &match : llvm::reverse(matches)) {
1109       if (match.uid.kind() != PdbSymUidKind::CompilandSym)
1110         continue;
1111 
1112       PdbCompilandSymId csid = match.uid.asCompilandSym();
1113       CVSymbol cvs = m_index->ReadSymbolRecord(csid);
1114       PDB_SymType type = CVSymToPDBSym(cvs.kind());
1115       if (type != PDB_SymType::Function && type != PDB_SymType::Block)
1116         continue;
1117       if (type == PDB_SymType::Function) {
1118         sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
1119         if (sc.function) {
1120           Block &block = sc.function->GetBlock(true);
1121           addr_t func_base =
1122               sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
1123           addr_t offset = file_addr - func_base;
1124           sc.block = block.FindInnermostBlockByOffset(offset);
1125         }
1126       }
1127 
1128       if (type == PDB_SymType::Block) {
1129         Block &block = GetOrCreateBlock(csid);
1130         sc.function = block.CalculateSymbolContextFunction();
1131         if (sc.function) {
1132           sc.function->GetBlock(true);
1133           addr_t func_base =
1134               sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
1135           addr_t offset = file_addr - func_base;
1136           sc.block = block.FindInnermostBlockByOffset(offset);
1137         }
1138       }
1139       if (sc.function)
1140         resolved_flags |= eSymbolContextFunction;
1141       if (sc.block)
1142         resolved_flags |= eSymbolContextBlock;
1143       break;
1144     }
1145   }
1146 
1147   if (resolve_scope & eSymbolContextLineEntry) {
1148     lldbassert(sc.comp_unit);
1149     if (auto *line_table = sc.comp_unit->GetLineTable()) {
1150       if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
1151         resolved_flags |= eSymbolContextLineEntry;
1152     }
1153   }
1154 
1155   return resolved_flags;
1156 }
1157 
1158 uint32_t SymbolFileNativePDB::ResolveSymbolContext(
1159     const SourceLocationSpec &src_location_spec,
1160     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
1161   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1162   const uint32_t prev_size = sc_list.GetSize();
1163   if (resolve_scope & eSymbolContextCompUnit) {
1164     for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
1165          ++cu_idx) {
1166       CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get();
1167       if (!cu)
1168         continue;
1169 
1170       bool file_spec_matches_cu_file_spec = FileSpec::Match(
1171           src_location_spec.GetFileSpec(), cu->GetPrimaryFile());
1172       if (file_spec_matches_cu_file_spec) {
1173         cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
1174         break;
1175       }
1176     }
1177   }
1178   return sc_list.GetSize() - prev_size;
1179 }
1180 
1181 bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
1182   // Unfortunately LLDB is set up to parse the entire compile unit line table
1183   // all at once, even if all it really needs is line info for a specific
1184   // function.  In the future it would be nice if it could set the sc.m_function
1185   // member, and we could only get the line info for the function in question.
1186   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1187   PdbSymUid cu_id(comp_unit.GetID());
1188   lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
1189   uint16_t modi = cu_id.asCompiland().modi;
1190   CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi);
1191   lldbassert(cii);
1192 
1193   // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records
1194   // in this CU. Add line entries into the set first so that if there are line
1195   // entries with same addres, the later is always more accurate than the
1196   // former.
1197   std::set<LineTable::Entry, LineTableEntryComparator> line_set;
1198 
1199   // This is basically a copy of the .debug$S subsections from all original COFF
1200   // object files merged together with address relocations applied.  We are
1201   // looking for all DEBUG_S_LINES subsections.
1202   for (const DebugSubsectionRecord &dssr :
1203        cii->m_debug_stream.getSubsectionsArray()) {
1204     if (dssr.kind() != DebugSubsectionKind::Lines)
1205       continue;
1206 
1207     DebugLinesSubsectionRef lines;
1208     llvm::BinaryStreamReader reader(dssr.getRecordData());
1209     if (auto EC = lines.initialize(reader)) {
1210       llvm::consumeError(std::move(EC));
1211       return false;
1212     }
1213 
1214     const LineFragmentHeader *lfh = lines.header();
1215     uint64_t virtual_addr =
1216         m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1217     if (virtual_addr == LLDB_INVALID_ADDRESS)
1218       continue;
1219 
1220     for (const LineColumnEntry &group : lines) {
1221       llvm::Expected<uint32_t> file_index_or_err =
1222           GetFileIndex(*cii, group.NameIndex);
1223       if (!file_index_or_err)
1224         continue;
1225       uint32_t file_index = file_index_or_err.get();
1226       lldbassert(!group.LineNumbers.empty());
1227       CompilandIndexItem::GlobalLineTable::Entry line_entry(
1228           LLDB_INVALID_ADDRESS, 0);
1229       for (const LineNumberEntry &entry : group.LineNumbers) {
1230         LineInfo cur_info(entry.Flags);
1231 
1232         if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1233           continue;
1234 
1235         uint64_t addr = virtual_addr + entry.Offset;
1236 
1237         bool is_statement = cur_info.isStatement();
1238         bool is_prologue = IsFunctionPrologue(*cii, addr);
1239         bool is_epilogue = IsFunctionEpilogue(*cii, addr);
1240 
1241         uint32_t lno = cur_info.getStartLine();
1242 
1243         LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false,
1244                                  is_prologue, is_epilogue, false);
1245         // Terminal entry has lower precedence than new entry.
1246         auto iter = line_set.find(new_entry);
1247         if (iter != line_set.end() && iter->is_terminal_entry)
1248           line_set.erase(iter);
1249         line_set.insert(new_entry);
1250 
1251         if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
1252           line_entry.SetRangeEnd(addr);
1253           cii->m_global_line_table.Append(line_entry);
1254         }
1255         line_entry.SetRangeBase(addr);
1256         line_entry.data = {file_index, lno};
1257       }
1258       LineInfo last_line(group.LineNumbers.back().Flags);
1259       line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
1260                        file_index, false, false, false, false, true);
1261 
1262       if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
1263         line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize);
1264         cii->m_global_line_table.Append(line_entry);
1265       }
1266     }
1267   }
1268 
1269   cii->m_global_line_table.Sort();
1270 
1271   // Parse all S_INLINESITE in this CU.
1272   const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray();
1273   for (auto iter = syms.begin(); iter != syms.end();) {
1274     if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
1275       ++iter;
1276       continue;
1277     }
1278 
1279     uint32_t record_offset = iter.offset();
1280     CVSymbol func_record =
1281         cii->m_debug_stream.readSymbolAtOffset(record_offset);
1282     SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record);
1283     addr_t file_vm_addr =
1284         m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
1285     if (file_vm_addr == LLDB_INVALID_ADDRESS)
1286       continue;
1287 
1288     AddressRange func_range(file_vm_addr, sol.length,
1289                             comp_unit.GetModule()->GetSectionList());
1290     Address func_base = func_range.GetBaseAddress();
1291     PdbCompilandSymId func_id{modi, record_offset};
1292 
1293     // Iterate all S_INLINESITEs in the function.
1294     auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) {
1295       if (kind != S_INLINESITE)
1296         return false;
1297 
1298       ParseInlineSite(id, func_base);
1299 
1300       for (const auto &line_entry :
1301            m_inline_sites[toOpaqueUid(id)]->line_entries) {
1302         // If line_entry is not terminal entry, remove previous line entry at
1303         // the same address and insert new one. Terminal entry inside an inline
1304         // site might not be terminal entry for its parent.
1305         if (!line_entry.is_terminal_entry)
1306           line_set.erase(line_entry);
1307         line_set.insert(line_entry);
1308       }
1309       // No longer useful after adding to line_set.
1310       m_inline_sites[toOpaqueUid(id)]->line_entries.clear();
1311       return true;
1312     };
1313     ParseSymbolArrayInScope(func_id, parse_inline_sites);
1314     // Jump to the end of the function record.
1315     iter = syms.at(getScopeEndOffset(func_record));
1316   }
1317 
1318   cii->m_global_line_table.Clear();
1319 
1320   // Add line entries in line_set to line_table.
1321   auto line_table = std::make_unique<LineTable>(&comp_unit);
1322   std::unique_ptr<LineSequence> sequence(
1323       line_table->CreateLineSequenceContainer());
1324   for (const auto &line_entry : line_set) {
1325     line_table->AppendLineEntryToSequence(
1326         sequence.get(), line_entry.file_addr, line_entry.line,
1327         line_entry.column, line_entry.file_idx,
1328         line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
1329         line_entry.is_prologue_end, line_entry.is_epilogue_begin,
1330         line_entry.is_terminal_entry);
1331   }
1332   line_table->InsertSequence(sequence.get());
1333 
1334   if (line_table->GetSize() == 0)
1335     return false;
1336 
1337   comp_unit.SetLineTable(line_table.release());
1338   return true;
1339 }
1340 
1341 bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
1342   // PDB doesn't contain information about macros
1343   return false;
1344 }
1345 
1346 llvm::Expected<uint32_t>
1347 SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii,
1348                                   uint32_t file_id) {
1349   if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings())
1350     return llvm::make_error<RawError>(raw_error_code::no_entry);
1351 
1352   const auto &checksums = cii.m_strings.checksums().getArray();
1353   const auto &strings = cii.m_strings.strings();
1354   // Indices in this structure are actually offsets of records in the
1355   // DEBUG_S_FILECHECKSUMS subsection.  Those entries then have an index
1356   // into the global PDB string table.
1357   auto iter = checksums.at(file_id);
1358   if (iter == checksums.end())
1359     return llvm::make_error<RawError>(raw_error_code::no_entry);
1360 
1361   llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
1362   if (!efn) {
1363     return efn.takeError();
1364   }
1365 
1366   // LLDB wants the index of the file in the list of support files.
1367   auto fn_iter = llvm::find(cii.m_file_list, *efn);
1368   if (fn_iter != cii.m_file_list.end())
1369     return std::distance(cii.m_file_list.begin(), fn_iter);
1370   return llvm::make_error<RawError>(raw_error_code::no_entry);
1371 }
1372 
1373 bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
1374                                             FileSpecList &support_files) {
1375   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1376   PdbSymUid cu_id(comp_unit.GetID());
1377   lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
1378   CompilandIndexItem *cci =
1379       m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
1380   lldbassert(cci);
1381 
1382   for (llvm::StringRef f : cci->m_file_list) {
1383     FileSpec::Style style =
1384         f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1385     FileSpec spec(f, style);
1386     support_files.Append(spec);
1387   }
1388   return true;
1389 }
1390 
1391 bool SymbolFileNativePDB::ParseImportedModules(
1392     const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1393   // PDB does not yet support module debug info
1394   return false;
1395 }
1396 
1397 void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,
1398                                           Address func_addr) {
1399   lldb::user_id_t opaque_uid = toOpaqueUid(id);
1400   if (m_inline_sites.contains(opaque_uid))
1401     return;
1402 
1403   addr_t func_base = func_addr.GetFileAddress();
1404   CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi);
1405   CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset);
1406   CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
1407 
1408   InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
1409   cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
1410   PdbCompilandSymId parent_id(id.modi, inline_site.Parent);
1411 
1412   std::shared_ptr<InlineSite> inline_site_sp =
1413       std::make_shared<InlineSite>(parent_id);
1414 
1415   // Get the inlined function declaration info.
1416   auto iter = cii->m_inline_map.find(inline_site.Inlinee);
1417   if (iter == cii->m_inline_map.end())
1418     return;
1419   InlineeSourceLine inlinee_line = iter->second;
1420 
1421   const FileSpecList &files = comp_unit->GetSupportFiles();
1422   FileSpec decl_file;
1423   llvm::Expected<uint32_t> file_index_or_err =
1424       GetFileIndex(*cii, inlinee_line.Header->FileID);
1425   if (!file_index_or_err)
1426     return;
1427   uint32_t file_offset = file_index_or_err.get();
1428   decl_file = files.GetFileSpecAtIndex(file_offset);
1429   uint32_t decl_line = inlinee_line.Header->SourceLineNum;
1430   std::unique_ptr<Declaration> decl_up =
1431       std::make_unique<Declaration>(decl_file, decl_line);
1432 
1433   // Parse range and line info.
1434   uint32_t code_offset = 0;
1435   int32_t line_offset = 0;
1436   std::optional<uint32_t> code_offset_base;
1437   std::optional<uint32_t> code_offset_end;
1438   std::optional<int32_t> cur_line_offset;
1439   std::optional<int32_t> next_line_offset;
1440   std::optional<uint32_t> next_file_offset;
1441 
1442   bool is_terminal_entry = false;
1443   bool is_start_of_statement = true;
1444   // The first instruction is the prologue end.
1445   bool is_prologue_end = true;
1446 
1447   auto update_code_offset = [&](uint32_t code_delta) {
1448     if (!code_offset_base)
1449       code_offset_base = code_offset;
1450     else if (!code_offset_end)
1451       code_offset_end = *code_offset_base + code_delta;
1452   };
1453   auto update_line_offset = [&](int32_t line_delta) {
1454     line_offset += line_delta;
1455     if (!code_offset_base || !cur_line_offset)
1456       cur_line_offset = line_offset;
1457     else
1458       next_line_offset = line_offset;
1459     ;
1460   };
1461   auto update_file_offset = [&](uint32_t offset) {
1462     if (!code_offset_base)
1463       file_offset = offset;
1464     else
1465       next_file_offset = offset;
1466   };
1467 
1468   for (auto &annot : inline_site.annotations()) {
1469     switch (annot.OpCode) {
1470     case BinaryAnnotationsOpCode::CodeOffset:
1471     case BinaryAnnotationsOpCode::ChangeCodeOffset:
1472     case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
1473       code_offset += annot.U1;
1474       update_code_offset(annot.U1);
1475       break;
1476     case BinaryAnnotationsOpCode::ChangeLineOffset:
1477       update_line_offset(annot.S1);
1478       break;
1479     case BinaryAnnotationsOpCode::ChangeCodeLength:
1480       update_code_offset(annot.U1);
1481       code_offset += annot.U1;
1482       is_terminal_entry = true;
1483       break;
1484     case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
1485       code_offset += annot.U1;
1486       update_code_offset(annot.U1);
1487       update_line_offset(annot.S1);
1488       break;
1489     case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
1490       code_offset += annot.U2;
1491       update_code_offset(annot.U2);
1492       update_code_offset(annot.U1);
1493       code_offset += annot.U1;
1494       is_terminal_entry = true;
1495       break;
1496     case BinaryAnnotationsOpCode::ChangeFile:
1497       update_file_offset(annot.U1);
1498       break;
1499     default:
1500       break;
1501     }
1502 
1503     // Add range if current range is finished.
1504     if (code_offset_base && code_offset_end && cur_line_offset) {
1505       inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
1506           *code_offset_base, *code_offset_end - *code_offset_base,
1507           decl_line + *cur_line_offset));
1508       // Set base, end, file offset and line offset for next range.
1509       if (next_file_offset)
1510         file_offset = *next_file_offset;
1511       if (next_line_offset) {
1512         cur_line_offset = next_line_offset;
1513         next_line_offset = std::nullopt;
1514       }
1515       code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;
1516       code_offset_end = next_file_offset = std::nullopt;
1517     }
1518     if (code_offset_base && cur_line_offset) {
1519       if (is_terminal_entry) {
1520         LineTable::Entry line_entry(
1521             func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
1522             file_offset, false, false, false, false, true);
1523         inline_site_sp->line_entries.push_back(line_entry);
1524       } else {
1525         LineTable::Entry line_entry(func_base + *code_offset_base,
1526                                     decl_line + *cur_line_offset, 0,
1527                                     file_offset, is_start_of_statement, false,
1528                                     is_prologue_end, false, false);
1529         inline_site_sp->line_entries.push_back(line_entry);
1530         is_prologue_end = false;
1531         is_start_of_statement = false;
1532       }
1533     }
1534     if (is_terminal_entry)
1535       is_start_of_statement = true;
1536     is_terminal_entry = false;
1537   }
1538 
1539   inline_site_sp->ranges.Sort();
1540 
1541   // Get the inlined function callsite info.
1542   std::unique_ptr<Declaration> callsite_up;
1543   if (!inline_site_sp->ranges.IsEmpty()) {
1544     auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
1545     addr_t base_offset = entry->GetRangeBase();
1546     if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() ==
1547         S_INLINESITE) {
1548       // Its parent is another inline site, lookup parent site's range vector
1549       // for callsite line.
1550       ParseInlineSite(parent_id, func_base);
1551       std::shared_ptr<InlineSite> parent_site =
1552           m_inline_sites[toOpaqueUid(parent_id)];
1553       FileSpec &parent_decl_file =
1554           parent_site->inline_function_info->GetDeclaration().GetFile();
1555       if (auto *parent_entry =
1556               parent_site->ranges.FindEntryThatContains(base_offset)) {
1557         callsite_up =
1558             std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
1559       }
1560     } else {
1561       // Its parent is a function, lookup global line table for callsite.
1562       if (auto *entry = cii->m_global_line_table.FindEntryThatContains(
1563               func_base + base_offset)) {
1564         const FileSpec &callsite_file =
1565             files.GetFileSpecAtIndex(entry->data.first);
1566         callsite_up =
1567             std::make_unique<Declaration>(callsite_file, entry->data.second);
1568       }
1569     }
1570   }
1571 
1572   // Get the inlined function name.
1573   CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee);
1574   std::string inlinee_name;
1575   if (inlinee_cvt.kind() == LF_MFUNC_ID) {
1576     MemberFuncIdRecord mfr;
1577     cantFail(
1578         TypeDeserializer::deserializeAs<MemberFuncIdRecord>(inlinee_cvt, mfr));
1579     LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
1580     inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
1581     inlinee_name.append("::");
1582     inlinee_name.append(mfr.getName().str());
1583   } else if (inlinee_cvt.kind() == LF_FUNC_ID) {
1584     FuncIdRecord fir;
1585     cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(inlinee_cvt, fir));
1586     TypeIndex parent_idx = fir.getParentScope();
1587     if (!parent_idx.isNoneType()) {
1588       LazyRandomTypeCollection &ids = m_index->ipi().typeCollection();
1589       inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
1590       inlinee_name.append("::");
1591     }
1592     inlinee_name.append(fir.getName().str());
1593   }
1594   inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
1595       inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
1596       callsite_up.get());
1597 
1598   m_inline_sites[opaque_uid] = inline_site_sp;
1599 }
1600 
1601 size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
1602   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1603   PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym();
1604   // After we iterate through inline sites inside the function, we already get
1605   // all the info needed, removing from the map to save memory.
1606   std::set<uint64_t> remove_uids;
1607   auto parse_blocks = [&](SymbolKind kind, PdbCompilandSymId id) {
1608     if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
1609         kind == S_INLINESITE) {
1610       GetOrCreateBlock(id);
1611       if (kind == S_INLINESITE)
1612         remove_uids.insert(toOpaqueUid(id));
1613       return true;
1614     }
1615     return false;
1616   };
1617   size_t count = ParseSymbolArrayInScope(func_id, parse_blocks);
1618   for (uint64_t uid : remove_uids) {
1619     m_inline_sites.erase(uid);
1620   }
1621   return count;
1622 }
1623 
1624 size_t SymbolFileNativePDB::ParseSymbolArrayInScope(
1625     PdbCompilandSymId parent_id,
1626     llvm::function_ref<bool(SymbolKind, PdbCompilandSymId)> fn) {
1627   CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi);
1628   CVSymbolArray syms =
1629       cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset);
1630 
1631   size_t count = 1;
1632   for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
1633     PdbCompilandSymId child_id(parent_id.modi, iter.offset());
1634     if (fn(iter->kind(), child_id))
1635       ++count;
1636   }
1637 
1638   return count;
1639 }
1640 
1641 void SymbolFileNativePDB::DumpClangAST(Stream &s) {
1642   auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
1643   if (!ts_or_err)
1644     return;
1645   auto ts = *ts_or_err;
1646   TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
1647   if (!clang)
1648     return;
1649   clang->GetNativePDBParser()->Dump(s);
1650 }
1651 
1652 void SymbolFileNativePDB::FindGlobalVariables(
1653     ConstString name, const CompilerDeclContext &parent_decl_ctx,
1654     uint32_t max_matches, VariableList &variables) {
1655   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1656   using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
1657 
1658   std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
1659       name.GetStringRef(), m_index->symrecords());
1660   for (const SymbolAndOffset &result : results) {
1661     switch (result.second.kind()) {
1662     case SymbolKind::S_GDATA32:
1663     case SymbolKind::S_LDATA32:
1664     case SymbolKind::S_GTHREAD32:
1665     case SymbolKind::S_LTHREAD32:
1666     case SymbolKind::S_CONSTANT: {
1667       PdbGlobalSymId global(result.first, false);
1668       if (VariableSP var = GetOrCreateGlobalVariable(global))
1669         variables.AddVariable(var);
1670       break;
1671     }
1672     default:
1673       continue;
1674     }
1675   }
1676 }
1677 
1678 void SymbolFileNativePDB::FindFunctions(
1679     const Module::LookupInfo &lookup_info,
1680     const CompilerDeclContext &parent_decl_ctx, bool include_inlines,
1681     SymbolContextList &sc_list) {
1682   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1683   ConstString name = lookup_info.GetLookupName();
1684   FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
1685   if (name_type_mask & eFunctionNameTypeFull)
1686     name = lookup_info.GetName();
1687 
1688   // For now we only support lookup by method name or full name.
1689   if (!(name_type_mask & eFunctionNameTypeFull ||
1690         name_type_mask & eFunctionNameTypeMethod))
1691     return;
1692 
1693   using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
1694 
1695   std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName(
1696       name.GetStringRef(), m_index->symrecords());
1697   for (const SymbolAndOffset &match : matches) {
1698     if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
1699       continue;
1700     ProcRefSym proc(match.second.kind());
1701     cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc));
1702 
1703     if (!IsValidRecord(proc))
1704       continue;
1705 
1706     CompilandIndexItem &cci =
1707         m_index->compilands().GetOrCreateCompiland(proc.modi());
1708     SymbolContext sc;
1709 
1710     sc.comp_unit = GetOrCreateCompileUnit(cci).get();
1711     PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
1712     sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
1713 
1714     sc_list.Append(sc);
1715   }
1716 }
1717 
1718 void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
1719                                         bool include_inlines,
1720                                         SymbolContextList &sc_list) {}
1721 
1722 void SymbolFileNativePDB::FindTypes(
1723     ConstString name, const CompilerDeclContext &parent_decl_ctx,
1724     uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
1725     TypeMap &types) {
1726   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1727   if (!name)
1728     return;
1729 
1730   searched_symbol_files.clear();
1731   searched_symbol_files.insert(this);
1732 
1733   // There is an assumption 'name' is not a regex
1734   FindTypesByName(name.GetStringRef(), max_matches, types);
1735 }
1736 
1737 void SymbolFileNativePDB::FindTypes(
1738     llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
1739     llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {}
1740 
1741 void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
1742                                           uint32_t max_matches,
1743                                           TypeMap &types) {
1744 
1745   std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
1746   if (max_matches > 0 && max_matches < matches.size())
1747     matches.resize(max_matches);
1748 
1749   for (TypeIndex ti : matches) {
1750     TypeSP type = GetOrCreateType(ti);
1751     if (!type)
1752       continue;
1753 
1754     types.Insert(type);
1755   }
1756 }
1757 
1758 size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
1759   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1760   // Only do the full type scan the first time.
1761   if (m_done_full_type_scan)
1762     return 0;
1763 
1764   const size_t old_count = GetTypeList().GetSize();
1765   LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
1766 
1767   // First process the entire TPI stream.
1768   for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
1769     TypeSP type = GetOrCreateType(*ti);
1770     if (type)
1771       (void)type->GetFullCompilerType();
1772   }
1773 
1774   // Next look for S_UDT records in the globals stream.
1775   for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
1776     PdbGlobalSymId global{gid, false};
1777     CVSymbol sym = m_index->ReadSymbolRecord(global);
1778     if (sym.kind() != S_UDT)
1779       continue;
1780 
1781     UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
1782     bool is_typedef = true;
1783     if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {
1784       CVType cvt = m_index->tpi().getType(udt.Type);
1785       llvm::StringRef name = CVTagRecord::create(cvt).name();
1786       if (name == udt.Name)
1787         is_typedef = false;
1788     }
1789 
1790     if (is_typedef)
1791       GetOrCreateTypedef(global);
1792   }
1793 
1794   const size_t new_count = GetTypeList().GetSize();
1795 
1796   m_done_full_type_scan = true;
1797 
1798   return new_count - old_count;
1799 }
1800 
1801 size_t
1802 SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
1803                                                   VariableList &variables) {
1804   PdbSymUid sym_uid(comp_unit.GetID());
1805   lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);
1806   return 0;
1807 }
1808 
1809 VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
1810                                                     PdbCompilandSymId var_id,
1811                                                     bool is_param) {
1812   ModuleSP module = GetObjectFile()->GetModule();
1813   Block &block = GetOrCreateBlock(scope_id);
1814   // Get function block.
1815   Block *func_block = &block;
1816   while (func_block->GetParent()) {
1817     func_block = func_block->GetParent();
1818   }
1819   Address addr;
1820   func_block->GetStartAddress(addr);
1821   VariableInfo var_info =
1822       GetVariableLocationInfo(*m_index, var_id, *func_block, module);
1823   Function *func = func_block->CalculateSymbolContextFunction();
1824   if (!func)
1825     return nullptr;
1826   // Use empty dwarf expr if optimized away so that it won't be filtered out
1827   // when lookuping local variables in this scope.
1828   if (!var_info.location.IsValid())
1829     var_info.location = DWARFExpressionList(module, DWARFExpression(), nullptr);
1830   var_info.location.SetFuncFileAddress(
1831       func->GetAddressRange().GetBaseAddress().GetFileAddress());
1832   CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
1833   CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
1834   TypeSP type_sp = GetOrCreateType(var_info.type);
1835   if (!type_sp)
1836     return nullptr;
1837   std::string name = var_info.name.str();
1838   Declaration decl;
1839   SymbolFileTypeSP sftype =
1840       std::make_shared<SymbolFileType>(*this, type_sp->GetID());
1841 
1842   is_param |= var_info.is_param;
1843   ValueType var_scope =
1844       is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;
1845   bool external = false;
1846   bool artificial = false;
1847   bool location_is_constant_data = false;
1848   bool static_member = false;
1849   Variable::RangeList scope_ranges;
1850   VariableSP var_sp = std::make_shared<Variable>(
1851       toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
1852       &block, scope_ranges, &decl, var_info.location, external, artificial,
1853       location_is_constant_data, static_member);
1854   if (!is_param) {
1855     auto ts_or_err = GetTypeSystemForLanguage(comp_unit_sp->GetLanguage());
1856     if (auto err = ts_or_err.takeError())
1857       return nullptr;
1858     auto ts = *ts_or_err;
1859     if (!ts)
1860       return nullptr;
1861 
1862     ts->GetNativePDBParser()->GetOrCreateVariableDecl(scope_id, var_id);
1863   }
1864   m_local_variables[toOpaqueUid(var_id)] = var_sp;
1865   return var_sp;
1866 }
1867 
1868 VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable(
1869     PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
1870   auto iter = m_local_variables.find(toOpaqueUid(var_id));
1871   if (iter != m_local_variables.end())
1872     return iter->second;
1873 
1874   return CreateLocalVariable(scope_id, var_id, is_param);
1875 }
1876 
1877 TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
1878   CVSymbol sym = m_index->ReadSymbolRecord(id);
1879   lldbassert(sym.kind() == SymbolKind::S_UDT);
1880 
1881   UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
1882 
1883   TypeSP target_type = GetOrCreateType(udt.Type);
1884 
1885   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1886   if (auto err = ts_or_err.takeError())
1887     return nullptr;
1888   auto ts = *ts_or_err;
1889   if (!ts)
1890     return nullptr;
1891 
1892   ts->GetNativePDBParser()->GetOrCreateTypedefDecl(id);
1893 
1894   Declaration decl;
1895   return MakeType(
1896       toOpaqueUid(id), ConstString(udt.Name), target_type->GetByteSize(nullptr),
1897       nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID,
1898       decl, target_type->GetForwardCompilerType(),
1899       lldb_private::Type::ResolveState::Forward);
1900 }
1901 
1902 TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) {
1903   auto iter = m_types.find(toOpaqueUid(id));
1904   if (iter != m_types.end())
1905     return iter->second;
1906 
1907   return CreateTypedef(id);
1908 }
1909 
1910 size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
1911   Block &block = GetOrCreateBlock(block_id);
1912 
1913   size_t count = 0;
1914 
1915   CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
1916   CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
1917   uint32_t params_remaining = 0;
1918   switch (sym.kind()) {
1919   case S_GPROC32:
1920   case S_LPROC32: {
1921     ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));
1922     cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));
1923     CVType signature = m_index->tpi().getType(proc.FunctionType);
1924     if (signature.kind() == LF_PROCEDURE) {
1925       ProcedureRecord sig;
1926       if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(
1927               signature, sig)) {
1928         llvm::consumeError(std::move(e));
1929         return 0;
1930       }
1931       params_remaining = sig.getParameterCount();
1932     } else if (signature.kind() == LF_MFUNCTION) {
1933       MemberFunctionRecord sig;
1934       if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
1935               signature, sig)) {
1936         llvm::consumeError(std::move(e));
1937         return 0;
1938       }
1939       params_remaining = sig.getParameterCount();
1940     } else
1941       return 0;
1942     break;
1943   }
1944   case S_BLOCK32:
1945     break;
1946   case S_INLINESITE:
1947     break;
1948   default:
1949     lldbassert(false && "Symbol is not a block!");
1950     return 0;
1951   }
1952 
1953   VariableListSP variables = block.GetBlockVariableList(false);
1954   if (!variables) {
1955     variables = std::make_shared<VariableList>();
1956     block.SetVariableList(variables);
1957   }
1958 
1959   CVSymbolArray syms = limitSymbolArrayToScope(
1960       cii->m_debug_stream.getSymbolArray(), block_id.offset);
1961 
1962   // Skip the first record since it's a PROC32 or BLOCK32, and there's
1963   // no point examining it since we know it's not a local variable.
1964   syms.drop_front();
1965   auto iter = syms.begin();
1966   auto end = syms.end();
1967 
1968   while (iter != end) {
1969     uint32_t record_offset = iter.offset();
1970     CVSymbol variable_cvs = *iter;
1971     PdbCompilandSymId child_sym_id(block_id.modi, record_offset);
1972     ++iter;
1973 
1974     // If this is a block or inline site, recurse into its children and then
1975     // skip it.
1976     if (variable_cvs.kind() == S_BLOCK32 ||
1977         variable_cvs.kind() == S_INLINESITE) {
1978       uint32_t block_end = getScopeEndOffset(variable_cvs);
1979       count += ParseVariablesForBlock(child_sym_id);
1980       iter = syms.at(block_end);
1981       continue;
1982     }
1983 
1984     bool is_param = params_remaining > 0;
1985     VariableSP variable;
1986     switch (variable_cvs.kind()) {
1987     case S_REGREL32:
1988     case S_REGISTER:
1989     case S_LOCAL:
1990       variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
1991       if (is_param)
1992         --params_remaining;
1993       if (variable)
1994         variables->AddVariableIfUnique(variable);
1995       break;
1996     default:
1997       break;
1998     }
1999   }
2000 
2001   // Pass false for set_children, since we call this recursively so that the
2002   // children will call this for themselves.
2003   block.SetDidParseVariables(true, false);
2004 
2005   return count;
2006 }
2007 
2008 size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
2009   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2010   lldbassert(sc.function || sc.comp_unit);
2011 
2012   VariableListSP variables;
2013   if (sc.block) {
2014     PdbSymUid block_id(sc.block->GetID());
2015 
2016     size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
2017     return count;
2018   }
2019 
2020   if (sc.function) {
2021     PdbSymUid block_id(sc.function->GetID());
2022 
2023     size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
2024     return count;
2025   }
2026 
2027   if (sc.comp_unit) {
2028     variables = sc.comp_unit->GetVariableList(false);
2029     if (!variables) {
2030       variables = std::make_shared<VariableList>();
2031       sc.comp_unit->SetVariableList(variables);
2032     }
2033     return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);
2034   }
2035 
2036   llvm_unreachable("Unreachable!");
2037 }
2038 
2039 CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
2040   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
2041   if (auto err = ts_or_err.takeError())
2042     return CompilerDecl();
2043   auto ts = *ts_or_err;
2044   if (!ts)
2045     return {};
2046 
2047   if (auto decl = ts->GetNativePDBParser()->GetOrCreateDeclForUid(uid))
2048     return *decl;
2049   return CompilerDecl();
2050 }
2051 
2052 CompilerDeclContext
2053 SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {
2054   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
2055   if (auto err = ts_or_err.takeError())
2056     return {};
2057   auto ts = *ts_or_err;
2058   if (!ts)
2059     return {};
2060 
2061   PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2062   clang::DeclContext *context =
2063       ast_builder->GetOrCreateDeclContextForUid(PdbSymUid(uid));
2064   if (!context)
2065     return {};
2066 
2067   return ast_builder->ToCompilerDeclContext(*context);
2068 }
2069 
2070 CompilerDeclContext
2071 SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
2072   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
2073   if (auto err = ts_or_err.takeError())
2074     return CompilerDeclContext();
2075   auto ts = *ts_or_err;
2076   if (!ts)
2077     return {};
2078 
2079   PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2080   clang::DeclContext *context = ast_builder->GetParentDeclContext(PdbSymUid(uid));
2081   if (!context)
2082     return CompilerDeclContext();
2083   return ast_builder->ToCompilerDeclContext(*context);
2084 }
2085 
2086 Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
2087   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2088   auto iter = m_types.find(type_uid);
2089   // lldb should not be passing us non-sensical type uids.  the only way it
2090   // could have a type uid in the first place is if we handed it out, in which
2091   // case we should know about the type.  However, that doesn't mean we've
2092   // instantiated it yet.  We can vend out a UID for a future type.  So if the
2093   // type doesn't exist, let's instantiate it now.
2094   if (iter != m_types.end())
2095     return &*iter->second;
2096 
2097   PdbSymUid uid(type_uid);
2098   lldbassert(uid.kind() == PdbSymUidKind::Type);
2099   PdbTypeSymId type_id = uid.asTypeSym();
2100   if (type_id.index.isNoneType())
2101     return nullptr;
2102 
2103   TypeSP type_sp = CreateAndCacheType(type_id);
2104   if (!type_sp)
2105     return nullptr;
2106   return &*type_sp;
2107 }
2108 
2109 std::optional<SymbolFile::ArrayInfo>
2110 SymbolFileNativePDB::GetDynamicArrayInfoForUID(
2111     lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
2112   return std::nullopt;
2113 }
2114 
2115 bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
2116   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2117   auto ts = compiler_type.GetTypeSystem();
2118   auto clang_type_system = ts.dyn_cast_or_null<TypeSystemClang>();
2119   if (!clang_type_system)
2120     return false;
2121 
2122   PdbAstBuilder *ast_builder =
2123       static_cast<PdbAstBuilder *>(clang_type_system->GetNativePDBParser());
2124   if (ast_builder &&
2125       ast_builder->GetClangASTImporter().CanImport(compiler_type))
2126     return ast_builder->GetClangASTImporter().CompleteType(compiler_type);
2127   clang::QualType qt =
2128       clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType());
2129 
2130   return ast_builder->CompleteType(qt);
2131 }
2132 
2133 void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
2134                                    TypeClass type_mask,
2135                                    lldb_private::TypeList &type_list) {}
2136 
2137 CompilerDeclContext SymbolFileNativePDB::FindNamespace(
2138     ConstString name, const CompilerDeclContext &parent_decl_ctx, bool) {
2139   return {};
2140 }
2141 
2142 llvm::Expected<lldb::TypeSystemSP>
2143 SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
2144   auto type_system_or_err =
2145       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
2146   if (type_system_or_err)
2147     if (auto ts = *type_system_or_err)
2148       ts->SetSymbolFile(this);
2149   return type_system_or_err;
2150 }
2151 
2152 uint64_t SymbolFileNativePDB::GetDebugInfoSize() {
2153   // PDB files are a separate file that contains all debug info.
2154   return m_index->pdb().getFileSize();
2155 }
2156 
2157 void SymbolFileNativePDB::BuildParentMap() {
2158   LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
2159 
2160   llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
2161   llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
2162 
2163   struct RecordIndices {
2164     TypeIndex forward;
2165     TypeIndex full;
2166   };
2167 
2168   llvm::StringMap<RecordIndices> record_indices;
2169 
2170   for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2171     CVType type = types.getType(*ti);
2172     if (!IsTagRecord(type))
2173       continue;
2174 
2175     CVTagRecord tag = CVTagRecord::create(type);
2176 
2177     RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
2178     if (tag.asTag().isForwardRef())
2179       indices.forward = *ti;
2180     else
2181       indices.full = *ti;
2182 
2183     if (indices.full != TypeIndex::None() &&
2184         indices.forward != TypeIndex::None()) {
2185       forward_to_full[indices.forward] = indices.full;
2186       full_to_forward[indices.full] = indices.forward;
2187     }
2188 
2189     // We're looking for LF_NESTTYPE records in the field list, so ignore
2190     // forward references (no field list), and anything without a nested class
2191     // (since there won't be any LF_NESTTYPE records).
2192     if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())
2193       continue;
2194 
2195     struct ProcessTpiStream : public TypeVisitorCallbacks {
2196       ProcessTpiStream(PdbIndex &index, TypeIndex parent,
2197                        const CVTagRecord &parent_cvt,
2198                        llvm::DenseMap<TypeIndex, TypeIndex> &parents)
2199           : index(index), parents(parents), parent(parent),
2200             parent_cvt(parent_cvt) {}
2201 
2202       PdbIndex &index;
2203       llvm::DenseMap<TypeIndex, TypeIndex> &parents;
2204 
2205       unsigned unnamed_type_index = 1;
2206       TypeIndex parent;
2207       const CVTagRecord &parent_cvt;
2208 
2209       llvm::Error visitKnownMember(CVMemberRecord &CVR,
2210                                    NestedTypeRecord &Record) override {
2211         std::string unnamed_type_name;
2212         if (Record.Name.empty()) {
2213           unnamed_type_name =
2214               llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();
2215           Record.Name = unnamed_type_name;
2216           ++unnamed_type_index;
2217         }
2218         std::optional<CVTagRecord> tag =
2219             GetNestedTagDefinition(Record, parent_cvt, index.tpi());
2220         if (!tag)
2221           return llvm::ErrorSuccess();
2222 
2223         parents[Record.Type] = parent;
2224         return llvm::ErrorSuccess();
2225       }
2226     };
2227 
2228     CVType field_list_cvt = m_index->tpi().getType(tag.asTag().FieldList);
2229     ProcessTpiStream process(*m_index, *ti, tag, m_parent_types);
2230     FieldListRecord field_list;
2231     if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
2232             field_list_cvt, field_list))
2233       llvm::consumeError(std::move(error));
2234     if (llvm::Error error = visitMemberRecordStream(field_list.Data, process))
2235       llvm::consumeError(std::move(error));
2236   }
2237 
2238   // Now that we know the forward -> full mapping of all type indices, we can
2239   // re-write all the indices.  At the end of this process, we want a mapping
2240   // consisting of fwd -> full and full -> full for all child -> parent indices.
2241   // We can re-write the values in place, but for the keys, we must save them
2242   // off so that we don't modify the map in place while also iterating it.
2243   std::vector<TypeIndex> full_keys;
2244   std::vector<TypeIndex> fwd_keys;
2245   for (auto &entry : m_parent_types) {
2246     TypeIndex key = entry.first;
2247     TypeIndex value = entry.second;
2248 
2249     auto iter = forward_to_full.find(value);
2250     if (iter != forward_to_full.end())
2251       entry.second = iter->second;
2252 
2253     iter = forward_to_full.find(key);
2254     if (iter != forward_to_full.end())
2255       fwd_keys.push_back(key);
2256     else
2257       full_keys.push_back(key);
2258   }
2259   for (TypeIndex fwd : fwd_keys) {
2260     TypeIndex full = forward_to_full[fwd];
2261     m_parent_types[full] = m_parent_types[fwd];
2262   }
2263   for (TypeIndex full : full_keys) {
2264     TypeIndex fwd = full_to_forward[full];
2265     m_parent_types[fwd] = m_parent_types[full];
2266   }
2267 }
2268 
2269 std::optional<PdbCompilandSymId>
2270 SymbolFileNativePDB::FindSymbolScope(PdbCompilandSymId id) {
2271   CVSymbol sym = m_index->ReadSymbolRecord(id);
2272   if (symbolOpensScope(sym.kind())) {
2273     // If this exact symbol opens a scope, we can just directly access its
2274     // parent.
2275     id.offset = getScopeParentOffset(sym);
2276     // Global symbols have parent offset of 0.  Return std::nullopt to indicate
2277     // this.
2278     if (id.offset == 0)
2279       return std::nullopt;
2280     return id;
2281   }
2282 
2283   // Otherwise we need to start at the beginning and iterate forward until we
2284   // reach (or pass) this particular symbol
2285   CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(id.modi);
2286   const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
2287 
2288   auto begin = syms.begin();
2289   auto end = syms.at(id.offset);
2290   std::vector<PdbCompilandSymId> scope_stack;
2291 
2292   while (begin != end) {
2293     if (begin.offset() > id.offset) {
2294       // We passed it.  We couldn't even find this symbol record.
2295       lldbassert(false && "Invalid compiland symbol id!");
2296       return std::nullopt;
2297     }
2298 
2299     // We haven't found the symbol yet.  Check if we need to open or close the
2300     // scope stack.
2301     if (symbolOpensScope(begin->kind())) {
2302       // We can use the end offset of the scope to determine whether or not
2303       // we can just outright skip this entire scope.
2304       uint32_t scope_end = getScopeEndOffset(*begin);
2305       if (scope_end < id.offset) {
2306         begin = syms.at(scope_end);
2307       } else {
2308         // The symbol we're looking for is somewhere in this scope.
2309         scope_stack.emplace_back(id.modi, begin.offset());
2310       }
2311     } else if (symbolEndsScope(begin->kind())) {
2312       scope_stack.pop_back();
2313     }
2314     ++begin;
2315   }
2316   if (scope_stack.empty())
2317     return std::nullopt;
2318   // We have a match!  Return the top of the stack
2319   return scope_stack.back();
2320 }
2321 
2322 std::optional<llvm::codeview::TypeIndex>
2323 SymbolFileNativePDB::GetParentType(llvm::codeview::TypeIndex ti) {
2324   auto parent_iter = m_parent_types.find(ti);
2325   if (parent_iter == m_parent_types.end())
2326     return std::nullopt;
2327   return parent_iter->second;
2328 }
2329