brintos

brintos / llvm-project-archived public Read only

0
0
Text · 101.2 KiB · 3bf113a Raw
2944 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "SymbolFileNativePDB.h"10 11#include "Plugins/ExpressionParser/Clang/ClangUtil.h"12#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"13#include "Plugins/ObjectFile/PDB/ObjectFilePDB.h"14#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"15#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"16#include "lldb/Core/Module.h"17#include "lldb/Core/PluginManager.h"18#include "lldb/Symbol/CompileUnit.h"19#include "lldb/Symbol/LineTable.h"20#include "lldb/Symbol/ObjectFile.h"21#include "lldb/Symbol/SymbolContext.h"22#include "lldb/Symbol/SymbolVendor.h"23#include "lldb/Symbol/Variable.h"24#include "lldb/Symbol/VariableList.h"25#include "lldb/Utility/LLDBLog.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 55#include "DWARFLocationExpression.h"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 68char SymbolFileNativePDB::ID;69 70static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {71  switch (lang) {72  case PDB_Lang::Cpp:73    return lldb::LanguageType::eLanguageTypeC_plus_plus;74  case PDB_Lang::C:75    return lldb::LanguageType::eLanguageTypeC;76  case PDB_Lang::Swift:77    return lldb::LanguageType::eLanguageTypeSwift;78  case PDB_Lang::Rust:79    return lldb::LanguageType::eLanguageTypeRust;80  case PDB_Lang::ObjC:81    return lldb::LanguageType::eLanguageTypeObjC;82  case PDB_Lang::ObjCpp:83    return lldb::LanguageType::eLanguageTypeObjC_plus_plus;84  default:85    return lldb::LanguageType::eLanguageTypeUnknown;86  }87}88 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 a99  // 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 time106  // doesn't match the PDB's current location, so check the location of the107  // 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-paths113  FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();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 information137  // 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 177static bool IsFunctionPrologue(const CompilandIndexItem &cci,178                               lldb::addr_t addr) {179  // FIXME: Implement this.180  return false;181}182 183static bool IsFunctionEpilogue(const CompilandIndexItem &cci,184                               lldb::addr_t addr) {185  // FIXME: Implement this.186  return false;187}188 189// See llvm::codeview::TypeIndex::simpleTypeName as well as strForPrimitiveTi190// from the original pdbdump:191// https://github.com/microsoft/microsoft-pdb/blob/805655a28bd8198004be2ac27e6e0290121a5e89/pdbdump/pdbdump.cpp#L1896-L1974192//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 it307  // is also used to indicate the primary definition of a nested class.  That is308  // 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 to319  // 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 a331  // single component of a mangled name.  So we can inject it into the parent's332  // 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 the339  // inner tag type is not necessarily the same as the outer tag type, re-write340  // 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 354void SymbolFileNativePDB::Initialize() {355  PluginManager::RegisterPlugin(GetPluginNameStatic(),356                                GetPluginDescriptionStatic(), CreateInstance,357                                DebuggerInitialize);358}359 360void SymbolFileNativePDB::Terminate() {361  PluginManager::UnregisterPlugin(CreateInstance);362}363 364void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {}365 366llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() {367  return "Microsoft PDB debug symbol cross-platform file reader.";368}369 370SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) {371  if (!SymbolFilePDB::UseNativePDB())372    return nullptr;373 374  return new SymbolFileNativePDB(std::move(objfile_sp));375}376 377SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)378    : SymbolFileCommon(std::move(objfile_sp)) {}379 380SymbolFileNativePDB::~SymbolFileNativePDB() = default;381 382uint32_t SymbolFileNativePDB::CalculateAbilities() {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(),394                                      m_allocator);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 between412  // stripped and not stripped.413  abilities = kAllAbilities;414 415  if (m_index->dbi().isStripped())416    abilities &= ~(Blocks | LocalVariables);417  return abilities;418}419 420void SymbolFileNativePDB::InitializeObject() {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(429      lldb::eLanguageTypeC_plus_plus);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);436    BuildParentMap();437  }438}439 440uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {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 the447  // 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 455Block *SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {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 entry472    // 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.  In478    // either case, its parent can be viewed as a block (e.g. a function479    // contains 1 big block.  So just get the parent block and add this block480    // 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    ast_builder->GetOrCreateBlockDecl(block_id);507    m_blocks.insert({opaque_block_uid, child_block});508    break;509  }510  case S_INLINESITE: {511    // This ensures line table is parsed first so we have inline sites info.512    comp_unit->GetLineTable();513 514    std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid];515    Block *parent_block = GetOrCreateBlock(inline_site->parent_id);516    if (!parent_block)517      return nullptr;518    BlockSP child_block = parent_block->CreateChild(opaque_block_uid);519    ast_builder->GetOrCreateInlinedFunctionDecl(block_id);520    // Copy ranges from InlineSite to Block.521    for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {522      auto *entry = inline_site->ranges.GetEntryAtIndex(i);523      child_block->AddRange(524          Block::Range(entry->GetRangeBase(), entry->GetByteSize()));525    }526    child_block->FinalizeRanges();527 528    // Get the inlined function callsite info.529    Declaration &decl = inline_site->inline_function_info->GetDeclaration();530    Declaration &callsite = inline_site->inline_function_info->GetCallSite();531    child_block->SetInlinedFunctionInfo(532        inline_site->inline_function_info->GetName().GetCString(), nullptr,533        &decl, &callsite);534    m_blocks.insert({opaque_block_uid, child_block});535    break;536  }537  default:538    lldbassert(false && "Symbol is not a block!");539  }540 541  return nullptr;542}543 544lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,545                                                     CompileUnit &comp_unit) {546  const CompilandIndexItem *cci =547      m_index->compilands().GetCompiland(func_id.modi);548  lldbassert(cci);549  CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);550 551  lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);552  SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record);553 554  auto file_vm_addr =555      m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);556  if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)557    return nullptr;558 559  Address func_addr(file_vm_addr, comp_unit.GetModule()->GetSectionList());560  if (!func_addr.IsValid())561    return nullptr;562 563  ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));564  cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));565  if (proc.FunctionType == TypeIndex::None())566    return nullptr;567  TypeSP func_type = GetOrCreateType(proc.FunctionType);568  if (!func_type)569    return nullptr;570 571  PdbTypeSymId sig_id(proc.FunctionType, false);572 573  std::optional<llvm::StringRef> mangled_opt = FindMangledSymbol(574      SegmentOffset(proc.Segment, proc.CodeOffset), proc.FunctionType);575  Mangled mangled(mangled_opt.value_or(proc.Name));576 577  FunctionSP func_sp = std::make_shared<Function>(578      &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,579      func_type.get(), func_addr,580      AddressRanges{AddressRange(func_addr, sol.length)});581 582  comp_unit.AddFunction(func_sp);583 584  auto ts_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage());585  if (auto err = ts_or_err.takeError())586    return func_sp;587  auto ts = *ts_or_err;588  if (!ts)589    return func_sp;590  ts->GetNativePDBParser()->GetOrCreateFunctionDecl(func_id);591 592  return func_sp;593}594 595CompUnitSP596SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {597  lldb::LanguageType lang =598      cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())599                         : lldb::eLanguageTypeUnknown;600 601  LazyBool optimized = eLazyBoolNo;602  if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())603    optimized = eLazyBoolYes;604 605  llvm::SmallString<64> source_file_name =606      m_index->compilands().GetMainSourceFile(cci);607  FileSpec fs(llvm::sys::path::convert_to_slash(608      source_file_name, llvm::sys::path::Style::windows_backslash));609 610  CompUnitSP cu_sp = std::make_shared<CompileUnit>(611      m_objfile_sp->GetModule(), nullptr, std::make_shared<SupportFile>(fs),612      toOpaqueUid(cci.m_id), lang, optimized);613 614  SetCompileUnitAtIndex(cci.m_id.modi, cu_sp);615  return cu_sp;616}617 618lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id,619                                                     const ModifierRecord &mr,620                                                     CompilerType ct) {621  TpiStream &stream = m_index->tpi();622 623  std::string name;624 625  if ((mr.Modifiers & ModifierOptions::Const) != ModifierOptions::None)626    name += "const ";627  if ((mr.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)628    name += "volatile ";629  if ((mr.Modifiers & ModifierOptions::Unaligned) != ModifierOptions::None)630    name += "__unaligned ";631 632  if (mr.ModifiedType.isSimple())633    name += GetSimpleTypeName(mr.ModifiedType.getSimpleKind());634  else635    name += computeTypeName(stream.typeCollection(), mr.ModifiedType);636  Declaration decl;637  lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);638 639  return MakeType(toOpaqueUid(type_id), ConstString(name),640                  llvm::expectedToOptional(modified_type->GetByteSize(nullptr)),641                  nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,642                  Type::ResolveState::Full);643}644 645lldb::TypeSP646SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id,647                                       const llvm::codeview::PointerRecord &pr,648                                       CompilerType ct) {649  TypeSP pointee = GetOrCreateType(pr.ReferentType);650  if (!pointee)651    return nullptr;652 653  if (pr.isPointerToMember()) {654    MemberPointerInfo mpi = pr.getMemberInfo();655    GetOrCreateType(mpi.ContainingType);656  }657 658  Declaration decl;659  return MakeType(toOpaqueUid(type_id), ConstString(), pr.getSize(), nullptr,660                  LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,661                  Type::ResolveState::Full);662}663 664lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti,665                                                   CompilerType ct) {666  uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));667  if (ti == TypeIndex::NullptrT()) {668    Declaration decl;669    return MakeType(uid, ConstString("decltype(nullptr)"), std::nullopt,670                    nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,671                    Type::ResolveState::Full);672  }673 674  if (ti.getSimpleMode() != SimpleTypeMode::Direct) {675    TypeSP direct_sp = GetOrCreateType(ti.makeDirect());676    uint32_t pointer_size = 0;677    switch (ti.getSimpleMode()) {678    case SimpleTypeMode::FarPointer32:679    case SimpleTypeMode::NearPointer32:680      pointer_size = 4;681      break;682    case SimpleTypeMode::NearPointer64:683      pointer_size = 8;684      break;685    default:686      // 128-bit and 16-bit pointers unsupported.687      return nullptr;688    }689    Declaration decl;690    return MakeType(uid, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID,691                    Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);692  }693 694  if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)695    return nullptr;696 697  size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind());698  llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());699 700  Declaration decl;701  return MakeType(uid, ConstString(type_name), size, nullptr, LLDB_INVALID_UID,702                  Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full);703}704 705static std::string GetUnqualifiedTypeName(const TagRecord &record) {706  if (!record.hasUniqueName())707    return std::string(MSVCUndecoratedNameParser::DropScope(record.Name));708 709  llvm::ms_demangle::Demangler demangler;710  std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());711  llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);712  if (demangler.Error)713    return std::string(MSVCUndecoratedNameParser::DropScope(record.Name));714 715  llvm::ms_demangle::IdentifierNode *idn =716      ttn->QualifiedName->getUnqualifiedIdentifier();717  return idn->toString();718}719 720lldb::TypeSP721SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id,722                                            const TagRecord &record,723                                            size_t size, CompilerType ct) {724 725  std::string uname = GetUnqualifiedTypeName(record);726 727  llvm::Expected<Declaration> maybeDecl = ResolveUdtDeclaration(type_id);728  Declaration decl;729  if (maybeDecl)730    decl = std::move(*maybeDecl);731  else732    LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), maybeDecl.takeError(),733                   "Failed to resolve declaration for '{1}': {0}", uname);734 735  return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr,736                  LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct,737                  Type::ResolveState::Forward);738}739 740lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,741                                                const ClassRecord &cr,742                                                CompilerType ct) {743  return CreateClassStructUnion(type_id, cr, cr.getSize(), ct);744}745 746lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,747                                                const UnionRecord &ur,748                                                CompilerType ct) {749  return CreateClassStructUnion(type_id, ur, ur.getSize(), ct);750}751 752lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,753                                                const EnumRecord &er,754                                                CompilerType ct) {755  std::string uname = GetUnqualifiedTypeName(er);756 757  llvm::Expected<Declaration> maybeDecl = ResolveUdtDeclaration(type_id);758  Declaration decl;759  if (maybeDecl)760    decl = std::move(*maybeDecl);761  else762    LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), maybeDecl.takeError(),763                   "Failed to resolve declaration for '{1}': {0}", uname);764 765  TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);766 767  return MakeType(768      toOpaqueUid(type_id), ConstString(uname),769      llvm::expectedToOptional(underlying_type->GetByteSize(nullptr)), nullptr,770      LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct,771      lldb_private::Type::ResolveState::Forward);772}773 774TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id,775                                            const ArrayRecord &ar,776                                            CompilerType ct) {777  TypeSP element_type = GetOrCreateType(ar.ElementType);778 779  Declaration decl;780  TypeSP array_sp =781      MakeType(toOpaqueUid(type_id), ConstString(), ar.Size, nullptr,782               LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct,783               lldb_private::Type::ResolveState::Full);784  array_sp->SetEncodingType(element_type.get());785  return array_sp;786}787 788TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id,789                                               const MemberFunctionRecord &mfr,790                                               CompilerType ct) {791  if (mfr.ReturnType.isSimple())792    GetOrCreateType(mfr.ReturnType);793  CreateSimpleArgumentListTypes(mfr.ArgumentList);794 795  Declaration decl;796  return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,797                  LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,798                  ct, lldb_private::Type::ResolveState::Full);799}800 801TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,802                                                const ProcedureRecord &pr,803                                                CompilerType ct) {804  if (pr.ReturnType.isSimple())805    GetOrCreateType(pr.ReturnType);806  CreateSimpleArgumentListTypes(pr.ArgumentList);807 808  Declaration decl;809  return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr,810                  LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,811                  ct, lldb_private::Type::ResolveState::Full);812}813 814void SymbolFileNativePDB::CreateSimpleArgumentListTypes(815    llvm::codeview::TypeIndex arglist_ti) {816  if (arglist_ti.isNoneType())817    return;818 819  CVType arglist_cvt = m_index->tpi().getType(arglist_ti);820  if (arglist_cvt.kind() != LF_ARGLIST)821    return; // invalid debug info822 823  ArgListRecord alr;824  llvm::cantFail(825      TypeDeserializer::deserializeAs<ArgListRecord>(arglist_cvt, alr));826  for (TypeIndex id : alr.getIndices())827    if (!id.isNoneType() && id.isSimple())828      GetOrCreateType(id);829}830 831TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {832  if (type_id.index.isSimple())833    return CreateSimpleType(type_id.index, ct);834 835  TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi();836  CVType cvt = stream.getType(type_id.index);837 838  if (cvt.kind() == LF_MODIFIER) {839    ModifierRecord modifier;840    llvm::cantFail(841        TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));842    return CreateModifierType(type_id, modifier, ct);843  }844 845  if (cvt.kind() == LF_POINTER) {846    PointerRecord pointer;847    llvm::cantFail(848        TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));849    return CreatePointerType(type_id, pointer, ct);850  }851 852  if (IsClassRecord(cvt.kind())) {853    ClassRecord cr;854    llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));855    return CreateTagType(type_id, cr, ct);856  }857 858  if (cvt.kind() == LF_ENUM) {859    EnumRecord er;860    llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));861    return CreateTagType(type_id, er, ct);862  }863 864  if (cvt.kind() == LF_UNION) {865    UnionRecord ur;866    llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));867    return CreateTagType(type_id, ur, ct);868  }869 870  if (cvt.kind() == LF_ARRAY) {871    ArrayRecord ar;872    llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));873    return CreateArrayType(type_id, ar, ct);874  }875 876  if (cvt.kind() == LF_PROCEDURE) {877    ProcedureRecord pr;878    llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));879    return CreateProcedureType(type_id, pr, ct);880  }881  if (cvt.kind() == LF_MFUNCTION) {882    MemberFunctionRecord mfr;883    llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));884    return CreateFunctionType(type_id, mfr, ct);885  }886 887  return nullptr;888}889 890TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) {891  // If they search for a UDT which is a forward ref, try and resolve the full892  // decl and just map the forward ref uid to the full decl record.893  std::optional<PdbTypeSymId> full_decl_uid;894  if (IsForwardRefUdt(type_id, m_index->tpi())) {895    auto expected_full_ti =896        m_index->tpi().findFullDeclForForwardRef(type_id.index);897    if (!expected_full_ti)898      llvm::consumeError(expected_full_ti.takeError());899    else if (*expected_full_ti != type_id.index) {900      full_decl_uid = PdbTypeSymId(*expected_full_ti, false);901 902      // It's possible that a lookup would occur for the full decl causing it903      // to be cached, then a second lookup would occur for the forward decl.904      // We don't want to create a second full decl, so make sure the full905      // decl hasn't already been cached.906      auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid));907      if (full_iter != m_types.end()) {908        TypeSP result = full_iter->second;909        // Map the forward decl to the TypeSP for the full decl so we can take910        // the fast path next time.911        m_types[toOpaqueUid(type_id)] = result;912        return result;913      }914    }915  }916 917  PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;918  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);919  if (auto err = ts_or_err.takeError())920    return nullptr;921  auto ts = *ts_or_err;922  if (!ts)923    return nullptr;924 925  PdbAstBuilder* ast_builder = ts->GetNativePDBParser();926  clang::QualType qt = ast_builder->GetOrCreateType(best_decl_id);927  if (qt.isNull())928    return nullptr;929 930  TypeSP result = CreateType(best_decl_id, ast_builder->ToCompilerType(qt));931  if (!result)932    return nullptr;933 934  uint64_t best_uid = toOpaqueUid(best_decl_id);935  m_types[best_uid] = result;936  // If we had both a forward decl and a full decl, make both point to the new937  // type.938  if (full_decl_uid)939    m_types[toOpaqueUid(type_id)] = result;940 941  return result;942}943 944TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {945  // We can't use try_emplace / overwrite here because the process of creating946  // a type could create nested types, which could invalidate iterators.  So947  // we have to do a 2-phase lookup / insert.948  auto iter = m_types.find(toOpaqueUid(type_id));949  if (iter != m_types.end())950    return iter->second;951 952  TypeSP type = CreateAndCacheType(type_id);953  if (type)954    GetTypeList().Insert(type);955  return type;956}957 958VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {959  CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);960  if (sym.kind() == S_CONSTANT)961    return CreateConstantSymbol(var_id, sym);962 963  lldb::ValueType scope = eValueTypeInvalid;964  TypeIndex ti;965  llvm::StringRef name;966  lldb::addr_t addr = 0;967  uint16_t section = 0;968  uint32_t offset = 0;969  bool is_external = false;970  switch (sym.kind()) {971  case S_GDATA32:972    is_external = true;973    [[fallthrough]];974  case S_LDATA32: {975    DataSym ds(sym.kind());976    llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds));977    ti = ds.Type;978    scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal979                                      : eValueTypeVariableStatic;980    name = ds.Name;981    section = ds.Segment;982    offset = ds.DataOffset;983    addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);984    break;985  }986  case S_GTHREAD32:987    is_external = true;988    [[fallthrough]];989  case S_LTHREAD32: {990    ThreadLocalDataSym tlds(sym.kind());991    llvm::cantFail(992        SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds));993    ti = tlds.Type;994    name = tlds.Name;995    section = tlds.Segment;996    offset = tlds.DataOffset;997    addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);998    scope = eValueTypeVariableThreadLocal;999    break;1000  }1001  default:1002    llvm_unreachable("unreachable!");1003  }1004 1005  CompUnitSP comp_unit;1006  std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);1007  // Some globals has modi points to the linker module, ignore them.1008  if (!modi || modi >= GetNumCompileUnits())1009    return nullptr;1010 1011  CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);1012  comp_unit = GetOrCreateCompileUnit(cci);1013 1014  Declaration decl;1015  PdbTypeSymId tid(ti, false);1016  SymbolFileTypeSP type_sp =1017      std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));1018  Variable::RangeList ranges;1019  auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());1020  if (auto err = ts_or_err.takeError())1021    return nullptr;1022  auto ts = *ts_or_err;1023  if (!ts)1024    return nullptr;1025 1026  ts->GetNativePDBParser()->GetOrCreateVariableDecl(var_id);1027 1028  ModuleSP module_sp = GetObjectFile()->GetModule();1029  DWARFExpressionList location(1030      module_sp, MakeGlobalLocationExpression(section, offset, module_sp),1031      nullptr);1032 1033  std::string global_name("::");1034  global_name += name;1035  bool artificial = false;1036  bool location_is_constant_data = false;1037  bool static_member = false;1038  VariableSP var_sp = std::make_shared<Variable>(1039      toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,1040      scope, comp_unit.get(), ranges, &decl, location, is_external, artificial,1041      location_is_constant_data, static_member);1042 1043  return var_sp;1044}1045 1046lldb::VariableSP1047SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,1048                                          const CVSymbol &cvs) {1049  TpiStream &tpi = m_index->tpi();1050  ConstantSym constant(cvs.kind());1051 1052  llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant));1053  std::string global_name("::");1054  global_name += constant.Name;1055  PdbTypeSymId tid(constant.Type, false);1056  SymbolFileTypeSP type_sp =1057      std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));1058 1059  Declaration decl;1060  Variable::RangeList ranges;1061  ModuleSP module = GetObjectFile()->GetModule();1062  DWARFExpressionList location(module,1063                               MakeConstantLocationExpression(1064                                   constant.Type, tpi, constant.Value, module),1065                               nullptr);1066 1067  bool external = false;1068  bool artificial = false;1069  bool location_is_constant_data = true;1070  bool static_member = false;1071  VariableSP var_sp = std::make_shared<Variable>(1072      toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),1073      type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,1074      external, artificial, location_is_constant_data, static_member);1075  return var_sp;1076}1077 1078VariableSP1079SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) {1080  auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr);1081  if (emplace_result.second) {1082    if (VariableSP var_sp = CreateGlobalVariable(var_id))1083      emplace_result.first->second = var_sp;1084    else1085      return nullptr;1086  }1087 1088  return emplace_result.first->second;1089}1090 1091lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) {1092  return GetOrCreateType(PdbTypeSymId(ti, false));1093}1094 1095FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id,1096                                                    CompileUnit &comp_unit) {1097  auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);1098  if (emplace_result.second)1099    emplace_result.first->second = CreateFunction(func_id, comp_unit);1100 1101  return emplace_result.first->second;1102}1103 1104CompUnitSP1105SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) {1106 1107  auto emplace_result =1108      m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr);1109  if (emplace_result.second)1110    emplace_result.first->second = CreateCompileUnit(cci);1111 1112  lldbassert(emplace_result.first->second);1113  return emplace_result.first->second;1114}1115 1116Block *SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) {1117  auto iter = m_blocks.find(toOpaqueUid(block_id));1118  if (iter != m_blocks.end())1119    return iter->second.get();1120 1121  return CreateBlock(block_id);1122}1123 1124void SymbolFileNativePDB::ParseDeclsForContext(1125    lldb_private::CompilerDeclContext decl_ctx) {1126  TypeSystem* ts_or_err = decl_ctx.GetTypeSystem();1127  if (!ts_or_err)1128    return;1129  PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();1130  clang::DeclContext *context = ast_builder->FromCompilerDeclContext(decl_ctx);1131  if (!context)1132    return;1133  ast_builder->ParseDeclsForContext(*context);1134}1135 1136lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {1137  if (index >= GetNumCompileUnits())1138    return CompUnitSP();1139  lldbassert(index < UINT16_MAX);1140  if (index >= UINT16_MAX)1141    return nullptr;1142 1143  CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);1144 1145  return GetOrCreateCompileUnit(item);1146}1147 1148lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {1149  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1150  PdbSymUid uid(comp_unit.GetID());1151  lldbassert(uid.kind() == PdbSymUidKind::Compiland);1152 1153  CompilandIndexItem *item =1154      m_index->compilands().GetCompiland(uid.asCompiland().modi);1155  lldbassert(item);1156  if (!item->m_compile_opts)1157    return lldb::eLanguageTypeUnknown;1158 1159  return TranslateLanguage(item->m_compile_opts->getLanguage());1160}1161 1162void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {1163  auto *section_list =1164      m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList();1165  if (!section_list)1166    return;1167 1168  PublicSym32 last_sym;1169  size_t last_sym_idx = 0;1170  lldb::SectionSP section_sp;1171 1172  // To estimate the size of a symbol, we use the difference to the next symbol.1173  // If there's no next symbol or the section/segment changed, the symbol will1174  // take the remaining space. The estimate can be too high in case there's1175  // padding between symbols. This similar to the algorithm used by the DIA1176  // SDK.1177  auto finish_last_symbol = [&](const PublicSym32 *next) {1178    if (!section_sp)1179      return;1180    Symbol *last = symtab.SymbolAtIndex(last_sym_idx);1181    if (!last)1182      return;1183 1184    if (next && last_sym.Segment == next->Segment) {1185      assert(last_sym.Offset <= next->Offset);1186      last->SetByteSize(next->Offset - last_sym.Offset);1187    } else {1188      // the last symbol was the last in its section1189      assert(section_sp->GetByteSize() >= last_sym.Offset);1190      assert(!next || next->Segment > last_sym.Segment);1191      last->SetByteSize(section_sp->GetByteSize() - last_sym.Offset);1192    }1193  };1194 1195  // The address map is sorted by the address of a symbol.1196  for (auto pid : m_index->publics().getAddressMap()) {1197    PdbGlobalSymId global{pid, true};1198    CVSymbol sym = m_index->ReadSymbolRecord(global);1199    auto kind = sym.kind();1200    if (kind != S_PUB32)1201      continue;1202    PublicSym32 pub =1203        llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym));1204    finish_last_symbol(&pub);1205 1206    if (!section_sp || last_sym.Segment != pub.Segment)1207      section_sp = section_list->FindSectionByID(pub.Segment);1208 1209    if (!section_sp)1210      continue;1211 1212    lldb::SymbolType type = eSymbolTypeData;1213    if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||1214        (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)1215      type = eSymbolTypeCode;1216 1217    last_sym_idx =1218        symtab.AddSymbol(Symbol(/*symID=*/pid,1219                                /*name=*/pub.Name,1220                                /*type=*/type,1221                                /*external=*/true,1222                                /*is_debug=*/true,1223                                /*is_trampoline=*/false,1224                                /*is_artificial=*/false,1225                                /*section_sp=*/section_sp,1226                                /*value=*/pub.Offset,1227                                /*size=*/0,1228                                /*size_is_valid=*/false,1229                                /*contains_linker_annotations=*/false,1230                                /*flags=*/0));1231    last_sym = pub;1232  }1233 1234  finish_last_symbol(nullptr);1235}1236 1237size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {1238  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1239  PdbSymUid uid{comp_unit.GetID()};1240  lldbassert(uid.kind() == PdbSymUidKind::Compiland);1241  uint16_t modi = uid.asCompiland().modi;1242  CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);1243 1244  size_t count = comp_unit.GetNumFunctions();1245  const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();1246  for (auto iter = syms.begin(); iter != syms.end(); ++iter) {1247    if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)1248      continue;1249 1250    PdbCompilandSymId sym_id{modi, iter.offset()};1251 1252    FunctionSP func = GetOrCreateFunction(sym_id, comp_unit);1253  }1254 1255  size_t new_count = comp_unit.GetNumFunctions();1256  lldbassert(new_count >= count);1257  return new_count - count;1258}1259 1260static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {1261  // If any of these flags are set, we need to resolve the compile unit.1262  uint32_t flags = eSymbolContextCompUnit;1263  flags |= eSymbolContextVariable;1264  flags |= eSymbolContextFunction;1265  flags |= eSymbolContextBlock;1266  flags |= eSymbolContextLineEntry;1267  return (resolve_scope & flags) != 0;1268}1269 1270uint32_t SymbolFileNativePDB::ResolveSymbolContext(1271    const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {1272  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1273  uint32_t resolved_flags = 0;1274  lldb::addr_t file_addr = addr.GetFileAddress();1275 1276  if (NeedsResolvedCompileUnit(resolve_scope)) {1277    std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);1278    if (!modi)1279      return 0;1280    CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi);1281    if (!cu_sp)1282      return 0;1283 1284    sc.comp_unit = cu_sp.get();1285    resolved_flags |= eSymbolContextCompUnit;1286  }1287 1288  if (resolve_scope & eSymbolContextFunction ||1289      resolve_scope & eSymbolContextBlock) {1290    lldbassert(sc.comp_unit);1291    std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);1292    // Search the matches in reverse.  This way if there are multiple matches1293    // (for example we are 3 levels deep in a nested scope) it will find the1294    // innermost one first.1295    for (const auto &match : llvm::reverse(matches)) {1296      if (match.uid.kind() != PdbSymUidKind::CompilandSym)1297        continue;1298 1299      PdbCompilandSymId csid = match.uid.asCompilandSym();1300      CVSymbol cvs = m_index->ReadSymbolRecord(csid);1301      PDB_SymType type = CVSymToPDBSym(cvs.kind());1302      if (type != PDB_SymType::Function && type != PDB_SymType::Block)1303        continue;1304      if (type == PDB_SymType::Function) {1305        sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();1306        if (sc.function) {1307          Block &block = sc.function->GetBlock(true);1308          addr_t func_base = sc.function->GetAddress().GetFileAddress();1309          addr_t offset = file_addr - func_base;1310          sc.block = block.FindInnermostBlockByOffset(offset);1311        }1312      }1313 1314      if (type == PDB_SymType::Block) {1315        Block *block = GetOrCreateBlock(csid);1316        if (!block)1317          continue;1318        sc.function = block->CalculateSymbolContextFunction();1319        if (sc.function) {1320          sc.function->GetBlock(true);1321          addr_t func_base = sc.function->GetAddress().GetFileAddress();1322          addr_t offset = file_addr - func_base;1323          sc.block = block->FindInnermostBlockByOffset(offset);1324        }1325      }1326      if (sc.function)1327        resolved_flags |= eSymbolContextFunction;1328      if (sc.block)1329        resolved_flags |= eSymbolContextBlock;1330      break;1331    }1332  }1333 1334  if (resolve_scope & eSymbolContextLineEntry) {1335    lldbassert(sc.comp_unit);1336    if (auto *line_table = sc.comp_unit->GetLineTable()) {1337      if (line_table->FindLineEntryByAddress(addr, sc.line_entry))1338        resolved_flags |= eSymbolContextLineEntry;1339    }1340  }1341 1342  return resolved_flags;1343}1344 1345uint32_t SymbolFileNativePDB::ResolveSymbolContext(1346    const SourceLocationSpec &src_location_spec,1347    lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {1348  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1349  const uint32_t prev_size = sc_list.GetSize();1350  if (resolve_scope & eSymbolContextCompUnit) {1351    for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;1352         ++cu_idx) {1353      CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get();1354      if (!cu)1355        continue;1356 1357      bool file_spec_matches_cu_file_spec = FileSpec::Match(1358          src_location_spec.GetFileSpec(), cu->GetPrimaryFile());1359      if (file_spec_matches_cu_file_spec) {1360        cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);1361        break;1362      }1363    }1364  }1365  return sc_list.GetSize() - prev_size;1366}1367 1368bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {1369  // Unfortunately LLDB is set up to parse the entire compile unit line table1370  // all at once, even if all it really needs is line info for a specific1371  // function.  In the future it would be nice if it could set the sc.m_function1372  // member, and we could only get the line info for the function in question.1373  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1374  PdbSymUid cu_id(comp_unit.GetID());1375  lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);1376  uint16_t modi = cu_id.asCompiland().modi;1377  CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi);1378  lldbassert(cii);1379 1380  // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records1381  // in this CU. Add line entries into the set first so that if there are line1382  // entries with same addres, the later is always more accurate than the1383  // former.1384  std::set<LineTable::Entry, LineTableEntryComparator> line_set;1385 1386  // This is basically a copy of the .debug$S subsections from all original COFF1387  // object files merged together with address relocations applied.  We are1388  // looking for all DEBUG_S_LINES subsections.1389  for (const DebugSubsectionRecord &dssr :1390       cii->m_debug_stream.getSubsectionsArray()) {1391    if (dssr.kind() != DebugSubsectionKind::Lines)1392      continue;1393 1394    DebugLinesSubsectionRef lines;1395    llvm::BinaryStreamReader reader(dssr.getRecordData());1396    if (auto EC = lines.initialize(reader)) {1397      llvm::consumeError(std::move(EC));1398      return false;1399    }1400 1401    const LineFragmentHeader *lfh = lines.header();1402    uint64_t virtual_addr =1403        m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);1404    if (virtual_addr == LLDB_INVALID_ADDRESS)1405      continue;1406 1407    for (const LineColumnEntry &group : lines) {1408      llvm::Expected<uint32_t> file_index_or_err =1409          GetFileIndex(*cii, group.NameIndex);1410      if (!file_index_or_err)1411        continue;1412      uint32_t file_index = file_index_or_err.get();1413      lldbassert(!group.LineNumbers.empty());1414      CompilandIndexItem::GlobalLineTable::Entry line_entry(1415          LLDB_INVALID_ADDRESS, 0);1416      for (const LineNumberEntry &entry : group.LineNumbers) {1417        LineInfo cur_info(entry.Flags);1418 1419        if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())1420          continue;1421 1422        uint64_t addr = virtual_addr + entry.Offset;1423 1424        bool is_statement = cur_info.isStatement();1425        bool is_prologue = IsFunctionPrologue(*cii, addr);1426        bool is_epilogue = IsFunctionEpilogue(*cii, addr);1427 1428        uint32_t lno = cur_info.getStartLine();1429 1430        LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false,1431                                 is_prologue, is_epilogue, false);1432        // Terminal entry has lower precedence than new entry.1433        auto iter = line_set.find(new_entry);1434        if (iter != line_set.end() && iter->is_terminal_entry)1435          line_set.erase(iter);1436        line_set.insert(new_entry);1437 1438        if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {1439          line_entry.SetRangeEnd(addr);1440          cii->m_global_line_table.Append(line_entry);1441        }1442        line_entry.SetRangeBase(addr);1443        line_entry.data = {file_index, lno};1444      }1445      LineInfo last_line(group.LineNumbers.back().Flags);1446      line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,1447                       file_index, false, false, false, false, true);1448 1449      if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) {1450        line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize);1451        cii->m_global_line_table.Append(line_entry);1452      }1453    }1454  }1455 1456  cii->m_global_line_table.Sort();1457 1458  // Parse all S_INLINESITE in this CU.1459  const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray();1460  for (auto iter = syms.begin(); iter != syms.end();) {1461    if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {1462      ++iter;1463      continue;1464    }1465 1466    uint32_t record_offset = iter.offset();1467    CVSymbol func_record =1468        cii->m_debug_stream.readSymbolAtOffset(record_offset);1469    SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record);1470    addr_t file_vm_addr =1471        m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset);1472    if (file_vm_addr == LLDB_INVALID_ADDRESS)1473      continue;1474 1475    Address func_base(file_vm_addr, comp_unit.GetModule()->GetSectionList());1476    PdbCompilandSymId func_id{modi, record_offset};1477 1478    // Iterate all S_INLINESITEs in the function.1479    auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) {1480      if (kind != S_INLINESITE)1481        return false;1482 1483      ParseInlineSite(id, func_base);1484 1485      for (const auto &line_entry :1486           m_inline_sites[toOpaqueUid(id)]->line_entries) {1487        // If line_entry is not terminal entry, remove previous line entry at1488        // the same address and insert new one. Terminal entry inside an inline1489        // site might not be terminal entry for its parent.1490        if (!line_entry.is_terminal_entry)1491          line_set.erase(line_entry);1492        line_set.insert(line_entry);1493      }1494      // No longer useful after adding to line_set.1495      m_inline_sites[toOpaqueUid(id)]->line_entries.clear();1496      return true;1497    };1498    ParseSymbolArrayInScope(func_id, parse_inline_sites);1499    // Jump to the end of the function record.1500    iter = syms.at(getScopeEndOffset(func_record));1501  }1502 1503  cii->m_global_line_table.Clear();1504 1505  // Add line entries in line_set to line_table.1506  std::vector<LineTable::Sequence> sequence(1);1507  for (const auto &line_entry : line_set) {1508    LineTable::AppendLineEntryToSequence(1509        sequence.back(), line_entry.file_addr, line_entry.line,1510        line_entry.column, line_entry.file_idx,1511        line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,1512        line_entry.is_prologue_end, line_entry.is_epilogue_begin,1513        line_entry.is_terminal_entry);1514  }1515  auto line_table =1516      std::make_unique<LineTable>(&comp_unit, std::move(sequence));1517 1518  if (line_table->GetSize() == 0)1519    return false;1520 1521  comp_unit.SetLineTable(line_table.release());1522  return true;1523}1524 1525bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {1526  // PDB doesn't contain information about macros1527  return false;1528}1529 1530llvm::Expected<uint32_t>1531SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii,1532                                  uint32_t file_id) {1533  if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings())1534    return llvm::make_error<RawError>(raw_error_code::no_entry);1535 1536  const auto &checksums = cii.m_strings.checksums().getArray();1537  const auto &strings = cii.m_strings.strings();1538  // Indices in this structure are actually offsets of records in the1539  // DEBUG_S_FILECHECKSUMS subsection.  Those entries then have an index1540  // into the global PDB string table.1541  auto iter = checksums.at(file_id);1542  if (iter == checksums.end())1543    return llvm::make_error<RawError>(raw_error_code::no_entry);1544 1545  llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);1546  if (!efn) {1547    return efn.takeError();1548  }1549 1550  // LLDB wants the index of the file in the list of support files.1551  auto fn_iter = llvm::find(cii.m_file_list, *efn);1552  if (fn_iter != cii.m_file_list.end())1553    return std::distance(cii.m_file_list.begin(), fn_iter);1554  return llvm::make_error<RawError>(raw_error_code::no_entry);1555}1556 1557bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,1558                                            SupportFileList &support_files) {1559  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1560  PdbSymUid cu_id(comp_unit.GetID());1561  lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);1562  CompilandIndexItem *cci =1563      m_index->compilands().GetCompiland(cu_id.asCompiland().modi);1564  lldbassert(cci);1565 1566  for (llvm::StringRef f : cci->m_file_list) {1567    FileSpec::Style style =1568        f.starts_with("/") ? FileSpec::Style::posix : FileSpec::Style::windows;1569    FileSpec spec(f, style);1570    support_files.Append(spec);1571  }1572  return true;1573}1574 1575bool SymbolFileNativePDB::ParseImportedModules(1576    const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {1577  // PDB does not yet support module debug info1578  return false;1579}1580 1581void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id,1582                                          Address func_addr) {1583  lldb::user_id_t opaque_uid = toOpaqueUid(id);1584  if (m_inline_sites.contains(opaque_uid))1585    return;1586 1587  addr_t func_base = func_addr.GetFileAddress();1588  CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi);1589  CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset);1590  CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);1591 1592  InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));1593  cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));1594  PdbCompilandSymId parent_id(id.modi, inline_site.Parent);1595 1596  std::shared_ptr<InlineSite> inline_site_sp =1597      std::make_shared<InlineSite>(parent_id);1598 1599  // Get the inlined function declaration info.1600  auto iter = cii->m_inline_map.find(inline_site.Inlinee);1601  if (iter == cii->m_inline_map.end())1602    return;1603  InlineeSourceLine inlinee_line = iter->second;1604 1605  const SupportFileList &files = comp_unit->GetSupportFiles();1606  FileSpec decl_file;1607  llvm::Expected<uint32_t> file_index_or_err =1608      GetFileIndex(*cii, inlinee_line.Header->FileID);1609  if (!file_index_or_err)1610    return;1611  uint32_t file_offset = file_index_or_err.get();1612  decl_file = files.GetFileSpecAtIndex(file_offset);1613  uint32_t decl_line = inlinee_line.Header->SourceLineNum;1614  std::unique_ptr<Declaration> decl_up =1615      std::make_unique<Declaration>(decl_file, decl_line);1616 1617  // Parse range and line info.1618  uint32_t code_offset = 0;1619  int32_t line_offset = 0;1620  std::optional<uint32_t> code_offset_base;1621  std::optional<uint32_t> code_offset_end;1622  std::optional<int32_t> cur_line_offset;1623  std::optional<int32_t> next_line_offset;1624  std::optional<uint32_t> next_file_offset;1625 1626  bool is_terminal_entry = false;1627  bool is_start_of_statement = true;1628  // The first instruction is the prologue end.1629  bool is_prologue_end = true;1630 1631  auto update_code_offset = [&](uint32_t code_delta) {1632    if (!code_offset_base)1633      code_offset_base = code_offset;1634    else if (!code_offset_end)1635      code_offset_end = *code_offset_base + code_delta;1636  };1637  auto update_line_offset = [&](int32_t line_delta) {1638    line_offset += line_delta;1639    if (!code_offset_base || !cur_line_offset)1640      cur_line_offset = line_offset;1641    else1642      next_line_offset = line_offset;1643    ;1644  };1645  auto update_file_offset = [&](uint32_t offset) {1646    if (!code_offset_base)1647      file_offset = offset;1648    else1649      next_file_offset = offset;1650  };1651 1652  for (auto &annot : inline_site.annotations()) {1653    switch (annot.OpCode) {1654    case BinaryAnnotationsOpCode::CodeOffset:1655    case BinaryAnnotationsOpCode::ChangeCodeOffset:1656    case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:1657      code_offset += annot.U1;1658      update_code_offset(annot.U1);1659      break;1660    case BinaryAnnotationsOpCode::ChangeLineOffset:1661      update_line_offset(annot.S1);1662      break;1663    case BinaryAnnotationsOpCode::ChangeCodeLength:1664      update_code_offset(annot.U1);1665      code_offset += annot.U1;1666      is_terminal_entry = true;1667      break;1668    case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:1669      code_offset += annot.U1;1670      update_code_offset(annot.U1);1671      update_line_offset(annot.S1);1672      break;1673    case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:1674      code_offset += annot.U2;1675      update_code_offset(annot.U2);1676      update_code_offset(annot.U1);1677      code_offset += annot.U1;1678      is_terminal_entry = true;1679      break;1680    case BinaryAnnotationsOpCode::ChangeFile:1681      update_file_offset(annot.U1);1682      break;1683    default:1684      break;1685    }1686 1687    // Add range if current range is finished.1688    if (code_offset_base && code_offset_end && cur_line_offset) {1689      inline_site_sp->ranges.Append(RangeSourceLineVector::Entry(1690          *code_offset_base, *code_offset_end - *code_offset_base,1691          decl_line + *cur_line_offset));1692      // Set base, end, file offset and line offset for next range.1693      if (next_file_offset)1694        file_offset = *next_file_offset;1695      if (next_line_offset) {1696        cur_line_offset = next_line_offset;1697        next_line_offset = std::nullopt;1698      }1699      code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;1700      code_offset_end = next_file_offset = std::nullopt;1701    }1702    if (code_offset_base && cur_line_offset) {1703      if (is_terminal_entry) {1704        LineTable::Entry line_entry(1705            func_base + *code_offset_base, decl_line + *cur_line_offset, 0,1706            file_offset, false, false, false, false, true);1707        inline_site_sp->line_entries.push_back(line_entry);1708      } else {1709        LineTable::Entry line_entry(func_base + *code_offset_base,1710                                    decl_line + *cur_line_offset, 0,1711                                    file_offset, is_start_of_statement, false,1712                                    is_prologue_end, false, false);1713        inline_site_sp->line_entries.push_back(line_entry);1714        is_prologue_end = false;1715        is_start_of_statement = false;1716      }1717    }1718    if (is_terminal_entry)1719      is_start_of_statement = true;1720    is_terminal_entry = false;1721  }1722 1723  inline_site_sp->ranges.Sort();1724 1725  // Get the inlined function callsite info.1726  std::unique_ptr<Declaration> callsite_up;1727  if (!inline_site_sp->ranges.IsEmpty()) {1728    auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);1729    addr_t base_offset = entry->GetRangeBase();1730    if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() ==1731        S_INLINESITE) {1732      // Its parent is another inline site, lookup parent site's range vector1733      // for callsite line.1734      ParseInlineSite(parent_id, func_base);1735      std::shared_ptr<InlineSite> parent_site =1736          m_inline_sites[toOpaqueUid(parent_id)];1737      FileSpec &parent_decl_file =1738          parent_site->inline_function_info->GetDeclaration().GetFile();1739      if (auto *parent_entry =1740              parent_site->ranges.FindEntryThatContains(base_offset)) {1741        callsite_up =1742            std::make_unique<Declaration>(parent_decl_file, parent_entry->data);1743      }1744    } else {1745      // Its parent is a function, lookup global line table for callsite.1746      if (auto *entry = cii->m_global_line_table.FindEntryThatContains(1747              func_base + base_offset)) {1748        const FileSpec &callsite_file =1749            files.GetFileSpecAtIndex(entry->data.first);1750        callsite_up =1751            std::make_unique<Declaration>(callsite_file, entry->data.second);1752      }1753    }1754  }1755 1756  // Get the inlined function name.1757  CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee);1758  std::string inlinee_name;1759  if (inlinee_cvt.kind() == LF_MFUNC_ID) {1760    MemberFuncIdRecord mfr;1761    cantFail(1762        TypeDeserializer::deserializeAs<MemberFuncIdRecord>(inlinee_cvt, mfr));1763    LazyRandomTypeCollection &types = m_index->tpi().typeCollection();1764    inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));1765    inlinee_name.append("::");1766    inlinee_name.append(mfr.getName().str());1767  } else if (inlinee_cvt.kind() == LF_FUNC_ID) {1768    FuncIdRecord fir;1769    cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(inlinee_cvt, fir));1770    TypeIndex parent_idx = fir.getParentScope();1771    if (!parent_idx.isNoneType()) {1772      LazyRandomTypeCollection &ids = m_index->ipi().typeCollection();1773      inlinee_name.append(std::string(ids.getTypeName(parent_idx)));1774      inlinee_name.append("::");1775    }1776    inlinee_name.append(fir.getName().str());1777  }1778  inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(1779      inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),1780      callsite_up.get());1781 1782  m_inline_sites[opaque_uid] = inline_site_sp;1783}1784 1785size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {1786  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1787  PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym();1788  // After we iterate through inline sites inside the function, we already get1789  // all the info needed, removing from the map to save memory.1790  std::set<uint64_t> remove_uids;1791  auto parse_blocks = [&](SymbolKind kind, PdbCompilandSymId id) {1792    if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||1793        kind == S_INLINESITE) {1794      GetOrCreateBlock(id);1795      if (kind == S_INLINESITE)1796        remove_uids.insert(toOpaqueUid(id));1797      return true;1798    }1799    return false;1800  };1801  size_t count = ParseSymbolArrayInScope(func_id, parse_blocks);1802  for (uint64_t uid : remove_uids) {1803    m_inline_sites.erase(uid);1804  }1805 1806  func.GetBlock(false).SetBlockInfoHasBeenParsed(true, true);1807  return count;1808}1809 1810size_t SymbolFileNativePDB::ParseSymbolArrayInScope(1811    PdbCompilandSymId parent_id,1812    llvm::function_ref<bool(SymbolKind, PdbCompilandSymId)> fn) {1813  CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi);1814  CVSymbolArray syms =1815      cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset);1816 1817  size_t count = 1;1818  for (auto iter = syms.begin(); iter != syms.end(); ++iter) {1819    PdbCompilandSymId child_id(parent_id.modi, iter.offset());1820    if (fn(iter->kind(), child_id))1821      ++count;1822  }1823 1824  return count;1825}1826 1827void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter,1828                                       bool show_color) {1829  auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);1830  if (!ts_or_err)1831    return;1832  auto ts = *ts_or_err;1833  TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());1834  if (!clang)1835    return;1836  clang->GetNativePDBParser()->Dump(s, filter, show_color);1837}1838 1839void SymbolFileNativePDB::CacheGlobalBaseNames() {1840  if (!m_func_full_names.IsEmpty() || !m_global_variable_base_names.IsEmpty())1841    return;1842 1843  // (segment, code offset) -> gid1844  std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids;1845 1846  // First, look through all items in the globals table.1847  for (const uint32_t gid : m_index->globals().getGlobalsTable()) {1848    CVSymbol sym = m_index->symrecords().readRecord(gid);1849    auto kind = sym.kind();1850 1851    // If this is a global variable, we only need to look at the name1852    llvm::StringRef name;1853    switch (kind) {1854    case SymbolKind::S_GDATA32:1855    case SymbolKind::S_LDATA32: {1856      DataSym data =1857          llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym));1858      name = data.Name;1859      break;1860    }1861    case SymbolKind::S_GTHREAD32:1862    case SymbolKind::S_LTHREAD32: {1863      ThreadLocalDataSym data = llvm::cantFail(1864          SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym));1865      name = data.Name;1866      break;1867    }1868    case SymbolKind::S_CONSTANT: {1869      ConstantSym data =1870          llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym));1871      name = data.Name;1872      break;1873    }1874    default:1875      break;1876    }1877 1878    if (!name.empty()) {1879      llvm::StringRef base = MSVCUndecoratedNameParser::DropScope(name);1880      if (base.empty())1881        base = name;1882 1883      m_global_variable_base_names.Append(ConstString(base), gid);1884      continue;1885    }1886 1887    if (kind != S_PROCREF && kind != S_LPROCREF)1888      continue;1889 1890    // For functions, we need to follow the reference to the procedure and look1891    // at the type1892 1893    ProcRefSym ref =1894        llvm::cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(sym));1895    if (ref.Name.empty())1896      continue;1897 1898    // Find the function this is referencing.1899    CompilandIndexItem &cci =1900        m_index->compilands().GetOrCreateCompiland(ref.modi());1901    auto iter = cci.m_debug_stream.getSymbolArray().at(ref.SymOffset);1902    if (iter == cci.m_debug_stream.getSymbolArray().end())1903      continue;1904    kind = iter->kind();1905    if (kind != S_GPROC32 && kind != S_LPROC32)1906      continue;1907 1908    ProcSym proc =1909        llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*iter));1910    if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)1911      continue;1912    if (proc.Name.empty() || proc.FunctionType.isSimple())1913      continue;1914 1915    // The function/procedure symbol only contains the demangled name.1916    // The mangled names are in the publics table. Save the address of this1917    // function to lookup the mangled name later.1918    func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);1919 1920    llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(proc.Name);1921    if (basename.empty())1922      basename = proc.Name;1923 1924    m_func_base_names.Append(ConstString(basename), gid);1925    m_func_full_names.Append(ConstString(proc.Name), gid);1926 1927    // To see if this is a member function, check the type.1928    auto type = m_index->tpi().getType(proc.FunctionType);1929    if (type.kind() == LF_MFUNCTION) {1930      MemberFunctionRecord mfr;1931      llvm::cantFail(1932          TypeDeserializer::deserializeAs<MemberFunctionRecord>(type, mfr));1933      if (!mfr.getThisType().isNoneType())1934        m_func_method_names.Append(ConstString(basename), gid);1935    }1936  }1937 1938  // The publics stream contains all mangled function names and their address.1939  for (auto pid : m_index->publics().getPublicsTable()) {1940    PdbGlobalSymId global{pid, true};1941    CVSymbol sym = m_index->ReadSymbolRecord(global);1942    auto kind = sym.kind();1943    if (kind != S_PUB32)1944      continue;1945    PublicSym32 pub =1946        llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym));1947    // We only care about mangled names - if the name isn't mangled, it's1948    // already in the full name map.1949    if (!Mangled::IsMangledName(pub.Name))1950      continue;1951 1952    // Check if this symbol is for one of our functions.1953    auto it = func_addr_ids.find({pub.Segment, pub.Offset});1954    if (it != func_addr_ids.end())1955      m_func_full_names.Append(ConstString(pub.Name), it->second);1956  }1957 1958  // Sort them before value searching is working properly.1959  m_func_full_names.Sort(std::less<uint32_t>());1960  m_func_full_names.SizeToFit();1961  m_func_method_names.Sort(std::less<uint32_t>());1962  m_func_method_names.SizeToFit();1963  m_func_base_names.Sort(std::less<uint32_t>());1964  m_func_base_names.SizeToFit();1965  m_global_variable_base_names.Sort(std::less<uint32_t>());1966  m_global_variable_base_names.SizeToFit();1967}1968 1969void SymbolFileNativePDB::FindGlobalVariables(1970    ConstString name, const CompilerDeclContext &parent_decl_ctx,1971    uint32_t max_matches, VariableList &variables) {1972  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1973 1974  CacheGlobalBaseNames();1975 1976  std::vector<uint32_t> results;1977  m_global_variable_base_names.GetValues(name, results);1978 1979  size_t n_matches = 0;1980  for (uint32_t gid : results) {1981    PdbGlobalSymId global(gid, false);1982 1983    if (parent_decl_ctx.IsValid() &&1984        GetDeclContextContainingUID(toOpaqueUid(global)) != parent_decl_ctx)1985      continue;1986 1987    VariableSP var = GetOrCreateGlobalVariable(global);1988    if (!var)1989      continue;1990    variables.AddVariable(var);1991 1992    if (++n_matches >= max_matches)1993      break;1994  }1995}1996 1997void SymbolFileNativePDB::FindFunctions(1998    const Module::LookupInfo &lookup_info,1999    const CompilerDeclContext &parent_decl_ctx, bool include_inlines,2000    SymbolContextList &sc_list) {2001  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2002  ConstString name = lookup_info.GetLookupName();2003  FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();2004  if (name_type_mask & eFunctionNameTypeFull)2005    name = lookup_info.GetName();2006 2007  if (!(name_type_mask & eFunctionNameTypeFull ||2008        name_type_mask & eFunctionNameTypeBase ||2009        name_type_mask & eFunctionNameTypeMethod))2010    return;2011  CacheGlobalBaseNames();2012 2013  std::set<uint32_t> resolved_ids; // avoid duplicate lookups2014  auto resolve_from = [&](UniqueCStringMap<uint32_t> &Names) {2015    std::vector<uint32_t> ids;2016    if (!Names.GetValues(name, ids))2017      return;2018 2019    for (uint32_t id : ids) {2020      if (!resolved_ids.insert(id).second)2021        continue;2022 2023      PdbGlobalSymId global{id, false};2024      if (parent_decl_ctx.IsValid() &&2025          GetDeclContextContainingUID(toOpaqueUid(global)) != parent_decl_ctx)2026        continue;2027 2028      CVSymbol sym = m_index->ReadSymbolRecord(global);2029      auto kind = sym.kind();2030      lldbassert(kind == S_PROCREF || kind == S_LPROCREF);2031 2032      ProcRefSym proc =2033          cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(sym));2034 2035      if (!IsValidRecord(proc))2036        continue;2037 2038      CompilandIndexItem &cci =2039          m_index->compilands().GetOrCreateCompiland(proc.modi());2040      SymbolContext sc;2041 2042      sc.comp_unit = GetOrCreateCompileUnit(cci).get();2043      if (!sc.comp_unit)2044        continue;2045 2046      PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);2047      sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();2048      if (!sc.function)2049        continue;2050 2051      sc_list.Append(sc);2052    }2053  };2054 2055  if (name_type_mask & eFunctionNameTypeFull)2056    resolve_from(m_func_full_names);2057  if (name_type_mask & eFunctionNameTypeBase)2058    resolve_from(m_func_base_names);2059  if (name_type_mask & eFunctionNameTypeMethod)2060    resolve_from(m_func_method_names);2061}2062 2063void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,2064                                        bool include_inlines,2065                                        SymbolContextList &sc_list) {}2066 2067void SymbolFileNativePDB::FindTypes(const lldb_private::TypeQuery &query,2068                                    lldb_private::TypeResults &results) {2069 2070  // Make sure we haven't already searched this SymbolFile before.2071  if (results.AlreadySearched(this))2072    return;2073 2074  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2075 2076  // We can't query for the full name because the type might reside2077  // in an anonymous namespace. Search for the basename in our map and check the2078  // matching types afterwards.2079  std::vector<uint32_t> matches;2080  m_type_base_names.GetValues(query.GetTypeBasename(), matches);2081 2082  for (uint32_t match_idx : matches) {2083    std::vector context = GetContextForType(TypeIndex(match_idx));2084    if (context.empty())2085      continue;2086 2087    if (query.ContextMatches(context)) {2088      TypeSP type_sp = GetOrCreateType(TypeIndex(match_idx));2089      if (!type_sp)2090        continue;2091 2092      results.InsertUnique(type_sp);2093      if (results.Done(query))2094        return;2095    }2096  }2097}2098 2099void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,2100                                          uint32_t max_matches,2101                                          TypeMap &types) {2102 2103  std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);2104  if (max_matches > 0 && max_matches < matches.size())2105    matches.resize(max_matches);2106 2107  for (TypeIndex ti : matches) {2108    TypeSP type = GetOrCreateType(ti);2109    if (!type)2110      continue;2111 2112    types.Insert(type);2113  }2114}2115 2116size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {2117  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2118  // Only do the full type scan the first time.2119  if (m_done_full_type_scan)2120    return 0;2121 2122  const size_t old_count = GetTypeList().GetSize();2123  LazyRandomTypeCollection &types = m_index->tpi().typeCollection();2124 2125  // First process the entire TPI stream.2126  for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {2127    TypeSP type = GetOrCreateType(*ti);2128    if (type)2129      (void)type->GetFullCompilerType();2130  }2131 2132  // Next look for S_UDT records in the globals stream.2133  for (const uint32_t gid : m_index->globals().getGlobalsTable()) {2134    PdbGlobalSymId global{gid, false};2135    CVSymbol sym = m_index->ReadSymbolRecord(global);2136    if (sym.kind() != S_UDT)2137      continue;2138 2139    UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));2140    bool is_typedef = true;2141    if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {2142      CVType cvt = m_index->tpi().getType(udt.Type);2143      llvm::StringRef name = CVTagRecord::create(cvt).name();2144      if (name == udt.Name)2145        is_typedef = false;2146    }2147 2148    if (is_typedef)2149      GetOrCreateTypedef(global);2150  }2151 2152  const size_t new_count = GetTypeList().GetSize();2153 2154  m_done_full_type_scan = true;2155 2156  return new_count - old_count;2157}2158 2159size_t2160SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,2161                                                  VariableList &variables) {2162  PdbSymUid sym_uid(comp_unit.GetID());2163  lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);2164  for (const uint32_t gid : m_index->globals().getGlobalsTable()) {2165    PdbGlobalSymId global{gid, false};2166    CVSymbol sym = m_index->ReadSymbolRecord(global);2167    // TODO: S_CONSTANT is not handled here to prevent a possible crash in2168    // lldb_private::npdb::MakeConstantLocationExpression when it's a record2169    // type (e.g. std::strong_ordering::equal). That function needs to be2170    // updated to handle this case when we add S_CONSTANT case here.2171    switch (sym.kind()) {2172    case SymbolKind::S_GDATA32:2173    case SymbolKind::S_LDATA32:2174    case SymbolKind::S_GTHREAD32:2175    case SymbolKind::S_LTHREAD32: {2176      if (VariableSP var = GetOrCreateGlobalVariable(global))2177        variables.AddVariable(var);2178      break;2179    }2180    default:2181      break;2182    }2183  }2184  return variables.GetSize();2185}2186 2187VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,2188                                                    PdbCompilandSymId var_id,2189                                                    bool is_param) {2190  ModuleSP module = GetObjectFile()->GetModule();2191  Block *block = GetOrCreateBlock(scope_id);2192  if (!block)2193    return nullptr;2194 2195  // Get function block.2196  Block *func_block = block;2197  while (func_block->GetParent()) {2198    func_block = func_block->GetParent();2199  }2200 2201  Address addr;2202  func_block->GetStartAddress(addr);2203  VariableInfo var_info =2204      GetVariableLocationInfo(*m_index, var_id, *func_block, module);2205  Function *func = func_block->CalculateSymbolContextFunction();2206  if (!func)2207    return nullptr;2208  // Use empty dwarf expr if optimized away so that it won't be filtered out2209  // when lookuping local variables in this scope.2210  if (!var_info.location.IsValid())2211    var_info.location = DWARFExpressionList(module, DWARFExpression(), nullptr);2212  var_info.location.SetFuncFileAddress(func->GetAddress().GetFileAddress());2213  CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);2214  CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);2215  TypeSP type_sp = GetOrCreateType(var_info.type);2216  if (!type_sp)2217    return nullptr;2218  std::string name = var_info.name.str();2219  Declaration decl;2220  SymbolFileTypeSP sftype =2221      std::make_shared<SymbolFileType>(*this, type_sp->GetID());2222 2223  is_param |= var_info.is_param;2224  ValueType var_scope =2225      is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;2226  bool external = false;2227  bool artificial = false;2228  bool location_is_constant_data = false;2229  bool static_member = false;2230  Variable::RangeList scope_ranges;2231  VariableSP var_sp = std::make_shared<Variable>(2232      toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, block,2233      scope_ranges, &decl, var_info.location, external, artificial,2234      location_is_constant_data, static_member);2235  if (!is_param) {2236    auto ts_or_err = GetTypeSystemForLanguage(comp_unit_sp->GetLanguage());2237    if (auto err = ts_or_err.takeError())2238      return nullptr;2239    auto ts = *ts_or_err;2240    if (!ts)2241      return nullptr;2242 2243    ts->GetNativePDBParser()->GetOrCreateVariableDecl(scope_id, var_id);2244  }2245  m_local_variables[toOpaqueUid(var_id)] = var_sp;2246  return var_sp;2247}2248 2249VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable(2250    PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {2251  auto iter = m_local_variables.find(toOpaqueUid(var_id));2252  if (iter != m_local_variables.end())2253    return iter->second;2254 2255  return CreateLocalVariable(scope_id, var_id, is_param);2256}2257 2258TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {2259  CVSymbol sym = m_index->ReadSymbolRecord(id);2260  lldbassert(sym.kind() == SymbolKind::S_UDT);2261 2262  UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));2263 2264  TypeSP target_type = GetOrCreateType(udt.Type);2265 2266  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);2267  if (auto err = ts_or_err.takeError())2268    return nullptr;2269  auto ts = *ts_or_err;2270  if (!ts)2271    return nullptr;2272 2273  auto *typedef_decl = ts->GetNativePDBParser()->GetOrCreateTypedefDecl(id);2274 2275  CompilerType ct = target_type->GetForwardCompilerType();2276  if (auto *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get()))2277    ct = clang->GetType(clang->getASTContext().getTypeDeclType(typedef_decl));2278 2279  Declaration decl;2280  return MakeType(toOpaqueUid(id), ConstString(udt.Name),2281                  llvm::expectedToOptional(target_type->GetByteSize(nullptr)),2282                  nullptr, target_type->GetID(),2283                  lldb_private::Type::eEncodingIsTypedefUID, decl, ct,2284                  lldb_private::Type::ResolveState::Forward);2285}2286 2287TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) {2288  auto iter = m_types.find(toOpaqueUid(id));2289  if (iter != m_types.end())2290    return iter->second;2291 2292  return CreateTypedef(id);2293}2294 2295size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {2296  Block *block = GetOrCreateBlock(block_id);2297  if (!block)2298    return 0;2299 2300  size_t count = 0;2301 2302  CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);2303  CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);2304  uint32_t params_remaining = 0;2305  switch (sym.kind()) {2306  case S_GPROC32:2307  case S_LPROC32: {2308    ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));2309    cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));2310    CVType signature = m_index->tpi().getType(proc.FunctionType);2311    if (signature.kind() == LF_PROCEDURE) {2312      ProcedureRecord sig;2313      if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(2314              signature, sig)) {2315        llvm::consumeError(std::move(e));2316        return 0;2317      }2318      params_remaining = sig.getParameterCount();2319    } else if (signature.kind() == LF_MFUNCTION) {2320      MemberFunctionRecord sig;2321      if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(2322              signature, sig)) {2323        llvm::consumeError(std::move(e));2324        return 0;2325      }2326      params_remaining = sig.getParameterCount();2327    } else2328      return 0;2329    break;2330  }2331  case S_BLOCK32:2332    break;2333  case S_INLINESITE:2334    break;2335  default:2336    lldbassert(false && "Symbol is not a block!");2337    return 0;2338  }2339 2340  VariableListSP variables = block->GetBlockVariableList(false);2341  if (!variables) {2342    variables = std::make_shared<VariableList>();2343    block->SetVariableList(variables);2344  }2345 2346  CVSymbolArray syms = limitSymbolArrayToScope(2347      cii->m_debug_stream.getSymbolArray(), block_id.offset);2348 2349  // Skip the first record since it's a PROC32 or BLOCK32, and there's2350  // no point examining it since we know it's not a local variable.2351  syms.drop_front();2352  auto iter = syms.begin();2353  auto end = syms.end();2354 2355  while (iter != end) {2356    uint32_t record_offset = iter.offset();2357    CVSymbol variable_cvs = *iter;2358    PdbCompilandSymId child_sym_id(block_id.modi, record_offset);2359    ++iter;2360 2361    // If this is a block or inline site, recurse into its children and then2362    // skip it.2363    if (variable_cvs.kind() == S_BLOCK32 ||2364        variable_cvs.kind() == S_INLINESITE) {2365      uint32_t block_end = getScopeEndOffset(variable_cvs);2366      count += ParseVariablesForBlock(child_sym_id);2367      iter = syms.at(block_end);2368      continue;2369    }2370 2371    bool is_param = params_remaining > 0;2372    VariableSP variable;2373    switch (variable_cvs.kind()) {2374    case S_REGREL32:2375    case S_REGISTER:2376    case S_LOCAL:2377      variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);2378      if (is_param)2379        --params_remaining;2380      if (variable)2381        variables->AddVariableIfUnique(variable);2382      break;2383    default:2384      break;2385    }2386  }2387 2388  // Pass false for set_children, since we call this recursively so that the2389  // children will call this for themselves.2390  block->SetDidParseVariables(true, false);2391 2392  return count;2393}2394 2395size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {2396  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2397  lldbassert(sc.function || sc.comp_unit);2398 2399  VariableListSP variables;2400  if (sc.block) {2401    PdbSymUid block_id(sc.block->GetID());2402 2403    size_t count = ParseVariablesForBlock(block_id.asCompilandSym());2404    return count;2405  }2406 2407  if (sc.function) {2408    PdbSymUid block_id(sc.function->GetID());2409 2410    size_t count = ParseVariablesForBlock(block_id.asCompilandSym());2411    return count;2412  }2413 2414  if (sc.comp_unit) {2415    variables = sc.comp_unit->GetVariableList(false);2416    if (!variables) {2417      variables = std::make_shared<VariableList>();2418      sc.comp_unit->SetVariableList(variables);2419    }2420    return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);2421  }2422 2423  llvm_unreachable("Unreachable!");2424}2425 2426CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {2427  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);2428  if (auto err = ts_or_err.takeError())2429    return CompilerDecl();2430  auto ts = *ts_or_err;2431  if (!ts)2432    return {};2433 2434  if (auto decl = ts->GetNativePDBParser()->GetOrCreateDeclForUid(uid))2435    return *decl;2436  return CompilerDecl();2437}2438 2439CompilerDeclContext2440SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {2441  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);2442  if (auto err = ts_or_err.takeError())2443    return {};2444  auto ts = *ts_or_err;2445  if (!ts)2446    return {};2447 2448  PdbAstBuilder *ast_builder = ts->GetNativePDBParser();2449  clang::DeclContext *context =2450      ast_builder->GetOrCreateDeclContextForUid(PdbSymUid(uid));2451  if (!context)2452    return {};2453 2454  return ast_builder->ToCompilerDeclContext(*context);2455}2456 2457CompilerDeclContext2458SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {2459  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);2460  if (auto err = ts_or_err.takeError())2461    return CompilerDeclContext();2462  auto ts = *ts_or_err;2463  if (!ts)2464    return {};2465 2466  PdbAstBuilder *ast_builder = ts->GetNativePDBParser();2467  clang::DeclContext *context = ast_builder->GetParentDeclContext(PdbSymUid(uid));2468  if (!context)2469    return CompilerDeclContext();2470  return ast_builder->ToCompilerDeclContext(*context);2471}2472 2473Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {2474  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2475  auto iter = m_types.find(type_uid);2476  // lldb should not be passing us non-sensical type uids.  the only way it2477  // could have a type uid in the first place is if we handed it out, in which2478  // case we should know about the type.  However, that doesn't mean we've2479  // instantiated it yet.  We can vend out a UID for a future type.  So if the2480  // type doesn't exist, let's instantiate it now.2481  if (iter != m_types.end())2482    return &*iter->second;2483 2484  PdbSymUid uid(type_uid);2485  lldbassert(uid.kind() == PdbSymUidKind::Type);2486  PdbTypeSymId type_id = uid.asTypeSym();2487  if (type_id.index.isNoneType())2488    return nullptr;2489 2490  TypeSP type_sp = CreateAndCacheType(type_id);2491  if (!type_sp)2492    return nullptr;2493  return &*type_sp;2494}2495 2496std::optional<SymbolFile::ArrayInfo>2497SymbolFileNativePDB::GetDynamicArrayInfoForUID(2498    lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {2499  return std::nullopt;2500}2501 2502bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {2503  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2504  auto clang_type_system = compiler_type.GetTypeSystem<TypeSystemClang>();2505  if (!clang_type_system)2506    return false;2507 2508  PdbAstBuilder *ast_builder =2509      static_cast<PdbAstBuilder *>(clang_type_system->GetNativePDBParser());2510  if (ast_builder &&2511      ast_builder->GetClangASTImporter().CanImport(compiler_type))2512    return ast_builder->GetClangASTImporter().CompleteType(compiler_type);2513  clang::QualType qt =2514      clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType());2515 2516  return ast_builder->CompleteType(qt);2517}2518 2519void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,2520                                   TypeClass type_mask,2521                                   lldb_private::TypeList &type_list) {}2522 2523CompilerDeclContext2524SymbolFileNativePDB::FindNamespace(ConstString name,2525                                   const CompilerDeclContext &parent_decl_ctx,2526                                   bool /* only_root_namespaces */) {2527  std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());2528  auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);2529  if (auto err = ts_or_err.takeError())2530    return {};2531  auto ts = *ts_or_err;2532  if (!ts)2533    return {};2534  auto *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());2535  if (!clang)2536    return {};2537 2538  PdbAstBuilder *ast_builder = clang->GetNativePDBParser();2539  if (!ast_builder)2540    return {};2541 2542  clang::DeclContext *decl_context = nullptr;2543  if (parent_decl_ctx)2544    decl_context = static_cast<clang::DeclContext *>(2545        parent_decl_ctx.GetOpaqueDeclContext());2546 2547  auto *namespace_decl =2548      ast_builder->FindNamespaceDecl(decl_context, name.GetStringRef());2549  if (!namespace_decl)2550    return CompilerDeclContext();2551 2552  return clang->CreateDeclContext(namespace_decl);2553}2554 2555llvm::Expected<lldb::TypeSystemSP>2556SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {2557  auto type_system_or_err =2558      m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);2559  if (type_system_or_err)2560    if (auto ts = *type_system_or_err)2561      ts->SetSymbolFile(this);2562  return type_system_or_err;2563}2564 2565uint64_t SymbolFileNativePDB::GetDebugInfoSize(bool load_all_debug_info) {2566  // PDB files are a separate file that contains all debug info.2567  return m_index->pdb().getFileSize();2568}2569 2570void SymbolFileNativePDB::BuildParentMap() {2571  LazyRandomTypeCollection &types = m_index->tpi().typeCollection();2572 2573  llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;2574  llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;2575 2576  struct RecordIndices {2577    TypeIndex forward;2578    TypeIndex full;2579  };2580 2581  llvm::StringMap<RecordIndices> record_indices;2582 2583  for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {2584    CVType type = types.getType(*ti);2585    if (!IsTagRecord(type))2586      continue;2587 2588    CVTagRecord tag = CVTagRecord::create(type);2589 2590    RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];2591    if (tag.asTag().isForwardRef()) {2592      indices.forward = *ti;2593    } else {2594      indices.full = *ti;2595 2596      auto base_name = MSVCUndecoratedNameParser::DropScope(tag.name());2597      m_type_base_names.Append(ConstString(base_name), ti->getIndex());2598    }2599 2600    if (indices.full != TypeIndex::None() &&2601        indices.forward != TypeIndex::None()) {2602      forward_to_full[indices.forward] = indices.full;2603      full_to_forward[indices.full] = indices.forward;2604    }2605 2606    // We're looking for LF_NESTTYPE records in the field list, so ignore2607    // forward references (no field list), and anything without a nested class2608    // (since there won't be any LF_NESTTYPE records).2609    if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())2610      continue;2611 2612    struct ProcessTpiStream : public TypeVisitorCallbacks {2613      ProcessTpiStream(PdbIndex &index, TypeIndex parent,2614                       const CVTagRecord &parent_cvt,2615                       llvm::DenseMap<TypeIndex, TypeIndex> &parents)2616          : index(index), parents(parents), parent(parent),2617            parent_cvt(parent_cvt) {}2618 2619      PdbIndex &index;2620      llvm::DenseMap<TypeIndex, TypeIndex> &parents;2621 2622      unsigned unnamed_type_index = 1;2623      TypeIndex parent;2624      const CVTagRecord &parent_cvt;2625 2626      llvm::Error visitKnownMember(CVMemberRecord &CVR,2627                                   NestedTypeRecord &Record) override {2628        std::string unnamed_type_name;2629        if (Record.Name.empty()) {2630          unnamed_type_name =2631              llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();2632          Record.Name = unnamed_type_name;2633          ++unnamed_type_index;2634        }2635        std::optional<CVTagRecord> tag =2636            GetNestedTagDefinition(Record, parent_cvt, index.tpi());2637        if (!tag)2638          return llvm::ErrorSuccess();2639 2640        parents[Record.Type] = parent;2641        return llvm::ErrorSuccess();2642      }2643    };2644 2645    CVType field_list_cvt = m_index->tpi().getType(tag.asTag().FieldList);2646    ProcessTpiStream process(*m_index, *ti, tag, m_parent_types);2647    FieldListRecord field_list;2648    if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(2649            field_list_cvt, field_list))2650      llvm::consumeError(std::move(error));2651    if (llvm::Error error = visitMemberRecordStream(field_list.Data, process))2652      llvm::consumeError(std::move(error));2653  }2654 2655  // After calling Append(), the type-name map needs to be sorted again to be2656  // able to look up a type by its name.2657  m_type_base_names.Sort(std::less<uint32_t>());2658 2659  // Now that we know the forward -> full mapping of all type indices, we can2660  // re-write all the indices.  At the end of this process, we want a mapping2661  // consisting of fwd -> full and full -> full for all child -> parent indices.2662  // We can re-write the values in place, but for the keys, we must save them2663  // off so that we don't modify the map in place while also iterating it.2664  std::vector<TypeIndex> full_keys;2665  std::vector<TypeIndex> fwd_keys;2666  for (auto &entry : m_parent_types) {2667    TypeIndex key = entry.first;2668    TypeIndex value = entry.second;2669 2670    auto iter = forward_to_full.find(value);2671    if (iter != forward_to_full.end())2672      entry.second = iter->second;2673 2674    iter = forward_to_full.find(key);2675    if (iter != forward_to_full.end())2676      fwd_keys.push_back(key);2677    else2678      full_keys.push_back(key);2679  }2680  for (TypeIndex fwd : fwd_keys) {2681    TypeIndex full = forward_to_full[fwd];2682    TypeIndex parent_idx = m_parent_types[fwd];2683    m_parent_types[full] = parent_idx;2684  }2685  for (TypeIndex full : full_keys) {2686    TypeIndex fwd = full_to_forward[full];2687    m_parent_types[fwd] = m_parent_types[full];2688  }2689}2690 2691std::optional<PdbCompilandSymId>2692SymbolFileNativePDB::FindSymbolScope(PdbCompilandSymId id) {2693  CVSymbol sym = m_index->ReadSymbolRecord(id);2694  if (symbolOpensScope(sym.kind())) {2695    // If this exact symbol opens a scope, we can just directly access its2696    // parent.2697    id.offset = getScopeParentOffset(sym);2698    // Global symbols have parent offset of 0.  Return std::nullopt to indicate2699    // this.2700    if (id.offset == 0)2701      return std::nullopt;2702    return id;2703  }2704 2705  // Otherwise we need to start at the beginning and iterate forward until we2706  // reach (or pass) this particular symbol2707  CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(id.modi);2708  const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();2709 2710  auto begin = syms.begin();2711  auto end = syms.at(id.offset);2712  std::vector<PdbCompilandSymId> scope_stack;2713 2714  while (begin != end) {2715    if (begin.offset() > id.offset) {2716      // We passed it.  We couldn't even find this symbol record.2717      lldbassert(false && "Invalid compiland symbol id!");2718      return std::nullopt;2719    }2720 2721    // We haven't found the symbol yet.  Check if we need to open or close the2722    // scope stack.2723    if (symbolOpensScope(begin->kind())) {2724      // We can use the end offset of the scope to determine whether or not2725      // we can just outright skip this entire scope.2726      uint32_t scope_end = getScopeEndOffset(*begin);2727      if (scope_end < id.offset) {2728        begin = syms.at(scope_end);2729      } else {2730        // The symbol we're looking for is somewhere in this scope.2731        scope_stack.emplace_back(id.modi, begin.offset());2732      }2733    } else if (symbolEndsScope(begin->kind())) {2734      scope_stack.pop_back();2735    }2736    ++begin;2737  }2738  if (scope_stack.empty())2739    return std::nullopt;2740  // We have a match!  Return the top of the stack2741  return scope_stack.back();2742}2743 2744std::optional<llvm::codeview::TypeIndex>2745SymbolFileNativePDB::GetParentType(llvm::codeview::TypeIndex ti) {2746  auto parent_iter = m_parent_types.find(ti);2747  if (parent_iter == m_parent_types.end())2748    return std::nullopt;2749  return parent_iter->second;2750}2751 2752std::vector<CompilerContext>2753SymbolFileNativePDB::GetContextForType(TypeIndex ti) {2754  CVType type = m_index->tpi().getType(ti);2755  if (!IsTagRecord(type))2756    return {};2757 2758  CVTagRecord tag = CVTagRecord::create(type);2759 2760  std::optional<Type::ParsedName> parsed_name =2761      Type::GetTypeScopeAndBasename(tag.name());2762  if (!parsed_name)2763    return {{tag.contextKind(), ConstString(tag.name())}};2764 2765  std::vector<CompilerContext> ctx;2766  // assume everything is a namespace at first2767  for (llvm::StringRef scope : parsed_name->scope) {2768    ctx.emplace_back(CompilerContextKind::Namespace, ConstString(scope));2769  }2770  // we know the kind of our own type2771  ctx.emplace_back(tag.contextKind(), ConstString(parsed_name->basename));2772 2773  // try to find the kind of parents2774  for (auto &el : llvm::reverse(llvm::drop_end(ctx))) {2775    std::optional<TypeIndex> parent = GetParentType(ti);2776    if (!parent)2777      break;2778 2779    ti = *parent;2780    type = m_index->tpi().getType(ti);2781    switch (type.kind()) {2782    case LF_CLASS:2783    case LF_STRUCTURE:2784    case LF_INTERFACE:2785      el.kind = CompilerContextKind::ClassOrStruct;2786      continue;2787    case LF_UNION:2788      el.kind = CompilerContextKind::Union;2789      continue;2790    case LF_ENUM:2791      el.kind = CompilerContextKind::Enum;2792      continue;2793    default:2794      break;2795    }2796    break;2797  }2798  return ctx;2799}2800 2801std::optional<llvm::StringRef>2802SymbolFileNativePDB::FindMangledFunctionName(PdbCompilandSymId func_id) {2803  const CompilandIndexItem *cci =2804      m_index->compilands().GetCompiland(func_id.modi);2805  if (!cci)2806    return std::nullopt;2807 2808  CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);2809  if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)2810    return std::nullopt;2811 2812  ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));2813  cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));2814 2815  return FindMangledSymbol(SegmentOffset(proc.Segment, proc.CodeOffset),2816                           proc.FunctionType);2817}2818 2819std::optional<llvm::StringRef>2820SymbolFileNativePDB::FindMangledSymbol(SegmentOffset so,2821                                       TypeIndex function_type) {2822  auto symbol = m_index->publics().findByAddress(m_index->symrecords(),2823                                                 so.segment, so.offset);2824  if (!symbol)2825    return std::nullopt;2826 2827  llvm::StringRef name = symbol->first.Name;2828  // For functions, we might need to strip the mangled name. See2829  // StripMangledFunctionName for more info.2830  if (!function_type.isNoneType() &&2831      (symbol->first.Flags & PublicSymFlags::Function) != PublicSymFlags::None)2832    name = StripMangledFunctionName(name, function_type);2833 2834  return name;2835}2836 2837llvm::StringRef2838SymbolFileNativePDB::StripMangledFunctionName(const llvm::StringRef mangled,2839                                              PdbTypeSymId func_ty) {2840  // "In non-64 bit environments" (on x86 in pactice), __cdecl functions get2841  // prefixed with an underscore. For compilers using LLVM, this happens in LLVM2842  // (as opposed to the compiler frontend). Because of this, DWARF doesn't2843  // contain the "full" mangled name in DW_AT_linkage_name for these functions.2844  // We strip the mangling here for compatibility with DWARF. See2845  // llvm.org/pr161676 and2846  // https://learn.microsoft.com/en-us/cpp/build/reference/decorated-names#FormatC2847 2848  if (!mangled.starts_with('_') ||2849      m_index->dbi().getMachineType() != PDB_Machine::x86)2850    return mangled;2851 2852  CVType cvt = m_index->tpi().getType(func_ty.index);2853  PDB_CallingConv cc = PDB_CallingConv::NearC;2854  if (cvt.kind() == LF_PROCEDURE) {2855    ProcedureRecord proc;2856    if (llvm::Error error =2857            TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, proc))2858      llvm::consumeError(std::move(error));2859    cc = proc.CallConv;2860  } else if (cvt.kind() == LF_MFUNCTION) {2861    MemberFunctionRecord mfunc;2862    if (llvm::Error error =2863            TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfunc))2864      llvm::consumeError(std::move(error));2865    cc = mfunc.CallConv;2866  } else {2867    LLDB_LOG(GetLog(LLDBLog::Symbols), "Unexpected function type, got {0}",2868             cvt.kind());2869    return mangled;2870  }2871 2872  if (cc == PDB_CallingConv::NearC || cc == PDB_CallingConv::FarC)2873    return mangled.drop_front();2874 2875  return mangled;2876}2877 2878void SymbolFileNativePDB::CacheUdtDeclarations() {2879  for (CVType cvt : m_index->ipi().typeArray()) {2880    switch (cvt.kind()) {2881    case LF_UDT_SRC_LINE: {2882      UdtSourceLineRecord udt_src;2883      llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_src));2884      m_udt_declarations.try_emplace(2885          udt_src.UDT, UdtDeclaration{/*FileNameIndex=*/udt_src.SourceFile,2886                                      /*IsIpiIndex=*/true,2887                                      /*Line=*/udt_src.LineNumber});2888    } break;2889    case LF_UDT_MOD_SRC_LINE: {2890      UdtModSourceLineRecord udt_mod_src;2891      llvm::cantFail(TypeDeserializer::deserializeAs(cvt, udt_mod_src));2892      // Some types might be contributed by multiple modules. We assume that2893      // they all point to the same file and line because we can only provide2894      // one location.2895      m_udt_declarations.try_emplace(2896          udt_mod_src.UDT,2897          UdtDeclaration{/*FileNameIndex=*/udt_mod_src.SourceFile,2898                         /*IsIpiIndex=*/false,2899                         /*Line=*/udt_mod_src.LineNumber});2900    } break;2901    default:2902      break;2903    }2904  }2905}2906 2907llvm::Expected<Declaration>2908SymbolFileNativePDB::ResolveUdtDeclaration(PdbTypeSymId type_id) {2909  std::call_once(m_cached_udt_declarations, [this] { CacheUdtDeclarations(); });2910 2911  auto it = m_udt_declarations.find(type_id.index);2912  if (it == m_udt_declarations.end())2913    return llvm::createStringError("No UDT declaration found");2914 2915  llvm::StringRef file_name;2916  if (it->second.IsIpiIndex) {2917    CVType cvt = m_index->ipi().getType(it->second.FileNameIndex);2918    if (cvt.kind() != LF_STRING_ID)2919      return llvm::createStringError("File name was not a LF_STRING_ID");2920 2921    StringIdRecord sid;2922    llvm::cantFail(TypeDeserializer::deserializeAs(cvt, sid));2923    file_name = sid.String;2924  } else {2925    // The file name index is an index into the string table2926    auto string_table = m_index->pdb().getStringTable();2927    if (!string_table)2928      return string_table.takeError();2929 2930    llvm::Expected<llvm::StringRef> string =2931        string_table->getStringTable().getString(2932            it->second.FileNameIndex.getIndex());2933    if (!string)2934      return string.takeError();2935    file_name = *string;2936  }2937 2938  // rustc sets the filename to "<unknown>" for some files2939  if (file_name == "\\<unknown>")2940    return Declaration();2941 2942  return Declaration(FileSpec(file_name), it->second.Line);2943}2944