LLDB mainline
SymbolFileNativePDB.cpp
Go to the documentation of this file.
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
10
16#include "lldb/Core/Module.h"
26#include "lldb/Utility/Log.h"
27
28#include "llvm/DebugInfo/CodeView/CVRecord.h"
29#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
30#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
31#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
32#include "llvm/DebugInfo/CodeView/RecordName.h"
33#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
34#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
35#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
36#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
37#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
38#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
39#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
40#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
41#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
42#include "llvm/DebugInfo/PDB/Native/PublicsStream.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
56#include "PdbSymUid.h"
57#include "PdbUtil.h"
58#include "UdtRecordCompleter.h"
59#include <optional>
60#include <string_view>
61
62using namespace lldb;
63using namespace lldb_private;
64using namespace npdb;
65using namespace llvm::codeview;
66using namespace llvm::pdb;
67
69
71 switch (lang) {
72 case PDB_Lang::Cpp:
74 case PDB_Lang::C:
76 case PDB_Lang::Swift:
78 case PDB_Lang::Rust:
80 case PDB_Lang::ObjC:
82 case PDB_Lang::ObjCpp:
84 default:
86 }
87}
88
89static std::optional<std::string>
90findMatchingPDBFilePath(llvm::StringRef original_pdb_path,
91 llvm::StringRef exe_path) {
92 const FileSystem &fs = FileSystem::Instance();
93
94 if (fs.Exists(original_pdb_path))
95 return std::string(original_pdb_path);
96
97 const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent();
98 // While the exe_path uses the native style, the exe might be compiled on a
99 // different OS, so try to guess the style used.
100 const FileSpec original_pdb_spec(original_pdb_path,
101 FileSpec::GuessPathStyle(original_pdb_path)
102 .value_or(FileSpec::Style::native));
103 const llvm::StringRef pdb_filename = original_pdb_spec.GetFilename();
104
105 // If the file doesn't exist, perhaps the path specified at build time
106 // doesn't match the PDB's current location, so check the location of the
107 // executable.
108 const FileSpec local_pdb = exe_dir.CopyByAppendingPathComponent(pdb_filename);
109 if (fs.Exists(local_pdb))
110 return local_pdb.GetPath();
111
112 // Otherwise, search for one in target.debug-file-search-paths
114 for (const FileSpec &search_dir : search_paths) {
115 FileSpec pdb_path = search_dir.CopyByAppendingPathComponent(pdb_filename);
116 if (fs.Exists(pdb_path))
117 return pdb_path.GetPath();
118 }
119
120 return std::nullopt;
121}
122
123static std::unique_ptr<PDBFile>
124loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
125 // Try to find a matching PDB for an EXE.
126 using namespace llvm::object;
127 auto expected_binary = createBinary(exe_path);
128
129 // If the file isn't a PE/COFF executable, fail.
130 if (!expected_binary) {
131 llvm::consumeError(expected_binary.takeError());
132 return nullptr;
133 }
134 OwningBinary<Binary> binary = std::move(*expected_binary);
135
136 // TODO: Avoid opening the PE/COFF binary twice by reading this information
137 // directly from the lldb_private::ObjectFile.
138 auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
139 if (!obj)
140 return nullptr;
141 const llvm::codeview::DebugInfo *pdb_info = nullptr;
142
143 // If it doesn't have a debug directory, fail.
144 llvm::StringRef pdb_file;
145 if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) {
146 consumeError(std::move(e));
147 return nullptr;
148 }
149
150 std::optional<std::string> resolved_pdb_path =
151 findMatchingPDBFilePath(pdb_file, exe_path);
152 if (!resolved_pdb_path)
153 return nullptr;
154
155 // If the file is not a PDB or if it doesn't have a matching GUID, fail.
156 auto pdb =
157 ObjectFilePDB::loadPDBFile(*std::move(resolved_pdb_path), allocator);
158 if (!pdb)
159 return nullptr;
160
161 auto expected_info = pdb->getPDBInfoStream();
162 if (!expected_info) {
163 llvm::consumeError(expected_info.takeError());
164 return nullptr;
165 }
166 llvm::codeview::GUID guid;
167 memcpy(&guid, pdb_info->PDB70.Signature, 16);
168
169 if (expected_info->getGuid() != guid)
170 return nullptr;
171
172 LLDB_LOG(GetLog(LLDBLog::Symbols), "Loading {0} for {1}", pdb->getFilePath(),
173 exe_path);
174 return pdb;
175}
176
178 lldb::addr_t addr) {
179 // FIXME: Implement this.
180 return false;
181}
182
184 lldb::addr_t addr) {
185 // FIXME: Implement this.
186 return false;
187}
188
189// See llvm::codeview::TypeIndex::simpleTypeName as well as strForPrimitiveTi
190// from the original pdbdump:
191// https://github.com/microsoft/microsoft-pdb/blob/805655a28bd8198004be2ac27e6e0290121a5e89/pdbdump/pdbdump.cpp#L1896-L1974
192//
193// For 64bit integers we use "long long" like DIA instead of "__int64".
194static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
195 switch (kind) {
196 case SimpleTypeKind::Boolean128:
197 return "__bool128";
198 case SimpleTypeKind::Boolean64:
199 return "__bool64";
200 case SimpleTypeKind::Boolean32:
201 return "__bool32";
202 case SimpleTypeKind::Boolean16:
203 return "__bool16";
204 case SimpleTypeKind::Boolean8:
205 return "bool";
206
207 case SimpleTypeKind::Byte:
208 case SimpleTypeKind::UnsignedCharacter:
209 return "unsigned char";
210 case SimpleTypeKind::NarrowCharacter:
211 return "char";
212 case SimpleTypeKind::SignedCharacter:
213 case SimpleTypeKind::SByte:
214 return "signed char";
215 case SimpleTypeKind::Character32:
216 return "char32_t";
217 case SimpleTypeKind::Character16:
218 return "char16_t";
219 case SimpleTypeKind::Character8:
220 return "char8_t";
221
222 case SimpleTypeKind::Complex128:
223 return "_Complex __float128";
224 case SimpleTypeKind::Complex80:
225 return "_Complex long double";
226 case SimpleTypeKind::Complex64:
227 return "_Complex double";
228 case SimpleTypeKind::Complex48:
229 return "_Complex __float48";
230 case SimpleTypeKind::Complex32:
231 case SimpleTypeKind::Complex32PartialPrecision:
232 return "_Complex float";
233 case SimpleTypeKind::Complex16:
234 return "_Complex _Float16";
235
236 case SimpleTypeKind::Float128:
237 return "__float128";
238 case SimpleTypeKind::Float80:
239 return "long double";
240 case SimpleTypeKind::Float64:
241 return "double";
242 case SimpleTypeKind::Float48:
243 return "__float48";
244 case SimpleTypeKind::Float32:
245 case SimpleTypeKind::Float32PartialPrecision:
246 return "float";
247 case SimpleTypeKind::Float16:
248 return "_Float16";
249
250 case SimpleTypeKind::Int128Oct:
251 case SimpleTypeKind::Int128:
252 return "__int128";
253 case SimpleTypeKind::Int64:
254 case SimpleTypeKind::Int64Quad:
255 return "long long";
256 case SimpleTypeKind::Int32Long:
257 return "long";
258 case SimpleTypeKind::Int32:
259 return "int";
260 case SimpleTypeKind::Int16:
261 case SimpleTypeKind::Int16Short:
262 return "short";
263
264 case SimpleTypeKind::UInt128Oct:
265 case SimpleTypeKind::UInt128:
266 return "unsigned __int128";
267 case SimpleTypeKind::UInt64:
268 case SimpleTypeKind::UInt64Quad:
269 return "unsigned long long";
270 case SimpleTypeKind::UInt32:
271 return "unsigned";
272 case SimpleTypeKind::UInt16:
273 case SimpleTypeKind::UInt16Short:
274 return "unsigned short";
275 case SimpleTypeKind::UInt32Long:
276 return "unsigned long";
277
278 case SimpleTypeKind::HResult:
279 return "HRESULT";
280 case SimpleTypeKind::Void:
281 return "void";
282 case SimpleTypeKind::WideCharacter:
283 return "wchar_t";
284
285 case SimpleTypeKind::None:
286 case SimpleTypeKind::NotTranslated:
287 return "";
288 }
289 return "";
290}
291
292static bool IsClassRecord(TypeLeafKind kind) {
293 switch (kind) {
294 case LF_STRUCTURE:
295 case LF_CLASS:
296 case LF_INTERFACE:
297 return true;
298 default:
299 return false;
300 }
301}
302
303static std::optional<CVTagRecord>
304GetNestedTagDefinition(const NestedTypeRecord &Record,
305 const CVTagRecord &parent, TpiStream &tpi) {
306 // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it
307 // is also used to indicate the primary definition of a nested class. That is
308 // to say, if you have:
309 // struct A {
310 // struct B {};
311 // using C = B;
312 // };
313 // Then in the debug info, this will appear as:
314 // LF_STRUCTURE `A::B` [type index = N]
315 // LF_STRUCTURE `A`
316 // LF_NESTTYPE [name = `B`, index = N]
317 // LF_NESTTYPE [name = `C`, index = N]
318 // In order to accurately reconstruct the decl context hierarchy, we need to
319 // know which ones are actual definitions and which ones are just aliases.
320
321 // If it's a simple type, then this is something like `using foo = int`.
322 if (Record.Type.isSimple())
323 return std::nullopt;
324
325 CVType cvt = tpi.getType(Record.Type);
326
327 if (!IsTagRecord(cvt))
328 return std::nullopt;
329
330 // If it's an inner definition, then treat whatever name we have here as a
331 // single component of a mangled name. So we can inject it into the parent's
332 // mangled name to see if it matches.
333 CVTagRecord child = CVTagRecord::create(cvt);
334 std::string qname = std::string(parent.asTag().getUniqueName());
335 if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
336 return std::nullopt;
337
338 // qname[3] is the tag type identifier (struct, class, union, etc). Since the
339 // inner tag type is not necessarily the same as the outer tag type, re-write
340 // it to match the inner tag type.
341 qname[3] = child.asTag().getUniqueName()[3];
342 std::string piece;
343 if (qname[3] == 'W')
344 piece = "4";
345 piece += Record.Name;
346 piece.push_back('@');
347 qname.insert(4, std::move(piece));
348 if (qname != child.asTag().UniqueName)
349 return std::nullopt;
350
351 return std::move(child);
352}
353
359
363
365
367 return "Microsoft PDB debug symbol cross-platform file reader.";
368}
369
372 return nullptr;
373
374 return new SymbolFileNativePDB(std::move(objfile_sp));
375}
376
379
381
383 uint32_t abilities = 0;
384 if (!m_objfile_sp)
385 return 0;
386
387 if (!m_index) {
388 // Lazily load and match the PDB file, but only do this once.
389 PDBFile *pdb_file;
390 if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) {
391 pdb_file = &pdb->GetPDBFile();
392 } else {
393 m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(),
395 pdb_file = m_file_up.get();
396 }
397
398 if (!pdb_file)
399 return 0;
400
401 auto expected_index = PdbIndex::create(pdb_file);
402 if (!expected_index) {
403 llvm::consumeError(expected_index.takeError());
404 return 0;
405 }
406 m_index = std::move(*expected_index);
407 }
408 if (!m_index)
409 return 0;
410
411 // We don't especially have to be precise here. We only distinguish between
412 // stripped and not stripped.
413 abilities = kAllAbilities;
414
415 if (m_index->dbi().isStripped())
416 abilities &= ~(Blocks | LocalVariables);
417 return abilities;
418}
419
421 m_obj_load_address = m_objfile_sp->GetModule()
422 ->GetObjectFile()
423 ->GetBaseAddress()
424 .GetFileAddress();
425 m_index->SetLoadAddress(m_obj_load_address);
426 m_index->ParseSectionContribs();
427
428 auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
430 if (auto err = ts_or_err.takeError()) {
431 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
432 "Failed to initialize: {0}");
433 } else {
434 if (auto ts = *ts_or_err)
435 ts->SetSymbolFile(this);
437 }
438}
439
441 const DbiModuleList &modules = m_index->dbi().modules();
442 uint32_t count = modules.getModuleCount();
443 if (count == 0)
444 return count;
445
446 // The linker can inject an additional "dummy" compilation unit into the
447 // PDB. Ignore this special compile unit for our purposes, if it is there.
448 // It is always the last one.
449 DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
450 if (last.getModuleName() == "* Linker *")
451 --count;
452 return count;
453}
454
456 CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
457 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
458 CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
459 lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
460 auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
461 if (auto err = ts_or_err.takeError())
462 return nullptr;
463 auto ts = *ts_or_err;
464 if (!ts)
465 return nullptr;
466 PdbAstBuilder* ast_builder = ts->GetNativePDBParser();
467
468 switch (sym.kind()) {
469 case S_GPROC32:
470 case S_LPROC32:
471 // This is a function. It must be global. Creating the Function entry
472 // for it automatically creates a block for it.
473 if (FunctionSP func = GetOrCreateFunction(block_id, *comp_unit))
474 return &func->GetBlock(false);
475 break;
476 case S_BLOCK32: {
477 // This is a block. Its parent is either a function or another block. In
478 // either case, its parent can be viewed as a block (e.g. a function
479 // contains 1 big block. So just get the parent block and add this block
480 // to it.
481 BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
482 cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
483 lldbassert(block.Parent != 0);
484 PdbCompilandSymId parent_id(block_id.modi, block.Parent);
485 Block *parent_block = GetOrCreateBlock(parent_id);
486 if (!parent_block)
487 return nullptr;
488 Function *func = parent_block->CalculateSymbolContextFunction();
489 lldbassert(func);
490 lldb::addr_t block_base =
491 m_index->MakeVirtualAddress(block.Segment, block.CodeOffset);
492 lldb::addr_t func_base = func->GetAddress().GetFileAddress();
493 BlockSP child_block = parent_block->CreateChild(opaque_block_uid);
494 if (block_base >= func_base)
495 child_block->AddRange(Block::Range(block_base - func_base, block.CodeSize));
496 else {
497 GetObjectFile()->GetModule()->ReportError(
498 "S_BLOCK32 at modi: {0:d} offset: {1:d}: adding range "
499 "[{2:x16}-{3:x16}) which has a base that is less than the "
500 "function's "
501 "low PC 0x%" PRIx64 ". Please file a bug and attach the file at the "
502 "start of this error message",
503 block_id.modi, block_id.offset, block_base,
504 block_base + block.CodeSize, func_base);
505 }
506 if (ast_builder)
507 ast_builder->EnsureBlock(block_id);
508 m_blocks.insert({opaque_block_uid, child_block});
509 break;
510 }
511 case S_INLINESITE: {
512 // This ensures line table is parsed first so we have inline sites info.
513 comp_unit->GetLineTable();
514
515 std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid];
516 Block *parent_block = GetOrCreateBlock(inline_site->parent_id);
517 if (!parent_block)
518 return nullptr;
519 BlockSP child_block = parent_block->CreateChild(opaque_block_uid);
520 if (ast_builder)
521 ast_builder->EnsureInlinedFunction(block_id);
522 // Copy ranges from InlineSite to Block.
523 for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
524 auto *entry = inline_site->ranges.GetEntryAtIndex(i);
525 child_block->AddRange(
526 Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
527 }
528 child_block->FinalizeRanges();
529
530 // Get the inlined function callsite info.
531 Declaration &decl = inline_site->inline_function_info->GetDeclaration();
532 Declaration &callsite = inline_site->inline_function_info->GetCallSite();
533 child_block->SetInlinedFunctionInfo(
534 inline_site->inline_function_info->GetName().GetCString(), nullptr,
535 &decl, &callsite);
536 m_blocks.insert({opaque_block_uid, child_block});
537 break;
538 }
539 default:
540 lldbassert(false && "Symbol is not a block!");
541 }
542
543 return nullptr;
544}
545
547 CompileUnit &comp_unit) {
548 const CompilandIndexItem *cci =
549 m_index->compilands().GetCompiland(func_id.modi);
550 lldbassert(cci);
551 CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
552
553 lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);
555
556 auto file_vm_addr =
557 m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
558 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
559 return nullptr;
560
561 Address func_addr(file_vm_addr, comp_unit.GetModule()->GetSectionList());
562 if (!func_addr.IsValid())
563 return nullptr;
564
565 ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
566 cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
567 if (proc.FunctionType == TypeIndex::None())
568 return nullptr;
569 TypeSP func_type = GetOrCreateType(proc.FunctionType);
570 if (!func_type)
571 return nullptr;
572
573 PdbTypeSymId sig_id(proc.FunctionType, false);
574
575 std::optional<llvm::StringRef> mangled_opt = FindMangledSymbol(
576 SegmentOffset(proc.Segment, proc.CodeOffset), proc.FunctionType);
577 Mangled mangled(mangled_opt.value_or(proc.Name));
578
579 FunctionSP func_sp = std::make_shared<Function>(
580 &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
581 func_type.get(), func_addr,
582 AddressRanges{AddressRange(func_addr, sol.length)});
583
584 comp_unit.AddFunction(func_sp);
585
586 auto ts_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage());
587 if (auto err = ts_or_err.takeError())
588 return func_sp;
589 auto ts = *ts_or_err;
590 if (ts) {
591 if (PdbAstBuilder *ast_builder = ts->GetNativePDBParser())
592 ast_builder->EnsureFunction(func_id);
593 }
594
595 return func_sp;
596}
597
600 lldb::LanguageType lang =
601 cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())
603
604 LazyBool optimized = eLazyBoolNo;
605 if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())
606 optimized = eLazyBoolYes;
607
608 llvm::SmallString<64> source_file_name =
609 m_index->compilands().GetMainSourceFile(cci);
610 FileSpec fs(llvm::sys::path::convert_to_slash(
611 source_file_name, llvm::sys::path::Style::windows_backslash));
612
613 CompUnitSP cu_sp = std::make_shared<CompileUnit>(
614 m_objfile_sp->GetModule(), nullptr, std::make_shared<SupportFile>(fs),
615 toOpaqueUid(cci.m_id), lang, optimized);
616
617 SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
618 return cu_sp;
619}
620
622 const ModifierRecord &mr,
623 CompilerType ct) {
624 TpiStream &stream = m_index->tpi();
625
626 std::string name;
627
628 if ((mr.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
629 name += "const ";
630 if ((mr.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)
631 name += "volatile ";
632 if ((mr.Modifiers & ModifierOptions::Unaligned) != ModifierOptions::None)
633 name += "__unaligned ";
634
635 if (mr.ModifiedType.isSimple())
636 name += GetSimpleTypeName(mr.ModifiedType.getSimpleKind());
637 else
638 name += computeTypeName(stream.typeCollection(), mr.ModifiedType);
639 Declaration decl;
640 lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);
641
642 return MakeType(toOpaqueUid(type_id), ConstString(name),
643 llvm::expectedToOptional(modified_type->GetByteSize(nullptr)),
644 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
646}
647
650 const llvm::codeview::PointerRecord &pr,
651 CompilerType ct) {
652 TypeSP pointee = GetOrCreateType(pr.ReferentType);
653 if (!pointee)
654 return nullptr;
655
656 if (pr.isPointerToMember()) {
657 MemberPointerInfo mpi = pr.getMemberInfo();
658 GetOrCreateType(mpi.ContainingType);
659 }
660
661 Declaration decl;
662 return MakeType(toOpaqueUid(type_id), ConstString(), pr.getSize(), nullptr,
665}
666
668 CompilerType ct) {
669 uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));
670 if (ti == TypeIndex::NullptrT()) {
671 Declaration decl;
672 return MakeType(uid, ConstString("decltype(nullptr)"), std::nullopt,
673 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,
675 }
676
677 if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
678 TypeSP direct_sp = GetOrCreateType(ti.makeDirect());
679 uint32_t pointer_size = 0;
680 switch (ti.getSimpleMode()) {
681 case SimpleTypeMode::FarPointer32:
682 case SimpleTypeMode::NearPointer32:
683 pointer_size = 4;
684 break;
685 case SimpleTypeMode::NearPointer64:
686 pointer_size = 8;
687 break;
688 default:
689 // 128-bit and 16-bit pointers unsupported.
690 return nullptr;
691 }
692 Declaration decl;
693 return MakeType(uid, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID,
695 }
696
697 if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
698 return nullptr;
699
700 size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind());
701 llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());
702
703 Declaration decl;
704 return MakeType(uid, ConstString(type_name), size, nullptr, LLDB_INVALID_UID,
706}
707
708static std::string GetUnqualifiedTypeName(const TagRecord &record) {
709 if (!record.hasUniqueName())
710 return std::string(MSVCUndecoratedNameParser::DropScope(record.Name));
711
712 llvm::ms_demangle::Demangler demangler;
713 std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());
714 llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
715 if (demangler.Error)
716 return std::string(MSVCUndecoratedNameParser::DropScope(record.Name));
717
718 llvm::ms_demangle::IdentifierNode *idn =
719 ttn->QualifiedName->getUnqualifiedIdentifier();
720 return idn->toString();
721}
722
725 const TagRecord &record,
726 size_t size, CompilerType ct) {
727
728 std::string uname = GetUnqualifiedTypeName(record);
729
730 llvm::Expected<Declaration> maybeDecl = ResolveUdtDeclaration(type_id);
731 Declaration decl;
732 if (maybeDecl)
733 decl = std::move(*maybeDecl);
734 else
735 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), maybeDecl.takeError(),
736 "Failed to resolve declaration for '{1}': {0}", uname);
737
738 return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr,
741}
742
744 const ClassRecord &cr,
745 CompilerType ct) {
746 return CreateClassStructUnion(type_id, cr, cr.getSize(), ct);
747}
748
750 const UnionRecord &ur,
751 CompilerType ct) {
752 return CreateClassStructUnion(type_id, ur, ur.getSize(), ct);
753}
754
756 const EnumRecord &er,
757 CompilerType ct) {
758 std::string uname = GetUnqualifiedTypeName(er);
759
760 llvm::Expected<Declaration> maybeDecl = ResolveUdtDeclaration(type_id);
761 Declaration decl;
762 if (maybeDecl)
763 decl = std::move(*maybeDecl);
764 else
765 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), maybeDecl.takeError(),
766 "Failed to resolve declaration for '{1}': {0}", uname);
767
768 TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
769
770 return MakeType(
771 toOpaqueUid(type_id), ConstString(uname),
772 llvm::expectedToOptional(underlying_type->GetByteSize(nullptr)), nullptr,
775}
776
778 const ArrayRecord &ar,
779 CompilerType ct) {
780 TypeSP element_type = GetOrCreateType(ar.ElementType);
781
782 Declaration decl;
783 TypeSP array_sp =
784 MakeType(toOpaqueUid(type_id), ConstString(), ar.Size, nullptr,
787 array_sp->SetEncodingType(element_type.get());
788 return array_sp;
789}
790
792 const MemberFunctionRecord &mfr,
793 CompilerType ct) {
794 if (mfr.ReturnType.isSimple())
795 GetOrCreateType(mfr.ReturnType);
796 CreateSimpleArgumentListTypes(mfr.ArgumentList);
797
798 Declaration decl;
799 return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
802}
803
805 const ProcedureRecord &pr,
806 CompilerType ct) {
807 if (pr.ReturnType.isSimple())
808 GetOrCreateType(pr.ReturnType);
809 CreateSimpleArgumentListTypes(pr.ArgumentList);
810
811 Declaration decl;
812 return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,
815}
816
818 llvm::codeview::TypeIndex arglist_ti) {
819 if (arglist_ti.isNoneType())
820 return;
821
822 CVType arglist_cvt = m_index->tpi().getType(arglist_ti);
823 if (arglist_cvt.kind() != LF_ARGLIST)
824 return; // invalid debug info
825
826 ArgListRecord alr;
827 llvm::cantFail(
828 TypeDeserializer::deserializeAs<ArgListRecord>(arglist_cvt, alr));
829 for (TypeIndex id : alr.getIndices())
830 if (!id.isNoneType() && id.isSimple())
831 GetOrCreateType(id);
832}
833
835 if (type_id.index.isSimple())
836 return CreateSimpleType(type_id.index, ct);
837
838 TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi();
839 CVType cvt = stream.getType(type_id.index);
840
841 if (cvt.kind() == LF_MODIFIER) {
842 ModifierRecord modifier;
843 llvm::cantFail(
844 TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
845 return CreateModifierType(type_id, modifier, ct);
846 }
847
848 if (cvt.kind() == LF_POINTER) {
849 PointerRecord pointer;
850 llvm::cantFail(
851 TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
852 return CreatePointerType(type_id, pointer, ct);
853 }
854
855 if (IsClassRecord(cvt.kind())) {
856 ClassRecord cr;
857 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
858 return CreateTagType(type_id, cr, ct);
859 }
860
861 if (cvt.kind() == LF_ENUM) {
862 EnumRecord er;
863 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
864 return CreateTagType(type_id, er, ct);
865 }
866
867 if (cvt.kind() == LF_UNION) {
868 UnionRecord ur;
869 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
870 return CreateTagType(type_id, ur, ct);
871 }
872
873 if (cvt.kind() == LF_ARRAY) {
874 ArrayRecord ar;
875 llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
876 return CreateArrayType(type_id, ar, ct);
877 }
878
879 if (cvt.kind() == LF_PROCEDURE) {
880 ProcedureRecord pr;
881 llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
882 return CreateProcedureType(type_id, pr, ct);
883 }
884 if (cvt.kind() == LF_MFUNCTION) {
885 MemberFunctionRecord mfr;
886 llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
887 return CreateFunctionType(type_id, mfr, ct);
888 }
889
890 return nullptr;
891}
892
894 // If they search for a UDT which is a forward ref, try and resolve the full
895 // decl and just map the forward ref uid to the full decl record.
896 std::optional<PdbTypeSymId> full_decl_uid;
897 if (IsForwardRefUdt(type_id, m_index->tpi())) {
898 auto expected_full_ti =
899 m_index->tpi().findFullDeclForForwardRef(type_id.index);
900 if (!expected_full_ti)
901 llvm::consumeError(expected_full_ti.takeError());
902 else if (*expected_full_ti != type_id.index) {
903 full_decl_uid = PdbTypeSymId(*expected_full_ti, false);
904
905 // It's possible that a lookup would occur for the full decl causing it
906 // to be cached, then a second lookup would occur for the forward decl.
907 // We don't want to create a second full decl, so make sure the full
908 // decl hasn't already been cached.
909 auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid));
910 if (full_iter != m_types.end()) {
911 TypeSP result = full_iter->second;
912 // Map the forward decl to the TypeSP for the full decl so we can take
913 // the fast path next time.
914 m_types[toOpaqueUid(type_id)] = result;
915 return result;
916 }
917 }
918 }
919
920 PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
922 if (auto err = ts_or_err.takeError())
923 return nullptr;
924 auto ts = *ts_or_err;
925 if (!ts)
926 return nullptr;
927 PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
928 if (!ast_builder)
929 return nullptr;
930 CompilerType ct = ast_builder->GetOrCreateType(best_decl_id);
931 if (!ct)
932 return nullptr;
933
934 TypeSP result = CreateType(best_decl_id, ct);
935 if (!result)
936 return nullptr;
937
938 uint64_t best_uid = toOpaqueUid(best_decl_id);
939 m_types[best_uid] = result;
940 // If we had both a forward decl and a full decl, make both point to the new
941 // type.
942 if (full_decl_uid)
943 m_types[toOpaqueUid(type_id)] = result;
944
945 return result;
946}
947
949 // We can't use try_emplace / overwrite here because the process of creating
950 // a type could create nested types, which could invalidate iterators. So
951 // we have to do a 2-phase lookup / insert.
952 auto iter = m_types.find(toOpaqueUid(type_id));
953 if (iter != m_types.end())
954 return iter->second;
955
956 TypeSP type = CreateAndCacheType(type_id);
957 if (type)
958 GetTypeList().Insert(type);
959 return type;
960}
961
963 CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
964 if (sym.kind() == S_CONSTANT)
965 return CreateConstantSymbol(var_id, sym);
966
968 TypeIndex ti;
969 llvm::StringRef name;
970 lldb::addr_t addr = 0;
971 uint16_t section = 0;
972 uint32_t offset = 0;
973 bool is_external = false;
974 switch (sym.kind()) {
975 case S_GDATA32:
976 is_external = true;
977 [[fallthrough]];
978 case S_LDATA32: {
979 DataSym ds(sym.kind());
980 llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds));
981 ti = ds.Type;
982 scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal
984 name = ds.Name;
985 section = ds.Segment;
986 offset = ds.DataOffset;
987 addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
988 break;
989 }
990 case S_GTHREAD32:
991 is_external = true;
992 [[fallthrough]];
993 case S_LTHREAD32: {
994 ThreadLocalDataSym tlds(sym.kind());
995 llvm::cantFail(
996 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds));
997 ti = tlds.Type;
998 name = tlds.Name;
999 section = tlds.Segment;
1000 offset = tlds.DataOffset;
1001 addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
1003 break;
1004 }
1005 default:
1006 llvm_unreachable("unreachable!");
1007 }
1008
1009 CompUnitSP comp_unit;
1010 std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);
1011 // Some globals has modi points to the linker module, ignore them.
1012 if (!modi || modi >= GetNumCompileUnits())
1013 return nullptr;
1014
1015 CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);
1016 comp_unit = GetOrCreateCompileUnit(cci);
1017
1018 Declaration decl;
1019 PdbTypeSymId tid(ti, false);
1020 SymbolFileTypeSP type_sp =
1021 std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
1022 Variable::RangeList ranges;
1023 auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
1024 if (auto err = ts_or_err.takeError())
1025 return nullptr;
1026 auto ts = *ts_or_err;
1027 if (ts) {
1028 if (PdbAstBuilder *ast_builder = ts->GetNativePDBParser())
1029 ast_builder->EnsureVariable(var_id);
1030 }
1031
1032 ModuleSP module_sp = GetObjectFile()->GetModule();
1033 DWARFExpressionList location(
1034 module_sp, MakeGlobalLocationExpression(section, offset, module_sp),
1035 nullptr);
1036
1037 std::string global_name("::");
1038 global_name += name;
1039 bool artificial = false;
1040 bool location_is_constant_data = false;
1041 bool static_member = false;
1042 VariableSP var_sp = std::make_shared<Variable>(
1043 toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
1044 scope, comp_unit.get(), ranges, &decl, location, is_external, artificial,
1045 location_is_constant_data, static_member);
1046
1047 return var_sp;
1048}
1049
1052 const CVSymbol &cvs) {
1053 TpiStream &tpi = m_index->tpi();
1054 ConstantSym constant(cvs.kind());
1055
1056 llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant));
1057 std::string global_name("::");
1058 global_name += constant.Name;
1059 PdbTypeSymId tid(constant.Type, false);
1060 SymbolFileTypeSP type_sp =
1061 std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
1062
1063 Declaration decl;
1064 Variable::RangeList ranges;
1065 ModuleSP module = GetObjectFile()->GetModule();
1066 DWARFExpressionList location(module,
1068 constant.Type, tpi, constant.Value, module),
1069 nullptr);
1070
1071 bool external = false;
1072 bool artificial = false;
1073 bool location_is_constant_data = true;
1074 bool static_member = false;
1075 VariableSP var_sp = std::make_shared<Variable>(
1076 toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
1077 type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
1078 external, artificial, location_is_constant_data, static_member);
1079 return var_sp;
1080}
1081
1084 auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr);
1085 if (emplace_result.second) {
1086 if (VariableSP var_sp = CreateGlobalVariable(var_id))
1087 emplace_result.first->second = var_sp;
1088 else
1089 return nullptr;
1090 }
1091
1092 return emplace_result.first->second;
1093}
1094
1096 return GetOrCreateType(PdbTypeSymId(ti, false));
1097}
1098
1100 CompileUnit &comp_unit) {
1101 auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);
1102 if (emplace_result.second)
1103 emplace_result.first->second = CreateFunction(func_id, comp_unit);
1104
1105 return emplace_result.first->second;
1106}
1107
1110
1111 auto emplace_result =
1112 m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr);
1113 if (emplace_result.second)
1114 emplace_result.first->second = CreateCompileUnit(cci);
1115
1116 lldbassert(emplace_result.first->second);
1117 return emplace_result.first->second;
1118}
1119
1121 auto iter = m_blocks.find(toOpaqueUid(block_id));
1122 if (iter != m_blocks.end())
1123 return iter->second.get();
1124
1125 return CreateBlock(block_id);
1126}
1127
1130 TypeSystem *ts = decl_ctx.GetTypeSystem();
1131 if (!ts)
1132 return;
1133 PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
1134 if (!ast_builder)
1135 return;
1136 ast_builder->ParseDeclsForContext(decl_ctx);
1137}
1138
1140 if (index >= GetNumCompileUnits())
1141 return CompUnitSP();
1142 lldbassert(index < UINT16_MAX);
1143 if (index >= UINT16_MAX)
1144 return nullptr;
1145
1146 CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);
1147
1148 return GetOrCreateCompileUnit(item);
1149}
1150
1152 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1153 PdbSymUid uid(comp_unit.GetID());
1155
1156 CompilandIndexItem *item =
1157 m_index->compilands().GetCompiland(uid.asCompiland().modi);
1158 lldbassert(item);
1159 if (!item->m_compile_opts)
1161
1162 return TranslateLanguage(item->m_compile_opts->getLanguage());
1163}
1164
1166 auto *section_list =
1167 m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList();
1168 if (!section_list)
1169 return;
1170
1171 PublicSym32 last_sym;
1172 size_t last_sym_idx = 0;
1173 lldb::SectionSP section_sp;
1174
1175 // To estimate the size of a symbol, we use the difference to the next symbol.
1176 // If there's no next symbol or the section/segment changed, the symbol will
1177 // take the remaining space. The estimate can be too high in case there's
1178 // padding between symbols. This similar to the algorithm used by the DIA
1179 // SDK.
1180 auto finish_last_symbol = [&](const PublicSym32 *next) {
1181 if (!section_sp)
1182 return;
1183 Symbol *last = symtab.SymbolAtIndex(last_sym_idx);
1184 if (!last)
1185 return;
1186
1187 if (next && last_sym.Segment == next->Segment) {
1188 assert(last_sym.Offset <= next->Offset);
1189 last->SetByteSize(next->Offset - last_sym.Offset);
1190 } else {
1191 // the last symbol was the last in its section
1192 assert(section_sp->GetByteSize() >= last_sym.Offset);
1193 assert(!next || next->Segment > last_sym.Segment);
1194 last->SetByteSize(section_sp->GetByteSize() - last_sym.Offset);
1195 }
1196 };
1197
1198 // The address map is sorted by the address of a symbol.
1199 for (auto pid : m_index->publics().getAddressMap()) {
1200 PdbGlobalSymId global{pid, true};
1201 CVSymbol sym = m_index->ReadSymbolRecord(global);
1202 auto kind = sym.kind();
1203 if (kind != S_PUB32)
1204 continue;
1205 PublicSym32 pub =
1206 llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym));
1207 finish_last_symbol(&pub);
1208
1209 if (!section_sp || last_sym.Segment != pub.Segment)
1210 section_sp = section_list->FindSectionByID(pub.Segment);
1211
1212 if (!section_sp)
1213 continue;
1214
1216 if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||
1217 (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
1218 type = eSymbolTypeCode;
1219
1220 last_sym_idx =
1221 symtab.AddSymbol(Symbol(/*symID=*/pid,
1222 /*name=*/pub.Name,
1223 /*type=*/type,
1224 /*external=*/true,
1225 /*is_debug=*/true,
1226 /*is_trampoline=*/false,
1227 /*is_artificial=*/false,
1228 /*section_sp=*/section_sp,
1229 /*value=*/pub.Offset,
1230 /*size=*/0,
1231 /*size_is_valid=*/false,
1232 /*contains_linker_annotations=*/false,
1233 /*flags=*/0));
1234 last_sym = pub;
1235 }
1236
1237 finish_last_symbol(nullptr);
1238}
1239
1241 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1242 PdbSymUid uid{comp_unit.GetID()};
1244 uint16_t modi = uid.asCompiland().modi;
1245 CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);
1246
1247 size_t count = comp_unit.GetNumFunctions();
1248 const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
1249 for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
1250 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
1251 continue;
1252
1253 PdbCompilandSymId sym_id{modi, iter.offset()};
1254
1255 FunctionSP func = GetOrCreateFunction(sym_id, comp_unit);
1256 }
1257
1258 size_t new_count = comp_unit.GetNumFunctions();
1259 lldbassert(new_count >= count);
1260 return new_count - count;
1261}
1262
1263static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
1264 // If any of these flags are set, we need to resolve the compile unit.
1265 uint32_t flags = eSymbolContextCompUnit;
1266 flags |= eSymbolContextVariable;
1267 flags |= eSymbolContextFunction;
1268 flags |= eSymbolContextBlock;
1269 flags |= eSymbolContextLineEntry;
1270 return (resolve_scope & flags) != 0;
1271}
1272
1274 const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
1275 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1276 uint32_t resolved_flags = 0;
1277 lldb::addr_t file_addr = addr.GetFileAddress();
1278
1279 if (NeedsResolvedCompileUnit(resolve_scope)) {
1280 std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);
1281 if (!modi)
1282 return 0;
1283 CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi);
1284 if (!cu_sp)
1285 return 0;
1286
1287 sc.comp_unit = cu_sp.get();
1288 resolved_flags |= eSymbolContextCompUnit;
1289 }
1290
1291 if (resolve_scope & eSymbolContextFunction ||
1292 resolve_scope & eSymbolContextBlock) {
1294 std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
1295 // Search the matches in reverse. This way if there are multiple matches
1296 // (for example we are 3 levels deep in a nested scope) it will find the
1297 // innermost one first.
1298 for (const auto &match : llvm::reverse(matches)) {
1299 if (match.uid.kind() != PdbSymUidKind::CompilandSym)
1300 continue;
1301
1302 PdbCompilandSymId csid = match.uid.asCompilandSym();
1303 CVSymbol cvs = m_index->ReadSymbolRecord(csid);
1304 PDB_SymType type = CVSymToPDBSym(cvs.kind());
1305 if (type != PDB_SymType::Function && type != PDB_SymType::Block)
1306 continue;
1307 if (type == PDB_SymType::Function) {
1308 sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
1309 if (sc.function) {
1310 Block &block = sc.function->GetBlock(true);
1311 addr_t func_base = sc.function->GetAddress().GetFileAddress();
1312 addr_t offset = file_addr - func_base;
1313 sc.block = block.FindInnermostBlockByOffset(offset);
1314 }
1315 }
1316
1317 if (type == PDB_SymType::Block) {
1318 Block *block = GetOrCreateBlock(csid);
1319 if (!block)
1320 continue;
1322 if (sc.function) {
1323 sc.function->GetBlock(true);
1324 addr_t func_base = sc.function->GetAddress().GetFileAddress();
1325 addr_t offset = file_addr - func_base;
1326 sc.block = block->FindInnermostBlockByOffset(offset);
1327 }
1328 }
1329 if (sc.function)
1330 resolved_flags |= eSymbolContextFunction;
1331 if (sc.block)
1332 resolved_flags |= eSymbolContextBlock;
1333 break;
1334 }
1335 }
1336
1337 if (resolve_scope & eSymbolContextLineEntry) {
1339 if (auto *line_table = sc.comp_unit->GetLineTable()) {
1340 if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
1341 resolved_flags |= eSymbolContextLineEntry;
1342 }
1343 }
1344
1345 return resolved_flags;
1346}
1347
1349 const SourceLocationSpec &src_location_spec,
1350 lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
1351 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1352 const uint32_t prev_size = sc_list.GetSize();
1353 if (resolve_scope & eSymbolContextCompUnit) {
1354 for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
1355 ++cu_idx) {
1356 CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get();
1357 if (!cu)
1358 continue;
1359
1360 bool file_spec_matches_cu_file_spec = FileSpec::Match(
1361 src_location_spec.GetFileSpec(), cu->GetPrimaryFile());
1362 if (file_spec_matches_cu_file_spec) {
1363 cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
1364 break;
1365 }
1366 }
1367 }
1368 return sc_list.GetSize() - prev_size;
1369}
1370
1372 // Unfortunately LLDB is set up to parse the entire compile unit line table
1373 // all at once, even if all it really needs is line info for a specific
1374 // function. In the future it would be nice if it could set the sc.m_function
1375 // member, and we could only get the line info for the function in question.
1376 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1377 PdbSymUid cu_id(comp_unit.GetID());
1379 uint16_t modi = cu_id.asCompiland().modi;
1380 CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi);
1381 lldbassert(cii);
1382
1383 // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records
1384 // in this CU. Add line entries into the set first so that if there are line
1385 // entries with same addres, the later is always more accurate than the
1386 // former.
1387 std::set<LineTable::Entry, LineTableEntryComparator> line_set;
1388
1389 // This is basically a copy of the .debug$S subsections from all original COFF
1390 // object files merged together with address relocations applied. We are
1391 // looking for all DEBUG_S_LINES subsections.
1392 for (const DebugSubsectionRecord &dssr :
1393 cii->m_debug_stream.getSubsectionsArray()) {
1394 if (dssr.kind() != DebugSubsectionKind::Lines)
1395 continue;
1396
1397 DebugLinesSubsectionRef lines;
1398 llvm::BinaryStreamReader reader(dssr.getRecordData());
1399 if (auto EC = lines.initialize(reader)) {
1400 llvm::consumeError(std::move(EC));
1401 return false;
1402 }
1403
1404 const LineFragmentHeader *lfh = lines.header();
1405 uint64_t virtual_addr =
1406 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1407 if (virtual_addr == LLDB_INVALID_ADDRESS)
1408 continue;
1409
1410 for (const LineColumnEntry &group : lines) {
1411 llvm::Expected<uint32_t> file_index_or_err =
1412 GetFileIndex(*cii, group.NameIndex);
1413 if (!file_index_or_err)
1414 continue;
1415 uint32_t file_index = file_index_or_err.get();
1416 lldbassert(!group.LineNumbers.empty());
1419 for (const LineNumberEntry &entry : group.LineNumbers) {
1420 LineInfo cur_info(entry.Flags);
1421
1422 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1423 continue;
1424
1425 uint64_t addr = virtual_addr + entry.Offset;
1426
1427 bool is_statement = cur_info.isStatement();
1428 bool is_prologue = IsFunctionPrologue(*cii, addr);
1429 bool is_epilogue = IsFunctionEpilogue(*cii, addr);
1430
1431 uint32_t lno = cur_info.getStartLine();
1432
1433 LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false,
1434 is_prologue, is_epilogue, false);
1435 // Terminal entry has lower precedence than new entry.
1436 auto iter = line_set.find(new_entry);
1437 if (iter != line_set.end() && iter->is_terminal_entry)
1438 line_set.erase(iter);
1439 line_set.insert(new_entry);
1440
1441 if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
1442 line_entry.SetRangeEnd(addr);
1443 cii->m_global_line_table.Append(line_entry);
1444 }
1445 line_entry.SetRangeBase(addr);
1446 line_entry.data = {file_index, lno};
1447 }
1448 LineInfo last_line(group.LineNumbers.back().Flags);
1449 line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
1450 file_index, false, false, false, false, true);
1451
1452 if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {
1453 line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize);
1454 cii->m_global_line_table.Append(line_entry);
1455 }
1456 }
1457 }
1458
1460
1461 // Parse all S_INLINESITE in this CU.
1462 const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray();
1463 for (auto iter = syms.begin(); iter != syms.end();) {
1464 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
1465 ++iter;
1466 continue;
1467 }
1468
1469 uint32_t record_offset = iter.offset();
1470 CVSymbol func_record =
1471 cii->m_debug_stream.readSymbolAtOffset(record_offset);
1473 addr_t file_vm_addr =
1474 m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);
1475 if (file_vm_addr == LLDB_INVALID_ADDRESS)
1476 continue;
1477
1478 Address func_base(file_vm_addr, comp_unit.GetModule()->GetSectionList());
1479 PdbCompilandSymId func_id{modi, record_offset};
1480
1481 // Iterate all S_INLINESITEs in the function.
1482 auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) {
1483 if (kind != S_INLINESITE)
1484 return false;
1485
1486 ParseInlineSite(id, func_base);
1487
1488 for (const auto &line_entry :
1489 m_inline_sites[toOpaqueUid(id)]->line_entries) {
1490 // If line_entry is not terminal entry, remove previous line entry at
1491 // the same address and insert new one. Terminal entry inside an inline
1492 // site might not be terminal entry for its parent.
1493 if (!line_entry.is_terminal_entry)
1494 line_set.erase(line_entry);
1495 line_set.insert(line_entry);
1496 }
1497 // No longer useful after adding to line_set.
1498 m_inline_sites[toOpaqueUid(id)]->line_entries.clear();
1499 return true;
1500 };
1501 ParseSymbolArrayInScope(func_id, parse_inline_sites);
1502 // Jump to the end of the function record.
1503 iter = syms.at(getScopeEndOffset(func_record));
1504 }
1505
1507
1508 // Add line entries in line_set to line_table.
1509 std::vector<LineTable::Sequence> sequence(1);
1510 for (const auto &line_entry : line_set) {
1512 sequence.back(), line_entry.file_addr, line_entry.line,
1513 line_entry.column, line_entry.file_idx,
1514 line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
1515 line_entry.is_prologue_end, line_entry.is_epilogue_begin,
1516 line_entry.is_terminal_entry);
1517 }
1518 auto line_table =
1519 std::make_unique<LineTable>(&comp_unit, std::move(sequence));
1520
1521 if (line_table->GetSize() == 0)
1522 return false;
1523
1524 comp_unit.SetLineTable(line_table.release());
1525 return true;
1526}
1527
1529 // PDB doesn't contain information about macros
1530 return false;
1531}
1532
1533llvm::Expected<uint32_t>
1535 uint32_t file_id) {
1536 if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings())
1537 return llvm::make_error<RawError>(raw_error_code::no_entry);
1538
1539 const auto &checksums = cii.m_strings.checksums().getArray();
1540 const auto &strings = cii.m_strings.strings();
1541 // Indices in this structure are actually offsets of records in the
1542 // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index
1543 // into the global PDB string table.
1544 auto iter = checksums.at(file_id);
1545 if (iter == checksums.end())
1546 return llvm::make_error<RawError>(raw_error_code::no_entry);
1547
1548 llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
1549 if (!efn) {
1550 return efn.takeError();
1551 }
1552
1553 // LLDB wants the index of the file in the list of support files.
1554 auto fn_iter = llvm::find(cii.m_file_list, *efn);
1555 if (fn_iter != cii.m_file_list.end())
1556 return std::distance(cii.m_file_list.begin(), fn_iter);
1557 return llvm::make_error<RawError>(raw_error_code::no_entry);
1558}
1559
1561 SupportFileList &support_files) {
1562 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1563 PdbSymUid cu_id(comp_unit.GetID());
1565 CompilandIndexItem *cci =
1566 m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
1567 lldbassert(cci);
1568
1569 for (llvm::StringRef f : cci->m_file_list) {
1570 FileSpec::Style style =
1571 f.starts_with("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1572 FileSpec spec(f, style);
1573 support_files.Append(spec);
1574 }
1575 return true;
1576}
1577
1579 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1580 // PDB does not yet support module debug info
1581 return false;
1582}
1583
1585 Address func_addr) {
1586 lldb::user_id_t opaque_uid = toOpaqueUid(id);
1587 if (m_inline_sites.contains(opaque_uid))
1588 return;
1589
1590 addr_t func_base = func_addr.GetFileAddress();
1591 CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi);
1592 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset);
1593 CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
1594
1595 InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
1596 cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
1597 PdbCompilandSymId parent_id(id.modi, inline_site.Parent);
1598
1599 std::shared_ptr<InlineSite> inline_site_sp =
1600 std::make_shared<InlineSite>(parent_id);
1601
1602 // Get the inlined function declaration info.
1603 auto iter = cii->m_inline_map.find(inline_site.Inlinee);
1604 if (iter == cii->m_inline_map.end())
1605 return;
1606 InlineeSourceLine inlinee_line = iter->second;
1607
1608 const SupportFileList &files = comp_unit->GetSupportFiles();
1609 FileSpec decl_file;
1610 llvm::Expected<uint32_t> file_index_or_err =
1611 GetFileIndex(*cii, inlinee_line.Header->FileID);
1612 if (!file_index_or_err)
1613 return;
1614 uint32_t file_offset = file_index_or_err.get();
1615 decl_file = files.GetFileSpecAtIndex(file_offset);
1616 uint32_t decl_line = inlinee_line.Header->SourceLineNum;
1617 std::unique_ptr<Declaration> decl_up =
1618 std::make_unique<Declaration>(decl_file, decl_line);
1619
1620 // Parse range and line info.
1621 uint32_t code_offset = 0;
1622 int32_t line_offset = 0;
1623 std::optional<uint32_t> code_offset_base;
1624 std::optional<uint32_t> code_offset_end;
1625 std::optional<int32_t> cur_line_offset;
1626 std::optional<int32_t> next_line_offset;
1627 std::optional<uint32_t> next_file_offset;
1628
1629 bool is_terminal_entry = false;
1630 bool is_start_of_statement = true;
1631 // The first instruction is the prologue end.
1632 bool is_prologue_end = true;
1633
1634 auto update_code_offset = [&](uint32_t code_delta) {
1635 if (!code_offset_base)
1636 code_offset_base = code_offset;
1637 else if (!code_offset_end)
1638 code_offset_end = *code_offset_base + code_delta;
1639 };
1640 auto update_line_offset = [&](int32_t line_delta) {
1641 line_offset += line_delta;
1642 if (!code_offset_base || !cur_line_offset)
1643 cur_line_offset = line_offset;
1644 else
1645 next_line_offset = line_offset;
1646 ;
1647 };
1648 auto update_file_offset = [&](uint32_t offset) {
1649 if (!code_offset_base)
1650 file_offset = offset;
1651 else
1652 next_file_offset = offset;
1653 };
1654
1655 for (auto &annot : inline_site.annotations()) {
1656 switch (annot.OpCode) {
1657 case BinaryAnnotationsOpCode::CodeOffset:
1658 case BinaryAnnotationsOpCode::ChangeCodeOffset:
1659 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
1660 code_offset += annot.U1;
1661 update_code_offset(annot.U1);
1662 break;
1663 case BinaryAnnotationsOpCode::ChangeLineOffset:
1664 update_line_offset(annot.S1);
1665 break;
1666 case BinaryAnnotationsOpCode::ChangeCodeLength:
1667 update_code_offset(annot.U1);
1668 code_offset += annot.U1;
1669 is_terminal_entry = true;
1670 break;
1671 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
1672 code_offset += annot.U1;
1673 update_code_offset(annot.U1);
1674 update_line_offset(annot.S1);
1675 break;
1676 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
1677 code_offset += annot.U2;
1678 update_code_offset(annot.U2);
1679 update_code_offset(annot.U1);
1680 code_offset += annot.U1;
1681 is_terminal_entry = true;
1682 break;
1683 case BinaryAnnotationsOpCode::ChangeFile:
1684 update_file_offset(annot.U1);
1685 break;
1686 default:
1687 break;
1688 }
1689
1690 // Add range if current range is finished.
1691 if (code_offset_base && code_offset_end && cur_line_offset) {
1692 inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(
1693 *code_offset_base, *code_offset_end - *code_offset_base,
1694 decl_line + *cur_line_offset));
1695 // Set base, end, file offset and line offset for next range.
1696 if (next_file_offset)
1697 file_offset = *next_file_offset;
1698 if (next_line_offset) {
1699 cur_line_offset = next_line_offset;
1700 next_line_offset = std::nullopt;
1701 }
1702 code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;
1703 code_offset_end = next_file_offset = std::nullopt;
1704 }
1705 if (code_offset_base && cur_line_offset) {
1706 if (is_terminal_entry) {
1707 LineTable::Entry line_entry(
1708 func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
1709 file_offset, false, false, false, false, true);
1710 inline_site_sp->line_entries.push_back(line_entry);
1711 } else {
1712 LineTable::Entry line_entry(func_base + *code_offset_base,
1713 decl_line + *cur_line_offset, 0,
1714 file_offset, is_start_of_statement, false,
1715 is_prologue_end, false, false);
1716 inline_site_sp->line_entries.push_back(line_entry);
1717 is_prologue_end = false;
1718 is_start_of_statement = false;
1719 }
1720 }
1721 if (is_terminal_entry)
1722 is_start_of_statement = true;
1723 is_terminal_entry = false;
1724 }
1725
1726 inline_site_sp->ranges.Sort();
1727
1728 // Get the inlined function callsite info.
1729 std::unique_ptr<Declaration> callsite_up;
1730 if (!inline_site_sp->ranges.IsEmpty()) {
1731 auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
1732 addr_t base_offset = entry->GetRangeBase();
1733 if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() ==
1734 S_INLINESITE) {
1735 // Its parent is another inline site, lookup parent site's range vector
1736 // for callsite line.
1737 ParseInlineSite(parent_id, func_base);
1738 std::shared_ptr<InlineSite> parent_site =
1739 m_inline_sites[toOpaqueUid(parent_id)];
1740 FileSpec &parent_decl_file =
1741 parent_site->inline_function_info->GetDeclaration().GetFile();
1742 if (auto *parent_entry =
1743 parent_site->ranges.FindEntryThatContains(base_offset)) {
1744 callsite_up =
1745 std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
1746 }
1747 } else {
1748 // Its parent is a function, lookup global line table for callsite.
1749 if (auto *entry = cii->m_global_line_table.FindEntryThatContains(
1750 func_base + base_offset)) {
1751 const FileSpec &callsite_file =
1752 files.GetFileSpecAtIndex(entry->data.first);
1753 callsite_up =
1754 std::make_unique<Declaration>(callsite_file, entry->data.second);
1755 }
1756 }
1757 }
1758
1759 // Get the inlined function name.
1760 std::string inlinee_name;
1761 llvm::Expected<CVType> inlinee_cvt =
1762 m_index->ipi().typeCollection().getTypeOrError(inline_site.Inlinee);
1763 if (!inlinee_cvt) {
1764 inlinee_name = "[error reading function name: " +
1765 llvm::toString(inlinee_cvt.takeError()) + "]";
1766 } else if (inlinee_cvt->kind() == LF_MFUNC_ID) {
1767 MemberFuncIdRecord mfr;
1768 cantFail(
1769 TypeDeserializer::deserializeAs<MemberFuncIdRecord>(*inlinee_cvt, mfr));
1770 LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
1771 inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
1772 inlinee_name.append("::");
1773 inlinee_name.append(mfr.getName().str());
1774 } else if (inlinee_cvt->kind() == LF_FUNC_ID) {
1775 FuncIdRecord fir;
1776 cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(*inlinee_cvt, fir));
1777 TypeIndex parent_idx = fir.getParentScope();
1778 if (!parent_idx.isNoneType()) {
1779 LazyRandomTypeCollection &ids = m_index->ipi().typeCollection();
1780 inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
1781 inlinee_name.append("::");
1782 }
1783 inlinee_name.append(fir.getName().str());
1784 }
1785 inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
1786 inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
1787 callsite_up.get());
1788
1789 m_inline_sites[opaque_uid] = inline_site_sp;
1790}
1791
1793 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1794 PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym();
1795 // After we iterate through inline sites inside the function, we already get
1796 // all the info needed, removing from the map to save memory.
1797 std::set<uint64_t> remove_uids;
1798 auto parse_blocks = [&](SymbolKind kind, PdbCompilandSymId id) {
1799 if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
1800 kind == S_INLINESITE) {
1801 GetOrCreateBlock(id);
1802 if (kind == S_INLINESITE)
1803 remove_uids.insert(toOpaqueUid(id));
1804 return true;
1805 }
1806 return false;
1807 };
1808 size_t count = ParseSymbolArrayInScope(func_id, parse_blocks);
1809 for (uint64_t uid : remove_uids) {
1810 m_inline_sites.erase(uid);
1811 }
1812
1813 func.GetBlock(false).SetBlockInfoHasBeenParsed(true, true);
1814 return count;
1815}
1816
1818 PdbCompilandSymId parent_id,
1819 llvm::function_ref<bool(SymbolKind, PdbCompilandSymId)> fn) {
1820 CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi);
1821 CVSymbolArray syms =
1822 cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset);
1823
1824 size_t count = 1;
1825 for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
1826 PdbCompilandSymId child_id(parent_id.modi, iter.offset());
1827 if (fn(iter->kind(), child_id))
1828 ++count;
1829 }
1830
1831 return count;
1832}
1833
1834void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter,
1835 bool show_color) {
1837 if (!ts_or_err)
1838 return;
1839 auto ts = *ts_or_err;
1840 TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
1841 if (!clang)
1842 return;
1843 PdbAstBuilder *ast_builder = clang->GetNativePDBParser();
1844 if (!ast_builder)
1845 return;
1846 ast_builder->Dump(s, filter, show_color);
1847}
1848
1850 if (!m_func_full_names.IsEmpty() || !m_global_variable_base_names.IsEmpty())
1851 return;
1852
1853 // (segment, code offset) -> gid
1854 std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids;
1855
1856 // First, look through all items in the globals table.
1857 for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
1858 CVSymbol sym = m_index->symrecords().readRecord(gid);
1859 auto kind = sym.kind();
1860
1861 // If this is a global variable, we only need to look at the name
1862 llvm::StringRef name;
1863 switch (kind) {
1864 case SymbolKind::S_GDATA32:
1865 case SymbolKind::S_LDATA32: {
1866 DataSym data =
1867 llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym));
1868 name = data.Name;
1869 break;
1870 }
1871 case SymbolKind::S_GTHREAD32:
1872 case SymbolKind::S_LTHREAD32: {
1873 ThreadLocalDataSym data = llvm::cantFail(
1874 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym));
1875 name = data.Name;
1876 break;
1877 }
1878 case SymbolKind::S_CONSTANT: {
1879 ConstantSym data =
1880 llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym));
1881 name = data.Name;
1882 break;
1883 }
1884 default:
1885 break;
1886 }
1887
1888 if (!name.empty()) {
1889 llvm::StringRef base = MSVCUndecoratedNameParser::DropScope(name);
1890 if (base.empty())
1891 base = name;
1892
1893 m_global_variable_base_names.Append(ConstString(base), gid);
1894 continue;
1895 }
1896
1897 if (kind != S_PROCREF && kind != S_LPROCREF)
1898 continue;
1899
1900 // For functions, we need to follow the reference to the procedure and look
1901 // at the type
1902
1903 ProcRefSym ref =
1904 llvm::cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(sym));
1905 if (ref.Name.empty())
1906 continue;
1907
1908 // Find the function this is referencing.
1909 CompilandIndexItem &cci =
1910 m_index->compilands().GetOrCreateCompiland(ref.modi());
1911 auto iter = cci.m_debug_stream.getSymbolArray().at(ref.SymOffset);
1912 if (iter == cci.m_debug_stream.getSymbolArray().end())
1913 continue;
1914 kind = iter->kind();
1915 if (kind != S_GPROC32 && kind != S_LPROC32)
1916 continue;
1917
1918 ProcSym proc =
1919 llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*iter));
1920 if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)
1921 continue;
1922 if (proc.Name.empty() || proc.FunctionType.isSimple())
1923 continue;
1924
1925 // The function/procedure symbol only contains the demangled name.
1926 // The mangled names are in the publics table. Save the address of this
1927 // function to lookup the mangled name later.
1928 func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
1929
1930 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(proc.Name);
1931 if (basename.empty())
1932 basename = proc.Name;
1933
1934 m_func_base_names.Append(ConstString(basename), gid);
1935 m_func_full_names.Append(ConstString(proc.Name), gid);
1936
1937 // To see if this is a member function, check the type.
1938 auto type = m_index->tpi().getType(proc.FunctionType);
1939 if (type.kind() == LF_MFUNCTION) {
1940 MemberFunctionRecord mfr;
1941 llvm::cantFail(
1942 TypeDeserializer::deserializeAs<MemberFunctionRecord>(type, mfr));
1943 if (!mfr.getThisType().isNoneType())
1944 m_func_method_names.Append(ConstString(basename), gid);
1945 }
1946 }
1947
1948 // The publics stream contains all mangled function names and their address.
1949 for (auto pid : m_index->publics().getPublicsTable()) {
1950 PdbGlobalSymId global{pid, true};
1951 CVSymbol sym = m_index->ReadSymbolRecord(global);
1952 auto kind = sym.kind();
1953 if (kind != S_PUB32)
1954 continue;
1955 PublicSym32 pub =
1956 llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym));
1957 // We only care about mangled names - if the name isn't mangled, it's
1958 // already in the full name map.
1959 if (!Mangled::IsMangledName(pub.Name))
1960 continue;
1961
1962 // Check if this symbol is for one of our functions.
1963 auto it = func_addr_ids.find({pub.Segment, pub.Offset});
1964 if (it != func_addr_ids.end())
1965 m_func_full_names.Append(ConstString(pub.Name), it->second);
1966 }
1967
1968 // Sort them before value searching is working properly.
1969 m_func_full_names.Sort(std::less<uint32_t>());
1970 m_func_full_names.SizeToFit();
1971 m_func_method_names.Sort(std::less<uint32_t>());
1972 m_func_method_names.SizeToFit();
1973 m_func_base_names.Sort(std::less<uint32_t>());
1974 m_func_base_names.SizeToFit();
1975 m_global_variable_base_names.Sort(std::less<uint32_t>());
1976 m_global_variable_base_names.SizeToFit();
1977}
1978
1980 ConstString name, const CompilerDeclContext &parent_decl_ctx,
1981 uint32_t max_matches, VariableList &variables) {
1982 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1983
1985
1986 std::vector<uint32_t> results;
1987 m_global_variable_base_names.GetValues(name, results);
1988
1989 size_t n_matches = 0;
1990 for (uint32_t gid : results) {
1991 PdbGlobalSymId global(gid, false);
1992
1993 if (parent_decl_ctx.IsValid() &&
1994 GetDeclContextContainingUID(toOpaqueUid(global)) != parent_decl_ctx)
1995 continue;
1996
1998 if (!var)
1999 continue;
2000 variables.AddVariable(var);
2001
2002 if (++n_matches >= max_matches)
2003 break;
2004 }
2005}
2006
2008 const Module::LookupInfo &lookup_info,
2009 const CompilerDeclContext &parent_decl_ctx, bool include_inlines,
2010 SymbolContextList &sc_list) {
2011 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2012 ConstString name = lookup_info.GetLookupName();
2013 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();
2014 if (name_type_mask & eFunctionNameTypeFull)
2015 name = lookup_info.GetName();
2016
2017 if (!(name_type_mask & eFunctionNameTypeFull ||
2018 name_type_mask & eFunctionNameTypeBase ||
2019 name_type_mask & eFunctionNameTypeMethod))
2020 return;
2022
2023 std::set<uint32_t> resolved_ids; // avoid duplicate lookups
2024 auto resolve_from = [&](UniqueCStringMap<uint32_t> &Names) {
2025 std::vector<uint32_t> ids;
2026 if (!Names.GetValues(name, ids))
2027 return;
2028
2029 for (uint32_t id : ids) {
2030 if (!resolved_ids.insert(id).second)
2031 continue;
2032
2033 PdbGlobalSymId global{id, false};
2034 if (parent_decl_ctx.IsValid() &&
2035 GetDeclContextContainingUID(toOpaqueUid(global)) != parent_decl_ctx)
2036 continue;
2037
2038 CVSymbol sym = m_index->ReadSymbolRecord(global);
2039 auto kind = sym.kind();
2040 lldbassert(kind == S_PROCREF || kind == S_LPROCREF);
2041
2042 ProcRefSym proc =
2043 cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(sym));
2044
2045 if (!IsValidRecord(proc))
2046 continue;
2047
2048 CompilandIndexItem &cci =
2049 m_index->compilands().GetOrCreateCompiland(proc.modi());
2050 SymbolContext sc;
2051
2052 sc.comp_unit = GetOrCreateCompileUnit(cci).get();
2053 if (!sc.comp_unit)
2054 continue;
2055
2056 PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
2057 sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
2058 if (!sc.function)
2059 continue;
2060
2061 sc_list.Append(sc);
2062 }
2063 };
2064
2065 if (name_type_mask & eFunctionNameTypeFull)
2066 resolve_from(m_func_full_names);
2067 if (name_type_mask & eFunctionNameTypeBase)
2068 resolve_from(m_func_base_names);
2069 if (name_type_mask & eFunctionNameTypeMethod)
2070 resolve_from(m_func_method_names);
2071}
2072
2074 bool include_inlines,
2075 SymbolContextList &sc_list) {}
2076
2078 lldb_private::TypeResults &results) {
2079
2080 // Make sure we haven't already searched this SymbolFile before.
2081 if (results.AlreadySearched(this))
2082 return;
2083
2084 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2085
2086 // We can't query for the full name because the type might reside
2087 // in an anonymous namespace. Search for the basename in our map and check the
2088 // matching types afterwards.
2089 std::vector<uint32_t> matches;
2090 m_type_base_names.GetValues(query.GetTypeBasename(), matches);
2091
2092 for (uint32_t match_idx : matches) {
2093 std::vector context = GetContextForType(TypeIndex(match_idx));
2094 if (context.empty())
2095 continue;
2096
2097 if (query.ContextMatches(context)) {
2098 TypeSP type_sp = GetOrCreateType(TypeIndex(match_idx));
2099 if (!type_sp)
2100 continue;
2101
2102 results.InsertUnique(type_sp);
2103 if (results.Done(query))
2104 return;
2105 }
2106 }
2107}
2108
2110 uint32_t max_matches,
2111 TypeMap &types) {
2112
2113 std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
2114 if (max_matches > 0 && max_matches < matches.size())
2115 matches.resize(max_matches);
2116
2117 for (TypeIndex ti : matches) {
2118 TypeSP type = GetOrCreateType(ti);
2119 if (!type)
2120 continue;
2121
2122 types.Insert(type);
2123 }
2124}
2125
2127 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2128 // Only do the full type scan the first time.
2130 return 0;
2131
2132 const size_t old_count = GetTypeList().GetSize();
2133 LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
2134
2135 // First process the entire TPI stream.
2136 for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2137 TypeSP type = GetOrCreateType(*ti);
2138 if (type)
2139 (void)type->GetFullCompilerType();
2140 }
2141
2142 // Next look for S_UDT records in the globals stream.
2143 for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
2144 PdbGlobalSymId global{gid, false};
2145 CVSymbol sym = m_index->ReadSymbolRecord(global);
2146 if (sym.kind() != S_UDT)
2147 continue;
2148
2149 UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
2150 bool is_typedef = true;
2151 if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {
2152 CVType cvt = m_index->tpi().getType(udt.Type);
2153 llvm::StringRef name = CVTagRecord::create(cvt).name();
2154 if (name == udt.Name)
2155 is_typedef = false;
2156 }
2157
2158 if (is_typedef)
2159 GetOrCreateTypedef(global);
2160 }
2161
2162 const size_t new_count = GetTypeList().GetSize();
2163
2164 m_done_full_type_scan = true;
2165
2166 return new_count - old_count;
2167}
2168
2169size_t
2171 VariableList &variables) {
2172 PdbSymUid sym_uid(comp_unit.GetID());
2174 for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
2175 PdbGlobalSymId global{gid, false};
2176 CVSymbol sym = m_index->ReadSymbolRecord(global);
2177 // TODO: S_CONSTANT is not handled here to prevent a possible crash in
2178 // lldb_private::npdb::MakeConstantLocationExpression when it's a record
2179 // type (e.g. std::strong_ordering::equal). That function needs to be
2180 // updated to handle this case when we add S_CONSTANT case here.
2181 switch (sym.kind()) {
2182 case SymbolKind::S_GDATA32:
2183 case SymbolKind::S_LDATA32:
2184 case SymbolKind::S_GTHREAD32:
2185 case SymbolKind::S_LTHREAD32: {
2186 if (VariableSP var = GetOrCreateGlobalVariable(global))
2187 variables.AddVariable(var);
2188 break;
2189 }
2190 default:
2191 break;
2192 }
2193 }
2194 return variables.GetSize();
2195}
2196
2198 PdbCompilandSymId var_id,
2199 bool is_param) {
2200 ModuleSP module = GetObjectFile()->GetModule();
2201 Block *block = GetOrCreateBlock(scope_id);
2202 if (!block)
2203 return nullptr;
2204
2205 // Get function block.
2206 Block *func_block = block;
2207 while (func_block->GetParent()) {
2208 func_block = func_block->GetParent();
2209 }
2210
2211 Address addr;
2212 func_block->GetStartAddress(addr);
2213 VariableInfo var_info =
2214 GetVariableLocationInfo(*m_index, var_id, *func_block, module);
2215 Function *func = func_block->CalculateSymbolContextFunction();
2216 if (!func)
2217 return nullptr;
2218 // Use empty dwarf expr if optimized away so that it won't be filtered out
2219 // when lookuping local variables in this scope.
2220 if (!var_info.location.IsValid())
2221 var_info.location = DWARFExpressionList(module, DWARFExpression(), nullptr);
2223 CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
2224 CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
2225 TypeSP type_sp = GetOrCreateType(var_info.type);
2226 if (!type_sp)
2227 return nullptr;
2228 std::string name = var_info.name.str();
2229 Declaration decl;
2230 SymbolFileTypeSP sftype =
2231 std::make_shared<SymbolFileType>(*this, type_sp->GetID());
2232
2233 is_param |= var_info.is_param;
2234 ValueType var_scope =
2236 bool external = false;
2237 bool artificial = false;
2238 bool location_is_constant_data = false;
2239 bool static_member = false;
2240 Variable::RangeList scope_ranges;
2241 VariableSP var_sp = std::make_shared<Variable>(
2242 toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, block,
2243 scope_ranges, &decl, var_info.location, external, artificial,
2244 location_is_constant_data, static_member);
2245 if (!is_param) {
2246 auto ts_or_err = GetTypeSystemForLanguage(comp_unit_sp->GetLanguage());
2247 if (auto err = ts_or_err.takeError())
2248 return nullptr;
2249 auto ts = *ts_or_err;
2250 if (ts) {
2251 if (PdbAstBuilder *ast_builder = ts->GetNativePDBParser())
2252 ast_builder->EnsureVariable(scope_id, var_id);
2253 }
2254 }
2255 m_local_variables[toOpaqueUid(var_id)] = var_sp;
2256 return var_sp;
2257}
2258
2260 PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
2261 auto iter = m_local_variables.find(toOpaqueUid(var_id));
2262 if (iter != m_local_variables.end())
2263 return iter->second;
2264
2265 return CreateLocalVariable(scope_id, var_id, is_param);
2266}
2267
2269 CVSymbol sym = m_index->ReadSymbolRecord(id);
2270 lldbassert(sym.kind() == SymbolKind::S_UDT);
2271
2272 UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
2273
2274 TypeSP target_type = GetOrCreateType(udt.Type);
2275
2277 if (auto err = ts_or_err.takeError())
2278 return nullptr;
2279 auto ts = *ts_or_err;
2280 if (!ts)
2281 return nullptr;
2282 PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2283 if (!ast_builder)
2284 return nullptr;
2285 CompilerType ct = ast_builder->GetOrCreateTypedefType(id);
2286 if (!ct)
2287 ct = target_type->GetForwardCompilerType();
2288
2289 Declaration decl;
2290 return MakeType(toOpaqueUid(id), ConstString(udt.Name),
2291 llvm::expectedToOptional(target_type->GetByteSize(nullptr)),
2292 nullptr, target_type->GetID(),
2295}
2296
2298 auto iter = m_types.find(toOpaqueUid(id));
2299 if (iter != m_types.end())
2300 return iter->second;
2301
2302 return CreateTypedef(id);
2303}
2304
2306 Block *block = GetOrCreateBlock(block_id);
2307 if (!block)
2308 return 0;
2309
2310 size_t count = 0;
2311
2312 CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
2313 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
2314 uint32_t params_remaining = 0;
2315 switch (sym.kind()) {
2316 case S_GPROC32:
2317 case S_LPROC32: {
2318 ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));
2319 cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));
2320 CVType signature = m_index->tpi().getType(proc.FunctionType);
2321 if (signature.kind() == LF_PROCEDURE) {
2322 ProcedureRecord sig;
2323 if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(
2324 signature, sig)) {
2325 llvm::consumeError(std::move(e));
2326 return 0;
2327 }
2328 params_remaining = sig.getParameterCount();
2329 } else if (signature.kind() == LF_MFUNCTION) {
2330 MemberFunctionRecord sig;
2331 if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2332 signature, sig)) {
2333 llvm::consumeError(std::move(e));
2334 return 0;
2335 }
2336 params_remaining = sig.getParameterCount();
2337 } else
2338 return 0;
2339 break;
2340 }
2341 case S_BLOCK32:
2342 break;
2343 case S_INLINESITE:
2344 break;
2345 default:
2346 lldbassert(false && "Symbol is not a block!");
2347 return 0;
2348 }
2349
2350 VariableListSP variables = block->GetBlockVariableList(false);
2351 if (!variables) {
2352 variables = std::make_shared<VariableList>();
2353 block->SetVariableList(variables);
2354 }
2355
2356 CVSymbolArray syms = limitSymbolArrayToScope(
2357 cii->m_debug_stream.getSymbolArray(), block_id.offset);
2358
2359 // Skip the first record since it's a PROC32 or BLOCK32, and there's
2360 // no point examining it since we know it's not a local variable.
2361 syms.drop_front();
2362 auto iter = syms.begin();
2363 auto end = syms.end();
2364
2365 while (iter != end) {
2366 uint32_t record_offset = iter.offset();
2367 CVSymbol variable_cvs = *iter;
2368 PdbCompilandSymId child_sym_id(block_id.modi, record_offset);
2369 ++iter;
2370
2371 // If this is a block or inline site, recurse into its children and then
2372 // skip it.
2373 if (variable_cvs.kind() == S_BLOCK32 ||
2374 variable_cvs.kind() == S_INLINESITE) {
2375 uint32_t block_end = getScopeEndOffset(variable_cvs);
2376 count += ParseVariablesForBlock(child_sym_id);
2377 iter = syms.at(block_end);
2378 continue;
2379 }
2380
2381 bool is_param = params_remaining > 0;
2382 VariableSP variable;
2383 switch (variable_cvs.kind()) {
2384 case S_REGREL32:
2385 case S_REGISTER:
2386 case S_LOCAL:
2387 variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
2388 if (is_param)
2389 --params_remaining;
2390 if (variable)
2391 variables->AddVariableIfUnique(variable);
2392 break;
2393 default:
2394 break;
2395 }
2396 }
2397
2398 // Pass false for set_children, since we call this recursively so that the
2399 // children will call this for themselves.
2400 block->SetDidParseVariables(true, false);
2401
2402 return count;
2403}
2404
2406 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2407 lldbassert(sc.function || sc.comp_unit);
2408
2409 VariableListSP variables;
2410 if (sc.block) {
2411 PdbSymUid block_id(sc.block->GetID());
2412
2413 size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
2414 return count;
2415 }
2416
2417 if (sc.function) {
2418 PdbSymUid block_id(sc.function->GetID());
2419
2420 size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
2421 return count;
2422 }
2423
2424 if (sc.comp_unit) {
2425 variables = sc.comp_unit->GetVariableList(false);
2426 if (!variables) {
2427 variables = std::make_shared<VariableList>();
2428 sc.comp_unit->SetVariableList(variables);
2429 }
2430 return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);
2431 }
2432
2433 llvm_unreachable("Unreachable!");
2434}
2435
2438 if (auto err = ts_or_err.takeError())
2439 return CompilerDecl();
2440 auto ts = *ts_or_err;
2441 if (!ts)
2442 return {};
2443 PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2444 if (!ast_builder)
2445 return {};
2446 return ast_builder->GetOrCreateDeclForUid(uid);
2447}
2448
2452 if (auto err = ts_or_err.takeError())
2453 return {};
2454 auto ts = *ts_or_err;
2455 if (!ts)
2456 return {};
2457 PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2458 if (!ast_builder)
2459 return {};
2460 return ast_builder->GetOrCreateDeclContextForUid(PdbSymUid(uid));
2461}
2462
2466 if (auto err = ts_or_err.takeError())
2467 return CompilerDeclContext();
2468 auto ts = *ts_or_err;
2469 if (!ts)
2470 return {};
2471 PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2472 if (!ast_builder)
2473 return {};
2474 return ast_builder->GetParentDeclContext(PdbSymUid(uid));
2475}
2476
2478 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2479 auto iter = m_types.find(type_uid);
2480 // lldb should not be passing us non-sensical type uids. the only way it
2481 // could have a type uid in the first place is if we handed it out, in which
2482 // case we should know about the type. However, that doesn't mean we've
2483 // instantiated it yet. We can vend out a UID for a future type. So if the
2484 // type doesn't exist, let's instantiate it now.
2485 if (iter != m_types.end())
2486 return &*iter->second;
2487
2488 PdbSymUid uid(type_uid);
2490 PdbTypeSymId type_id = uid.asTypeSym();
2491 if (type_id.index.isNoneType())
2492 return nullptr;
2493
2494 TypeSP type_sp = CreateAndCacheType(type_id);
2495 if (!type_sp)
2496 return nullptr;
2497 return &*type_sp;
2498}
2499
2500std::optional<SymbolFile::ArrayInfo>
2502 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
2503 return std::nullopt;
2504}
2505
2507 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2508 auto ts = compiler_type.GetTypeSystem();
2509 if (!ts)
2510 return false;
2511
2512 PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
2513 if (!ast_builder)
2514 return false;
2515 return ast_builder->CompleteType(compiler_type);
2516}
2517
2519 TypeClass type_mask,
2520 lldb_private::TypeList &type_list) {}
2521
2524 const CompilerDeclContext &parent_decl_ctx,
2525 bool /* only_root_namespaces */) {
2526 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2528 if (auto err = ts_or_err.takeError())
2529 return {};
2530 auto ts = *ts_or_err;
2531 if (!ts)
2532 return {};
2533 auto *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
2534 if (!clang)
2535 return {};
2536
2537 PdbAstBuilder *ast_builder = clang->GetNativePDBParser();
2538 if (!ast_builder)
2539 return {};
2540
2541 return ast_builder->FindNamespaceDecl(parent_decl_ctx, name.GetStringRef());
2542}
2543
2544llvm::Expected<lldb::TypeSystemSP>
2546 auto type_system_or_err =
2547 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
2548 if (type_system_or_err)
2549 if (auto ts = *type_system_or_err)
2550 ts->SetSymbolFile(this);
2551 return type_system_or_err;
2552}
2553
2554uint64_t SymbolFileNativePDB::GetDebugInfoSize(bool load_all_debug_info) {
2555 // PDB files are a separate file that contains all debug info.
2556 return m_index->pdb().getFileSize();
2557}
2558
2560 LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
2561
2562 llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
2563 llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
2564
2565 struct RecordIndices {
2566 TypeIndex forward;
2567 TypeIndex full;
2568 };
2569
2570 llvm::StringMap<RecordIndices> record_indices;
2571
2572 for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2573 CVType type = types.getType(*ti);
2574 if (!IsTagRecord(type))
2575 continue;
2576
2577 CVTagRecord tag = CVTagRecord::create(type);
2578
2579 RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
2580 if (tag.asTag().isForwardRef()) {
2581 indices.forward = *ti;
2582 } else {
2583 indices.full = *ti;
2584
2585 auto base_name = MSVCUndecoratedNameParser::DropScope(tag.name());
2586 m_type_base_names.Append(ConstString(base_name), ti->getIndex());
2587 }
2588
2589 if (indices.full != TypeIndex::None() &&
2590 indices.forward != TypeIndex::None()) {
2591 forward_to_full[indices.forward] = indices.full;
2592 full_to_forward[indices.full] = indices.forward;
2593 }
2594
2595 // We're looking for LF_NESTTYPE records in the field list, so ignore
2596 // forward references (no field list), and anything without a nested class
2597 // (since there won't be any LF_NESTTYPE records).
2598 if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())
2599 continue;
2600
2601 struct ProcessTpiStream : public TypeVisitorCallbacks {
2602 ProcessTpiStream(PdbIndex &index, TypeIndex parent,
2603 const CVTagRecord &parent_cvt,
2604 llvm::DenseMap<TypeIndex, TypeIndex> &parents)
2605 : index(index), parents(parents), parent(parent),
2606 parent_cvt(parent_cvt) {}
2607
2608 PdbIndex &index;
2609 llvm::DenseMap<TypeIndex, TypeIndex> &parents;
2610
2611 unsigned unnamed_type_index = 1;
2612 TypeIndex parent;
2613 const CVTagRecord &parent_cvt;
2614
2615 llvm::Error visitKnownMember(CVMemberRecord &CVR,
2616 NestedTypeRecord &Record) override {
2617 std::string unnamed_type_name;
2618 if (Record.Name.empty()) {
2619 unnamed_type_name =
2620 llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();
2621 Record.Name = unnamed_type_name;
2622 ++unnamed_type_index;
2623 }
2624 std::optional<CVTagRecord> tag =
2625 GetNestedTagDefinition(Record, parent_cvt, index.tpi());
2626 if (!tag)
2627 return llvm::ErrorSuccess();
2628
2629 parents[Record.Type] = parent;
2630 return llvm::ErrorSuccess();
2631 }
2632 };
2633
2634 CVType field_list_cvt = m_index->tpi().getType(tag.asTag().FieldList);
2635 ProcessTpiStream process(*m_index, *ti, tag, m_parent_types);
2636 FieldListRecord field_list;
2637 if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
2638 field_list_cvt, field_list))
2639 llvm::consumeError(std::move(error));
2640 if (llvm::Error error = visitMemberRecordStream(field_list.Data, process))
2641 llvm::consumeError(std::move(error));
2642 }
2643
2644 // After calling Append(), the type-name map needs to be sorted again to be
2645 // able to look up a type by its name.
2646 m_type_base_names.Sort(std::less<uint32_t>());
2647
2648 // Now that we know the forward -> full mapping of all type indices, we can
2649 // re-write all the indices. At the end of this process, we want a mapping
2650 // consisting of fwd -> full and full -> full for all child -> parent indices.
2651 // We can re-write the values in place, but for the keys, we must save them
2652 // off so that we don't modify the map in place while also iterating it.
2653 std::vector<TypeIndex> full_keys;
2654 std::vector<TypeIndex> fwd_keys;
2655 for (auto &entry : m_parent_types) {
2656 TypeIndex key = entry.first;
2657 TypeIndex value = entry.second;
2658
2659 auto iter = forward_to_full.find(value);
2660 if (iter != forward_to_full.end())
2661 entry.second = iter->second;
2662
2663 iter = forward_to_full.find(key);
2664 if (iter != forward_to_full.end())
2665 fwd_keys.push_back(key);
2666 else
2667 full_keys.push_back(key);
2668 }
2669 for (TypeIndex fwd : fwd_keys) {
2670 TypeIndex full = forward_to_full[fwd];
2671 TypeIndex parent_idx = m_parent_types[fwd];
2672 m_parent_types[full] = parent_idx;
2673 }
2674 for (TypeIndex full : full_keys) {
2675 TypeIndex fwd = full_to_forward[full];
2676 m_parent_types[fwd] = m_parent_types[full];
2677 }
2678}
2679
2680std::optional<PdbCompilandSymId>
2682 CVSymbol sym = m_index->ReadSymbolRecord(id);
2683 if (symbolOpensScope(sym.kind())) {
2684 // If this exact symbol opens a scope, we can just directly access its
2685 // parent.
2686 id.offset = getScopeParentOffset(sym);
2687 // Global symbols have parent offset of 0. Return std::nullopt to indicate
2688 // this.
2689 if (id.offset == 0)
2690 return std::nullopt;
2691 return id;
2692 }
2693
2694 // Otherwise we need to start at the beginning and iterate forward until we
2695 // reach (or pass) this particular symbol
2696 CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(id.modi);
2697 const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
2698
2699 auto begin = syms.begin();
2700 auto end = syms.at(id.offset);
2701 std::vector<PdbCompilandSymId> scope_stack;
2702
2703 while (begin != end) {
2704 if (begin.offset() > id.offset) {
2705 // We passed it. We couldn't even find this symbol record.
2706 lldbassert(false && "Invalid compiland symbol id!");
2707 return std::nullopt;
2708 }
2709
2710 // We haven't found the symbol yet. Check if we need to open or close the
2711 // scope stack.
2712 if (symbolOpensScope(begin->kind())) {
2713 // We can use the end offset of the scope to determine whether or not
2714 // we can just outright skip this entire scope.
2715 uint32_t scope_end = getScopeEndOffset(*begin);
2716 if (scope_end < id.offset) {
2717 begin = syms.at(scope_end);
2718 } else {
2719 // The symbol we're looking for is somewhere in this scope.
2720 scope_stack.emplace_back(id.modi, begin.offset());
2721 }
2722 } else if (symbolEndsScope(begin->kind())) {
2723 scope_stack.pop_back();
2724 }
2725 ++begin;
2726 }
2727 if (scope_stack.empty())
2728 return std::nullopt;
2729 // We have a match! Return the top of the stack
2730 return scope_stack.back();
2731}
2732
2733std::optional<llvm::codeview::TypeIndex>
2734SymbolFileNativePDB::GetParentType(llvm::codeview::TypeIndex ti) {
2735 auto parent_iter = m_parent_types.find(ti);
2736 if (parent_iter == m_parent_types.end())
2737 return std::nullopt;
2738 return parent_iter->second;
2739}
2740
2741std::vector<CompilerContext>
2743 CVType type = m_index->tpi().getType(ti);
2744 if (!IsTagRecord(type))
2745 return {};
2746
2747 CVTagRecord tag = CVTagRecord::create(type);
2748
2749 std::optional<Type::ParsedName> parsed_name =
2751 if (!parsed_name)
2752 return {{tag.contextKind(), ConstString(tag.name())}};
2753
2754 std::vector<CompilerContext> ctx;
2755 // assume everything is a namespace at first
2756 for (llvm::StringRef scope : parsed_name->scope) {
2757 ctx.emplace_back(CompilerContextKind::Namespace, ConstString(scope));
2758 }
2759 // we know the kind of our own type
2760 ctx.emplace_back(tag.contextKind(), ConstString(parsed_name->basename));
2761
2762 // try to find the kind of parents
2763 for (auto &el : llvm::reverse(llvm::drop_end(ctx))) {
2764 std::optional<TypeIndex> parent = GetParentType(ti);
2765 if (!parent)
2766 break;
2767
2768 ti = *parent;
2769 type = m_index->tpi().getType(ti);
2770 switch (type.kind()) {
2771 case LF_CLASS:
2772 case LF_STRUCTURE:
2773 case LF_INTERFACE:
2775 continue;
2776 case LF_UNION:
2778 continue;
2779 case LF_ENUM:
2780 el.kind = CompilerContextKind::Enum;
2781 continue;
2782 default:
2783 break;
2784 }
2785 break;
2786 }
2787 return ctx;
2788}
2789
2790std::optional<llvm::StringRef>
2792 const CompilandIndexItem *cci =
2793 m_index->compilands().GetCompiland(func_id.modi);
2794 if (!cci)
2795 return std::nullopt;
2796
2797 CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
2798 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)
2799 return std::nullopt;
2800
2801 ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
2802 cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
2803
2804 return FindMangledSymbol(SegmentOffset(proc.Segment, proc.CodeOffset),
2805 proc.FunctionType);
2806}
2807
2808std::optional<llvm::StringRef>
2810 TypeIndex function_type) {
2811 auto symbol = m_index->publics().findByAddress(m_index->symrecords(),
2812 so.segment, so.offset);
2813 if (!symbol)
2814 return std::nullopt;
2815
2816 llvm::StringRef name = symbol->first.Name;
2817 // For functions, we might need to strip the mangled name. See
2818 // StripMangledFunctionName for more info.
2819 if (!function_type.isNoneType() &&
2820 (symbol->first.Flags & PublicSymFlags::Function) != PublicSymFlags::None)
2821 name = StripMangledFunctionName(name, function_type);
2822
2823 return name;
2824}
2825
2826llvm::StringRef
2828 PdbTypeSymId func_ty) {
2829 // "In non-64 bit environments" (on x86 in pactice), __cdecl functions get
2830 // prefixed with an underscore. For compilers using LLVM, this happens in LLVM
2831 // (as opposed to the compiler frontend). Because of this, DWARF doesn't
2832 // contain the "full" mangled name in DW_AT_linkage_name for these functions.
2833 // We strip the mangling here for compatibility with DWARF. See
2834 // llvm.org/pr161676 and
2835 // https://learn.microsoft.com/en-us/cpp/build/reference/decorated-names#FormatC
2836
2837 if (!mangled.starts_with('_') ||
2838 m_index->dbi().getMachineType() != PDB_Machine::x86)
2839 return mangled;
2840
2841 CVType cvt = m_index->tpi().getType(func_ty.index);
2842 PDB_CallingConv cc = PDB_CallingConv::NearC;
2843 if (cvt.kind() == LF_PROCEDURE) {
2844 ProcedureRecord proc;
2845 if (llvm::Error error =
2846 TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, proc))
2847 llvm::consumeError(std::move(error));
2848 cc = proc.CallConv;
2849 } else if (cvt.kind() == LF_MFUNCTION) {
2850 MemberFunctionRecord mfunc;
2851 if (llvm::Error error =
2852 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfunc))
2853 llvm::consumeError(std::move(error));
2854 cc = mfunc.CallConv;
2855 } else {
2856 LLDB_LOG(GetLog(LLDBLog::Symbols), "Unexpected function type, got {0}",
2857 cvt.kind());
2858 return mangled;
2859 }
2860
2861 if (cc == PDB_CallingConv::NearC || cc == PDB_CallingConv::FarC)
2862 return mangled.drop_front();
2863
2864 return mangled;
2865}
2866
2868 for (CVType cvt : m_index->ipi().typeArray()) {
2869 switch (cvt.kind()) {
2870 case LF_UDT_SRC_LINE: {
2871 UdtSourceLineRecord udt_src;
2872 llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_src));
2873 m_udt_declarations.try_emplace(
2874 udt_src.UDT, UdtDeclaration{/*FileNameIndex=*/udt_src.SourceFile,
2875 /*IsIpiIndex=*/true,
2876 /*Line=*/udt_src.LineNumber});
2877 } break;
2878 case LF_UDT_MOD_SRC_LINE: {
2879 UdtModSourceLineRecord udt_mod_src;
2880 llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_mod_src));
2881 // Some types might be contributed by multiple modules. We assume that
2882 // they all point to the same file and line because we can only provide
2883 // one location.
2884 m_udt_declarations.try_emplace(
2885 udt_mod_src.UDT,
2886 UdtDeclaration{/*FileNameIndex=*/udt_mod_src.SourceFile,
2887 /*IsIpiIndex=*/false,
2888 /*Line=*/udt_mod_src.LineNumber});
2889 } break;
2890 default:
2891 break;
2892 }
2893 }
2894}
2895
2896llvm::Expected<Declaration>
2898 std::call_once(m_cached_udt_declarations, [this] { CacheUdtDeclarations(); });
2899
2900 auto it = m_udt_declarations.find(type_id.index);
2901 if (it == m_udt_declarations.end())
2902 return llvm::createStringError("No UDT declaration found");
2903
2904 llvm::StringRef file_name;
2905 if (it->second.IsIpiIndex) {
2906 CVType cvt = m_index->ipi().getType(it->second.FileNameIndex);
2907 if (cvt.kind() != LF_STRING_ID)
2908 return llvm::createStringError("File name was not a LF_STRING_ID");
2909
2910 StringIdRecord sid;
2911 llvm::cantFail(TypeDeserializer::deserializeAs(cvt, sid));
2912 file_name = sid.String;
2913 } else {
2914 // The file name index is an index into the string table
2915 auto string_table = m_index->pdb().getStringTable();
2916 if (!string_table)
2917 return string_table.takeError();
2918
2919 llvm::Expected<llvm::StringRef> string =
2920 string_table->getStringTable().getString(
2921 it->second.FileNameIndex.getIndex());
2922 if (!string)
2923 return string.takeError();
2924 file_name = *string;
2925 }
2926
2927 // rustc sets the filename to "<unknown>" for some files
2928 if (file_name == "\\<unknown>")
2929 return Declaration();
2930
2931 return Declaration(FileSpec(file_name), it->second.Line);
2932}
static llvm::raw_ostream & error(Stream &strm)
#define lldbassert(x)
Definition LLDBAssert.h:16
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
static std::unique_ptr< PDBFile > loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator)
static std::optional< CVTagRecord > GetNestedTagDefinition(const NestedTypeRecord &Record, const CVTagRecord &parent, TpiStream &tpi)
static lldb::LanguageType TranslateLanguage(PDB_Lang lang)
static std::string GetUnqualifiedTypeName(const TagRecord &record)
static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind)
static bool IsClassRecord(TypeLeafKind kind)
static bool IsFunctionEpilogue(const CompilandIndexItem &cci, lldb::addr_t addr)
static bool NeedsResolvedCompileUnit(uint32_t resolve_scope)
static std::optional< std::string > findMatchingPDBFilePath(llvm::StringRef original_pdb_path, llvm::StringRef exe_path)
static bool IsFunctionPrologue(const CompilandIndexItem &cci, lldb::addr_t addr)
static llvm::StringRef DropScope(llvm::StringRef name)
static bool UseNativePDB()
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:281
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
A class that describes a single lexical block.
Definition Block.h:41
RangeList::Entry Range
Definition Block.h:44
lldb::VariableListSP GetBlockVariableList(bool can_create)
Get the variable list for this block only.
Definition Block.cpp:392
Block * FindInnermostBlockByOffset(const lldb::addr_t offset)
Definition Block.cpp:127
void SetBlockInfoHasBeenParsed(bool b, bool set_children)
Definition Block.cpp:479
lldb::BlockSP CreateChild(lldb::user_id_t uid)
Creates a block with the specified UID uid.
Definition Block.cpp:380
Function * CalculateSymbolContextFunction() override
Definition Block.cpp:150
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
Definition Block.h:319
Block * GetParent() const
Get the parent block.
Definition Block.cpp:202
bool GetStartAddress(Address &addr)
Definition Block.cpp:317
void SetDidParseVariables(bool b, bool set_children)
Definition Block.cpp:489
A class that describes a compilation unit.
Definition CompileUnit.h:43
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list, RealpathPrefixes *realpath_prefixes=nullptr)
Resolve symbol contexts by file and line.
void SetLineTable(LineTable *line_table)
Set the line table for the compile unit.
void AddFunction(lldb::FunctionSP &function_sp)
Add a function to this compile unit.
size_t GetNumFunctions() const
Returns the number of functions in this compile unit.
lldb::LanguageType GetLanguage()
LineTable * GetLineTable()
Get the line table for the compile unit.
Represents a generic declaration context in a program.
Represents a generic declaration such as a function declaration.
Generic representation of a type in a programming language.
TypeSystemSPWrapper GetTypeSystem() const
Accessors.
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
bool IsValid() const
Return true if the location expression contains data.
void SetFuncFileAddress(lldb::addr_t func_file_addr)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
A class to manage flag bits.
Definition Debugger.h:87
A class that describes the declaration location of a lldb object.
Definition Declaration.h:24
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file collection class.
A file utility class.
Definition FileSpec.h:57
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
Definition FileSpec.cpp:425
static std::optional< Style > GuessPathStyle(llvm::StringRef absolute_path)
Attempt to guess path style for a given path string.
Definition FileSpec.cpp:310
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
Definition FileSpec.cpp:301
const ConstString & GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:251
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
FileSpec CopyByRemovingLastPathComponent() const
Definition FileSpec.cpp:431
llvm::sys::path::Style Style
Definition FileSpec.h:59
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
A class that describes a function.
Definition Function.h:400
const Address & GetAddress() const
Return the address of the function (its entry point).
Definition Function.h:453
Block & GetBlock(bool can_create)
Get accessor for the block list.
Definition Function.cpp:383
static void AppendLineEntryToSequence(Sequence &sequence, lldb::addr_t file_addr, uint32_t line, uint16_t column, uint16_t file_idx, bool is_start_of_statement, bool is_start_of_basic_block, bool is_prologue_end, bool is_epilogue_begin, bool is_terminal_entry)
Definition LineTable.cpp:59
A class that handles mangled names.
Definition Mangled.h:34
static bool IsMangledName(llvm::StringRef name)
Definition Mangled.cpp:39
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A class that encapsulates name lookup information.
Definition Module.h:908
lldb::FunctionNameType GetNameTypeMask() const
Definition Module.h:949
ConstString GetLookupName() const
Definition Module.h:947
ConstString GetName() const
Definition Module.h:945
static std::unique_ptr< llvm::pdb::PDBFile > loadPDBFile(std::string PdbPath, llvm::BumpPtrAllocator &Allocator)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
RangeData< lldb::addr_t, uint32_t, std::pair< uint32_t, uint32_t > > Entry
Definition RangeMap.h:462
void Append(const Entry &entry)
Definition RangeMap.h:474
Entry * FindEntryThatContains(B addr)
Definition RangeMap.h:583
"lldb/Core/SourceLocationSpec.h" A source location specifier class.
A stream class that can stream formatted output to a file.
Definition Stream.h:28
A list of support files for a CompileUnit.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
void Append(const FileSpec &file)
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Block * block
The Block for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
LineEntry line_entry
The LineEntry for a given query.
lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override
ObjectFile * GetObjectFile() override
Definition SymbolFile.h:570
virtual TypeList & GetTypeList()
Definition SymbolFile.h:643
lldb::ObjectFileSP m_objfile_sp
Definition SymbolFile.h:646
void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp)
SymbolFileCommon(lldb::ObjectFileSP objfile_sp)
Definition SymbolFile.h:555
uint32_t GetNumCompileUnits() override
lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name, std::optional< uint64_t > byte_size, SymbolContextScope *context, lldb::user_id_t encoding_uid, Type::EncodingDataType encoding_uid_type, const Declaration &decl, const CompilerType &compiler_qual_type, Type::ResolveState compiler_type_resolve_state, uint32_t opaque_payload=0) override
This function is used to create types that belong to a SymbolFile.
Definition SymbolFile.h:614
virtual std::recursive_mutex & GetModuleMutex() const
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
void SetByteSize(lldb::addr_t size)
Definition Symbol.h:213
Symbol * SymbolAtIndex(size_t idx)
Definition Symtab.cpp:228
uint32_t AddSymbol(const Symbol &symbol)
Definition Symtab.cpp:64
static FileSpecList GetDefaultDebugFileSearchPaths()
Definition Target.cpp:2801
uint32_t GetSize() const
Definition TypeList.cpp:60
void Insert(const lldb::TypeSP &type)
Definition TypeList.cpp:27
void Insert(const lldb::TypeSP &type)
Definition TypeMap.cpp:27
A class that contains all state required for type lookups.
Definition Type.h:104
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
Definition Type.cpp:113
bool ContextMatches(llvm::ArrayRef< lldb_private::CompilerContext > context) const
Check of a CompilerContext array from matching type from a symbol file matches the m_context.
Definition Type.cpp:129
This class tracks the state and results of a TypeQuery.
Definition Type.h:344
bool InsertUnique(const lldb::TypeSP &type_sp)
When types that match a TypeQuery are found, this API is used to insert the matching types.
Definition Type.cpp:194
bool Done(const TypeQuery &query) const
Check if the type matching has found all of the matches that it needs.
Definition Type.cpp:200
bool AlreadySearched(lldb_private::SymbolFile *sym_file)
Check if a SymbolFile object has already been searched by this type match object.
Definition Type.cpp:190
A TypeSystem implementation based on Clang.
Interface for representing a type system.
Definition TypeSystem.h:70
virtual npdb::PdbAstBuilder * GetNativePDBParser()
Definition TypeSystem.h:92
@ eEncodingIsTypedefUID
This type is alias to a type whose UID is m_encoding_uid.
Definition Type.h:434
@ eEncodingIsUID
This type is the type whose UID is m_encoding_uid.
Definition Type.h:423
static std::optional< ParsedName > GetTypeScopeAndBasename(llvm::StringRef name)
Definition Type.cpp:792
void AddVariable(const lldb::VariableSP &var_sp)
RangeVector< lldb::addr_t, lldb::addr_t > RangeList
Definition Variable.h:27
virtual CompilerType GetOrCreateTypedefType(PdbGlobalSymId id)=0
virtual void Dump(Stream &stream, llvm::StringRef filter, bool show_color)=0
virtual CompilerDeclContext FindNamespaceDecl(CompilerDeclContext parent_ctx, llvm::StringRef name)=0
virtual bool CompleteType(CompilerType ct)=0
virtual void EnsureBlock(PdbCompilandSymId block_id)=0
virtual CompilerDeclContext GetParentDeclContext(PdbSymUid uid)=0
virtual CompilerType GetOrCreateType(PdbTypeSymId type)=0
virtual CompilerDecl GetOrCreateDeclForUid(PdbSymUid uid)=0
virtual void EnsureInlinedFunction(PdbCompilandSymId inlinesite_id)=0
virtual void ParseDeclsForContext(CompilerDeclContext context)=0
virtual CompilerDeclContext GetOrCreateDeclContextForUid(PdbSymUid uid)=0
PdbIndex - Lazy access to the important parts of a PDB file.
Definition PdbIndex.h:47
static llvm::Expected< std::unique_ptr< PdbIndex > > create(llvm::pdb::PDBFile *)
Definition PdbIndex.cpp:43
llvm::pdb::TpiStream & tpi()
Definition PdbIndex.h:124
PdbCompilandId asCompiland() const
PdbCompilandSymId asCompilandSym() const
PdbTypeSymId asTypeSym() const
PdbSymUidKind kind() const
void CreateSimpleArgumentListTypes(llvm::codeview::TypeIndex arglist_ti)
lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id)
bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override
lldb::TypeSP CreateArrayType(PdbTypeSymId type_id, const llvm::codeview::ArrayRecord &ar, CompilerType ct)
std::optional< ArrayInfo > GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) override
If type_uid points to an array type, return its characteristics.
void CacheGlobalBaseNames()
Caches the basenames of symbols found in the globals stream.
llvm::Expected< Declaration > ResolveUdtDeclaration(PdbTypeSymId type_id)
lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id)
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language) override
void InitializeObject() override
Initialize the SymbolFile object.
lldb_private::UniqueCStringMap< uint32_t > m_func_base_names
basename -> Global ID(s)
static SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp)
llvm::DenseMap< lldb::user_id_t, lldb::TypeSP > m_types
bool CompleteType(CompilerType &compiler_type) override
lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override
CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override
void DumpClangAST(Stream &s, llvm::StringRef filter, bool show_color) override
lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param)
size_t ParseVariablesForContext(const SymbolContext &sc) override
size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override
lldb::TypeSP CreatePointerType(PdbTypeSymId type_id, const llvm::codeview::PointerRecord &pr, CompilerType ct)
lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id, CompileUnit &comp_unit)
llvm::DenseMap< lldb::user_id_t, lldb::BlockSP > m_blocks
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, SupportFileList &support_files) override
CompilerDecl GetDeclForUID(lldb::user_id_t uid) override
std::optional< llvm::StringRef > FindMangledFunctionName(PdbCompilandSymId id)
Find the mangled name for a function.
SymbolFileNativePDB(lldb::ObjectFileSP objfile_sp)
lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id)
void FindTypesByName(llvm::StringRef name, uint32_t max_matches, TypeMap &types)
lldb::TypeSP CreateTagType(PdbTypeSymId type_id, const llvm::codeview::ClassRecord &cr, CompilerType ct)
lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id)
void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override
llvm::DenseMap< lldb::user_id_t, lldb::VariableSP > m_local_variables
lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id, const llvm::codeview::CVSymbol &cvs)
lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct)
lldb_private::UniqueCStringMap< uint32_t > m_func_method_names
method basename -> Global ID(s)
std::optional< llvm::codeview::TypeIndex > GetParentType(llvm::codeview::TypeIndex ti)
lldb_private::UniqueCStringMap< uint32_t > m_global_variable_base_names
global variable basename -> Global ID(s)
void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) override
std::unique_ptr< llvm::pdb::PDBFile > m_file_up
lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param)
lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id, const llvm::codeview::ProcedureRecord &pr, CompilerType ct)
lldb::TypeSP CreateModifierType(PdbTypeSymId type_id, const llvm::codeview::ModifierRecord &mr, CompilerType ct)
uint64_t GetDebugInfoSize(bool load_all_debug_info=false) override
Metrics gathering functions.
std::optional< llvm::StringRef > FindMangledSymbol(SegmentOffset so, llvm::codeview::TypeIndex function_type=llvm::codeview::TypeIndex())
Find a symbol name at a specific address (so).
size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override
Block * GetOrCreateBlock(PdbCompilandSymId block_id)
size_t ParseBlocksRecursive(Function &func) override
lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci)
std::optional< PdbCompilandSymId > FindSymbolScope(PdbCompilandSymId id)
size_t ParseSymbolArrayInScope(PdbCompilandSymId parent, llvm::function_ref< bool(llvm::codeview::SymbolKind, PdbCompilandSymId)> fn)
size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit, VariableList &variables)
llvm::DenseMap< lldb::user_id_t, lldb::CompUnitSP > m_compilands
Block * CreateBlock(PdbCompilandSymId block_id)
std::vector< CompilerContext > GetContextForType(llvm::codeview::TypeIndex ti)
llvm::Expected< uint32_t > GetFileIndex(const CompilandIndexItem &cii, uint32_t file_id)
lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci)
Type * ResolveTypeUID(lldb::user_id_t type_uid) override
llvm::DenseMap< lldb::user_id_t, lldb::FunctionSP > m_functions
bool ParseImportedModules(const SymbolContext &sc, std::vector< lldb_private::SourceModule > &imported_modules) override
llvm::StringRef StripMangledFunctionName(llvm::StringRef mangled, PdbTypeSymId func_ty)
static void DebuggerInitialize(Debugger &debugger)
llvm::DenseMap< lldb::user_id_t, std::shared_ptr< InlineSite > > m_inline_sites
void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr)
lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id, const llvm::codeview::TagRecord &record, size_t size, CompilerType ct)
void FindGlobalVariables(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override
size_t ParseVariablesForBlock(PdbCompilandSymId block_id)
void ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override
lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id, CompileUnit &comp_unit)
llvm::DenseMap< llvm::codeview::TypeIndex, llvm::codeview::TypeIndex > m_parent_types
lldb_private::UniqueCStringMap< uint32_t > m_func_full_names
mangled name/full function name -> Global ID(s)
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
lldb::TypeSP CreateFunctionType(PdbTypeSymId type_id, const llvm::codeview::MemberFunctionRecord &pr, CompilerType ct)
lldb_private::UniqueCStringMap< uint32_t > m_type_base_names
lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id)
CompilerDeclContext FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx, bool only_root_namespaces) override
Finds a namespace of name name and whose parent context is parent_decl_ctx.
CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override
lldb::TypeSP CreateTypedef(PdbGlobalSymId id)
llvm::DenseMap< llvm::codeview::TypeIndex, UdtDeclaration > m_udt_declarations
void FindTypes(const lldb_private::TypeQuery &match, lldb_private::TypeResults &results) override
Find types using a type-matching object that contains all search parameters.
uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override
llvm::DenseMap< lldb::user_id_t, lldb::VariableSP > m_global_vars
lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti, CompilerType ct)
#define LLDB_INVALID_UID
#define LLDB_INVALID_ADDRESS
uint64_t toOpaqueUid(const T &cid)
Definition PdbSymUid.h:114
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
SegmentOffsetLength GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym)
bool IsTagRecord(llvm::codeview::CVType cvt)
Definition PdbUtil.cpp:517
bool IsValidRecord(const RecordT &sym)
Definition PdbUtil.h:129
DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, lldb::ModuleSP module)
VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block &func_block, lldb::ModuleSP module)
Definition PdbUtil.cpp:734
bool IsForwardRefUdt(llvm::codeview::CVType cvt)
llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind)
DWARFExpression MakeConstantLocationExpression(llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, const llvm::APSInt &constant, lldb::ModuleSP module)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
std::shared_ptr< lldb_private::Function > FunctionSP
std::shared_ptr< lldb_private::Block > BlockSP
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeRust
Rust.
@ eLanguageTypeObjC_plus_plus
Objective-C++.
@ eLanguageTypeSwift
Swift.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
@ eLanguageTypeC_plus_plus
ISO C++:1998.
std::shared_ptr< lldb_private::Type > TypeSP
SymbolType
Symbol types.
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::SymbolFileType > SymbolFileTypeSP
std::shared_ptr< lldb_private::Variable > VariableSP
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
std::shared_ptr< lldb_private::CompileUnit > CompUnitSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
BaseType GetRangeBase() const
Definition RangeMap.h:45
void SetRangeEnd(BaseType end)
Definition RangeMap.h:80
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
Definition RangeMap.h:48
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition UserID.h:47
CompilerContextKind contextKind() const
Definition PdbUtil.h:75
static CVTagRecord create(llvm::codeview::CVType type)
Definition PdbUtil.cpp:198
const llvm::codeview::TagRecord & asTag() const
Definition PdbUtil.h:44
llvm::StringRef name() const
Definition PdbUtil.h:67
Represents a single compile unit.
std::map< llvm::codeview::TypeIndex, llvm::codeview::InlineeSourceLine > m_inline_map
std::optional< llvm::codeview::Compile3Sym > m_compile_opts
llvm::pdb::ModuleDebugStreamRef m_debug_stream
llvm::codeview::StringsAndChecksumsRef m_strings
std::vector< llvm::StringRef > m_file_list
llvm::codeview::TypeIndex index
Definition PdbSymUid.h:76
DWARFExpressionList location
Definition PdbUtil.h:115
llvm::codeview::TypeIndex type
Definition PdbUtil.h:114