30#include "clang/Basic/ABI.h"
31#include "llvm/ADT/DenseMap.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/DebugInfo/CodeView/CVRecord.h"
35#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
36#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
37#include "llvm/DebugInfo/CodeView/Formatters.h"
38#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
39#include "llvm/DebugInfo/CodeView/RecordName.h"
40#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
41#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
42#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
43#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
44#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
45#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
46#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
47#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
48#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
49#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
50#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
51#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
52#include "llvm/DebugInfo/PDB/PDB.h"
53#include "llvm/DebugInfo/PDB/PDBTypes.h"
54#include "llvm/Demangle/MicrosoftDemangle.h"
55#include "llvm/Object/COFF.h"
56#include "llvm/Support/Allocator.h"
57#include "llvm/Support/BinaryStreamReader.h"
58#include "llvm/Support/Error.h"
59#include "llvm/Support/ErrorExtras.h"
60#include "llvm/Support/ErrorOr.h"
61#include "llvm/Support/MemoryBuffer.h"
90 case PDB_Lang::ObjCpp:
97static std::optional<std::string>
99 llvm::StringRef exe_path) {
102 if (fs.
Exists(original_pdb_path))
103 return std::string(original_pdb_path);
108 const FileSpec original_pdb_spec(original_pdb_path,
110 .value_or(FileSpec::Style::native));
111 const llvm::StringRef pdb_filename = original_pdb_spec.
GetFilename();
122 for (
const FileSpec &search_dir : search_paths) {
131static std::unique_ptr<PDBFile>
134 using namespace llvm::object;
135 auto expected_binary = createBinary(exe_path);
138 if (!expected_binary) {
139 llvm::consumeError(expected_binary.takeError());
142 OwningBinary<Binary> binary = std::move(*expected_binary);
146 auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
149 const llvm::codeview::DebugInfo *pdb_info =
nullptr;
152 llvm::StringRef pdb_file;
153 if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) {
154 consumeError(std::move(e));
158 std::optional<std::string> resolved_pdb_path =
160 if (!resolved_pdb_path)
169 auto expected_info =
pdb->getPDBInfoStream();
170 if (!expected_info) {
171 llvm::consumeError(expected_info.takeError());
174 llvm::codeview::GUID guid;
175 memcpy(&guid, pdb_info->PDB70.Signature, 16);
177 if (expected_info->getGuid() != guid)
202 case SimpleTypeKind::Boolean128:
204 case SimpleTypeKind::Boolean64:
206 case SimpleTypeKind::Boolean32:
208 case SimpleTypeKind::Boolean16:
210 case SimpleTypeKind::Boolean8:
213 case SimpleTypeKind::Byte:
214 case SimpleTypeKind::UnsignedCharacter:
215 return "unsigned char";
216 case SimpleTypeKind::NarrowCharacter:
218 case SimpleTypeKind::SignedCharacter:
219 case SimpleTypeKind::SByte:
220 return "signed char";
221 case SimpleTypeKind::Character32:
223 case SimpleTypeKind::Character16:
225 case SimpleTypeKind::Character8:
228 case SimpleTypeKind::Complex128:
229 return "_Complex __float128";
230 case SimpleTypeKind::Complex80:
231 return "_Complex long double";
232 case SimpleTypeKind::Complex64:
233 return "_Complex double";
234 case SimpleTypeKind::Complex48:
235 return "_Complex __float48";
236 case SimpleTypeKind::Complex32:
237 case SimpleTypeKind::Complex32PartialPrecision:
238 return "_Complex float";
239 case SimpleTypeKind::Complex16:
240 return "_Complex _Float16";
242 case SimpleTypeKind::Float128:
244 case SimpleTypeKind::Float80:
245 return "long double";
246 case SimpleTypeKind::Float64:
248 case SimpleTypeKind::Float48:
250 case SimpleTypeKind::Float32:
251 case SimpleTypeKind::Float32PartialPrecision:
253 case SimpleTypeKind::Float16:
256 case SimpleTypeKind::Int128Oct:
257 case SimpleTypeKind::Int128:
259 case SimpleTypeKind::Int64:
260 case SimpleTypeKind::Int64Quad:
262 case SimpleTypeKind::Int32Long:
264 case SimpleTypeKind::Int32:
266 case SimpleTypeKind::Int16:
267 case SimpleTypeKind::Int16Short:
270 case SimpleTypeKind::UInt128Oct:
271 case SimpleTypeKind::UInt128:
272 return "unsigned __int128";
273 case SimpleTypeKind::UInt64:
274 case SimpleTypeKind::UInt64Quad:
275 return "unsigned long long";
276 case SimpleTypeKind::UInt32:
278 case SimpleTypeKind::UInt16:
279 case SimpleTypeKind::UInt16Short:
280 return "unsigned short";
281 case SimpleTypeKind::UInt32Long:
282 return "unsigned long";
284 case SimpleTypeKind::HResult:
286 case SimpleTypeKind::Void:
288 case SimpleTypeKind::WideCharacter:
291 case SimpleTypeKind::None:
292 case SimpleTypeKind::NotTranslated:
309static std::optional<CVTagRecord>
328 if (Record.Type.isSimple())
331 CVType cvt = tpi.getType(Record.Type);
340 std::string qname = std::string(parent.
asTag().getUniqueName());
341 if (qname.size() < 4 || child.
asTag().getUniqueName().size() < 4)
347 qname[3] = child.
asTag().getUniqueName()[3];
351 piece += Record.Name;
352 piece.push_back(
'@');
353 qname.insert(4, std::move(piece));
354 if (qname != child.
asTag().UniqueName)
357 return std::move(child);
373 return "Microsoft PDB debug symbol cross-platform file reader.";
389 uint32_t abilities = 0;
397 pdb_file = &
pdb->GetPDBFile();
409 pdb_file->getFilePath(),
410 m_objfile_sp->GetModule()->GetObjectFile()->GetFileSpec().GetPath());
413 if (!expected_index) {
414 llvm::consumeError(expected_index.takeError());
417 m_index = std::move(*expected_index);
426 if (
m_index->dbi().isStripped())
437 m_index->ParseSectionContribs();
439 auto ts_or_err =
m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
441 if (
auto err = ts_or_err.takeError()) {
443 "Failed to initialize: {0}");
445 if (
auto ts = *ts_or_err)
446 ts->SetSymbolFile(
this);
451 const DbiModuleList &modules =
m_index->dbi().modules();
452 uint32_t count = modules.getModuleCount();
459 DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
460 if (last.getModuleName() ==
"* Linker *")
471 if (
auto err = ts_or_err.takeError())
473 auto ts = *ts_or_err;
478 switch (sym.kind()) {
484 return &func->GetBlock(
false);
491 BlockSym block(
static_cast<SymbolRecordKind
>(sym.kind()));
492 if (
auto err = SymbolDeserializer::deserializeAs<BlockSym>(sym, block)) {
494 "Failed to deserialize BlockSym record: {0}");
497 if (block.Parent == 0) {
513 m_index->MakeVirtualAddress(block.Segment, block.CodeOffset);
516 if (block_base >= func_base)
517 child_block->AddRange(
Block::Range(block_base - func_base, block.CodeSize));
520 "S_BLOCK32 at modi: {0:d} offset: {1:d}: adding range "
521 "[{2:x16}-{3:x16}) which has a base that is less than the "
523 "low PC 0x%" PRIx64
". Please file a bug and attach the file at the "
524 "start of this error message",
526 block_base + block.CodeSize, func_base);
530 m_blocks.insert({opaque_block_uid, child_block});
535 comp_unit->GetLineTable();
537 std::shared_ptr<InlineSite> inline_site =
m_inline_sites[opaque_block_uid];
545 for (
size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
546 auto *entry = inline_site->ranges.GetEntryAtIndex(i);
547 child_block->AddRange(
548 Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
550 child_block->FinalizeRanges();
553 Declaration &decl = inline_site->inline_function_info->GetDeclaration();
554 Declaration &callsite = inline_site->inline_function_info->GetCallSite();
555 child_block->SetInlinedFunctionInfo(
556 inline_site->inline_function_info->GetName().GetCString(),
nullptr,
558 m_blocks.insert({opaque_block_uid, child_block});
579 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32) {
595 ProcSym proc(
static_cast<SymbolRecordKind
>(sym_record.kind()));
596 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)) {
598 "Failed to deserialize ProcSym record: {0}");
601 if (proc.FunctionType == TypeIndex::None())
610 SegmentOffset(proc.Segment, proc.CodeOffset), proc.FunctionType);
611 Mangled mangled(mangled_opt.value_or(proc.Name));
613 FunctionSP func_sp = std::make_shared<Function>(
615 func_type.get(), func_addr,
621 if (
auto err = ts_or_err.takeError())
623 auto ts = *ts_or_err;
626 ast_builder->EnsureFunction(func_id);
642 llvm::SmallString<64> source_file_name;
643 if (
auto main_file_or_err =
m_index->compilands().GetMainSourceFile(cci)) {
644 source_file_name = std::move(*main_file_or_err);
647 "Failed to determine main source file: {0}");
649 FileSpec fs(llvm::sys::path::convert_to_slash(
650 source_file_name, llvm::sys::path::Style::windows_backslash));
652 CompUnitSP cu_sp = std::make_shared<CompileUnit>(
653 m_objfile_sp->GetModule(),
nullptr, std::make_shared<SupportFile>(fs),
661 const ModifierRecord &mr,
663 TpiStream &stream =
m_index->tpi();
667 if ((mr.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
669 if ((mr.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)
671 if ((mr.Modifiers & ModifierOptions::Unaligned) != ModifierOptions::None)
672 name +=
"__unaligned ";
674 if (mr.ModifiedType.isSimple())
677 name += computeTypeName(stream.typeCollection(), mr.ModifiedType);
682 llvm::expectedToOptional(modified_type->GetByteSize(
nullptr)),
689 const llvm::codeview::PointerRecord &pr,
695 if (pr.isPointerToMember()) {
696 MemberPointerInfo mpi = pr.getMemberInfo();
709 if (ti == TypeIndex::NullptrT()) {
716 if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
718 uint32_t pointer_size = 0;
719 switch (ti.getSimpleMode()) {
720 case SimpleTypeMode::FarPointer32:
721 case SimpleTypeMode::NearPointer32:
724 case SimpleTypeMode::NearPointer64:
736 if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
748 if (!record.hasUniqueName())
751 llvm::ms_demangle::Demangler demangler;
752 std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());
753 llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
757 llvm::ms_demangle::IdentifierNode *idn =
758 ttn->QualifiedName->getUnqualifiedIdentifier();
759 return idn->toString();
764 const TagRecord &record,
772 decl = std::move(*maybeDecl);
775 "Failed to resolve declaration for '{1}': {0}", uname);
783 const ClassRecord &cr,
789 const UnionRecord &ur,
795 const EnumRecord &er,
802 decl = std::move(*maybeDecl);
805 "Failed to resolve declaration for '{1}': {0}", uname);
811 llvm::expectedToOptional(underlying_type->GetByteSize(
nullptr)),
nullptr,
817 const ArrayRecord &ar,
826 array_sp->SetEncodingType(element_type.get());
831 const MemberFunctionRecord &mfr,
833 if (mfr.ReturnType.isSimple())
844 const ProcedureRecord &pr,
846 if (pr.ReturnType.isSimple())
857 llvm::codeview::TypeIndex arglist_ti) {
858 if (arglist_ti.isNoneType())
861 CVType arglist_cvt =
m_index->tpi().getType(arglist_ti);
862 if (arglist_cvt.kind() != LF_ARGLIST)
867 TypeDeserializer::deserializeAs<ArgListRecord>(arglist_cvt, alr)) {
869 "Failed to deserialize ArgListRecord record ({1}): {0}",
873 for (TypeIndex
id : alr.getIndices())
874 if (!
id.isNoneType() &&
id.isSimple())
879 if (type_id.
index.isSimple())
883 CVType cvt = stream.getType(type_id.
index);
885 if (cvt.kind() == LF_MODIFIER) {
886 ModifierRecord modifier;
888 TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)) {
890 "Failed to deserialize ModifierRecord record ({1}): {0}",
897 if (cvt.kind() == LF_POINTER) {
898 PointerRecord pointer;
900 TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)) {
902 "Failed to deserialize PointerRecord record ({1}): {0}",
911 if (
auto err = TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)) {
913 "Failed to deserialize ClassRecord record ({1}): {0}",
920 if (cvt.kind() == LF_ENUM) {
922 if (
auto err = TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)) {
924 "Failed to deserialize EnumRecord record ({1}): {0}",
931 if (cvt.kind() == LF_UNION) {
933 if (
auto err = TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)) {
935 "Failed to deserialize UnionRecord record ({1}): {0}",
942 if (cvt.kind() == LF_ARRAY) {
944 if (
auto err = TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)) {
946 "Failed to deserialize ArrayRecord record ({1}): {0}",
953 if (cvt.kind() == LF_PROCEDURE) {
955 if (
auto err = TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)) {
957 "Failed to deserialize ProcedureRecord record ({1}): {0}",
963 if (cvt.kind() == LF_MFUNCTION) {
964 MemberFunctionRecord mfr;
966 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)) {
969 "Failed to deserialize MemberFunctionRecord record ({1}): {0}",
982 std::optional<PdbTypeSymId> full_decl_uid;
984 auto expected_full_ti =
985 m_index->tpi().findFullDeclForForwardRef(type_id.
index);
986 if (!expected_full_ti)
987 llvm::consumeError(expected_full_ti.takeError());
988 else if (*expected_full_ti != type_id.
index) {
996 if (full_iter !=
m_types.end()) {
997 TypeSP result = full_iter->second;
1006 PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
1008 if (
auto err = ts_or_err.takeError())
1010 auto ts = *ts_or_err;
1040 return iter->second;
1049 CVSymbol sym =
m_index->symrecords().readRecord(var_id.
offset);
1050 if (sym.kind() == S_CONSTANT)
1056 llvm::StringRef name;
1059 bool is_external =
false;
1061 switch (sym.kind()) {
1066 DataSym ds(sym.kind());
1067 if (
auto err = SymbolDeserializer::deserializeAs<DataSym>(sym, ds)) {
1069 "Failed to deserialize DataSym record: {0}");
1077 addr =
m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
1088 ThreadLocalDataSym tlds(sym.kind());
1090 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)) {
1092 "Failed to deserialize ThreadLocalDataSym record: {0}");
1098 addr =
m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
1107 llvm_unreachable(
"unreachable!");
1111 std::optional<uint16_t> modi =
m_index->GetModuleIndexForVa(addr);
1122 std::make_shared<SymbolFileType>(*
this,
toOpaqueUid(tid));
1125 if (
auto err = ts_or_err.takeError())
1127 auto ts = *ts_or_err;
1130 ast_builder->EnsureVariable(var_id);
1138 bool artificial =
false;
1139 bool location_is_constant_data =
false;
1140 bool static_member =
false;
1141 VariableSP var_sp = std::make_shared<Variable>(
1142 toOpaqueUid(var_id), name.str().c_str(), mangled_name.str().c_str(),
1143 type_sp, scope, comp_unit.get(), ranges, &decl, location, is_external,
1144 artificial, location_is_constant_data, static_member);
1151 const CVSymbol &cvs) {
1152 TpiStream &tpi =
m_index->tpi();
1153 ConstantSym constant(cvs.kind());
1155 if (cvs.kind() != S_CONSTANT)
1159 SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)) {
1161 "Failed to deserialize ConstantSym record: {0}");
1164 std::string global_name(
"::");
1165 global_name += constant.Name;
1168 std::make_shared<SymbolFileType>(*
this,
toOpaqueUid(tid));
1174 constant.Value, module);
1175 if (!location_or_err) {
1177 "Failed to make constant location expression for {1}: {0}",
1183 bool external =
false;
1184 bool artificial =
false;
1185 bool location_is_constant_data =
true;
1186 bool static_member =
false;
1187 VariableSP var_sp = std::make_shared<Variable>(
1188 toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
1190 external, artificial, location_is_constant_data, static_member);
1197 if (emplace_result.second) {
1199 emplace_result.first->second = var_sp;
1204 return emplace_result.first->second;
1214 if (emplace_result.second)
1215 emplace_result.first->second =
CreateFunction(func_id, comp_unit);
1217 return emplace_result.first->second;
1223 auto emplace_result =
1225 if (emplace_result.second) {
1231 return emplace_result.first->second;
1237 return iter->second.get();
1256 assert(index < UINT16_MAX &&
"Invalid compile unit index");
1257 if (index >= UINT16_MAX)
1269 assert(
false &&
"uid of compile unit not a compiland");
1283 auto *section_list =
1284 m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList();
1288 llvm::DenseMap<lldb::addr_t, llvm::SmallVector<uint32_t, 1>> symbols_by_addr;
1289 for (uint32_t i = 0, n = symtab.
GetNumSymbols(); i < n; ++i) {
1295 PublicSym32 last_sym;
1296 size_t last_sym_idx = 0;
1304 auto finish_last_symbol = [&](
const PublicSym32 *next) {
1311 if (next && last_sym.Segment == next->Segment) {
1312 if (next->Offset < last_sym.Offset) {
1314 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1315 "greater than the following offset {3}",
1316 last_sym.Name, last_sym.Segment, last_sym.Offset,
1320 last->
SetByteSize(next->Offset - last_sym.Offset);
1323 if (section_sp->GetByteSize() < last_sym.Offset) {
1325 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1326 "past the end of section '{3}' (size {4})",
1327 last_sym.Name, last_sym.Segment, last_sym.Offset,
1328 section_sp->GetName(), section_sp->GetByteSize());
1331 last->
SetByteSize(section_sp->GetByteSize() - last_sym.Offset);
1336 for (
auto pid :
m_index->publics().getAddressMap()) {
1338 CVSymbol sym =
m_index->ReadSymbolRecord(global);
1339 auto kind = sym.kind();
1340 if (kind != S_PUB32)
1342 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
1345 "Failed to deserialize PublicSym32 record: {0}");
1348 PublicSym32 pub = std::move(*pub_or_err);
1349 finish_last_symbol(&pub);
1351 if (!section_sp || last_sym.Segment != pub.Segment)
1352 section_sp = section_list->FindSectionByID(pub.Segment);
1358 if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||
1359 (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
1377 if (it != symbols_by_addr.end() &&
1378 llvm::any_of(it->second, [&](uint32_t idx) {
1379 Symbol *sym = symtab.SymbolAtIndex(idx);
1380 return sym && sym->GetMangled() == pub_symbol.GetMangled();
1384 last_sym_idx = symtab.
AddSymbol(pub_symbol);
1388 finish_last_symbol(
nullptr);
1395 assert(
false &&
"uid of compile unit not a compiland");
1403 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
1404 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
1413 if (new_count < count) {
1414 assert(
false &&
"less functions after parsing than before");
1417 return new_count - count;
1422 uint32_t flags = eSymbolContextCompUnit;
1423 flags |= eSymbolContextVariable;
1424 flags |= eSymbolContextFunction;
1425 flags |= eSymbolContextBlock;
1426 flags |= eSymbolContextLineEntry;
1427 return (resolve_scope & flags) != 0;
1431 const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
1433 uint32_t resolved_flags = 0;
1437 std::optional<uint16_t> modi =
m_index->GetModuleIndexForVa(file_addr);
1445 resolved_flags |= eSymbolContextCompUnit;
1448 if (resolve_scope & eSymbolContextFunction ||
1449 resolve_scope & eSymbolContextBlock) {
1452 "missing compile unit for symbol at address {0:x}", file_addr);
1455 std::vector<SymbolAndUid> matches =
m_index->FindSymbolsByVa(file_addr);
1459 for (
const auto &match : llvm::reverse(matches)) {
1463 PdbCompilandSymId csid = match.uid.asCompilandSym();
1464 CVSymbol cvs =
m_index->ReadSymbolRecord(csid);
1466 if (type != PDB_SymType::Function && type != PDB_SymType::Block)
1468 if (type == PDB_SymType::Function) {
1473 addr_t offset = file_addr - func_base;
1478 if (type == PDB_SymType::Block) {
1486 addr_t offset = file_addr - func_base;
1491 resolved_flags |= eSymbolContextFunction;
1493 resolved_flags |= eSymbolContextBlock;
1498 if (resolve_scope & eSymbolContextLineEntry) {
1501 "missing compile unit for symbol at address {0:x}", file_addr);
1505 if (line_table->FindLineEntryByAddress(addr, sc.
line_entry))
1506 resolved_flags |= eSymbolContextLineEntry;
1510 return resolved_flags;
1517 const uint32_t prev_size = sc_list.
GetSize();
1518 if (resolve_scope & eSymbolContextCompUnit) {
1527 if (file_spec_matches_cu_file_spec) {
1533 return sc_list.
GetSize() - prev_size;
1544 assert(
false &&
"uid of compile unit not a compiland");
1558 std::set<LineTable::Entry, LineTableEntryComparator> line_set;
1563 for (
const DebugSubsectionRecord &dssr :
1565 if (dssr.kind() != DebugSubsectionKind::Lines)
1568 DebugLinesSubsectionRef lines;
1569 llvm::BinaryStreamReader reader(dssr.getRecordData());
1570 if (
auto EC = lines.initialize(reader)) {
1571 llvm::consumeError(std::move(EC));
1575 const LineFragmentHeader *lfh = lines.header();
1576 uint64_t virtual_addr =
1577 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1581 for (
const LineColumnEntry &group : lines) {
1582 llvm::Expected<uint32_t> file_index_or_err =
1584 if (!file_index_or_err) {
1586 "failed to get file index for line entry: {0}");
1589 uint32_t file_index = file_index_or_err.get();
1590 if (group.LineNumbers.empty()) {
1592 "no line numbers for {0} in modi={1}", group.NameIndex, modi);
1597 for (
const LineNumberEntry &entry : group.LineNumbers) {
1598 LineInfo cur_info(entry.Flags);
1600 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1603 uint64_t addr = virtual_addr + entry.Offset;
1605 bool is_statement = cur_info.isStatement();
1609 uint32_t lno = cur_info.getStartLine();
1612 is_prologue, is_epilogue,
false);
1614 auto iter = line_set.find(new_entry);
1615 if (iter != line_set.end() && iter->is_terminal_entry)
1616 line_set.erase(iter);
1617 line_set.insert(new_entry);
1624 line_entry.
data = {file_index, lno};
1626 LineInfo last_line(group.LineNumbers.back().Flags);
1627 line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
1628 file_index,
false,
false,
false,
false,
true);
1631 line_entry.
SetRangeEnd(virtual_addr + lfh->CodeSize);
1640 const CVSymbolArray &syms = cii->
m_debug_stream.getSymbolArray();
1641 for (
auto iter = syms.begin(); iter != syms.end();) {
1642 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
1647 uint32_t record_offset = iter.offset();
1648 CVSymbol func_record =
1661 if (kind != S_INLINESITE)
1666 for (
const auto &line_entry :
1671 if (!line_entry.is_terminal_entry)
1672 line_set.erase(line_entry);
1673 line_set.insert(line_entry);
1681 iter = syms.at(getScopeEndOffset(func_record));
1687 std::vector<LineTable::Sequence> sequence(1);
1688 for (
const auto &line_entry : line_set) {
1690 sequence.back(), line_entry.file_addr, line_entry.line,
1691 line_entry.column, line_entry.file_idx,
1692 line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
1693 line_entry.is_prologue_end, line_entry.is_epilogue_begin,
1694 line_entry.is_terminal_entry);
1697 std::make_unique<LineTable>(&comp_unit, std::move(sequence));
1699 if (line_table->GetSize() == 0)
1711llvm::Expected<uint32_t>
1715 return llvm::make_error<RawError>(raw_error_code::no_entry);
1717 const auto &checksums = cii.
m_strings.checksums().getArray();
1718 const auto &strings = cii.
m_strings.strings();
1722 auto iter = checksums.at(file_id);
1723 if (iter == checksums.end())
1724 return llvm::make_error<RawError>(raw_error_code::no_entry);
1726 llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
1728 return efn.takeError();
1734 return std::distance(cii.
m_file_list.begin(), fn_iter);
1735 return llvm::make_error<RawError>(raw_error_code::no_entry);
1743 assert(
false &&
"uid of compile unit not a compiland");
1756 f.starts_with(
"/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1758 support_files.
Append(spec);
1764 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1777 CVSymbol sym = cii->
m_debug_stream.readSymbolAtOffset(
id.offset);
1779 if (sym.kind() != S_INLINESITE)
1782 InlineSiteSym inline_site(
static_cast<SymbolRecordKind
>(sym.kind()));
1784 SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)) {
1786 "Failed to deserialize InlineSiteSym record: {0}");
1791 std::shared_ptr<InlineSite> inline_site_sp =
1792 std::make_shared<InlineSite>(parent_id);
1795 auto iter = cii->
m_inline_map.find(inline_site.Inlinee);
1798 InlineeSourceLine inlinee_line = iter->second;
1802 llvm::Expected<uint32_t> file_index_or_err =
1804 if (!file_index_or_err) {
1806 "failed to get file index for inline site: {0}");
1809 uint32_t file_offset = file_index_or_err.get();
1811 uint32_t decl_line = inlinee_line.Header->SourceLineNum;
1812 std::unique_ptr<Declaration> decl_up =
1813 std::make_unique<Declaration>(decl_file, decl_line);
1816 uint32_t code_offset = 0;
1817 int32_t line_offset = 0;
1818 std::optional<uint32_t> code_offset_base;
1819 std::optional<uint32_t> code_offset_end;
1820 std::optional<int32_t> cur_line_offset;
1821 std::optional<int32_t> next_line_offset;
1822 std::optional<uint32_t> next_file_offset;
1824 bool is_terminal_entry =
false;
1825 bool is_start_of_statement =
true;
1827 bool is_prologue_end =
true;
1829 auto update_code_offset = [&](uint32_t code_delta) {
1830 if (!code_offset_base)
1831 code_offset_base = code_offset;
1832 else if (!code_offset_end)
1833 code_offset_end = *code_offset_base + code_delta;
1835 auto update_line_offset = [&](int32_t line_delta) {
1836 line_offset += line_delta;
1837 if (!code_offset_base || !cur_line_offset)
1838 cur_line_offset = line_offset;
1840 next_line_offset = line_offset;
1843 auto update_file_offset = [&](uint32_t offset) {
1844 if (!code_offset_base)
1845 file_offset = offset;
1847 next_file_offset = offset;
1850 for (
auto &annot : inline_site.annotations()) {
1851 switch (annot.OpCode) {
1852 case BinaryAnnotationsOpCode::CodeOffset:
1853 case BinaryAnnotationsOpCode::ChangeCodeOffset:
1854 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
1855 code_offset += annot.U1;
1856 update_code_offset(annot.U1);
1858 case BinaryAnnotationsOpCode::ChangeLineOffset:
1859 update_line_offset(annot.S1);
1861 case BinaryAnnotationsOpCode::ChangeCodeLength:
1862 update_code_offset(annot.U1);
1863 code_offset += annot.U1;
1864 is_terminal_entry =
true;
1866 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
1867 code_offset += annot.U1;
1868 update_code_offset(annot.U1);
1869 update_line_offset(annot.S1);
1871 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
1872 code_offset += annot.U2;
1873 update_code_offset(annot.U2);
1874 update_code_offset(annot.U1);
1875 code_offset += annot.U1;
1876 is_terminal_entry =
true;
1878 case BinaryAnnotationsOpCode::ChangeFile:
1879 update_file_offset(annot.U1);
1886 if (code_offset_base && code_offset_end && cur_line_offset) {
1888 *code_offset_base, *code_offset_end - *code_offset_base,
1889 decl_line + *cur_line_offset));
1891 if (next_file_offset)
1892 file_offset = *next_file_offset;
1893 if (next_line_offset) {
1894 cur_line_offset = next_line_offset;
1895 next_line_offset = std::nullopt;
1897 code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;
1898 code_offset_end = next_file_offset = std::nullopt;
1900 if (code_offset_base && cur_line_offset) {
1901 if (is_terminal_entry) {
1903 func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
1904 file_offset,
false,
false,
false,
false,
true);
1905 inline_site_sp->line_entries.push_back(line_entry);
1908 decl_line + *cur_line_offset, 0,
1909 file_offset, is_start_of_statement,
false,
1910 is_prologue_end,
false,
false);
1911 inline_site_sp->line_entries.push_back(line_entry);
1912 is_prologue_end =
false;
1913 is_start_of_statement =
false;
1916 if (is_terminal_entry)
1917 is_start_of_statement =
true;
1918 is_terminal_entry =
false;
1921 inline_site_sp->ranges.Sort();
1924 std::unique_ptr<Declaration> callsite_up;
1925 if (!inline_site_sp->ranges.IsEmpty()) {
1926 auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
1927 addr_t base_offset = entry->GetRangeBase();
1933 std::shared_ptr<InlineSite> parent_site =
1936 parent_site->inline_function_info->GetDeclaration().GetFile();
1937 if (
auto *parent_entry =
1938 parent_site->ranges.FindEntryThatContains(base_offset)) {
1940 std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
1945 func_base + base_offset)) {
1949 std::make_unique<Declaration>(callsite_file, entry->data.second);
1955 std::string inlinee_name;
1956 llvm::Expected<CVType> inlinee_cvt =
1957 m_index->ipi().typeCollection().getTypeOrError(inline_site.Inlinee);
1959 inlinee_name =
"[error reading function name: " +
1960 llvm::toString(inlinee_cvt.takeError()) +
"]";
1961 }
else if (inlinee_cvt->kind() == LF_MFUNC_ID) {
1962 MemberFuncIdRecord mfr;
1963 if (
auto err = TypeDeserializer::deserializeAs<MemberFuncIdRecord>(
1964 *inlinee_cvt, mfr)) {
1966 "[error reading function name: " + llvm::toString(std::move(err)) +
1969 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
1970 inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
1971 inlinee_name.append(
"::");
1972 inlinee_name.append(mfr.getName().str());
1974 }
else if (inlinee_cvt->kind() == LF_FUNC_ID) {
1977 TypeDeserializer::deserializeAs<FuncIdRecord>(*inlinee_cvt, fir)) {
1979 "[error reading function name: " + llvm::toString(std::move(err)) +
1982 TypeIndex parent_idx = fir.getParentScope();
1983 if (!parent_idx.isNoneType()) {
1984 LazyRandomTypeCollection &ids =
m_index->ipi().typeCollection();
1985 inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
1986 inlinee_name.append(
"::");
1988 inlinee_name.append(fir.getName().str());
1991 inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
1992 inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
2003 std::set<uint64_t> remove_uids;
2005 if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
2006 kind == S_INLINESITE) {
2008 if (kind == S_INLINESITE)
2015 for (uint64_t uid : remove_uids) {
2027 CVSymbolArray syms =
2031 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
2033 if (fn(iter->kind(), child_id))
2045 "failed to get C++ type system: {0}");
2048 auto ts = *ts_or_err;
2055 ast_builder->
Dump(s, filter, show_color);
2063 std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids;
2066 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2067 CVSymbol sym =
m_index->symrecords().readRecord(gid);
2068 auto kind = sym.kind();
2071 llvm::StringRef name;
2073 case SymbolKind::S_GDATA32:
2074 case SymbolKind::S_LDATA32: {
2075 auto data_or_err = SymbolDeserializer::deserializeAs<DataSym>(sym);
2078 "Failed to deserialize DataSym record: {0}");
2081 name = data_or_err->Name;
2084 case SymbolKind::S_GTHREAD32:
2085 case SymbolKind::S_LTHREAD32: {
2087 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym);
2090 "Failed to deserialize ThreadLocalDataSym record: {0}");
2093 name = data_or_err->Name;
2096 case SymbolKind::S_CONSTANT: {
2097 auto data_or_err = SymbolDeserializer::deserializeAs<ConstantSym>(sym);
2100 "Failed to deserialize ConstantSym record: {0}");
2103 name = data_or_err->Name;
2110 if (!name.empty()) {
2119 if (kind != S_PROCREF && kind != S_LPROCREF)
2125 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2128 "Failed to deserialize ProcRefSym record: {0}");
2131 ProcRefSym ref = std::move(*ref_or_err);
2132 if (ref.Name.empty())
2137 m_index->compilands().GetOrCreateCompiland(ref.modi());
2138 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref.SymOffset);
2141 kind = iter->kind();
2142 if (kind != S_GPROC32 && kind != S_LPROC32)
2145 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
2148 "Failed to deserialize ProcSym record: {0}");
2151 ProcSym proc = std::move(*proc_or_err);
2152 if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)
2154 if (proc.Name.empty() || proc.FunctionType.isSimple())
2160 func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
2163 if (basename.empty())
2164 basename = proc.Name;
2170 auto type =
m_index->tpi().getType(proc.FunctionType);
2171 if (type.kind() == LF_MFUNCTION) {
2172 MemberFunctionRecord mfr;
2173 if (
auto err = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2177 "Failed to deserialize MemberFunctionRecord record ({1}): {0}",
2179 }
else if (!mfr.getThisType().isNoneType())
2185 for (
auto pid :
m_index->publics().getPublicsTable()) {
2187 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2188 auto kind = sym.kind();
2189 if (kind != S_PUB32)
2191 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
2194 "Failed to deserialize PublicSym32 record: {0}");
2197 PublicSym32 pub = std::move(*pub_or_err);
2204 auto it = func_addr_ids.find({pub.Segment, pub.Offset});
2205 if (it != func_addr_ids.end())
2227 llvm::StringRef context;
2228 llvm::StringRef basename;
2233 std::vector<uint32_t> results;
2236 size_t n_matches = 0;
2237 for (uint32_t gid : results) {
2240 if (parent_decl_ctx.
IsValid() &&
2247 if (!context.empty() &&
2248 !var->GetName().GetStringRef().contains(name.
GetStringRef()))
2252 if (++n_matches >= max_matches)
2264 if (name_type_mask & eFunctionNameTypeFull)
2267 if (!(name_type_mask & eFunctionNameTypeFull ||
2268 name_type_mask & eFunctionNameTypeBase ||
2269 name_type_mask & eFunctionNameTypeMethod))
2273 std::set<uint32_t> resolved_ids;
2275 std::vector<uint32_t> ids;
2276 if (!Names.GetValues(name, ids))
2279 for (uint32_t
id : ids) {
2280 if (!resolved_ids.insert(
id).second)
2284 if (parent_decl_ctx.
IsValid() &&
2288 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2289 auto kind = sym.kind();
2290 if (kind != S_PROCREF && kind != S_LPROCREF) {
2296 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2299 "Failed to deserialize ProcRefSym record: {0}");
2302 ProcRefSym proc = std::move(*proc_or_err);
2308 m_index->compilands().GetOrCreateCompiland(proc.modi());
2324 if (name_type_mask & eFunctionNameTypeFull)
2326 if (name_type_mask & eFunctionNameTypeBase)
2328 if (name_type_mask & eFunctionNameTypeMethod)
2333 bool include_inlines,
2350 std::vector<uint32_t> matches;
2353 for (uint32_t match_idx : matches) {
2355 if (context.empty())
2364 if (results.
Done(query))
2371 uint32_t max_matches,
2374 std::vector<TypeIndex> matches =
m_index->tpi().findRecordsByName(name);
2375 if (max_matches > 0 && max_matches < matches.size())
2376 matches.resize(max_matches);
2378 for (TypeIndex ti : matches) {
2394 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
2397 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2400 (void)type->GetFullCompilerType();
2404 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2406 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2407 if (sym.kind() != S_UDT)
2410 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2413 "Failed to deserialize UDTSym record: {0}");
2416 UDTSym udt = std::move(*udt_or_err);
2417 bool is_typedef =
true;
2419 CVType cvt =
m_index->tpi().getType(udt.Type);
2421 if (name == udt.Name)
2433 return new_count - old_count;
2439 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2441 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2446 switch (sym.kind()) {
2447 case SymbolKind::S_GDATA32:
2448 case SymbolKind::S_LDATA32:
2449 case SymbolKind::S_GTHREAD32:
2450 case SymbolKind::S_LTHREAD32: {
2452 if (var && var->GetSymbolContextScope() == &comp_unit)
2478 bool location_is_constant_data = is_constant;
2482 if (sym.kind() != S_CONSTANT)
2484 ConstantSym constant(sym.kind());
2486 SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant)) {
2488 "Failed to deserialize ConstantSym record: {0}");
2492 var_info.
name = constant.Name;
2493 var_info.
type = constant.Type;
2495 constant.Type,
m_index->tpi(), constant.Value, module);
2496 if (!location_or_err) {
2498 "Failed to make constant location expression for {1}: {0}",
2506 Block *func_block = block;
2527 std::string name = var_info.
name.str();
2530 std::make_shared<SymbolFileType>(*
this, type_sp->GetID());
2535 bool external =
false;
2536 bool artificial =
false;
2537 bool static_member =
false;
2539 VariableSP var_sp = std::make_shared<Variable>(
2540 toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, block,
2541 scope_ranges, &decl, var_info.
location, external, artificial,
2542 location_is_constant_data, static_member);
2545 if (
auto err = ts_or_err.takeError())
2547 auto ts = *ts_or_err;
2550 ast_builder->EnsureVariable(scope_id, var_id);
2560 bool is_param,
bool is_constant) {
2563 return iter->second;
2569 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
2570 if (sym.kind() != S_UDT) {
2575 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2578 "Failed to deserialize UDTSym record: {0}");
2581 UDTSym udt = std::move(*udt_or_err);
2586 if (
auto err = ts_or_err.takeError())
2588 auto ts = *ts_or_err;
2596 ct = target_type->GetForwardCompilerType();
2600 llvm::expectedToOptional(target_type->GetByteSize(
nullptr)),
2601 nullptr, target_type->GetID(),
2609 return iter->second;
2623 uint32_t params_remaining = 0;
2624 switch (sym.kind()) {
2627 ProcSym proc(
static_cast<SymbolRecordKind
>(sym.kind()));
2628 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)) {
2630 "Failed to deserialize ProcSym record: {0}");
2633 CVType signature =
m_index->tpi().getType(proc.FunctionType);
2634 if (signature.kind() == LF_PROCEDURE) {
2635 ProcedureRecord sig;
2636 if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(
2638 llvm::consumeError(std::move(e));
2641 params_remaining = sig.getParameterCount();
2642 }
else if (signature.kind() == LF_MFUNCTION) {
2643 MemberFunctionRecord sig;
2644 if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2646 llvm::consumeError(std::move(e));
2649 params_remaining = sig.getParameterCount();
2665 variables = std::make_shared<VariableList>();
2669 CVSymbolArray syms = limitSymbolArrayToScope(
2675 auto iter = syms.begin();
2676 auto end = syms.end();
2678 while (iter != end) {
2679 uint32_t record_offset = iter.offset();
2680 CVSymbol variable_cvs = *iter;
2686 if (variable_cvs.kind() == S_BLOCK32 ||
2687 variable_cvs.kind() == S_INLINESITE) {
2688 uint32_t block_end = getScopeEndOffset(variable_cvs);
2690 iter = syms.at(block_end);
2694 bool is_param = params_remaining > 0;
2696 switch (variable_cvs.kind()) {
2698 case S_REGREL32_INDIR:
2705 variables->AddVariableIfUnique(variable);
2712 variables->AddVariableIfUnique(variable);
2746 variables = std::make_shared<VariableList>();
2753 "missing missing block, function, or module for symbol context");
2759 if (
auto err = ts_or_err.takeError())
2761 auto ts = *ts_or_err;
2773 if (
auto err = ts_or_err.takeError())
2775 auto ts = *ts_or_err;
2787 if (
auto err = ts_or_err.takeError())
2789 auto ts = *ts_or_err;
2800 auto iter =
m_types.find(type_uid);
2807 return &*iter->second;
2811 assert(
false &&
"uid is not a type index");
2815 if (type_id.
index.isNoneType())
2824std::optional<SymbolFile::ArrayInfo>
2827 return std::nullopt;
2843 TypeClass type_mask,
2852 if (
auto err = ts_or_err.takeError())
2854 auto ts = *ts_or_err;
2857 auto *
clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
2868llvm::Expected<lldb::TypeSystemSP>
2870 auto type_system_or_err =
2871 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
2872 if (type_system_or_err)
2873 if (
auto ts = *type_system_or_err)
2874 ts->SetSymbolFile(
this);
2875 return type_system_or_err;
2880 return m_index->pdb().getFileSize();
2888 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
2890 llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
2891 llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
2893 struct RecordIndices {
2898 llvm::StringMap<RecordIndices> record_indices;
2900 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2901 CVType type = types.getType(*ti);
2907 RecordIndices &indices = record_indices[tag.
asTag().getUniqueName()];
2908 if (tag.
asTag().isForwardRef()) {
2909 indices.forward = *ti;
2917 if (indices.full != TypeIndex::None() &&
2918 indices.forward != TypeIndex::None()) {
2919 forward_to_full[indices.forward] = indices.full;
2920 full_to_forward[indices.full] = indices.forward;
2926 if (tag.
asTag().isForwardRef() || !tag.
asTag().containsNestedClass())
2930 ProcessTpiStream(
PdbIndex &index, TypeIndex parent,
2932 llvm::DenseMap<TypeIndex, TypeIndex> &parents)
2933 : index(index), parents(parents), parent(parent),
2934 parent_cvt(parent_cvt) {}
2937 llvm::DenseMap<TypeIndex, TypeIndex> &parents;
2939 unsigned unnamed_type_index = 1;
2943 llvm::Error visitKnownMember(CVMemberRecord &CVR,
2944 NestedTypeRecord &Record)
override {
2945 std::string unnamed_type_name;
2946 if (Record.Name.empty()) {
2948 llvm::formatv(
"<unnamed-type-$S{0}>", unnamed_type_index).str();
2949 Record.Name = unnamed_type_name;
2950 ++unnamed_type_index;
2952 std::optional<CVTagRecord> tag =
2955 return llvm::ErrorSuccess();
2957 parents[Record.Type] = parent;
2958 return llvm::ErrorSuccess();
2962 CVType field_list_cvt =
m_index->tpi().getType(tag.
asTag().FieldList);
2963 if (field_list_cvt.kind() != LF_FIELDLIST)
2967 FieldListRecord field_list;
2968 if (llvm::Error
error = TypeDeserializer::deserializeAs<FieldListRecord>(
2969 field_list_cvt, field_list))
2970 llvm::consumeError(std::move(
error));
2971 if (llvm::Error
error = visitMemberRecordStream(field_list.Data, process))
2972 llvm::consumeError(std::move(
error));
2984 std::vector<TypeIndex> full_keys;
2985 std::vector<TypeIndex> fwd_keys;
2987 TypeIndex key = entry.first;
2988 TypeIndex value = entry.second;
2990 auto iter = forward_to_full.find(value);
2991 if (iter != forward_to_full.end())
2992 entry.second = iter->second;
2994 iter = forward_to_full.find(key);
2995 if (iter != forward_to_full.end())
2996 fwd_keys.push_back(key);
2998 full_keys.push_back(key);
3000 for (TypeIndex fwd : fwd_keys) {
3001 TypeIndex full = forward_to_full[fwd];
3005 for (TypeIndex full : full_keys) {
3006 TypeIndex fwd = full_to_forward[full];
3011std::optional<PdbCompilandSymId>
3013 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
3014 if (symbolOpensScope(sym.kind())) {
3017 id.offset = getScopeParentOffset(sym);
3021 return std::nullopt;
3030 auto begin = syms.begin();
3031 auto end = syms.at(
id.offset);
3032 std::vector<PdbCompilandSymId> scope_stack;
3034 while (begin != end) {
3035 if (begin.offset() >
id.offset) {
3039 return std::nullopt;
3044 if (symbolOpensScope(begin->kind())) {
3047 uint32_t scope_end = getScopeEndOffset(*begin);
3048 if (scope_end <
id.offset) {
3049 begin = syms.at(scope_end);
3052 scope_stack.emplace_back(
id.modi, begin.offset());
3054 }
else if (symbolEndsScope(begin->kind())) {
3055 scope_stack.pop_back();
3059 if (scope_stack.empty())
3060 return std::nullopt;
3062 return scope_stack.back();
3065std::optional<llvm::codeview::TypeIndex>
3070 return std::nullopt;
3071 return parent_iter->second;
3074std::vector<CompilerContext>
3076 CVType type =
m_index->tpi().getType(ti);
3082 std::optional<Type::ParsedName> parsed_name =
3087 std::vector<CompilerContext> ctx;
3089 for (llvm::StringRef scope : parsed_name->scope) {
3096 for (
auto &el : llvm::reverse(llvm::drop_end(ctx))) {
3102 type =
m_index->tpi().getType(ti);
3103 switch (type.kind()) {
3123std::optional<llvm::StringRef>
3125 TypeIndex function_type) {
3126 auto symbol =
m_index->publics().findByAddress(
m_index->symrecords(),
3129 return std::nullopt;
3131 llvm::StringRef name = symbol->first.Name;
3134 if (!function_type.isNoneType() &&
3135 (symbol->first.Flags & PublicSymFlags::Function) != PublicSymFlags::None)
3152 if (!mangled.starts_with(
'_') ||
3153 m_index->dbi().getMachineType() != PDB_Machine::x86)
3157 PDB_CallingConv cc = PDB_CallingConv::NearC;
3158 if (cvt.kind() == LF_PROCEDURE) {
3159 ProcedureRecord proc;
3160 if (llvm::Error
error =
3161 TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, proc))
3162 llvm::consumeError(std::move(
error));
3164 }
else if (cvt.kind() == LF_MFUNCTION) {
3165 MemberFunctionRecord mfunc;
3166 if (llvm::Error
error =
3167 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfunc))
3168 llvm::consumeError(std::move(
error));
3169 cc = mfunc.CallConv;
3176 if (cc == PDB_CallingConv::NearC || cc == PDB_CallingConv::FarC)
3177 return mangled.drop_front();
3184 llvm::StringRef lookup_name) {
3185 if (lookup_name.empty())
3205 CVSymbol sym_record = cci->
m_debug_stream.readSymbolAtOffset(
id.offset);
3206 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)
3209 ProcSym proc(
static_cast<SymbolRecordKind
>(sym_record.kind()));
3210 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)) {
3212 "Failed to deserialize ProcSym record: {0}");
3218 llvm::StringRef lookup_name =
3221 .value_or(proc.Name);
3227 llvm::StringRef qualified_name) {
3228 if (std::optional<PdbCompilandSymId> func_id =
3234std::optional<PdbCompilandSymId>
3236 TypeIndex method_type) {
3239 if (
m_index->globals().getGlobalsTable().HashRecords.empty())
3240 return std::nullopt;
3243 for (
const auto &[offset, sym] :
m_index->globals().findRecordsByName(
3244 qualified_name,
m_index->symrecords())) {
3245 if (sym.kind() != S_PROCREF && sym.kind() != S_LPROCREF)
3247 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
3250 "Failed to deserialize ProcRefSym record: {0}");
3256 m_index->compilands().GetOrCreateCompiland(ref_or_err->modi());
3257 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref_or_err->SymOffset);
3260 if (iter->kind() != S_GPROC32 && iter->kind() != S_LPROC32)
3262 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
3265 "Failed to deserialize ProcSym record: {0}");
3270 if (proc_or_err->FunctionType == method_type)
3273 return std::nullopt;
3276llvm::Expected<SymbolContext>
3283 !discriminator.empty()) {
3284 const bool is_ctor = discriminator.consume_front(
"C");
3286 bool is_defined =
false;
3287 if ((is_ctor || discriminator.consume_front(
"D")) &&
3288 llvm::to_integer(discriminator, kind))
3289 is_defined = is_ctor ? kind == clang::CXXCtorType::Ctor_Complete ||
3290 kind == clang::CXXCtorType::Ctor_Base
3291 : kind == clang::CXXDtorType::Dtor_Complete ||
3292 kind == clang::CXXDtorType::Dtor_Base;
3294 return llvm::createStringErrorV(
3295 "{0} refers to a structor variant without debug info", label);
3300 return llvm::createStringErrorV(
"invalid function ID in {0}", label);
3305 return llvm::createStringErrorV(
"invalid compiland in {0}", label);
3309 return llvm::createStringErrorV(
"failed to create compile unit for {0}",
3314 return llvm::createStringErrorV(
"failed to create function for {0}", label);
3317 func->CalculateSymbolContext(&sc);
3322 for (CVType cvt :
m_index->ipi().typeArray()) {
3323 switch (cvt.kind()) {
3324 case LF_UDT_SRC_LINE: {
3325 UdtSourceLineRecord udt_src;
3326 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_src)) {
3328 "Failed to deserialize UdtSourceLineRecord record: {0}");
3334 udt_src.LineNumber});
3336 case LF_UDT_MOD_SRC_LINE: {
3337 UdtModSourceLineRecord udt_mod_src;
3338 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_mod_src)) {
3341 "Failed to deserialize UdtModSourceLineRecord record: {0}");
3351 udt_mod_src.LineNumber});
3359llvm::Expected<Declaration>
3365 return llvm::createStringError(
"no UDT declaration found");
3367 llvm::StringRef file_name;
3368 if (it->second.IsIpiIndex) {
3369 CVType cvt =
m_index->ipi().getType(it->second.FileNameIndex);
3370 if (cvt.kind() != LF_STRING_ID)
3371 return llvm::createStringError(
"file name was not a LF_STRING_ID");
3374 if (
auto err = TypeDeserializer::deserializeAs(cvt, sid))
3375 return std::move(err);
3376 file_name = sid.String;
3379 auto string_table =
m_index->pdb().getStringTable();
3381 return string_table.takeError();
3383 llvm::Expected<llvm::StringRef>
string =
3384 string_table->getStringTable().getString(
3385 it->second.FileNameIndex.getIndex());
3387 return string.takeError();
3388 file_name = *string;
3392 if (file_name ==
"\\<unknown>")
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
static std::unique_ptr< PDBFile > loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator)
static std::optional< CVTagRecord > GetNestedTagDefinition(const NestedTypeRecord &Record, const CVTagRecord &parent, TpiStream &tpi)
static lldb::LanguageType TranslateLanguage(PDB_Lang lang)
static std::string GetUnqualifiedTypeName(const TagRecord &record)
static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind)
static bool IsClassRecord(TypeLeafKind kind)
static bool IsFunctionEpilogue(const CompilandIndexItem &cci, lldb::addr_t addr)
static bool NeedsResolvedCompileUnit(uint32_t resolve_scope)
static std::optional< std::string > findMatchingPDBFilePath(llvm::StringRef original_pdb_path, llvm::StringRef exe_path)
static bool IsFunctionPrologue(const CompilandIndexItem &cci, lldb::addr_t addr)
static llvm::StringRef DropScope(llvm::StringRef name)
static bool UseNativePDB()
A section + offset based address class.
lldb::addr_t GetFileAddress() const
Get the file address.
bool IsValid() const
Check if the object state is valid.
A class that describes a single lexical block.
lldb::VariableListSP GetBlockVariableList(bool can_create)
Get the variable list for this block only.
Block * FindInnermostBlockByOffset(const lldb::addr_t offset)
void SetBlockInfoHasBeenParsed(bool b, bool set_children)
lldb::BlockSP CreateChild(lldb::user_id_t uid)
Creates a block with the specified UID uid.
Function * CalculateSymbolContextFunction() override
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
Block * GetParent() const
Get the parent block.
bool GetStartAddress(Address &addr)
void SetDidParseVariables(bool b, bool set_children)
static bool ExtractContextAndIdentifier(llvm::StringRef name, llvm::StringRef &context, llvm::StringRef &identifier)
A class that describes a compilation unit.
void SetVariableList(lldb::VariableListSP &variable_list_sp)
Set accessor for the variable list.
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
void ResolveSymbolContext(const SourceLocationSpec &src_location_spec, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list, RealpathPrefixes *realpath_prefixes=nullptr)
Resolve symbol contexts by file and line.
void SetLineTable(LineTable *line_table)
Set the line table for the compile unit.
void AddFunction(lldb::FunctionSP &function_sp)
Add a function to this compile unit.
size_t GetNumFunctions() const
Returns the number of functions in this compile unit.
lldb::LanguageType GetLanguage()
LineTable * GetLineTable()
Get the line table for the compile unit.
Represents a generic declaration context in a program.
TypeSystem * GetTypeSystem() const
Represents a generic declaration such as a function declaration.
Generic representation of a type in a programming language.
TypeSystemSPWrapper GetTypeSystem() const
Accessors.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
bool IsValid() const
Return true if the location expression contains data.
void SetFuncFileAddress(lldb::addr_t func_file_addr)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
A class to manage flag bits.
A class that describes the declaration location of a lldb object.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
static std::optional< Style > GuessPathStyle(llvm::StringRef absolute_path)
Attempt to guess path style for a given path string.
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
llvm::StringRef GetFilename() const
Filename string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
FileSpec CopyByRemovingLastPathComponent() const
llvm::sys::path::Style Style
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
A class that describes a function.
const Address & GetAddress() const
Return the address of the function (its entry point).
Block & GetBlock(bool can_create)
Get accessor for the block list.
static void AppendLineEntryToSequence(Sequence &sequence, lldb::addr_t file_addr, uint32_t line, uint16_t column, uint16_t file_idx, bool is_start_of_statement, bool is_start_of_basic_block, bool is_prologue_end, bool is_epilogue_begin, bool is_terminal_entry)
A class that handles mangled names.
static bool IsMangledName(llvm::StringRef name)
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A class that encapsulates name lookup information.
lldb::FunctionNameType GetNameTypeMask() const
ConstString GetLookupName() const
ConstString GetName() const
static std::unique_ptr< llvm::pdb::PDBFile > loadPDBFile(std::string PdbPath, llvm::BumpPtrAllocator &Allocator)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
RangeData< lldb::addr_t, uint32_t, std::pair< uint32_t, uint32_t > > Entry
void Append(const Entry &entry)
Entry * FindEntryThatContains(B addr)
"lldb/Core/SourceLocationSpec.h" A source location specifier class.
FileSpec GetFileSpec() const
A stream class that can stream formatted output to a file.
A list of support files for a CompileUnit.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
void Append(const FileSpec &file)
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
Block * block
The Block for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
LineEntry line_entry
The LineEntry for a given query.
lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override
ObjectFile * GetObjectFile() override
virtual TypeList & GetTypeList()
lldb::ObjectFileSP m_objfile_sp
void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp)
SymbolFileCommon(lldb::ObjectFileSP objfile_sp)
uint32_t GetNumCompileUnits() override
lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name, std::optional< uint64_t > byte_size, SymbolContextScope *context, lldb::user_id_t encoding_uid, Type::EncodingDataType encoding_uid_type, const Declaration &decl, const CompilerType &compiler_qual_type, Type::ResolveState compiler_type_resolve_state, uint32_t opaque_payload=0) override
This function is used to create types that belong to a SymbolFile.
virtual std::recursive_mutex & GetModuleMutex() const
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
bool ValueIsAddress() const
void SetType(lldb::SymbolType type)
Address & GetAddressRef()
void SetByteSize(lldb::addr_t size)
Symbol * SymbolAtIndex(size_t idx)
uint32_t AddSymbol(const Symbol &symbol)
size_t GetNumSymbols() const
static FileSpecList GetDefaultDebugFileSearchPaths()
void Insert(const lldb::TypeSP &type)
void Insert(const lldb::TypeSP &type)
A class that contains all state required for type lookups.
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
bool ContextMatches(llvm::ArrayRef< lldb_private::CompilerContext > context) const
Check of a CompilerContext array from matching type from a symbol file matches the m_context.
This class tracks the state and results of a TypeQuery.
bool InsertUnique(const lldb::TypeSP &type_sp)
When types that match a TypeQuery are found, this API is used to insert the matching types.
bool Done(const TypeQuery &query) const
Check if the type matching has found all of the matches that it needs.
bool AlreadySearched(lldb_private::SymbolFile *sym_file)
Check if a SymbolFile object has already been searched by this type match object.
A TypeSystem implementation based on Clang.
Interface for representing a type system.
virtual npdb::PdbAstBuilder * GetNativePDBParser()
@ eEncodingIsTypedefUID
This type is alias to a type whose UID is m_encoding_uid.
@ eEncodingIsUID
This type is the type whose UID is m_encoding_uid.
static std::optional< ParsedName > GetTypeScopeAndBasename(llvm::StringRef name)
void AddVariable(const lldb::VariableSP &var_sp)
RangeVector< lldb::addr_t, lldb::addr_t > RangeList
virtual CompilerType GetOrCreateTypedefType(PdbGlobalSymId id)=0
virtual void Dump(Stream &stream, llvm::StringRef filter, bool show_color)=0
virtual CompilerDeclContext FindNamespaceDecl(CompilerDeclContext parent_ctx, llvm::StringRef name)=0
virtual bool CompleteType(CompilerType ct)=0
virtual void EnsureBlock(PdbCompilandSymId block_id)=0
virtual CompilerDeclContext GetParentDeclContext(PdbSymUid uid)=0
virtual CompilerType GetOrCreateType(PdbTypeSymId type)=0
virtual CompilerDecl GetOrCreateDeclForUid(PdbSymUid uid)=0
virtual void EnsureInlinedFunction(PdbCompilandSymId inlinesite_id)=0
virtual void ParseDeclsForContext(CompilerDeclContext context)=0
virtual CompilerDeclContext GetOrCreateDeclContextForUid(PdbSymUid uid)=0
PdbIndex - Lazy access to the important parts of a PDB file.
static llvm::Expected< std::unique_ptr< PdbIndex > > create(llvm::pdb::PDBFile *)
llvm::pdb::TpiStream & tpi()
PdbCompilandId asCompiland() const
PdbCompilandSymId asCompilandSym() const
PdbTypeSymId asTypeSym() const
uint64_t toOpaqueId() const
PdbSymUidKind kind() const
void CreateSimpleArgumentListTypes(llvm::codeview::TypeIndex arglist_ti)
lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id)
bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override
lldb::TypeSP CreateArrayType(PdbTypeSymId type_id, const llvm::codeview::ArrayRecord &ar, CompilerType ct)
std::optional< ArrayInfo > GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) override
If type_uid points to an array type, return its characteristics.
void CacheGlobalBaseNames()
Caches the basenames of symbols found in the globals stream.
llvm::Expected< Declaration > ResolveUdtDeclaration(PdbTypeSymId type_id)
lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id)
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language) override
void InitializeObject() override
Initialize the SymbolFile object.
lldb_private::UniqueCStringMap< uint32_t > m_func_base_names
basename -> Global ID(s)
static SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp)
uint32_t CalculateNumCompileUnits() override
llvm::DenseMap< lldb::user_id_t, lldb::TypeSP > m_types
bool CompleteType(CompilerType &compiler_type) override
lldb::LanguageType ParseLanguage(lldb_private::CompileUnit &comp_unit) override
CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override
void DumpClangAST(Stream &s, llvm::StringRef filter, bool show_color) override
size_t ParseVariablesForContext(const SymbolContext &sc) override
size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override
lldb::TypeSP CreatePointerType(PdbTypeSymId type_id, const llvm::codeview::PointerRecord &pr, CompilerType ct)
lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id, CompileUnit &comp_unit)
llvm::DenseMap< lldb::user_id_t, lldb::BlockSP > m_blocks
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, SupportFileList &support_files) override
CompilerDecl GetDeclForUID(lldb::user_id_t uid) override
SymbolFileNativePDB(lldb::ObjectFileSP objfile_sp)
lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id)
void FindTypesByName(llvm::StringRef name, uint32_t max_matches, TypeMap &types)
lldb::TypeSP CreateTagType(PdbTypeSymId type_id, const llvm::codeview::ClassRecord &cr, CompilerType ct)
lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id)
llvm::BumpPtrAllocator m_allocator
void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list) override
std::string GetFunctionCallLabel(PdbCompilandSymId id)
Build the asm label for the declaration of a function so that calls to it are routed through ResolveF...
llvm::DenseMap< lldb::user_id_t, lldb::VariableSP > m_local_variables
~SymbolFileNativePDB() override
llvm::Expected< SymbolContext > ResolveFunctionCallLabel(FunctionCallLabel &label) override
Resolves the function corresponding to the specified LLDB function call label.
lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id, const llvm::codeview::CVSymbol &cvs)
lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct)
lldb_private::UniqueCStringMap< uint32_t > m_func_method_names
method basename -> Global ID(s)
void AddSymbols(Symtab &symtab) override
std::optional< llvm::codeview::TypeIndex > GetParentType(llvm::codeview::TypeIndex ti)
lldb_private::UniqueCStringMap< uint32_t > m_global_variable_base_names
global variable basename -> Global ID(s)
void FindFunctions(const Module::LookupInfo &lookup_info, const CompilerDeclContext &parent_decl_ctx, bool include_inlines, SymbolContextList &sc_list) override
static llvm::StringRef GetPluginDescriptionStatic()
std::unique_ptr< llvm::pdb::PDBFile > m_file_up
lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id, const llvm::codeview::ProcedureRecord &pr, CompilerType ct)
lldb::TypeSP CreateModifierType(PdbTypeSymId type_id, const llvm::codeview::ModifierRecord &mr, CompilerType ct)
uint64_t GetDebugInfoSize(bool load_all_debug_info=false) override
Metrics gathering functions.
std::optional< llvm::StringRef > FindMangledSymbol(SegmentOffset so, llvm::codeview::TypeIndex function_type=llvm::codeview::TypeIndex())
Find a symbol name at a specific address (so).
size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override
Block * GetOrCreateBlock(PdbCompilandSymId block_id)
lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param, bool is_constant=false)
lldb::addr_t m_obj_load_address
size_t ParseBlocksRecursive(Function &func) override
std::once_flag m_cached_udt_declarations
void CacheUdtDeclarations()
std::optional< PdbCompilandSymId > FindMethodDefinition(llvm::StringRef qualified_name, llvm::codeview::TypeIndex method_type)
Find the S_GPROC32/S_LPROC32 record named qualified_name whose type is method_type.
lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci)
std::optional< PdbCompilandSymId > FindSymbolScope(PdbCompilandSymId id)
size_t ParseSymbolArrayInScope(PdbCompilandSymId parent, llvm::function_ref< bool(llvm::codeview::SymbolKind, PdbCompilandSymId)> fn)
size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit, VariableList &variables)
uint32_t CalculateAbilities() override
llvm::DenseMap< lldb::user_id_t, lldb::CompUnitSP > m_compilands
Block * CreateBlock(PdbCompilandSymId block_id)
std::vector< CompilerContext > GetContextForType(llvm::codeview::TypeIndex ti)
llvm::Expected< uint32_t > GetFileIndex(const CompilandIndexItem &cii, uint32_t file_id)
lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci)
Type * ResolveTypeUID(lldb::user_id_t type_uid) override
llvm::DenseMap< lldb::user_id_t, lldb::FunctionSP > m_functions
bool ParseImportedModules(const SymbolContext &sc, std::vector< lldb_private::SourceModule > &imported_modules) override
llvm::StringRef StripMangledFunctionName(llvm::StringRef mangled, PdbTypeSymId func_ty)
static void DebuggerInitialize(Debugger &debugger)
lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param, bool is_constant=false)
llvm::DenseMap< lldb::user_id_t, std::shared_ptr< InlineSite > > m_inline_sites
void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr)
std::string MakeFunctionCallLabel(PdbSymUid uid, llvm::StringRef lookup_name)
lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id, const llvm::codeview::TagRecord &record, size_t size, CompilerType ct)
void FindGlobalVariables(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) override
static llvm::StringRef GetPluginNameStatic()
size_t ParseVariablesForBlock(PdbCompilandSymId block_id)
void ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override
lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id, CompileUnit &comp_unit)
llvm::DenseMap< llvm::codeview::TypeIndex, llvm::codeview::TypeIndex > m_parent_types
lldb_private::UniqueCStringMap< uint32_t > m_func_full_names
mangled name/full function name -> Global ID(s)
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
lldb::TypeSP CreateFunctionType(PdbTypeSymId type_id, const llvm::codeview::MemberFunctionRecord &pr, CompilerType ct)
lldb_private::UniqueCStringMap< uint32_t > m_type_base_names
lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id)
CompilerDeclContext FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx, bool only_root_namespaces) override
Finds a namespace of name name and whose parent context is parent_decl_ctx.
CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override
bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override
lldb::TypeSP CreateTypedef(PdbGlobalSymId id)
bool m_done_full_type_scan
llvm::DenseMap< llvm::codeview::TypeIndex, UdtDeclaration > m_udt_declarations
void FindTypes(const lldb_private::TypeQuery &match, lldb_private::TypeResults &results) override
Find types using a type-matching object that contains all search parameters.
static char ID
LLVM RTTI support.
std::string GetMethodCallLabel(llvm::codeview::TypeIndex method_type, llvm::StringRef qualified_name)
Build the asm label for a method that was declared in the field list of its class.
uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) override
std::unique_ptr< PdbIndex > m_index
llvm::DenseMap< lldb::user_id_t, lldb::VariableSP > m_global_vars
lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti, CompilerType ct)
#define LLDB_INVALID_ADDRESS
uint64_t toOpaqueUid(const T &cid)
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
SegmentOffsetLength GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym)
bool IsTagRecord(llvm::codeview::CVType cvt)
bool IsValidRecord(const RecordT &sym)
llvm::Expected< DWARFExpression > MakeConstantLocationExpression(llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, const llvm::APSInt &constant, lldb::ModuleSP module)
DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, lldb::ModuleSP module)
VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block &func_block, lldb::ModuleSP module)
bool IsForwardRefUdt(llvm::codeview::CVType cvt)
llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind)
DWARFExpression MakeGlobalThreadLocalLocationExpression(uint32_t offset, const lldb::ModuleSP &module)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::Function > FunctionSP
std::shared_ptr< lldb_private::Block > BlockSP
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeObjC_plus_plus
Objective-C++.
@ eLanguageTypeSwift
Swift.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
@ eLanguageTypeC_plus_plus
ISO C++:1998.
std::shared_ptr< lldb_private::Type > TypeSP
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::SymbolFileType > SymbolFileTypeSP
std::shared_ptr< lldb_private::Variable > VariableSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::Module > ModuleSP
std::shared_ptr< lldb_private::CompileUnit > CompUnitSP
Holds parsed information about a function call label that LLDB attaches as an AsmLabel to function AS...
lldb::user_id_t symbol_id
Unique identifier of the function symbol on which to perform the function call.
std::string toString() const
Encode this FunctionCallLabel into its string representation.
llvm::StringRef discriminator
Arbitrary string which language plugins can interpret for their own needs.
BaseType GetRangeBase() const
void SetRangeEnd(BaseType end)
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
lldb::user_id_t GetID() const
Get accessor for the user ID.
CompilerContextKind contextKind() const
static CVTagRecord create(llvm::codeview::CVType type)
const llvm::codeview::TagRecord & asTag() const
llvm::StringRef name() const
Represents a single compile unit.
std::map< llvm::codeview::TypeIndex, llvm::codeview::InlineeSourceLine > m_inline_map
std::optional< llvm::codeview::Compile3Sym > m_compile_opts
llvm::pdb::ModuleDebugStreamRef m_debug_stream
GlobalLineTable m_global_line_table
llvm::codeview::StringsAndChecksumsRef m_strings
std::vector< llvm::StringRef > m_file_list
llvm::codeview::TypeIndex index
DWARFExpressionList location
llvm::codeview::TypeIndex type