15#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
16#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
17#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
18#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
19#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
36 llvm::ArrayRef<LocalVariableAddrGap> gaps) {
44 while (!gaps.empty()) {
45 const LocalVariableAddrGap &gap = gaps.front();
47 result.
Append(start, gap_start - start);
48 start = gap_start + gap.Range;
49 gaps = gaps.drop_front();
52 result.
Append(start, end - start);
57struct MemberLocations {
58 std::map<uint64_t, MemberValLocation> offset_to_location;
60 bool is_dwarf =
false;
62 MemberLocations() =
default;
63 MemberLocations(
const DWARFExpression &expr) : expr(expr), is_dwarf(true) {}
64 MemberLocations(uint64_t offset,
const MemberValLocation &member_loc) {
65 insert(offset, member_loc);
68 void insert(uint64_t offset,
const MemberValLocation &member_loc) {
69 offset_to_location[offset] = member_loc;
74 bool operator()(
const MemberLocations &,
const MemberLocations &)
const {
82 MemberLocations::Comparator>
85void AddMemberLocationRanges(RangeMap &location_map, uint64_t offset,
88 RangeMap new_location_map;
90 RangeMap::Entry *entry) {
91 RangeMap::Entry overlap_region = {base, end - base, entry->data};
92 overlap_region.data.insert(offset, member_loc);
93 new_location_map.Append(overlap_region);
96 for (
const auto &range : ranges) {
99 uint32_t base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
100 while (
auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
101 if (base >= end || entry->base >= end)
103 if (entry->data.is_dwarf)
104 base = entry->GetRangeEnd();
107 if (base > entry->base) {
109 new_location_map.Append({end, entry_end - end, entry->data});
110 add_overlap_region(base, end < entry_end ? end : entry_end, entry);
111 entry->SetRangeEnd(base);
112 }
else if (base < entry->base) {
113 new_location_map.Append(
114 {base, entry->base - base, {offset, member_loc}});
115 if (entry_end == end)
116 entry->data.insert(offset, member_loc);
118 add_overlap_region(entry->base, end, entry);
119 entry->ShrinkFront(end - entry->base);
122 if (end < entry_end) {
123 new_location_map.Append({end, entry_end, entry->data});
124 entry->SetRangeEnd(end);
126 entry->data.insert(offset, member_loc);
134 new_location_map.Append({base, end - base, {offset, member_loc}});
136 for (
const auto &entry : new_location_map)
137 location_map.Append(entry);
138 if (!new_location_map.IsEmpty())
146 RangeMap new_location_map;
147 for (
const auto &range : ranges) {
150 uint32_t base_idx = location_map.FindEntryIndexThatContains(base);
151 uint32_t end_idx = location_map.FindEntryIndexThatContains(end - 1);
153 if (base_idx == end_idx && base_idx !=
UINT32_MAX) {
154 auto *entry = location_map.GetMutableEntryAtIndex(base_idx);
155 if (base > entry->base) {
156 new_location_map.Append({entry->base, base - entry->base, entry->data});
157 entry->ShrinkFront(base - entry->base);
159 if (end == entry->GetRangeEnd())
162 entry->ShrinkFront(end - base);
163 new_location_map.Append({base, end - base, expr});
167 base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
168 if (
auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
169 if (entry->Contains(base) && entry->base != base) {
170 entry->SetRangeEnd(base);
174 end_idx = location_map.FindEntryIndexThatContainsOrFollows(end - 1);
175 if (
auto *entry = location_map.GetMutableEntryAtIndex(end_idx)) {
176 if (entry->Contains(end - 1)) {
177 if (entry->GetRangeEnd() == end)
180 entry->ShrinkFront(end - entry->base);
185 end_idx = location_map.GetSize();
187 location_map.Erase(base_idx, end_idx);
188 new_location_map.Append({base, end - base, expr});
191 for (
const auto &entry : new_location_map)
192 location_map.Append(entry);
198 assert(
IsTagRecord(type) &&
"type is not a tag record!");
199 switch (type.kind()) {
204 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr));
209 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur));
214 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er));
218 llvm_unreachable(
"Unreachable!");
223 : cvclass(std::move(c)),
224 m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {}
226 : cvunion(std::move(u)), m_kind(
Union) {}
233 return PDB_SymType::CompilandDetails;
235 return PDB_SymType::CompilandEnv;
238 return PDB_SymType::Thunk;
240 return PDB_SymType::CoffGroup;
242 return PDB_SymType::Export;
246 return PDB_SymType::Function;
248 return PDB_SymType::PublicSymbol;
250 return PDB_SymType::InlineSite;
254 case S_REGREL32_INDIR:
263 return PDB_SymType::Data;
265 return PDB_SymType::Block;
267 return PDB_SymType::Label;
269 return PDB_SymType::CallSite;
270 case S_HEAPALLOCSITE:
271 return PDB_SymType::HeapAllocationSite;
273 return PDB_SymType::Callee;
275 return PDB_SymType::Caller;
277 assert(
false &&
"Invalid symbol record kind!");
279 return PDB_SymType::None;
285 return PDB_SymType::ArrayType;
287 return PDB_SymType::FunctionSig;
289 return PDB_SymType::BaseClass;
291 return PDB_SymType::BaseInterface;
296 return PDB_SymType::UDT;
298 return PDB_SymType::PointerType;
300 return PDB_SymType::Enum;
302 return PDB_SymType::FunctionSig;
304 return PDB_SymType::BuiltinType;
306 assert(
false &&
"Invalid type record kind!");
308 return PDB_SymType::None;
312 switch (sym.kind()) {
318 case S_LPROC32_DPC_ID:
325 case S_HEAPALLOCSITE:
339 switch (sym.kind()) {
345 case S_LPROC32_DPC_ID:
357 RecordT record(
static_cast<SymbolRecordKind
>(sym.kind()));
358 cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
362template <
typename RecordT>
365 return {record.Segment, record.CodeOffset};
371 return {record.ThunkSection, record.ThunkOffset};
376 return {record.Segment, record.Offset};
382 return {record.Segment, record.Offset};
387 return {record.Segment, record.DataOffset};
393 return {record.Segment, record.DataOffset};
397 switch (sym.kind()) {
403 case S_LPROC32_DPC_ID:
404 return ::GetSegmentAndOffset<ProcSym>(sym);
406 return ::GetSegmentAndOffset<Thunk32Sym>(sym);
409 return ::GetSegmentAndOffset<TrampolineSym>(sym);
412 return ::GetSegmentAndOffset<CoffGroupSym>(sym);
415 return ::GetSegmentAndOffset<BlockSym>(sym);
418 return ::GetSegmentAndOffset<LabelSym>(sym);
421 return ::GetSegmentAndOffset<CallSiteInfoSym>(sym);
423 case S_HEAPALLOCSITE:
424 return ::GetSegmentAndOffset<HeapAllocationSiteSym>(sym);
430 return ::GetSegmentAndOffset<DataSym>(sym);
434 return ::GetSegmentAndOffset<ThreadLocalDataSym>(sym);
437 assert(
false &&
"Record does not have a segment/offset!");
442template <
typename RecordT>
445 return {record.Segment, record.CodeOffset, record.CodeSize};
452 return {record.ThunkSection, record.ThunkOffset, record.Size};
470 switch (sym.kind()) {
476 case S_LPROC32_DPC_ID:
477 return ::GetSegmentOffsetAndLength<ProcSym>(sym);
479 return ::GetSegmentOffsetAndLength<Thunk32Sym>(sym);
482 return ::GetSegmentOffsetAndLength<TrampolineSym>(sym);
485 return ::GetSegmentOffsetAndLength<CoffGroupSym>(sym);
488 return ::GetSegmentOffsetAndLength<BlockSym>(sym);
491 assert(
false &&
"Record does not have a segment/offset/length triple!");
500 switch (cvt.kind()) {
504 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
505 return cr.isForwardRef();
507 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
508 return ur.isForwardRef();
510 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
511 return er.isForwardRef();
518 switch (cvt.kind()) {
530 switch (cvt.kind()) {
542 if (
id.is_ipi ||
id.index.isSimple())
548 if (
id.is_ipi ||
id.index.isSimple())
556 case MemberAccess::Private:
558 case MemberAccess::Protected:
560 case MemberAccess::Public:
562 case MemberAccess::None:
565 llvm_unreachable(
"unreachable");
569 switch (cvt.kind()) {
574 cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
579 cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
584 cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
588 llvm_unreachable(
"Unreachable!");
593 if (modifier.kind() != LF_MODIFIER) {
594 assert(
false &&
"must be called on an LF_MODIFIER");
598 llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr));
599 return mr.ModifiedType;
609 if (sym.kind() == S_REGREL32) {
610 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
611 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
612 result.
type = reg.Type;
613 result.
name = reg.Name;
617 if (sym.kind() == S_REGREL32_INDIR) {
618 RegRelativeIndirSym reg(SymbolRecordKind::RegRelativeIndirSym);
619 cantFail(SymbolDeserializer::deserializeAs<RegRelativeIndirSym>(sym, reg));
620 result.
type = reg.Type;
621 result.
name = reg.Name;
625 if (sym.kind() == S_REGISTER) {
626 RegisterSym reg(SymbolRecordKind::RegisterSym);
627 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
628 result.
type = reg.Index;
629 result.
name = reg.Name;
633 if (sym.kind() == S_LOCAL) {
634 LocalSym local(SymbolRecordKind::LocalSym);
635 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
636 result.
type = local.Type;
637 result.
name = local.Name;
639 ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None);
643 if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) {
644 DataSym data(SymbolRecordKind::DataSym);
645 cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, data));
646 result.
type = data.Type;
647 result.
name = data.Name;
651 if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) {
652 ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym);
653 cantFail(SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, data));
654 result.
type = data.Type;
655 result.
name = data.Name;
659 if (sym.kind() == S_CONSTANT) {
660 ConstantSym constant(SymbolRecordKind::ConstantSym);
661 cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant));
662 result.
type = constant.Type;
663 result.
name = constant.Name;
667 assert(
false &&
"Invalid variable record kind!");
671static llvm::FixedStreamArray<FrameData>::Iterator
673 const DebugFrameDataSubsectionRef &fpo_data,
676 return fpo_data.end();
680 const RangeListEntry &range = ranges.
GetEntryRef(0);
682 auto it = fpo_data.begin();
685 for (; it != fpo_data.end(); ++it) {
686 RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
688 if (fd_range.Contains(range)) {
695 for (; it != fpo_data.end(); ++it) {
696 RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize);
698 if (!fd_range.Contains(range)) {
709 llvm::StringRef &out_program) {
710 const DebugFrameDataSubsectionRef &new_fpo_data =
711 index.
dbi().getNewFpoRecords();
715 if (frame_data_it == new_fpo_data.end())
718 auto strings = index.
pdb().getStringTable();
720 consumeError(strings.takeError());
723 out_program = cantFail(strings->getStringForID(frame_data_it->FrameFunc));
731 if (frame_proc_cvs.kind() != S_FRAMEPROC)
732 return RegisterId::NONE;
734 FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym);
735 cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs,
742 return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type)
743 : frame_proc.getLocalFramePtrReg(cpu_type);
754 if (sym.kind() == S_REGREL32) {
755 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
756 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
763 if (sym.kind() == S_REGREL32_INDIR) {
764 RegRelativeIndirSym reg(SymbolRecordKind::RegRelativeIndirSym);
765 cantFail(SymbolDeserializer::deserializeAs<RegRelativeIndirSym>(sym, reg));
769 reg.OffsetInUdt, module),
774 if (sym.kind() == S_REGISTER) {
775 RegisterSym reg(SymbolRecordKind::RegisterSym);
776 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
783 if (sym.kind() == S_LOCAL) {
784 LocalSym local(SymbolRecordKind::LocalSym);
785 if (llvm::Error
error =
786 SymbolDeserializer::deserializeAs<LocalSym>(sym, local)) {
787 llvm::consumeError(std::move(
error));
792 var_id.
offset + sym.RecordData.size());
793 CVSymbol loc_specifier_cvs;
795 RegisterId base_reg = RegisterId::NONE;
798 std::map<uint64_t, size_t> offset_to_size;
802 RangeMap location_map;
806 bool finished =
false;
809 switch (loc_specifier_cvs.kind()) {
810 case S_DEFRANGE_FRAMEPOINTER_REL: {
811 DefRangeFramePointerRelSym loc(
812 SymbolRecordKind::DefRangeFramePointerRelSym);
813 if (llvm::Error
error =
814 SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
815 loc_specifier_cvs, loc)) {
816 llvm::consumeError(std::move(
error));
821 if (base_reg == RegisterId::NONE) {
825 if (func_block_cvs.kind() != S_GPROC32 &&
826 func_block_cvs.kind() != S_LPROC32)
831 func_block_cvs.length());
834 if (base_reg == RegisterId::NONE)
838 if (base_reg == RegisterId::VFRAME) {
839 llvm::StringRef program;
848 AddDwarfRange(location_map, expr, raw_ranges);
851 case S_DEFRANGE_REGISTER: {
852 DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
853 if (llvm::Error
error =
854 SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
855 loc_specifier_cvs, loc)) {
856 llvm::consumeError(std::move(
error));
859 RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
864 AddDwarfRange(location_map, expr, raw_ranges);
867 case S_DEFRANGE_REGISTER_REL: {
868 DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
869 if (llvm::Error
error =
870 SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
871 loc_specifier_cvs, loc)) {
872 llvm::consumeError(std::move(
error));
877 RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
879 if (reg_id == RegisterId::VFRAME) {
880 llvm::StringRef program;
883 program, loc.Hdr.BasePointerOffset, module);
892 if (!loc.hasSpilledUDTMember())
893 AddDwarfRange(location_map, expr, raw_ranges);
896 case S_DEFRANGE_REGISTER_REL_INDIR: {
897 DefRangeRegisterRelIndirSym loc(
898 SymbolRecordKind::DefRangeRegisterRelIndirSym);
899 if (llvm::Error
error =
900 SymbolDeserializer::deserializeAs<DefRangeRegisterRelIndirSym>(
901 loc_specifier_cvs, loc)) {
902 llvm::consumeError(std::move(
error));
907 RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
909 if (reg_id == RegisterId::VFRAME) {
910 llvm::StringRef program;
913 program, loc.Hdr.BasePointerOffset, loc.Hdr.OffsetInUdt,
920 reg_id, loc.Hdr.BasePointerOffset, loc.Hdr.OffsetInUdt, module);
923 if (!loc.hasSpilledUDTMember())
924 AddDwarfRange(location_map, expr, raw_ranges);
927 case S_DEFRANGE_SUBFIELD_REGISTER: {
928 DefRangeSubfieldRegisterSym loc(
929 SymbolRecordKind::DefRangeSubfieldRegisterSym);
930 if (llvm::Error
error =
931 SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
932 loc_specifier_cvs, loc)) {
933 llvm::consumeError(std::move(
error));
942 offset_to_size[loc.Hdr.OffsetInParent] =
reg_size;
943 AddMemberLocationRanges(location_map, loc.Hdr.OffsetInParent,
944 {loc.Hdr.Register, 0, true}, ranges);
950 case S_DEFRANGE_SUBFIELD:
951 case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
958 loc_specifier_id.
modi,
959 loc_specifier_id.
offset + loc_specifier_cvs.RecordData.size());
961 for (
const auto &entry : location_map) {
963 entry.data.is_dwarf ? entry.data.expr
965 entry.data.offset_to_location,
966 offset_to_size, type_size, module);
973 llvm_unreachable(
"Symbol is not a local variable!");
980 case SimpleTypeKind::Boolean128:
981 case SimpleTypeKind::Boolean16:
982 case SimpleTypeKind::Boolean32:
983 case SimpleTypeKind::Boolean64:
984 case SimpleTypeKind::Boolean8:
986 case SimpleTypeKind::Byte:
987 case SimpleTypeKind::UnsignedCharacter:
989 case SimpleTypeKind::NarrowCharacter:
991 case SimpleTypeKind::SignedCharacter:
992 case SimpleTypeKind::SByte:
994 case SimpleTypeKind::Character16:
996 case SimpleTypeKind::Character32:
998 case SimpleTypeKind::Character8:
1000 case SimpleTypeKind::Complex80:
1002 case SimpleTypeKind::Complex64:
1004 case SimpleTypeKind::Complex32:
1005 case SimpleTypeKind::Complex32PartialPrecision:
1007 case SimpleTypeKind::Float80:
1009 case SimpleTypeKind::Float128:
1011 case SimpleTypeKind::Float64:
1013 case SimpleTypeKind::Float32:
1014 case SimpleTypeKind::Float32PartialPrecision:
1016 case SimpleTypeKind::Float16:
1018 case SimpleTypeKind::Int128:
1019 case SimpleTypeKind::Int128Oct:
1021 case SimpleTypeKind::Int64:
1022 case SimpleTypeKind::Int64Quad:
1024 case SimpleTypeKind::Int32:
1026 case SimpleTypeKind::Int16:
1027 case SimpleTypeKind::Int16Short:
1029 case SimpleTypeKind::UInt128:
1030 case SimpleTypeKind::UInt128Oct:
1032 case SimpleTypeKind::UInt64:
1033 case SimpleTypeKind::UInt64Quad:
1035 case SimpleTypeKind::HResult:
1036 case SimpleTypeKind::UInt32:
1038 case SimpleTypeKind::UInt16:
1039 case SimpleTypeKind::UInt16Short:
1041 case SimpleTypeKind::Int32Long:
1043 case SimpleTypeKind::UInt32Long:
1045 case SimpleTypeKind::Void:
1047 case SimpleTypeKind::WideCharacter:
1051 case SimpleTypeKind::Float48:
1052 case SimpleTypeKind::Complex16:
1053 case SimpleTypeKind::Complex48:
1054 case SimpleTypeKind::Complex128:
1055 case SimpleTypeKind::NotTranslated:
1056 case SimpleTypeKind::None:
1064 case SimpleTypeKind::Boolean128:
1065 case SimpleTypeKind::Complex128:
1066 case SimpleTypeKind::Int128:
1067 case SimpleTypeKind::Int128Oct:
1068 case SimpleTypeKind::UInt128:
1069 case SimpleTypeKind::UInt128Oct:
1070 case SimpleTypeKind::Float128:
1072 case SimpleTypeKind::Complex80:
1073 case SimpleTypeKind::Float80:
1075 case SimpleTypeKind::Boolean64:
1076 case SimpleTypeKind::Complex64:
1077 case SimpleTypeKind::UInt64:
1078 case SimpleTypeKind::UInt64Quad:
1079 case SimpleTypeKind::Float64:
1080 case SimpleTypeKind::Int64:
1081 case SimpleTypeKind::Int64Quad:
1083 case SimpleTypeKind::Complex48:
1084 case SimpleTypeKind::Float48:
1086 case SimpleTypeKind::Boolean32:
1087 case SimpleTypeKind::Character32:
1088 case SimpleTypeKind::Complex32:
1089 case SimpleTypeKind::Complex32PartialPrecision:
1090 case SimpleTypeKind::Float32:
1091 case SimpleTypeKind::Float32PartialPrecision:
1092 case SimpleTypeKind::Int32:
1093 case SimpleTypeKind::Int32Long:
1094 case SimpleTypeKind::UInt32Long:
1095 case SimpleTypeKind::HResult:
1096 case SimpleTypeKind::UInt32:
1098 case SimpleTypeKind::Boolean16:
1099 case SimpleTypeKind::Character16:
1100 case SimpleTypeKind::Complex16:
1101 case SimpleTypeKind::Float16:
1102 case SimpleTypeKind::Int16:
1103 case SimpleTypeKind::Int16Short:
1104 case SimpleTypeKind::UInt16:
1105 case SimpleTypeKind::UInt16Short:
1106 case SimpleTypeKind::WideCharacter:
1108 case SimpleTypeKind::Boolean8:
1109 case SimpleTypeKind::Byte:
1110 case SimpleTypeKind::UnsignedCharacter:
1111 case SimpleTypeKind::NarrowCharacter:
1112 case SimpleTypeKind::SignedCharacter:
1113 case SimpleTypeKind::SByte:
1114 case SimpleTypeKind::Character8:
1117 case SimpleTypeKind::Void:
1118 case SimpleTypeKind::None:
1119 case SimpleTypeKind::NotTranslated:
1127 if (
id.index.isSimple())
1130 CVType cvt = tpi.getType(
id.index);
1141 return llvm::cantFail(tpi.findFullDeclForForwardRef(
id.index));
1146 llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record));
1147 return record.getSize();
1151 llvm::pdb::TpiStream &tpi) {
1152 if (
id.index.isSimple()) {
1153 switch (
id.index.getSimpleMode()) {
1154 case SimpleTypeMode::Direct:
1156 case SimpleTypeMode::NearPointer32:
1157 case SimpleTypeMode::FarPointer32:
1159 case SimpleTypeMode::NearPointer64:
1161 case SimpleTypeMode::NearPointer128:
1169 TypeIndex index =
id.index;
1171 index = llvm::cantFail(tpi.findFullDeclForForwardRef(index));
1173 CVType cvt = tpi.getType(index);
1174 switch (cvt.kind()) {
1179 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record));
1193 BitFieldRecord record;
1194 llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, record));
1203std::optional<PdbTypeSymId>
1205 switch (symbol.kind()) {
1206 case SymbolKind::S_GPROC32:
1207 case SymbolKind::S_LPROC32:
1208 case SymbolKind::S_LPROC32_ID:
1209 case SymbolKind::S_GPROC32_ID: {
1210 ProcSym reg(SymbolRecordKind::ProcSym);
1211 llvm::Error err = SymbolDeserializer::deserializeAs<ProcSym>(symbol, reg);
1213 return std::nullopt;
1216 case SymbolKind::S_INLINESITE: {
1217 InlineSiteSym reg(SymbolRecordKind::InlineesSym);
1219 SymbolDeserializer::deserializeAs<InlineSiteSym>(symbol, reg);
1221 return std::nullopt;
1225 return std::nullopt;
static const size_t reg_size
static llvm::raw_ostream & error(Stream &strm)
SegmentOffsetLength GetSegmentOffsetAndLength< CoffGroupSym >(const CVSymbol &sym)
static llvm::FixedStreamArray< FrameData >::Iterator GetCorrespondingFrameData(lldb::addr_t load_addr, const DebugFrameDataSubsectionRef &fpo_data, const Variable::RangeList &ranges)
SegmentOffset GetSegmentAndOffset< TrampolineSym >(const CVSymbol &sym)
SegmentOffset GetSegmentAndOffset< CoffGroupSym >(const CVSymbol &sym)
SegmentOffset GetSegmentAndOffset< Thunk32Sym >(const CVSymbol &sym)
SegmentOffset GetSegmentAndOffset< DataSym >(const CVSymbol &sym)
static size_t GetSizeOfTypeInternal(CVType cvt)
SegmentOffsetLength GetSegmentOffsetAndLength< TrampolineSym >(const CVSymbol &sym)
RecordT createRecord(const CVSymbol &sym)
SegmentOffset GetSegmentAndOffset< ThreadLocalDataSym >(const CVSymbol &sym)
static bool GetFrameDataProgram(PdbIndex &index, const Variable::RangeList &ranges, llvm::StringRef &out_program)
SegmentOffsetLength GetSegmentOffsetAndLength< Thunk32Sym >(const CVSymbol &sym)
static Variable::RangeList MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, llvm::ArrayRef< LocalVariableAddrGap > gaps)
static RegisterId GetBaseFrameRegister(PdbIndex &index, PdbCompilandSymId frame_proc_id, bool is_parameter)
static llvm::StringRef DropScope(llvm::StringRef name)
A class that describes a single lexical block.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr)
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
bool IsValid() const
Return true if the location expression contains data.
Entry & GetEntryRef(size_t i)
void Append(const Entry &entry)
Range< lldb::addr_t, lldb::addr_t > Entry
RangeVector< lldb::addr_t, lldb::addr_t > RangeList
const CompilandIndexItem * GetCompiland(uint16_t modi) const
PdbIndex - Lazy access to the important parts of a PDB file.
CompileUnitIndex & compilands()
llvm::pdb::DbiStream & dbi()
llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const
lldb::addr_t GetLoadAddress() const
llvm::pdb::PDBFile & pdb()
lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const
llvm::pdb::TpiStream & tpi()
PdbCompilandSymId asCompilandSym() const
#define LLDB_INVALID_ADDRESS
bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym)
DWARFExpression MakeRegRelIndirLocationExpression(llvm::codeview::RegisterId reg, int32_t offset, int32_t offset_in_udt, lldb::ModuleSP module)
std::optional< PdbTypeSymId > GetFunctionType(llvm::codeview::CVSymbol symbol)
llvm::StringRef DropNameScope(llvm::StringRef name)
DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module)
llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind)
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
DWARFExpression MakeVFrameRelLocationExpression(llvm::StringRef fpo_program, int32_t offset, lldb::ModuleSP module)
SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym)
lldb::BasicType GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind)
VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol)
SegmentOffsetLength GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym)
bool IsTagRecord(llvm::codeview::CVType cvt)
llvm::codeview::TypeIndex LookThroughModifierRecord(llvm::codeview::CVType modifier)
DWARFExpression MakeVFrameRelIndirLocationExpression(llvm::StringRef fpo_program, int32_t offset, int32_t offset_in_udt, lldb::ModuleSP module)
DWARFExpression MakeEnregisteredLocationExpressionForComposite(const std::map< uint64_t, MemberValLocation > &offset_to_location, std::map< uint64_t, size_t > &offset_to_size, size_t total_size, lldb::ModuleSP module)
VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block &func_block, lldb::ModuleSP module)
bool IsForwardRefUdt(llvm::codeview::CVType cvt)
lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access)
llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt)
DWARFExpression MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg, lldb::ModuleSP module)
llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind)
size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi)
uint32_t GetRegisterSize(llvm::codeview::RegisterId register_id)
PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi)
bool IsClassStructUnion(llvm::codeview::CVType cvt)
bool SymbolIsCode(const llvm::codeview::CVSymbol &sym)
A class that represents a running process on the host machine.
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
@ eBasicTypeUnsignedShort
@ eBasicTypeUnsignedInt128
@ eBasicTypeLongDoubleComplex
@ eBasicTypeUnsignedLongLong
@ eBasicTypeDoubleComplex
std::shared_ptr< lldb_private::Module > ModuleSP
lldb::user_id_t GetID() const
Get accessor for the user ID.
static CVTagRecord create(llvm::codeview::CVType type)
CVTagRecord(llvm::codeview::ClassRecord &&c)
std::optional< llvm::codeview::Compile3Sym > m_compile_opts
DWARFExpressionList location
llvm::codeview::TypeIndex type