40#define DEBUG_TYPE "CodeViewUtilities"
74#define CV_TYPE(enum, val) {#enum, enum},
75#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
86 auto GetName = [&](
auto Record) {
95 if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)
97 else if (RK == TypeRecordKind::Union)
99 else if (RK == TypeRecordKind::Enum)
109#define DEBUG_TYPE "CodeViewDataVisitor"
123 using RecordEntry = std::pair<TypeLeafKind, LVElement *>;
124 using RecordTable = std::map<TypeIndex, RecordEntry>;
125 RecordTable RecordFromTypes;
126 RecordTable RecordFromIds;
128 using NameTable = std::map<StringRef, TypeIndex>;
129 NameTable NameFromTypes;
130 NameTable NameFromIds;
133 LVTypeRecords(
LVShared *Shared) : Shared(Shared) {}
142class LVForwardReferences {
144 using ForwardEntry = std::pair<TypeIndex, TypeIndex>;
145 using ForwardTypeNames = std::map<StringRef, ForwardEntry>;
146 ForwardTypeNames ForwardTypesNames;
149 using ForwardType = std::map<TypeIndex, TypeIndex>;
150 ForwardType ForwardTypes;
154 ForwardTypes.emplace(TIForward, TIReference);
162 It->second.first = TIForward;
163 add(TIForward, It->second.second);
173 It->second.second = TIReference;
174 add(It->second.first, TIReference);
179 LVForwardReferences() =
default;
185 (IsForwardRef) ? add(
Name, TI) : update(
Name, TI);
189 auto It = ForwardTypes.find(TIForward);
194 auto It = ForwardTypesNames.find(
Name);
195 return It != ForwardTypesNames.end() ? It->second.second
208class LVNamespaceDeduction {
211 using Names = std::map<StringRef, LVScope *>;
212 Names NamespaceNames;
214 using LookupSet = std::set<StringRef>;
215 LookupSet DeducedScopes;
216 LookupSet UnresolvedScopes;
217 LookupSet IdentifiedNamespaces;
220 if (NamespaceNames.find(
Name) == NamespaceNames.end())
221 NamespaceNames.emplace(
Name, Namespace);
225 LVNamespaceDeduction(
LVShared *Shared) : Shared(Shared) {}
234 auto It = NamespaceNames.find(
Name);
235 LVScope *Namespace = It != NamespaceNames.end() ? It->second :
nullptr;
243 if (Components.empty())
246 LVStringRefs::size_type FirstNamespace = 0;
247 LVStringRefs::size_type FirstNonNamespace;
248 for (LVStringRefs::size_type Index = 0; Index < Components.size();
250 FirstNonNamespace = Index;
251 LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);
252 if (Iter == IdentifiedNamespaces.end())
256 return std::make_tuple(FirstNamespace, FirstNonNamespace);
261class LVStringRecords {
262 using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;
263 using StringIds = std::map<TypeIndex, StringEntry>;
267 LVStringRecords() =
default;
271 auto [It,
Inserted] = Strings.try_emplace(TI);
273 It->second = std::make_tuple(++Index, std::string(
String),
nullptr);
277 StringIds::iterator Iter = Strings.
find(TI);
278 return Iter != Strings.end() ? std::get<1>(Iter->second) :
StringRef{};
282 StringIds::iterator Iter = Strings.find(TI);
283 return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;
326 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
327 Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),
328 std::forward_as_tuple(
Kind, Element));
331void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, StringRef
Name) {
332 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
336LVElement *LVTypeRecords::find(uint32_t StreamIdx, TypeIndex TI,
bool Create) {
338 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
340 LVElement *Element =
nullptr;
341 RecordTable::iterator Iter =
Target.find(TI);
342 if (Iter !=
Target.end()) {
343 Element = Iter->second.second;
344 if (Element || !Create)
351 Element->setOffsetFromTypeIndex();
352 Target[TI].second = Element;
358TypeIndex LVTypeRecords::find(uint32_t StreamIdx, StringRef
Name) {
359 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
364void LVStringRecords::addFilenames() {
365 for (StringIds::const_reference Entry : Strings) {
366 StringRef
Name = std::get<1>(
Entry.second);
367 LVScopeCompileUnit *
Scope = std::get<2>(
Entry.second);
373void LVStringRecords::addFilenames(LVScopeCompileUnit *Scope) {
374 for (StringIds::reference Entry : Strings)
375 if (!std::get<2>(
Entry.second))
379void LVNamespaceDeduction::add(StringRef
String) {
380 StringRef InnerComponent;
381 StringRef OuterComponent;
383 DeducedScopes.insert(InnerComponent);
384 if (OuterComponent.
size())
385 UnresolvedScopes.insert(OuterComponent);
388void LVNamespaceDeduction::init() {
395 for (
const StringRef &Unresolved : UnresolvedScopes) {
397 for (
const StringRef &Component : Components) {
398 LookupSet::iterator Iter = DeducedScopes.find(Component);
399 if (Iter == DeducedScopes.end())
400 IdentifiedNamespaces.insert(Component);
405 auto Print = [&](LookupSet &Container,
const char *Title) {
406 auto Header = [&]() {
412 for (
const StringRef &Item : Container)
416 Print(DeducedScopes,
"Deducted Scopes");
417 Print(UnresolvedScopes,
"Unresolved Scopes");
418 Print(IdentifiedNamespaces,
"Namespaces");
422LVScope *LVNamespaceDeduction::get(
LVStringRefs Components) {
424 for (
const StringRef &Component : Components)
428 if (Components.empty())
434 for (
const StringRef &Component : Components) {
441 Namespace->setTag(dwarf::DW_TAG_namespace);
445 add(Component, Namespace);
452LVScope *LVNamespaceDeduction::get(StringRef ScopedName,
bool CheckScope) {
456 LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);
457 return Iter == IdentifiedNamespaces.end();
461 {
dbgs() <<
formatv(
"ScopedName: '{0}'\n", ScopedName.
str().c_str()); });
463 return get(Components);
467#define DEBUG_TYPE "CodeViewTypeVisitor"
472void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
473 uint32_t StreamIdx)
const {
488 if (
options().getInternalTag())
489 Shared->TypeKinds.insert(
Record.kind());
493 CurrentTypeIndex = TI;
494 Shared->TypeRecords.add(StreamIdx, TI,
Record.kind());
506 W.getOStream() <<
" {\n";
515 W.startLine() <<
"}\n";
529 W.printNumber(
"NumArgs",
static_cast<uint32_t>(Args.getArgs().size()));
543 String = Ids.getTypeName(TI);
545 Shared->StringRecords.add(TI,
String);
549 String = Ids.getTypeName(TI);
551 Shared->StringRecords.add(TI,
String);
552 LogicalVisitor->setCompileUnitName(std::string(
String));
562 W.printString(
"Name",
Class.getName());
566 Shared->NamespaceDeduction.add(
Class.getName());
567 Shared->ForwardReferences.record(
Class.isForwardRef(),
Class.getName(),
571 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Class.getName());
580 W.printString(
"Name",
Enum.getName());
584 Shared->NamespaceDeduction.add(
Enum.getName());
594 W.printString(
"Name", Func.getName());
598 Shared->NamespaceDeduction.add(Func.getName());
612 Shared->TypeRecords.add(
StreamTPI, CurrentTypeIndex, {});
621 W.printString(
"StringData",
String.getString());
633 W.printNumber(
"LineNumber",
Line.getLineNumber());
636 Shared->LineRecords.push_back(CurrentTypeIndex);
643 W.printNumber(
"MemberCount",
Union.getMemberCount());
645 W.printNumber(
"SizeOf",
Union.getSize());
646 W.printString(
"Name",
Union.getName());
647 if (
Union.hasUniqueName())
648 W.printString(
"UniqueName",
Union.getUniqueName());
652 Shared->NamespaceDeduction.add(
Union.getName());
653 Shared->ForwardReferences.record(
Union.isForwardRef(),
Union.getName(),
657 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Union.getName());
662#define DEBUG_TYPE "CodeViewSymbolVisitor"
671 Reader->printRelocatedField(
Label, CoffSection, RelocOffset,
Offset,
678 Reader->getLinkageName(CoffSection, RelocOffset,
Offset, RelocSym);
692 return Reader->CVStringTable;
695void LVSymbolVisitor::printLocalVariableAddrRange(
697 DictScope S(W,
"LocalVariableAddrRange");
699 ObjDelegate->printRelocatedField(
"OffsetStart", RelocationOffset,
701 W.printHex(
"ISectStart",
Range.ISectStart);
702 W.printHex(
"Range",
Range.Range);
705void LVSymbolVisitor::printLocalVariableAddrGap(
709 W.printHex(
"GapStartOffset", Gap.GapStartOffset);
710 W.printHex(
"Range", Gap.Range);
714void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI)
const {
725 W.printNumber(
"Offset",
Offset);
729 if (
options().getInternalTag())
730 Shared->SymbolKinds.insert(
Kind);
732 LogicalVisitor->CurrentElement = LogicalVisitor->createElement(
Kind);
733 if (!LogicalVisitor->CurrentElement) {
743 IsCompileUnit =
false;
744 if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())
745 LogicalVisitor->CurrentElement->setOffset(
Offset);
747 assert(LogicalVisitor->CurrentScope &&
"Invalid scope!");
748 LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);
750 if (LogicalVisitor->CurrentSymbol)
751 LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);
752 if (LogicalVisitor->CurrentType)
753 LogicalVisitor->addElement(LogicalVisitor->CurrentType);
765 LogicalVisitor->popScope();
779 W.printHex(
"CodeSize",
Block.CodeSize);
780 W.printHex(
"Segment",
Block.Segment);
781 W.printString(
"BlockName",
Block.Name);
784 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
787 ObjDelegate->getLinkageName(
Block.getRelocationOffset(),
Block.CodeOffset,
791 if (
options().getGeneralCollectRanges()) {
795 Reader->linearAddress(
Block.Segment,
Block.CodeOffset, Addendum);
797 Scope->addObject(LowPC, HighPC);
809 W.printNumber(
"Offset",
Local.Offset);
810 W.printString(
"VarName",
Local.Name);
813 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
814 Symbol->setName(
Local.Name);
822 Symbol->resetIsVariable();
824 if (
Local.Name ==
"this") {
825 Symbol->setIsParameter();
826 Symbol->setIsArtificial();
829 bool(
Local.Offset > 0) ? Symbol->setIsParameter()
830 : Symbol->setIsVariable();
834 if (Symbol->getIsParameter())
835 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
837 setLocalVariableType(Symbol,
Local.Type);
848 W.printNumber(
"Offset",
Local.Offset);
849 W.printString(
"VarName",
Local.Name);
852 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
853 Symbol->setName(
Local.Name);
856 Symbol->resetIsVariable();
859 if (
Local.Name ==
"this") {
860 Symbol->setIsArtificial();
861 Symbol->setIsParameter();
864 determineSymbolKind(Symbol,
Local.Register);
868 if (Symbol->getIsParameter())
869 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
871 setLocalVariableType(Symbol,
Local.Type);
882 W.printNumber(
"Offset",
Local.Offset);
883 W.printNumber(
"OffsetInUdt",
Local.OffsetInUdt);
884 W.printString(
"VarName",
Local.Name);
887 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
888 Symbol->setName(
Local.Name);
891 Symbol->resetIsVariable();
894 if (
Local.Name ==
"this") {
895 Symbol->setIsArtificial();
896 Symbol->setIsParameter();
899 determineSymbolKind(Symbol,
Local.Register);
903 if (Symbol->getIsParameter())
904 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
906 setLocalVariableType(Symbol,
Local.Type);
918 if (
Error Err = LogicalVisitor->finishVisitation(
919 CVBuildType, BuildInfo.
BuildId, Reader->getCompileUnit()))
934 W.printString(
"VersionName", Compile2.
Version);
949 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
951 Reader->setCompileUnitCPUType(Compile2.
Machine);
952 Scope->setName(CurrentObjectName);
953 if (
options().getAttributeProducer())
954 Scope->setProducer(Compile2.
Version);
955 if (
options().getAttributeLanguage())
962 Reader->addModule(Scope);
965 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
969 CurrentObjectName =
"";
982 W.printString(
"VersionName", Compile3.
Version);
997 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
999 Reader->setCompileUnitCPUType(Compile3.
Machine);
1000 Scope->setName(CurrentObjectName);
1001 if (
options().getAttributeProducer())
1002 Scope->setProducer(Compile3.
Version);
1003 if (
options().getAttributeLanguage())
1010 Reader->addModule(Scope);
1013 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
1017 CurrentObjectName =
"";
1027 W.printString(
"Name",
Constant.Name);
1030 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1033 Symbol->resetIncludeInPrint();
1046 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1048 W.printNumber(
"Offset", DefRangeFramePointerRelFullScope.
Offset);
1051 if (
LVSymbol *Symbol = LocalSymbol) {
1052 Symbol->setHasCodeViewLocation();
1053 LocalSymbol =
nullptr;
1060 Symbol->addLocation(Attr, 0, 0, 0, 0);
1061 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1073 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1075 W.printNumber(
"Offset", DefRangeFramePointerRel.
Hdr.
Offset);
1076 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
1078 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
1085 if (
LVSymbol *Symbol = LocalSymbol) {
1086 Symbol->setHasCodeViewLocation();
1087 LocalSymbol =
nullptr;
1096 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1099 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1111 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1113 W.printBoolean(
"HasSpilledUDTMember",
1115 W.printNumber(
"OffsetInParent", DefRangeRegisterRel.
offsetInParent());
1116 W.printNumber(
"BasePointerOffset",
1118 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
1120 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
1123 if (
LVSymbol *Symbol = LocalSymbol) {
1124 Symbol->setHasCodeViewLocation();
1125 LocalSymbol =
nullptr;
1135 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1138 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2});
1150 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1155 printLocalVariableAddrRange(DefRangeRegister.
Range,
1157 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1160 if (
LVSymbol *Symbol = LocalSymbol) {
1161 Symbol->setHasCodeViewLocation();
1162 LocalSymbol =
nullptr;
1170 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1173 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1185 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1189 W.printNumber(
"MayHaveNoName", DefRangeSubfieldRegister.
Hdr.
MayHaveNoName);
1190 W.printNumber(
"OffsetInParent",
1192 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1194 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1197 if (
LVSymbol *Symbol = LocalSymbol) {
1198 Symbol->setHasCodeViewLocation();
1199 LocalSymbol =
nullptr;
1208 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1211 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1223 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1228 if (!ExpectedProgram) {
1231 "String table offset outside of bounds of String Table!");
1233 W.printString(
"Program", *ExpectedProgram);
1235 W.printNumber(
"OffsetInParent", DefRangeSubfield.
OffsetInParent);
1236 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1238 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
1241 if (
LVSymbol *Symbol = LocalSymbol) {
1242 Symbol->setHasCodeViewLocation();
1243 LocalSymbol =
nullptr;
1251 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1254 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1266 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1271 if (!ExpectedProgram) {
1274 "String table offset outside of bounds of String Table!");
1276 W.printString(
"Program", *ExpectedProgram);
1279 printLocalVariableAddrGap(DefRange.
Gaps);
1282 if (
LVSymbol *Symbol = LocalSymbol) {
1283 Symbol->setHasCodeViewLocation();
1284 LocalSymbol =
nullptr;
1292 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1295 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1338 W.printString(
"DisplayName",
Data.Name);
1341 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1344 ObjDelegate->getLinkageName(
Data.getRelocationOffset(),
Data.DataOffset,
1347 Symbol->setName(
Data.Name);
1356 if (
getReader().isSystemEntry(Symbol) && !
options().getAttributeSystem()) {
1357 Symbol->resetIncludeInPrint();
1361 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Data.Name)) {
1364 if (Symbol->getParentScope()->removeElement(Symbol))
1365 Namespace->addElement(Symbol);
1368 Symbol->setType(LogicalVisitor->getElement(
StreamTPI,
Data.Type));
1369 if (
Record.kind() == SymbolKind::S_GDATA32)
1370 Symbol->setIsExternal();
1381 if (
LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1382 LVScope *AbstractFunction = Reader->createScopeFunction();
1383 AbstractFunction->setIsSubprogram();
1384 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1386 AbstractFunction->setIsInlinedAbstract();
1389 LogicalVisitor->startProcessArgumentList();
1392 if (
Error Err = LogicalVisitor->finishVisitation(
1393 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1395 LogicalVisitor->stopProcessArgumentList();
1400 InlinedFunction->setName(
Name);
1401 InlinedFunction->setLinkageName(
Name);
1404 if (
Error Err = LogicalVisitor->inlineSiteAnnotation(
1405 AbstractFunction, InlinedFunction,
InlineSite))
1417 W.printString(
"VarName",
Local.Name);
1420 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1421 Symbol->setName(
Local.Name);
1424 Symbol->resetIsVariable();
1428 Local.Name ==
"this") {
1429 Symbol->setIsArtificial();
1430 Symbol->setIsParameter();
1433 : Symbol->setIsVariable();
1437 if (Symbol->getIsParameter())
1438 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1440 setLocalVariableType(Symbol,
Local.Type);
1445 LocalSymbol = Symbol;
1454 W.printHex(
"Signature", ObjName.
Signature);
1455 W.printString(
"ObjectName", ObjName.
Name);
1458 CurrentObjectName = ObjName.
Name;
1464 if (InFunctionScope)
1468 InFunctionScope =
true;
1472 W.printHex(
"Segment", Proc.
Segment);
1473 W.printFlags(
"Flags",
static_cast<uint8_t>(Proc.
Flags),
1475 W.printString(
"DisplayName", Proc.
Name);
1524 if (
options().getGeneralCollectRanges()) {
1530 Function->addObject(LowPC, HighPC);
1533 if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1535 Reader->getCompileUnit()->addPublicName(
Function, LowPC, HighPC);
1556 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
1558 std::optional<CVType> CVFunctionType;
1559 auto GetRecordType = [&]() ->
bool {
1560 CVFunctionType = Ids.tryGetType(TIFunctionType);
1561 if (!CVFunctionType)
1566 if (CVFunctionType->kind() == LF_FUNC_ID)
1570 return (CVFunctionType->kind() == LF_MFUNC_ID);
1574 if (!GetRecordType()) {
1575 CVFunctionType = Types.tryGetType(TIFunctionType);
1576 if (!CVFunctionType)
1580 if (
Error Err = LogicalVisitor->finishVisitation(
1581 *CVFunctionType, TIFunctionType,
Function))
1585 if (
Record.kind() == SymbolKind::S_GPROC32 ||
1586 Record.kind() == SymbolKind::S_GPROC32_ID)
1592 if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1597 if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1609 InFunctionScope =
false;
1615 if (InFunctionScope)
1619 InFunctionScope =
true;
1622 W.printHex(
"Segment",
Thunk.Segment);
1623 W.printString(
"Name",
Thunk.Name);
1636 W.printString(
"UDTName",
UDT.Name);
1639 if (
LVType *
Type = LogicalVisitor->CurrentType) {
1640 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
UDT.Name)) {
1641 if (
Type->getParentScope()->removeElement(
Type))
1642 Namespace->addElement(
Type);
1655 Type->resetIncludeInPrint();
1658 if (
UDT.Name == RecordName)
1659 Type->resetIncludeInPrint();
1678 W.printHex(
"BaseOffset",
JumpTable.BaseOffset);
1679 W.printNumber(
"BaseSegment",
JumpTable.BaseSegment);
1682 W.printHex(
"BranchOffset",
JumpTable.BranchOffset);
1683 W.printHex(
"TableOffset",
JumpTable.TableOffset);
1684 W.printNumber(
"BranchSegment",
JumpTable.BranchSegment);
1685 W.printNumber(
"TableSegment",
JumpTable.TableSegment);
1686 W.printNumber(
"EntriesCount",
JumpTable.EntriesCount);
1695 switch (
Caller.getKind()) {
1696 case SymbolRecordKind::CallerSym:
1697 FieldName =
"Callee";
1699 case SymbolRecordKind::CalleeSym:
1700 FieldName =
"Caller";
1702 case SymbolRecordKind::InlineesSym:
1703 FieldName =
"Inlinee";
1707 "Unknown CV Record type for a CallerSym object!");
1709 for (
auto FuncID :
Caller.Indices) {
1718 if (Element && Element->getIsScoped()) {
1737#define DEBUG_TYPE "CodeViewLogicalVisitor"
1744 : Reader(Reader), W(W), Input(Input) {
1747 Shared = std::make_shared<LVShared>(Reader,
this);
1753 StreamIdx ==
StreamTPI ? types() : ids());
1758 W.getOStream() <<
"\n";
1761 W.getOStream() <<
" {\n";
1766 << Element->
getName() <<
"\n";
1771 W.startLine() <<
"}\n";
1777 W.getOStream() <<
"\n";
1780 W.getOStream() <<
" {\n";
1785 << Element->
getName() <<
"\n";
1790 W.startLine() <<
"}\n";
1808 W.printNumber(
"NumArgs",
Size);
1817 TypeIndex ParameterType = Indices[Index];
1831 W.printNumber(
"SizeOf", AT.
getSize());
1832 W.printString(
"Name", AT.
getName());
1836 if (Element->getIsFinalized())
1838 Element->setIsFinalized();
1844 Reader->getCompileUnit()->addElement(Array);
1847 LVType *PrevSubrange =
nullptr;
1855 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1880 while (CVEntry.
kind() == LF_ARRAY) {
1891 AddSubrangeType(AR);
1892 TIArrayType = TIElementType;
1898 CVType CVElementType =
Types.getType(TIElementType);
1899 if (CVElementType.
kind() == LF_MODIFIER) {
1901 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1914 CVEntry =
Types.getType(TIElementType);
1916 const_cast<CVType &
>(CVEntry), AR)) {
1926 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
1987 W.printNumber(
"MemberCount",
Class.getMemberCount());
1991 W.printNumber(
"SizeOf",
Class.getSize());
1992 W.printString(
"Name",
Class.getName());
1993 if (
Class.hasUniqueName())
1994 W.printString(
"UniqueName",
Class.getUniqueName());
1998 if (Element->getIsFinalized())
2000 Element->setIsFinalized();
2006 Scope->setName(
Class.getName());
2007 if (
Class.hasUniqueName())
2008 Scope->setLinkageName(
Class.getUniqueName());
2011 if (
Class.isNested()) {
2012 Scope->setIsNested();
2013 createParents(
Class.getName(), Scope);
2016 if (
Class.isScoped())
2017 Scope->setIsScoped();
2021 if (!(
Class.isNested() ||
Class.isScoped())) {
2022 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2023 Namespace->addElement(Scope);
2025 Reader->getCompileUnit()->addElement(Scope);
2031 TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2037 const_cast<CVType &
>(CVReference), ReferenceRecord))
2058 W.printNumber(
"NumEnumerators",
Enum.getMemberCount());
2061 W.printString(
"Name",
Enum.getName());
2069 if (Scope->getIsFinalized())
2071 Scope->setIsFinalized();
2075 Scope->setName(
Enum.getName());
2076 if (
Enum.hasUniqueName())
2077 Scope->setLinkageName(
Enum.getUniqueName());
2081 if (
Enum.isNested()) {
2082 Scope->setIsNested();
2083 createParents(
Enum.getName(), Scope);
2086 if (
Enum.isScoped()) {
2087 Scope->setIsScoped();
2088 Scope->setIsEnumClass();
2092 if (!(
Enum.isNested() ||
Enum.isScoped())) {
2093 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2094 Namespace->addElement(Scope);
2096 Reader->getCompileUnit()->addElement(Scope);
2119 if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2133 W.printString(
"Name", Func.getName());
2145 TypeIndex TIParent = Func.getParentScope();
2146 if (FunctionDcl->getIsInlinedAbstract()) {
2147 FunctionDcl->setName(Func.getName());
2149 Reader->getCompileUnit()->addElement(FunctionDcl);
2153 CVType CVParentScope = ids().getType(TIParent);
2158 TypeIndex TIFunctionType = Func.getFunctionType();
2159 CVType CVFunctionType =
Types.getType(TIFunctionType);
2164 FunctionDcl->setIsFinalized();
2188 W.printString(
"Name", Id.getName());
2193 if (FunctionDcl->getIsInlinedAbstract()) {
2199 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2200 Class->addElement(FunctionDcl);
2203 TypeIndex TIFunctionType = Id.getFunctionType();
2204 CVType CVFunction = types().getType(TIFunctionType);
2229 MemberFunction->setIsFinalized();
2231 MemberFunction->setOffset(TI.
getIndex());
2232 MemberFunction->setOffsetFromTypeIndex();
2234 if (ProcessArgumentList) {
2235 ProcessArgumentList =
false;
2237 if (!MemberFunction->getIsStatic()) {
2242 createParameter(ThisPointer,
StringRef(), MemberFunction);
2243 This->setIsArtificial();
2270 Method.Name = OverloadedMethodName;
2302 bool SeenModifier =
false;
2305 SeenModifier =
true;
2306 LastLink->
setTag(dwarf::DW_TAG_const_type);
2307 LastLink->setIsConst();
2318 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2319 LastLink->setIsVolatile();
2320 LastLink->
setName(
"volatile");
2331 LastLink->setIsUnaligned();
2332 LastLink->
setName(
"unaligned");
2335 LastLink->
setType(ModifiedType);
2345 W.printNumber(
"IsFlat", Ptr.
isFlat());
2346 W.printNumber(
"IsConst", Ptr.
isConst());
2347 W.printNumber(
"IsVolatile", Ptr.
isVolatile());
2349 W.printNumber(
"IsRestrict", Ptr.
isRestrict());
2352 W.printNumber(
"SizeOf", Ptr.
getSize());
2377 bool SeenModifier =
false;
2383 SeenModifier =
true;
2385 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2394 LVType *LReference = Reader->createType();
2395 LReference->setIsModifier();
2396 LastLink->
setType(LReference);
2397 LastLink = LReference;
2400 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2401 LastLink->setIsReference();
2406 LVType *RReference = Reader->createType();
2407 RReference->setIsModifier();
2408 LastLink->
setType(RReference);
2409 LastLink = RReference;
2412 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2413 LastLink->setIsRvalueReference();
2439 if (ProcessArgumentList) {
2440 ProcessArgumentList =
false;
2458 W.printNumber(
"MemberCount",
Union.getMemberCount());
2460 W.printNumber(
"SizeOf",
Union.getSize());
2461 W.printString(
"Name",
Union.getName());
2462 if (
Union.hasUniqueName())
2463 W.printString(
"UniqueName",
Union.getUniqueName());
2471 if (Scope->getIsFinalized())
2473 Scope->setIsFinalized();
2475 Scope->setName(
Union.getName());
2476 if (
Union.hasUniqueName())
2477 Scope->setLinkageName(
Union.getUniqueName());
2480 if (
Union.isNested()) {
2481 Scope->setIsNested();
2482 createParents(
Union.getName(), Scope);
2484 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2485 Namespace->addElement(Scope);
2487 Reader->getCompileUnit()->addElement(Scope);
2490 if (!
Union.getFieldList().isNoneType()) {
2507 W.printNumber(
"Age", TS.
getAge());
2508 W.printString(
"Name", TS.
getName());
2522 W.printString(
"VFTableName", VFT.
getName());
2524 W.printString(
"MethodName",
N);
2551 W.printNumber(
"NumStrings",
Size);
2567 W.printString(
"StringData",
String.getString());
2570 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2571 String.getString(),
false)) {
2575 Scope->removeElement(Element);
2576 Namespace->addElement(Element);
2607 W.printNumber(
"Module", ModSourceLine.
getModule());
2652 W.printHex(
"BaseOffset",
Base.getBaseOffset());
2661 Symbol->setAccessibilityCode(
Base.getAccess());
2675 W.printHex(
"FieldOffset",
Field.getFieldOffset());
2676 W.printString(
"Name",
Field.getName());
2692 W.printNumber(
"EnumValue",
Enum.getValue());
2693 W.printString(
"Name",
Enum.getName());
2701 Enum.getValue().toString(
Value, 16,
true,
true);
2728 W.printString(
"Name",
Nested.getName());
2739 if (NestedType && NestedType->getIsNested()) {
2745 if (NestedTypeName.
size() && RecordName.
size()) {
2747 std::tie(OuterComponent, std::ignore) =
2751 if (OuterComponent.
size() && OuterComponent == RecordName) {
2752 if (!NestedType->getIsScopedAlready()) {
2753 Scope->addElement(NestedType);
2754 NestedType->setIsScopedAlready();
2757 Typedef->resetIncludeInPrint();
2774 if (Method.isIntroducingVirtual())
2775 W.printHex(
"VFTableOffset", Method.getVFTableOffset());
2776 W.printString(
"Name", Method.getName());
2783 ProcessArgumentList =
true;
2785 MemberFunction->setIsFinalized();
2788 MemberFunction->
setName(Method.getName());
2789 MemberFunction->setAccessibilityCode(Method.getAccess());
2793 MemberFunction->setIsStatic();
2794 MemberFunction->setVirtualityCode(
Kind);
2799 MemberFunction->setIsArtificial();
2802 CVType CVMethodType =
Types.getType(Method.getType());
2807 ProcessArgumentList =
false;
2818 W.printHex(
"MethodCount", Method.getNumOverloads());
2820 W.printString(
"Name", Method.getName());
2827 OverloadedMethodName = Method.getName();
2828 CVType CVMethods =
Types.getType(Method.getMethodList());
2842 W.printString(
"Name",
Field.getName());
2872 W.printHex(
"VBPtrOffset",
Base.getVBPtrOffset());
2873 W.printHex(
"VBTableIndex",
Base.getVTableIndex());
2882 Symbol->setAccessibilityCode(
Base.getAccess());
2901#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2904 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2908#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2909 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2910#define TYPE_RECORD(EnumName, EnumVal, Name)
2911#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2912#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2928#define TYPE_RECORD(EnumName, EnumVal, Name) \
2930 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2934#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2935 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2936#define MEMBER_RECORD(EnumName, EnumVal, Name)
2937#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2938#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2945Error LVLogicalVisitor::visitFieldListMemberStream(
2954 while (!Reader.empty()) {
2955 if (
Error Err = Reader.readEnum(Leaf))
2973 if (!ScopeStack.empty())
2975 InCompileUnitScope =
true;
2979 ReaderParent->addElement(Scope);
2983 ReaderScope->addElement(Symbol);
2987 ReaderScope->addElement(
Type);
2999 if (
options().getAttributeBase())
3006 case TypeLeafKind::LF_ENUMERATE:
3010 case TypeLeafKind::LF_MODIFIER:
3014 case TypeLeafKind::LF_POINTER:
3022 case TypeLeafKind::LF_BCLASS:
3023 case TypeLeafKind::LF_IVBCLASS:
3024 case TypeLeafKind::LF_VBCLASS:
3029 case TypeLeafKind::LF_MEMBER:
3030 case TypeLeafKind::LF_STMEMBER:
3037 case TypeLeafKind::LF_ARRAY:
3041 case TypeLeafKind::LF_CLASS:
3046 case TypeLeafKind::LF_ENUM:
3050 case TypeLeafKind::LF_METHOD:
3051 case TypeLeafKind::LF_ONEMETHOD:
3052 case TypeLeafKind::LF_PROCEDURE:
3057 case TypeLeafKind::LF_STRUCTURE:
3062 case TypeLeafKind::LF_UNION:
3081 case SymbolKind::S_UDT:
3087 case SymbolKind::S_CONSTANT:
3093 case SymbolKind::S_BPREL32:
3094 case SymbolKind::S_REGREL32:
3095 case SymbolKind::S_REGREL32_INDIR:
3096 case SymbolKind::S_GDATA32:
3097 case SymbolKind::S_LDATA32:
3098 case SymbolKind::S_LOCAL:
3108 case SymbolKind::S_BLOCK32:
3113 case SymbolKind::S_COMPILE2:
3114 case SymbolKind::S_COMPILE3:
3119 case SymbolKind::S_INLINESITE:
3120 case SymbolKind::S_INLINESITE2:
3123 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3125 case SymbolKind::S_LPROC32:
3126 case SymbolKind::S_GPROC32:
3127 case SymbolKind::S_LPROC32_ID:
3128 case SymbolKind::S_GPROC32_ID:
3129 case SymbolKind::S_SEPCODE:
3130 case SymbolKind::S_THUNK32:
3150 Element->setIsFinalized();
3160 Element->setOffsetFromTypeIndex();
3164 W.printString(
"** Not implemented. **");
3171 Element->setOffsetFromTypeIndex();
3185 Symbol->setName(
Name);
3190 CVType CVMemberType = Types.getType(TI);
3191 if (CVMemberType.
kind() == LF_BITFIELD) {
3206 LVSymbol *
Parameter = Reader->createSymbol();
3209 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3220LVType *LVLogicalVisitor::createBaseType(
TypeIndex TI, StringRef TypeName) {
3222 TypeIndex TIR = (TypeIndex)SimpleKind;
3225 W.printString(
"TypeName", TypeName);
3228 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TIR))
3229 return static_cast<LVType *
>(Element);
3234 Reader->getCompileUnit()->addElement(
CurrentType);
3239LVType *LVLogicalVisitor::createPointerType(
TypeIndex TI, StringRef TypeName) {
3242 W.printString(
"TypeName", TypeName);
3245 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TI))
3246 return static_cast<LVType *
>(Element);
3248 LVType *Pointee = createBaseType(TI,
TypeName.drop_back(1));
3252 Reader->getCompileUnit()->addElement(
CurrentType);
3257void LVLogicalVisitor::createParents(StringRef ScopedName,
LVElement *Element) {
3277 if (Components.size() < 2)
3279 Components.pop_back();
3281 LVStringRefs::size_type FirstNamespace;
3282 LVStringRefs::size_type FirstAggregate;
3283 std::tie(FirstNamespace, FirstAggregate) =
3284 Shared->NamespaceDeduction.find(Components);
3287 W.printString(
"First Namespace", Components[FirstNamespace]);
3288 W.printString(
"First NonNamespace", Components[FirstAggregate]);
3292 if (FirstNamespace < FirstAggregate) {
3293 Shared->NamespaceDeduction.get(
3295 Components.begin() + FirstAggregate));
3301 LVScope *Aggregate =
nullptr;
3302 TypeIndex TIAggregate;
3304 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3307 for (LVStringRefs::size_type Index = FirstAggregate;
3310 Components.begin() + Index + 1),
3312 TIAggregate = Shared->ForwardReferences.remap(
3313 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3323 if (Aggregate && !Element->getIsScopedAlready()) {
3325 Element->setIsScopedAlready();
3332 TI = Shared->ForwardReferences.remap(TI);
3335 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3343 return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3344 : createBaseType(TI, TypeName);
3352 if (Element->getIsFinalized())
3366 Element->setIsFinalized();
3373 for (
const TypeIndex &Entry : Shared->LineRecords) {
3383 W.printNumber(
"LineNumber",
Line.getLineNumber());
3389 if (
LVElement *Element = Shared->TypeRecords.find(
3393 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3401 Shared->NamespaceDeduction.init();
3407 if (!
options().getInternalTag())
3412 auto NewLine = [&]() {
3425 Shared->TypeKinds.clear();
3428 OS <<
"\nSymbols:\n";
3431 Shared->SymbolKinds.clear();
3445 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3452 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3453 if (Iter != InlineeInfo.end()) {
3454 LineNumber = Iter->second.first;
3463 dbgs() <<
"inlineSiteAnnotation\n"
3464 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n"
3465 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n"
3466 <<
"Parent: " << Parent->
getName() <<
"\n"
3467 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3471 if (!
options().getPrintLines())
3478 int32_t LineOffset = LineNumber;
3482 auto UpdateCodeOffset = [&](
uint32_t Delta) {
3489 auto UpdateLineOffset = [&](int32_t Delta) {
3490 LineOffset += Delta;
3492 char Sign = Delta > 0 ?
'+' :
'-';
3493 dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3497 auto UpdateFileOffset = [&](int32_t
Offset) {
3503 auto CreateLine = [&]() {
3507 Line->setLineNumber(LineOffset);
3514 bool SeenLowAddress =
false;
3515 bool SeenHighAddress =
false;
3519 for (
auto &Annot :
InlineSite.annotations()) {
3526 switch (Annot.OpCode) {
3530 UpdateCodeOffset(Annot.U1);
3535 SeenLowAddress =
true;
3540 SeenHighAddress =
true;
3544 UpdateCodeOffset(Annot.U2);
3549 UpdateCodeOffset(Annot.U1);
3550 UpdateLineOffset(Annot.S1);
3557 UpdateFileOffset(Annot.U1);
3563 if (SeenLowAddress && SeenHighAddress) {
3564 SeenLowAddress =
false;
3565 SeenHighAddress =
false;
3566 InlinedFunction->
addObject(LowPC, HighPC);
3570 Reader->addInlineeLines(InlinedFunction,
InlineeLines);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Lower Kernel Arguments
OptimizedStructLayoutField Field
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - 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...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr size_t size() const
size - 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
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)
Error visitKnownRecord(CVType &Record, ArgListRecord &Args, TypeIndex TI, LVElement *Element)
void printRecords(raw_ostream &OS) const
void printTypeEnd(CVType &Record)
Error visitMemberRecord(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks, TypeIndex TI, LVElement *Element)
Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base, TypeIndex TI, LVElement *Element)
void printMemberEnd(CVMemberRecord &Record)
Error inlineSiteAnnotation(LVScope *AbstractFunction, LVScope *InlinedFunction, InlineSiteSym &InlineSite)
LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W, llvm::pdb::InputFile &Input)
void printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx)
Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI)
void pushScope(LVScope *Scope)
Error visitUnknownType(CVType &Record, TypeIndex TI)
void addElement(LVScope *Scope, bool IsCompileUnit)
void printTypeBegin(CVType &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
LVElement * getElement(uint32_t StreamIdx, TypeIndex TI, LVScope *Parent=nullptr)
void printMemberBegin(CVMemberRecord &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
Error finishVisitation(CVType &Record, TypeIndex TI, LVElement *Element)
LVElement * createElement(TypeLeafKind Kind)
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....
CVRecord< SymbolKind > CVSymbol
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getJumpTableEntrySizeNames()
bool symbolEndsScope(SymbolKind Kind)
Return true if this ssymbol ends a scope.
MethodOptions
Equivalent to CV_fldattr_t bitfield.
LLVM_ABI ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
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 ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
LLVM_ABI ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
bool isAggregate(CVType CVT)
Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, LF_CLASS, LF_INTERFACE,...
LLVM_ABI ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
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 ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
LLVM_ABI ArrayRef< EnumEntry< SourceLanguage > > getSourceLanguageNames()
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 ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
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)
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
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.
FunctionAddr VTableAddr Count
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
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)
FunctionAddr VTableAddr uintptr_t uintptr_t Data
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.