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;
1128 std::string var_name = name.str();
1130 if (
PdbAstBuilder *ast_builder = ts->GetNativePDBParser()) {
1131 ast_builder->EnsureVariable(var_id);
1132 var_name = ast_builder->GetQualifiedName(name);
1141 bool artificial =
false;
1142 bool location_is_constant_data =
false;
1143 bool static_member =
false;
1144 VariableSP var_sp = std::make_shared<Variable>(
1145 toOpaqueUid(var_id), var_name.c_str(), mangled_name.str().c_str(),
1146 type_sp, scope, comp_unit.get(), ranges, &decl, location, is_external,
1147 artificial, location_is_constant_data, static_member);
1154 const CVSymbol &cvs) {
1155 TpiStream &tpi =
m_index->tpi();
1156 ConstantSym constant(cvs.kind());
1158 if (cvs.kind() != S_CONSTANT)
1162 SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)) {
1164 "Failed to deserialize ConstantSym record: {0}");
1169 std::make_shared<SymbolFileType>(*
this,
toOpaqueUid(tid));
1175 constant.Value, module);
1176 if (!location_or_err) {
1178 "Failed to make constant location expression for {1}: {0}",
1184 std::string var_name = constant.Name.str();
1186 if (
auto err = ts_or_err.takeError()) {
1188 "Failed to get type system for {1}: {0}", constant.Name);
1189 }
else if (
auto ts = *ts_or_err) {
1191 var_name = ast_builder->GetQualifiedName(constant.Name);
1194 bool external =
false;
1195 bool artificial =
false;
1196 bool location_is_constant_data =
true;
1197 bool static_member =
false;
1198 VariableSP var_sp = std::make_shared<Variable>(
1201 ranges, &decl, location, external, artificial, location_is_constant_data,
1209 if (emplace_result.second) {
1211 emplace_result.first->second = var_sp;
1216 return emplace_result.first->second;
1226 if (emplace_result.second)
1227 emplace_result.first->second =
CreateFunction(func_id, comp_unit);
1229 return emplace_result.first->second;
1235 auto emplace_result =
1237 if (emplace_result.second) {
1243 return emplace_result.first->second;
1249 return iter->second.get();
1268 assert(index < UINT16_MAX &&
"Invalid compile unit index");
1269 if (index >= UINT16_MAX)
1281 assert(
false &&
"uid of compile unit not a compiland");
1295 auto *section_list =
1296 m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList();
1300 llvm::DenseMap<lldb::addr_t, llvm::SmallVector<uint32_t, 1>> symbols_by_addr;
1301 for (uint32_t i = 0, n = symtab.
GetNumSymbols(); i < n; ++i) {
1307 PublicSym32 last_sym;
1308 size_t last_sym_idx = 0;
1316 auto finish_last_symbol = [&](
const PublicSym32 *next) {
1323 if (next && last_sym.Segment == next->Segment) {
1324 if (next->Offset < last_sym.Offset) {
1326 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1327 "greater than the following offset {3}",
1328 last_sym.Name, last_sym.Segment, last_sym.Offset,
1332 last->
SetByteSize(next->Offset - last_sym.Offset);
1335 if (section_sp->GetByteSize() < last_sym.Offset) {
1337 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1338 "past the end of section '{3}' (size {4})",
1339 last_sym.Name, last_sym.Segment, last_sym.Offset,
1340 section_sp->GetName(), section_sp->GetByteSize());
1343 last->
SetByteSize(section_sp->GetByteSize() - last_sym.Offset);
1348 for (
auto pid :
m_index->publics().getAddressMap()) {
1350 CVSymbol sym =
m_index->ReadSymbolRecord(global);
1351 auto kind = sym.kind();
1352 if (kind != S_PUB32)
1354 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
1357 "Failed to deserialize PublicSym32 record: {0}");
1360 PublicSym32 pub = std::move(*pub_or_err);
1361 finish_last_symbol(&pub);
1363 if (!section_sp || last_sym.Segment != pub.Segment)
1364 section_sp = section_list->FindSectionByID(pub.Segment);
1370 if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||
1371 (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
1389 if (it != symbols_by_addr.end() &&
1390 llvm::any_of(it->second, [&](uint32_t idx) {
1391 Symbol *sym = symtab.SymbolAtIndex(idx);
1392 return sym && sym->GetMangled() == pub_symbol.GetMangled();
1396 last_sym_idx = symtab.
AddSymbol(pub_symbol);
1400 finish_last_symbol(
nullptr);
1407 assert(
false &&
"uid of compile unit not a compiland");
1415 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
1416 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
1425 if (new_count < count) {
1426 assert(
false &&
"less functions after parsing than before");
1429 return new_count - count;
1434 uint32_t flags = eSymbolContextCompUnit;
1435 flags |= eSymbolContextVariable;
1436 flags |= eSymbolContextFunction;
1437 flags |= eSymbolContextBlock;
1438 flags |= eSymbolContextLineEntry;
1439 return (resolve_scope & flags) != 0;
1443 const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
1445 uint32_t resolved_flags = 0;
1449 std::optional<uint16_t> modi =
m_index->GetModuleIndexForVa(file_addr);
1457 resolved_flags |= eSymbolContextCompUnit;
1460 if (resolve_scope & eSymbolContextFunction ||
1461 resolve_scope & eSymbolContextBlock) {
1464 "missing compile unit for symbol at address {0:x}", file_addr);
1467 std::vector<SymbolAndUid> matches =
m_index->FindSymbolsByVa(file_addr);
1471 for (
const auto &match : llvm::reverse(matches)) {
1475 PdbCompilandSymId csid = match.uid.asCompilandSym();
1476 CVSymbol cvs =
m_index->ReadSymbolRecord(csid);
1478 if (type != PDB_SymType::Function && type != PDB_SymType::Block)
1480 if (type == PDB_SymType::Function) {
1485 addr_t offset = file_addr - func_base;
1490 if (type == PDB_SymType::Block) {
1498 addr_t offset = file_addr - func_base;
1503 resolved_flags |= eSymbolContextFunction;
1505 resolved_flags |= eSymbolContextBlock;
1510 if (resolve_scope & eSymbolContextLineEntry) {
1513 "missing compile unit for symbol at address {0:x}", file_addr);
1517 if (line_table->FindLineEntryByAddress(addr, sc.
line_entry))
1518 resolved_flags |= eSymbolContextLineEntry;
1522 return resolved_flags;
1529 const uint32_t prev_size = sc_list.
GetSize();
1530 if (resolve_scope & eSymbolContextCompUnit) {
1539 if (file_spec_matches_cu_file_spec) {
1545 return sc_list.
GetSize() - prev_size;
1556 assert(
false &&
"uid of compile unit not a compiland");
1570 std::set<LineTable::Entry, LineTableEntryComparator> line_set;
1575 for (
const DebugSubsectionRecord &dssr :
1577 if (dssr.kind() != DebugSubsectionKind::Lines)
1580 DebugLinesSubsectionRef lines;
1581 llvm::BinaryStreamReader reader(dssr.getRecordData());
1582 if (
auto EC = lines.initialize(reader)) {
1583 llvm::consumeError(std::move(EC));
1587 const LineFragmentHeader *lfh = lines.header();
1588 uint64_t virtual_addr =
1589 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1593 for (
const LineColumnEntry &group : lines) {
1594 llvm::Expected<uint32_t> file_index_or_err =
1596 if (!file_index_or_err) {
1598 "failed to get file index for line entry: {0}");
1601 uint32_t file_index = file_index_or_err.get();
1602 if (group.LineNumbers.empty()) {
1604 "no line numbers for {0} in modi={1}", group.NameIndex, modi);
1609 for (
const LineNumberEntry &entry : group.LineNumbers) {
1610 LineInfo cur_info(entry.Flags);
1612 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1615 uint64_t addr = virtual_addr + entry.Offset;
1617 bool is_statement = cur_info.isStatement();
1621 uint32_t lno = cur_info.getStartLine();
1624 is_prologue, is_epilogue,
false);
1626 auto iter = line_set.find(new_entry);
1627 if (iter != line_set.end() && iter->is_terminal_entry)
1628 line_set.erase(iter);
1629 line_set.insert(new_entry);
1636 line_entry.
data = {file_index, lno};
1638 LineInfo last_line(group.LineNumbers.back().Flags);
1639 line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
1640 file_index,
false,
false,
false,
false,
true);
1643 line_entry.
SetRangeEnd(virtual_addr + lfh->CodeSize);
1652 const CVSymbolArray &syms = cii->
m_debug_stream.getSymbolArray();
1653 for (
auto iter = syms.begin(); iter != syms.end();) {
1654 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
1659 uint32_t record_offset = iter.offset();
1660 CVSymbol func_record =
1673 if (kind != S_INLINESITE)
1678 for (
const auto &line_entry :
1683 if (!line_entry.is_terminal_entry)
1684 line_set.erase(line_entry);
1685 line_set.insert(line_entry);
1693 iter = syms.at(getScopeEndOffset(func_record));
1699 std::vector<LineTable::Sequence> sequence(1);
1700 for (
const auto &line_entry : line_set) {
1702 sequence.back(), line_entry.file_addr, line_entry.line,
1703 line_entry.column, line_entry.file_idx,
1704 line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
1705 line_entry.is_prologue_end, line_entry.is_epilogue_begin,
1706 line_entry.is_terminal_entry);
1709 std::make_unique<LineTable>(&comp_unit, std::move(sequence));
1711 if (line_table->GetSize() == 0)
1723llvm::Expected<uint32_t>
1727 return llvm::make_error<RawError>(raw_error_code::no_entry);
1729 const auto &checksums = cii.
m_strings.checksums().getArray();
1730 const auto &strings = cii.
m_strings.strings();
1734 auto iter = checksums.at(file_id);
1735 if (iter == checksums.end())
1736 return llvm::make_error<RawError>(raw_error_code::no_entry);
1738 llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
1740 return efn.takeError();
1746 return std::distance(cii.
m_file_list.begin(), fn_iter);
1747 return llvm::make_error<RawError>(raw_error_code::no_entry);
1755 assert(
false &&
"uid of compile unit not a compiland");
1768 f.starts_with(
"/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1770 support_files.
Append(spec);
1776 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1789 CVSymbol sym = cii->
m_debug_stream.readSymbolAtOffset(
id.offset);
1791 if (sym.kind() != S_INLINESITE)
1794 InlineSiteSym inline_site(
static_cast<SymbolRecordKind
>(sym.kind()));
1796 SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)) {
1798 "Failed to deserialize InlineSiteSym record: {0}");
1803 std::shared_ptr<InlineSite> inline_site_sp =
1804 std::make_shared<InlineSite>(parent_id);
1807 auto iter = cii->
m_inline_map.find(inline_site.Inlinee);
1810 InlineeSourceLine inlinee_line = iter->second;
1814 llvm::Expected<uint32_t> file_index_or_err =
1816 if (!file_index_or_err) {
1818 "failed to get file index for inline site: {0}");
1821 uint32_t file_offset = file_index_or_err.get();
1823 uint32_t decl_line = inlinee_line.Header->SourceLineNum;
1824 std::unique_ptr<Declaration> decl_up =
1825 std::make_unique<Declaration>(decl_file, decl_line);
1828 uint32_t code_offset = 0;
1829 int32_t line_offset = 0;
1830 std::optional<uint32_t> code_offset_base;
1831 std::optional<uint32_t> code_offset_end;
1832 std::optional<int32_t> cur_line_offset;
1833 std::optional<int32_t> next_line_offset;
1834 std::optional<uint32_t> next_file_offset;
1836 bool is_terminal_entry =
false;
1837 bool is_start_of_statement =
true;
1839 bool is_prologue_end =
true;
1841 auto update_code_offset = [&](uint32_t code_delta) {
1842 if (!code_offset_base)
1843 code_offset_base = code_offset;
1844 else if (!code_offset_end)
1845 code_offset_end = *code_offset_base + code_delta;
1847 auto update_line_offset = [&](int32_t line_delta) {
1848 line_offset += line_delta;
1849 if (!code_offset_base || !cur_line_offset)
1850 cur_line_offset = line_offset;
1852 next_line_offset = line_offset;
1855 auto update_file_offset = [&](uint32_t offset) {
1856 if (!code_offset_base)
1857 file_offset = offset;
1859 next_file_offset = offset;
1862 for (
auto &annot : inline_site.annotations()) {
1863 switch (annot.OpCode) {
1864 case BinaryAnnotationsOpCode::CodeOffset:
1865 case BinaryAnnotationsOpCode::ChangeCodeOffset:
1866 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
1867 code_offset += annot.U1;
1868 update_code_offset(annot.U1);
1870 case BinaryAnnotationsOpCode::ChangeLineOffset:
1871 update_line_offset(annot.S1);
1873 case BinaryAnnotationsOpCode::ChangeCodeLength:
1874 update_code_offset(annot.U1);
1875 code_offset += annot.U1;
1876 is_terminal_entry =
true;
1878 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
1879 code_offset += annot.U1;
1880 update_code_offset(annot.U1);
1881 update_line_offset(annot.S1);
1883 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
1884 code_offset += annot.U2;
1885 update_code_offset(annot.U2);
1886 update_code_offset(annot.U1);
1887 code_offset += annot.U1;
1888 is_terminal_entry =
true;
1890 case BinaryAnnotationsOpCode::ChangeFile:
1891 update_file_offset(annot.U1);
1898 if (code_offset_base && code_offset_end && cur_line_offset) {
1900 *code_offset_base, *code_offset_end - *code_offset_base,
1901 decl_line + *cur_line_offset));
1903 if (next_file_offset)
1904 file_offset = *next_file_offset;
1905 if (next_line_offset) {
1906 cur_line_offset = next_line_offset;
1907 next_line_offset = std::nullopt;
1909 code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;
1910 code_offset_end = next_file_offset = std::nullopt;
1912 if (code_offset_base && cur_line_offset) {
1913 if (is_terminal_entry) {
1915 func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
1916 file_offset,
false,
false,
false,
false,
true);
1917 inline_site_sp->line_entries.push_back(line_entry);
1920 decl_line + *cur_line_offset, 0,
1921 file_offset, is_start_of_statement,
false,
1922 is_prologue_end,
false,
false);
1923 inline_site_sp->line_entries.push_back(line_entry);
1924 is_prologue_end =
false;
1925 is_start_of_statement =
false;
1928 if (is_terminal_entry)
1929 is_start_of_statement =
true;
1930 is_terminal_entry =
false;
1933 inline_site_sp->ranges.Sort();
1936 std::unique_ptr<Declaration> callsite_up;
1937 if (!inline_site_sp->ranges.IsEmpty()) {
1938 auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
1939 addr_t base_offset = entry->GetRangeBase();
1945 std::shared_ptr<InlineSite> parent_site =
1948 parent_site->inline_function_info->GetDeclaration().GetFile();
1949 if (
auto *parent_entry =
1950 parent_site->ranges.FindEntryThatContains(base_offset)) {
1952 std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
1957 func_base + base_offset)) {
1961 std::make_unique<Declaration>(callsite_file, entry->data.second);
1967 std::string inlinee_name;
1968 llvm::Expected<CVType> inlinee_cvt =
1969 m_index->ipi().typeCollection().getTypeOrError(inline_site.Inlinee);
1971 inlinee_name =
"[error reading function name: " +
1972 llvm::toString(inlinee_cvt.takeError()) +
"]";
1973 }
else if (inlinee_cvt->kind() == LF_MFUNC_ID) {
1974 MemberFuncIdRecord mfr;
1975 if (
auto err = TypeDeserializer::deserializeAs<MemberFuncIdRecord>(
1976 *inlinee_cvt, mfr)) {
1978 "[error reading function name: " + llvm::toString(std::move(err)) +
1981 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
1982 inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
1983 inlinee_name.append(
"::");
1984 inlinee_name.append(mfr.getName().str());
1986 }
else if (inlinee_cvt->kind() == LF_FUNC_ID) {
1989 TypeDeserializer::deserializeAs<FuncIdRecord>(*inlinee_cvt, fir)) {
1991 "[error reading function name: " + llvm::toString(std::move(err)) +
1994 TypeIndex parent_idx = fir.getParentScope();
1995 if (!parent_idx.isNoneType()) {
1996 LazyRandomTypeCollection &ids =
m_index->ipi().typeCollection();
1997 inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
1998 inlinee_name.append(
"::");
2000 inlinee_name.append(fir.getName().str());
2003 inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
2004 inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
2015 std::set<uint64_t> remove_uids;
2017 if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
2018 kind == S_INLINESITE) {
2020 if (kind == S_INLINESITE)
2027 for (uint64_t uid : remove_uids) {
2039 CVSymbolArray syms =
2043 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
2045 if (fn(iter->kind(), child_id))
2057 "failed to get C++ type system: {0}");
2060 auto ts = *ts_or_err;
2067 ast_builder->
Dump(s, filter, show_color);
2075 std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids;
2078 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2079 CVSymbol sym =
m_index->symrecords().readRecord(gid);
2080 auto kind = sym.kind();
2083 llvm::StringRef name;
2085 case SymbolKind::S_GDATA32:
2086 case SymbolKind::S_LDATA32: {
2087 auto data_or_err = SymbolDeserializer::deserializeAs<DataSym>(sym);
2090 "Failed to deserialize DataSym record: {0}");
2093 name = data_or_err->Name;
2096 case SymbolKind::S_GTHREAD32:
2097 case SymbolKind::S_LTHREAD32: {
2099 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym);
2102 "Failed to deserialize ThreadLocalDataSym record: {0}");
2105 name = data_or_err->Name;
2108 case SymbolKind::S_CONSTANT: {
2109 auto data_or_err = SymbolDeserializer::deserializeAs<ConstantSym>(sym);
2112 "Failed to deserialize ConstantSym record: {0}");
2115 name = data_or_err->Name;
2122 if (!name.empty()) {
2131 if (kind != S_PROCREF && kind != S_LPROCREF)
2137 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2140 "Failed to deserialize ProcRefSym record: {0}");
2143 ProcRefSym ref = std::move(*ref_or_err);
2144 if (ref.Name.empty())
2149 m_index->compilands().GetOrCreateCompiland(ref.modi());
2150 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref.SymOffset);
2153 kind = iter->kind();
2154 if (kind != S_GPROC32 && kind != S_LPROC32)
2157 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
2160 "Failed to deserialize ProcSym record: {0}");
2163 ProcSym proc = std::move(*proc_or_err);
2164 if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)
2166 if (proc.Name.empty() || proc.FunctionType.isSimple())
2172 func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
2175 if (basename.empty())
2176 basename = proc.Name;
2182 auto type =
m_index->tpi().getType(proc.FunctionType);
2183 if (type.kind() == LF_MFUNCTION) {
2184 MemberFunctionRecord mfr;
2185 if (
auto err = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2189 "Failed to deserialize MemberFunctionRecord record ({1}): {0}",
2191 }
else if (!mfr.getThisType().isNoneType())
2197 for (
auto pid :
m_index->publics().getPublicsTable()) {
2199 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2200 auto kind = sym.kind();
2201 if (kind != S_PUB32)
2203 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
2206 "Failed to deserialize PublicSym32 record: {0}");
2209 PublicSym32 pub = std::move(*pub_or_err);
2216 auto it = func_addr_ids.find({pub.Segment, pub.Offset});
2217 if (it != func_addr_ids.end())
2241 bool is_rooted = lookup_name.consume_front(
"::");
2243 llvm::StringRef context;
2244 llvm::StringRef basename;
2247 basename = lookup_name;
2248 std::string scoped_suffix = (
"::" + lookup_name).str();
2250 std::vector<uint32_t> results;
2253 size_t n_matches = 0;
2254 for (uint32_t gid : results) {
2257 if (parent_decl_ctx.
IsValid() &&
2264 if (is_rooted || !context.empty()) {
2265 llvm::StringRef var_name = var->GetName().GetStringRef();
2266 if (var_name != lookup_name &&
2267 (is_rooted || !var_name.ends_with(scoped_suffix)))
2272 if (++n_matches >= max_matches)
2284 if (name_type_mask & eFunctionNameTypeFull)
2287 if (!(name_type_mask & eFunctionNameTypeFull ||
2288 name_type_mask & eFunctionNameTypeBase ||
2289 name_type_mask & eFunctionNameTypeMethod))
2293 std::set<uint32_t> resolved_ids;
2295 std::vector<uint32_t> ids;
2296 if (!Names.GetValues(name, ids))
2299 for (uint32_t
id : ids) {
2300 if (!resolved_ids.insert(
id).second)
2304 if (parent_decl_ctx.
IsValid() &&
2312 if (name_type_mask & eFunctionNameTypeFull)
2314 if (name_type_mask & eFunctionNameTypeBase)
2316 if (name_type_mask & eFunctionNameTypeMethod)
2321 bool include_inlines,
2328 std::vector<uint32_t> ids;
2332 std::set<uint32_t> resolved_ids;
2333 for (uint32_t
id : ids)
2334 if (resolved_ids.insert(
id).second)
2340 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2341 auto kind = sym.kind();
2342 if (kind != S_PROCREF && kind != S_LPROCREF) {
2347 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2350 "Failed to deserialize ProcRefSym record: {0}");
2353 ProcRefSym proc = std::move(*proc_or_err);
2359 m_index->compilands().GetOrCreateCompiland(proc.modi());
2388 std::vector<uint32_t> matches;
2391 for (uint32_t match_idx : matches) {
2393 if (context.empty())
2402 if (results.
Done(query))
2408 std::vector<uint32_t> typedef_matches;
2410 for (uint32_t gid : typedef_matches) {
2420 if (results.
Done(query))
2425std::vector<CompilerContext>
2427 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
2428 if (sym.kind() != S_UDT)
2430 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2432 llvm::consumeError(udt_or_err.takeError());
2436 std::optional<Type::ParsedName> parsed_name =
2443 std::vector<CompilerContext> ctx;
2444 for (llvm::StringRef scope : parsed_name->scope)
2452 uint32_t max_matches,
2455 std::vector<TypeIndex> matches =
m_index->tpi().findRecordsByName(name);
2456 if (max_matches > 0 && max_matches < matches.size())
2457 matches.resize(max_matches);
2459 for (TypeIndex ti : matches) {
2475 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
2478 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2481 (void)type->GetFullCompilerType();
2485 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2487 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2488 if (sym.kind() != S_UDT)
2491 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2494 "Failed to deserialize UDTSym record: {0}");
2505 return new_count - old_count;
2511 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2513 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2518 switch (sym.kind()) {
2519 case SymbolKind::S_GDATA32:
2520 case SymbolKind::S_LDATA32:
2521 case SymbolKind::S_GTHREAD32:
2522 case SymbolKind::S_LTHREAD32: {
2524 if (var && var->GetSymbolContextScope() == &comp_unit)
2550 bool location_is_constant_data = is_constant;
2554 if (sym.kind() != S_CONSTANT)
2556 ConstantSym constant(sym.kind());
2558 SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant)) {
2560 "Failed to deserialize ConstantSym record: {0}");
2564 var_info.
name = constant.Name;
2565 var_info.
type = constant.Type;
2567 constant.Type,
m_index->tpi(), constant.Value, module);
2568 if (!location_or_err) {
2570 "Failed to make constant location expression for {1}: {0}",
2578 Block *func_block = block;
2599 std::string name = var_info.
name.str();
2602 std::make_shared<SymbolFileType>(*
this, type_sp->GetID());
2607 bool external =
false;
2608 bool artificial =
false;
2609 bool static_member =
false;
2611 VariableSP var_sp = std::make_shared<Variable>(
2612 toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, block,
2613 scope_ranges, &decl, var_info.
location, external, artificial,
2614 location_is_constant_data, static_member);
2617 if (
auto err = ts_or_err.takeError())
2619 auto ts = *ts_or_err;
2622 ast_builder->EnsureVariable(scope_id, var_id);
2632 bool is_param,
bool is_constant) {
2635 return iter->second;
2645 return iter->second;
2652 CVSymbol sym =
m_index->ReadSymbolRecord(var_id);
2654 llvm::StringRef name;
2657 switch (sym.kind()) {
2659 DataSym ds(sym.kind());
2660 if (
auto err = SymbolDeserializer::deserializeAs<DataSym>(sym, ds)) {
2662 "Failed to deserialize DataSym record: {0}");
2672 ThreadLocalDataSym tlds(sym.kind());
2674 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)) {
2676 "Failed to deserialize ThreadLocalDataSym record: {0}");
2694 std::make_shared<SymbolFileType>(*
this, type_sp->GetID());
2698 VariableSP var_sp = std::make_shared<Variable>(
2699 toOpaqueUid(var_id), name.str().c_str(),
nullptr, sftype,
2708 if (
auto err = ts_or_err.takeError())
2709 llvm::consumeError(std::move(err));
2710 else if (
auto ts = *ts_or_err)
2712 ast_builder->EnsureVariable(scope_id, var_id);
2720 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
2721 if (sym.kind() != S_UDT) {
2726 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2729 "Failed to deserialize UDTSym record: {0}");
2732 UDTSym udt = std::move(*udt_or_err);
2737 if (
auto err = ts_or_err.takeError())
2739 auto ts = *ts_or_err;
2747 ct = target_type->GetForwardCompilerType();
2751 llvm::expectedToOptional(target_type->GetByteSize(
nullptr)),
2752 nullptr, target_type->GetID(),
2760 return iter->second;
2772 CVType cvt =
m_index->tpi().getType(udt.Type);
2785 uint32_t params_remaining = 0;
2786 switch (sym.kind()) {
2789 ProcSym proc(
static_cast<SymbolRecordKind
>(sym.kind()));
2790 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)) {
2792 "Failed to deserialize ProcSym record: {0}");
2795 CVType signature =
m_index->tpi().getType(proc.FunctionType);
2796 if (signature.kind() == LF_PROCEDURE) {
2797 ProcedureRecord sig;
2798 if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(
2800 llvm::consumeError(std::move(e));
2803 params_remaining = sig.getParameterCount();
2804 }
else if (signature.kind() == LF_MFUNCTION) {
2805 MemberFunctionRecord sig;
2806 if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2808 llvm::consumeError(std::move(e));
2811 params_remaining = sig.getParameterCount();
2827 variables = std::make_shared<VariableList>();
2831 CVSymbolArray syms = limitSymbolArrayToScope(
2837 auto iter = syms.begin();
2838 auto end = syms.end();
2840 while (iter != end) {
2841 uint32_t record_offset = iter.offset();
2842 CVSymbol variable_cvs = *iter;
2848 if (variable_cvs.kind() == S_BLOCK32 ||
2849 variable_cvs.kind() == S_INLINESITE) {
2850 uint32_t block_end = getScopeEndOffset(variable_cvs);
2852 iter = syms.at(block_end);
2856 bool is_param = params_remaining > 0;
2858 switch (variable_cvs.kind()) {
2860 case S_REGREL32_INDIR:
2867 variables->AddVariableIfUnique(variable);
2874 variables->AddVariableIfUnique(variable);
2880 variables->AddVariableIfUnique(variable);
2914 variables = std::make_shared<VariableList>();
2921 "missing missing block, function, or module for symbol context");
2927 if (
auto err = ts_or_err.takeError())
2929 auto ts = *ts_or_err;
2941 if (
auto err = ts_or_err.takeError())
2943 auto ts = *ts_or_err;
2955 if (
auto err = ts_or_err.takeError())
2957 auto ts = *ts_or_err;
2968 auto iter =
m_types.find(type_uid);
2975 return &*iter->second;
2979 assert(
false &&
"uid is not a type index");
2983 if (type_id.
index.isNoneType())
2992std::optional<SymbolFile::ArrayInfo>
2995 return std::nullopt;
3011 TypeClass type_mask,
3020 if (
auto err = ts_or_err.takeError())
3022 auto ts = *ts_or_err;
3025 auto *
clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
3036llvm::Expected<lldb::TypeSystemSP>
3038 auto type_system_or_err =
3039 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
3040 if (type_system_or_err)
3041 if (
auto ts = *type_system_or_err)
3042 ts->SetSymbolFile(
this);
3043 return type_system_or_err;
3048 return m_index->pdb().getFileSize();
3056 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
3058 llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
3059 llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
3061 struct RecordIndices {
3066 llvm::StringMap<RecordIndices> record_indices;
3068 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
3069 CVType type = types.getType(*ti);
3075 RecordIndices &indices = record_indices[tag.
asTag().getUniqueName()];
3076 if (tag.
asTag().isForwardRef()) {
3077 indices.forward = *ti;
3085 if (indices.full != TypeIndex::None() &&
3086 indices.forward != TypeIndex::None()) {
3087 forward_to_full[indices.forward] = indices.full;
3088 full_to_forward[indices.full] = indices.forward;
3094 if (tag.
asTag().isForwardRef() || !tag.
asTag().containsNestedClass())
3098 ProcessTpiStream(
PdbIndex &index, TypeIndex parent,
3100 llvm::DenseMap<TypeIndex, TypeIndex> &parents)
3101 : index(index), parents(parents), parent(parent),
3102 parent_cvt(parent_cvt) {}
3105 llvm::DenseMap<TypeIndex, TypeIndex> &parents;
3107 unsigned unnamed_type_index = 1;
3111 llvm::Error visitKnownMember(CVMemberRecord &CVR,
3112 NestedTypeRecord &Record)
override {
3113 std::string unnamed_type_name;
3114 if (Record.Name.empty()) {
3116 llvm::formatv(
"<unnamed-type-$S{0}>", unnamed_type_index).str();
3117 Record.Name = unnamed_type_name;
3118 ++unnamed_type_index;
3120 std::optional<CVTagRecord> tag =
3123 return llvm::ErrorSuccess();
3125 parents[Record.Type] = parent;
3126 return llvm::ErrorSuccess();
3130 CVType field_list_cvt =
m_index->tpi().getType(tag.
asTag().FieldList);
3131 if (field_list_cvt.kind() != LF_FIELDLIST)
3135 FieldListRecord field_list;
3136 if (llvm::Error
error = TypeDeserializer::deserializeAs<FieldListRecord>(
3137 field_list_cvt, field_list))
3138 llvm::consumeError(std::move(
error));
3139 if (llvm::Error
error = visitMemberRecordStream(field_list.Data, process))
3140 llvm::consumeError(std::move(
error));
3147 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
3148 CVSymbol sym =
m_index->symrecords().readRecord(gid);
3149 if (sym.kind() != S_UDT)
3151 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
3153 llvm::consumeError(udt_or_err.takeError());
3158 llvm::StringRef base_name =
3169 std::vector<TypeIndex> full_keys;
3170 std::vector<TypeIndex> fwd_keys;
3172 TypeIndex key = entry.first;
3173 TypeIndex value = entry.second;
3175 auto iter = forward_to_full.find(value);
3176 if (iter != forward_to_full.end())
3177 entry.second = iter->second;
3179 iter = forward_to_full.find(key);
3180 if (iter != forward_to_full.end())
3181 fwd_keys.push_back(key);
3183 full_keys.push_back(key);
3185 for (TypeIndex fwd : fwd_keys) {
3186 TypeIndex full = forward_to_full[fwd];
3190 for (TypeIndex full : full_keys) {
3191 TypeIndex fwd = full_to_forward[full];
3196std::optional<PdbCompilandSymId>
3198 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
3199 if (symbolOpensScope(sym.kind())) {
3202 id.offset = getScopeParentOffset(sym);
3206 return std::nullopt;
3215 auto begin = syms.begin();
3216 auto end = syms.at(
id.offset);
3217 std::vector<PdbCompilandSymId> scope_stack;
3219 while (begin != end) {
3220 if (begin.offset() >
id.offset) {
3224 return std::nullopt;
3229 if (symbolOpensScope(begin->kind())) {
3232 uint32_t scope_end = getScopeEndOffset(*begin);
3233 if (scope_end <
id.offset) {
3234 begin = syms.at(scope_end);
3237 scope_stack.emplace_back(
id.modi, begin.offset());
3239 }
else if (symbolEndsScope(begin->kind())) {
3240 scope_stack.pop_back();
3244 if (scope_stack.empty())
3245 return std::nullopt;
3247 return scope_stack.back();
3250std::optional<llvm::codeview::TypeIndex>
3255 return std::nullopt;
3256 return parent_iter->second;
3259std::vector<CompilerContext>
3261 CVType type =
m_index->tpi().getType(ti);
3267 std::optional<Type::ParsedName> parsed_name =
3272 std::vector<CompilerContext> ctx;
3274 for (llvm::StringRef scope : parsed_name->scope) {
3281 for (
auto &el : llvm::reverse(llvm::drop_end(ctx))) {
3287 type =
m_index->tpi().getType(ti);
3288 switch (type.kind()) {
3308std::optional<llvm::StringRef>
3310 TypeIndex function_type) {
3311 auto symbol =
m_index->publics().findByAddress(
m_index->symrecords(),
3314 return std::nullopt;
3316 llvm::StringRef name = symbol->first.Name;
3319 if (!function_type.isNoneType() &&
3320 (symbol->first.Flags & PublicSymFlags::Function) != PublicSymFlags::None)
3337 if (!mangled.starts_with(
'_') ||
3338 m_index->dbi().getMachineType() != PDB_Machine::x86)
3342 PDB_CallingConv cc = PDB_CallingConv::NearC;
3343 if (cvt.kind() == LF_PROCEDURE) {
3344 ProcedureRecord proc;
3345 if (llvm::Error
error =
3346 TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, proc))
3347 llvm::consumeError(std::move(
error));
3349 }
else if (cvt.kind() == LF_MFUNCTION) {
3350 MemberFunctionRecord mfunc;
3351 if (llvm::Error
error =
3352 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfunc))
3353 llvm::consumeError(std::move(
error));
3354 cc = mfunc.CallConv;
3361 if (cc == PDB_CallingConv::NearC || cc == PDB_CallingConv::FarC)
3362 return mangled.drop_front();
3369 llvm::StringRef lookup_name) {
3370 if (lookup_name.empty())
3390 CVSymbol sym_record = cci->
m_debug_stream.readSymbolAtOffset(
id.offset);
3391 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)
3394 ProcSym proc(
static_cast<SymbolRecordKind
>(sym_record.kind()));
3395 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)) {
3397 "Failed to deserialize ProcSym record: {0}");
3403 llvm::StringRef lookup_name =
3406 .value_or(proc.Name);
3412 llvm::StringRef qualified_name) {
3413 if (std::optional<PdbCompilandSymId> func_id =
3419std::optional<PdbCompilandSymId>
3421 TypeIndex method_type) {
3424 if (
m_index->globals().getGlobalsTable().HashRecords.empty())
3425 return std::nullopt;
3428 for (
const auto &[offset, sym] :
m_index->globals().findRecordsByName(
3429 qualified_name,
m_index->symrecords())) {
3430 if (sym.kind() != S_PROCREF && sym.kind() != S_LPROCREF)
3432 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
3435 "Failed to deserialize ProcRefSym record: {0}");
3441 m_index->compilands().GetOrCreateCompiland(ref_or_err->modi());
3442 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref_or_err->SymOffset);
3445 if (iter->kind() != S_GPROC32 && iter->kind() != S_LPROC32)
3447 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
3450 "Failed to deserialize ProcSym record: {0}");
3455 if (proc_or_err->FunctionType == method_type)
3458 return std::nullopt;
3461llvm::Expected<SymbolContext>
3468 !discriminator.empty()) {
3469 const bool is_ctor = discriminator.consume_front(
"C");
3471 bool is_defined =
false;
3472 if ((is_ctor || discriminator.consume_front(
"D")) &&
3473 llvm::to_integer(discriminator, kind))
3474 is_defined = is_ctor ? kind == clang::CXXCtorType::Ctor_Complete ||
3475 kind == clang::CXXCtorType::Ctor_Base
3476 : kind == clang::CXXDtorType::Dtor_Complete ||
3477 kind == clang::CXXDtorType::Dtor_Base;
3479 return llvm::createStringErrorV(
3480 "{0} refers to a structor variant without debug info", label);
3485 return llvm::createStringErrorV(
"invalid function ID in {0}", label);
3490 return llvm::createStringErrorV(
"invalid compiland in {0}", label);
3494 return llvm::createStringErrorV(
"failed to create compile unit for {0}",
3499 return llvm::createStringErrorV(
"failed to create function for {0}", label);
3502 func->CalculateSymbolContext(&sc);
3507 for (CVType cvt :
m_index->ipi().typeArray()) {
3508 switch (cvt.kind()) {
3509 case LF_UDT_SRC_LINE: {
3510 UdtSourceLineRecord udt_src;
3511 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_src)) {
3513 "Failed to deserialize UdtSourceLineRecord record: {0}");
3519 udt_src.LineNumber});
3521 case LF_UDT_MOD_SRC_LINE: {
3522 UdtModSourceLineRecord udt_mod_src;
3523 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_mod_src)) {
3526 "Failed to deserialize UdtModSourceLineRecord record: {0}");
3536 udt_mod_src.LineNumber});
3544llvm::Expected<Declaration>
3550 return llvm::createStringError(
"no UDT declaration found");
3552 llvm::StringRef file_name;
3553 if (it->second.IsIpiIndex) {
3554 CVType cvt =
m_index->ipi().getType(it->second.FileNameIndex);
3555 if (cvt.kind() != LF_STRING_ID)
3556 return llvm::createStringError(
"file name was not a LF_STRING_ID");
3559 if (
auto err = TypeDeserializer::deserializeAs(cvt, sid))
3560 return std::move(err);
3561 file_name = sid.String;
3564 auto string_table =
m_index->pdb().getStringTable();
3566 return string_table.takeError();
3568 llvm::Expected<llvm::StringRef>
string =
3569 string_table->getStringTable().getString(
3570 it->second.FileNameIndex.getIndex());
3572 return string.takeError();
3573 file_name = *string;
3577 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.
@ kAllAbilities
All detailed debug-information abilities.
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
std::vector< CompilerContext > GetContextForTypedef(PdbGlobalSymId id)
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()
void AppendFunctionForProcRef(PdbGlobalSymId global, SymbolContextList &sc_list)
Append the function referenced by the S_PROCREF/S_LPROCREF global.
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)
lldb_private::UniqueCStringMap< uint32_t > m_typedef_base_names
typedef basename -> Global ID(s) of its S_UDT
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
bool IsTypedefUdt(const llvm::codeview::UDTSym &udt)
Returns true if udt is a typedef rather than the S_UDT that is emitted for every tag type.
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
lldb::VariableSP GetOrCreateLocalStaticVariable(PdbCompilandSymId scope_id, PdbCompilandSymId var_id)
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