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 
9 #include "SymbolFileNativePDB.h"
10 
11 #include "clang/AST/Attr.h"
12 #include "clang/AST/CharUnits.h"
13 #include "clang/AST/Decl.h"
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/Type.h"
16 
20 #include "lldb/Core/Module.h"
22 #include "lldb/Core/StreamBuffer.h"
23 #include "lldb/Core/StreamFile.h"
25 #include "lldb/Symbol/LineTable.h"
26 #include "lldb/Symbol/ObjectFile.h"
29 #include "lldb/Symbol/Variable.h"
31 #include "lldb/Utility/Log.h"
32 
33 #include "llvm/DebugInfo/CodeView/CVRecord.h"
34 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
35 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
36 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
37 #include "llvm/DebugInfo/CodeView/RecordName.h"
38 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
39 #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
40 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
41 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
42 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
43 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
44 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
45 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
46 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
47 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
48 #include "llvm/DebugInfo/PDB/PDBTypes.h"
49 #include "llvm/Demangle/MicrosoftDemangle.h"
50 #include "llvm/Object/COFF.h"
51 #include "llvm/Support/Allocator.h"
52 #include "llvm/Support/BinaryStreamReader.h"
53 #include "llvm/Support/Error.h"
54 #include "llvm/Support/ErrorOr.h"
55 #include "llvm/Support/MemoryBuffer.h"
56 
58 #include "PdbAstBuilder.h"
59 #include "PdbSymUid.h"
60 #include "PdbUtil.h"
61 #include "UdtRecordCompleter.h"
62 
63 using namespace lldb;
64 using namespace lldb_private;
65 using namespace npdb;
66 using namespace llvm::codeview;
67 using namespace llvm::pdb;
68 
70 
71 static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
72  switch (lang) {
73  case PDB_Lang::Cpp:
75  case PDB_Lang::C:
77  case PDB_Lang::Swift:
79  default:
81  }
82 }
83 
84 static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath,
85  llvm::BumpPtrAllocator &Allocator) {
86  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
87  llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
88  /*RequiresNullTerminator=*/false);
89  if (!ErrorOrBuffer)
90  return nullptr;
91  std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
92 
93  llvm::StringRef Path = Buffer->getBufferIdentifier();
94  auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(
95  std::move(Buffer), llvm::support::little);
96 
97  auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
98  if (auto EC = File->parseFileHeaders()) {
99  llvm::consumeError(std::move(EC));
100  return nullptr;
101  }
102  if (auto EC = File->parseStreamData()) {
103  llvm::consumeError(std::move(EC));
104  return nullptr;
105  }
106 
107  return File;
108 }
109 
110 static std::unique_ptr<PDBFile>
111 loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
112  // Try to find a matching PDB for an EXE.
113  using namespace llvm::object;
114  auto expected_binary = createBinary(exe_path);
115 
116  // If the file isn't a PE/COFF executable, fail.
117  if (!expected_binary) {
118  llvm::consumeError(expected_binary.takeError());
119  return nullptr;
120  }
121  OwningBinary<Binary> binary = std::move(*expected_binary);
122 
123  // TODO: Avoid opening the PE/COFF binary twice by reading this information
124  // directly from the lldb_private::ObjectFile.
125  auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
126  if (!obj)
127  return nullptr;
128  const llvm::codeview::DebugInfo *pdb_info = nullptr;
129 
130  // If it doesn't have a debug directory, fail.
131  llvm::StringRef pdb_file;
132  auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file);
133  if (ec)
134  return nullptr;
135 
136  // if the file doesn't exist, is not a pdb, or doesn't have a matching guid,
137  // fail.
138  llvm::file_magic magic;
139  ec = llvm::identify_magic(pdb_file, magic);
140  if (ec || magic != llvm::file_magic::pdb)
141  return nullptr;
142  std::unique_ptr<PDBFile> pdb = loadPDBFile(std::string(pdb_file), allocator);
143  if (!pdb)
144  return nullptr;
145 
146  auto expected_info = pdb->getPDBInfoStream();
147  if (!expected_info) {
148  llvm::consumeError(expected_info.takeError());
149  return nullptr;
150  }
151  llvm::codeview::GUID guid;
152  memcpy(&guid, pdb_info->PDB70.Signature, 16);
153 
154  if (expected_info->getGuid() != guid)
155  return nullptr;
156  return pdb;
157 }
158 
159 static bool IsFunctionPrologue(const CompilandIndexItem &cci,
160  lldb::addr_t addr) {
161  // FIXME: Implement this.
162  return false;
163 }
164 
165 static bool IsFunctionEpilogue(const CompilandIndexItem &cci,
166  lldb::addr_t addr) {
167  // FIXME: Implement this.
168  return false;
169 }
170 
171 static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
172  switch (kind) {
173  case SimpleTypeKind::Boolean128:
174  case SimpleTypeKind::Boolean16:
175  case SimpleTypeKind::Boolean32:
176  case SimpleTypeKind::Boolean64:
177  case SimpleTypeKind::Boolean8:
178  return "bool";
179  case SimpleTypeKind::Byte:
180  case SimpleTypeKind::UnsignedCharacter:
181  return "unsigned char";
182  case SimpleTypeKind::NarrowCharacter:
183  return "char";
184  case SimpleTypeKind::SignedCharacter:
185  case SimpleTypeKind::SByte:
186  return "signed char";
187  case SimpleTypeKind::Character16:
188  return "char16_t";
189  case SimpleTypeKind::Character32:
190  return "char32_t";
191  case SimpleTypeKind::Complex80:
192  case SimpleTypeKind::Complex64:
193  case SimpleTypeKind::Complex32:
194  return "complex";
195  case SimpleTypeKind::Float128:
196  case SimpleTypeKind::Float80:
197  return "long double";
198  case SimpleTypeKind::Float64:
199  return "double";
200  case SimpleTypeKind::Float32:
201  return "float";
202  case SimpleTypeKind::Float16:
203  return "single";
204  case SimpleTypeKind::Int128:
205  return "__int128";
206  case SimpleTypeKind::Int64:
207  case SimpleTypeKind::Int64Quad:
208  return "int64_t";
209  case SimpleTypeKind::Int32:
210  return "int";
211  case SimpleTypeKind::Int16:
212  return "short";
213  case SimpleTypeKind::UInt128:
214  return "unsigned __int128";
215  case SimpleTypeKind::UInt64:
216  case SimpleTypeKind::UInt64Quad:
217  return "uint64_t";
218  case SimpleTypeKind::HResult:
219  return "HRESULT";
220  case SimpleTypeKind::UInt32:
221  return "unsigned";
222  case SimpleTypeKind::UInt16:
223  case SimpleTypeKind::UInt16Short:
224  return "unsigned short";
225  case SimpleTypeKind::Int32Long:
226  return "long";
227  case SimpleTypeKind::UInt32Long:
228  return "unsigned long";
229  case SimpleTypeKind::Void:
230  return "void";
231  case SimpleTypeKind::WideCharacter:
232  return "wchar_t";
233  default:
234  return "";
235  }
236 }
237 
238 static bool IsClassRecord(TypeLeafKind kind) {
239  switch (kind) {
240  case LF_STRUCTURE:
241  case LF_CLASS:
242  case LF_INTERFACE:
243  return true;
244  default:
245  return false;
246  }
247 }
248 
249 void SymbolFileNativePDB::Initialize() {
250  PluginManager::RegisterPlugin(GetPluginNameStatic(),
251  GetPluginDescriptionStatic(), CreateInstance,
252  DebuggerInitialize);
253 }
254 
255 void SymbolFileNativePDB::Terminate() {
256  PluginManager::UnregisterPlugin(CreateInstance);
257 }
258 
259 void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {}
260 
261 ConstString SymbolFileNativePDB::GetPluginNameStatic() {
262  static ConstString g_name("native-pdb");
263  return g_name;
264 }
265 
266 const char *SymbolFileNativePDB::GetPluginDescriptionStatic() {
267  return "Microsoft PDB debug symbol cross-platform file reader.";
268 }
269 
270 SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {
271  return new SymbolFileNativePDB(std::move(objfile_sp));
272 }
273 
274 SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
275  : SymbolFile(std::move(objfile_sp)) {}
276 
278 
280  uint32_t abilities = 0;
281  if (!m_objfile_sp)
282  return 0;
283 
284  if (!m_index) {
285  // Lazily load and match the PDB file, but only do this once.
286  std::unique_ptr<PDBFile> file_up =
287  loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), m_allocator);
288 
289  if (!file_up) {
290  auto module_sp = m_objfile_sp->GetModule();
291  if (!module_sp)
292  return 0;
293  // See if any symbol file is specified through `--symfile` option.
294  FileSpec symfile = module_sp->GetSymbolFileFileSpec();
295  if (!symfile)
296  return 0;
297  file_up = loadPDBFile(symfile.GetPath(), m_allocator);
298  }
299 
300  if (!file_up)
301  return 0;
302 
303  auto expected_index = PdbIndex::create(std::move(file_up));
304  if (!expected_index) {
305  llvm::consumeError(expected_index.takeError());
306  return 0;
307  }
308  m_index = std::move(*expected_index);
309  }
310  if (!m_index)
311  return 0;
312 
313  // We don't especially have to be precise here. We only distinguish between
314  // stripped and not stripped.
315  abilities = kAllAbilities;
316 
317  if (m_index->dbi().isStripped())
318  abilities &= ~(Blocks | LocalVariables);
319  return abilities;
320 }
321 
323  m_obj_load_address = m_objfile_sp->GetBaseAddress().GetFileAddress();
324  m_index->SetLoadAddress(m_obj_load_address);
325  m_index->ParseSectionContribs();
326 
327  auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
329  if (auto err = ts_or_err.takeError()) {
331  std::move(err), "Failed to initialize");
332  } else {
333  ts_or_err->SetSymbolFile(this);
334  auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get());
335  lldbassert(clang);
336  m_ast = std::make_unique<PdbAstBuilder>(*m_objfile_sp, *m_index, *clang);
337  }
338 }
339 
341  const DbiModuleList &modules = m_index->dbi().modules();
342  uint32_t count = modules.getModuleCount();
343  if (count == 0)
344  return count;
345 
346  // The linker can inject an additional "dummy" compilation unit into the
347  // PDB. Ignore this special compile unit for our purposes, if it is there.
348  // It is always the last one.
349  DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
350  if (last.getModuleName() == "* Linker *")
351  --count;
352  return count;
353 }
354 
356  CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
357  CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
358 
359  if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) {
360  // This is a function. It must be global. Creating the Function entry for
361  // it automatically creates a block for it.
362  CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
363  return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false);
364  }
365 
366  lldbassert(sym.kind() == S_BLOCK32);
367 
368  // This is a block. Its parent is either a function or another block. In
369  // either case, its parent can be viewed as a block (e.g. a function contains
370  // 1 big block. So just get the parent block and add this block to it.
371  BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
372  cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
373  lldbassert(block.Parent != 0);
374  PdbCompilandSymId parent_id(block_id.modi, block.Parent);
375  Block &parent_block = GetOrCreateBlock(parent_id);
376  lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
377  BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
378  parent_block.AddChild(child_block);
379 
380  m_ast->GetOrCreateBlockDecl(block_id);
381 
382  m_blocks.insert({opaque_block_uid, child_block});
383  return *child_block;
384 }
385 
387  CompileUnit &comp_unit) {
388  const CompilandIndexItem *cci =
389  m_index->compilands().GetCompiland(func_id.modi);
390  lldbassert(cci);
391  CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
392 
393  lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);
395 
396  auto file_vm_addr = m_index->MakeVirtualAddress(sol.so);
397  if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
398  return nullptr;
399 
400  AddressRange func_range(file_vm_addr, sol.length,
401  comp_unit.GetModule()->GetSectionList());
402  if (!func_range.GetBaseAddress().IsValid())
403  return nullptr;
404 
405  ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
406  cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
407  if (proc.FunctionType == TypeIndex::None())
408  return nullptr;
409  TypeSP func_type = GetOrCreateType(proc.FunctionType);
410  if (!func_type)
411  return nullptr;
412 
413  PdbTypeSymId sig_id(proc.FunctionType, false);
414  Mangled mangled(proc.Name);
415  FunctionSP func_sp = std::make_shared<Function>(
416  &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
417  func_type.get(), func_range);
418 
419  comp_unit.AddFunction(func_sp);
420 
421  m_ast->GetOrCreateFunctionDecl(func_id);
422 
423  return func_sp;
424 }
425 
426 CompUnitSP
428  lldb::LanguageType lang =
429  cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())
431 
432  LazyBool optimized = eLazyBoolNo;
433  if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())
434  optimized = eLazyBoolYes;
435 
436  llvm::SmallString<64> source_file_name =
437  m_index->compilands().GetMainSourceFile(cci);
438  FileSpec fs(source_file_name);
439 
440  CompUnitSP cu_sp =
441  std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs,
442  toOpaqueUid(cci.m_id), lang, optimized);
443 
444  SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);
445  return cu_sp;
446 }
447 
449  const ModifierRecord &mr,
450  CompilerType ct) {
451  TpiStream &stream = m_index->tpi();
452 
453  std::string name;
454  if (mr.ModifiedType.isSimple())
455  name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind()));
456  else
457  name = computeTypeName(stream.typeCollection(), mr.ModifiedType);
458  Declaration decl;
459  lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);
460 
461  return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(name),
462  modified_type->GetByteSize(), nullptr,
465 }
466 
467 lldb::TypeSP
469  const llvm::codeview::PointerRecord &pr,
470  CompilerType ct) {
471  TypeSP pointee = GetOrCreateType(pr.ReferentType);
472  if (!pointee)
473  return nullptr;
474 
475  if (pr.isPointerToMember()) {
476  MemberPointerInfo mpi = pr.getMemberInfo();
477  GetOrCreateType(mpi.ContainingType);
478  }
479 
480  Declaration decl;
481  return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(),
482  pr.getSize(), nullptr, LLDB_INVALID_UID,
483  Type::eEncodingIsUID, decl, ct,
485 }
486 
487 lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti,
488  CompilerType ct) {
489  uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));
490  if (ti == TypeIndex::NullptrT()) {
491  Declaration decl;
492  return std::make_shared<Type>(
493  uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID,
495  }
496 
497  if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
498  TypeSP direct_sp = GetOrCreateType(ti.makeDirect());
499  uint32_t pointer_size = 0;
500  switch (ti.getSimpleMode()) {
501  case SimpleTypeMode::FarPointer32:
502  case SimpleTypeMode::NearPointer32:
503  pointer_size = 4;
504  break;
505  case SimpleTypeMode::NearPointer64:
506  pointer_size = 8;
507  break;
508  default:
509  // 128-bit and 16-bit pointers unsupported.
510  return nullptr;
511  }
512  Declaration decl;
513  return std::make_shared<Type>(
514  uid, this, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID,
516  }
517 
518  if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
519  return nullptr;
520 
521  size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind());
522  llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());
523 
524  Declaration decl;
525  return std::make_shared<Type>(uid, this, ConstString(type_name), size,
527  decl, ct, Type::ResolveState::Full);
528 }
529 
530 static std::string GetUnqualifiedTypeName(const TagRecord &record) {
531  if (!record.hasUniqueName()) {
532  MSVCUndecoratedNameParser parser(record.Name);
533  llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
534 
535  return std::string(specs.back().GetBaseName());
536  }
537 
538  llvm::ms_demangle::Demangler demangler;
539  StringView sv(record.UniqueName.begin(), record.UniqueName.size());
540  llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
541  if (demangler.Error)
542  return std::string(record.Name);
543 
544  llvm::ms_demangle::IdentifierNode *idn =
545  ttn->QualifiedName->getUnqualifiedIdentifier();
546  return idn->toString();
547 }
548 
549 lldb::TypeSP
551  const TagRecord &record,
552  size_t size, CompilerType ct) {
553 
554  std::string uname = GetUnqualifiedTypeName(record);
555 
556  // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
557  Declaration decl;
558  return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(uname),
559  size, nullptr, LLDB_INVALID_UID,
560  Type::eEncodingIsUID, decl, ct,
562 }
563 
565  const ClassRecord &cr,
566  CompilerType ct) {
567  return CreateClassStructUnion(type_id, cr, cr.getSize(), ct);
568 }
569 
571  const UnionRecord &ur,
572  CompilerType ct) {
573  return CreateClassStructUnion(type_id, ur, ur.getSize(), ct);
574 }
575 
577  const EnumRecord &er,
578  CompilerType ct) {
579  std::string uname = GetUnqualifiedTypeName(er);
580 
581  Declaration decl;
582  TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
583 
584  return std::make_shared<lldb_private::Type>(
585  toOpaqueUid(type_id), this, ConstString(uname),
586  underlying_type->GetByteSize(), nullptr, LLDB_INVALID_UID,
589 }
590 
592  const ArrayRecord &ar,
593  CompilerType ct) {
594  TypeSP element_type = GetOrCreateType(ar.ElementType);
595 
596  Declaration decl;
597  TypeSP array_sp = std::make_shared<lldb_private::Type>(
598  toOpaqueUid(type_id), this, ConstString(), ar.Size, nullptr,
601  array_sp->SetEncodingType(element_type.get());
602  return array_sp;
603 }
604 
605 
607  const MemberFunctionRecord &mfr,
608  CompilerType ct) {
609  Declaration decl;
610  return std::make_shared<lldb_private::Type>(
611  toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID,
614 }
615 
617  const ProcedureRecord &pr,
618  CompilerType ct) {
619  Declaration decl;
620  return std::make_shared<lldb_private::Type>(
621  toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID,
624 }
625 
627  if (type_id.index.isSimple())
628  return CreateSimpleType(type_id.index, ct);
629 
630  TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi();
631  CVType cvt = stream.getType(type_id.index);
632 
633  if (cvt.kind() == LF_MODIFIER) {
634  ModifierRecord modifier;
635  llvm::cantFail(
636  TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
637  return CreateModifierType(type_id, modifier, ct);
638  }
639 
640  if (cvt.kind() == LF_POINTER) {
641  PointerRecord pointer;
642  llvm::cantFail(
643  TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
644  return CreatePointerType(type_id, pointer, ct);
645  }
646 
647  if (IsClassRecord(cvt.kind())) {
648  ClassRecord cr;
649  llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
650  return CreateTagType(type_id, cr, ct);
651  }
652 
653  if (cvt.kind() == LF_ENUM) {
654  EnumRecord er;
655  llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
656  return CreateTagType(type_id, er, ct);
657  }
658 
659  if (cvt.kind() == LF_UNION) {
660  UnionRecord ur;
661  llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
662  return CreateTagType(type_id, ur, ct);
663  }
664 
665  if (cvt.kind() == LF_ARRAY) {
666  ArrayRecord ar;
667  llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
668  return CreateArrayType(type_id, ar, ct);
669  }
670 
671  if (cvt.kind() == LF_PROCEDURE) {
672  ProcedureRecord pr;
673  llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
674  return CreateProcedureType(type_id, pr, ct);
675  }
676  if (cvt.kind() == LF_MFUNCTION) {
677  MemberFunctionRecord mfr;
678  llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
679  return CreateFunctionType(type_id, mfr, ct);
680  }
681 
682  return nullptr;
683 }
684 
686  // If they search for a UDT which is a forward ref, try and resolve the full
687  // decl and just map the forward ref uid to the full decl record.
688  llvm::Optional<PdbTypeSymId> full_decl_uid;
689  if (IsForwardRefUdt(type_id, m_index->tpi())) {
690  auto expected_full_ti =
691  m_index->tpi().findFullDeclForForwardRef(type_id.index);
692  if (!expected_full_ti)
693  llvm::consumeError(expected_full_ti.takeError());
694  else if (*expected_full_ti != type_id.index) {
695  full_decl_uid = PdbTypeSymId(*expected_full_ti, false);
696 
697  // It's possible that a lookup would occur for the full decl causing it
698  // to be cached, then a second lookup would occur for the forward decl.
699  // We don't want to create a second full decl, so make sure the full
700  // decl hasn't already been cached.
701  auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid));
702  if (full_iter != m_types.end()) {
703  TypeSP result = full_iter->second;
704  // Map the forward decl to the TypeSP for the full decl so we can take
705  // the fast path next time.
706  m_types[toOpaqueUid(type_id)] = result;
707  return result;
708  }
709  }
710  }
711 
712  PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
713 
714  clang::QualType qt = m_ast->GetOrCreateType(best_decl_id);
715 
716  TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt));
717  if (!result)
718  return nullptr;
719 
720  uint64_t best_uid = toOpaqueUid(best_decl_id);
721  m_types[best_uid] = result;
722  // If we had both a forward decl and a full decl, make both point to the new
723  // type.
724  if (full_decl_uid)
725  m_types[toOpaqueUid(type_id)] = result;
726 
727  return result;
728 }
729 
731  // We can't use try_emplace / overwrite here because the process of creating
732  // a type could create nested types, which could invalidate iterators. So
733  // we have to do a 2-phase lookup / insert.
734  auto iter = m_types.find(toOpaqueUid(type_id));
735  if (iter != m_types.end())
736  return iter->second;
737 
738  TypeSP type = CreateAndCacheType(type_id);
739  if (type)
740  GetTypeList().Insert(type);
741  return type;
742 }
743 
745  CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
746  if (sym.kind() == S_CONSTANT)
747  return CreateConstantSymbol(var_id, sym);
748 
750  TypeIndex ti;
751  llvm::StringRef name;
752  lldb::addr_t addr = 0;
753  uint16_t section = 0;
754  uint32_t offset = 0;
755  bool is_external = false;
756  switch (sym.kind()) {
757  case S_GDATA32:
758  is_external = true;
759  LLVM_FALLTHROUGH;
760  case S_LDATA32: {
761  DataSym ds(sym.kind());
762  llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds));
763  ti = ds.Type;
764  scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal
766  name = ds.Name;
767  section = ds.Segment;
768  offset = ds.DataOffset;
769  addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
770  break;
771  }
772  case S_GTHREAD32:
773  is_external = true;
774  LLVM_FALLTHROUGH;
775  case S_LTHREAD32: {
776  ThreadLocalDataSym tlds(sym.kind());
777  llvm::cantFail(
778  SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds));
779  ti = tlds.Type;
780  name = tlds.Name;
781  section = tlds.Segment;
782  offset = tlds.DataOffset;
783  addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
785  break;
786  }
787  default:
788  llvm_unreachable("unreachable!");
789  }
790 
791  CompUnitSP comp_unit;
792  llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);
793  if (modi) {
794  CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);
795  comp_unit = GetOrCreateCompileUnit(cci);
796  }
797 
798  Declaration decl;
799  PdbTypeSymId tid(ti, false);
800  SymbolFileTypeSP type_sp =
801  std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
802  Variable::RangeList ranges;
803 
804  m_ast->GetOrCreateVariableDecl(var_id);
805 
807  section, offset, GetObjectFile()->GetModule());
808 
809  std::string global_name("::");
810  global_name += name;
811  VariableSP var_sp = std::make_shared<Variable>(
812  toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
813  scope, comp_unit.get(), ranges, &decl, location, is_external, false,
814  false);
815  var_sp->SetLocationIsConstantValueData(false);
816 
817  return var_sp;
818 }
819 
820 lldb::VariableSP
822  const CVSymbol &cvs) {
823  TpiStream &tpi = m_index->tpi();
824  ConstantSym constant(cvs.kind());
825 
826  llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant));
827  std::string global_name("::");
828  global_name += constant.Name;
829  PdbTypeSymId tid(constant.Type, false);
830  SymbolFileTypeSP type_sp =
831  std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
832 
833  Declaration decl;
834  Variable::RangeList ranges;
835  ModuleSP module = GetObjectFile()->GetModule();
837  constant.Type, tpi, constant.Value, module);
838 
839  VariableSP var_sp = std::make_shared<Variable>(
840  toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
841  type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
842  false, false, false);
843  var_sp->SetLocationIsConstantValueData(true);
844  return var_sp;
845 }
846 
847 VariableSP
849  auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr);
850  if (emplace_result.second)
851  emplace_result.first->second = CreateGlobalVariable(var_id);
852 
853  return emplace_result.first->second;
854 }
855 
856 lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) {
857  return GetOrCreateType(PdbTypeSymId(ti, false));
858 }
859 
861  CompileUnit &comp_unit) {
862  auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);
863  if (emplace_result.second)
864  emplace_result.first->second = CreateFunction(func_id, comp_unit);
865 
866  return emplace_result.first->second;
867 }
868 
869 CompUnitSP
871 
872  auto emplace_result =
873  m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr);
874  if (emplace_result.second)
875  emplace_result.first->second = CreateCompileUnit(cci);
876 
877  lldbassert(emplace_result.first->second);
878  return emplace_result.first->second;
879 }
880 
882  auto iter = m_blocks.find(toOpaqueUid(block_id));
883  if (iter != m_blocks.end())
884  return *iter->second;
885 
886  return CreateBlock(block_id);
887 }
888 
891  clang::DeclContext *context = m_ast->FromCompilerDeclContext(decl_ctx);
892  if (!context)
893  return;
894  m_ast->ParseDeclsForContext(*context);
895 }
896 
898  if (index >= GetNumCompileUnits())
899  return CompUnitSP();
900  lldbassert(index < UINT16_MAX);
901  if (index >= UINT16_MAX)
902  return nullptr;
903 
904  CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);
905 
906  return GetOrCreateCompileUnit(item);
907 }
908 
910  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
911  PdbSymUid uid(comp_unit.GetID());
912  lldbassert(uid.kind() == PdbSymUidKind::Compiland);
913 
914  CompilandIndexItem *item =
915  m_index->compilands().GetCompiland(uid.asCompiland().modi);
916  lldbassert(item);
917  if (!item->m_compile_opts)
919 
920  return TranslateLanguage(item->m_compile_opts->getLanguage());
921 }
922 
923 void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
924 
926  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
927  PdbSymUid uid{comp_unit.GetID()};
928  lldbassert(uid.kind() == PdbSymUidKind::Compiland);
929  uint16_t modi = uid.asCompiland().modi;
930  CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);
931 
932  size_t count = comp_unit.GetNumFunctions();
933  const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
934  for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
935  if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
936  continue;
937 
938  PdbCompilandSymId sym_id{modi, iter.offset()};
939 
940  FunctionSP func = GetOrCreateFunction(sym_id, comp_unit);
941  }
942 
943  size_t new_count = comp_unit.GetNumFunctions();
944  lldbassert(new_count >= count);
945  return new_count - count;
946 }
947 
948 static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
949  // If any of these flags are set, we need to resolve the compile unit.
950  uint32_t flags = eSymbolContextCompUnit;
951  flags |= eSymbolContextVariable;
952  flags |= eSymbolContextFunction;
953  flags |= eSymbolContextBlock;
954  flags |= eSymbolContextLineEntry;
955  return (resolve_scope & flags) != 0;
956 }
957 
959  const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
960  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
961  uint32_t resolved_flags = 0;
962  lldb::addr_t file_addr = addr.GetFileAddress();
963 
964  if (NeedsResolvedCompileUnit(resolve_scope)) {
965  llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);
966  if (!modi)
967  return 0;
968  CompilandIndexItem *cci = m_index->compilands().GetCompiland(*modi);
969  if (!cci)
970  return 0;
971 
972  sc.comp_unit = GetOrCreateCompileUnit(*cci).get();
973  resolved_flags |= eSymbolContextCompUnit;
974  }
975 
976  if (resolve_scope & eSymbolContextFunction ||
977  resolve_scope & eSymbolContextBlock) {
978  lldbassert(sc.comp_unit);
979  std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
980  // Search the matches in reverse. This way if there are multiple matches
981  // (for example we are 3 levels deep in a nested scope) it will find the
982  // innermost one first.
983  for (const auto &match : llvm::reverse(matches)) {
984  if (match.uid.kind() != PdbSymUidKind::CompilandSym)
985  continue;
986 
987  PdbCompilandSymId csid = match.uid.asCompilandSym();
988  CVSymbol cvs = m_index->ReadSymbolRecord(csid);
989  PDB_SymType type = CVSymToPDBSym(cvs.kind());
990  if (type != PDB_SymType::Function && type != PDB_SymType::Block)
991  continue;
992  if (type == PDB_SymType::Function) {
993  sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
994  sc.block = sc.GetFunctionBlock();
995  }
996 
997  if (type == PDB_SymType::Block) {
998  sc.block = &GetOrCreateBlock(csid);
1000  }
1001  resolved_flags |= eSymbolContextFunction;
1002  resolved_flags |= eSymbolContextBlock;
1003  break;
1004  }
1005  }
1006 
1007  if (resolve_scope & eSymbolContextLineEntry) {
1008  lldbassert(sc.comp_unit);
1009  if (auto *line_table = sc.comp_unit->GetLineTable()) {
1010  if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
1011  resolved_flags |= eSymbolContextLineEntry;
1012  }
1013  }
1014 
1015  return resolved_flags;
1016 }
1017 
1019  const FileSpec &file_spec, uint32_t line, bool check_inlines,
1020  lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
1021  return 0;
1022 }
1023 
1024 static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence,
1025  const CompilandIndexItem &cci,
1026  lldb::addr_t base_addr,
1027  uint32_t file_number,
1028  const LineFragmentHeader &block,
1029  const LineNumberEntry &cur) {
1030  LineInfo cur_info(cur.Flags);
1031 
1032  if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1033  return;
1034 
1035  uint64_t addr = base_addr + cur.Offset;
1036 
1037  bool is_statement = cur_info.isStatement();
1038  bool is_prologue = IsFunctionPrologue(cci, addr);
1039  bool is_epilogue = IsFunctionEpilogue(cci, addr);
1040 
1041  uint32_t lno = cur_info.getStartLine();
1042 
1043  table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number,
1044  is_statement, false, is_prologue, is_epilogue,
1045  false);
1046 }
1047 
1049  const LineFragmentHeader &block,
1050  lldb::addr_t base_addr, uint32_t file_number,
1051  uint32_t last_line,
1052  std::unique_ptr<LineSequence> seq) {
1053  // The end is always a terminal entry, so insert it regardless.
1054  table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize,
1055  last_line, 0, file_number, false, false,
1056  false, false, true);
1057  table.InsertSequence(seq.release());
1058 }
1059 
1061  // Unfortunately LLDB is set up to parse the entire compile unit line table
1062  // all at once, even if all it really needs is line info for a specific
1063  // function. In the future it would be nice if it could set the sc.m_function
1064  // member, and we could only get the line info for the function in question.
1065  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1066  PdbSymUid cu_id(comp_unit.GetID());
1067  lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
1068  CompilandIndexItem *cci =
1069  m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
1070  lldbassert(cci);
1071  auto line_table = std::make_unique<LineTable>(&comp_unit);
1072 
1073  // This is basically a copy of the .debug$S subsections from all original COFF
1074  // object files merged together with address relocations applied. We are
1075  // looking for all DEBUG_S_LINES subsections.
1076  for (const DebugSubsectionRecord &dssr :
1077  cci->m_debug_stream.getSubsectionsArray()) {
1078  if (dssr.kind() != DebugSubsectionKind::Lines)
1079  continue;
1080 
1081  DebugLinesSubsectionRef lines;
1082  llvm::BinaryStreamReader reader(dssr.getRecordData());
1083  if (auto EC = lines.initialize(reader)) {
1084  llvm::consumeError(std::move(EC));
1085  return false;
1086  }
1087 
1088  const LineFragmentHeader *lfh = lines.header();
1089  uint64_t virtual_addr =
1090  m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1091 
1092  const auto &checksums = cci->m_strings.checksums().getArray();
1093  const auto &strings = cci->m_strings.strings();
1094  for (const LineColumnEntry &group : lines) {
1095  // Indices in this structure are actually offsets of records in the
1096  // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index
1097  // into the global PDB string table.
1098  auto iter = checksums.at(group.NameIndex);
1099  if (iter == checksums.end())
1100  continue;
1101 
1102  llvm::Expected<llvm::StringRef> efn =
1103  strings.getString(iter->FileNameOffset);
1104  if (!efn) {
1105  llvm::consumeError(efn.takeError());
1106  continue;
1107  }
1108 
1109  // LLDB wants the index of the file in the list of support files.
1110  auto fn_iter = llvm::find(cci->m_file_list, *efn);
1111  lldbassert(fn_iter != cci->m_file_list.end());
1112  uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter);
1113 
1114  std::unique_ptr<LineSequence> sequence(
1115  line_table->CreateLineSequenceContainer());
1116  lldbassert(!group.LineNumbers.empty());
1117 
1118  for (const LineNumberEntry &entry : group.LineNumbers) {
1119  AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr,
1120  file_index, *lfh, entry);
1121  }
1122  LineInfo last_line(group.LineNumbers.back().Flags);
1123  TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index,
1124  last_line.getEndLine(), std::move(sequence));
1125  }
1126  }
1127 
1128  if (line_table->GetSize() == 0)
1129  return false;
1130 
1131  comp_unit.SetLineTable(line_table.release());
1132  return true;
1133 }
1134 
1136  // PDB doesn't contain information about macros
1137  return false;
1138 }
1139 
1141  FileSpecList &support_files) {
1142  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1143  PdbSymUid cu_id(comp_unit.GetID());
1144  lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
1145  CompilandIndexItem *cci =
1146  m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
1147  lldbassert(cci);
1148 
1149  for (llvm::StringRef f : cci->m_file_list) {
1150  FileSpec::Style style =
1151  f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1152  FileSpec spec(f, style);
1153  support_files.Append(spec);
1154  }
1155  return true;
1156 }
1157 
1159  const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1160  // PDB does not yet support module debug info
1161  return false;
1162 }
1163 
1165  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1166  GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym());
1167  // FIXME: Parse child blocks
1168  return 1;
1169 }
1170 
1172 
1174  ConstString name, const CompilerDeclContext &parent_decl_ctx,
1175  uint32_t max_matches, VariableList &variables) {
1176  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1177  using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
1178 
1179  std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
1180  name.GetStringRef(), m_index->symrecords());
1181  for (const SymbolAndOffset &result : results) {
1182  VariableSP var;
1183  switch (result.second.kind()) {
1184  case SymbolKind::S_GDATA32:
1185  case SymbolKind::S_LDATA32:
1186  case SymbolKind::S_GTHREAD32:
1187  case SymbolKind::S_LTHREAD32:
1188  case SymbolKind::S_CONSTANT: {
1189  PdbGlobalSymId global(result.first, false);
1190  var = GetOrCreateGlobalVariable(global);
1191  variables.AddVariable(var);
1192  break;
1193  }
1194  default:
1195  continue;
1196  }
1197  }
1198 }
1199 
1201  ConstString name, const CompilerDeclContext &parent_decl_ctx,
1202  FunctionNameType name_type_mask, bool include_inlines,
1203  SymbolContextList &sc_list) {
1204  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1205  // For now we only support lookup by method name.
1206  if (!(name_type_mask & eFunctionNameTypeMethod))
1207  return;
1208 
1209  using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
1210 
1211  std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName(
1212  name.GetStringRef(), m_index->symrecords());
1213  for (const SymbolAndOffset &match : matches) {
1214  if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
1215  continue;
1216  ProcRefSym proc(match.second.kind());
1217  cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc));
1218 
1219  if (!IsValidRecord(proc))
1220  continue;
1221 
1222  CompilandIndexItem &cci =
1223  m_index->compilands().GetOrCreateCompiland(proc.modi());
1224  SymbolContext sc;
1225 
1226  sc.comp_unit = GetOrCreateCompileUnit(cci).get();
1227  PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
1228  sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
1229 
1230  sc_list.Append(sc);
1231  }
1232 }
1233 
1235  bool include_inlines,
1236  SymbolContextList &sc_list) {}
1237 
1239  ConstString name, const CompilerDeclContext &parent_decl_ctx,
1240  uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
1241  TypeMap &types) {
1242  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1243  if (!name)
1244  return;
1245 
1246  searched_symbol_files.clear();
1247  searched_symbol_files.insert(this);
1248 
1249  // There is an assumption 'name' is not a regex
1250  FindTypesByName(name.GetStringRef(), max_matches, types);
1251 }
1252 
1254  llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
1255  llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {}
1256 
1257 void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
1258  uint32_t max_matches,
1259  TypeMap &types) {
1260 
1261  std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
1262  if (max_matches > 0 && max_matches < matches.size())
1263  matches.resize(max_matches);
1264 
1265  for (TypeIndex ti : matches) {
1266  TypeSP type = GetOrCreateType(ti);
1267  if (!type)
1268  continue;
1269 
1270  types.Insert(type);
1271  }
1272 }
1273 
1275  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1276  // Only do the full type scan the first time.
1278  return 0;
1279 
1280  const size_t old_count = GetTypeList().GetSize();
1281  LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
1282 
1283  // First process the entire TPI stream.
1284  for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
1285  TypeSP type = GetOrCreateType(*ti);
1286  if (type)
1287  (void)type->GetFullCompilerType();
1288  }
1289 
1290  // Next look for S_UDT records in the globals stream.
1291  for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
1292  PdbGlobalSymId global{gid, false};
1293  CVSymbol sym = m_index->ReadSymbolRecord(global);
1294  if (sym.kind() != S_UDT)
1295  continue;
1296 
1297  UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
1298  bool is_typedef = true;
1299  if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {
1300  CVType cvt = m_index->tpi().getType(udt.Type);
1301  llvm::StringRef name = CVTagRecord::create(cvt).name();
1302  if (name == udt.Name)
1303  is_typedef = false;
1304  }
1305 
1306  if (is_typedef)
1307  GetOrCreateTypedef(global);
1308  }
1309 
1310  const size_t new_count = GetTypeList().GetSize();
1311 
1312  m_done_full_type_scan = true;
1313 
1314  return new_count - old_count;
1315 }
1316 
1317 size_t
1319  VariableList &variables) {
1320  PdbSymUid sym_uid(comp_unit.GetID());
1321  lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);
1322  return 0;
1323 }
1324 
1326  PdbCompilandSymId var_id,
1327  bool is_param) {
1328  ModuleSP module = GetObjectFile()->GetModule();
1329  Block &block = GetOrCreateBlock(scope_id);
1330  VariableInfo var_info =
1331  GetVariableLocationInfo(*m_index, var_id, block, module);
1332  if (!var_info.location || !var_info.ranges)
1333  return nullptr;
1334 
1335  CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
1336  CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
1337  TypeSP type_sp = GetOrCreateType(var_info.type);
1338  std::string name = var_info.name.str();
1339  Declaration decl;
1340  SymbolFileTypeSP sftype =
1341  std::make_shared<SymbolFileType>(*this, type_sp->GetID());
1342 
1343  ValueType var_scope =
1345  VariableSP var_sp = std::make_shared<Variable>(
1346  toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
1347  comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false,
1348  false, false);
1349 
1350  if (!is_param)
1351  m_ast->GetOrCreateVariableDecl(scope_id, var_id);
1352 
1353  m_local_variables[toOpaqueUid(var_id)] = var_sp;
1354  return var_sp;
1355 }
1356 
1358  PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
1359  auto iter = m_local_variables.find(toOpaqueUid(var_id));
1360  if (iter != m_local_variables.end())
1361  return iter->second;
1362 
1363  return CreateLocalVariable(scope_id, var_id, is_param);
1364 }
1365 
1367  CVSymbol sym = m_index->ReadSymbolRecord(id);
1368  lldbassert(sym.kind() == SymbolKind::S_UDT);
1369 
1370  UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
1371 
1372  TypeSP target_type = GetOrCreateType(udt.Type);
1373 
1374  (void)m_ast->GetOrCreateTypedefDecl(id);
1375 
1376  Declaration decl;
1377  return std::make_shared<lldb_private::Type>(
1378  toOpaqueUid(id), this, ConstString(udt.Name), target_type->GetByteSize(),
1379  nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID,
1380  decl, target_type->GetForwardCompilerType(),
1382 }
1383 
1385  auto iter = m_types.find(toOpaqueUid(id));
1386  if (iter != m_types.end())
1387  return iter->second;
1388 
1389  return CreateTypedef(id);
1390 }
1391 
1393  Block &block = GetOrCreateBlock(block_id);
1394 
1395  size_t count = 0;
1396 
1397  CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
1398  CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
1399  uint32_t params_remaining = 0;
1400  switch (sym.kind()) {
1401  case S_GPROC32:
1402  case S_LPROC32: {
1403  ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));
1404  cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));
1405  CVType signature = m_index->tpi().getType(proc.FunctionType);
1406  ProcedureRecord sig;
1407  cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(signature, sig));
1408  params_remaining = sig.getParameterCount();
1409  break;
1410  }
1411  case S_BLOCK32:
1412  break;
1413  default:
1414  lldbassert(false && "Symbol is not a block!");
1415  return 0;
1416  }
1417 
1418  VariableListSP variables = block.GetBlockVariableList(false);
1419  if (!variables) {
1420  variables = std::make_shared<VariableList>();
1421  block.SetVariableList(variables);
1422  }
1423 
1424  CVSymbolArray syms = limitSymbolArrayToScope(
1425  cii->m_debug_stream.getSymbolArray(), block_id.offset);
1426 
1427  // Skip the first record since it's a PROC32 or BLOCK32, and there's
1428  // no point examining it since we know it's not a local variable.
1429  syms.drop_front();
1430  auto iter = syms.begin();
1431  auto end = syms.end();
1432 
1433  while (iter != end) {
1434  uint32_t record_offset = iter.offset();
1435  CVSymbol variable_cvs = *iter;
1436  PdbCompilandSymId child_sym_id(block_id.modi, record_offset);
1437  ++iter;
1438 
1439  // If this is a block, recurse into its children and then skip it.
1440  if (variable_cvs.kind() == S_BLOCK32) {
1441  uint32_t block_end = getScopeEndOffset(variable_cvs);
1442  count += ParseVariablesForBlock(child_sym_id);
1443  iter = syms.at(block_end);
1444  continue;
1445  }
1446 
1447  bool is_param = params_remaining > 0;
1448  VariableSP variable;
1449  switch (variable_cvs.kind()) {
1450  case S_REGREL32:
1451  case S_REGISTER:
1452  case S_LOCAL:
1453  variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
1454  if (is_param)
1455  --params_remaining;
1456  if (variable)
1457  variables->AddVariableIfUnique(variable);
1458  break;
1459  default:
1460  break;
1461  }
1462  }
1463 
1464  // Pass false for set_children, since we call this recursively so that the
1465  // children will call this for themselves.
1466  block.SetDidParseVariables(true, false);
1467 
1468  return count;
1469 }
1470 
1472  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1473  lldbassert(sc.function || sc.comp_unit);
1474 
1475  VariableListSP variables;
1476  if (sc.block) {
1477  PdbSymUid block_id(sc.block->GetID());
1478 
1479  size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
1480  return count;
1481  }
1482 
1483  if (sc.function) {
1484  PdbSymUid block_id(sc.function->GetID());
1485 
1486  size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
1487  return count;
1488  }
1489 
1490  if (sc.comp_unit) {
1491  variables = sc.comp_unit->GetVariableList(false);
1492  if (!variables) {
1493  variables = std::make_shared<VariableList>();
1494  sc.comp_unit->SetVariableList(variables);
1495  }
1496  return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);
1497  }
1498 
1499  llvm_unreachable("Unreachable!");
1500 }
1501 
1503  if (auto decl = m_ast->GetOrCreateDeclForUid(uid))
1504  return decl.getValue();
1505  else
1506  return CompilerDecl();
1507 }
1508 
1511  clang::DeclContext *context =
1512  m_ast->GetOrCreateDeclContextForUid(PdbSymUid(uid));
1513  if (!context)
1514  return {};
1515 
1516  return m_ast->ToCompilerDeclContext(*context);
1517 }
1518 
1521  clang::DeclContext *context = m_ast->GetParentDeclContext(PdbSymUid(uid));
1522  return m_ast->ToCompilerDeclContext(*context);
1523 }
1524 
1526  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1527  auto iter = m_types.find(type_uid);
1528  // lldb should not be passing us non-sensical type uids. the only way it
1529  // could have a type uid in the first place is if we handed it out, in which
1530  // case we should know about the type. However, that doesn't mean we've
1531  // instantiated it yet. We can vend out a UID for a future type. So if the
1532  // type doesn't exist, let's instantiate it now.
1533  if (iter != m_types.end())
1534  return &*iter->second;
1535 
1536  PdbSymUid uid(type_uid);
1537  lldbassert(uid.kind() == PdbSymUidKind::Type);
1538  PdbTypeSymId type_id = uid.asTypeSym();
1539  if (type_id.index.isNoneType())
1540  return nullptr;
1541 
1542  TypeSP type_sp = CreateAndCacheType(type_id);
1543  return &*type_sp;
1544 }
1545 
1546 llvm::Optional<SymbolFile::ArrayInfo>
1548  lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
1549  return llvm::None;
1550 }
1551 
1552 
1554  clang::QualType qt =
1555  clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType());
1556 
1557  return m_ast->CompleteType(qt);
1558 }
1559 
1561  TypeClass type_mask,
1562  lldb_private::TypeList &type_list) {}
1563 
1566  const CompilerDeclContext &parent_decl_ctx) {
1567  return {};
1568 }
1569 
1570 llvm::Expected<TypeSystem &>
1572  auto type_system_or_err =
1573  m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
1574  if (type_system_or_err) {
1575  type_system_or_err->SetSymbolFile(this);
1576  }
1577  return type_system_or_err;
1578 }
1579 
1581  static ConstString g_name("pdb");
1582  return g_name;
1583 }
1584 
bool IsTagRecord(llvm::codeview::CVType cvt)
Definition: PdbUtil.cpp:370
A class to manage flag bits.
Definition: Debugger.h:70
void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, llvm::DenseSet< SymbolFile *> &searched_symbol_files, TypeMap &types) override
Represents a single compile unit.
size_t ParseBlocksRecursive(Function &func) override
SegmentOffsetLength GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym)
static void TerminateLineSequence(LineTable &table, const LineFragmentHeader &block, lldb::addr_t base_addr, uint32_t file_number, uint32_t last_line, std::unique_ptr< LineSequence > seq)
Defines a list of symbol context objects.
llvm::codeview::TypeIndex type
Definition: PdbUtil.h:105
A class that represents a running process on the host machine.
lldb::TypeSP CreateTagType(PdbTypeSymId type_id, const llvm::codeview::ClassRecord &cr, CompilerType ct)
static llvm::Expected< std::unique_ptr< PdbIndex > > create(std::unique_ptr< llvm::pdb::PDBFile >)
Definition: PdbIndex.cpp:42
lldb::TypeSP CreatePointerType(PdbTypeSymId type_id, const llvm::codeview::PointerRecord &pr, CompilerType ct)
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
Represents a generic declaration context in a program.
llvm::pdb::ModuleDebugStreamRef m_debug_stream
VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block &block, lldb::ModuleSP module)
Definition: PdbUtil.cpp:580
lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id, const llvm::codeview::CVSymbol &cvs)
#define lldbassert(x)
Definition: LLDBAssert.h:15
void AddVariable(const lldb::VariableSP &var_sp)
void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp)
Definition: SymbolFile.cpp:178
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit, VariableList &variables)
llvm::DenseMap< lldb::user_id_t, lldb::TypeSP > m_types
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it...
llvm::Optional< llvm::codeview::Compile3Sym > m_compile_opts
llvm::codeview::TypeIndex index
Definition: PdbSymUid.h:76
virtual std::recursive_mutex & GetModuleMutex() const
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
Definition: SymbolFile.cpp:33
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
static std::string GetUnqualifiedTypeName(const TagRecord &record)
lldb::ObjectFileSP m_objfile_sp
Definition: SymbolFile.h:309
void AddChild(const lldb::BlockSP &child_block_sp)
Add a child to this object.
Definition: Block.cpp:374
lldb::TypeSP CreateTypedef(PdbGlobalSymId id)
lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param)
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47
A file utility class.
Definition: FileSpec.h:56
A class that describes a function.
Definition: Function.h:390
Block & CreateBlock(PdbCompilandSymId block_id)
static bool IsFunctionEpilogue(const CompilandIndexItem &cci, lldb::addr_t addr)
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:290
CompileUnit * comp_unit
The CompileUnit for a given query.
lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id, CompileUnit &comp_unit)
bool CompleteType(CompilerType &compiler_type) override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool IsValidRecord(const RecordT &sym)
Definition: PdbUtil.h:120
CompilerDeclContext FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx) override
lldb::VariableListSP GetBlockVariableList(bool can_create)
Get the variable list for this block only.
Definition: Block.cpp:388
size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition: TypeSystem.h:40
static void AppendLineEntryToSequence(LineSequence *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:69
Type * ResolveTypeUID(lldb::user_id_t type_uid) override
#define LLDB_INVALID_UID
Definition: lldb-defines.h:91
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
Definition: Block.h:331
A class that describes a single lexical block.
Definition: Block.h:41
uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override
bool IsForwardRefUdt(llvm::codeview::CVType cvt)
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:265
static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind)
size_t ParseVariablesForBlock(PdbCompilandSymId block_id)
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
void Insert(const lldb::TypeSP &type)
Definition: TypeMap.cpp:27
An abstract base class for files.
Definition: File.h:34
A class that describes a compilation unit.
Definition: CompileUnit.h:37
uint32_t GetSize() const
Definition: TypeList.cpp:60
lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override
static bool IsClassRecord(TypeLeafKind kind)
lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct)
void SetLineTable(LineTable *line_table)
Set the line table for the compile unit.
void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override
#define LIBLLDB_LOG_SYMBOLS
Definition: Logging.h:34
Function * function
The Function for a given query.
llvm::Optional< DWARFExpression > location
Definition: PdbUtil.h:106
lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci)
static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence, const CompilandIndexItem &cci, lldb::addr_t base_addr, uint32_t file_number, const LineFragmentHeader &block, const LineNumberEntry &cur)
lldb::opaque_compiler_type_t GetOpaqueQualType() const
Definition: CompilerType.h:168
lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id, const llvm::codeview::ProcedureRecord &pr, CompilerType ct)
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
Block * GetFunctionBlock()
Find a block that defines the function represented by this symbol context.
uint64_t user_id_t
Definition: lldb-types.h:84
LanguageType
Programming language type.
lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id)
lldb::TypeSP CreateFunctionType(PdbTypeSymId type_id, const llvm::codeview::MemberFunctionRecord &pr, CompilerType ct)
void FindFunctions(ConstString name, const CompilerDeclContext &parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) override
CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override
llvm::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 Insert(const lldb::TypeSP &type)
Definition: TypeList.cpp:27
lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id, const llvm::codeview::TagRecord &record, size_t size, CompilerType ct)
lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id)
void ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override
lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id)
A line table class.
Definition: LineTable.h:37
static bool NeedsResolvedCompileUnit(uint32_t resolve_scope)
bool ParseImportedModules(const SymbolContext &sc, std::vector< lldb_private::SourceModule > &imported_modules) override
Block & GetOrCreateBlock(PdbCompilandSymId block_id)
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:232
lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti, CompilerType ct)
llvm::Optional< Variable::RangeList > ranges
Definition: PdbUtil.h:107
static char ID
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param)
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
This type is pointer to a type whose UID is m_encoding_uid.
Definition: Type.h:76
llvm::DenseMap< lldb::user_id_t, lldb::BlockSP > m_blocks
A section + offset based address class.
Definition: Address.h:59
llvm::DenseMap< lldb::user_id_t, lldb::CompUnitSP > m_compilands
static std::unique_ptr< PDBFile > loadPDBFile(std::string PdbPath, llvm::BumpPtrAllocator &Allocator)
function argument variables
LineTable * GetLineTable()
Get the line table for the compile unit.
static std::unique_ptr< PDBFile > loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator)
size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override
void AddSymbols(Symtab &symtab) override
llvm::DenseMap< lldb::user_id_t, lldb::VariableSP > m_global_vars
DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, lldb::ModuleSP module)
lldb::TypeSP CreateArrayType(PdbTypeSymId type_id, const llvm::codeview::ArrayRecord &ar, CompilerType ct)
llvm::sys::path::Style Style
Definition: FileSpec.h:58
bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override
size_t ParseVariablesForContext(const SymbolContext &sc) override
function local variables
void FindTypesByName(llvm::StringRef name, uint32_t max_matches, TypeMap &types)
This type is the type whose UID is m_encoding_uid.
Definition: Type.h:69
uint64_t addr_t
Definition: lldb-types.h:83
DWARFExpression MakeConstantLocationExpression(llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, const llvm::APSInt &constant, lldb::ModuleSP module)
void SetDidParseVariables(bool b, bool set_children)
Definition: Block.cpp:485
A uniqued constant string class.
Definition: ConstString.h:40
Unknown or invalid language value.
An abstract base class used during symbol table creation.
Definition: LineTable.h:23
size_t GetNumFunctions() const
Returns the number of functions in this compile unit.
Definition: CompileUnit.h:404
CompilerDecl GetDeclForUID(lldb::user_id_t uid) override
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
Non-standardized C, such as K&R.
LineEntry line_entry
The LineEntry for a given query.
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:62
Definition: SBAddress.h:15
thread local storage variable
Represents a generic type in a programming language.
Definition: CompilerType.h:33
llvm::DenseMap< lldb::user_id_t, lldb::VariableSP > m_local_variables
ObjectFile * GetObjectFile()
Definition: SymbolFile.h:265
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, FileSpecList &support_files) override
virtual TypeList & GetTypeList()
Definition: SymbolFile.h:305
llvm::StringRef name() const
Definition: PdbUtil.h:68
void FindGlobalVariables(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override
static bool IsFunctionPrologue(const CompilandIndexItem &cci, lldb::addr_t addr)
void InsertSequence(LineSequence *sequence)
Definition: LineTable.cpp:105
lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id)
Function * CalculateSymbolContextFunction() override
Definition: Block.cpp:143
llvm::ArrayRef< MSVCUndecoratedNameSpecifier > GetSpecifiers() const
static CVTagRecord create(llvm::codeview::CVType type)
Definition: PdbUtil.cpp:51
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
A class that describes the declaration location of a lldb object.
Definition: Declaration.h:24
std::unique_ptr< PdbAstBuilder > m_ast
lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id, CompileUnit &comp_unit)
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
Block * block
The Block for a given query.
A section + offset based address range class.
Definition: AddressRange.h:25
lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id)
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
void InitializeObject() override
Initialize the SymbolFile object.
lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci)
lldb::TypeSP CreateModifierType(PdbTypeSymId type_id, const llvm::codeview::ModifierRecord &mr, CompilerType ct)
llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind)
uint64_t toOpaqueUid(const T &cid)
Definition: PdbSymUid.h:114
Represents a generic declaration such as a function declaration.
Definition: CompilerDecl.h:28
llvm::DenseMap< lldb::user_id_t, lldb::FunctionSP > m_functions
static lldb::LanguageType TranslateLanguage(PDB_Lang lang)
llvm::Expected< TypeSystem & > GetTypeSystemForLanguage(lldb::LanguageType language) override
CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override