31#include "clang/Basic/ABI.h"
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/STLExtras.h"
34#include "llvm/ADT/SmallVector.h"
35#include "llvm/DebugInfo/CodeView/CVRecord.h"
36#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
37#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
38#include "llvm/DebugInfo/CodeView/Formatters.h"
39#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
40#include "llvm/DebugInfo/CodeView/RecordName.h"
41#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
42#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
43#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
44#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
45#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
46#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
47#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
48#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
49#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
50#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
51#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
52#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
53#include "llvm/DebugInfo/PDB/PDB.h"
54#include "llvm/DebugInfo/PDB/PDBTypes.h"
55#include "llvm/Demangle/MicrosoftDemangle.h"
56#include "llvm/Object/COFF.h"
57#include "llvm/Support/Allocator.h"
58#include "llvm/Support/BinaryStreamReader.h"
59#include "llvm/Support/Error.h"
60#include "llvm/Support/ErrorExtras.h"
61#include "llvm/Support/ErrorOr.h"
62#include "llvm/Support/MemoryBuffer.h"
91 case PDB_Lang::ObjCpp:
98static std::optional<std::string>
100 llvm::StringRef exe_path) {
103 if (fs.
Exists(original_pdb_path))
104 return std::string(original_pdb_path);
109 const FileSpec original_pdb_spec(original_pdb_path,
111 .value_or(FileSpec::Style::native));
112 const llvm::StringRef pdb_filename = original_pdb_spec.
GetFilename();
123 for (
const FileSpec &search_dir : search_paths) {
132static std::unique_ptr<PDBFile>
135 using namespace llvm::object;
136 auto expected_binary = createBinary(exe_path);
139 if (!expected_binary) {
140 llvm::consumeError(expected_binary.takeError());
143 OwningBinary<Binary> binary = std::move(*expected_binary);
147 auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
150 const llvm::codeview::DebugInfo *pdb_info =
nullptr;
153 llvm::StringRef pdb_file;
154 if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) {
155 consumeError(std::move(e));
159 std::optional<std::string> resolved_pdb_path =
161 if (!resolved_pdb_path)
170 auto expected_info =
pdb->getPDBInfoStream();
171 if (!expected_info) {
172 llvm::consumeError(expected_info.takeError());
175 llvm::codeview::GUID guid;
176 memcpy(&guid, pdb_info->PDB70.Signature, 16);
178 if (expected_info->getGuid() != guid)
203 case SimpleTypeKind::Boolean128:
205 case SimpleTypeKind::Boolean64:
207 case SimpleTypeKind::Boolean32:
209 case SimpleTypeKind::Boolean16:
211 case SimpleTypeKind::Boolean8:
214 case SimpleTypeKind::Byte:
215 case SimpleTypeKind::UnsignedCharacter:
216 return "unsigned char";
217 case SimpleTypeKind::NarrowCharacter:
219 case SimpleTypeKind::SignedCharacter:
220 case SimpleTypeKind::SByte:
221 return "signed char";
222 case SimpleTypeKind::Character32:
224 case SimpleTypeKind::Character16:
226 case SimpleTypeKind::Character8:
229 case SimpleTypeKind::Complex128:
230 return "_Complex __float128";
231 case SimpleTypeKind::Complex80:
232 return "_Complex long double";
233 case SimpleTypeKind::Complex64:
234 return "_Complex double";
235 case SimpleTypeKind::Complex48:
236 return "_Complex __float48";
237 case SimpleTypeKind::Complex32:
238 case SimpleTypeKind::Complex32PartialPrecision:
239 return "_Complex float";
240 case SimpleTypeKind::Complex16:
241 return "_Complex _Float16";
243 case SimpleTypeKind::Float128:
245 case SimpleTypeKind::Float80:
246 return "long double";
247 case SimpleTypeKind::Float64:
249 case SimpleTypeKind::Float48:
251 case SimpleTypeKind::Float32:
252 case SimpleTypeKind::Float32PartialPrecision:
254 case SimpleTypeKind::Float16:
257 case SimpleTypeKind::Int128Oct:
258 case SimpleTypeKind::Int128:
260 case SimpleTypeKind::Int64:
261 case SimpleTypeKind::Int64Quad:
263 case SimpleTypeKind::Int32Long:
265 case SimpleTypeKind::Int32:
267 case SimpleTypeKind::Int16:
268 case SimpleTypeKind::Int16Short:
271 case SimpleTypeKind::UInt128Oct:
272 case SimpleTypeKind::UInt128:
273 return "unsigned __int128";
274 case SimpleTypeKind::UInt64:
275 case SimpleTypeKind::UInt64Quad:
276 return "unsigned long long";
277 case SimpleTypeKind::UInt32:
279 case SimpleTypeKind::UInt16:
280 case SimpleTypeKind::UInt16Short:
281 return "unsigned short";
282 case SimpleTypeKind::UInt32Long:
283 return "unsigned long";
285 case SimpleTypeKind::HResult:
287 case SimpleTypeKind::Void:
289 case SimpleTypeKind::WideCharacter:
292 case SimpleTypeKind::None:
293 case SimpleTypeKind::NotTranslated:
310static std::optional<CVTagRecord>
329 if (Record.Type.isSimple())
332 CVType cvt = tpi.getType(Record.Type);
341 std::string qname = std::string(parent.
asTag().getUniqueName());
342 if (qname.size() < 4 || child.
asTag().getUniqueName().size() < 4)
348 qname[3] = child.
asTag().getUniqueName()[3];
352 piece += Record.Name;
353 piece.push_back(
'@');
354 qname.insert(4, std::move(piece));
355 if (qname != child.
asTag().UniqueName)
358 return std::move(child);
374 return "Microsoft PDB debug symbol cross-platform file reader.";
378 if (!llvm::isa_and_nonnull<ObjectFilePECOFF, ObjectFilePDB>(objfile_sp.get()))
392 uint32_t abilities = 0;
400 pdb_file = &
pdb->GetPDBFile();
412 pdb_file->getFilePath(),
413 m_objfile_sp->GetModule()->GetObjectFile()->GetFileSpec().GetPath());
416 if (!expected_index) {
417 llvm::consumeError(expected_index.takeError());
420 m_index = std::move(*expected_index);
429 if (
m_index->dbi().isStripped())
440 m_index->ParseSectionContribs();
442 auto ts_or_err =
m_objfile_sp->GetModule()->GetTypeSystemForLanguage(
444 if (
auto err = ts_or_err.takeError()) {
446 "Failed to initialize: {0}");
448 if (
auto ts = *ts_or_err)
449 ts->SetSymbolFile(
this);
454 const DbiModuleList &modules =
m_index->dbi().modules();
455 uint32_t count = modules.getModuleCount();
462 DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
463 if (last.getModuleName() ==
"* Linker *")
474 if (
auto err = ts_or_err.takeError())
476 auto ts = *ts_or_err;
481 switch (sym.kind()) {
487 return &func->GetBlock(
false);
494 BlockSym block(
static_cast<SymbolRecordKind
>(sym.kind()));
495 if (
auto err = SymbolDeserializer::deserializeAs<BlockSym>(sym, block)) {
497 "Failed to deserialize BlockSym record: {0}");
500 if (block.Parent == 0) {
516 m_index->MakeVirtualAddress(block.Segment, block.CodeOffset);
519 if (block_base >= func_base)
520 child_block->AddRange(
Block::Range(block_base - func_base, block.CodeSize));
523 "S_BLOCK32 at modi: {0:d} offset: {1:d}: adding range "
524 "[{2:x16}-{3:x16}) which has a base that is less than the "
525 "function's low PC {4:x16}",
527 block_base + block.CodeSize, func_base);
531 m_blocks.insert({opaque_block_uid, child_block});
536 comp_unit->GetLineTable();
538 std::shared_ptr<InlineSite> inline_site =
m_inline_sites[opaque_block_uid];
546 for (
size_t i = 0; i < inline_site->ranges.GetSize(); ++i) {
547 auto *entry = inline_site->ranges.GetEntryAtIndex(i);
548 child_block->AddRange(
549 Block::Range(entry->GetRangeBase(), entry->GetByteSize()));
551 child_block->FinalizeRanges();
554 Declaration &decl = inline_site->inline_function_info->GetDeclaration();
555 Declaration &callsite = inline_site->inline_function_info->GetCallSite();
556 child_block->SetInlinedFunctionInfo(
557 inline_site->inline_function_info->GetName().GetCString(),
nullptr,
559 m_blocks.insert({opaque_block_uid, child_block});
580 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32) {
596 ProcSym proc(
static_cast<SymbolRecordKind
>(sym_record.kind()));
597 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)) {
599 "Failed to deserialize ProcSym record: {0}");
602 if (proc.FunctionType == TypeIndex::None())
611 SegmentOffset(proc.Segment, proc.CodeOffset), proc.FunctionType);
612 Mangled mangled(mangled_opt.value_or(proc.Name));
614 FunctionSP func_sp = std::make_shared<Function>(
616 func_type.get(), func_addr,
622 if (
auto err = ts_or_err.takeError())
624 auto ts = *ts_or_err;
627 ast_builder->EnsureFunction(func_id);
643 llvm::SmallString<64> source_file_name;
644 if (
auto main_file_or_err =
m_index->compilands().GetMainSourceFile(cci)) {
645 source_file_name = std::move(*main_file_or_err);
648 "Failed to determine main source file: {0}");
650 FileSpec fs(llvm::sys::path::convert_to_slash(
651 source_file_name, llvm::sys::path::Style::windows_backslash));
653 CompUnitSP cu_sp = std::make_shared<CompileUnit>(
654 m_objfile_sp->GetModule(),
nullptr, std::make_shared<SupportFile>(fs),
662 const ModifierRecord &mr,
664 TpiStream &stream =
m_index->tpi();
668 if ((mr.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
670 if ((mr.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)
672 if ((mr.Modifiers & ModifierOptions::Unaligned) != ModifierOptions::None)
673 name +=
"__unaligned ";
675 if (mr.ModifiedType.isSimple())
678 name += computeTypeName(stream.typeCollection(), mr.ModifiedType);
683 llvm::expectedToOptional(modified_type->GetByteSize(
nullptr)),
690 const llvm::codeview::PointerRecord &pr,
696 if (pr.isPointerToMember()) {
697 MemberPointerInfo mpi = pr.getMemberInfo();
710 if (ti == TypeIndex::NullptrT()) {
717 if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
719 uint32_t pointer_size = 0;
720 switch (ti.getSimpleMode()) {
721 case SimpleTypeMode::FarPointer32:
722 case SimpleTypeMode::NearPointer32:
725 case SimpleTypeMode::NearPointer64:
737 if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
749 if (!record.hasUniqueName())
752 llvm::ms_demangle::Demangler demangler;
753 std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());
754 llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
758 llvm::ms_demangle::IdentifierNode *idn =
759 ttn->QualifiedName->getUnqualifiedIdentifier();
760 return idn->toString();
765 const TagRecord &record,
773 decl = std::move(*maybeDecl);
776 "Failed to resolve declaration for '{1}': {0}", uname);
784 const ClassRecord &cr,
790 const UnionRecord &ur,
796 const EnumRecord &er,
803 decl = std::move(*maybeDecl);
806 "Failed to resolve declaration for '{1}': {0}", uname);
812 llvm::expectedToOptional(underlying_type->GetByteSize(
nullptr)),
nullptr,
818 const ArrayRecord &ar,
827 array_sp->SetEncodingType(element_type.get());
832 const MemberFunctionRecord &mfr,
834 if (mfr.ReturnType.isSimple())
845 const ProcedureRecord &pr,
847 if (pr.ReturnType.isSimple())
858 llvm::codeview::TypeIndex arglist_ti) {
859 if (arglist_ti.isNoneType())
862 CVType arglist_cvt =
m_index->tpi().getType(arglist_ti);
863 if (arglist_cvt.kind() != LF_ARGLIST)
868 TypeDeserializer::deserializeAs<ArgListRecord>(arglist_cvt, alr)) {
870 "Failed to deserialize ArgListRecord record ({1}): {0}",
874 for (TypeIndex
id : alr.getIndices())
875 if (!
id.isNoneType() &&
id.isSimple())
880 if (type_id.
index.isSimple())
884 CVType cvt = stream.getType(type_id.
index);
886 if (cvt.kind() == LF_MODIFIER) {
887 ModifierRecord modifier;
889 TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)) {
891 "Failed to deserialize ModifierRecord record ({1}): {0}",
898 if (cvt.kind() == LF_POINTER) {
899 PointerRecord pointer;
901 TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)) {
903 "Failed to deserialize PointerRecord record ({1}): {0}",
912 if (
auto err = TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)) {
914 "Failed to deserialize ClassRecord record ({1}): {0}",
921 if (cvt.kind() == LF_ENUM) {
923 if (
auto err = TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)) {
925 "Failed to deserialize EnumRecord record ({1}): {0}",
932 if (cvt.kind() == LF_UNION) {
934 if (
auto err = TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)) {
936 "Failed to deserialize UnionRecord record ({1}): {0}",
943 if (cvt.kind() == LF_ARRAY) {
945 if (
auto err = TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)) {
947 "Failed to deserialize ArrayRecord record ({1}): {0}",
954 if (cvt.kind() == LF_PROCEDURE) {
956 if (
auto err = TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)) {
958 "Failed to deserialize ProcedureRecord record ({1}): {0}",
964 if (cvt.kind() == LF_MFUNCTION) {
965 MemberFunctionRecord mfr;
967 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)) {
970 "Failed to deserialize MemberFunctionRecord record ({1}): {0}",
983 std::optional<PdbTypeSymId> full_decl_uid;
985 auto expected_full_ti =
986 m_index->tpi().findFullDeclForForwardRef(type_id.
index);
987 if (!expected_full_ti)
988 llvm::consumeError(expected_full_ti.takeError());
989 else if (*expected_full_ti != type_id.
index) {
997 if (full_iter !=
m_types.end()) {
998 TypeSP result = full_iter->second;
1007 PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
1009 if (
auto err = ts_or_err.takeError())
1011 auto ts = *ts_or_err;
1041 return iter->second;
1050 CVSymbol sym =
m_index->symrecords().readRecord(var_id.
offset);
1051 if (sym.kind() == S_CONSTANT)
1057 llvm::StringRef name;
1060 bool is_external =
false;
1062 switch (sym.kind()) {
1067 DataSym ds(sym.kind());
1068 if (
auto err = SymbolDeserializer::deserializeAs<DataSym>(sym, ds)) {
1070 "Failed to deserialize DataSym record: {0}");
1078 addr =
m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
1089 ThreadLocalDataSym tlds(sym.kind());
1091 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)) {
1093 "Failed to deserialize ThreadLocalDataSym record: {0}");
1099 addr =
m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
1108 llvm_unreachable(
"unreachable!");
1112 std::optional<uint16_t> modi =
m_index->GetModuleIndexForVa(addr);
1123 std::make_shared<SymbolFileType>(*
this,
toOpaqueUid(tid));
1126 if (
auto err = ts_or_err.takeError())
1128 auto ts = *ts_or_err;
1129 std::string var_name = name.str();
1131 if (
PdbAstBuilder *ast_builder = ts->GetNativePDBParser()) {
1132 ast_builder->EnsureVariable(var_id);
1133 var_name = ast_builder->GetQualifiedName(name);
1142 bool artificial =
false;
1143 bool location_is_constant_data =
false;
1144 bool static_member =
false;
1145 VariableSP var_sp = std::make_shared<Variable>(
1146 toOpaqueUid(var_id), var_name.c_str(), mangled_name.str().c_str(),
1147 type_sp, scope, comp_unit.get(), ranges, &decl, location, is_external,
1148 artificial, location_is_constant_data, static_member);
1155 const CVSymbol &cvs) {
1156 TpiStream &tpi =
m_index->tpi();
1157 ConstantSym constant(cvs.kind());
1159 if (cvs.kind() != S_CONSTANT)
1163 SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)) {
1165 "Failed to deserialize ConstantSym record: {0}");
1170 std::make_shared<SymbolFileType>(*
this,
toOpaqueUid(tid));
1176 constant.Value, module);
1177 if (!location_or_err) {
1179 "Failed to make constant location expression for {1}: {0}",
1185 std::string var_name = constant.Name.str();
1187 if (
auto err = ts_or_err.takeError()) {
1189 "Failed to get type system for {1}: {0}", constant.Name);
1190 }
else if (
auto ts = *ts_or_err) {
1192 var_name = ast_builder->GetQualifiedName(constant.Name);
1195 bool external =
false;
1196 bool artificial =
false;
1197 bool location_is_constant_data =
true;
1198 bool static_member =
false;
1199 VariableSP var_sp = std::make_shared<Variable>(
1202 ranges, &decl, location, external, artificial, location_is_constant_data,
1210 if (emplace_result.second) {
1212 emplace_result.first->second = var_sp;
1217 return emplace_result.first->second;
1227 if (emplace_result.second)
1228 emplace_result.first->second =
CreateFunction(func_id, comp_unit);
1230 return emplace_result.first->second;
1236 auto emplace_result =
1238 if (emplace_result.second) {
1244 return emplace_result.first->second;
1250 return iter->second.get();
1269 assert(index < UINT16_MAX &&
"Invalid compile unit index");
1270 if (index >= UINT16_MAX)
1282 assert(
false &&
"uid of compile unit not a compiland");
1296 auto *section_list =
1297 m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList();
1301 llvm::DenseMap<lldb::addr_t, llvm::SmallVector<uint32_t, 1>> symbols_by_addr;
1302 for (uint32_t i = 0, n = symtab.
GetNumSymbols(); i < n; ++i) {
1308 PublicSym32 last_sym;
1309 size_t last_sym_idx = 0;
1317 auto finish_last_symbol = [&](
const PublicSym32 *next) {
1324 if (next && last_sym.Segment == next->Segment) {
1325 if (next->Offset < last_sym.Offset) {
1327 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1328 "greater than the following offset {3}",
1329 last_sym.Name, last_sym.Segment, last_sym.Offset,
1333 last->
SetByteSize(next->Offset - last_sym.Offset);
1336 if (section_sp->GetByteSize() < last_sym.Offset) {
1338 "Ignoring size estimate for '{0}': segment {1} offset {2} is "
1339 "past the end of section '{3}' (size {4})",
1340 last_sym.Name, last_sym.Segment, last_sym.Offset,
1341 section_sp->GetName(), section_sp->GetByteSize());
1344 last->
SetByteSize(section_sp->GetByteSize() - last_sym.Offset);
1349 for (
auto pid :
m_index->publics().getAddressMap()) {
1351 CVSymbol sym =
m_index->ReadSymbolRecord(global);
1352 auto kind = sym.kind();
1353 if (kind != S_PUB32)
1355 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
1358 "Failed to deserialize PublicSym32 record: {0}");
1361 PublicSym32 pub = std::move(*pub_or_err);
1362 finish_last_symbol(&pub);
1364 if (!section_sp || last_sym.Segment != pub.Segment)
1365 section_sp = section_list->FindSectionByID(pub.Segment);
1371 if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||
1372 (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
1390 if (it != symbols_by_addr.end() &&
1391 llvm::any_of(it->second, [&](uint32_t idx) {
1392 Symbol *sym = symtab.SymbolAtIndex(idx);
1393 return sym && sym->GetMangled() == pub_symbol.GetMangled();
1397 last_sym_idx = symtab.
AddSymbol(pub_symbol);
1401 finish_last_symbol(
nullptr);
1408 assert(
false &&
"uid of compile unit not a compiland");
1416 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
1417 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
1426 if (new_count < count) {
1427 assert(
false &&
"less functions after parsing than before");
1430 return new_count - count;
1435 uint32_t flags = eSymbolContextCompUnit;
1436 flags |= eSymbolContextVariable;
1437 flags |= eSymbolContextFunction;
1438 flags |= eSymbolContextBlock;
1439 flags |= eSymbolContextLineEntry;
1440 return (resolve_scope & flags) != 0;
1444 const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
1446 uint32_t resolved_flags = 0;
1450 std::optional<uint16_t> modi =
m_index->GetModuleIndexForVa(file_addr);
1458 resolved_flags |= eSymbolContextCompUnit;
1461 if (resolve_scope & eSymbolContextFunction ||
1462 resolve_scope & eSymbolContextBlock) {
1465 "missing compile unit for symbol at address {0:x}", file_addr);
1468 std::vector<SymbolAndUid> matches =
m_index->FindSymbolsByVa(file_addr);
1472 for (
const auto &match : llvm::reverse(matches)) {
1476 PdbCompilandSymId csid = match.uid.asCompilandSym();
1477 CVSymbol cvs =
m_index->ReadSymbolRecord(csid);
1479 if (type != PDB_SymType::Function && type != PDB_SymType::Block)
1481 if (type == PDB_SymType::Function) {
1486 addr_t offset = file_addr - func_base;
1491 if (type == PDB_SymType::Block) {
1499 addr_t offset = file_addr - func_base;
1504 resolved_flags |= eSymbolContextFunction;
1506 resolved_flags |= eSymbolContextBlock;
1511 if (resolve_scope & eSymbolContextLineEntry) {
1514 "missing compile unit for symbol at address {0:x}", file_addr);
1518 if (line_table->FindLineEntryByAddress(addr, sc.
line_entry))
1519 resolved_flags |= eSymbolContextLineEntry;
1523 return resolved_flags;
1530 const uint32_t prev_size = sc_list.
GetSize();
1531 if (resolve_scope & eSymbolContextCompUnit) {
1540 if (file_spec_matches_cu_file_spec) {
1546 return sc_list.
GetSize() - prev_size;
1557 assert(
false &&
"uid of compile unit not a compiland");
1571 std::set<LineTable::Entry, LineTableEntryComparator> line_set;
1576 for (
const DebugSubsectionRecord &dssr :
1578 if (dssr.kind() != DebugSubsectionKind::Lines)
1581 DebugLinesSubsectionRef lines;
1582 llvm::BinaryStreamReader reader(dssr.getRecordData());
1583 if (
auto EC = lines.initialize(reader)) {
1584 llvm::consumeError(std::move(EC));
1588 const LineFragmentHeader *lfh = lines.header();
1589 uint64_t virtual_addr =
1590 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
1594 for (
const LineColumnEntry &group : lines) {
1595 llvm::Expected<uint32_t> file_index_or_err =
1597 if (!file_index_or_err) {
1599 "failed to get file index for line entry: {0}");
1602 uint32_t file_index = file_index_or_err.get();
1603 if (group.LineNumbers.empty()) {
1605 "no line numbers for {0} in modi={1}", group.NameIndex, modi);
1610 const bool has_columns = lines.hasColumnInfo() &&
1611 group.Columns.size() == group.LineNumbers.size();
1612 for (
const auto &[i, entry] : llvm::enumerate(group.LineNumbers)) {
1613 LineInfo cur_info(entry.Flags);
1614 uint16_t column = has_columns ? group.Columns[i].StartColumn : 0;
1616 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
1619 uint64_t addr = virtual_addr + entry.Offset;
1621 bool is_statement = cur_info.isStatement();
1625 uint32_t lno = cur_info.getStartLine();
1628 false, is_prologue, is_epilogue,
false);
1630 auto iter = line_set.find(new_entry);
1631 if (iter != line_set.end() && iter->is_terminal_entry)
1632 line_set.erase(iter);
1633 line_set.insert(new_entry);
1640 line_entry.
data = {file_index, lno};
1642 LineInfo last_line(group.LineNumbers.back().Flags);
1643 line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0,
1644 file_index,
false,
false,
false,
false,
true);
1647 line_entry.
SetRangeEnd(virtual_addr + lfh->CodeSize);
1656 const CVSymbolArray &syms = cii->
m_debug_stream.getSymbolArray();
1657 for (
auto iter = syms.begin(); iter != syms.end();) {
1658 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) {
1663 uint32_t record_offset = iter.offset();
1664 CVSymbol func_record =
1670 iter = syms.at(getScopeEndOffset(func_record));
1679 if (kind != S_INLINESITE)
1684 for (
const auto &line_entry :
1689 if (!line_entry.is_terminal_entry)
1690 line_set.erase(line_entry);
1691 line_set.insert(line_entry);
1699 iter = syms.at(getScopeEndOffset(func_record));
1705 std::vector<LineTable::Sequence> sequence(1);
1706 for (
const auto &line_entry : line_set) {
1708 sequence.back(), line_entry.file_addr, line_entry.line,
1709 line_entry.column, line_entry.file_idx,
1710 line_entry.is_start_of_statement, line_entry.is_start_of_basic_block,
1711 line_entry.is_prologue_end, line_entry.is_epilogue_begin,
1712 line_entry.is_terminal_entry);
1715 std::make_unique<LineTable>(&comp_unit, std::move(sequence));
1717 if (line_table->GetSize() == 0)
1729llvm::Expected<uint32_t>
1733 return llvm::make_error<RawError>(raw_error_code::no_entry);
1735 const auto &checksums = cii.
m_strings.checksums().getArray();
1736 const auto &strings = cii.
m_strings.strings();
1740 auto iter = checksums.at(file_id);
1741 if (iter == checksums.end())
1742 return llvm::make_error<RawError>(raw_error_code::no_entry);
1744 llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset);
1746 return efn.takeError();
1752 return std::distance(cii.
m_file_list.begin(), fn_iter);
1753 return llvm::make_error<RawError>(raw_error_code::no_entry);
1761 assert(
false &&
"uid of compile unit not a compiland");
1774 f.starts_with(
"/") ? FileSpec::Style::posix : FileSpec::Style::windows;
1776 support_files.
Append(spec);
1782 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
1795 CVSymbol sym = cii->
m_debug_stream.readSymbolAtOffset(
id.offset);
1797 if (sym.kind() != S_INLINESITE)
1800 InlineSiteSym inline_site(
static_cast<SymbolRecordKind
>(sym.kind()));
1802 SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)) {
1804 "Failed to deserialize InlineSiteSym record: {0}");
1809 std::shared_ptr<InlineSite> inline_site_sp =
1810 std::make_shared<InlineSite>(parent_id);
1813 auto iter = cii->
m_inline_map.find(inline_site.Inlinee);
1816 InlineeSourceLine inlinee_line = iter->second;
1820 llvm::Expected<uint32_t> file_index_or_err =
1822 if (!file_index_or_err) {
1824 "failed to get file index for inline site: {0}");
1827 uint32_t file_offset = file_index_or_err.get();
1829 uint32_t decl_line = inlinee_line.Header->SourceLineNum;
1830 std::unique_ptr<Declaration> decl_up =
1831 std::make_unique<Declaration>(decl_file, decl_line);
1834 uint32_t code_offset = 0;
1835 int32_t line_offset = 0;
1836 std::optional<uint32_t> code_offset_base;
1837 std::optional<uint32_t> code_offset_end;
1838 std::optional<int32_t> cur_line_offset;
1839 std::optional<int32_t> next_line_offset;
1840 std::optional<uint32_t> next_file_offset;
1842 bool is_terminal_entry =
false;
1843 bool is_start_of_statement =
true;
1845 bool is_prologue_end =
true;
1847 auto update_code_offset = [&](uint32_t code_delta) {
1848 if (!code_offset_base)
1849 code_offset_base = code_offset;
1850 else if (!code_offset_end)
1851 code_offset_end = *code_offset_base + code_delta;
1853 auto update_line_offset = [&](int32_t line_delta) {
1854 line_offset += line_delta;
1855 if (!code_offset_base || !cur_line_offset)
1856 cur_line_offset = line_offset;
1858 next_line_offset = line_offset;
1861 auto update_file_offset = [&](uint32_t offset) {
1862 if (!code_offset_base)
1863 file_offset = offset;
1865 next_file_offset = offset;
1868 for (
auto &annot : inline_site.annotations()) {
1869 switch (annot.OpCode) {
1870 case BinaryAnnotationsOpCode::CodeOffset:
1871 case BinaryAnnotationsOpCode::ChangeCodeOffset:
1872 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
1873 code_offset += annot.U1;
1874 update_code_offset(annot.U1);
1876 case BinaryAnnotationsOpCode::ChangeLineOffset:
1877 update_line_offset(annot.S1);
1879 case BinaryAnnotationsOpCode::ChangeCodeLength:
1880 update_code_offset(annot.U1);
1881 code_offset += annot.U1;
1882 is_terminal_entry =
true;
1884 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
1885 code_offset += annot.U1;
1886 update_code_offset(annot.U1);
1887 update_line_offset(annot.S1);
1889 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
1890 code_offset += annot.U2;
1891 update_code_offset(annot.U2);
1892 update_code_offset(annot.U1);
1893 code_offset += annot.U1;
1894 is_terminal_entry =
true;
1896 case BinaryAnnotationsOpCode::ChangeFile:
1897 update_file_offset(annot.U1);
1904 if (code_offset_base && code_offset_end && cur_line_offset) {
1906 *code_offset_base, *code_offset_end - *code_offset_base,
1907 decl_line + *cur_line_offset));
1909 if (next_file_offset)
1910 file_offset = *next_file_offset;
1911 if (next_line_offset) {
1912 cur_line_offset = next_line_offset;
1913 next_line_offset = std::nullopt;
1915 code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end;
1916 code_offset_end = next_file_offset = std::nullopt;
1918 if (code_offset_base && cur_line_offset) {
1919 if (is_terminal_entry) {
1921 func_base + *code_offset_base, decl_line + *cur_line_offset, 0,
1922 file_offset,
false,
false,
false,
false,
true);
1923 inline_site_sp->line_entries.push_back(line_entry);
1926 decl_line + *cur_line_offset, 0,
1927 file_offset, is_start_of_statement,
false,
1928 is_prologue_end,
false,
false);
1929 inline_site_sp->line_entries.push_back(line_entry);
1930 is_prologue_end =
false;
1931 is_start_of_statement =
false;
1934 if (is_terminal_entry)
1935 is_start_of_statement =
true;
1936 is_terminal_entry =
false;
1939 inline_site_sp->ranges.Sort();
1942 std::unique_ptr<Declaration> callsite_up;
1943 if (!inline_site_sp->ranges.IsEmpty()) {
1944 auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0);
1945 addr_t base_offset = entry->GetRangeBase();
1951 std::shared_ptr<InlineSite> parent_site =
1954 parent_site->inline_function_info->GetDeclaration().GetFile();
1955 if (
auto *parent_entry =
1956 parent_site->ranges.FindEntryThatContains(base_offset)) {
1958 std::make_unique<Declaration>(parent_decl_file, parent_entry->data);
1963 func_base + base_offset)) {
1967 std::make_unique<Declaration>(callsite_file, entry->data.second);
1973 std::string inlinee_name;
1974 llvm::Expected<CVType> inlinee_cvt =
1975 m_index->ipi().typeCollection().getTypeOrError(inline_site.Inlinee);
1977 inlinee_name =
"[error reading function name: " +
1978 llvm::toString(inlinee_cvt.takeError()) +
"]";
1979 }
else if (inlinee_cvt->kind() == LF_MFUNC_ID) {
1980 MemberFuncIdRecord mfr;
1981 if (
auto err = TypeDeserializer::deserializeAs<MemberFuncIdRecord>(
1982 *inlinee_cvt, mfr)) {
1984 "[error reading function name: " + llvm::toString(std::move(err)) +
1987 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
1988 inlinee_name.append(std::string(types.getTypeName(mfr.ClassType)));
1989 inlinee_name.append(
"::");
1990 inlinee_name.append(mfr.getName().str());
1992 }
else if (inlinee_cvt->kind() == LF_FUNC_ID) {
1995 TypeDeserializer::deserializeAs<FuncIdRecord>(*inlinee_cvt, fir)) {
1997 "[error reading function name: " + llvm::toString(std::move(err)) +
2000 TypeIndex parent_idx = fir.getParentScope();
2001 if (!parent_idx.isNoneType()) {
2002 LazyRandomTypeCollection &ids =
m_index->ipi().typeCollection();
2003 inlinee_name.append(std::string(ids.getTypeName(parent_idx)));
2004 inlinee_name.append(
"::");
2006 inlinee_name.append(fir.getName().str());
2009 inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>(
2010 inlinee_name.c_str(), llvm::StringRef(), decl_up.get(),
2021 std::set<uint64_t> remove_uids;
2023 if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 ||
2024 kind == S_INLINESITE) {
2026 if (kind == S_INLINESITE)
2033 for (uint64_t uid : remove_uids) {
2045 CVSymbolArray syms =
2049 for (
auto iter = syms.begin(); iter != syms.end(); ++iter) {
2051 if (fn(iter->kind(), child_id))
2063 "failed to get C++ type system: {0}");
2066 auto ts = *ts_or_err;
2073 ast_builder->
Dump(s, filter, show_color);
2081 std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids;
2084 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2085 CVSymbol sym =
m_index->symrecords().readRecord(gid);
2086 auto kind = sym.kind();
2089 llvm::StringRef name;
2091 case SymbolKind::S_GDATA32:
2092 case SymbolKind::S_LDATA32: {
2093 auto data_or_err = SymbolDeserializer::deserializeAs<DataSym>(sym);
2096 "Failed to deserialize DataSym record: {0}");
2099 name = data_or_err->Name;
2102 case SymbolKind::S_GTHREAD32:
2103 case SymbolKind::S_LTHREAD32: {
2105 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym);
2108 "Failed to deserialize ThreadLocalDataSym record: {0}");
2111 name = data_or_err->Name;
2114 case SymbolKind::S_CONSTANT: {
2115 auto data_or_err = SymbolDeserializer::deserializeAs<ConstantSym>(sym);
2118 "Failed to deserialize ConstantSym record: {0}");
2121 name = data_or_err->Name;
2128 if (!name.empty()) {
2137 if (kind != S_PROCREF && kind != S_LPROCREF)
2143 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2146 "Failed to deserialize ProcRefSym record: {0}");
2149 ProcRefSym ref = std::move(*ref_or_err);
2150 if (ref.Name.empty())
2155 m_index->compilands().GetOrCreateCompiland(ref.modi());
2156 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref.SymOffset);
2159 kind = iter->kind();
2160 if (kind != S_GPROC32 && kind != S_LPROC32)
2163 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
2166 "Failed to deserialize ProcSym record: {0}");
2169 ProcSym proc = std::move(*proc_or_err);
2170 if ((proc.Flags & ProcSymFlags::IsUnreachable) != ProcSymFlags::None)
2172 if (proc.Name.empty() || proc.FunctionType.isSimple())
2178 func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid);
2181 if (basename.empty())
2182 basename = proc.Name;
2188 auto type =
m_index->tpi().getType(proc.FunctionType);
2189 if (type.kind() == LF_MFUNCTION) {
2190 MemberFunctionRecord mfr;
2191 if (
auto err = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2195 "Failed to deserialize MemberFunctionRecord record ({1}): {0}",
2197 }
else if (!mfr.getThisType().isNoneType())
2203 for (
auto pid :
m_index->publics().getPublicsTable()) {
2205 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2206 auto kind = sym.kind();
2207 if (kind != S_PUB32)
2209 auto pub_or_err = SymbolDeserializer::deserializeAs<PublicSym32>(sym);
2212 "Failed to deserialize PublicSym32 record: {0}");
2215 PublicSym32 pub = std::move(*pub_or_err);
2222 auto it = func_addr_ids.find({pub.Segment, pub.Offset});
2223 if (it != func_addr_ids.end())
2247 bool is_rooted = lookup_name.consume_front(
"::");
2249 llvm::StringRef context;
2250 llvm::StringRef basename;
2253 basename = lookup_name;
2254 std::string scoped_suffix = (
"::" + lookup_name).str();
2256 std::vector<uint32_t> results;
2259 size_t n_matches = 0;
2260 for (uint32_t gid : results) {
2263 if (parent_decl_ctx.
IsValid() &&
2270 if (is_rooted || !context.empty()) {
2271 llvm::StringRef var_name = var->GetName().GetStringRef();
2272 if (var_name != lookup_name &&
2273 (is_rooted || !var_name.ends_with(scoped_suffix)))
2278 if (++n_matches >= max_matches)
2290 if (name_type_mask & eFunctionNameTypeFull)
2293 if (!(name_type_mask & eFunctionNameTypeFull ||
2294 name_type_mask & eFunctionNameTypeBase ||
2295 name_type_mask & eFunctionNameTypeMethod))
2299 std::set<uint32_t> resolved_ids;
2301 std::vector<uint32_t> ids;
2302 if (!Names.GetValues(name, ids))
2305 for (uint32_t
id : ids) {
2306 if (!resolved_ids.insert(
id).second)
2310 if (parent_decl_ctx.
IsValid() &&
2318 if (name_type_mask & eFunctionNameTypeFull)
2320 if (name_type_mask & eFunctionNameTypeBase)
2322 if (name_type_mask & eFunctionNameTypeMethod)
2327 bool include_inlines,
2334 std::vector<uint32_t> ids;
2338 std::set<uint32_t> resolved_ids;
2339 for (uint32_t
id : ids)
2340 if (resolved_ids.insert(
id).second)
2346 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2347 auto kind = sym.kind();
2348 if (kind != S_PROCREF && kind != S_LPROCREF) {
2353 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
2356 "Failed to deserialize ProcRefSym record: {0}");
2359 ProcRefSym proc = std::move(*proc_or_err);
2365 m_index->compilands().GetOrCreateCompiland(proc.modi());
2394 std::vector<uint32_t> matches;
2397 for (uint32_t match_idx : matches) {
2399 if (context.empty())
2408 if (results.
Done(query))
2414 std::vector<uint32_t> typedef_matches;
2416 for (uint32_t gid : typedef_matches) {
2426 if (results.
Done(query))
2431std::vector<CompilerContext>
2433 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
2434 if (sym.kind() != S_UDT)
2436 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2438 llvm::consumeError(udt_or_err.takeError());
2442 std::optional<Type::ParsedName> parsed_name =
2449 std::vector<CompilerContext> ctx;
2450 for (llvm::StringRef scope : parsed_name->scope)
2458 uint32_t max_matches,
2461 std::vector<TypeIndex> matches =
m_index->tpi().findRecordsByName(name);
2462 if (max_matches > 0 && max_matches < matches.size())
2463 matches.resize(max_matches);
2465 for (TypeIndex ti : matches) {
2481 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
2484 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
2487 (void)type->GetFullCompilerType();
2491 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2493 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2494 if (sym.kind() != S_UDT)
2497 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2500 "Failed to deserialize UDTSym record: {0}");
2511 return new_count - old_count;
2517 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
2519 CVSymbol sym =
m_index->ReadSymbolRecord(global);
2524 switch (sym.kind()) {
2525 case SymbolKind::S_GDATA32:
2526 case SymbolKind::S_LDATA32:
2527 case SymbolKind::S_GTHREAD32:
2528 case SymbolKind::S_LTHREAD32: {
2530 if (var && var->GetSymbolContextScope() == &comp_unit)
2556 bool location_is_constant_data = is_constant;
2560 if (sym.kind() != S_CONSTANT)
2562 ConstantSym constant(sym.kind());
2564 SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant)) {
2566 "Failed to deserialize ConstantSym record: {0}");
2570 var_info.
name = constant.Name;
2571 var_info.
type = constant.Type;
2573 constant.Type,
m_index->tpi(), constant.Value, module);
2574 if (!location_or_err) {
2576 "Failed to make constant location expression for {1}: {0}",
2584 Block *func_block = block;
2605 std::string name = var_info.
name.str();
2608 std::make_shared<SymbolFileType>(*
this, type_sp->GetID());
2613 bool external =
false;
2614 bool artificial =
false;
2615 bool static_member =
false;
2617 VariableSP var_sp = std::make_shared<Variable>(
2618 toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, block,
2619 scope_ranges, &decl, var_info.
location, external, artificial,
2620 location_is_constant_data, static_member);
2623 if (
auto err = ts_or_err.takeError())
2625 auto ts = *ts_or_err;
2628 ast_builder->EnsureVariable(scope_id, var_id);
2638 bool is_param,
bool is_constant) {
2641 return iter->second;
2651 return iter->second;
2658 CVSymbol sym =
m_index->ReadSymbolRecord(var_id);
2660 llvm::StringRef name;
2663 switch (sym.kind()) {
2665 DataSym ds(sym.kind());
2666 if (
auto err = SymbolDeserializer::deserializeAs<DataSym>(sym, ds)) {
2668 "Failed to deserialize DataSym record: {0}");
2678 ThreadLocalDataSym tlds(sym.kind());
2680 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)) {
2682 "Failed to deserialize ThreadLocalDataSym record: {0}");
2700 std::make_shared<SymbolFileType>(*
this, type_sp->GetID());
2704 VariableSP var_sp = std::make_shared<Variable>(
2705 toOpaqueUid(var_id), name.str().c_str(),
nullptr, sftype,
2714 if (
auto err = ts_or_err.takeError())
2715 llvm::consumeError(std::move(err));
2716 else if (
auto ts = *ts_or_err)
2718 ast_builder->EnsureVariable(scope_id, var_id);
2726 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
2727 if (sym.kind() != S_UDT) {
2732 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
2735 "Failed to deserialize UDTSym record: {0}");
2738 UDTSym udt = std::move(*udt_or_err);
2743 if (
auto err = ts_or_err.takeError())
2745 auto ts = *ts_or_err;
2753 ct = target_type->GetForwardCompilerType();
2757 llvm::expectedToOptional(target_type->GetByteSize(
nullptr)),
2758 nullptr, target_type->GetID(),
2766 return iter->second;
2778 CVType cvt =
m_index->tpi().getType(udt.Type);
2791 uint32_t params_remaining = 0;
2792 switch (sym.kind()) {
2795 ProcSym proc(
static_cast<SymbolRecordKind
>(sym.kind()));
2796 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)) {
2798 "Failed to deserialize ProcSym record: {0}");
2801 CVType signature =
m_index->tpi().getType(proc.FunctionType);
2802 if (signature.kind() == LF_PROCEDURE) {
2803 ProcedureRecord sig;
2804 if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>(
2806 llvm::consumeError(std::move(e));
2809 params_remaining = sig.getParameterCount();
2810 }
else if (signature.kind() == LF_MFUNCTION) {
2811 MemberFunctionRecord sig;
2812 if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>(
2814 llvm::consumeError(std::move(e));
2817 params_remaining = sig.getParameterCount();
2833 variables = std::make_shared<VariableList>();
2837 CVSymbolArray syms = limitSymbolArrayToScope(
2843 auto iter = syms.begin();
2844 auto end = syms.end();
2846 while (iter != end) {
2847 uint32_t record_offset = iter.offset();
2848 CVSymbol variable_cvs = *iter;
2854 if (variable_cvs.kind() == S_BLOCK32 ||
2855 variable_cvs.kind() == S_INLINESITE) {
2856 uint32_t block_end = getScopeEndOffset(variable_cvs);
2858 iter = syms.at(block_end);
2862 bool is_param = params_remaining > 0;
2864 switch (variable_cvs.kind()) {
2866 case S_REGREL32_INDIR:
2873 variables->AddVariableIfUnique(variable);
2880 variables->AddVariableIfUnique(variable);
2886 variables->AddVariableIfUnique(variable);
2920 variables = std::make_shared<VariableList>();
2927 "missing missing block, function, or module for symbol context");
2933 if (
auto err = ts_or_err.takeError())
2935 auto ts = *ts_or_err;
2947 if (
auto err = ts_or_err.takeError())
2949 auto ts = *ts_or_err;
2961 if (
auto err = ts_or_err.takeError())
2963 auto ts = *ts_or_err;
2974 auto iter =
m_types.find(type_uid);
2981 return &*iter->second;
2985 assert(
false &&
"uid is not a type index");
2989 if (type_id.
index.isNoneType())
2998std::optional<SymbolFile::ArrayInfo>
3001 return std::nullopt;
3017 TypeClass type_mask,
3026 if (
auto err = ts_or_err.takeError())
3028 auto ts = *ts_or_err;
3031 auto *
clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
3045 std::string qualified_name;
3046 if (parent_decl_ctx.
IsValid())
3056llvm::Expected<lldb::TypeSystemSP>
3058 auto type_system_or_err =
3059 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
3060 if (type_system_or_err)
3061 if (
auto ts = *type_system_or_err)
3062 ts->SetSymbolFile(
this);
3063 return type_system_or_err;
3068 return m_index->pdb().getFileSize();
3076 LazyRandomTypeCollection &types =
m_index->tpi().typeCollection();
3078 llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
3079 llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
3081 struct RecordIndices {
3086 llvm::StringMap<RecordIndices> record_indices;
3088 for (
auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
3089 CVType type = types.getType(*ti);
3095 RecordIndices &indices = record_indices[tag.
asTag().getUniqueName()];
3096 if (tag.
asTag().isForwardRef()) {
3097 indices.forward = *ti;
3105 if (indices.full != TypeIndex::None() &&
3106 indices.forward != TypeIndex::None()) {
3107 forward_to_full[indices.forward] = indices.full;
3108 full_to_forward[indices.full] = indices.forward;
3114 if (tag.
asTag().isForwardRef() || !tag.
asTag().containsNestedClass())
3118 ProcessTpiStream(
PdbIndex &index, TypeIndex parent,
3120 llvm::DenseMap<TypeIndex, TypeIndex> &parents)
3121 : index(index), parents(parents), parent(parent),
3122 parent_cvt(parent_cvt) {}
3125 llvm::DenseMap<TypeIndex, TypeIndex> &parents;
3127 unsigned unnamed_type_index = 1;
3131 llvm::Error visitKnownMember(CVMemberRecord &CVR,
3132 NestedTypeRecord &Record)
override {
3133 std::string unnamed_type_name;
3134 if (Record.Name.empty()) {
3136 llvm::formatv(
"<unnamed-type-$S{0}>", unnamed_type_index).str();
3137 Record.Name = unnamed_type_name;
3138 ++unnamed_type_index;
3140 std::optional<CVTagRecord> tag =
3143 return llvm::ErrorSuccess();
3145 parents[Record.Type] = parent;
3146 return llvm::ErrorSuccess();
3150 CVType field_list_cvt =
m_index->tpi().getType(tag.
asTag().FieldList);
3151 if (field_list_cvt.kind() != LF_FIELDLIST)
3155 FieldListRecord field_list;
3156 if (llvm::Error
error = TypeDeserializer::deserializeAs<FieldListRecord>(
3157 field_list_cvt, field_list))
3158 llvm::consumeError(std::move(
error));
3159 if (llvm::Error
error = visitMemberRecordStream(field_list.Data, process))
3160 llvm::consumeError(std::move(
error));
3167 for (
const uint32_t gid :
m_index->globals().getGlobalsTable()) {
3168 CVSymbol sym =
m_index->symrecords().readRecord(gid);
3169 if (sym.kind() != S_UDT)
3171 auto udt_or_err = SymbolDeserializer::deserializeAs<UDTSym>(sym);
3173 llvm::consumeError(udt_or_err.takeError());
3179 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.
GetSpecifiers();
3191 std::vector<TypeIndex> full_keys;
3192 std::vector<TypeIndex> fwd_keys;
3194 TypeIndex key = entry.first;
3195 TypeIndex value = entry.second;
3197 auto iter = forward_to_full.find(value);
3198 if (iter != forward_to_full.end())
3199 entry.second = iter->second;
3201 iter = forward_to_full.find(key);
3202 if (iter != forward_to_full.end())
3203 fwd_keys.push_back(key);
3205 full_keys.push_back(key);
3207 for (TypeIndex fwd : fwd_keys) {
3208 TypeIndex full = forward_to_full[fwd];
3212 for (TypeIndex full : full_keys) {
3213 TypeIndex fwd = full_to_forward[full];
3218std::optional<PdbCompilandSymId>
3220 CVSymbol sym =
m_index->ReadSymbolRecord(
id);
3221 if (symbolOpensScope(sym.kind())) {
3224 id.offset = getScopeParentOffset(sym);
3228 return std::nullopt;
3237 auto begin = syms.begin();
3238 auto end = syms.at(
id.offset);
3239 std::vector<PdbCompilandSymId> scope_stack;
3241 while (begin != end) {
3242 if (begin.offset() >
id.offset) {
3246 return std::nullopt;
3251 if (symbolOpensScope(begin->kind())) {
3254 uint32_t scope_end = getScopeEndOffset(*begin);
3255 if (scope_end <
id.offset) {
3256 begin = syms.at(scope_end);
3259 scope_stack.emplace_back(
id.modi, begin.offset());
3261 }
else if (symbolEndsScope(begin->kind())) {
3262 scope_stack.pop_back();
3266 if (scope_stack.empty())
3267 return std::nullopt;
3269 return scope_stack.back();
3272std::optional<llvm::codeview::TypeIndex>
3277 return std::nullopt;
3278 return parent_iter->second;
3281std::vector<CompilerContext>
3283 CVType type =
m_index->tpi().getType(ti);
3289 std::optional<Type::ParsedName> parsed_name =
3294 std::vector<CompilerContext> ctx;
3296 for (llvm::StringRef scope : parsed_name->scope) {
3303 for (
auto &el : llvm::reverse(llvm::drop_end(ctx))) {
3309 type =
m_index->tpi().getType(ti);
3310 switch (type.kind()) {
3330std::optional<llvm::StringRef>
3332 TypeIndex function_type) {
3333 auto symbol =
m_index->publics().findByAddress(
m_index->symrecords(),
3336 return std::nullopt;
3338 llvm::StringRef name = symbol->first.Name;
3341 if (!function_type.isNoneType() &&
3342 (symbol->first.Flags & PublicSymFlags::Function) != PublicSymFlags::None)
3359 if (!mangled.starts_with(
'_') ||
3360 m_index->dbi().getMachineType() != PDB_Machine::x86)
3364 PDB_CallingConv cc = PDB_CallingConv::NearC;
3365 if (cvt.kind() == LF_PROCEDURE) {
3366 ProcedureRecord proc;
3367 if (llvm::Error
error =
3368 TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, proc))
3369 llvm::consumeError(std::move(
error));
3371 }
else if (cvt.kind() == LF_MFUNCTION) {
3372 MemberFunctionRecord mfunc;
3373 if (llvm::Error
error =
3374 TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfunc))
3375 llvm::consumeError(std::move(
error));
3376 cc = mfunc.CallConv;
3383 if (cc == PDB_CallingConv::NearC || cc == PDB_CallingConv::FarC)
3384 return mangled.drop_front();
3391 llvm::StringRef lookup_name) {
3392 if (lookup_name.empty())
3412 CVSymbol sym_record = cci->
m_debug_stream.readSymbolAtOffset(
id.offset);
3413 if (sym_record.kind() != S_LPROC32 && sym_record.kind() != S_GPROC32)
3416 ProcSym proc(
static_cast<SymbolRecordKind
>(sym_record.kind()));
3417 if (
auto err = SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)) {
3419 "Failed to deserialize ProcSym record: {0}");
3425 llvm::StringRef lookup_name =
3428 .value_or(proc.Name);
3434 llvm::StringRef qualified_name) {
3435 if (std::optional<PdbCompilandSymId> func_id =
3441std::optional<PdbCompilandSymId>
3443 TypeIndex method_type) {
3446 if (
m_index->globals().getGlobalsTable().HashRecords.empty())
3447 return std::nullopt;
3450 for (
const auto &[offset, sym] :
m_index->globals().findRecordsByName(
3451 qualified_name,
m_index->symrecords())) {
3452 if (sym.kind() != S_PROCREF && sym.kind() != S_LPROCREF)
3454 auto ref_or_err = SymbolDeserializer::deserializeAs<ProcRefSym>(sym);
3457 "Failed to deserialize ProcRefSym record: {0}");
3463 m_index->compilands().GetOrCreateCompiland(ref_or_err->modi());
3464 auto iter = cci.
m_debug_stream.getSymbolArray().at(ref_or_err->SymOffset);
3467 if (iter->kind() != S_GPROC32 && iter->kind() != S_LPROC32)
3469 auto proc_or_err = SymbolDeserializer::deserializeAs<ProcSym>(*iter);
3472 "Failed to deserialize ProcSym record: {0}");
3477 if (proc_or_err->FunctionType == method_type)
3480 return std::nullopt;
3483llvm::Expected<SymbolContext>
3490 !discriminator.empty()) {
3491 const bool is_ctor = discriminator.consume_front(
"C");
3493 bool is_defined =
false;
3494 if ((is_ctor || discriminator.consume_front(
"D")) &&
3495 llvm::to_integer(discriminator, kind))
3496 is_defined = is_ctor ? kind == clang::CXXCtorType::Ctor_Complete ||
3497 kind == clang::CXXCtorType::Ctor_Base
3498 : kind == clang::CXXDtorType::Dtor_Complete ||
3499 kind == clang::CXXDtorType::Dtor_Base;
3501 return llvm::createStringErrorV(
3502 "{0} refers to a structor variant without debug info", label);
3507 return llvm::createStringErrorV(
"invalid function ID in {0}", label);
3512 return llvm::createStringErrorV(
"invalid compiland in {0}", label);
3516 return llvm::createStringErrorV(
"failed to create compile unit for {0}",
3521 return llvm::createStringErrorV(
"failed to create function for {0}", label);
3524 func->CalculateSymbolContext(&sc);
3529 for (CVType cvt :
m_index->ipi().typeArray()) {
3530 switch (cvt.kind()) {
3531 case LF_UDT_SRC_LINE: {
3532 UdtSourceLineRecord udt_src;
3533 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_src)) {
3535 "Failed to deserialize UdtSourceLineRecord record: {0}");
3541 udt_src.LineNumber});
3543 case LF_UDT_MOD_SRC_LINE: {
3544 UdtModSourceLineRecord udt_mod_src;
3545 if (
auto err = TypeDeserializer::deserializeAs(cvt, udt_mod_src)) {
3548 "Failed to deserialize UdtModSourceLineRecord record: {0}");
3558 udt_mod_src.LineNumber});
3566llvm::Expected<Declaration>
3572 return llvm::createStringError(
"no UDT declaration found");
3574 llvm::StringRef file_name;
3575 if (it->second.IsIpiIndex) {
3576 CVType cvt =
m_index->ipi().getType(it->second.FileNameIndex);
3577 if (cvt.kind() != LF_STRING_ID)
3578 return llvm::createStringError(
"file name was not a LF_STRING_ID");
3581 if (
auto err = TypeDeserializer::deserializeAs(cvt, sid))
3582 return std::move(err);
3583 file_name = sid.String;
3586 auto string_table =
m_index->pdb().getStringTable();
3588 return string_table.takeError();
3590 llvm::Expected<llvm::StringRef>
string =
3591 string_table->getStringTable().getString(
3592 it->second.FileNameIndex.getIndex());
3594 return string.takeError();
3595 file_name = *string;
3599 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)
llvm::ArrayRef< MSVCUndecoratedNameSpecifier > GetSpecifiers() const
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.
ConstString GetScopeQualifiedName() const
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.
std::string GetString() const
Get the string value as a std::string.
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
Add symbols from this SymbolFile to the ObjectFile's symbol table.
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)
llvm::StringMap< uint32_t > m_typedef_scopes
Qualified name of a scope of a typedef -> Global ID of a typedef in it.
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