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());
1152 W.printBoolean(
"HasSpilledUDTMember",
1154 W.printNumber(
"OffsetInParent", DefRangeRegisterRelIndir.
offsetInParent());
1155 W.printNumber(
"BasePointerOffset",
1157 W.printNumber(
"OffsetInUdt", DefRangeRegisterRelIndir.
Hdr.
OffsetInUdt);
1158 printLocalVariableAddrRange(DefRangeRegisterRelIndir.
Range,
1160 printLocalVariableAddrGap(DefRangeRegisterRelIndir.
Gaps);
1163 if (
LVSymbol *Symbol = LocalSymbol) {
1164 Symbol->setHasCodeViewLocation();
1165 LocalSymbol =
nullptr;
1176 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1179 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2, Operand3});
1191 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1196 printLocalVariableAddrRange(DefRangeRegister.
Range,
1198 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1201 if (
LVSymbol *Symbol = LocalSymbol) {
1202 Symbol->setHasCodeViewLocation();
1203 LocalSymbol =
nullptr;
1211 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1214 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1226 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1230 W.printNumber(
"MayHaveNoName", DefRangeSubfieldRegister.
Hdr.
MayHaveNoName);
1231 W.printNumber(
"OffsetInParent",
1233 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1235 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1238 if (
LVSymbol *Symbol = LocalSymbol) {
1239 Symbol->setHasCodeViewLocation();
1240 LocalSymbol =
nullptr;
1249 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1252 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1264 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1269 if (!ExpectedProgram) {
1272 "String table offset outside of bounds of String Table!");
1274 W.printString(
"Program", *ExpectedProgram);
1276 W.printNumber(
"OffsetInParent", DefRangeSubfield.
OffsetInParent);
1277 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1279 printLocalVariableAddrGap(DefRangeSubfield.
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});
1307 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1312 if (!ExpectedProgram) {
1315 "String table offset outside of bounds of String Table!");
1317 W.printString(
"Program", *ExpectedProgram);
1320 printLocalVariableAddrGap(DefRange.
Gaps);
1323 if (
LVSymbol *Symbol = LocalSymbol) {
1324 Symbol->setHasCodeViewLocation();
1325 LocalSymbol =
nullptr;
1333 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1336 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1379 W.printString(
"DisplayName",
Data.Name);
1382 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1385 ObjDelegate->getLinkageName(
Data.getRelocationOffset(),
Data.DataOffset,
1388 Symbol->setName(
Data.Name);
1397 if (
getReader().isSystemEntry(Symbol) && !
options().getAttributeSystem()) {
1398 Symbol->resetIncludeInPrint();
1402 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Data.Name)) {
1405 if (Symbol->getParentScope()->removeElement(Symbol))
1406 Namespace->addElement(Symbol);
1409 Symbol->setType(LogicalVisitor->getElement(
StreamTPI,
Data.Type));
1410 if (
Record.kind() == SymbolKind::S_GDATA32)
1411 Symbol->setIsExternal();
1422 if (
LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1423 LVScope *AbstractFunction = Reader->createScopeFunction();
1424 AbstractFunction->setIsSubprogram();
1425 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1427 AbstractFunction->setIsInlinedAbstract();
1430 LogicalVisitor->startProcessArgumentList();
1433 if (
Error Err = LogicalVisitor->finishVisitation(
1434 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1436 LogicalVisitor->stopProcessArgumentList();
1441 InlinedFunction->setName(
Name);
1442 InlinedFunction->setLinkageName(
Name);
1445 if (
Error Err = LogicalVisitor->inlineSiteAnnotation(
1446 AbstractFunction, InlinedFunction,
InlineSite))
1458 W.printString(
"VarName",
Local.Name);
1461 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1462 Symbol->setName(
Local.Name);
1465 Symbol->resetIsVariable();
1469 Local.Name ==
"this") {
1470 Symbol->setIsArtificial();
1471 Symbol->setIsParameter();
1474 : Symbol->setIsVariable();
1478 if (Symbol->getIsParameter())
1479 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1481 setLocalVariableType(Symbol,
Local.Type);
1486 LocalSymbol = Symbol;
1495 W.printHex(
"Signature", ObjName.
Signature);
1496 W.printString(
"ObjectName", ObjName.
Name);
1499 CurrentObjectName = ObjName.
Name;
1505 if (InFunctionScope)
1509 InFunctionScope =
true;
1513 W.printHex(
"Segment", Proc.
Segment);
1514 W.printFlags(
"Flags",
static_cast<uint8_t>(Proc.
Flags),
1516 W.printString(
"DisplayName", Proc.
Name);
1565 if (
options().getGeneralCollectRanges()) {
1571 Function->addObject(LowPC, HighPC);
1574 if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1576 Reader->getCompileUnit()->addPublicName(
Function, LowPC, HighPC);
1597 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
1599 std::optional<CVType> CVFunctionType;
1600 auto GetRecordType = [&]() ->
bool {
1601 CVFunctionType = Ids.tryGetType(TIFunctionType);
1602 if (!CVFunctionType)
1607 if (CVFunctionType->kind() == LF_FUNC_ID)
1611 return (CVFunctionType->kind() == LF_MFUNC_ID);
1615 if (!GetRecordType()) {
1616 CVFunctionType = Types.tryGetType(TIFunctionType);
1617 if (!CVFunctionType)
1621 if (
Error Err = LogicalVisitor->finishVisitation(
1622 *CVFunctionType, TIFunctionType,
Function))
1626 if (
Record.kind() == SymbolKind::S_GPROC32 ||
1627 Record.kind() == SymbolKind::S_GPROC32_ID)
1633 if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1638 if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1650 InFunctionScope =
false;
1656 if (InFunctionScope)
1660 InFunctionScope =
true;
1663 W.printHex(
"Segment",
Thunk.Segment);
1664 W.printString(
"Name",
Thunk.Name);
1677 W.printString(
"UDTName",
UDT.Name);
1680 if (
LVType *
Type = LogicalVisitor->CurrentType) {
1681 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
UDT.Name)) {
1682 if (
Type->getParentScope()->removeElement(
Type))
1683 Namespace->addElement(
Type);
1696 Type->resetIncludeInPrint();
1699 if (
UDT.Name == RecordName)
1700 Type->resetIncludeInPrint();
1719 W.printHex(
"BaseOffset",
JumpTable.BaseOffset);
1720 W.printNumber(
"BaseSegment",
JumpTable.BaseSegment);
1723 W.printHex(
"BranchOffset",
JumpTable.BranchOffset);
1724 W.printHex(
"TableOffset",
JumpTable.TableOffset);
1725 W.printNumber(
"BranchSegment",
JumpTable.BranchSegment);
1726 W.printNumber(
"TableSegment",
JumpTable.TableSegment);
1727 W.printNumber(
"EntriesCount",
JumpTable.EntriesCount);
1736 switch (
Caller.getKind()) {
1737 case SymbolRecordKind::CallerSym:
1738 FieldName =
"Callee";
1740 case SymbolRecordKind::CalleeSym:
1741 FieldName =
"Caller";
1743 case SymbolRecordKind::InlineesSym:
1744 FieldName =
"Inlinee";
1748 "Unknown CV Record type for a CallerSym object!");
1750 for (
auto FuncID :
Caller.Indices) {
1759 if (Element && Element->getIsScoped()) {
1778#define DEBUG_TYPE "CodeViewLogicalVisitor"
1785 : Reader(Reader), W(W), Input(Input) {
1788 Shared = std::make_shared<LVShared>(Reader,
this);
1794 StreamIdx ==
StreamTPI ? types() : ids());
1799 W.getOStream() <<
"\n";
1802 W.getOStream() <<
" {\n";
1807 << Element->
getName() <<
"\n";
1812 W.startLine() <<
"}\n";
1818 W.getOStream() <<
"\n";
1821 W.getOStream() <<
" {\n";
1826 << Element->
getName() <<
"\n";
1831 W.startLine() <<
"}\n";
1849 W.printNumber(
"NumArgs",
Size);
1858 TypeIndex ParameterType = Indices[Index];
1872 W.printNumber(
"SizeOf", AT.
getSize());
1873 W.printString(
"Name", AT.
getName());
1877 if (Element->getIsFinalized())
1879 Element->setIsFinalized();
1885 Reader->getCompileUnit()->addElement(Array);
1888 LVType *PrevSubrange =
nullptr;
1896 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1921 while (CVEntry.
kind() == LF_ARRAY) {
1932 AddSubrangeType(AR);
1933 TIArrayType = TIElementType;
1939 CVType CVElementType =
Types.getType(TIElementType);
1940 if (CVElementType.
kind() == LF_MODIFIER) {
1942 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1955 CVEntry =
Types.getType(TIElementType);
1957 const_cast<CVType &
>(CVEntry), AR)) {
1967 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
2028 W.printNumber(
"MemberCount",
Class.getMemberCount());
2032 W.printNumber(
"SizeOf",
Class.getSize());
2033 W.printString(
"Name",
Class.getName());
2034 if (
Class.hasUniqueName())
2035 W.printString(
"UniqueName",
Class.getUniqueName());
2039 if (Element->getIsFinalized())
2041 Element->setIsFinalized();
2047 Scope->setName(
Class.getName());
2048 if (
Class.hasUniqueName())
2049 Scope->setLinkageName(
Class.getUniqueName());
2052 if (
Class.isNested()) {
2053 Scope->setIsNested();
2054 createParents(
Class.getName(), Scope);
2057 if (
Class.isScoped())
2058 Scope->setIsScoped();
2062 if (!(
Class.isNested() ||
Class.isScoped())) {
2063 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2064 Namespace->addElement(Scope);
2066 Reader->getCompileUnit()->addElement(Scope);
2072 TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2078 const_cast<CVType &
>(CVReference), ReferenceRecord))
2099 W.printNumber(
"NumEnumerators",
Enum.getMemberCount());
2102 W.printString(
"Name",
Enum.getName());
2110 if (Scope->getIsFinalized())
2112 Scope->setIsFinalized();
2116 Scope->setName(
Enum.getName());
2117 if (
Enum.hasUniqueName())
2118 Scope->setLinkageName(
Enum.getUniqueName());
2122 if (
Enum.isNested()) {
2123 Scope->setIsNested();
2124 createParents(
Enum.getName(), Scope);
2127 if (
Enum.isScoped()) {
2128 Scope->setIsScoped();
2129 Scope->setIsEnumClass();
2133 if (!(
Enum.isNested() ||
Enum.isScoped())) {
2134 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2135 Namespace->addElement(Scope);
2137 Reader->getCompileUnit()->addElement(Scope);
2160 if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2174 W.printString(
"Name", Func.getName());
2186 TypeIndex TIParent = Func.getParentScope();
2187 if (FunctionDcl->getIsInlinedAbstract()) {
2188 FunctionDcl->setName(Func.getName());
2190 Reader->getCompileUnit()->addElement(FunctionDcl);
2194 CVType CVParentScope = ids().getType(TIParent);
2199 TypeIndex TIFunctionType = Func.getFunctionType();
2200 CVType CVFunctionType =
Types.getType(TIFunctionType);
2205 FunctionDcl->setIsFinalized();
2229 W.printString(
"Name", Id.getName());
2234 if (FunctionDcl->getIsInlinedAbstract()) {
2240 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2241 Class->addElement(FunctionDcl);
2244 TypeIndex TIFunctionType = Id.getFunctionType();
2245 CVType CVFunction = types().getType(TIFunctionType);
2270 MemberFunction->setIsFinalized();
2272 MemberFunction->setOffset(TI.
getIndex());
2273 MemberFunction->setOffsetFromTypeIndex();
2275 if (ProcessArgumentList) {
2276 ProcessArgumentList =
false;
2278 if (!MemberFunction->getIsStatic()) {
2283 createParameter(ThisPointer,
StringRef(), MemberFunction);
2284 This->setIsArtificial();
2311 Method.Name = OverloadedMethodName;
2343 bool SeenModifier =
false;
2346 SeenModifier =
true;
2347 LastLink->
setTag(dwarf::DW_TAG_const_type);
2348 LastLink->setIsConst();
2359 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2360 LastLink->setIsVolatile();
2361 LastLink->
setName(
"volatile");
2372 LastLink->setIsUnaligned();
2373 LastLink->
setName(
"unaligned");
2376 LastLink->
setType(ModifiedType);
2386 W.printNumber(
"IsFlat", Ptr.
isFlat());
2387 W.printNumber(
"IsConst", Ptr.
isConst());
2388 W.printNumber(
"IsVolatile", Ptr.
isVolatile());
2390 W.printNumber(
"IsRestrict", Ptr.
isRestrict());
2393 W.printNumber(
"SizeOf", Ptr.
getSize());
2418 bool SeenModifier =
false;
2424 SeenModifier =
true;
2426 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2435 LVType *LReference = Reader->createType();
2436 LReference->setIsModifier();
2437 LastLink->
setType(LReference);
2438 LastLink = LReference;
2441 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2442 LastLink->setIsReference();
2447 LVType *RReference = Reader->createType();
2448 RReference->setIsModifier();
2449 LastLink->
setType(RReference);
2450 LastLink = RReference;
2453 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2454 LastLink->setIsRvalueReference();
2480 if (ProcessArgumentList) {
2481 ProcessArgumentList =
false;
2499 W.printNumber(
"MemberCount",
Union.getMemberCount());
2501 W.printNumber(
"SizeOf",
Union.getSize());
2502 W.printString(
"Name",
Union.getName());
2503 if (
Union.hasUniqueName())
2504 W.printString(
"UniqueName",
Union.getUniqueName());
2512 if (Scope->getIsFinalized())
2514 Scope->setIsFinalized();
2516 Scope->setName(
Union.getName());
2517 if (
Union.hasUniqueName())
2518 Scope->setLinkageName(
Union.getUniqueName());
2521 if (
Union.isNested()) {
2522 Scope->setIsNested();
2523 createParents(
Union.getName(), Scope);
2525 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2526 Namespace->addElement(Scope);
2528 Reader->getCompileUnit()->addElement(Scope);
2531 if (!
Union.getFieldList().isNoneType()) {
2548 W.printNumber(
"Age", TS.
getAge());
2549 W.printString(
"Name", TS.
getName());
2563 W.printString(
"VFTableName", VFT.
getName());
2565 W.printString(
"MethodName",
N);
2592 W.printNumber(
"NumStrings",
Size);
2608 W.printString(
"StringData",
String.getString());
2611 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2612 String.getString(),
false)) {
2616 Scope->removeElement(Element);
2617 Namespace->addElement(Element);
2648 W.printNumber(
"Module", ModSourceLine.
getModule());
2693 W.printHex(
"BaseOffset",
Base.getBaseOffset());
2702 Symbol->setAccessibilityCode(
Base.getAccess());
2716 W.printHex(
"FieldOffset",
Field.getFieldOffset());
2717 W.printString(
"Name",
Field.getName());
2733 W.printNumber(
"EnumValue",
Enum.getValue());
2734 W.printString(
"Name",
Enum.getName());
2742 Enum.getValue().toString(
Value, 16,
true,
true);
2769 W.printString(
"Name",
Nested.getName());
2780 if (NestedType && NestedType->getIsNested()) {
2786 if (NestedTypeName.
size() && RecordName.
size()) {
2788 std::tie(OuterComponent, std::ignore) =
2792 if (OuterComponent.
size() && OuterComponent == RecordName) {
2793 if (!NestedType->getIsScopedAlready()) {
2794 Scope->addElement(NestedType);
2795 NestedType->setIsScopedAlready();
2798 Typedef->resetIncludeInPrint();
2815 if (Method.isIntroducingVirtual())
2816 W.printHex(
"VFTableOffset", Method.getVFTableOffset());
2817 W.printString(
"Name", Method.getName());
2824 ProcessArgumentList =
true;
2826 MemberFunction->setIsFinalized();
2829 MemberFunction->
setName(Method.getName());
2830 MemberFunction->setAccessibilityCode(Method.getAccess());
2834 MemberFunction->setIsStatic();
2835 MemberFunction->setVirtualityCode(
Kind);
2840 MemberFunction->setIsArtificial();
2843 CVType CVMethodType =
Types.getType(Method.getType());
2848 ProcessArgumentList =
false;
2859 W.printHex(
"MethodCount", Method.getNumOverloads());
2861 W.printString(
"Name", Method.getName());
2868 OverloadedMethodName = Method.getName();
2869 CVType CVMethods =
Types.getType(Method.getMethodList());
2883 W.printString(
"Name",
Field.getName());
2913 W.printHex(
"VBPtrOffset",
Base.getVBPtrOffset());
2914 W.printHex(
"VBTableIndex",
Base.getVTableIndex());
2923 Symbol->setAccessibilityCode(
Base.getAccess());
2942#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2945 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2949#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2950 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2951#define TYPE_RECORD(EnumName, EnumVal, Name)
2952#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2953#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2969#define TYPE_RECORD(EnumName, EnumVal, Name) \
2971 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2975#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2976 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2977#define MEMBER_RECORD(EnumName, EnumVal, Name)
2978#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2979#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2986Error LVLogicalVisitor::visitFieldListMemberStream(
2995 while (!Reader.empty()) {
2996 if (
Error Err = Reader.readEnum(Leaf))
3014 if (!ScopeStack.empty())
3016 InCompileUnitScope =
true;
3020 ReaderParent->addElement(Scope);
3024 ReaderScope->addElement(Symbol);
3028 ReaderScope->addElement(
Type);
3040 if (
options().getAttributeBase())
3047 case TypeLeafKind::LF_ENUMERATE:
3051 case TypeLeafKind::LF_MODIFIER:
3055 case TypeLeafKind::LF_POINTER:
3063 case TypeLeafKind::LF_BCLASS:
3064 case TypeLeafKind::LF_IVBCLASS:
3065 case TypeLeafKind::LF_VBCLASS:
3070 case TypeLeafKind::LF_MEMBER:
3071 case TypeLeafKind::LF_STMEMBER:
3078 case TypeLeafKind::LF_ARRAY:
3082 case TypeLeafKind::LF_CLASS:
3087 case TypeLeafKind::LF_ENUM:
3091 case TypeLeafKind::LF_METHOD:
3092 case TypeLeafKind::LF_ONEMETHOD:
3093 case TypeLeafKind::LF_PROCEDURE:
3098 case TypeLeafKind::LF_STRUCTURE:
3103 case TypeLeafKind::LF_UNION:
3122 case SymbolKind::S_UDT:
3128 case SymbolKind::S_CONSTANT:
3134 case SymbolKind::S_BPREL32:
3135 case SymbolKind::S_REGREL32:
3136 case SymbolKind::S_REGREL32_INDIR:
3137 case SymbolKind::S_GDATA32:
3138 case SymbolKind::S_LDATA32:
3139 case SymbolKind::S_LOCAL:
3149 case SymbolKind::S_BLOCK32:
3154 case SymbolKind::S_COMPILE2:
3155 case SymbolKind::S_COMPILE3:
3160 case SymbolKind::S_INLINESITE:
3161 case SymbolKind::S_INLINESITE2:
3164 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3166 case SymbolKind::S_LPROC32:
3167 case SymbolKind::S_GPROC32:
3168 case SymbolKind::S_LPROC32_ID:
3169 case SymbolKind::S_GPROC32_ID:
3170 case SymbolKind::S_SEPCODE:
3171 case SymbolKind::S_THUNK32:
3191 Element->setIsFinalized();
3201 Element->setOffsetFromTypeIndex();
3205 W.printString(
"** Not implemented. **");
3212 Element->setOffsetFromTypeIndex();
3226 Symbol->setName(
Name);
3231 CVType CVMemberType = Types.getType(TI);
3232 if (CVMemberType.
kind() == LF_BITFIELD) {
3247 LVSymbol *
Parameter = Reader->createSymbol();
3250 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3261LVType *LVLogicalVisitor::createBaseType(
TypeIndex TI, StringRef TypeName) {
3263 TypeIndex TIR = (TypeIndex)SimpleKind;
3266 W.printString(
"TypeName", TypeName);
3269 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TIR))
3270 return static_cast<LVType *
>(Element);
3275 Reader->getCompileUnit()->addElement(
CurrentType);
3280LVType *LVLogicalVisitor::createPointerType(
TypeIndex TI, StringRef TypeName) {
3283 W.printString(
"TypeName", TypeName);
3286 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TI))
3287 return static_cast<LVType *
>(Element);
3289 LVType *Pointee = createBaseType(TI,
TypeName.drop_back(1));
3293 Reader->getCompileUnit()->addElement(
CurrentType);
3298void LVLogicalVisitor::createParents(StringRef ScopedName,
LVElement *Element) {
3318 if (Components.size() < 2)
3320 Components.pop_back();
3322 LVStringRefs::size_type FirstNamespace;
3323 LVStringRefs::size_type FirstAggregate;
3324 std::tie(FirstNamespace, FirstAggregate) =
3325 Shared->NamespaceDeduction.find(Components);
3328 W.printString(
"First Namespace", Components[FirstNamespace]);
3329 W.printString(
"First NonNamespace", Components[FirstAggregate]);
3333 if (FirstNamespace < FirstAggregate) {
3334 Shared->NamespaceDeduction.get(
3336 Components.begin() + FirstAggregate));
3342 LVScope *Aggregate =
nullptr;
3343 TypeIndex TIAggregate;
3345 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3348 for (LVStringRefs::size_type Index = FirstAggregate;
3351 Components.begin() + Index + 1),
3353 TIAggregate = Shared->ForwardReferences.remap(
3354 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3364 if (Aggregate && !Element->getIsScopedAlready()) {
3366 Element->setIsScopedAlready();
3373 TI = Shared->ForwardReferences.remap(TI);
3376 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3384 return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3385 : createBaseType(TI, TypeName);
3393 if (Element->getIsFinalized())
3407 Element->setIsFinalized();
3414 for (
const TypeIndex &Entry : Shared->LineRecords) {
3424 W.printNumber(
"LineNumber",
Line.getLineNumber());
3430 if (
LVElement *Element = Shared->TypeRecords.find(
3434 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3442 Shared->NamespaceDeduction.init();
3448 if (!
options().getInternalTag())
3453 auto NewLine = [&]() {
3466 Shared->TypeKinds.clear();
3469 OS <<
"\nSymbols:\n";
3472 Shared->SymbolKinds.clear();
3486 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3493 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3494 if (Iter != InlineeInfo.end()) {
3495 LineNumber = Iter->second.first;
3504 dbgs() <<
"inlineSiteAnnotation\n"
3505 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n"
3506 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n"
3507 <<
"Parent: " << Parent->
getName() <<
"\n"
3508 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3512 if (!
options().getPrintLines())
3519 int32_t LineOffset = LineNumber;
3523 auto UpdateCodeOffset = [&](
uint32_t Delta) {
3530 auto UpdateLineOffset = [&](int32_t Delta) {
3531 LineOffset += Delta;
3533 char Sign = Delta > 0 ?
'+' :
'-';
3534 dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3538 auto UpdateFileOffset = [&](int32_t
Offset) {
3544 auto CreateLine = [&]() {
3548 Line->setLineNumber(LineOffset);
3555 bool SeenLowAddress =
false;
3556 bool SeenHighAddress =
false;
3560 for (
auto &Annot :
InlineSite.annotations()) {
3567 switch (Annot.OpCode) {
3571 UpdateCodeOffset(Annot.U1);
3576 SeenLowAddress =
true;
3581 SeenHighAddress =
true;
3585 UpdateCodeOffset(Annot.U2);
3590 UpdateCodeOffset(Annot.U1);
3591 UpdateLineOffset(Annot.S1);
3598 UpdateFileOffset(Annot.U1);
3604 if (SeenLowAddress && SeenHighAddress) {
3605 SeenLowAddress =
false;
3606 SeenHighAddress =
false;
3607 InlinedFunction->
addObject(LowPC, HighPC);
3611 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
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)
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.