29#include "clang/Basic/ABI.h"
30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/SmallVector.h"
33#include "llvm/DebugInfo/CodeView/CVRecord.h"
34#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
35#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
36#include "llvm/DebugInfo/CodeView/Formatters.h"
37#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
38#include "llvm/DebugInfo/CodeView/RecordName.h"
39#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
40#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
41#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
42#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
43#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
44#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
45#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
46#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
47#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
48#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
49#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
50#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
51#include "llvm/DebugInfo/PDB/PDB.h"
52#include "llvm/DebugInfo/PDB/PDBTypes.h"
53#include "llvm/Demangle/MicrosoftDemangle.h"
54#include "llvm/Object/COFF.h"
55#include "llvm/Support/Allocator.h"
56#include "llvm/Support/BinaryStreamReader.h"
57#include "llvm/Support/Error.h"
58#include "llvm/Support/ErrorExtras.h"
59#include "llvm/Support/ErrorOr.h"
60#include "llvm/Support/MemoryBuffer.h"
89 case PDB_Lang::ObjCpp:
96static std::optional<std::string>
98 llvm::StringRef exe_path) {
101 if (fs.
Exists(original_pdb_path))
102 return std::string(original_pdb_path);
107 const FileSpec original_pdb_spec(original_pdb_path,
109 .value_or(FileSpec::Style::native));
110 const llvm::StringRef pdb_filename = original_pdb_spec.
GetFilename();
121 for (
const FileSpec &search_dir : search_paths) {
130static std::unique_ptr<PDBFile>
133 using namespace llvm::object;
134 auto expected_binary = createBinary(exe_path);
137 if (!expected_binary) {
138 llvm::consumeError(expected_binary.takeError());
141 OwningBinary<Binary> binary = std::move(*expected_binary);
145 auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
148 const llvm::codeview::DebugInfo *pdb_info =
nullptr;
151 llvm::StringRef pdb_file;
152 if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) {
153 consumeError(std::move(e));
157 std::optional<std::string> resolved_pdb_path =
159 if (!resolved_pdb_path)
168 auto expected_info =
pdb->getPDBInfoStream();
169 if (!expected_info) {
170 llvm::consumeError(expected_info.takeError());
173 llvm::codeview::GUID guid;
174 memcpy(&guid, pdb_info->PDB70.Signature, 16);
176 if (expected_info->getGuid() != guid)
201 case SimpleTypeKind::Boolean128:
203 case SimpleTypeKind::Boolean64:
205 case SimpleTypeKind::Boolean32:
207 case SimpleTypeKind::Boolean16:
209 case SimpleTypeKind::Boolean8:
212 case SimpleTypeKind::Byte:
213 case SimpleTypeKind::UnsignedCharacter:
214 return "unsigned char";
215 case SimpleTypeKind::NarrowCharacter:
217 case SimpleTypeKind::SignedCharacter:
218 case SimpleTypeKind::SByte:
219 return "signed char";
220 case SimpleTypeKind::Character32:
222 case SimpleTypeKind::Character16:
224 case SimpleTypeKind::Character8:
227 case SimpleTypeKind::Complex128:
228 return "_Complex __float128";
229 case SimpleTypeKind::Complex80:
230 return "_Complex long double";
231 case SimpleTypeKind::Complex64:
232 return "_Complex double";
233 case SimpleTypeKind::Complex48:
234 return "_Complex __float48";
235 case SimpleTypeKind::Complex32:
236 case SimpleTypeKind::Complex32PartialPrecision:
237 return "_Complex float";
238 case SimpleTypeKind::Complex16:
239 return "_Complex _Float16";
241 case SimpleTypeKind::Float128:
243 case SimpleTypeKind::Float80:
244 return "long double";
245 case SimpleTypeKind::Float64:
247 case SimpleTypeKind::Float48:
249 case SimpleTypeKind::Float32:
250 case SimpleTypeKind::Float32PartialPrecision:
252 case SimpleTypeKind::Float16:
255 case SimpleTypeKind::Int128Oct:
256 case SimpleTypeKind::Int128:
258 case SimpleTypeKind::Int64:
259 case SimpleTypeKind::Int64Quad:
261 case SimpleTypeKind::Int32Long:
263 case SimpleTypeKind::Int32:
265 case SimpleTypeKind::Int16:
266 case SimpleTypeKind::Int16Short:
269 case SimpleTypeKind::UInt128Oct:
270 case SimpleTypeKind::UInt128:
271 return "unsigned __int128";
272 case SimpleTypeKind::UInt64:
273 case SimpleTypeKind::UInt64Quad:
274 return "unsigned long long";
275 case SimpleTypeKind::UInt32:
277 case SimpleTypeKind::UInt16:
278 case SimpleTypeKind::UInt16Short:
279 return "unsigned short";
280 case SimpleTypeKind::UInt32Long:
281 return "unsigned long";
283 case SimpleTypeKind::HResult:
285 case SimpleTypeKind::Void:
287 case SimpleTypeKind::WideCharacter:
290 case SimpleTypeKind::None:
291 case SimpleTypeKind::NotTranslated:
308static std::optional<CVTagRecord>
327 if (Record.Type.isSimple())
330 CVType cvt = tpi.getType(Record.Type);
339 std::string qname = std::string(parent.
asTag().getUniqueName());
340 if (qname.size() < 4 || child.
asTag().getUniqueName().size() < 4)
346 qname[3] = child.
asTag().getUniqueName()[3];
350 piece += Record.Name;
351 piece.push_back(
'@');
352 qname.insert(4, std::move(piece));
353 if (qname != child.
asTag().UniqueName)
356 return std::move(child);
372 return "Microsoft PDB debug symbol cross-platform file reader.";
388 uint32_t abilities = 0;
396 pdb_file = &
pdb->GetPDBFile();
408 pdb_file->getFilePath(),
409 m_objfile_sp->GetModule()->GetObjectFile()->GetFileSpec().GetPath());
412 if (!expected_index) {
413 llvm::consumeError(expected_index.takeError());
416 m_index = std::move(*expected_index);
425 if (
m_index->dbi().isStripped())
436 m_index->ParseSectionContribs();
438 auto ts_or_err =
m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
440 if (
auto err = ts_or_err.takeError()) {
442 "Failed to initialize: {0}");
444 if (
auto ts = *ts_or_err)
445 ts->SetSymbolFile(
this);
450 const DbiModuleList &modules =
m_index->dbi().modules();
451 uint32_t count = modules.getModuleCount();
458 DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
459 if (last.getModuleName() ==
"* Linker *")
470 if (
auto err = ts_or_err.takeError())
472 auto ts = *ts_or_err;
477 switch (sym.kind()) {
483 return &func->GetBlock(
false);
490 BlockSym block(
static_cast<SymbolRecordKind
>(sym.kind()));
491 if (
auto err = SymbolDeserializer::deserializeAs<BlockSym>(sym, block)) {
493 "Failed to deserialize BlockSym record: {0}");
496 if (block.Parent == 0) {
512 m_index->MakeVirtualAddress(block.Segment, block.CodeOffset);
515 if (block_base >= func_base)
516 child_block->AddRange(
Block::Range(block_base - func_base, block.CodeSize));
519 "S_BLOCK32 at modi: {0:d} offset: {1:d}: adding range "
520 "[{2:x16}-{3:x16}) which has a base that is less than the "
522 "low PC 0x%" PRIx64
". Please file a bug and attach the file at the "
523 "start of this error message",
525 block_base + block.CodeSize, func_base);
529 m_blocks.insert({opaque_block_uid, child_block});
534 comp_unit->GetLineTable();
536 std::shared_ptr<InlineSite> inline_site =
m_inline_sites[opaque_block_uid];
544 for (
size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
545 auto *entry = inline_site->ranges.GetEntryAtIndex(i);
546 child_block->AddRange(
547 Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
549 child_block->FinalizeRanges();
552 Declaration &decl = inline_site->inline_function_info->GetDeclaration();
553 Declaration &callsite = inline_site->inline_function_info->GetCallSite();
554 child_block->SetInlinedFunctionInfo(
555 inline_site->inline_function_info->GetName().GetCString(),
nullptr,
557 m_blocks.insert({opaque_block_uid, child_block});
578 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32) {
594 ProcSym proc(
static_cast<SymbolRecordKind
>(sym_record.kind()));
595 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)) {
597 "Failed to deserialize ProcSym record: {0}");
600 if (proc.FunctionType == TypeIndex::None())
609 SegmentOffset(proc.Segment, proc.CodeOffset), proc.FunctionType);
610 Mangled mangled(mangled_opt.value_or(proc.Name));
612 FunctionSP func_sp = std::make_shared<Function>(
614 func_type.get(), func_addr,
620 if (
auto err = ts_or_err.takeError())
622 auto ts = *ts_or_err;
625 ast_builder->EnsureFunction(func_id);
641 llvm::SmallString<64> source_file_name;
642 if (
auto main_file_or_err =
m_index->compilands().GetMainSourceFile(cci)) {
643 source_file_name = std::move(*main_file_or_err);
646 "Failed to determine main source file: {0}");
648 FileSpec fs(llvm::sys::path::convert_to_slash(
649 source_file_name, llvm::sys::path::Style::windows_backslash));
651 CompUnitSP cu_sp = std::make_shared<CompileUnit>(
652 m_objfile_sp->GetModule(),
nullptr, std::make_shared<SupportFile>(fs),
660 const ModifierRecord &mr,
662 TpiStream &stream =
m_index->tpi();
666 if ((mr.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
668 if ((mr.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)
670 if ((mr.Modifiers & ModifierOptions::Unaligned) != ModifierOptions::None)
671 name +=
"__unaligned ";
673 if (mr.ModifiedType.isSimple())
676 name += computeTypeName(stream.typeCollection(), mr.ModifiedType);
681 llvm::expectedToOptional(modified_type->GetByteSize(
nullptr)),
688 const llvm::codeview::PointerRecord &pr,
694 if (pr.isPointerToMember()) {
695 MemberPointerInfo mpi = pr.getMemberInfo();
708 if (ti == TypeIndex::NullptrT()) {
715 if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
717 uint32_t pointer_size = 0;
718 switch (ti.getSimpleMode()) {
719 case SimpleTypeMode::FarPointer32:
720 case SimpleTypeMode::NearPointer32:
723 case SimpleTypeMode::NearPointer64:
735 if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
747 if (!record.hasUniqueName())
750 llvm::ms_demangle::Demangler demangler;
751 std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());
752 llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
756 llvm::ms_demangle::IdentifierNode *idn =
757 ttn->QualifiedName->getUnqualifiedIdentifier();
758 return idn->toString();
763 const TagRecord &record,
771 decl = std::move(*maybeDecl);
774 "Failed to resolve declaration for '{1}': {0}", uname);
782 const ClassRecord &cr,
788 const UnionRecord &ur,
794 const EnumRecord &er,
801 decl = std::move(*maybeDecl);
804 "Failed to resolve declaration for '{1}': {0}", uname);
810 llvm::expectedToOptional(underlying_type->GetByteSize(
nullptr)),
nullptr,
816 const ArrayRecord &ar,
825 array_sp->SetEncodingType(element_type.get());
830 const MemberFunctionRecord &mfr,
832 if (mfr.ReturnType.isSimple())
843 const ProcedureRecord &pr,
845 if (pr.ReturnType.isSimple())
856 llvm::codeview::TypeIndex arglist_ti) {
857 if (arglist_ti.isNoneType())
860 CVType arglist_cvt =
m_index->tpi().getType(arglist_ti);
861 if (arglist_cvt.kind() != LF_ARGLIST)
866 TypeDeserializer::deserializeAs<ArgListRecord>(arglist_cvt, alr)) {
868 "Failed to deserialize ArgListRecord record ({1}): {0}",
872 for (TypeIndex
id : alr.getIndices())
873 if (!
id.isNoneType() &&
id.isSimple())
878 if (type_id.
index.isSimple())
882 CVType cvt = stream.getType(type_id.
index);
884 if (cvt.kind() == LF_MODIFIER) {
885 ModifierRecord modifier;
887 TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)) {
889 "Failed to deserialize ModifierRecord record ({1}): {0}",
896 if (cvt.kind() == LF_POINTER) {
897 PointerRecord pointer;
899 TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)) {
901 "Failed to deserialize PointerRecord record ({1}): {0}",
910 if (
auto err = TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)) {
912 "Failed to deserialize ClassRecord record ({1}): {0}",
919 if (cvt.kind() == LF_ENUM) {
921 if (
auto err = TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)) {
923 "Failed to deserialize EnumRecord record ({1}): {0}",
930 if (cvt.kind() == LF_UNION) {
932 if (
auto err = TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)) {
934 "Failed to deserialize UnionRecord record ({1}): {0}",
941 if (cvt.kind() == LF_ARRAY) {
943 if (
auto err = TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)) {
945 "Failed to deserialize ArrayRecord record ({1}): {0}",
952 if (cvt.kind() == LF_PROCEDURE) {
954 if (
auto err = TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)) {
956 "Failed to deserialize ProcedureRecord record ({1}): {0}",
962 if (cvt.kind() == LF_MFUNCTION) {
963 MemberFunctionRecord mfr;
965 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)) {
968 "Failed to deserialize MemberFunctionRecord record ({1}): {0}",
981 std::optional<PdbTypeSymId> full_decl_uid;
983 auto expected_full_ti =
984 m_index->tpi().findFullDeclForForwardRef(type_id.
index);
985 if (!expected_full_ti)
986 llvm::consumeError(expected_full_ti.takeError());
987 else if (*expected_full_ti != type_id.
index) {
995 if (full_iter !=
m_types.end()) {
996 TypeSP result = full_iter->second;
1005 PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
1007 if (
auto err = ts_or_err.takeError())
1009 auto ts = *ts_or_err;
1039 return iter->second;
1048 CVSymbol sym =
m_index->symrecords().readRecord(var_id.
offset);
1049 if (sym.kind() == S_CONSTANT)
1055 llvm::StringRef name;
1057 bool is_external =
false;
1059 switch (sym.kind()) {
1064 DataSym ds(sym.kind());
1065 if (
auto err = SymbolDeserializer::deserializeAs<DataSym>(sym, ds)) {
1067 "Failed to deserialize DataSym record: {0}");
1074 addr =
m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
1085 ThreadLocalDataSym tlds(sym.kind());
1087 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)) {
1089 "Failed to deserialize ThreadLocalDataSym record: {0}");
1094 addr =
m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
1103 llvm_unreachable(
"unreachable!");
1107 std::optional<uint16_t> modi =
m_index->GetModuleIndexForVa(addr);
1118 std::make_shared<SymbolFileType>(*
this,
toOpaqueUid(tid));
1121 if (
auto err = ts_or_err.takeError())
1123 auto ts = *ts_or_err;
1126 ast_builder->EnsureVariable(var_id);
1131 std::string global_name(
"::");
1132 global_name += name;
1133 bool artificial =
false;
1134 bool location_is_constant_data =
false;
1135 bool static_member =
false;
1136 VariableSP var_sp = std::make_shared<Variable>(
1137 toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
1138 scope, comp_unit.get(), ranges, &decl, location, is_external, artificial,
1139 location_is_constant_data, static_member);
1146 const CVSymbol &cvs) {
1147 TpiStream &tpi =
m_index->tpi();
1148 ConstantSym constant(cvs.kind());
1150 if (cvs.kind() != S_CONSTANT)
1154 SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)) {
1156 "Failed to deserialize ConstantSym record: {0}");
1159 std::string global_name(
"::");
1160 global_name += constant.Name;
1163 std::make_shared<SymbolFileType>(*
this,
toOpaqueUid(tid));
1169 constant.Value, module);
1170 if (!location_or_err) {
1172 "Failed to make constant location expression for {1}: {0}",
1178 bool external =
false;
1179 bool artificial =
false;
1180 bool location_is_constant_data =
true;
1181 bool static_member =
false;
1182 VariableSP var_sp = std::make_shared<Variable>(
1183 toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
1185 external, artificial, location_is_constant_data, static_member);
1192 if (emplace_result.second) {
1194 emplace_result.first->second = var_sp;
1199 return emplace_result.first->second;
1209 if (emplace_result.second)
1210 emplace_result.first->second =
CreateFunction(func_id, comp_unit);
1212 return emplace_result.first->second;
1218 auto emplace_result =
1220 if (emplace_result.second) {
1226 return emplace_result.first->second;
1232 return iter->second.get();
1251 assert(index < UINT16_MAX &&
"Invalid compile unit index");
1252 if (index >= UINT16_MAX)
1264 assert(
false &&
"uid of compile unit not a compiland");
1278 auto *section_list =
1279 m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList();
1283 llvm::DenseMap<lldb::addr_t, llvm::SmallVector<uint32_t, 1>> symbols_by_addr;
1284 for (uint32_t i = 0, n = symtab.
GetNumSymbols(); i < n; ++i) {
1290 PublicSym32 last_sym;
1291 size_t last_sym_idx = 0;
1299 auto finish_last_symbol = [&](
const PublicSym32 *next) {
1306 if (next && last_sym.Segment == next->Segment) {
1307 if (next->Offset < last_sym.Offset) {
1309 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1310 "greater than the following offset {3}",
1311 last_sym.Name, last_sym.Segment, last_sym.Offset,
1315 last->
SetByteSize(next->Offset - last_sym.Offset);
1318 if (section_sp->GetByteSize() < last_sym.Offset) {
1320 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1321 "past the end of section '{3}' (size {4})",
1322 last_sym.Name, last_sym.Segment, last_sym.Offset,
1323 section_sp->GetName(), section_sp->GetByteSize());
1326 last->
SetByteSize(section_sp->GetByteSize() - last_sym.Offset);
1331 for (
auto pid :
m_index->publics().getAddressMap()) {
1333 CVSymbol sym =
m_index->ReadSymbolRecord(global);
1334 auto kind = sym.kind();
1335 if (kind != S_PUB32)
1337 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
1340 "Failed to deserialize PublicSym32 record: {0}");
1343 PublicSym32 pub = std::move(*pub_or_err);
1344 finish_last_symbol(&pub);
1346 if (!section_sp || last_sym.Segment != pub.Segment)
1347 section_sp = section_list->FindSectionByID(pub.Segment);
1353 if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||
1354 (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
1372 if (it != symbols_by_addr.end() &&
1373 llvm::any_of(it->second, [&](uint32_t idx) {
1374 Symbol *sym = symtab.SymbolAtIndex(idx);
1375 return sym && sym->GetMangled() == pub_symbol.GetMangled();
1379 last_sym_idx = symtab.
AddSymbol(pub_symbol);
1383 finish_last_symbol(
nullptr);
1390 assert(
false &&
"uid of compile unit not a compiland");
1398 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
1399 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
1408 if (new_count < count) {
1409 assert(
false &&
"less functions after parsing than before");
1412 return new_count - count;
1417 uint32_t flags = eSymbolContextCompUnit;
1418 flags |= eSymbolContextVariable;
1419 flags |= eSymbolContextFunction;
1420 flags |= eSymbolContextBlock;
1421 flags |= eSymbolContextLineEntry;
1422 return (resolve_scope & flags) != 0;
1426 const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
1428 uint32_t resolved_flags = 0;
1432 std::optional<uint16_t> modi =
m_index->GetModuleIndexForVa(file_addr);
1440 resolved_flags |= eSymbolContextCompUnit;
1443 if (resolve_scope & eSymbolContextFunction ||
1444 resolve_scope & eSymbolContextBlock) {
1447 "missing compile unit for symbol at address {0:x}", file_addr);
1450 std::vector<SymbolAndUid> matches =
m_index->FindSymbolsByVa(file_addr);
1454 for (
const auto &match : llvm::reverse(matches)) {
1458 PdbCompilandSymId csid = match.uid.asCompilandSym();
1459 CVSymbol cvs =
m_index->ReadSymbolRecord(csid);
1461 if (type != PDB_SymType::Function && type != PDB_SymType::Block)
1463 if (type == PDB_SymType::Function) {
1468 addr_t offset = file_addr - func_base;
1473 if (type == PDB_SymType::Block) {
1481 addr_t offset = file_addr - func_base;
1486 resolved_flags |= eSymbolContextFunction;
1488 resolved_flags |= eSymbolContextBlock;
1493 if (resolve_scope & eSymbolContextLineEntry) {
1496 "missing compile unit for symbol at address {0:x}", file_addr);
1500 if (line_table->FindLineEntryByAddress(addr, sc.
line_entry))
1501 resolved_flags |= eSymbolContextLineEntry;
1505 return resolved_flags;
1512 const uint32_t prev_size = sc_list.
GetSize();
1513 if (resolve_scope & eSymbolContextCompUnit) {
1522 if (file_spec_matches_cu_file_spec) {
1528 return sc_list.
GetSize() - prev_size;
1539 assert(
false &&
"uid of compile unit not a compiland");
1553 std::set<LineTable::Entry, LineTableEntryComparator> line_set;
1558 for (
const DebugSubsectionRecord &dssr :
1560 if (dssr.kind() != DebugSubsectionKind::Lines)
1563 DebugLinesSubsectionRef lines;
1564 llvm::BinaryStreamReader reader(dssr.getRecordData());
1565 if (
auto EC = lines.initialize(reader)) {
1566 llvm::consumeError(std::move(EC));
1570 const LineFragmentHeader *lfh = lines.header();
1571 uint64_t virtual_addr =
1572 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1576 for (
const LineColumnEntry &group : lines) {
1577 llvm::Expected<uint32_t> file_index_or_err =
1579 if (!file_index_or_err) {
1581 "failed to get file index for line entry: {0}");
1584 uint32_t file_index = file_index_or_err.get();
1585 if (group.LineNumbers.empty()) {
1587 "no line numbers for {0} in modi={1}", group.NameIndex, modi);
1592 for (
const LineNumberEntry &entry : group.LineNumbers) {
1593 LineInfo cur_info(entry.Flags);
1595 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1598 uint64_t addr = virtual_addr + entry.Offset;
1600 bool is_statement = cur_info.isStatement();
1604 uint32_t lno = cur_info.getStartLine();
1607 is_prologue, is_epilogue,
false);
1609 auto iter = line_set.find(new_entry);
1610 if (iter != line_set.end() && iter->is_terminal_entry)
1611 line_set.erase(iter);
1612 line_set.insert(new_entry);
1619 line_entry.
data = {file_index, lno};
1621 LineInfo last_line(group.LineNumbers.back().Flags);
1622 line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
1623 file_index,
false,
false,
false,
false,
true);
1626 line_entry.
SetRangeEnd(virtual_addr + lfh->CodeSize);
1635 const CVSymbolArray &syms = cii->
m_debug_stream.getSymbolArray();
1636 for (
auto iter = syms.begin(); iter != syms.end();) {
1637 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
1642 uint32_t record_offset = iter.offset();
1643 CVSymbol func_record =
1656 if (kind != S_INLINESITE)
1661 for (
const auto &line_entry :
1666 if (!line_entry.is_terminal_entry)
1667 line_set.erase(line_entry);
1668 line_set.insert(line_entry);
1676 iter = syms.at(getScopeEndOffset(func_record));
1682 std::vector<LineTable::Sequence> sequence(1);
1683 for (
const auto &line_entry : line_set) {
1685 sequence.back(), line_entry.file_addr, line_entry.line,
1686 line_entry.column, line_entry.file_idx,
1687 line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
1688 line_entry.is_prologue_end, line_entry.is_epilogue_begin,
1689 line_entry.is_terminal_entry);
1692 std::make_unique<LineTable>(&comp_unit, std::move(sequence));
1694 if (line_table->GetSize() == 0)
1706llvm::Expected<uint32_t>
1710 return llvm::make_error<RawError>(raw_error_code::no_entry);
1712 const auto &checksums = cii.
m_strings.checksums().getArray();
1713 const auto &strings = cii.
m_strings.strings();
1717 auto iter = checksums.at(file_id);
1718 if (iter == checksums.end())
1719 return llvm::make_error<RawError>(raw_error_code::no_entry);
1721 llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
1723 return efn.takeError();
1729 return std::distance(cii.
m_file_list.begin(), fn_iter);
1730 return llvm::make_error<RawError>(raw_error_code::no_entry);
1738 assert(
false &&
"uid of compile unit not a compiland");
1751 f.starts_with(
"/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1753 support_files.
Append(spec);
1759 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1772 CVSymbol sym = cii->
m_debug_stream.readSymbolAtOffset(
id.offset);
1774 if (sym.kind() != S_INLINESITE)
1777 InlineSiteSym inline_site(
static_cast<SymbolRecordKind
>(sym.kind()));
1779 SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)) {
1781 "Failed to deserialize InlineSiteSym record: {0}");
1786 std::shared_ptr<InlineSite> inline_site_sp =
1787 std::make_shared<InlineSite>(parent_id);
1790 auto iter = cii->
m_inline_map.find(inline_site.Inlinee);
1793 InlineeSourceLine inlinee_line = iter->second;
1797 llvm::Expected<uint32_t> file_index_or_err =
1799 if (!file_index_or_err) {
1801 "failed to get file index for inline site: {0}");
1804 uint32_t file_offset = file_index_or_err.get();
1806 uint32_t decl_line = inlinee_line.Header->SourceLineNum;
1807 std::unique_ptr<Declaration> decl_up =
1808 std::make_unique<Declaration>(decl_file, decl_line);
1811 uint32_t code_offset = 0;
1812 int32_t line_offset = 0;
1813 std::optional<uint32_t> code_offset_base;
1814 std::optional<uint32_t> code_offset_end;
1815 std::optional<int32_t> cur_line_offset;
1816 std::optional<int32_t> next_line_offset;
1817 std::optional<uint32_t> next_file_offset;
1819 bool is_terminal_entry =
false;
1820 bool is_start_of_statement =
true;
1822 bool is_prologue_end =
true;
1824 auto update_code_offset = [&](uint32_t code_delta) {
1825 if (!code_offset_base)
1826 code_offset_base = code_offset;
1827 else if (!code_offset_end)
1828 code_offset_end = *code_offset_base + code_delta;
1830 auto update_line_offset = [&](int32_t line_delta) {
1831 line_offset += line_delta;
1832 if (!code_offset_base || !cur_line_offset)
1833 cur_line_offset = line_offset;
1835 next_line_offset = line_offset;
1838 auto update_file_offset = [&](uint32_t offset) {
1839 if (!code_offset_base)
1840 file_offset = offset;
1842 next_file_offset = offset;
1845 for (
auto &annot : inline_site.annotations()) {
1846 switch (annot.OpCode) {
1847 case BinaryAnnotationsOpCode::CodeOffset:
1848 case BinaryAnnotationsOpCode::ChangeCodeOffset:
1849 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
1850 code_offset += annot.U1;
1851 update_code_offset(annot.U1);
1853 case BinaryAnnotationsOpCode::ChangeLineOffset:
1854 update_line_offset(annot.S1);
1856 case BinaryAnnotationsOpCode::ChangeCodeLength:
1857 update_code_offset(annot.U1);
1858 code_offset += annot.U1;
1859 is_terminal_entry =
true;
1861 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
1862 code_offset += annot.U1;
1863 update_code_offset(annot.U1);
1864 update_line_offset(annot.S1);
1866 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
1867 code_offset += annot.U2;
1868 update_code_offset(annot.U2);
1869 update_code_offset(annot.U1);
1870 code_offset += annot.U1;
1871 is_terminal_entry =
true;
1873 case BinaryAnnotationsOpCode::ChangeFile:
1874 update_file_offset(annot.U1);
1881 if (code_offset_base && code_offset_end && cur_line_offset) {
1883 *code_offset_base, *code_offset_end - *code_offset_base,
1884 decl_line + *cur_line_offset));
1886 if (next_file_offset)
1887 file_offset = *next_file_offset;
1888 if (next_line_offset) {
1889 cur_line_offset = next_line_offset;
1890 next_line_offset = std::nullopt;
1892 code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;
1893 code_offset_end = next_file_offset = std::nullopt;
1895 if (code_offset_base && cur_line_offset) {
1896 if (is_terminal_entry) {
1898 func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
1899 file_offset,
false,
false,
false,
false,
true);
1900 inline_site_sp->line_entries.push_back(line_entry);
1903 decl_line + *cur_line_offset, 0,
1904 file_offset, is_start_of_statement,
false,
1905 is_prologue_end,
false,
false);
1906 inline_site_sp->line_entries.push_back(line_entry);
1907 is_prologue_end =
false;
1908 is_start_of_statement =
false;
1911 if (is_terminal_entry)
1912 is_start_of_statement =
true;
1913 is_terminal_entry =
false;
1916 inline_site_sp->ranges.Sort();
1919 std::unique_ptr<Declaration> callsite_up;
1920 if (!inline_site_sp->ranges.IsEmpty()) {
1921 auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
1922 addr_t base_offset = entry->GetRangeBase();
1928 std::shared_ptr<InlineSite> parent_site =
1931 parent_site->inline_function_info->GetDeclaration().GetFile();
1932 if (
auto *parent_entry =
1933 parent_site->ranges.FindEntryThatContains(base_offset)) {
1935 std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
1940 func_base + base_offset)) {
1944 std::make_unique<Declaration>(callsite_file, entry->data.second);
1950 std::string inlinee_name;
1951 llvm::Expected<CVType> inlinee_cvt =
1952 m_index->ipi().typeCollection().getTypeOrError(inline_site.Inlinee);
1954 inlinee_name =
"[error reading function name: " +
1955 llvm::toString(inlinee_cvt.takeError()) +
"]";
1956 }
else if (inlinee_cvt->kind() == LF_MFUNC_ID) {
1957 MemberFuncIdRecord mfr;
1958 if (
auto err = TypeDeserializer::deserializeAs<MemberFuncIdRecord>(
1959 *inlinee_cvt, mfr)) {
1961 "[error reading function name: " + llvm::toString(std::move(err)) +
1964 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
1965 inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
1966 inlinee_name.append(
"::");
1967 inlinee_name.append(mfr.getName().str());
1969 }
else if (inlinee_cvt->kind() == LF_FUNC_ID) {
1972 TypeDeserializer::deserializeAs<FuncIdRecord>(*inlinee_cvt, fir)) {
1974 "[error reading function name: " + llvm::toString(std::move(err)) +
1977 TypeIndex parent_idx = fir.getParentScope();
1978 if (!parent_idx.isNoneType()) {
1979 LazyRandomTypeCollection &ids =
m_index->ipi().typeCollection();
1980 inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
1981 inlinee_name.append(
"::");
1983 inlinee_name.append(fir.getName().str());
1986 inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
1987 inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
1998 std::set<uint64_t> remove_uids;
2000 if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
2001 kind == S_INLINESITE) {
2003 if (kind == S_INLINESITE)
2010 for (uint64_t uid : remove_uids) {
2022 CVSymbolArray syms =
2026 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
2028 if (fn(iter->kind(), child_id))
2040 "failed to get C++ type system: {0}");
2043 auto ts = *ts_or_err;
2050 ast_builder->
Dump(s, filter, show_color);
2058 std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids;
2061 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2062 CVSymbol sym =
m_index->symrecords().readRecord(gid);
2063 auto kind = sym.kind();
2066 llvm::StringRef name;
2068 case SymbolKind::S_GDATA32:
2069 case SymbolKind::S_LDATA32: {
2070 auto data_or_err = SymbolDeserializer::deserializeAs<DataSym>(sym);
2073 "Failed to deserialize DataSym record: {0}");
2076 name = data_or_err->Name;
2079 case SymbolKind::S_GTHREAD32:
2080 case SymbolKind::S_LTHREAD32: {
2082 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym);
2085 "Failed to deserialize ThreadLocalDataSym record: {0}");
2088 name = data_or_err->Name;
2091 case SymbolKind::S_CONSTANT: {
2092 auto data_or_err = SymbolDeserializer::deserializeAs<ConstantSym>(sym);
2095 "Failed to deserialize ConstantSym record: {0}");
2098 name = data_or_err->Name;
2105 if (!name.empty()) {
2114 if (kind != S_PROCREF && kind != S_LPROCREF)
2120 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2123 "Failed to deserialize ProcRefSym record: {0}");
2126 ProcRefSym ref = std::move(*ref_or_err);
2127 if (ref.Name.empty())
2132 m_index->compilands().GetOrCreateCompiland(ref.modi());
2133 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref.SymOffset);
2136 kind = iter->kind();
2137 if (kind != S_GPROC32 && kind != S_LPROC32)
2140 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
2143 "Failed to deserialize ProcSym record: {0}");
2146 ProcSym proc = std::move(*proc_or_err);
2147 if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)
2149 if (proc.Name.empty() || proc.FunctionType.isSimple())
2155 func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
2158 if (basename.empty())
2159 basename = proc.Name;
2165 auto type =
m_index->tpi().getType(proc.FunctionType);
2166 if (type.kind() == LF_MFUNCTION) {
2167 MemberFunctionRecord mfr;
2168 if (
auto err = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2172 "Failed to deserialize MemberFunctionRecord record ({1}): {0}",
2174 }
else if (!mfr.getThisType().isNoneType())
2180 for (
auto pid :
m_index->publics().getPublicsTable()) {
2182 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2183 auto kind = sym.kind();
2184 if (kind != S_PUB32)
2186 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
2189 "Failed to deserialize PublicSym32 record: {0}");
2192 PublicSym32 pub = std::move(*pub_or_err);
2199 auto it = func_addr_ids.find({pub.Segment, pub.Offset});
2200 if (it != func_addr_ids.end())
2222 std::vector<uint32_t> results;
2225 size_t n_matches = 0;
2226 for (uint32_t gid : results) {
2229 if (parent_decl_ctx.
IsValid() &&
2238 if (++n_matches >= max_matches)
2250 if (name_type_mask & eFunctionNameTypeFull)
2253 if (!(name_type_mask & eFunctionNameTypeFull ||
2254 name_type_mask & eFunctionNameTypeBase ||
2255 name_type_mask & eFunctionNameTypeMethod))
2259 std::set<uint32_t> resolved_ids;
2261 std::vector<uint32_t> ids;
2262 if (!Names.GetValues(name, ids))
2265 for (uint32_t
id : ids) {
2266 if (!resolved_ids.insert(
id).second)
2270 if (parent_decl_ctx.
IsValid() &&
2274 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2275 auto kind = sym.kind();
2276 if (kind != S_PROCREF && kind != S_LPROCREF) {
2282 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2285 "Failed to deserialize ProcRefSym record: {0}");
2288 ProcRefSym proc = std::move(*proc_or_err);
2294 m_index->compilands().GetOrCreateCompiland(proc.modi());
2310 if (name_type_mask & eFunctionNameTypeFull)
2312 if (name_type_mask & eFunctionNameTypeBase)
2314 if (name_type_mask & eFunctionNameTypeMethod)
2319 bool include_inlines,
2336 std::vector<uint32_t> matches;
2339 for (uint32_t match_idx : matches) {
2341 if (context.empty())
2350 if (results.
Done(query))
2357 uint32_t max_matches,
2360 std::vector<TypeIndex> matches =
m_index->tpi().findRecordsByName(name);
2361 if (max_matches > 0 && max_matches < matches.size())
2362 matches.resize(max_matches);
2364 for (TypeIndex ti : matches) {
2380 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
2383 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2386 (void)type->GetFullCompilerType();
2390 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2392 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2393 if (sym.kind() != S_UDT)
2396 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2399 "Failed to deserialize UDTSym record: {0}");
2402 UDTSym udt = std::move(*udt_or_err);
2403 bool is_typedef =
true;
2405 CVType cvt =
m_index->tpi().getType(udt.Type);
2407 if (name == udt.Name)
2419 return new_count - old_count;
2425 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2427 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2432 switch (sym.kind()) {
2433 case SymbolKind::S_GDATA32:
2434 case SymbolKind::S_LDATA32:
2435 case SymbolKind::S_GTHREAD32:
2436 case SymbolKind::S_LTHREAD32: {
2463 bool location_is_constant_data = is_constant;
2467 if (sym.kind() != S_CONSTANT)
2469 ConstantSym constant(sym.kind());
2471 SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant)) {
2473 "Failed to deserialize ConstantSym record: {0}");
2477 var_info.
name = constant.Name;
2478 var_info.
type = constant.Type;
2480 constant.Type,
m_index->tpi(), constant.Value, module);
2481 if (!location_or_err) {
2483 "Failed to make constant location expression for {1}: {0}",
2491 Block *func_block = block;
2512 std::string name = var_info.
name.str();
2515 std::make_shared<SymbolFileType>(*
this, type_sp->GetID());
2520 bool external =
false;
2521 bool artificial =
false;
2522 bool static_member =
false;
2524 VariableSP var_sp = std::make_shared<Variable>(
2525 toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, block,
2526 scope_ranges, &decl, var_info.
location, external, artificial,
2527 location_is_constant_data, static_member);
2530 if (
auto err = ts_or_err.takeError())
2532 auto ts = *ts_or_err;
2535 ast_builder->EnsureVariable(scope_id, var_id);
2545 bool is_param,
bool is_constant) {
2548 return iter->second;
2554 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
2555 if (sym.kind() != S_UDT) {
2560 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2563 "Failed to deserialize UDTSym record: {0}");
2566 UDTSym udt = std::move(*udt_or_err);
2571 if (
auto err = ts_or_err.takeError())
2573 auto ts = *ts_or_err;
2581 ct = target_type->GetForwardCompilerType();
2585 llvm::expectedToOptional(target_type->GetByteSize(
nullptr)),
2586 nullptr, target_type->GetID(),
2594 return iter->second;
2608 uint32_t params_remaining = 0;
2609 switch (sym.kind()) {
2612 ProcSym proc(
static_cast<SymbolRecordKind
>(sym.kind()));
2613 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)) {
2615 "Failed to deserialize ProcSym record: {0}");
2618 CVType signature =
m_index->tpi().getType(proc.FunctionType);
2619 if (signature.kind() == LF_PROCEDURE) {
2620 ProcedureRecord sig;
2621 if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(
2623 llvm::consumeError(std::move(e));
2626 params_remaining = sig.getParameterCount();
2627 }
else if (signature.kind() == LF_MFUNCTION) {
2628 MemberFunctionRecord sig;
2629 if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2631 llvm::consumeError(std::move(e));
2634 params_remaining = sig.getParameterCount();
2650 variables = std::make_shared<VariableList>();
2654 CVSymbolArray syms = limitSymbolArrayToScope(
2660 auto iter = syms.begin();
2661 auto end = syms.end();
2663 while (iter != end) {
2664 uint32_t record_offset = iter.offset();
2665 CVSymbol variable_cvs = *iter;
2671 if (variable_cvs.kind() == S_BLOCK32 ||
2672 variable_cvs.kind() == S_INLINESITE) {
2673 uint32_t block_end = getScopeEndOffset(variable_cvs);
2675 iter = syms.at(block_end);
2679 bool is_param = params_remaining > 0;
2681 switch (variable_cvs.kind()) {
2683 case S_REGREL32_INDIR:
2690 variables->AddVariableIfUnique(variable);
2697 variables->AddVariableIfUnique(variable);
2731 variables = std::make_shared<VariableList>();
2738 "missing missing block, function, or module for symbol context");
2744 if (
auto err = ts_or_err.takeError())
2746 auto ts = *ts_or_err;
2758 if (
auto err = ts_or_err.takeError())
2760 auto ts = *ts_or_err;
2772 if (
auto err = ts_or_err.takeError())
2774 auto ts = *ts_or_err;
2785 auto iter =
m_types.find(type_uid);
2792 return &*iter->second;
2796 assert(
false &&
"uid is not a type index");
2800 if (type_id.
index.isNoneType())
2809std::optional<SymbolFile::ArrayInfo>
2812 return std::nullopt;
2828 TypeClass type_mask,
2837 if (
auto err = ts_or_err.takeError())
2839 auto ts = *ts_or_err;
2842 auto *
clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
2853llvm::Expected<lldb::TypeSystemSP>
2855 auto type_system_or_err =
2856 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
2857 if (type_system_or_err)
2858 if (
auto ts = *type_system_or_err)
2859 ts->SetSymbolFile(
this);
2860 return type_system_or_err;
2865 return m_index->pdb().getFileSize();
2873 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
2875 llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
2876 llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
2878 struct RecordIndices {
2883 llvm::StringMap<RecordIndices> record_indices;
2885 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2886 CVType type = types.getType(*ti);
2892 RecordIndices &indices = record_indices[tag.
asTag().getUniqueName()];
2893 if (tag.
asTag().isForwardRef()) {
2894 indices.forward = *ti;
2902 if (indices.full != TypeIndex::None() &&
2903 indices.forward != TypeIndex::None()) {
2904 forward_to_full[indices.forward] = indices.full;
2905 full_to_forward[indices.full] = indices.forward;
2911 if (tag.
asTag().isForwardRef() || !tag.
asTag().containsNestedClass())
2915 ProcessTpiStream(
PdbIndex &index, TypeIndex parent,
2917 llvm::DenseMap<TypeIndex, TypeIndex> &parents)
2918 : index(index), parents(parents), parent(parent),
2919 parent_cvt(parent_cvt) {}
2922 llvm::DenseMap<TypeIndex, TypeIndex> &parents;
2924 unsigned unnamed_type_index = 1;
2928 llvm::Error visitKnownMember(CVMemberRecord &CVR,
2929 NestedTypeRecord &Record)
override {
2930 std::string unnamed_type_name;
2931 if (Record.Name.empty()) {
2933 llvm::formatv(
"<unnamed-type-$S{0}>", unnamed_type_index).str();
2934 Record.Name = unnamed_type_name;
2935 ++unnamed_type_index;
2937 std::optional<CVTagRecord> tag =
2940 return llvm::ErrorSuccess();
2942 parents[Record.Type] = parent;
2943 return llvm::ErrorSuccess();
2947 CVType field_list_cvt =
m_index->tpi().getType(tag.
asTag().FieldList);
2948 if (field_list_cvt.kind() != LF_FIELDLIST)
2952 FieldListRecord field_list;
2953 if (llvm::Error
error = TypeDeserializer::deserializeAs<FieldListRecord>(
2954 field_list_cvt, field_list))
2955 llvm::consumeError(std::move(
error));
2956 if (llvm::Error
error = visitMemberRecordStream(field_list.Data, process))
2957 llvm::consumeError(std::move(
error));
2969 std::vector<TypeIndex> full_keys;
2970 std::vector<TypeIndex> fwd_keys;
2972 TypeIndex key = entry.first;
2973 TypeIndex value = entry.second;
2975 auto iter = forward_to_full.find(value);
2976 if (iter != forward_to_full.end())
2977 entry.second = iter->second;
2979 iter = forward_to_full.find(key);
2980 if (iter != forward_to_full.end())
2981 fwd_keys.push_back(key);
2983 full_keys.push_back(key);
2985 for (TypeIndex fwd : fwd_keys) {
2986 TypeIndex full = forward_to_full[fwd];
2990 for (TypeIndex full : full_keys) {
2991 TypeIndex fwd = full_to_forward[full];
2996std::optional<PdbCompilandSymId>
2998 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
2999 if (symbolOpensScope(sym.kind())) {
3002 id.offset = getScopeParentOffset(sym);
3006 return std::nullopt;
3015 auto begin = syms.begin();
3016 auto end = syms.at(
id.offset);
3017 std::vector<PdbCompilandSymId> scope_stack;
3019 while (begin != end) {
3020 if (begin.offset() >
id.offset) {
3024 return std::nullopt;
3029 if (symbolOpensScope(begin->kind())) {
3032 uint32_t scope_end = getScopeEndOffset(*begin);
3033 if (scope_end <
id.offset) {
3034 begin = syms.at(scope_end);
3037 scope_stack.emplace_back(
id.modi, begin.offset());
3039 }
else if (symbolEndsScope(begin->kind())) {
3040 scope_stack.pop_back();
3044 if (scope_stack.empty())
3045 return std::nullopt;
3047 return scope_stack.back();
3050std::optional<llvm::codeview::TypeIndex>
3055 return std::nullopt;
3056 return parent_iter->second;
3059std::vector<CompilerContext>
3061 CVType type =
m_index->tpi().getType(ti);
3067 std::optional<Type::ParsedName> parsed_name =
3072 std::vector<CompilerContext> ctx;
3074 for (llvm::StringRef scope : parsed_name->scope) {
3081 for (
auto &el : llvm::reverse(llvm::drop_end(ctx))) {
3087 type =
m_index->tpi().getType(ti);
3088 switch (type.kind()) {
3108std::optional<llvm::StringRef>
3110 TypeIndex function_type) {
3111 auto symbol =
m_index->publics().findByAddress(
m_index->symrecords(),
3114 return std::nullopt;
3116 llvm::StringRef name = symbol->first.Name;
3119 if (!function_type.isNoneType() &&
3120 (symbol->first.Flags & PublicSymFlags::Function) != PublicSymFlags::None)
3137 if (!mangled.starts_with(
'_') ||
3138 m_index->dbi().getMachineType() != PDB_Machine::x86)
3142 PDB_CallingConv cc = PDB_CallingConv::NearC;
3143 if (cvt.kind() == LF_PROCEDURE) {
3144 ProcedureRecord proc;
3145 if (llvm::Error
error =
3146 TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, proc))
3147 llvm::consumeError(std::move(
error));
3149 }
else if (cvt.kind() == LF_MFUNCTION) {
3150 MemberFunctionRecord mfunc;
3151 if (llvm::Error
error =
3152 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfunc))
3153 llvm::consumeError(std::move(
error));
3154 cc = mfunc.CallConv;
3161 if (cc == PDB_CallingConv::NearC || cc == PDB_CallingConv::FarC)
3162 return mangled.drop_front();
3169 llvm::StringRef lookup_name) {
3170 if (lookup_name.empty())
3190 CVSymbol sym_record = cci->
m_debug_stream.readSymbolAtOffset(
id.offset);
3191 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)
3194 ProcSym proc(
static_cast<SymbolRecordKind
>(sym_record.kind()));
3195 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)) {
3197 "Failed to deserialize ProcSym record: {0}");
3203 llvm::StringRef lookup_name =
3206 .value_or(proc.Name);
3212 llvm::StringRef qualified_name) {
3213 if (std::optional<PdbCompilandSymId> func_id =
3219std::optional<PdbCompilandSymId>
3221 TypeIndex method_type) {
3224 if (
m_index->globals().getGlobalsTable().HashRecords.empty())
3225 return std::nullopt;
3228 for (
const auto &[offset, sym] :
m_index->globals().findRecordsByName(
3229 qualified_name,
m_index->symrecords())) {
3230 if (sym.kind() != S_PROCREF && sym.kind() != S_LPROCREF)
3232 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
3235 "Failed to deserialize ProcRefSym record: {0}");
3241 m_index->compilands().GetOrCreateCompiland(ref_or_err->modi());
3242 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref_or_err->SymOffset);
3245 if (iter->kind() != S_GPROC32 && iter->kind() != S_LPROC32)
3247 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
3250 "Failed to deserialize ProcSym record: {0}");
3255 if (proc_or_err->FunctionType == method_type)
3258 return std::nullopt;
3261llvm::Expected<SymbolContext>
3268 !discriminator.empty()) {
3269 const bool is_ctor = discriminator.consume_front(
"C");
3271 bool is_defined =
false;
3272 if ((is_ctor || discriminator.consume_front(
"D")) &&
3273 llvm::to_integer(discriminator, kind))
3274 is_defined = is_ctor ? kind == clang::CXXCtorType::Ctor_Complete ||
3275 kind == clang::CXXCtorType::Ctor_Base
3276 : kind == clang::CXXDtorType::Dtor_Complete ||
3277 kind == clang::CXXDtorType::Dtor_Base;
3279 return llvm::createStringErrorV(
3280 "{0} refers to a structor variant without debug info", label);
3285 return llvm::createStringErrorV(
"invalid function ID in {0}", label);
3290 return llvm::createStringErrorV(
"invalid compiland in {0}", label);
3294 return llvm::createStringErrorV(
"failed to create compile unit for {0}",
3299 return llvm::createStringErrorV(
"failed to create function for {0}", label);
3302 func->CalculateSymbolContext(&sc);
3307 for (CVType cvt :
m_index->ipi().typeArray()) {
3308 switch (cvt.kind()) {
3309 case LF_UDT_SRC_LINE: {
3310 UdtSourceLineRecord udt_src;
3311 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_src)) {
3313 "Failed to deserialize UdtSourceLineRecord record: {0}");
3319 udt_src.LineNumber});
3321 case LF_UDT_MOD_SRC_LINE: {
3322 UdtModSourceLineRecord udt_mod_src;
3323 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_mod_src)) {
3326 "Failed to deserialize UdtModSourceLineRecord record: {0}");
3336 udt_mod_src.LineNumber});
3344llvm::Expected<Declaration>
3350 return llvm::createStringError(
"no UDT declaration found");
3352 llvm::StringRef file_name;
3353 if (it->second.IsIpiIndex) {
3354 CVType cvt =
m_index->ipi().getType(it->second.FileNameIndex);
3355 if (cvt.kind() != LF_STRING_ID)
3356 return llvm::createStringError(
"file name was not a LF_STRING_ID");
3359 if (
auto err = TypeDeserializer::deserializeAs(cvt, sid))
3360 return std::move(err);
3361 file_name = sid.String;
3364 auto string_table =
m_index->pdb().getStringTable();
3366 return string_table.takeError();
3368 llvm::Expected<llvm::StringRef>
string =
3369 string_table->getStringTable().getString(
3370 it->second.FileNameIndex.getIndex());
3372 return string.takeError();
3373 file_name = *string;
3377 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)
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