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();
462 return get(Components);
466#define DEBUG_TYPE "CodeViewTypeVisitor"
471void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
472 uint32_t StreamIdx)
const {
487 if (
options().getInternalTag())
488 Shared->TypeKinds.insert(
Record.kind());
492 CurrentTypeIndex = TI;
493 Shared->TypeRecords.add(StreamIdx, TI,
Record.kind());
505 W.getOStream() <<
" {\n";
514 W.startLine() <<
"}\n";
528 W.printNumber(
"NumArgs",
static_cast<uint32_t>(Args.getArgs().size()));
542 String = Ids.getTypeName(TI);
544 Shared->StringRecords.add(TI,
String);
548 String = Ids.getTypeName(TI);
550 Shared->StringRecords.add(TI,
String);
551 LogicalVisitor->setCompileUnitName(std::string(
String));
561 W.printString(
"Name",
Class.getName());
565 Shared->NamespaceDeduction.add(
Class.getName());
566 Shared->ForwardReferences.record(
Class.isForwardRef(),
Class.getName(),
570 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Class.getName());
579 W.printString(
"Name",
Enum.getName());
583 Shared->NamespaceDeduction.add(
Enum.getName());
593 W.printString(
"Name", Func.getName());
597 Shared->NamespaceDeduction.add(Func.getName());
611 Shared->TypeRecords.add(
StreamTPI, CurrentTypeIndex, {});
620 W.printString(
"StringData",
String.getString());
632 W.printNumber(
"LineNumber",
Line.getLineNumber());
635 Shared->LineRecords.push_back(CurrentTypeIndex);
642 W.printNumber(
"MemberCount",
Union.getMemberCount());
644 W.printNumber(
"SizeOf",
Union.getSize());
645 W.printString(
"Name",
Union.getName());
646 if (
Union.hasUniqueName())
647 W.printString(
"UniqueName",
Union.getUniqueName());
651 Shared->NamespaceDeduction.add(
Union.getName());
652 Shared->ForwardReferences.record(
Union.isForwardRef(),
Union.getName(),
656 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Union.getName());
661#define DEBUG_TYPE "CodeViewSymbolVisitor"
670 Reader->printRelocatedField(
Label, CoffSection, RelocOffset,
Offset,
677 Reader->getLinkageName(CoffSection, RelocOffset,
Offset, RelocSym);
691 return Reader->CVStringTable;
694void LVSymbolVisitor::printLocalVariableAddrRange(
696 DictScope S(W,
"LocalVariableAddrRange");
698 ObjDelegate->printRelocatedField(
"OffsetStart", RelocationOffset,
700 W.printHex(
"ISectStart",
Range.ISectStart);
701 W.printHex(
"Range",
Range.Range);
704void LVSymbolVisitor::printLocalVariableAddrGap(
708 W.printHex(
"GapStartOffset", Gap.GapStartOffset);
709 W.printHex(
"Range", Gap.Range);
713void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI)
const {
724 W.printNumber(
"Offset",
Offset);
728 if (
options().getInternalTag())
729 Shared->SymbolKinds.insert(
Kind);
731 LogicalVisitor->CurrentElement = LogicalVisitor->createElement(
Kind);
732 if (!LogicalVisitor->CurrentElement) {
742 IsCompileUnit =
false;
743 if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())
744 LogicalVisitor->CurrentElement->setOffset(
Offset);
746 assert(LogicalVisitor->CurrentScope &&
"Invalid scope!");
747 LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);
749 if (LogicalVisitor->CurrentSymbol)
750 LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);
751 if (LogicalVisitor->CurrentType)
752 LogicalVisitor->addElement(LogicalVisitor->CurrentType);
764 LogicalVisitor->popScope();
778 W.printHex(
"CodeSize",
Block.CodeSize);
779 W.printHex(
"Segment",
Block.Segment);
780 W.printString(
"BlockName",
Block.Name);
783 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
786 ObjDelegate->getLinkageName(
Block.getRelocationOffset(),
Block.CodeOffset,
790 if (
options().getGeneralCollectRanges()) {
794 Reader->linearAddress(
Block.Segment,
Block.CodeOffset, Addendum);
796 Scope->addObject(LowPC, HighPC);
808 W.printNumber(
"Offset",
Local.Offset);
809 W.printString(
"VarName",
Local.Name);
812 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
813 Symbol->setName(
Local.Name);
821 Symbol->resetIsVariable();
823 if (
Local.Name ==
"this") {
824 Symbol->setIsParameter();
825 Symbol->setIsArtificial();
828 bool(
Local.Offset > 0) ? Symbol->setIsParameter()
829 : Symbol->setIsVariable();
833 if (Symbol->getIsParameter())
834 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
836 setLocalVariableType(Symbol,
Local.Type);
847 W.printNumber(
"Offset",
Local.Offset);
848 W.printString(
"VarName",
Local.Name);
851 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
852 Symbol->setName(
Local.Name);
855 Symbol->resetIsVariable();
858 if (
Local.Name ==
"this") {
859 Symbol->setIsArtificial();
860 Symbol->setIsParameter();
863 determineSymbolKind(Symbol,
Local.Register);
867 if (Symbol->getIsParameter())
868 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
870 setLocalVariableType(Symbol,
Local.Type);
881 W.printNumber(
"Offset",
Local.Offset);
882 W.printNumber(
"OffsetInUdt",
Local.OffsetInUdt);
883 W.printString(
"VarName",
Local.Name);
886 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
887 Symbol->setName(
Local.Name);
890 Symbol->resetIsVariable();
893 if (
Local.Name ==
"this") {
894 Symbol->setIsArtificial();
895 Symbol->setIsParameter();
898 determineSymbolKind(Symbol,
Local.Register);
902 if (Symbol->getIsParameter())
903 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
905 setLocalVariableType(Symbol,
Local.Type);
917 if (
Error Err = LogicalVisitor->finishVisitation(
918 CVBuildType, BuildInfo.
BuildId, Reader->getCompileUnit()))
933 W.printString(
"VersionName", Compile2.
Version);
948 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
950 Reader->setCompileUnitCPUType(Compile2.
Machine);
951 Scope->setName(CurrentObjectName);
952 if (
options().getAttributeProducer())
953 Scope->setProducer(Compile2.
Version);
954 if (
options().getAttributeLanguage())
961 Reader->addModule(Scope);
964 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
968 CurrentObjectName =
"";
981 W.printString(
"VersionName", Compile3.
Version);
996 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
998 Reader->setCompileUnitCPUType(Compile3.
Machine);
999 Scope->setName(CurrentObjectName);
1000 if (
options().getAttributeProducer())
1001 Scope->setProducer(Compile3.
Version);
1002 if (
options().getAttributeLanguage())
1009 Reader->addModule(Scope);
1012 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
1016 CurrentObjectName =
"";
1026 W.printString(
"Name",
Constant.Name);
1029 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1032 Symbol->resetIncludeInPrint();
1045 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1047 W.printNumber(
"Offset", DefRangeFramePointerRelFullScope.
Offset);
1050 if (
LVSymbol *Symbol = LocalSymbol) {
1051 Symbol->setHasCodeViewLocation();
1052 LocalSymbol =
nullptr;
1059 Symbol->addLocation(Attr, 0, 0, 0, 0);
1060 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1072 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1074 W.printNumber(
"Offset", DefRangeFramePointerRel.
Hdr.
Offset);
1075 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
1077 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
1084 if (
LVSymbol *Symbol = LocalSymbol) {
1085 Symbol->setHasCodeViewLocation();
1086 LocalSymbol =
nullptr;
1095 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1098 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1110 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1112 W.printBoolean(
"HasSpilledUDTMember",
1114 W.printNumber(
"OffsetInParent", DefRangeRegisterRel.
offsetInParent());
1115 W.printNumber(
"BasePointerOffset",
1117 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
1119 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
1122 if (
LVSymbol *Symbol = LocalSymbol) {
1123 Symbol->setHasCodeViewLocation();
1124 LocalSymbol =
nullptr;
1134 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1137 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2});
1149 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1151 W.printBoolean(
"HasSpilledUDTMember",
1153 W.printNumber(
"OffsetInParent", DefRangeRegisterRelIndir.
offsetInParent());
1154 W.printNumber(
"BasePointerOffset",
1156 W.printNumber(
"OffsetInUdt", DefRangeRegisterRelIndir.
Hdr.
OffsetInUdt);
1157 printLocalVariableAddrRange(DefRangeRegisterRelIndir.
Range,
1159 printLocalVariableAddrGap(DefRangeRegisterRelIndir.
Gaps);
1162 if (
LVSymbol *Symbol = LocalSymbol) {
1163 Symbol->setHasCodeViewLocation();
1164 LocalSymbol =
nullptr;
1175 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1178 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2, Operand3});
1190 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1195 printLocalVariableAddrRange(DefRangeRegister.
Range,
1197 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1200 if (
LVSymbol *Symbol = LocalSymbol) {
1201 Symbol->setHasCodeViewLocation();
1202 LocalSymbol =
nullptr;
1210 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1213 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1225 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1229 W.printNumber(
"MayHaveNoName", DefRangeSubfieldRegister.
Hdr.
MayHaveNoName);
1230 W.printNumber(
"OffsetInParent",
1232 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1234 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1237 if (
LVSymbol *Symbol = LocalSymbol) {
1238 Symbol->setHasCodeViewLocation();
1239 LocalSymbol =
nullptr;
1248 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1251 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1263 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1268 if (!ExpectedProgram) {
1271 "String table offset outside of bounds of String Table!");
1273 W.printString(
"Program", *ExpectedProgram);
1275 W.printNumber(
"OffsetInParent", DefRangeSubfield.
OffsetInParent);
1276 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1278 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
1281 if (
LVSymbol *Symbol = LocalSymbol) {
1282 Symbol->setHasCodeViewLocation();
1283 LocalSymbol =
nullptr;
1291 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1294 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1306 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1311 if (!ExpectedProgram) {
1314 "String table offset outside of bounds of String Table!");
1316 W.printString(
"Program", *ExpectedProgram);
1319 printLocalVariableAddrGap(DefRange.
Gaps);
1322 if (
LVSymbol *Symbol = LocalSymbol) {
1323 Symbol->setHasCodeViewLocation();
1324 LocalSymbol =
nullptr;
1332 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1335 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1378 W.printString(
"DisplayName",
Data.Name);
1381 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1384 ObjDelegate->getLinkageName(
Data.getRelocationOffset(),
Data.DataOffset,
1387 Symbol->setName(
Data.Name);
1396 if (
getReader().isSystemEntry(Symbol) && !
options().getAttributeSystem()) {
1397 Symbol->resetIncludeInPrint();
1401 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Data.Name)) {
1404 if (Symbol->getParentScope()->removeElement(Symbol))
1405 Namespace->addElement(Symbol);
1408 Symbol->setType(LogicalVisitor->getElement(
StreamTPI,
Data.Type));
1409 if (
Record.kind() == SymbolKind::S_GDATA32)
1410 Symbol->setIsExternal();
1421 if (
LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1422 LVScope *AbstractFunction = Reader->createScopeFunction();
1423 AbstractFunction->setIsSubprogram();
1424 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1426 AbstractFunction->setIsInlinedAbstract();
1429 LogicalVisitor->startProcessArgumentList();
1432 if (
Error Err = LogicalVisitor->finishVisitation(
1433 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1435 LogicalVisitor->stopProcessArgumentList();
1440 InlinedFunction->setName(
Name);
1441 InlinedFunction->setLinkageName(
Name);
1444 if (
Error Err = LogicalVisitor->inlineSiteAnnotation(
1445 AbstractFunction, InlinedFunction,
InlineSite))
1457 W.printString(
"VarName",
Local.Name);
1460 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1461 Symbol->setName(
Local.Name);
1464 Symbol->resetIsVariable();
1468 Local.Name ==
"this") {
1469 Symbol->setIsArtificial();
1470 Symbol->setIsParameter();
1473 : Symbol->setIsVariable();
1477 if (Symbol->getIsParameter())
1478 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1480 setLocalVariableType(Symbol,
Local.Type);
1485 LocalSymbol = Symbol;
1494 W.printHex(
"Signature", ObjName.
Signature);
1495 W.printString(
"ObjectName", ObjName.
Name);
1498 CurrentObjectName = ObjName.
Name;
1504 if (InFunctionScope)
1508 InFunctionScope =
true;
1512 W.printHex(
"Segment", Proc.
Segment);
1513 W.printFlags(
"Flags",
static_cast<uint8_t>(Proc.
Flags),
1515 W.printString(
"DisplayName", Proc.
Name);
1564 if (
options().getGeneralCollectRanges()) {
1570 Function->addObject(LowPC, HighPC);
1573 if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1575 Reader->getCompileUnit()->addPublicName(
Function, LowPC, HighPC);
1596 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
1598 std::optional<CVType> CVFunctionType;
1599 auto GetRecordType = [&]() ->
bool {
1600 CVFunctionType = Ids.tryGetType(TIFunctionType);
1601 if (!CVFunctionType)
1606 if (CVFunctionType->kind() == LF_FUNC_ID)
1610 return (CVFunctionType->kind() == LF_MFUNC_ID);
1614 if (!GetRecordType()) {
1615 CVFunctionType = Types.tryGetType(TIFunctionType);
1616 if (!CVFunctionType)
1620 if (
Error Err = LogicalVisitor->finishVisitation(
1621 *CVFunctionType, TIFunctionType,
Function))
1625 if (
Record.kind() == SymbolKind::S_GPROC32 ||
1626 Record.kind() == SymbolKind::S_GPROC32_ID)
1632 if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1637 if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1649 InFunctionScope =
false;
1655 if (InFunctionScope)
1659 InFunctionScope =
true;
1662 W.printHex(
"Segment",
Thunk.Segment);
1663 W.printString(
"Name",
Thunk.Name);
1676 W.printString(
"UDTName",
UDT.Name);
1679 if (
LVType *
Type = LogicalVisitor->CurrentType) {
1680 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
UDT.Name)) {
1681 if (
Type->getParentScope()->removeElement(
Type))
1682 Namespace->addElement(
Type);
1695 Type->resetIncludeInPrint();
1698 if (
UDT.Name == RecordName)
1699 Type->resetIncludeInPrint();
1718 W.printHex(
"BaseOffset",
JumpTable.BaseOffset);
1719 W.printNumber(
"BaseSegment",
JumpTable.BaseSegment);
1722 W.printHex(
"BranchOffset",
JumpTable.BranchOffset);
1723 W.printHex(
"TableOffset",
JumpTable.TableOffset);
1724 W.printNumber(
"BranchSegment",
JumpTable.BranchSegment);
1725 W.printNumber(
"TableSegment",
JumpTable.TableSegment);
1726 W.printNumber(
"EntriesCount",
JumpTable.EntriesCount);
1735 switch (
Caller.getKind()) {
1736 case SymbolRecordKind::CallerSym:
1737 FieldName =
"Callee";
1739 case SymbolRecordKind::CalleeSym:
1740 FieldName =
"Caller";
1742 case SymbolRecordKind::InlineesSym:
1743 FieldName =
"Inlinee";
1747 "Unknown CV Record type for a CallerSym object!");
1749 for (
auto FuncID :
Caller.Indices) {
1758 if (Element && Element->getIsScoped()) {
1777#define DEBUG_TYPE "CodeViewLogicalVisitor"
1784 : Reader(Reader), W(W), Input(Input) {
1787 Shared = std::make_shared<LVShared>(Reader,
this);
1793 StreamIdx ==
StreamTPI ? types() : ids());
1798 W.getOStream() <<
"\n";
1801 W.getOStream() <<
" {\n";
1806 << Element->
getName() <<
"\n";
1811 W.startLine() <<
"}\n";
1817 W.getOStream() <<
"\n";
1820 W.getOStream() <<
" {\n";
1825 << Element->
getName() <<
"\n";
1830 W.startLine() <<
"}\n";
1848 W.printNumber(
"NumArgs",
Size);
1857 TypeIndex ParameterType = Indices[Index];
1871 W.printNumber(
"SizeOf", AT.
getSize());
1872 W.printString(
"Name", AT.
getName());
1876 if (Element->getIsFinalized())
1878 Element->setIsFinalized();
1884 Reader->getCompileUnit()->addElement(Array);
1887 LVType *PrevSubrange =
nullptr;
1895 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1920 while (CVEntry.
kind() == LF_ARRAY) {
1931 AddSubrangeType(AR);
1932 TIArrayType = TIElementType;
1938 CVType CVElementType =
Types.getType(TIElementType);
1939 if (CVElementType.
kind() == LF_MODIFIER) {
1941 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1954 CVEntry =
Types.getType(TIElementType);
1956 const_cast<CVType &
>(CVEntry), AR)) {
1966 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
2027 W.printNumber(
"MemberCount",
Class.getMemberCount());
2031 W.printNumber(
"SizeOf",
Class.getSize());
2032 W.printString(
"Name",
Class.getName());
2033 if (
Class.hasUniqueName())
2034 W.printString(
"UniqueName",
Class.getUniqueName());
2038 if (Element->getIsFinalized())
2040 Element->setIsFinalized();
2046 Scope->setName(
Class.getName());
2047 if (
Class.hasUniqueName())
2048 Scope->setLinkageName(
Class.getUniqueName());
2051 if (
Class.isNested()) {
2052 Scope->setIsNested();
2053 createParents(
Class.getName(), Scope);
2056 if (
Class.isScoped())
2057 Scope->setIsScoped();
2061 if (!(
Class.isNested() ||
Class.isScoped())) {
2062 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2063 Namespace->addElement(Scope);
2065 Reader->getCompileUnit()->addElement(Scope);
2071 TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2077 const_cast<CVType &
>(CVReference), ReferenceRecord))
2098 W.printNumber(
"NumEnumerators",
Enum.getMemberCount());
2101 W.printString(
"Name",
Enum.getName());
2109 if (Scope->getIsFinalized())
2111 Scope->setIsFinalized();
2115 Scope->setName(
Enum.getName());
2116 if (
Enum.hasUniqueName())
2117 Scope->setLinkageName(
Enum.getUniqueName());
2121 if (
Enum.isNested()) {
2122 Scope->setIsNested();
2123 createParents(
Enum.getName(), Scope);
2126 if (
Enum.isScoped()) {
2127 Scope->setIsScoped();
2128 Scope->setIsEnumClass();
2132 if (!(
Enum.isNested() ||
Enum.isScoped())) {
2133 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2134 Namespace->addElement(Scope);
2136 Reader->getCompileUnit()->addElement(Scope);
2159 if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2173 W.printString(
"Name", Func.getName());
2185 TypeIndex TIParent = Func.getParentScope();
2186 if (FunctionDcl->getIsInlinedAbstract()) {
2187 FunctionDcl->setName(Func.getName());
2189 Reader->getCompileUnit()->addElement(FunctionDcl);
2193 CVType CVParentScope = ids().getType(TIParent);
2198 TypeIndex TIFunctionType = Func.getFunctionType();
2199 CVType CVFunctionType =
Types.getType(TIFunctionType);
2204 FunctionDcl->setIsFinalized();
2228 W.printString(
"Name", Id.getName());
2233 if (FunctionDcl->getIsInlinedAbstract()) {
2239 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2240 Class->addElement(FunctionDcl);
2243 TypeIndex TIFunctionType = Id.getFunctionType();
2244 CVType CVFunction = types().getType(TIFunctionType);
2269 MemberFunction->setIsFinalized();
2271 MemberFunction->setOffset(TI.
getIndex());
2272 MemberFunction->setOffsetFromTypeIndex();
2274 if (ProcessArgumentList) {
2275 ProcessArgumentList =
false;
2277 if (!MemberFunction->getIsStatic()) {
2282 createParameter(ThisPointer,
StringRef(), MemberFunction);
2283 This->setIsArtificial();
2310 Method.Name = OverloadedMethodName;
2342 bool SeenModifier =
false;
2345 SeenModifier =
true;
2346 LastLink->
setTag(dwarf::DW_TAG_const_type);
2347 LastLink->setIsConst();
2358 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2359 LastLink->setIsVolatile();
2360 LastLink->
setName(
"volatile");
2371 LastLink->setIsUnaligned();
2372 LastLink->
setName(
"unaligned");
2375 LastLink->
setType(ModifiedType);
2385 W.printNumber(
"IsFlat", Ptr.
isFlat());
2386 W.printNumber(
"IsConst", Ptr.
isConst());
2387 W.printNumber(
"IsVolatile", Ptr.
isVolatile());
2389 W.printNumber(
"IsRestrict", Ptr.
isRestrict());
2392 W.printNumber(
"SizeOf", Ptr.
getSize());
2417 bool SeenModifier =
false;
2423 SeenModifier =
true;
2425 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2434 LVType *LReference = Reader->createType();
2435 LReference->setIsModifier();
2436 LastLink->
setType(LReference);
2437 LastLink = LReference;
2440 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2441 LastLink->setIsReference();
2446 LVType *RReference = Reader->createType();
2447 RReference->setIsModifier();
2448 LastLink->
setType(RReference);
2449 LastLink = RReference;
2452 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2453 LastLink->setIsRvalueReference();
2479 if (ProcessArgumentList) {
2480 ProcessArgumentList =
false;
2498 W.printNumber(
"MemberCount",
Union.getMemberCount());
2500 W.printNumber(
"SizeOf",
Union.getSize());
2501 W.printString(
"Name",
Union.getName());
2502 if (
Union.hasUniqueName())
2503 W.printString(
"UniqueName",
Union.getUniqueName());
2511 if (Scope->getIsFinalized())
2513 Scope->setIsFinalized();
2515 Scope->setName(
Union.getName());
2516 if (
Union.hasUniqueName())
2517 Scope->setLinkageName(
Union.getUniqueName());
2520 if (
Union.isNested()) {
2521 Scope->setIsNested();
2522 createParents(
Union.getName(), Scope);
2524 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2525 Namespace->addElement(Scope);
2527 Reader->getCompileUnit()->addElement(Scope);
2530 if (!
Union.getFieldList().isNoneType()) {
2547 W.printNumber(
"Age", TS.
getAge());
2548 W.printString(
"Name", TS.
getName());
2562 W.printString(
"VFTableName", VFT.
getName());
2564 W.printString(
"MethodName",
N);
2591 W.printNumber(
"NumStrings",
Size);
2607 W.printString(
"StringData",
String.getString());
2610 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2611 String.getString(),
false)) {
2615 Scope->removeElement(Element);
2616 Namespace->addElement(Element);
2647 W.printNumber(
"Module", ModSourceLine.
getModule());
2692 W.printHex(
"BaseOffset",
Base.getBaseOffset());
2701 Symbol->setAccessibilityCode(
Base.getAccess());
2715 W.printHex(
"FieldOffset",
Field.getFieldOffset());
2716 W.printString(
"Name",
Field.getName());
2732 W.printNumber(
"EnumValue",
Enum.getValue());
2733 W.printString(
"Name",
Enum.getName());
2741 Enum.getValue().toString(
Value, 16,
true,
true);
2768 W.printString(
"Name",
Nested.getName());
2779 if (NestedType && NestedType->getIsNested()) {
2785 if (NestedTypeName.
size() && RecordName.
size()) {
2787 std::tie(OuterComponent, std::ignore) =
2791 if (OuterComponent.
size() && OuterComponent == RecordName) {
2792 if (!NestedType->getIsScopedAlready()) {
2793 Scope->addElement(NestedType);
2794 NestedType->setIsScopedAlready();
2797 Typedef->resetIncludeInPrint();
2814 if (Method.isIntroducingVirtual())
2815 W.printHex(
"VFTableOffset", Method.getVFTableOffset());
2816 W.printString(
"Name", Method.getName());
2823 ProcessArgumentList =
true;
2825 MemberFunction->setIsFinalized();
2828 MemberFunction->
setName(Method.getName());
2829 MemberFunction->setAccessibilityCode(Method.getAccess());
2833 MemberFunction->setIsStatic();
2834 MemberFunction->setVirtualityCode(
Kind);
2839 MemberFunction->setIsArtificial();
2842 CVType CVMethodType =
Types.getType(Method.getType());
2847 ProcessArgumentList =
false;
2858 W.printHex(
"MethodCount", Method.getNumOverloads());
2860 W.printString(
"Name", Method.getName());
2867 OverloadedMethodName = Method.getName();
2868 CVType CVMethods =
Types.getType(Method.getMethodList());
2882 W.printString(
"Name",
Field.getName());
2912 W.printHex(
"VBPtrOffset",
Base.getVBPtrOffset());
2913 W.printHex(
"VBTableIndex",
Base.getVTableIndex());
2922 Symbol->setAccessibilityCode(
Base.getAccess());
2941#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2944 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2948#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2949 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2950#define TYPE_RECORD(EnumName, EnumVal, Name)
2951#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2952#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2968#define TYPE_RECORD(EnumName, EnumVal, Name) \
2970 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2974#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2975 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2976#define MEMBER_RECORD(EnumName, EnumVal, Name)
2977#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2978#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2985Error LVLogicalVisitor::visitFieldListMemberStream(
2994 while (!Reader.empty()) {
2995 if (
Error Err = Reader.readEnum(Leaf))
3013 if (!ScopeStack.empty())
3015 InCompileUnitScope =
true;
3019 ReaderParent->addElement(Scope);
3023 ReaderScope->addElement(Symbol);
3027 ReaderScope->addElement(
Type);
3039 if (
options().getAttributeBase())
3046 case TypeLeafKind::LF_ENUMERATE:
3050 case TypeLeafKind::LF_MODIFIER:
3054 case TypeLeafKind::LF_POINTER:
3062 case TypeLeafKind::LF_BCLASS:
3063 case TypeLeafKind::LF_IVBCLASS:
3064 case TypeLeafKind::LF_VBCLASS:
3069 case TypeLeafKind::LF_MEMBER:
3070 case TypeLeafKind::LF_STMEMBER:
3077 case TypeLeafKind::LF_ARRAY:
3081 case TypeLeafKind::LF_CLASS:
3086 case TypeLeafKind::LF_ENUM:
3090 case TypeLeafKind::LF_METHOD:
3091 case TypeLeafKind::LF_ONEMETHOD:
3092 case TypeLeafKind::LF_PROCEDURE:
3097 case TypeLeafKind::LF_STRUCTURE:
3102 case TypeLeafKind::LF_UNION:
3121 case SymbolKind::S_UDT:
3127 case SymbolKind::S_CONSTANT:
3133 case SymbolKind::S_BPREL32:
3134 case SymbolKind::S_REGREL32:
3135 case SymbolKind::S_REGREL32_INDIR:
3136 case SymbolKind::S_GDATA32:
3137 case SymbolKind::S_LDATA32:
3138 case SymbolKind::S_LOCAL:
3148 case SymbolKind::S_BLOCK32:
3153 case SymbolKind::S_COMPILE2:
3154 case SymbolKind::S_COMPILE3:
3159 case SymbolKind::S_INLINESITE:
3160 case SymbolKind::S_INLINESITE2:
3163 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3165 case SymbolKind::S_LPROC32:
3166 case SymbolKind::S_GPROC32:
3167 case SymbolKind::S_LPROC32_ID:
3168 case SymbolKind::S_GPROC32_ID:
3169 case SymbolKind::S_SEPCODE:
3170 case SymbolKind::S_THUNK32:
3190 Element->setIsFinalized();
3200 Element->setOffsetFromTypeIndex();
3204 W.printString(
"** Not implemented. **");
3211 Element->setOffsetFromTypeIndex();
3225 Symbol->setName(
Name);
3230 CVType CVMemberType = Types.getType(TI);
3231 if (CVMemberType.
kind() == LF_BITFIELD) {
3246 LVSymbol *
Parameter = Reader->createSymbol();
3249 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3260LVType *LVLogicalVisitor::createBaseType(
TypeIndex TI, StringRef TypeName) {
3262 TypeIndex TIR = (TypeIndex)SimpleKind;
3265 W.printString(
"TypeName", TypeName);
3268 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TIR))
3269 return static_cast<LVType *
>(Element);
3274 Reader->getCompileUnit()->addElement(
CurrentType);
3279LVType *LVLogicalVisitor::createPointerType(
TypeIndex TI, StringRef TypeName) {
3282 W.printString(
"TypeName", TypeName);
3285 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TI))
3286 return static_cast<LVType *
>(Element);
3288 LVType *Pointee = createBaseType(TI,
TypeName.drop_back(1));
3292 Reader->getCompileUnit()->addElement(
CurrentType);
3297void LVLogicalVisitor::createParents(StringRef ScopedName,
LVElement *Element) {
3317 if (Components.size() < 2)
3319 Components.pop_back();
3321 LVStringRefs::size_type FirstNamespace;
3322 LVStringRefs::size_type FirstAggregate;
3323 std::tie(FirstNamespace, FirstAggregate) =
3324 Shared->NamespaceDeduction.find(Components);
3327 W.printString(
"First Namespace", Components[FirstNamespace]);
3328 W.printString(
"First NonNamespace", Components[FirstAggregate]);
3332 if (FirstNamespace < FirstAggregate) {
3333 Shared->NamespaceDeduction.get(
3335 Components.begin() + FirstAggregate));
3341 LVScope *Aggregate =
nullptr;
3342 TypeIndex TIAggregate;
3344 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3347 for (LVStringRefs::size_type Index = FirstAggregate;
3350 Components.begin() + Index + 1),
3352 TIAggregate = Shared->ForwardReferences.remap(
3353 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3363 if (Aggregate && !Element->getIsScopedAlready()) {
3365 Element->setIsScopedAlready();
3372 TI = Shared->ForwardReferences.remap(TI);
3375 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3383 return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3384 : createBaseType(TI, TypeName);
3392 if (Element->getIsFinalized())
3406 Element->setIsFinalized();
3413 for (
const TypeIndex &Entry : Shared->LineRecords) {
3423 W.printNumber(
"LineNumber",
Line.getLineNumber());
3429 if (
LVElement *Element = Shared->TypeRecords.find(
3433 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3441 Shared->NamespaceDeduction.init();
3447 if (!
options().getInternalTag())
3452 auto NewLine = [&]() {
3465 Shared->TypeKinds.clear();
3468 OS <<
"\nSymbols:\n";
3471 Shared->SymbolKinds.clear();
3485 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3492 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3493 if (Iter != InlineeInfo.end()) {
3494 LineNumber = Iter->second.first;
3503 dbgs() <<
"inlineSiteAnnotation\n"
3504 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n"
3505 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n"
3506 <<
"Parent: " << Parent->
getName() <<
"\n"
3507 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3511 if (!
options().getPrintLines())
3518 int32_t LineOffset = LineNumber;
3522 auto UpdateCodeOffset = [&](
uint32_t Delta) {
3529 auto UpdateLineOffset = [&](int32_t Delta) {
3530 LineOffset += Delta;
3532 char Sign = Delta > 0 ?
'+' :
'-';
3533 dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3537 auto UpdateFileOffset = [&](int32_t
Offset) {
3543 auto CreateLine = [&]() {
3547 Line->setLineNumber(LineOffset);
3554 bool SeenLowAddress =
false;
3555 bool SeenHighAddress =
false;
3559 for (
auto &Annot :
InlineSite.annotations()) {
3566 switch (Annot.OpCode) {
3570 UpdateCodeOffset(Annot.U1);
3575 SeenLowAddress =
true;
3580 SeenHighAddress =
true;
3584 UpdateCodeOffset(Annot.U2);
3589 UpdateCodeOffset(Annot.U1);
3590 UpdateLineOffset(Annot.S1);
3597 UpdateFileOffset(Annot.U1);
3603 if (SeenLowAddress && SeenHighAddress) {
3604 SeenLowAddress =
false;
3605 SeenHighAddress =
false;
3606 InlinedFunction->
addObject(LowPC, HighPC);
3610 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.
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
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.