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);
838 if (Element && Element->getIsScoped()) {
864 W.printNumber(
"Offset",
Local.Offset);
865 W.printString(
"VarName",
Local.Name);
868 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
869 Symbol->setName(
Local.Name);
872 Symbol->resetIsVariable();
875 if (
Local.Name ==
"this") {
876 Symbol->setIsArtificial();
877 Symbol->setIsParameter();
880 determineSymbolKind(Symbol,
Local.Register);
884 if (Symbol->getIsParameter())
885 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
888 if (Element && Element->getIsScoped()) {
915 if (
Error Err = LogicalVisitor->finishVisitation(
916 CVBuildType, BuildInfo.
BuildId, Reader->getCompileUnit()))
931 W.printString(
"VersionName", Compile2.
Version);
946 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
948 Reader->setCompileUnitCPUType(Compile2.
Machine);
949 Scope->setName(CurrentObjectName);
950 if (
options().getAttributeProducer())
951 Scope->setProducer(Compile2.
Version);
952 if (
options().getAttributeLanguage())
959 Reader->addModule(Scope);
962 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
966 CurrentObjectName =
"";
979 W.printString(
"VersionName", Compile3.
Version);
994 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
996 Reader->setCompileUnitCPUType(Compile3.
Machine);
997 Scope->setName(CurrentObjectName);
998 if (
options().getAttributeProducer())
999 Scope->setProducer(Compile3.
Version);
1000 if (
options().getAttributeLanguage())
1007 Reader->addModule(Scope);
1010 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
1014 CurrentObjectName =
"";
1024 W.printString(
"Name",
Constant.Name);
1027 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1030 Symbol->resetIncludeInPrint();
1043 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1045 W.printNumber(
"Offset", DefRangeFramePointerRelFullScope.
Offset);
1048 if (
LVSymbol *Symbol = LocalSymbol) {
1049 Symbol->setHasCodeViewLocation();
1050 LocalSymbol =
nullptr;
1057 Symbol->addLocation(Attr, 0, 0, 0, 0);
1058 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1070 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1072 W.printNumber(
"Offset", DefRangeFramePointerRel.
Hdr.
Offset);
1073 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
1075 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
1082 if (
LVSymbol *Symbol = LocalSymbol) {
1083 Symbol->setHasCodeViewLocation();
1084 LocalSymbol =
nullptr;
1093 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1096 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1108 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1110 W.printBoolean(
"HasSpilledUDTMember",
1112 W.printNumber(
"OffsetInParent", DefRangeRegisterRel.
offsetInParent());
1113 W.printNumber(
"BasePointerOffset",
1115 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
1117 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
1120 if (
LVSymbol *Symbol = LocalSymbol) {
1121 Symbol->setHasCodeViewLocation();
1122 LocalSymbol =
nullptr;
1132 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1135 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2});
1147 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1152 printLocalVariableAddrRange(DefRangeRegister.
Range,
1154 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1157 if (
LVSymbol *Symbol = LocalSymbol) {
1158 Symbol->setHasCodeViewLocation();
1159 LocalSymbol =
nullptr;
1167 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1170 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1182 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1186 W.printNumber(
"MayHaveNoName", DefRangeSubfieldRegister.
Hdr.
MayHaveNoName);
1187 W.printNumber(
"OffsetInParent",
1189 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1191 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1194 if (
LVSymbol *Symbol = LocalSymbol) {
1195 Symbol->setHasCodeViewLocation();
1196 LocalSymbol =
nullptr;
1205 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1208 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1220 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1225 if (!ExpectedProgram) {
1228 "String table offset outside of bounds of String Table!");
1230 W.printString(
"Program", *ExpectedProgram);
1232 W.printNumber(
"OffsetInParent", DefRangeSubfield.
OffsetInParent);
1233 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1235 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
1238 if (
LVSymbol *Symbol = LocalSymbol) {
1239 Symbol->setHasCodeViewLocation();
1240 LocalSymbol =
nullptr;
1248 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1251 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
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);
1276 printLocalVariableAddrGap(DefRange.
Gaps);
1279 if (
LVSymbol *Symbol = LocalSymbol) {
1280 Symbol->setHasCodeViewLocation();
1281 LocalSymbol =
nullptr;
1289 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1292 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1335 W.printString(
"DisplayName",
Data.Name);
1338 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1341 ObjDelegate->getLinkageName(
Data.getRelocationOffset(),
Data.DataOffset,
1344 Symbol->setName(
Data.Name);
1353 if (
getReader().isSystemEntry(Symbol) && !
options().getAttributeSystem()) {
1354 Symbol->resetIncludeInPrint();
1358 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Data.Name)) {
1361 if (Symbol->getParentScope()->removeElement(Symbol))
1362 Namespace->addElement(Symbol);
1365 Symbol->setType(LogicalVisitor->getElement(
StreamTPI,
Data.Type));
1366 if (
Record.kind() == SymbolKind::S_GDATA32)
1367 Symbol->setIsExternal();
1378 if (
LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1379 LVScope *AbstractFunction = Reader->createScopeFunction();
1380 AbstractFunction->setIsSubprogram();
1381 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1383 AbstractFunction->setIsInlinedAbstract();
1386 LogicalVisitor->startProcessArgumentList();
1389 if (
Error Err = LogicalVisitor->finishVisitation(
1390 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1392 LogicalVisitor->stopProcessArgumentList();
1397 InlinedFunction->setName(
Name);
1398 InlinedFunction->setLinkageName(
Name);
1401 if (
Error Err = LogicalVisitor->inlineSiteAnnotation(
1402 AbstractFunction, InlinedFunction,
InlineSite))
1414 W.printString(
"VarName",
Local.Name);
1417 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1418 Symbol->setName(
Local.Name);
1421 Symbol->resetIsVariable();
1425 Local.Name ==
"this") {
1426 Symbol->setIsArtificial();
1427 Symbol->setIsParameter();
1430 : Symbol->setIsVariable();
1434 if (Symbol->getIsParameter())
1435 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1438 if (Element && Element->getIsScoped()) {
1452 LocalSymbol = Symbol;
1461 W.printHex(
"Signature", ObjName.
Signature);
1462 W.printString(
"ObjectName", ObjName.
Name);
1465 CurrentObjectName = ObjName.
Name;
1471 if (InFunctionScope)
1475 InFunctionScope =
true;
1479 W.printHex(
"Segment", Proc.
Segment);
1480 W.printFlags(
"Flags",
static_cast<uint8_t>(Proc.
Flags),
1482 W.printString(
"DisplayName", Proc.
Name);
1531 if (
options().getGeneralCollectRanges()) {
1537 Function->addObject(LowPC, HighPC);
1540 if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1542 Reader->getCompileUnit()->addPublicName(
Function, LowPC, HighPC);
1563 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
1565 std::optional<CVType> CVFunctionType;
1566 auto GetRecordType = [&]() ->
bool {
1567 CVFunctionType = Ids.tryGetType(TIFunctionType);
1568 if (!CVFunctionType)
1573 if (CVFunctionType->kind() == LF_FUNC_ID)
1577 return (CVFunctionType->kind() == LF_MFUNC_ID);
1581 if (!GetRecordType()) {
1582 CVFunctionType = Types.tryGetType(TIFunctionType);
1583 if (!CVFunctionType)
1587 if (
Error Err = LogicalVisitor->finishVisitation(
1588 *CVFunctionType, TIFunctionType,
Function))
1592 if (
Record.kind() == SymbolKind::S_GPROC32 ||
1593 Record.kind() == SymbolKind::S_GPROC32_ID)
1599 if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1604 if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1616 InFunctionScope =
false;
1622 if (InFunctionScope)
1626 InFunctionScope =
true;
1629 W.printHex(
"Segment",
Thunk.Segment);
1630 W.printString(
"Name",
Thunk.Name);
1643 W.printString(
"UDTName",
UDT.Name);
1646 if (
LVType *
Type = LogicalVisitor->CurrentType) {
1647 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
UDT.Name)) {
1648 if (
Type->getParentScope()->removeElement(
Type))
1649 Namespace->addElement(
Type);
1662 Type->resetIncludeInPrint();
1665 if (
UDT.Name == RecordName)
1666 Type->resetIncludeInPrint();
1685 W.printHex(
"BaseOffset",
JumpTable.BaseOffset);
1686 W.printNumber(
"BaseSegment",
JumpTable.BaseSegment);
1689 W.printHex(
"BranchOffset",
JumpTable.BranchOffset);
1690 W.printHex(
"TableOffset",
JumpTable.TableOffset);
1691 W.printNumber(
"BranchSegment",
JumpTable.BranchSegment);
1692 W.printNumber(
"TableSegment",
JumpTable.TableSegment);
1693 W.printNumber(
"EntriesCount",
JumpTable.EntriesCount);
1702 switch (
Caller.getKind()) {
1703 case SymbolRecordKind::CallerSym:
1704 FieldName =
"Callee";
1706 case SymbolRecordKind::CalleeSym:
1707 FieldName =
"Caller";
1709 case SymbolRecordKind::InlineesSym:
1710 FieldName =
"Inlinee";
1714 "Unknown CV Record type for a CallerSym object!");
1716 for (
auto FuncID :
Caller.Indices) {
1724#define DEBUG_TYPE "CodeViewLogicalVisitor"
1731 : Reader(Reader), W(W), Input(Input) {
1734 Shared = std::make_shared<LVShared>(Reader,
this);
1740 StreamIdx ==
StreamTPI ? types() : ids());
1745 W.getOStream() <<
"\n";
1748 W.getOStream() <<
" {\n";
1753 << Element->
getName() <<
"\n";
1758 W.startLine() <<
"}\n";
1764 W.getOStream() <<
"\n";
1767 W.getOStream() <<
" {\n";
1772 << Element->
getName() <<
"\n";
1777 W.startLine() <<
"}\n";
1795 W.printNumber(
"NumArgs",
Size);
1804 TypeIndex ParameterType = Indices[Index];
1818 W.printNumber(
"SizeOf", AT.
getSize());
1819 W.printString(
"Name", AT.
getName());
1823 if (Element->getIsFinalized())
1825 Element->setIsFinalized();
1831 Reader->getCompileUnit()->addElement(Array);
1834 LVType *PrevSubrange =
nullptr;
1842 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1867 while (CVEntry.
kind() == LF_ARRAY) {
1878 AddSubrangeType(AR);
1879 TIArrayType = TIElementType;
1885 CVType CVElementType =
Types.getType(TIElementType);
1886 if (CVElementType.
kind() == LF_MODIFIER) {
1888 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1901 CVEntry =
Types.getType(TIElementType);
1903 const_cast<CVType &
>(CVEntry), AR)) {
1913 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
1974 W.printNumber(
"MemberCount",
Class.getMemberCount());
1978 W.printNumber(
"SizeOf",
Class.getSize());
1979 W.printString(
"Name",
Class.getName());
1980 if (
Class.hasUniqueName())
1981 W.printString(
"UniqueName",
Class.getUniqueName());
1985 if (Element->getIsFinalized())
1987 Element->setIsFinalized();
1993 Scope->setName(
Class.getName());
1994 if (
Class.hasUniqueName())
1995 Scope->setLinkageName(
Class.getUniqueName());
1998 if (
Class.isNested()) {
1999 Scope->setIsNested();
2000 createParents(
Class.getName(), Scope);
2003 if (
Class.isScoped())
2004 Scope->setIsScoped();
2008 if (!(
Class.isNested() ||
Class.isScoped())) {
2009 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2010 Namespace->addElement(Scope);
2012 Reader->getCompileUnit()->addElement(Scope);
2018 TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2024 const_cast<CVType &
>(CVReference), ReferenceRecord))
2045 W.printNumber(
"NumEnumerators",
Enum.getMemberCount());
2048 W.printString(
"Name",
Enum.getName());
2056 if (Scope->getIsFinalized())
2058 Scope->setIsFinalized();
2062 Scope->setName(
Enum.getName());
2063 if (
Enum.hasUniqueName())
2064 Scope->setLinkageName(
Enum.getUniqueName());
2068 if (
Enum.isNested()) {
2069 Scope->setIsNested();
2070 createParents(
Enum.getName(), Scope);
2073 if (
Enum.isScoped()) {
2074 Scope->setIsScoped();
2075 Scope->setIsEnumClass();
2079 if (!(
Enum.isNested() ||
Enum.isScoped())) {
2080 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2081 Namespace->addElement(Scope);
2083 Reader->getCompileUnit()->addElement(Scope);
2106 if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2120 W.printString(
"Name", Func.getName());
2132 TypeIndex TIParent = Func.getParentScope();
2133 if (FunctionDcl->getIsInlinedAbstract()) {
2134 FunctionDcl->setName(Func.getName());
2136 Reader->getCompileUnit()->addElement(FunctionDcl);
2140 CVType CVParentScope = ids().getType(TIParent);
2145 TypeIndex TIFunctionType = Func.getFunctionType();
2146 CVType CVFunctionType =
Types.getType(TIFunctionType);
2151 FunctionDcl->setIsFinalized();
2175 W.printString(
"Name", Id.getName());
2180 if (FunctionDcl->getIsInlinedAbstract()) {
2186 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2187 Class->addElement(FunctionDcl);
2190 TypeIndex TIFunctionType = Id.getFunctionType();
2191 CVType CVFunction = types().getType(TIFunctionType);
2216 MemberFunction->setIsFinalized();
2218 MemberFunction->setOffset(TI.
getIndex());
2219 MemberFunction->setOffsetFromTypeIndex();
2221 if (ProcessArgumentList) {
2222 ProcessArgumentList =
false;
2224 if (!MemberFunction->getIsStatic()) {
2229 createParameter(ThisPointer,
StringRef(), MemberFunction);
2230 This->setIsArtificial();
2257 Method.Name = OverloadedMethodName;
2289 bool SeenModifier =
false;
2292 SeenModifier =
true;
2293 LastLink->
setTag(dwarf::DW_TAG_const_type);
2294 LastLink->setIsConst();
2305 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2306 LastLink->setIsVolatile();
2307 LastLink->
setName(
"volatile");
2318 LastLink->setIsUnaligned();
2319 LastLink->
setName(
"unaligned");
2322 LastLink->
setType(ModifiedType);
2332 W.printNumber(
"IsFlat",
Ptr.isFlat());
2333 W.printNumber(
"IsConst",
Ptr.isConst());
2334 W.printNumber(
"IsVolatile",
Ptr.isVolatile());
2335 W.printNumber(
"IsUnaligned",
Ptr.isUnaligned());
2336 W.printNumber(
"IsRestrict",
Ptr.isRestrict());
2337 W.printNumber(
"IsThisPtr&",
Ptr.isLValueReferenceThisPtr());
2338 W.printNumber(
"IsThisPtr&&",
Ptr.isRValueReferenceThisPtr());
2339 W.printNumber(
"SizeOf",
Ptr.getSize());
2341 if (
Ptr.isPointerToMember()) {
2353 Pointee =
Ptr.isPointerToMember()
2354 ? Shared->TypeRecords.find(
StreamTPI,
Ptr.getReferentType())
2364 bool SeenModifier =
false;
2369 if (
Ptr.isRestrict()) {
2370 SeenModifier =
true;
2372 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2381 LVType *LReference = Reader->createType();
2382 LReference->setIsModifier();
2383 LastLink->
setType(LReference);
2384 LastLink = LReference;
2387 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2388 LastLink->setIsReference();
2393 LVType *RReference = Reader->createType();
2394 RReference->setIsModifier();
2395 LastLink->
setType(RReference);
2396 LastLink = RReference;
2399 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2400 LastLink->setIsRvalueReference();
2426 if (ProcessArgumentList) {
2427 ProcessArgumentList =
false;
2445 W.printNumber(
"MemberCount",
Union.getMemberCount());
2447 W.printNumber(
"SizeOf",
Union.getSize());
2448 W.printString(
"Name",
Union.getName());
2449 if (
Union.hasUniqueName())
2450 W.printString(
"UniqueName",
Union.getUniqueName());
2458 if (Scope->getIsFinalized())
2460 Scope->setIsFinalized();
2462 Scope->setName(
Union.getName());
2463 if (
Union.hasUniqueName())
2464 Scope->setLinkageName(
Union.getUniqueName());
2467 if (
Union.isNested()) {
2468 Scope->setIsNested();
2469 createParents(
Union.getName(), Scope);
2471 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2472 Namespace->addElement(Scope);
2474 Reader->getCompileUnit()->addElement(Scope);
2477 if (!
Union.getFieldList().isNoneType()) {
2494 W.printNumber(
"Age", TS.
getAge());
2495 W.printString(
"Name", TS.
getName());
2509 W.printString(
"VFTableName", VFT.
getName());
2511 W.printString(
"MethodName",
N);
2538 W.printNumber(
"NumStrings",
Size);
2554 W.printString(
"StringData",
String.getString());
2557 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2558 String.getString(),
false)) {
2562 Scope->removeElement(Element);
2563 Namespace->addElement(Element);
2594 W.printNumber(
"Module", ModSourceLine.
getModule());
2639 W.printHex(
"BaseOffset",
Base.getBaseOffset());
2648 Symbol->setAccessibilityCode(
Base.getAccess());
2662 W.printHex(
"FieldOffset",
Field.getFieldOffset());
2663 W.printString(
"Name",
Field.getName());
2679 W.printNumber(
"EnumValue",
Enum.getValue());
2680 W.printString(
"Name",
Enum.getName());
2688 Enum.getValue().toString(
Value, 16,
true,
true);
2715 W.printString(
"Name",
Nested.getName());
2726 if (NestedType && NestedType->getIsNested()) {
2732 if (NestedTypeName.
size() && RecordName.
size()) {
2734 std::tie(OuterComponent, std::ignore) =
2738 if (OuterComponent.
size() && OuterComponent == RecordName) {
2739 if (!NestedType->getIsScopedAlready()) {
2740 Scope->addElement(NestedType);
2741 NestedType->setIsScopedAlready();
2744 Typedef->resetIncludeInPrint();
2761 if (Method.isIntroducingVirtual())
2762 W.printHex(
"VFTableOffset", Method.getVFTableOffset());
2763 W.printString(
"Name", Method.getName());
2770 ProcessArgumentList =
true;
2772 MemberFunction->setIsFinalized();
2775 MemberFunction->
setName(Method.getName());
2776 MemberFunction->setAccessibilityCode(Method.getAccess());
2780 MemberFunction->setIsStatic();
2781 MemberFunction->setVirtualityCode(
Kind);
2786 MemberFunction->setIsArtificial();
2789 CVType CVMethodType =
Types.getType(Method.getType());
2794 ProcessArgumentList =
false;
2805 W.printHex(
"MethodCount", Method.getNumOverloads());
2807 W.printString(
"Name", Method.getName());
2814 OverloadedMethodName = Method.getName();
2815 CVType CVMethods =
Types.getType(Method.getMethodList());
2829 W.printString(
"Name",
Field.getName());
2859 W.printHex(
"VBPtrOffset",
Base.getVBPtrOffset());
2860 W.printHex(
"VBTableIndex",
Base.getVTableIndex());
2869 Symbol->setAccessibilityCode(
Base.getAccess());
2888#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2891 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2895#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2896 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2897#define TYPE_RECORD(EnumName, EnumVal, Name)
2898#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2899#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2915#define TYPE_RECORD(EnumName, EnumVal, Name) \
2917 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2921#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2922 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2923#define MEMBER_RECORD(EnumName, EnumVal, Name)
2924#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2925#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2932Error LVLogicalVisitor::visitFieldListMemberStream(
2941 while (!Reader.empty()) {
2942 if (
Error Err = Reader.readEnum(Leaf))
2960 if (!ScopeStack.empty())
2962 InCompileUnitScope =
true;
2966 ReaderParent->addElement(Scope);
2970 ReaderScope->addElement(Symbol);
2974 ReaderScope->addElement(
Type);
2986 if (
options().getAttributeBase())
2993 case TypeLeafKind::LF_ENUMERATE:
2997 case TypeLeafKind::LF_MODIFIER:
3001 case TypeLeafKind::LF_POINTER:
3009 case TypeLeafKind::LF_BCLASS:
3010 case TypeLeafKind::LF_IVBCLASS:
3011 case TypeLeafKind::LF_VBCLASS:
3016 case TypeLeafKind::LF_MEMBER:
3017 case TypeLeafKind::LF_STMEMBER:
3024 case TypeLeafKind::LF_ARRAY:
3028 case TypeLeafKind::LF_CLASS:
3033 case TypeLeafKind::LF_ENUM:
3037 case TypeLeafKind::LF_METHOD:
3038 case TypeLeafKind::LF_ONEMETHOD:
3039 case TypeLeafKind::LF_PROCEDURE:
3044 case TypeLeafKind::LF_STRUCTURE:
3049 case TypeLeafKind::LF_UNION:
3068 case SymbolKind::S_UDT:
3074 case SymbolKind::S_CONSTANT:
3080 case SymbolKind::S_BPREL32:
3081 case SymbolKind::S_REGREL32:
3082 case SymbolKind::S_GDATA32:
3083 case SymbolKind::S_LDATA32:
3084 case SymbolKind::S_LOCAL:
3094 case SymbolKind::S_BLOCK32:
3099 case SymbolKind::S_COMPILE2:
3100 case SymbolKind::S_COMPILE3:
3105 case SymbolKind::S_INLINESITE:
3106 case SymbolKind::S_INLINESITE2:
3109 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3111 case SymbolKind::S_LPROC32:
3112 case SymbolKind::S_GPROC32:
3113 case SymbolKind::S_LPROC32_ID:
3114 case SymbolKind::S_GPROC32_ID:
3115 case SymbolKind::S_SEPCODE:
3116 case SymbolKind::S_THUNK32:
3136 Element->setIsFinalized();
3146 Element->setOffsetFromTypeIndex();
3150 W.printString(
"** Not implemented. **");
3157 Element->setOffsetFromTypeIndex();
3171 Symbol->setName(
Name);
3176 CVType CVMemberType = Types.getType(TI);
3177 if (CVMemberType.
kind() == LF_BITFIELD) {
3192 LVSymbol *
Parameter = Reader->createSymbol();
3195 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3206LVType *LVLogicalVisitor::createBaseType(
TypeIndex TI, StringRef TypeName) {
3208 TypeIndex TIR = (TypeIndex)SimpleKind;
3211 W.printString(
"TypeName", TypeName);
3214 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TIR))
3215 return static_cast<LVType *
>(Element);
3220 Reader->getCompileUnit()->addElement(
CurrentType);
3225LVType *LVLogicalVisitor::createPointerType(
TypeIndex TI, StringRef TypeName) {
3228 W.printString(
"TypeName", TypeName);
3231 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TI))
3232 return static_cast<LVType *
>(Element);
3234 LVType *Pointee = createBaseType(TI,
TypeName.drop_back(1));
3238 Reader->getCompileUnit()->addElement(
CurrentType);
3243void LVLogicalVisitor::createParents(StringRef ScopedName,
LVElement *Element) {
3263 if (Components.size() < 2)
3265 Components.pop_back();
3267 LVStringRefs::size_type FirstNamespace;
3268 LVStringRefs::size_type FirstAggregate;
3269 std::tie(FirstNamespace, FirstAggregate) =
3270 Shared->NamespaceDeduction.find(Components);
3273 W.printString(
"First Namespace", Components[FirstNamespace]);
3274 W.printString(
"First NonNamespace", Components[FirstAggregate]);
3278 if (FirstNamespace < FirstAggregate) {
3279 Shared->NamespaceDeduction.get(
3281 Components.begin() + FirstAggregate));
3287 LVScope *Aggregate =
nullptr;
3288 TypeIndex TIAggregate;
3290 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3293 for (LVStringRefs::size_type Index = FirstAggregate;
3296 Components.begin() + Index + 1),
3298 TIAggregate = Shared->ForwardReferences.remap(
3299 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3309 if (Aggregate && !Element->getIsScopedAlready()) {
3311 Element->setIsScopedAlready();
3318 TI = Shared->ForwardReferences.remap(TI);
3321 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3329 return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3330 : createBaseType(TI, TypeName);
3338 if (Element->getIsFinalized())
3352 Element->setIsFinalized();
3359 for (
const TypeIndex &Entry : Shared->LineRecords) {
3369 W.printNumber(
"LineNumber",
Line.getLineNumber());
3375 if (
LVElement *Element = Shared->TypeRecords.find(
3379 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3387 Shared->NamespaceDeduction.init();
3393 if (!
options().getInternalTag())
3398 auto NewLine = [&]() {
3411 Shared->TypeKinds.clear();
3414 OS <<
"\nSymbols:\n";
3417 Shared->SymbolKinds.clear();
3431 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3438 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3439 if (Iter != InlineeInfo.end()) {
3440 LineNumber = Iter->second.first;
3449 dbgs() <<
"inlineSiteAnnotation\n"
3450 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n"
3451 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n"
3452 <<
"Parent: " << Parent->
getName() <<
"\n"
3453 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3457 if (!
options().getPrintLines())
3464 int32_t LineOffset = LineNumber;
3468 auto UpdateCodeOffset = [&](
uint32_t Delta) {
3475 auto UpdateLineOffset = [&](int32_t Delta) {
3476 LineOffset += Delta;
3478 char Sign = Delta > 0 ?
'+' :
'-';
3479 dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3483 auto UpdateFileOffset = [&](int32_t
Offset) {
3489 auto CreateLine = [&]() {
3493 Line->setLineNumber(LineOffset);
3500 bool SeenLowAddress =
false;
3501 bool SeenHighAddress =
false;
3505 for (
auto &Annot :
InlineSite.annotations()) {
3512 switch (Annot.OpCode) {
3516 UpdateCodeOffset(Annot.U1);
3521 SeenLowAddress =
true;
3526 SeenHighAddress =
true;
3530 UpdateCodeOffset(Annot.U2);
3535 UpdateCodeOffset(Annot.U1);
3536 UpdateLineOffset(Annot.S1);
3543 UpdateFileOffset(Annot.U1);
3549 if (SeenLowAddress && SeenHighAddress) {
3550 SeenLowAddress =
false;
3551 SeenHighAddress =
false;
3552 InlinedFunction->
addObject(LowPC, HighPC);
3556 Reader->addInlineeLines(InlinedFunction,
InlineeLines);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Lower Kernel Arguments
OptimizedStructLayoutField Field
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Provides read only access to a subclass of BinaryStream.
This is an important base class in LLVM.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringRef getName() const
void setName(const Init *Name)
virtual void printString(StringRef Value)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr size_t size() const
size - Get the string size.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Value(Type *Ty, unsigned scid)
TypeIndex getElementType() const
TypeIndex getIndexType() const
StringRef getName() const
uint8_t getBitSize() const
TypeIndex getType() const
uint8_t getBitOffset() const
@ CurrentDirectory
Absolute CWD path.
@ SourceFile
Path to main source file, relative or absolute.
ArrayRef< TypeIndex > getArgs() const
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
uint8_t getLanguage() const
uint32_t getFlags() const
CompileSym3Flags getFlags() const
SourceLanguage getLanguage() const
Represents a read-only view of a CodeView string table.
LLVM_ABI Expected< StringRef > getString(uint32_t Offset) const
DefRangeFramePointerRelHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeRegisterRelHeader Hdr
bool hasSpilledUDTMember() const
uint32_t getRelocationOffset() const
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
DefRangeRegisterHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldRegisterHeader Hdr
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
LocalVariableAddrRange Range
uint32_t getSignature() const
RegisterId getLocalFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to local variables.
RegisterId getParamFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to parameters.
FrameProcedureOptions Flags
Provides amortized O(1) random access to a CodeView type stream.
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
TypeIndex getContinuationIndex() const
TypeIndex getReturnType() const
int32_t getThisPointerAdjustment() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
TypeIndex getThisType() const
TypeIndex getClassType() const
std::vector< OneMethodRecord > Methods
For method overload sets. LF_METHOD.
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< std::nullopt_t > 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.