blob: c8b8d380327fbb651c8f3002cabe86d953b5ea46 [file] [log] [blame]
Zachary Turner307f5ae2018-10-12 19:47:13 +00001//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFileNativePDB.h"
11
12#include "clang/Lex/Lexer.h"
13
14#include "lldb/Core/Module.h"
15#include "lldb/Core/PluginManager.h"
16#include "lldb/Symbol/CompileUnit.h"
17#include "lldb/Symbol/LineTable.h"
18#include "lldb/Symbol/ObjectFile.h"
19#include "lldb/Symbol/SymbolContext.h"
20#include "lldb/Symbol/SymbolVendor.h"
21
22#include "llvm/DebugInfo/CodeView/CVRecord.h"
23#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
24#include "llvm/DebugInfo/CodeView/RecordName.h"
25#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
26#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
27#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
28#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
29#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
30#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
31#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
32#include "llvm/DebugInfo/PDB/PDBTypes.h"
33#include "llvm/Object/COFF.h"
34#include "llvm/Support/Allocator.h"
35#include "llvm/Support/BinaryStreamReader.h"
36#include "llvm/Support/ErrorOr.h"
37#include "llvm/Support/MemoryBuffer.h"
38
39#include "PdbSymUid.h"
40#include "PdbUtil.h"
41
42using namespace lldb;
43using namespace lldb_private;
44using namespace lldb_private::npdb;
45using namespace llvm::codeview;
46using namespace llvm::pdb;
47
48static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
49 switch (lang) {
50 case PDB_Lang::Cpp:
51 return lldb::LanguageType::eLanguageTypeC_plus_plus;
52 case PDB_Lang::C:
53 return lldb::LanguageType::eLanguageTypeC;
54 default:
55 return lldb::LanguageType::eLanguageTypeUnknown;
56 }
57}
58
59static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath,
60 llvm::BumpPtrAllocator &Allocator) {
61 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
62 llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
63 /*RequiresNullTerminator=*/false);
64 if (!ErrorOrBuffer)
65 return nullptr;
66 std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
67
68 llvm::StringRef Path = Buffer->getBufferIdentifier();
69 auto Stream = llvm::make_unique<llvm::MemoryBufferByteStream>(
70 std::move(Buffer), llvm::support::little);
71
72 auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
Zachary Turner8040eea2018-10-12 22:57:40 +000073 if (auto EC = File->parseFileHeaders()) {
74 llvm::consumeError(std::move(EC));
Zachary Turner307f5ae2018-10-12 19:47:13 +000075 return nullptr;
Zachary Turner8040eea2018-10-12 22:57:40 +000076 }
77 if (auto EC = File->parseStreamData()) {
78 llvm::consumeError(std::move(EC));
Zachary Turner307f5ae2018-10-12 19:47:13 +000079 return nullptr;
Zachary Turner8040eea2018-10-12 22:57:40 +000080 }
Zachary Turner307f5ae2018-10-12 19:47:13 +000081
82 return File;
83}
84
85static std::unique_ptr<PDBFile>
86loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
87 // Try to find a matching PDB for an EXE.
88 using namespace llvm::object;
89 auto expected_binary = createBinary(exe_path);
90
91 // If the file isn't a PE/COFF executable, fail.
92 if (!expected_binary) {
93 llvm::consumeError(expected_binary.takeError());
94 return nullptr;
95 }
96 OwningBinary<Binary> binary = std::move(*expected_binary);
97
98 auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
99 if (!obj)
100 return nullptr;
101 const llvm::codeview::DebugInfo *pdb_info = nullptr;
102
103 // If it doesn't have a debug directory, fail.
104 llvm::StringRef pdb_file;
105 auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file);
106 if (ec)
107 return nullptr;
108
109 // if the file doesn't exist, is not a pdb, or doesn't have a matching guid,
110 // fail.
111 llvm::file_magic magic;
112 ec = llvm::identify_magic(pdb_file, magic);
113 if (ec || magic != llvm::file_magic::pdb)
114 return nullptr;
115 std::unique_ptr<PDBFile> pdb = loadPDBFile(pdb_file, allocator);
Zachary Turner8040eea2018-10-12 22:57:40 +0000116 if (!pdb)
117 return nullptr;
118
Zachary Turner307f5ae2018-10-12 19:47:13 +0000119 auto expected_info = pdb->getPDBInfoStream();
120 if (!expected_info) {
121 llvm::consumeError(expected_info.takeError());
122 return nullptr;
123 }
124 llvm::codeview::GUID guid;
125 memcpy(&guid, pdb_info->PDB70.Signature, 16);
126
127 if (expected_info->getGuid() != guid)
128 return nullptr;
129 return pdb;
130}
131
132static bool IsFunctionPrologue(const CompilandIndexItem &cci,
133 lldb::addr_t addr) {
134 // FIXME: Implement this.
135 return false;
136}
137
138static bool IsFunctionEpilogue(const CompilandIndexItem &cci,
139 lldb::addr_t addr) {
140 // FIXME: Implement this.
141 return false;
142}
143
144void SymbolFileNativePDB::Initialize() {
145 PluginManager::RegisterPlugin(GetPluginNameStatic(),
146 GetPluginDescriptionStatic(), CreateInstance,
147 DebuggerInitialize);
148}
149
150void SymbolFileNativePDB::Terminate() {
151 PluginManager::UnregisterPlugin(CreateInstance);
152}
153
154void SymbolFileNativePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {
155}
156
157lldb_private::ConstString SymbolFileNativePDB::GetPluginNameStatic() {
158 static ConstString g_name("native-pdb");
159 return g_name;
160}
161
162const char *SymbolFileNativePDB::GetPluginDescriptionStatic() {
163 return "Microsoft PDB debug symbol cross-platform file reader.";
164}
165
166lldb_private::SymbolFile *
167SymbolFileNativePDB::CreateInstance(lldb_private::ObjectFile *obj_file) {
168 return new SymbolFileNativePDB(obj_file);
169}
170
171SymbolFileNativePDB::SymbolFileNativePDB(lldb_private::ObjectFile *object_file)
172 : SymbolFile(object_file) {}
173
174SymbolFileNativePDB::~SymbolFileNativePDB() {}
175
176uint32_t SymbolFileNativePDB::CalculateAbilities() {
177 uint32_t abilities = 0;
178 if (!m_obj_file)
179 return 0;
180
181 if (!m_index) {
182 // Lazily load and match the PDB file, but only do this once.
183 std::unique_ptr<PDBFile> file_up =
184 loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator);
185
186 if (!file_up) {
187 auto module_sp = m_obj_file->GetModule();
188 if (!module_sp)
189 return 0;
190 // See if any symbol file is specified through `--symfile` option.
191 FileSpec symfile = module_sp->GetSymbolFileFileSpec();
192 if (!symfile)
193 return 0;
194 file_up = loadPDBFile(symfile.GetPath(), m_allocator);
195 }
196
197 if (!file_up)
198 return 0;
199
200 auto expected_index = PdbIndex::create(std::move(file_up));
201 if (!expected_index) {
202 llvm::consumeError(expected_index.takeError());
203 return 0;
204 }
205 m_index = std::move(*expected_index);
206 }
207 if (!m_index)
208 return 0;
209
210 // We don't especially have to be precise here. We only distinguish between
211 // stripped and not stripped.
212 abilities = kAllAbilities;
213
214 if (m_index->dbi().isStripped())
215 abilities &= ~(Blocks | LocalVariables);
216 return abilities;
217}
218
219void SymbolFileNativePDB::InitializeObject() {
220 m_obj_load_address = m_obj_file->GetFileOffset();
221 m_index->SetLoadAddress(m_obj_load_address);
222 m_index->ParseSectionContribs();
223}
224
225uint32_t SymbolFileNativePDB::GetNumCompileUnits() {
226 const DbiModuleList &modules = m_index->dbi().modules();
227 uint32_t count = modules.getModuleCount();
228 if (count == 0)
229 return count;
230
231 // The linker can inject an additional "dummy" compilation unit into the
232 // PDB. Ignore this special compile unit for our purposes, if it is there.
233 // It is always the last one.
234 DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
235 if (last.getModuleName() == "* Linker *")
236 --count;
237 return count;
238}
239
240lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbSymUid func_uid,
241 const SymbolContext &sc) {
242 lldbassert(func_uid.tag() == PDB_SymType::Function);
243
244 PdbSymUid cuid = PdbSymUid::makeCompilandId(func_uid.asCuSym().modi);
245
246 const CompilandIndexItem *cci = m_index->compilands().GetCompiland(cuid);
247 lldbassert(cci);
248 CVSymbol sym_record =
249 cci->m_debug_stream.readSymbolAtOffset(func_uid.asCuSym().offset);
250
251 lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);
252 SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record);
253
254 auto file_vm_addr = m_index->MakeVirtualAddress(sol.so);
255 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
256 return nullptr;
257
258 AddressRange func_range(file_vm_addr, sol.length,
259 sc.module_sp->GetSectionList());
260 if (!func_range.GetBaseAddress().IsValid())
261 return nullptr;
262
263 lldb_private::Type *func_type = nullptr;
264
265 // FIXME: Resolve types and mangled names.
266 PdbSymUid sig_uid =
267 PdbSymUid::makeTypeSymId(PDB_SymType::FunctionSig, TypeIndex{0}, false);
268 Mangled mangled(getSymbolName(sym_record));
269
270 FunctionSP func_sp = std::make_shared<Function>(
271 sc.comp_unit, func_uid.toOpaqueId(), sig_uid.toOpaqueId(), mangled,
272 func_type, func_range);
273
274 sc.comp_unit->AddFunction(func_sp);
275 return func_sp;
276}
277
278CompUnitSP
279SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
280 lldb::LanguageType lang =
281 cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())
282 : lldb::eLanguageTypeUnknown;
283
284 LazyBool optimized = eLazyBoolNo;
285 if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())
286 optimized = eLazyBoolYes;
287
288 llvm::StringRef source_file_name =
289 m_index->compilands().GetMainSourceFile(cci);
290 lldb_private::FileSpec fs(source_file_name, false);
291
292 CompUnitSP cu_sp =
293 std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, fs,
294 cci.m_uid.toOpaqueId(), lang, optimized);
295
296 const PdbCompilandId &cuid = cci.m_uid.asCompiland();
297 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cuid.modi,
298 cu_sp);
299 return cu_sp;
300}
301
302FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbSymUid func_uid,
303 const SymbolContext &sc) {
304 lldbassert(func_uid.tag() == PDB_SymType::Function);
305 auto emplace_result = m_functions.try_emplace(func_uid.toOpaqueId(), nullptr);
306 if (emplace_result.second)
307 emplace_result.first->second = CreateFunction(func_uid, sc);
308
309 lldbassert(emplace_result.first->second);
310 return emplace_result.first->second;
311}
312
313CompUnitSP
314SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) {
315 auto emplace_result =
316 m_compilands.try_emplace(cci.m_uid.toOpaqueId(), nullptr);
317 if (emplace_result.second)
318 emplace_result.first->second = CreateCompileUnit(cci);
319
320 lldbassert(emplace_result.first->second);
321 return emplace_result.first->second;
322}
323
324lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
325 if (index >= GetNumCompileUnits())
326 return CompUnitSP();
327 lldbassert(index < UINT16_MAX);
328 if (index >= UINT16_MAX)
329 return nullptr;
330
331 CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);
332
333 return GetOrCreateCompileUnit(item);
334}
335
336lldb::LanguageType SymbolFileNativePDB::ParseCompileUnitLanguage(
337 const lldb_private::SymbolContext &sc) {
338 // What fields should I expect to be filled out on the SymbolContext? Is it
339 // safe to assume that `sc.comp_unit` is valid?
340 if (!sc.comp_unit)
341 return lldb::eLanguageTypeUnknown;
342 PdbSymUid uid = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID());
343 lldbassert(uid.tag() == PDB_SymType::Compiland);
344
345 CompilandIndexItem *item = m_index->compilands().GetCompiland(uid);
346 lldbassert(item);
347 if (!item->m_compile_opts)
348 return lldb::eLanguageTypeUnknown;
349
350 return TranslateLanguage(item->m_compile_opts->getLanguage());
351}
352
353size_t SymbolFileNativePDB::ParseCompileUnitFunctions(
354 const lldb_private::SymbolContext &sc) {
355 lldbassert(sc.comp_unit);
356 return false;
357}
358
359static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
360 // If any of these flags are set, we need to resolve the compile unit.
361 uint32_t flags = eSymbolContextCompUnit;
362 flags |= eSymbolContextVariable;
363 flags |= eSymbolContextFunction;
364 flags |= eSymbolContextBlock;
365 flags |= eSymbolContextLineEntry;
366 return (resolve_scope & flags) != 0;
367}
368
369uint32_t
370SymbolFileNativePDB::ResolveSymbolContext(const lldb_private::Address &addr,
371 uint32_t resolve_scope,
372 lldb_private::SymbolContext &sc) {
373 uint32_t resolved_flags = 0;
374 lldb::addr_t file_addr = addr.GetFileAddress();
375
376 if (NeedsResolvedCompileUnit(resolve_scope)) {
377 llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);
378 if (!modi)
379 return 0;
380 PdbSymUid cuid = PdbSymUid::makeCompilandId(*modi);
381 CompilandIndexItem *cci = m_index->compilands().GetCompiland(cuid);
382 if (!cci)
383 return 0;
384
385 sc.comp_unit = GetOrCreateCompileUnit(*cci).get();
386 resolved_flags |= eSymbolContextCompUnit;
387 }
388
389 if (resolve_scope & eSymbolContextFunction) {
390 lldbassert(sc.comp_unit);
391 std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
392 for (const auto &match : matches) {
393 if (match.uid.tag() != PDB_SymType::Function)
394 continue;
395 sc.function = GetOrCreateFunction(match.uid, sc).get();
396 }
397 resolved_flags |= eSymbolContextFunction;
398 }
399
400 if (resolve_scope & eSymbolContextLineEntry) {
401 lldbassert(sc.comp_unit);
402 if (auto *line_table = sc.comp_unit->GetLineTable()) {
403 if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
404 resolved_flags |= eSymbolContextLineEntry;
405 }
406 }
407
408 return resolved_flags;
409}
410
411static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence,
412 const CompilandIndexItem &cci,
413 lldb::addr_t base_addr,
414 uint32_t file_number,
415 const LineFragmentHeader &block,
416 const LineNumberEntry &cur) {
417 LineInfo cur_info(cur.Flags);
418
419 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
420 return;
421
422 uint64_t addr = base_addr + cur.Offset;
423
424 bool is_statement = cur_info.isStatement();
425 bool is_prologue = IsFunctionPrologue(cci, addr);
426 bool is_epilogue = IsFunctionEpilogue(cci, addr);
427
428 uint32_t lno = cur_info.getStartLine();
429
430 table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number,
431 is_statement, false, is_prologue, is_epilogue,
432 false);
433}
434
435static void TerminateLineSequence(LineTable &table,
436 const LineFragmentHeader &block,
437 lldb::addr_t base_addr, uint32_t file_number,
438 uint32_t last_line,
439 std::unique_ptr<LineSequence> seq) {
440 // The end is always a terminal entry, so insert it regardless.
441 table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize,
442 last_line, 0, file_number, false, false,
443 false, false, true);
444 table.InsertSequence(seq.release());
445}
446
447bool SymbolFileNativePDB::ParseCompileUnitLineTable(
448 const lldb_private::SymbolContext &sc) {
449 // Unfortunately LLDB is set up to parse the entire compile unit line table
450 // all at once, even if all it really needs is line info for a specific
451 // function. In the future it would be nice if it could set the sc.m_function
452 // member, and we could only get the line info for the function in question.
453 lldbassert(sc.comp_unit);
454 PdbSymUid cu_id = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID());
455 lldbassert(cu_id.isCompiland());
456 CompilandIndexItem *cci = m_index->compilands().GetCompiland(cu_id);
457 lldbassert(cci);
458 auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
459
460 // This is basically a copy of the .debug$S subsections from all original COFF
461 // object files merged together with address relocations applied. We are
462 // looking for all DEBUG_S_LINES subsections.
463 for (const DebugSubsectionRecord &dssr :
464 cci->m_debug_stream.getSubsectionsArray()) {
465 if (dssr.kind() != DebugSubsectionKind::Lines)
466 continue;
467
468 DebugLinesSubsectionRef lines;
469 llvm::BinaryStreamReader reader(dssr.getRecordData());
470 if (auto EC = lines.initialize(reader)) {
471 llvm::consumeError(std::move(EC));
472 return false;
473 }
474
475 const LineFragmentHeader *lfh = lines.header();
476 uint64_t virtual_addr =
477 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
478
479 const auto &checksums = cci->m_strings.checksums().getArray();
480 const auto &strings = cci->m_strings.strings();
481 for (const LineColumnEntry &group : lines) {
482 // Indices in this structure are actually offsets of records in the
483 // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index
484 // into the global PDB string table.
485 auto iter = checksums.at(group.NameIndex);
486 if (iter == checksums.end())
487 continue;
488
489 llvm::Expected<llvm::StringRef> efn =
490 strings.getString(iter->FileNameOffset);
491 if (!efn) {
492 llvm::consumeError(efn.takeError());
493 continue;
494 }
495
496 // LLDB wants the index of the file in the list of support files.
497 auto fn_iter = llvm::find(cci->m_file_list, *efn);
498 lldbassert(fn_iter != cci->m_file_list.end());
499 uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter);
500
501 std::unique_ptr<LineSequence> sequence(
502 line_table->CreateLineSequenceContainer());
503 lldbassert(!group.LineNumbers.empty());
504
505 for (const LineNumberEntry &entry : group.LineNumbers) {
506 AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr,
507 file_index, *lfh, entry);
508 }
509 LineInfo last_line(group.LineNumbers.back().Flags);
510 TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index,
511 last_line.getEndLine(), std::move(sequence));
512 }
513 }
514
515 if (line_table->GetSize() == 0)
516 return false;
517
518 sc.comp_unit->SetLineTable(line_table.release());
519 return true;
520}
521
522bool SymbolFileNativePDB::ParseCompileUnitDebugMacros(
523 const lldb_private::SymbolContext &sc) {
524 // PDB doesn't contain information about macros
525 return false;
526}
527
528bool SymbolFileNativePDB::ParseCompileUnitSupportFiles(
529 const lldb_private::SymbolContext &sc,
530 lldb_private::FileSpecList &support_files) {
531 lldbassert(sc.comp_unit);
532
533 PdbSymUid comp_uid = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID());
534 lldbassert(comp_uid.tag() == PDB_SymType::Compiland);
535
536 const CompilandIndexItem *cci = m_index->compilands().GetCompiland(comp_uid);
537 lldbassert(cci);
538
539 for (llvm::StringRef f : cci->m_file_list) {
540 FileSpec::Style style =
541 f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
542 FileSpec spec(f, false, style);
543 support_files.Append(spec);
544 }
545
546 return true;
547}
548
549bool SymbolFileNativePDB::ParseImportedModules(
550 const lldb_private::SymbolContext &sc,
551 std::vector<lldb_private::ConstString> &imported_modules) {
552 // PDB does not yet support module debug info
553 return false;
554}
555
556size_t SymbolFileNativePDB::ParseFunctionBlocks(
557 const lldb_private::SymbolContext &sc) {
558 lldbassert(sc.comp_unit && sc.function);
559 return 0;
560}
561
562uint32_t SymbolFileNativePDB::FindFunctions(
563 const lldb_private::ConstString &name,
564 const lldb_private::CompilerDeclContext *parent_decl_ctx,
565 uint32_t name_type_mask, bool include_inlines, bool append,
566 lldb_private::SymbolContextList &sc_list) {
567 // For now we only support lookup by method name.
568 if (!(name_type_mask & eFunctionNameTypeMethod))
569 return 0;
570
571 using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
572
573 std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName(
574 name.GetStringRef(), m_index->symrecords());
575 for (const SymbolAndOffset &match : matches) {
576 if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
577 continue;
578 ProcRefSym proc(match.second.kind());
579 cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc));
580
581 if (!IsValidRecord(proc))
582 continue;
583
584 PdbSymUid cuid = PdbSymUid::makeCompilandId(proc);
585 CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(cuid);
586 lldb_private::SymbolContext sc;
587
588 sc.comp_unit = GetOrCreateCompileUnit(cci).get();
589 sc.module_sp = sc.comp_unit->GetModule();
590 PdbSymUid func_uid = PdbSymUid::makeCuSymId(proc);
591 sc.function = GetOrCreateFunction(func_uid, sc).get();
592
593 sc_list.Append(sc);
594 }
595
596 return sc_list.GetSize();
597}
598
599uint32_t
600SymbolFileNativePDB::FindFunctions(const lldb_private::RegularExpression &regex,
601 bool include_inlines, bool append,
602 lldb_private::SymbolContextList &sc_list) {
603 return 0;
604}
605
606lldb_private::CompilerDeclContext SymbolFileNativePDB::FindNamespace(
607 const lldb_private::SymbolContext &sc,
608 const lldb_private::ConstString &name,
609 const lldb_private::CompilerDeclContext *parent_decl_ctx) {
610 return {};
611}
612
613lldb_private::TypeSystem *
614SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
615 auto type_system =
616 m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
617 if (type_system)
618 type_system->SetSymbolFile(this);
619 return type_system;
620}
621
622lldb_private::ConstString SymbolFileNativePDB::GetPluginName() {
623 static ConstString g_name("pdb");
624 return g_name;
625}
626
627uint32_t SymbolFileNativePDB::GetPluginVersion() { return 1; }