39#define DEBUG_TYPE "CodeViewUtilities"
80 auto GetName = [&](
auto Record) {
89 if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)
91 else if (RK == TypeRecordKind::Union)
93 else if (RK == TypeRecordKind::Enum)
103#define DEBUG_TYPE "CodeViewDataVisitor"
117 using RecordEntry = std::pair<TypeLeafKind, LVElement *>;
118 using RecordTable = std::map<TypeIndex, RecordEntry>;
119 RecordTable RecordFromTypes;
120 RecordTable RecordFromIds;
122 using NameTable = std::map<StringRef, TypeIndex>;
123 NameTable NameFromTypes;
124 NameTable NameFromIds;
127 LVTypeRecords(
LVShared *Shared) : Shared(Shared) {}
136class LVForwardReferences {
138 using ForwardEntry = std::pair<TypeIndex, TypeIndex>;
139 using ForwardTypeNames = std::map<StringRef, ForwardEntry>;
140 ForwardTypeNames ForwardTypesNames;
143 using ForwardType = std::map<TypeIndex, TypeIndex>;
144 ForwardType ForwardTypes;
148 ForwardTypes.emplace(TIForward, TIReference);
156 It->second.first = TIForward;
157 add(TIForward, It->second.second);
167 It->second.second = TIReference;
168 add(It->second.first, TIReference);
173 LVForwardReferences() =
default;
179 (IsForwardRef) ? add(
Name, TI) : update(
Name, TI);
183 auto It = ForwardTypes.find(TIForward);
188 auto It = ForwardTypesNames.find(
Name);
189 return It != ForwardTypesNames.end() ? It->second.second
202class LVNamespaceDeduction {
205 using Names = std::map<StringRef, LVScope *>;
206 Names NamespaceNames;
208 using LookupSet = std::set<StringRef>;
209 LookupSet DeducedScopes;
210 LookupSet UnresolvedScopes;
211 LookupSet IdentifiedNamespaces;
214 if (NamespaceNames.find(
Name) == NamespaceNames.end())
215 NamespaceNames.emplace(
Name, Namespace);
219 LVNamespaceDeduction(
LVShared *Shared) : Shared(Shared) {}
228 auto It = NamespaceNames.find(
Name);
229 LVScope *Namespace = It != NamespaceNames.end() ? It->second :
nullptr;
237 if (Components.empty())
240 LVStringRefs::size_type FirstNamespace = 0;
241 LVStringRefs::size_type FirstNonNamespace;
242 for (LVStringRefs::size_type Index = 0; Index < Components.size();
244 FirstNonNamespace = Index;
245 LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);
246 if (Iter == IdentifiedNamespaces.end())
250 return std::make_tuple(FirstNamespace, FirstNonNamespace);
255class LVStringRecords {
256 using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;
257 using StringIds = std::map<TypeIndex, StringEntry>;
261 LVStringRecords() =
default;
265 auto [It,
Inserted] = Strings.try_emplace(TI);
267 It->second = std::make_tuple(++Index, std::string(
String),
nullptr);
271 StringIds::iterator Iter = Strings.
find(TI);
272 return Iter != Strings.end() ? std::get<1>(Iter->second) :
StringRef{};
276 StringIds::iterator Iter = Strings.find(TI);
277 return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;
320 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
321 Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),
322 std::forward_as_tuple(
Kind, Element));
325void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, StringRef
Name) {
326 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
330LVElement *LVTypeRecords::find(uint32_t StreamIdx, TypeIndex TI,
bool Create) {
332 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
334 LVElement *Element =
nullptr;
335 RecordTable::iterator Iter =
Target.find(TI);
336 if (Iter !=
Target.end()) {
337 Element = Iter->second.second;
338 if (Element || !Create)
345 Element->setOffsetFromTypeIndex();
346 Target[TI].second = Element;
352TypeIndex LVTypeRecords::find(uint32_t StreamIdx, StringRef
Name) {
353 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
358void LVStringRecords::addFilenames() {
359 for (StringIds::const_reference Entry : Strings) {
360 StringRef
Name = std::get<1>(
Entry.second);
361 LVScopeCompileUnit *
Scope = std::get<2>(
Entry.second);
367void LVStringRecords::addFilenames(LVScopeCompileUnit *Scope) {
368 for (StringIds::reference Entry : Strings)
369 if (!std::get<2>(
Entry.second))
373void LVNamespaceDeduction::add(StringRef
String) {
374 StringRef InnerComponent;
375 StringRef OuterComponent;
377 DeducedScopes.insert(InnerComponent);
378 if (OuterComponent.
size())
379 UnresolvedScopes.insert(OuterComponent);
382void LVNamespaceDeduction::init() {
389 for (
const StringRef &Unresolved : UnresolvedScopes) {
391 for (
const StringRef &Component : Components) {
392 LookupSet::iterator Iter = DeducedScopes.find(Component);
393 if (Iter == DeducedScopes.end())
394 IdentifiedNamespaces.insert(Component);
399 auto Print = [&](LookupSet &Container,
const char *Title) {
400 auto Header = [&]() {
406 for (
const StringRef &Item : Container)
410 Print(DeducedScopes,
"Deducted Scopes");
411 Print(UnresolvedScopes,
"Unresolved Scopes");
412 Print(IdentifiedNamespaces,
"Namespaces");
416LVScope *LVNamespaceDeduction::get(
LVStringRefs Components) {
418 for (
const StringRef &Component : Components)
422 if (Components.empty())
428 for (
const StringRef &Component : Components) {
435 Namespace->setTag(dwarf::DW_TAG_namespace);
439 add(Component, Namespace);
446LVScope *LVNamespaceDeduction::get(StringRef ScopedName,
bool CheckScope) {
450 LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);
451 return Iter == IdentifiedNamespaces.end();
456 return get(Components);
460#define DEBUG_TYPE "CodeViewTypeVisitor"
465void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
466 uint32_t StreamIdx)
const {
481 if (
options().getInternalTag())
482 Shared->TypeKinds.insert(
Record.kind());
486 CurrentTypeIndex = TI;
487 Shared->TypeRecords.add(StreamIdx, TI,
Record.kind());
499 W.getOStream() <<
" {\n";
508 W.startLine() <<
"}\n";
522 W.printNumber(
"NumArgs",
static_cast<uint32_t>(Args.getArgs().size()));
536 String = Ids.getTypeName(TI);
538 Shared->StringRecords.add(TI,
String);
542 String = Ids.getTypeName(TI);
544 Shared->StringRecords.add(TI,
String);
545 LogicalVisitor->setCompileUnitName(std::string(
String));
555 W.printString(
"Name",
Class.getName());
559 Shared->NamespaceDeduction.add(
Class.getName());
560 Shared->ForwardReferences.record(
Class.isForwardRef(),
Class.getName(),
564 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Class.getName());
573 W.printString(
"Name",
Enum.getName());
577 Shared->NamespaceDeduction.add(
Enum.getName());
587 W.printString(
"Name", Func.getName());
591 Shared->NamespaceDeduction.add(Func.getName());
605 Shared->TypeRecords.add(
StreamTPI, CurrentTypeIndex, {});
614 W.printString(
"StringData",
String.getString());
626 W.printNumber(
"LineNumber",
Line.getLineNumber());
629 Shared->LineRecords.push_back(CurrentTypeIndex);
636 W.printNumber(
"MemberCount",
Union.getMemberCount());
638 W.printNumber(
"SizeOf",
Union.getSize());
639 W.printString(
"Name",
Union.getName());
640 if (
Union.hasUniqueName())
641 W.printString(
"UniqueName",
Union.getUniqueName());
645 Shared->NamespaceDeduction.add(
Union.getName());
646 Shared->ForwardReferences.record(
Union.isForwardRef(),
Union.getName(),
650 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Union.getName());
655#define DEBUG_TYPE "CodeViewSymbolVisitor"
664 Reader->printRelocatedField(
Label, CoffSection, RelocOffset,
Offset,
671 Reader->getLinkageName(CoffSection, RelocOffset,
Offset, RelocSym);
685 return Reader->CVStringTable;
688void LVSymbolVisitor::printLocalVariableAddrRange(
690 DictScope S(W,
"LocalVariableAddrRange");
692 ObjDelegate->printRelocatedField(
"OffsetStart", RelocationOffset,
694 W.printHex(
"ISectStart",
Range.ISectStart);
695 W.printHex(
"Range",
Range.Range);
698void LVSymbolVisitor::printLocalVariableAddrGap(
702 W.printHex(
"GapStartOffset", Gap.GapStartOffset);
703 W.printHex(
"Range", Gap.Range);
707void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI)
const {
718 W.printNumber(
"Offset",
Offset);
722 if (
options().getInternalTag())
723 Shared->SymbolKinds.insert(
Kind);
725 LogicalVisitor->CurrentElement = LogicalVisitor->createElement(
Kind);
726 if (!LogicalVisitor->CurrentElement) {
736 IsCompileUnit =
false;
737 if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())
738 LogicalVisitor->CurrentElement->setOffset(
Offset);
740 assert(LogicalVisitor->CurrentScope &&
"Invalid scope!");
741 LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);
743 if (LogicalVisitor->CurrentSymbol)
744 LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);
745 if (LogicalVisitor->CurrentType)
746 LogicalVisitor->addElement(LogicalVisitor->CurrentType);
758 LogicalVisitor->popScope();
772 W.printHex(
"CodeSize",
Block.CodeSize);
773 W.printHex(
"Segment",
Block.Segment);
774 W.printString(
"BlockName",
Block.Name);
777 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
780 ObjDelegate->getLinkageName(
Block.getRelocationOffset(),
Block.CodeOffset,
784 if (
options().getGeneralCollectRanges()) {
788 Reader->linearAddress(
Block.Segment,
Block.CodeOffset, Addendum);
790 Scope->addObject(LowPC, HighPC);
802 W.printNumber(
"Offset",
Local.Offset);
803 W.printString(
"VarName",
Local.Name);
806 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
807 Symbol->setName(
Local.Name);
815 Symbol->resetIsVariable();
817 if (
Local.Name ==
"this") {
818 Symbol->setIsParameter();
819 Symbol->setIsArtificial();
822 bool(
Local.Offset > 0) ? Symbol->setIsParameter()
823 : Symbol->setIsVariable();
827 if (Symbol->getIsParameter())
828 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
830 setLocalVariableType(Symbol,
Local.Type);
841 W.printNumber(
"Offset",
Local.Offset);
842 W.printString(
"VarName",
Local.Name);
845 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
846 Symbol->setName(
Local.Name);
849 Symbol->resetIsVariable();
852 if (
Local.Name ==
"this") {
853 Symbol->setIsArtificial();
854 Symbol->setIsParameter();
857 determineSymbolKind(Symbol,
Local.Register);
861 if (Symbol->getIsParameter())
862 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
864 setLocalVariableType(Symbol,
Local.Type);
875 W.printNumber(
"Offset",
Local.Offset);
876 W.printNumber(
"OffsetInUdt",
Local.OffsetInUdt);
877 W.printString(
"VarName",
Local.Name);
880 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
881 Symbol->setName(
Local.Name);
884 Symbol->resetIsVariable();
887 if (
Local.Name ==
"this") {
888 Symbol->setIsArtificial();
889 Symbol->setIsParameter();
892 determineSymbolKind(Symbol,
Local.Register);
896 if (Symbol->getIsParameter())
897 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
899 setLocalVariableType(Symbol,
Local.Type);
911 if (
Error Err = LogicalVisitor->finishVisitation(
912 CVBuildType, BuildInfo.
BuildId, Reader->getCompileUnit()))
927 W.printString(
"VersionName", Compile2.
Version);
942 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
944 Reader->setCompileUnitCPUType(Compile2.
Machine);
945 Scope->setName(CurrentObjectName);
946 if (
options().getAttributeProducer())
947 Scope->setProducer(Compile2.
Version);
948 if (
options().getAttributeLanguage())
955 Reader->addModule(Scope);
958 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
962 CurrentObjectName =
"";
975 W.printString(
"VersionName", Compile3.
Version);
990 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
992 Reader->setCompileUnitCPUType(Compile3.
Machine);
993 Scope->setName(CurrentObjectName);
994 if (
options().getAttributeProducer())
995 Scope->setProducer(Compile3.
Version);
996 if (
options().getAttributeLanguage())
1003 Reader->addModule(Scope);
1006 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
1010 CurrentObjectName =
"";
1020 W.printString(
"Name",
Constant.Name);
1023 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1026 Symbol->resetIncludeInPrint();
1039 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1041 W.printNumber(
"Offset", DefRangeFramePointerRelFullScope.
Offset);
1044 if (
LVSymbol *Symbol = LocalSymbol) {
1045 Symbol->setHasCodeViewLocation();
1046 LocalSymbol =
nullptr;
1052 uint64_t Operand1 = DefRangeFramePointerRelFullScope.
Offset;
1053 Symbol->addLocation(Attr, 0, 0, 0, 0);
1054 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1066 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1068 W.printNumber(
"Offset", DefRangeFramePointerRel.
Hdr.
Offset);
1069 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
1071 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
1078 if (
LVSymbol *Symbol = LocalSymbol) {
1079 Symbol->setHasCodeViewLocation();
1080 LocalSymbol =
nullptr;
1085 uint64_t Operand1 = DefRangeFramePointerRel.
Hdr.
Offset;
1089 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1092 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1104 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1106 W.printBoolean(
"HasSpilledUDTMember",
1108 W.printNumber(
"OffsetInParent", DefRangeRegisterRel.
offsetInParent());
1109 W.printNumber(
"BasePointerOffset",
1111 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
1113 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
1116 if (
LVSymbol *Symbol = LocalSymbol) {
1117 Symbol->setHasCodeViewLocation();
1118 LocalSymbol =
nullptr;
1123 uint64_t Operand1 = DefRangeRegisterRel.
Hdr.
Register;
1128 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1131 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2});
1143 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1145 W.printBoolean(
"HasSpilledUDTMember",
1147 W.printNumber(
"OffsetInParent", DefRangeRegisterRelIndir.
offsetInParent());
1148 W.printNumber(
"BasePointerOffset",
1150 W.printNumber(
"OffsetInUdt", DefRangeRegisterRelIndir.
Hdr.
OffsetInUdt);
1151 printLocalVariableAddrRange(DefRangeRegisterRelIndir.
Range,
1153 printLocalVariableAddrGap(DefRangeRegisterRelIndir.
Gaps);
1156 if (
LVSymbol *Symbol = LocalSymbol) {
1157 Symbol->setHasCodeViewLocation();
1158 LocalSymbol =
nullptr;
1163 const uint64_t Operand1 = DefRangeRegisterRelIndir.
Hdr.
Register;
1165 const uint64_t Operand3 = DefRangeRegisterRelIndir.
Hdr.
OffsetInUdt;
1169 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1172 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2, Operand3});
1184 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1186 W.printEnum(
"Register", uint16_t(DefRangeRegister.
Hdr.
Register),
1189 printLocalVariableAddrRange(DefRangeRegister.
Range,
1191 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1194 if (
LVSymbol *Symbol = LocalSymbol) {
1195 Symbol->setHasCodeViewLocation();
1196 LocalSymbol =
nullptr;
1200 uint64_t Operand1 = DefRangeRegister.
Hdr.
Register;
1204 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1207 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1219 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1221 W.printEnum(
"Register", uint16_t(DefRangeSubfieldRegister.
Hdr.
Register),
1223 W.printNumber(
"MayHaveNoName", DefRangeSubfieldRegister.
Hdr.
MayHaveNoName);
1224 W.printNumber(
"OffsetInParent",
1226 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1228 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1231 if (
LVSymbol *Symbol = LocalSymbol) {
1232 Symbol->setHasCodeViewLocation();
1233 LocalSymbol =
nullptr;
1238 uint64_t Operand1 = DefRangeSubfieldRegister.
Hdr.
Register;
1242 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1245 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1257 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1262 if (!ExpectedProgram) {
1265 "String table offset outside of bounds of String Table!");
1267 W.printString(
"Program", *ExpectedProgram);
1269 W.printNumber(
"OffsetInParent", DefRangeSubfield.
OffsetInParent);
1270 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1272 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
1275 if (
LVSymbol *Symbol = LocalSymbol) {
1276 Symbol->setHasCodeViewLocation();
1277 LocalSymbol =
nullptr;
1281 uint64_t Operand1 = DefRangeSubfield.
Program;
1285 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1288 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1300 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1305 if (!ExpectedProgram) {
1308 "String table offset outside of bounds of String Table!");
1310 W.printString(
"Program", *ExpectedProgram);
1313 printLocalVariableAddrGap(DefRange.
Gaps);
1316 if (
LVSymbol *Symbol = LocalSymbol) {
1317 Symbol->setHasCodeViewLocation();
1318 LocalSymbol =
nullptr;
1322 uint64_t Operand1 = DefRange.
Program;
1326 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1329 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1372 W.printString(
"DisplayName",
Data.Name);
1375 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1378 ObjDelegate->getLinkageName(
Data.getRelocationOffset(),
Data.DataOffset,
1381 Symbol->setName(
Data.Name);
1390 if (
getReader().isSystemEntry(Symbol) && !
options().getAttributeSystem()) {
1391 Symbol->resetIncludeInPrint();
1395 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Data.Name)) {
1398 if (Symbol->getParentScope()->removeElement(Symbol))
1399 Namespace->addElement(Symbol);
1402 Symbol->setType(LogicalVisitor->getElement(
StreamTPI,
Data.Type));
1403 if (
Record.kind() == SymbolKind::S_GDATA32)
1404 Symbol->setIsExternal();
1415 if (
LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1416 LVScope *AbstractFunction = Reader->createScopeFunction();
1417 AbstractFunction->setIsSubprogram();
1418 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1420 AbstractFunction->setIsInlinedAbstract();
1423 LogicalVisitor->startProcessArgumentList();
1426 if (
Error Err = LogicalVisitor->finishVisitation(
1427 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1429 LogicalVisitor->stopProcessArgumentList();
1434 InlinedFunction->setName(
Name);
1435 InlinedFunction->setLinkageName(
Name);
1438 if (
Error Err = LogicalVisitor->inlineSiteAnnotation(
1439 AbstractFunction, InlinedFunction,
InlineSite))
1451 W.printString(
"VarName",
Local.Name);
1454 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1455 Symbol->setName(
Local.Name);
1458 Symbol->resetIsVariable();
1462 Local.Name ==
"this") {
1463 Symbol->setIsArtificial();
1464 Symbol->setIsParameter();
1467 : Symbol->setIsVariable();
1471 if (Symbol->getIsParameter())
1472 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1474 setLocalVariableType(Symbol,
Local.Type);
1479 LocalSymbol = Symbol;
1488 W.printHex(
"Signature", ObjName.
Signature);
1489 W.printString(
"ObjectName", ObjName.
Name);
1492 CurrentObjectName = ObjName.
Name;
1498 if (InFunctionScope)
1502 InFunctionScope =
true;
1506 W.printHex(
"Segment", Proc.
Segment);
1507 W.printFlags(
"Flags",
static_cast<uint8_t>(Proc.
Flags),
1509 W.printString(
"DisplayName", Proc.
Name);
1558 if (
options().getGeneralCollectRanges()) {
1564 Function->addObject(LowPC, HighPC);
1567 if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1569 Reader->getCompileUnit()->addPublicName(
Function, LowPC, HighPC);
1590 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
1592 std::optional<CVType> CVFunctionType;
1593 auto GetRecordType = [&]() ->
bool {
1594 CVFunctionType = Ids.tryGetType(TIFunctionType);
1595 if (!CVFunctionType)
1600 if (CVFunctionType->kind() == LF_FUNC_ID)
1604 return (CVFunctionType->kind() == LF_MFUNC_ID);
1608 if (!GetRecordType()) {
1609 CVFunctionType = Types.tryGetType(TIFunctionType);
1610 if (!CVFunctionType)
1614 if (
Error Err = LogicalVisitor->finishVisitation(
1615 *CVFunctionType, TIFunctionType,
Function))
1619 if (
Record.kind() == SymbolKind::S_GPROC32 ||
1620 Record.kind() == SymbolKind::S_GPROC32_ID)
1626 if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1631 if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1643 InFunctionScope =
false;
1649 if (InFunctionScope)
1653 InFunctionScope =
true;
1656 W.printHex(
"Segment",
Thunk.Segment);
1657 W.printString(
"Name",
Thunk.Name);
1670 W.printString(
"UDTName",
UDT.Name);
1673 if (
LVType *
Type = LogicalVisitor->CurrentType) {
1674 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
UDT.Name)) {
1675 if (
Type->getParentScope()->removeElement(
Type))
1676 Namespace->addElement(
Type);
1689 Type->resetIncludeInPrint();
1692 if (
UDT.Name == RecordName)
1693 Type->resetIncludeInPrint();
1712 W.printHex(
"BaseOffset",
JumpTable.BaseOffset);
1713 W.printNumber(
"BaseSegment",
JumpTable.BaseSegment);
1714 W.printFlags(
"SwitchType",
static_cast<uint16_t
>(
JumpTable.SwitchType),
1716 W.printHex(
"BranchOffset",
JumpTable.BranchOffset);
1717 W.printHex(
"TableOffset",
JumpTable.TableOffset);
1718 W.printNumber(
"BranchSegment",
JumpTable.BranchSegment);
1719 W.printNumber(
"TableSegment",
JumpTable.TableSegment);
1720 W.printNumber(
"EntriesCount",
JumpTable.EntriesCount);
1729 switch (
Caller.getKind()) {
1730 case SymbolRecordKind::CallerSym:
1731 FieldName =
"Callee";
1733 case SymbolRecordKind::CalleeSym:
1734 FieldName =
"Caller";
1736 case SymbolRecordKind::InlineesSym:
1737 FieldName =
"Inlinee";
1741 "Unknown CV Record type for a CallerSym object!");
1743 for (
auto FuncID :
Caller.Indices) {
1752 if (Element && Element->getIsScoped()) {
1771#define DEBUG_TYPE "CodeViewLogicalVisitor"
1778 : Reader(Reader), W(W), Input(Input) {
1781 Shared = std::make_shared<LVShared>(Reader,
this);
1787 StreamIdx ==
StreamTPI ? types() : ids());
1792 W.getOStream() <<
"\n";
1795 W.getOStream() <<
" {\n";
1800 << Element->
getName() <<
"\n";
1805 W.startLine() <<
"}\n";
1811 W.getOStream() <<
"\n";
1814 W.getOStream() <<
" {\n";
1819 << Element->
getName() <<
"\n";
1824 W.startLine() <<
"}\n";
1842 W.printNumber(
"NumArgs",
Size);
1851 TypeIndex ParameterType = Indices[Index];
1865 W.printNumber(
"SizeOf", AT.
getSize());
1866 W.printString(
"Name", AT.
getName());
1870 if (Element->getIsFinalized())
1872 Element->setIsFinalized();
1878 Reader->getCompileUnit()->addElement(Array);
1881 LVType *PrevSubrange =
nullptr;
1889 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1914 while (CVEntry.
kind() == LF_ARRAY) {
1925 AddSubrangeType(AR);
1926 TIArrayType = TIElementType;
1932 CVType CVElementType =
Types.getType(TIElementType);
1933 if (CVElementType.
kind() == LF_MODIFIER) {
1935 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1948 CVEntry =
Types.getType(TIElementType);
1950 const_cast<CVType &
>(CVEntry), AR)) {
1960 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
2021 W.printNumber(
"MemberCount",
Class.getMemberCount());
2025 W.printNumber(
"SizeOf",
Class.getSize());
2026 W.printString(
"Name",
Class.getName());
2027 if (
Class.hasUniqueName())
2028 W.printString(
"UniqueName",
Class.getUniqueName());
2032 if (Element->getIsFinalized())
2034 Element->setIsFinalized();
2040 Scope->setName(
Class.getName());
2041 if (
Class.hasUniqueName())
2042 Scope->setLinkageName(
Class.getUniqueName());
2045 if (
Class.isNested()) {
2046 Scope->setIsNested();
2047 createParents(
Class.getName(), Scope);
2050 if (
Class.isScoped())
2051 Scope->setIsScoped();
2055 if (!(
Class.isNested() ||
Class.isScoped())) {
2056 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2057 Namespace->addElement(Scope);
2059 Reader->getCompileUnit()->addElement(Scope);
2065 TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2071 const_cast<CVType &
>(CVReference), ReferenceRecord))
2092 W.printNumber(
"NumEnumerators",
Enum.getMemberCount());
2095 W.printString(
"Name",
Enum.getName());
2103 if (Scope->getIsFinalized())
2105 Scope->setIsFinalized();
2109 Scope->setName(
Enum.getName());
2110 if (
Enum.hasUniqueName())
2111 Scope->setLinkageName(
Enum.getUniqueName());
2115 if (
Enum.isNested()) {
2116 Scope->setIsNested();
2117 createParents(
Enum.getName(), Scope);
2120 if (
Enum.isScoped()) {
2121 Scope->setIsScoped();
2122 Scope->setIsEnumClass();
2126 if (!(
Enum.isNested() ||
Enum.isScoped())) {
2127 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2128 Namespace->addElement(Scope);
2130 Reader->getCompileUnit()->addElement(Scope);
2153 if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2167 W.printString(
"Name", Func.getName());
2179 TypeIndex TIParent = Func.getParentScope();
2180 if (FunctionDcl->getIsInlinedAbstract()) {
2181 FunctionDcl->setName(Func.getName());
2183 Reader->getCompileUnit()->addElement(FunctionDcl);
2187 CVType CVParentScope = ids().getType(TIParent);
2192 TypeIndex TIFunctionType = Func.getFunctionType();
2193 CVType CVFunctionType =
Types.getType(TIFunctionType);
2198 FunctionDcl->setIsFinalized();
2222 W.printString(
"Name", Id.getName());
2227 if (FunctionDcl->getIsInlinedAbstract()) {
2233 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2234 Class->addElement(FunctionDcl);
2237 TypeIndex TIFunctionType = Id.getFunctionType();
2238 CVType CVFunction = types().getType(TIFunctionType);
2263 MemberFunction->setIsFinalized();
2265 MemberFunction->setOffset(TI.
getIndex());
2266 MemberFunction->setOffsetFromTypeIndex();
2268 if (ProcessArgumentList) {
2269 ProcessArgumentList =
false;
2271 if (!MemberFunction->getIsStatic()) {
2276 createParameter(ThisPointer,
StringRef(), MemberFunction);
2277 This->setIsArtificial();
2304 Method.Name = OverloadedMethodName;
2336 bool SeenModifier =
false;
2337 uint16_t Mods =
static_cast<uint16_t
>(
Mod.getModifiers());
2339 SeenModifier =
true;
2340 LastLink->
setTag(dwarf::DW_TAG_const_type);
2341 LastLink->setIsConst();
2352 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2353 LastLink->setIsVolatile();
2354 LastLink->
setName(
"volatile");
2365 LastLink->setIsUnaligned();
2366 LastLink->
setName(
"unaligned");
2369 LastLink->
setType(ModifiedType);
2379 W.printNumber(
"IsFlat", Ptr.
isFlat());
2380 W.printNumber(
"IsConst", Ptr.
isConst());
2381 W.printNumber(
"IsVolatile", Ptr.
isVolatile());
2383 W.printNumber(
"IsRestrict", Ptr.
isRestrict());
2386 W.printNumber(
"SizeOf", Ptr.
getSize());
2411 bool SeenModifier =
false;
2417 SeenModifier =
true;
2419 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2428 LVType *LReference = Reader->createType();
2429 LReference->setIsModifier();
2430 LastLink->
setType(LReference);
2431 LastLink = LReference;
2434 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2435 LastLink->setIsReference();
2440 LVType *RReference = Reader->createType();
2441 RReference->setIsModifier();
2442 LastLink->
setType(RReference);
2443 LastLink = RReference;
2446 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2447 LastLink->setIsRvalueReference();
2473 if (ProcessArgumentList) {
2474 ProcessArgumentList =
false;
2492 W.printNumber(
"MemberCount",
Union.getMemberCount());
2494 W.printNumber(
"SizeOf",
Union.getSize());
2495 W.printString(
"Name",
Union.getName());
2496 if (
Union.hasUniqueName())
2497 W.printString(
"UniqueName",
Union.getUniqueName());
2505 if (Scope->getIsFinalized())
2507 Scope->setIsFinalized();
2509 Scope->setName(
Union.getName());
2510 if (
Union.hasUniqueName())
2511 Scope->setLinkageName(
Union.getUniqueName());
2514 if (
Union.isNested()) {
2515 Scope->setIsNested();
2516 createParents(
Union.getName(), Scope);
2518 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2519 Namespace->addElement(Scope);
2521 Reader->getCompileUnit()->addElement(Scope);
2524 if (!
Union.getFieldList().isNoneType()) {
2541 W.printNumber(
"Age", TS.
getAge());
2542 W.printString(
"Name", TS.
getName());
2556 W.printString(
"VFTableName", VFT.
getName());
2558 W.printString(
"MethodName",
N);
2585 W.printNumber(
"NumStrings",
Size);
2601 W.printString(
"StringData",
String.getString());
2604 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2605 String.getString(),
false)) {
2609 Scope->removeElement(Element);
2610 Namespace->addElement(Element);
2641 W.printNumber(
"Module", ModSourceLine.
getModule());
2686 W.printHex(
"BaseOffset",
Base.getBaseOffset());
2695 Symbol->setAccessibilityCode(
Base.getAccess());
2709 W.printHex(
"FieldOffset",
Field.getFieldOffset());
2710 W.printString(
"Name",
Field.getName());
2726 W.printNumber(
"EnumValue",
Enum.getValue());
2727 W.printString(
"Name",
Enum.getName());
2735 Enum.getValue().toString(
Value, 16,
true,
true);
2762 W.printString(
"Name",
Nested.getName());
2773 if (NestedType && NestedType->getIsNested()) {
2779 if (NestedTypeName.
size() && RecordName.
size()) {
2781 std::tie(OuterComponent, std::ignore) =
2785 if (OuterComponent.
size() && OuterComponent == RecordName) {
2786 if (!NestedType->getIsScopedAlready()) {
2787 Scope->addElement(NestedType);
2788 NestedType->setIsScopedAlready();
2791 Typedef->resetIncludeInPrint();
2808 if (Method.isIntroducingVirtual())
2809 W.printHex(
"VFTableOffset", Method.getVFTableOffset());
2810 W.printString(
"Name", Method.getName());
2817 ProcessArgumentList =
true;
2819 MemberFunction->setIsFinalized();
2822 MemberFunction->
setName(Method.getName());
2823 MemberFunction->setAccessibilityCode(Method.getAccess());
2827 MemberFunction->setIsStatic();
2828 MemberFunction->setVirtualityCode(
Kind);
2833 MemberFunction->setIsArtificial();
2836 CVType CVMethodType =
Types.getType(Method.getType());
2841 ProcessArgumentList =
false;
2852 W.printHex(
"MethodCount", Method.getNumOverloads());
2854 W.printString(
"Name", Method.getName());
2861 OverloadedMethodName = Method.getName();
2862 CVType CVMethods =
Types.getType(Method.getMethodList());
2876 W.printString(
"Name",
Field.getName());
2906 W.printHex(
"VBPtrOffset",
Base.getVBPtrOffset());
2907 W.printHex(
"VBTableIndex",
Base.getVTableIndex());
2916 Symbol->setAccessibilityCode(
Base.getAccess());
2935#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2938 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2942#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2943 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2944#define TYPE_RECORD(EnumName, EnumVal, Name)
2945#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2946#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2962#define TYPE_RECORD(EnumName, EnumVal, Name) \
2964 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2968#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2969 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2970#define MEMBER_RECORD(EnumName, EnumVal, Name)
2971#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2972#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2979Error LVLogicalVisitor::visitFieldListMemberStream(
2988 while (!Reader.empty()) {
2989 if (
Error Err = Reader.readEnum(Leaf))
3007 if (!ScopeStack.empty())
3009 InCompileUnitScope =
true;
3013 ReaderParent->addElement(Scope);
3017 ReaderScope->addElement(Symbol);
3021 ReaderScope->addElement(
Type);
3033 if (
options().getAttributeBase())
3040 case TypeLeafKind::LF_ENUMERATE:
3044 case TypeLeafKind::LF_MODIFIER:
3048 case TypeLeafKind::LF_POINTER:
3056 case TypeLeafKind::LF_BCLASS:
3057 case TypeLeafKind::LF_IVBCLASS:
3058 case TypeLeafKind::LF_VBCLASS:
3063 case TypeLeafKind::LF_MEMBER:
3064 case TypeLeafKind::LF_STMEMBER:
3071 case TypeLeafKind::LF_ARRAY:
3075 case TypeLeafKind::LF_CLASS:
3080 case TypeLeafKind::LF_ENUM:
3084 case TypeLeafKind::LF_METHOD:
3085 case TypeLeafKind::LF_ONEMETHOD:
3086 case TypeLeafKind::LF_PROCEDURE:
3091 case TypeLeafKind::LF_STRUCTURE:
3096 case TypeLeafKind::LF_UNION:
3115 case SymbolKind::S_UDT:
3121 case SymbolKind::S_CONSTANT:
3127 case SymbolKind::S_BPREL32:
3128 case SymbolKind::S_REGREL32:
3129 case SymbolKind::S_REGREL32_INDIR:
3130 case SymbolKind::S_GDATA32:
3131 case SymbolKind::S_LDATA32:
3132 case SymbolKind::S_LOCAL:
3142 case SymbolKind::S_BLOCK32:
3147 case SymbolKind::S_COMPILE2:
3148 case SymbolKind::S_COMPILE3:
3153 case SymbolKind::S_INLINESITE:
3154 case SymbolKind::S_INLINESITE2:
3157 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3159 case SymbolKind::S_LPROC32:
3160 case SymbolKind::S_GPROC32:
3161 case SymbolKind::S_LPROC32_ID:
3162 case SymbolKind::S_GPROC32_ID:
3163 case SymbolKind::S_SEPCODE:
3164 case SymbolKind::S_THUNK32:
3184 Element->setIsFinalized();
3194 Element->setOffsetFromTypeIndex();
3198 W.printString(
"** Not implemented. **");
3205 Element->setOffsetFromTypeIndex();
3219 Symbol->setName(
Name);
3224 CVType CVMemberType = Types.getType(TI);
3225 if (CVMemberType.
kind() == LF_BITFIELD) {
3240 LVSymbol *
Parameter = Reader->createSymbol();
3243 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3254LVType *LVLogicalVisitor::createBaseType(
TypeIndex TI, StringRef TypeName) {
3256 TypeIndex TIR = (TypeIndex)SimpleKind;
3259 W.printString(
"TypeName", TypeName);
3262 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TIR))
3263 return static_cast<LVType *
>(Element);
3268 Reader->getCompileUnit()->addElement(
CurrentType);
3273LVType *LVLogicalVisitor::createPointerType(
TypeIndex TI, StringRef TypeName) {
3276 W.printString(
"TypeName", TypeName);
3279 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TI))
3280 return static_cast<LVType *
>(Element);
3282 LVType *Pointee = createBaseType(TI,
TypeName.drop_back(1));
3286 Reader->getCompileUnit()->addElement(
CurrentType);
3291void LVLogicalVisitor::createParents(StringRef ScopedName,
LVElement *Element) {
3311 if (Components.size() < 2)
3313 Components.pop_back();
3315 LVStringRefs::size_type FirstNamespace;
3316 LVStringRefs::size_type FirstAggregate;
3317 std::tie(FirstNamespace, FirstAggregate) =
3318 Shared->NamespaceDeduction.find(Components);
3321 W.printString(
"First Namespace", Components[FirstNamespace]);
3322 W.printString(
"First NonNamespace", Components[FirstAggregate]);
3326 if (FirstNamespace < FirstAggregate) {
3327 Shared->NamespaceDeduction.get(
3329 Components.begin() + FirstAggregate));
3335 LVScope *Aggregate =
nullptr;
3336 TypeIndex TIAggregate;
3338 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3341 for (LVStringRefs::size_type Index = FirstAggregate;
3344 Components.begin() + Index + 1),
3346 TIAggregate = Shared->ForwardReferences.remap(
3347 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3357 if (Aggregate && !Element->getIsScopedAlready()) {
3359 Element->setIsScopedAlready();
3366 TI = Shared->ForwardReferences.remap(TI);
3369 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3377 return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3378 : createBaseType(TI, TypeName);
3386 if (Element->getIsFinalized())
3400 Element->setIsFinalized();
3407 for (
const TypeIndex &Entry : Shared->LineRecords) {
3417 W.printNumber(
"LineNumber",
Line.getLineNumber());
3423 if (
LVElement *Element = Shared->TypeRecords.find(
3427 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3435 Shared->NamespaceDeduction.init();
3441 if (!
options().getInternalTag())
3446 auto NewLine = [&]() {
3459 Shared->TypeKinds.clear();
3462 OS <<
"\nSymbols:\n";
3465 Shared->SymbolKinds.clear();
3479 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3486 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3487 if (Iter != InlineeInfo.end()) {
3488 LineNumber = Iter->second.first;
3497 dbgs() <<
"inlineSiteAnnotation\n"
3498 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n"
3499 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n"
3500 <<
"Parent: " << Parent->
getName() <<
"\n"
3501 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3505 if (!
options().getPrintLines())
3512 int32_t LineOffset = LineNumber;
3516 auto UpdateCodeOffset = [&](
uint32_t Delta) {
3523 auto UpdateLineOffset = [&](int32_t Delta) {
3524 LineOffset += Delta;
3526 char Sign = Delta > 0 ?
'+' :
'-';
3527 dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3531 auto UpdateFileOffset = [&](int32_t
Offset) {
3537 auto CreateLine = [&]() {
3541 Line->setLineNumber(LineOffset);
3548 bool SeenLowAddress =
false;
3549 bool SeenHighAddress =
false;
3551 uint64_t HighPC = 0;
3553 for (
auto &Annot :
InlineSite.annotations()) {
3560 switch (Annot.OpCode) {
3564 UpdateCodeOffset(Annot.U1);
3569 SeenLowAddress =
true;
3574 SeenHighAddress =
true;
3578 UpdateCodeOffset(Annot.U2);
3583 UpdateCodeOffset(Annot.U1);
3584 UpdateLineOffset(Annot.S1);
3591 UpdateFileOffset(Annot.U1);
3597 if (SeenLowAddress && SeenHighAddress) {
3598 SeenLowAddress =
false;
3599 SeenHighAddress =
false;
3600 InlinedFunction->
addObject(LowPC, HighPC);
3604 Reader->addInlineeLines(InlinedFunction,
InlineeLines);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Lower Kernel Arguments
OptimizedStructLayoutField Field
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Provides read only access to a subclass of BinaryStream.
This is an important base class in LLVM.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringRef getName() const
void setName(const Init *Name)
virtual void printString(StringRef Value)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Value(Type *Ty, unsigned scid)
TypeIndex getElementType() const
TypeIndex getIndexType() const
StringRef getName() const
uint8_t getBitSize() const
TypeIndex getType() const
uint8_t getBitOffset() const
@ CurrentDirectory
Absolute CWD path.
@ SourceFile
Path to main source file, relative or absolute.
ArrayRef< TypeIndex > getArgs() const
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
uint8_t getLanguage() const
uint32_t getFlags() const
CompileSym3Flags getFlags() const
SourceLanguage getLanguage() const
Represents a read-only view of a CodeView string table.
LLVM_ABI Expected< StringRef > getString(uint32_t Offset) const
DefRangeFramePointerRelHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
S_DEFRANGE_REGISTER_REL_INDIR.
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
bool hasSpilledUDTMember() const
DefRangeRegisterRelIndirHeader Hdr
LocalVariableAddrRange Range
DefRangeRegisterRelHeader Hdr
bool hasSpilledUDTMember() const
uint32_t getRelocationOffset() const
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
DefRangeRegisterHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldRegisterHeader Hdr
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
LocalVariableAddrRange Range
uint32_t getSignature() const
RegisterId getLocalFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to local variables.
RegisterId getParamFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to parameters.
FrameProcedureOptions Flags
Provides amortized O(1) random access to a CodeView type stream.
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
TypeIndex getContinuationIndex() const
TypeIndex getReturnType() const
int32_t getThisPointerAdjustment() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
TypeIndex getThisType() const
TypeIndex getClassType() const
std::vector< OneMethodRecord > Methods
For method overload sets. LF_METHOD.
bool isRValueReferenceThisPtr() const
TypeIndex getReferentType() const
MemberPointerInfo getMemberInfo() const
bool isPointerToMember() const
bool isLValueReferenceThisPtr() const
PointerMode getMode() const
uint32_t getSignature() const
StringRef getPrecompFilePath() const
uint32_t getTypesCount() const
uint32_t getStartTypeIndex() const
uint32_t getRelocationOffset() const
TypeIndex getReturnType() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
ArrayRef< TypeIndex > getIndices() const
TypeIndex getFieldList() const
static Error deserializeAs(CVType &CVT, T &Record)
static TypeIndex fromArrayIndex(uint32_t Index)
SimpleTypeKind getSimpleKind() const
void setIndex(uint32_t I)
static const uint32_t FirstNonSimpleIndex
static LLVM_ABI StringRef simpleTypeName(TypeIndex TI)
uint32_t getIndex() const
StringRef getName() const
const GUID & getGuid() const
void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks)
virtual Error visitUnknownMember(CVMemberRecord &Record)
virtual Error visitMemberEnd(CVMemberRecord &Record)
virtual Error visitMemberBegin(CVMemberRecord &Record)
TypeIndex getSourceFile() const
uint16_t getModule() const
uint32_t getLineNumber() const
uint32_t getLineNumber() const
TypeIndex getSourceFile() const
TypeIndex getType() const
uint32_t getVFPtrOffset() const
TypeIndex getOverriddenVTable() const
ArrayRef< StringRef > getMethodNames() const
StringRef getName() const
TypeIndex getCompleteClass() const
uint32_t getEntryCount() const
Stores all information relating to a compile unit, be it in its original instance in the object file ...
static StringRef getSymbolKindName(SymbolKind Kind)
virtual void setCount(int64_t Value)
virtual void setBitSize(uint32_t Size)
LVScope * getFunctionParent() const
virtual void updateLevel(LVScope *Parent, bool Moved=false)
virtual int64_t getCount() const
void setInlineCode(uint32_t Code)
virtual void setReference(LVElement *Element)
void setName(StringRef ElementName) override
StringRef getName() const override
void setType(LVElement *Element=nullptr)
void setFilenameIndex(size_t Index)
LLVM_ABI Error visitKnownRecord(CVType &Record, ArgListRecord &Args, TypeIndex TI, LVElement *Element)
LLVM_ABI void printRecords(raw_ostream &OS) const
LLVM_ABI void printTypeEnd(CVType &Record)
LLVM_ABI Error visitMemberRecord(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks, TypeIndex TI, LVElement *Element)
LLVM_ABI Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base, TypeIndex TI, LVElement *Element)
LLVM_ABI void printMemberEnd(CVMemberRecord &Record)
LLVM_ABI Error inlineSiteAnnotation(LVScope *AbstractFunction, LVScope *InlinedFunction, InlineSiteSym &InlineSite)
LLVM_ABI LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W, llvm::pdb::InputFile &Input)
LLVM_ABI void printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx)
LLVM_ABI Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI)
void pushScope(LVScope *Scope)
LLVM_ABI Error visitUnknownType(CVType &Record, TypeIndex TI)
LLVM_ABI void processNamespaces()
LLVM_ABI void addElement(LVScope *Scope, bool IsCompileUnit)
LLVM_ABI void printTypeBegin(CVType &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
LLVM_ABI void processLines()
LLVM_ABI LVElement * getElement(uint32_t StreamIdx, TypeIndex TI, LVScope *Parent=nullptr)
LLVM_ABI void printMemberBegin(CVMemberRecord &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
LLVM_ABI Error finishVisitation(CVType &Record, TypeIndex TI, LVElement *Element)
LLVM_ABI LVElement * createElement(TypeLeafKind Kind)
LLVM_ABI void processFiles()
LVScope * getParentScope() const
void setOffset(LVOffset DieOffset)
LVOffset getOffset() const
void setLineNumber(uint32_t Number)
void setTag(dwarf::Tag Tag)
virtual bool isSystemEntry(LVElement *Element, StringRef Name={}) const
LVScopeCompileUnit * getCompileUnit() const
void addElement(LVElement *Element)
void addObject(LVLocation *Location)
const LVLocations * getRanges() const
void getLinkageName(uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
void printRelocatedField(StringRef Label, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
DebugStringTableSubsectionRef getStringTable() override
StringRef getFileNameForFileOffset(uint32_t FileOffset) override
Error visitSymbolEnd(CVSymbol &Record) override
Error visitKnownRecord(CVSymbol &Record, BlockSym &Block) override
Error visitSymbolBegin(CVSymbol &Record) override
Error visitUnknownSymbol(CVSymbol &Record) override
Action to take on unknown symbols. By default, they are ignored.
Error visitMemberEnd(CVMemberRecord &Record) override
Error visitUnknownMember(CVMemberRecord &Record) override
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Error visitMemberBegin(CVMemberRecord &Record) override
Error visitKnownRecord(CVType &Record, BuildInfoRecord &Args) override
Error visitUnknownType(CVType &Record) override
Action to take on unknown types. By default, they are ignored.
This class implements an extremely fast bulk output stream that can only output to a stream.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
@ ChangeCodeLengthAndCodeOffset
@ ChangeCodeOffsetAndLineOffset
PointerMode
Equivalent to CV_ptrmode_e.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
CVRecord< TypeLeafKind > CVType
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
LLVM_ABI EnumStrings< SourceLanguage, 1 > getSourceLanguageNames()
LLVM_ABI EnumStrings< unsigned, 1 > getCPUTypeNames()
LLVM_ABI EnumStrings< uint16_t, 1 > getJumpTableEntrySizeNames()
CVRecord< SymbolKind > CVSymbol
bool symbolEndsScope(SymbolKind Kind)
Return true if this ssymbol ends a scope.
LLVM_ABI EnumStrings< uint16_t, 1 > getLocalFlagNames()
MethodOptions
Equivalent to CV_fldattr_t bitfield.
LLVM_ABI EnumStrings< uint32_t, 1 > getCompileSym3FlagNames()
MemberAccess
Source-level access specifier. (CV_access_e)
bool symbolOpensScope(SymbolKind Kind)
Return true if this symbol opens a scope.
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
LLVM_ABI EnumStrings< SymbolKind, 1 > getSymbolTypeNames()
bool isAggregate(CVType CVT)
Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, LF_CLASS, LF_INTERFACE,...
LLVM_ABI EnumStrings< uint16_t, 1 > getRegisterNames(CPUType Cpu)
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
LLVM_ABI uint64_t getSizeInBytesForTypeRecord(CVType CVT)
Given an arbitrary codeview type, return the type's size in the case of aggregate (LF_STRUCTURE,...
LLVM_ABI EnumStrings< uint8_t, 1 > getProcSymFlagNames()
LLVM_ABI EnumStrings< TypeLeafKind, 1 > getTypeLeafNames()
LLVM_ABI uint64_t getSizeInBytesForTypeIndex(TypeIndex TI)
Given an arbitrary codeview type index, determine its size.
LLVM_ABI TypeIndex getModifiedType(const CVType &CVT)
Given a CVType which is assumed to be an LF_MODIFIER, return the TypeIndex of the type that the LF_MO...
SourceLanguage
These values correspond to the CV_CFL_LANG enumeration in the Microsoft Debug Interface Access SDK,...
LLVM_ABI void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types)
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
@ DW_INL_declared_inlined
constexpr Tag DW_TAG_unaligned
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
static TypeIndex getTrueType(TypeIndex &TI)
std::vector< TypeIndex > LVLineRecords
std::set< SymbolKind > LVSymbolKinds
static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI)
constexpr unsigned int DWARF_CHAR_BIT
LLVM_ABI LVStringRefs getAllLexicalComponents(StringRef Name)
std::vector< StringRef > LVStringRefs
LLVM_ABI std::string transformPath(StringRef Path)
LLVM_ABI LVLexicalComponent getInnerComponent(StringRef Name)
std::tuple< LVStringRefs::size_type, LVStringRefs::size_type > LVLexicalIndex
std::set< TypeLeafKind > LVTypeKinds
SmallVector< LVLine *, 8 > LVLines
LLVM_ABI std::string getScopedName(const LVStringRefs &Components, StringRef BaseName={})
SmallVector< LVLocation *, 8 > LVLocations
@ Parameter
An inlay hint that is for a parameter.
LLVM_ABI std::string formatTypeLeafKind(codeview::TypeLeafKind K)
Print(const T &, const DataFlowGraph &) -> Print< T >
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
std::tuple< uint64_t, uint32_t > InlineSite
LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
@ Mod
The access may modify the value stored in memory.
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void consumeError(Error Err)
Consume a Error without doing anything.
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)
LVLineRecords LineRecords
LVTypeRecords TypeRecords
LVCodeViewReader * Reader
LVLogicalVisitor * Visitor
LVNamespaceDeduction NamespaceDeduction
LVSymbolKinds SymbolKinds
LVStringRecords StringRecords
LVForwardReferences ForwardReferences
A source language supported by any of the debug info representations.