40#define DEBUG_TYPE "CodeViewUtilities"
81 auto GetName = [&](
auto Record) {
90 if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)
92 else if (RK == TypeRecordKind::Union)
94 else if (RK == TypeRecordKind::Enum)
104#define DEBUG_TYPE "CodeViewDataVisitor"
118 using RecordEntry = std::pair<TypeLeafKind, LVElement *>;
119 using RecordTable = std::map<TypeIndex, RecordEntry>;
120 RecordTable RecordFromTypes;
121 RecordTable RecordFromIds;
123 using NameTable = std::map<StringRef, TypeIndex>;
124 NameTable NameFromTypes;
125 NameTable NameFromIds;
128 LVTypeRecords(
LVShared *Shared) : Shared(Shared) {}
137class LVForwardReferences {
139 using ForwardEntry = std::pair<TypeIndex, TypeIndex>;
140 using ForwardTypeNames = std::map<StringRef, ForwardEntry>;
141 ForwardTypeNames ForwardTypesNames;
144 using ForwardType = std::map<TypeIndex, TypeIndex>;
145 ForwardType ForwardTypes;
149 ForwardTypes.emplace(TIForward, TIReference);
157 It->second.first = TIForward;
158 add(TIForward, It->second.second);
168 It->second.second = TIReference;
169 add(It->second.first, TIReference);
174 LVForwardReferences() =
default;
180 (IsForwardRef) ? add(
Name, TI) : update(
Name, TI);
184 auto It = ForwardTypes.find(TIForward);
189 auto It = ForwardTypesNames.find(
Name);
190 return It != ForwardTypesNames.end() ? It->second.second
203class LVNamespaceDeduction {
206 using Names = std::map<StringRef, LVScope *>;
207 Names NamespaceNames;
209 using LookupSet = std::set<StringRef>;
210 LookupSet DeducedScopes;
211 LookupSet UnresolvedScopes;
212 LookupSet IdentifiedNamespaces;
215 if (NamespaceNames.find(
Name) == NamespaceNames.end())
216 NamespaceNames.emplace(
Name, Namespace);
220 LVNamespaceDeduction(
LVShared *Shared) : Shared(Shared) {}
229 auto It = NamespaceNames.find(
Name);
230 LVScope *Namespace = It != NamespaceNames.end() ? It->second :
nullptr;
238 if (Components.empty())
241 LVStringRefs::size_type FirstNamespace = 0;
242 LVStringRefs::size_type FirstNonNamespace;
243 for (LVStringRefs::size_type Index = 0; Index < Components.size();
245 FirstNonNamespace = Index;
246 LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);
247 if (Iter == IdentifiedNamespaces.end())
251 return std::make_tuple(FirstNamespace, FirstNonNamespace);
256class LVStringRecords {
257 using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;
258 using StringIds = std::map<TypeIndex, StringEntry>;
262 LVStringRecords() =
default;
266 auto [It,
Inserted] = Strings.try_emplace(TI);
268 It->second = std::make_tuple(++Index, std::string(
String),
nullptr);
272 StringIds::iterator Iter = Strings.
find(TI);
273 return Iter != Strings.end() ? std::get<1>(Iter->second) :
StringRef{};
277 StringIds::iterator Iter = Strings.find(TI);
278 return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;
321 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
322 Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),
323 std::forward_as_tuple(
Kind, Element));
326void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, StringRef
Name) {
327 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
331LVElement *LVTypeRecords::find(uint32_t StreamIdx, TypeIndex TI,
bool Create) {
333 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
335 LVElement *Element =
nullptr;
336 RecordTable::iterator Iter =
Target.find(TI);
337 if (Iter !=
Target.end()) {
338 Element = Iter->second.second;
339 if (Element || !Create)
346 Element->setOffsetFromTypeIndex();
347 Target[TI].second = Element;
353TypeIndex LVTypeRecords::find(uint32_t StreamIdx, StringRef
Name) {
354 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
359void LVStringRecords::addFilenames() {
360 for (StringIds::const_reference Entry : Strings) {
361 StringRef
Name = std::get<1>(
Entry.second);
362 LVScopeCompileUnit *
Scope = std::get<2>(
Entry.second);
368void LVStringRecords::addFilenames(LVScopeCompileUnit *Scope) {
369 for (StringIds::reference Entry : Strings)
370 if (!std::get<2>(
Entry.second))
374void LVNamespaceDeduction::add(StringRef
String) {
375 StringRef InnerComponent;
376 StringRef OuterComponent;
378 DeducedScopes.insert(InnerComponent);
379 if (OuterComponent.
size())
380 UnresolvedScopes.insert(OuterComponent);
383void LVNamespaceDeduction::init() {
390 for (
const StringRef &Unresolved : UnresolvedScopes) {
392 for (
const StringRef &Component : Components) {
393 LookupSet::iterator Iter = DeducedScopes.find(Component);
394 if (Iter == DeducedScopes.end())
395 IdentifiedNamespaces.insert(Component);
400 auto Print = [&](LookupSet &Container,
const char *Title) {
401 auto Header = [&]() {
407 for (
const StringRef &Item : Container)
411 Print(DeducedScopes,
"Deducted Scopes");
412 Print(UnresolvedScopes,
"Unresolved Scopes");
413 Print(IdentifiedNamespaces,
"Namespaces");
417LVScope *LVNamespaceDeduction::get(
LVStringRefs Components) {
419 for (
const StringRef &Component : Components)
423 if (Components.empty())
429 for (
const StringRef &Component : Components) {
436 Namespace->setTag(dwarf::DW_TAG_namespace);
440 add(Component, Namespace);
447LVScope *LVNamespaceDeduction::get(StringRef ScopedName,
bool CheckScope) {
451 LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);
452 return Iter == IdentifiedNamespaces.end();
457 return get(Components);
461#define DEBUG_TYPE "CodeViewTypeVisitor"
466void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
467 uint32_t StreamIdx)
const {
482 if (
options().getInternalTag())
483 Shared->TypeKinds.insert(
Record.kind());
487 CurrentTypeIndex = TI;
488 Shared->TypeRecords.add(StreamIdx, TI,
Record.kind());
500 W.getOStream() <<
" {\n";
509 W.startLine() <<
"}\n";
523 W.printNumber(
"NumArgs",
static_cast<uint32_t>(Args.getArgs().size()));
537 String = Ids.getTypeName(TI);
539 Shared->StringRecords.add(TI,
String);
543 String = Ids.getTypeName(TI);
545 Shared->StringRecords.add(TI,
String);
546 LogicalVisitor->setCompileUnitName(std::string(
String));
556 W.printString(
"Name",
Class.getName());
560 Shared->NamespaceDeduction.add(
Class.getName());
561 Shared->ForwardReferences.record(
Class.isForwardRef(),
Class.getName(),
565 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Class.getName());
574 W.printString(
"Name",
Enum.getName());
578 Shared->NamespaceDeduction.add(
Enum.getName());
588 W.printString(
"Name", Func.getName());
592 Shared->NamespaceDeduction.add(Func.getName());
606 Shared->TypeRecords.add(
StreamTPI, CurrentTypeIndex, {});
615 W.printString(
"StringData",
String.getString());
627 W.printNumber(
"LineNumber",
Line.getLineNumber());
630 Shared->LineRecords.push_back(CurrentTypeIndex);
637 W.printNumber(
"MemberCount",
Union.getMemberCount());
639 W.printNumber(
"SizeOf",
Union.getSize());
640 W.printString(
"Name",
Union.getName());
641 if (
Union.hasUniqueName())
642 W.printString(
"UniqueName",
Union.getUniqueName());
646 Shared->NamespaceDeduction.add(
Union.getName());
647 Shared->ForwardReferences.record(
Union.isForwardRef(),
Union.getName(),
651 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex,
Union.getName());
656#define DEBUG_TYPE "CodeViewSymbolVisitor"
665 Reader->printRelocatedField(
Label, CoffSection, RelocOffset,
Offset,
672 Reader->getLinkageName(CoffSection, RelocOffset,
Offset, RelocSym);
686 return Reader->CVStringTable;
689void LVSymbolVisitor::printLocalVariableAddrRange(
691 DictScope S(W,
"LocalVariableAddrRange");
693 ObjDelegate->printRelocatedField(
"OffsetStart", RelocationOffset,
695 W.printHex(
"ISectStart",
Range.ISectStart);
696 W.printHex(
"Range",
Range.Range);
699void LVSymbolVisitor::printLocalVariableAddrGap(
703 W.printHex(
"GapStartOffset", Gap.GapStartOffset);
704 W.printHex(
"Range", Gap.Range);
708void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI)
const {
719 W.printNumber(
"Offset",
Offset);
723 if (
options().getInternalTag())
724 Shared->SymbolKinds.insert(
Kind);
726 LogicalVisitor->CurrentElement = LogicalVisitor->createElement(
Kind);
727 if (!LogicalVisitor->CurrentElement) {
737 IsCompileUnit =
false;
738 if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())
739 LogicalVisitor->CurrentElement->setOffset(
Offset);
741 assert(LogicalVisitor->CurrentScope &&
"Invalid scope!");
742 LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);
744 if (LogicalVisitor->CurrentSymbol)
745 LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);
746 if (LogicalVisitor->CurrentType)
747 LogicalVisitor->addElement(LogicalVisitor->CurrentType);
759 LogicalVisitor->popScope();
773 W.printHex(
"CodeSize",
Block.CodeSize);
774 W.printHex(
"Segment",
Block.Segment);
775 W.printString(
"BlockName",
Block.Name);
778 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
781 ObjDelegate->getLinkageName(
Block.getRelocationOffset(),
Block.CodeOffset,
785 if (
options().getGeneralCollectRanges()) {
789 Reader->linearAddress(
Block.Segment,
Block.CodeOffset, Addendum);
791 Scope->addObject(LowPC, HighPC);
803 W.printNumber(
"Offset",
Local.Offset);
804 W.printString(
"VarName",
Local.Name);
807 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
808 Symbol->setName(
Local.Name);
816 Symbol->resetIsVariable();
818 if (
Local.Name ==
"this") {
819 Symbol->setIsParameter();
820 Symbol->setIsArtificial();
823 bool(
Local.Offset > 0) ? Symbol->setIsParameter()
824 : Symbol->setIsVariable();
828 if (Symbol->getIsParameter())
829 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
831 setLocalVariableType(Symbol,
Local.Type);
842 W.printNumber(
"Offset",
Local.Offset);
843 W.printString(
"VarName",
Local.Name);
846 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
847 Symbol->setName(
Local.Name);
850 Symbol->resetIsVariable();
853 if (
Local.Name ==
"this") {
854 Symbol->setIsArtificial();
855 Symbol->setIsParameter();
858 determineSymbolKind(Symbol,
Local.Register);
862 if (Symbol->getIsParameter())
863 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
865 setLocalVariableType(Symbol,
Local.Type);
876 W.printNumber(
"Offset",
Local.Offset);
877 W.printNumber(
"OffsetInUdt",
Local.OffsetInUdt);
878 W.printString(
"VarName",
Local.Name);
881 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
882 Symbol->setName(
Local.Name);
885 Symbol->resetIsVariable();
888 if (
Local.Name ==
"this") {
889 Symbol->setIsArtificial();
890 Symbol->setIsParameter();
893 determineSymbolKind(Symbol,
Local.Register);
897 if (Symbol->getIsParameter())
898 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
900 setLocalVariableType(Symbol,
Local.Type);
912 if (
Error Err = LogicalVisitor->finishVisitation(
913 CVBuildType, BuildInfo.
BuildId, Reader->getCompileUnit()))
928 W.printString(
"VersionName", Compile2.
Version);
943 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
945 Reader->setCompileUnitCPUType(Compile2.
Machine);
946 Scope->setName(CurrentObjectName);
947 if (
options().getAttributeProducer())
948 Scope->setProducer(Compile2.
Version);
949 if (
options().getAttributeLanguage())
956 Reader->addModule(Scope);
959 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
963 CurrentObjectName =
"";
976 W.printString(
"VersionName", Compile3.
Version);
991 if (
LVScope *Scope = LogicalVisitor->CurrentScope) {
993 Reader->setCompileUnitCPUType(Compile3.
Machine);
994 Scope->setName(CurrentObjectName);
995 if (
options().getAttributeProducer())
996 Scope->setProducer(Compile3.
Version);
997 if (
options().getAttributeLanguage())
1004 Reader->addModule(Scope);
1007 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
1011 CurrentObjectName =
"";
1021 W.printString(
"Name",
Constant.Name);
1024 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1027 Symbol->resetIncludeInPrint();
1040 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1042 W.printNumber(
"Offset", DefRangeFramePointerRelFullScope.
Offset);
1045 if (
LVSymbol *Symbol = LocalSymbol) {
1046 Symbol->setHasCodeViewLocation();
1047 LocalSymbol =
nullptr;
1054 Symbol->addLocation(Attr, 0, 0, 0, 0);
1055 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1067 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1069 W.printNumber(
"Offset", DefRangeFramePointerRel.
Hdr.
Offset);
1070 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
1072 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
1079 if (
LVSymbol *Symbol = LocalSymbol) {
1080 Symbol->setHasCodeViewLocation();
1081 LocalSymbol =
nullptr;
1090 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1093 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1105 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1107 W.printBoolean(
"HasSpilledUDTMember",
1109 W.printNumber(
"OffsetInParent", DefRangeRegisterRel.
offsetInParent());
1110 W.printNumber(
"BasePointerOffset",
1112 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
1114 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
1117 if (
LVSymbol *Symbol = LocalSymbol) {
1118 Symbol->setHasCodeViewLocation();
1119 LocalSymbol =
nullptr;
1129 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1132 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2});
1144 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1146 W.printBoolean(
"HasSpilledUDTMember",
1148 W.printNumber(
"OffsetInParent", DefRangeRegisterRelIndir.
offsetInParent());
1149 W.printNumber(
"BasePointerOffset",
1151 W.printNumber(
"OffsetInUdt", DefRangeRegisterRelIndir.
Hdr.
OffsetInUdt);
1152 printLocalVariableAddrRange(DefRangeRegisterRelIndir.
Range,
1154 printLocalVariableAddrGap(DefRangeRegisterRelIndir.
Gaps);
1157 if (
LVSymbol *Symbol = LocalSymbol) {
1158 Symbol->setHasCodeViewLocation();
1159 LocalSymbol =
nullptr;
1170 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1173 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2, Operand3});
1185 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1190 printLocalVariableAddrRange(DefRangeRegister.
Range,
1192 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1195 if (
LVSymbol *Symbol = LocalSymbol) {
1196 Symbol->setHasCodeViewLocation();
1197 LocalSymbol =
nullptr;
1205 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1208 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1220 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1224 W.printNumber(
"MayHaveNoName", DefRangeSubfieldRegister.
Hdr.
MayHaveNoName);
1225 W.printNumber(
"OffsetInParent",
1227 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1229 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1232 if (
LVSymbol *Symbol = LocalSymbol) {
1233 Symbol->setHasCodeViewLocation();
1234 LocalSymbol =
nullptr;
1243 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1246 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1258 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1263 if (!ExpectedProgram) {
1266 "String table offset outside of bounds of String Table!");
1268 W.printString(
"Program", *ExpectedProgram);
1270 W.printNumber(
"OffsetInParent", DefRangeSubfield.
OffsetInParent);
1271 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1273 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
1276 if (
LVSymbol *Symbol = LocalSymbol) {
1277 Symbol->setHasCodeViewLocation();
1278 LocalSymbol =
nullptr;
1286 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1289 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1301 W.getOStream() <<
formatv(
"Symbol: {0}, ", LocalSymbol->getName());
1306 if (!ExpectedProgram) {
1309 "String table offset outside of bounds of String Table!");
1311 W.printString(
"Program", *ExpectedProgram);
1314 printLocalVariableAddrGap(DefRange.
Gaps);
1317 if (
LVSymbol *Symbol = LocalSymbol) {
1318 Symbol->setHasCodeViewLocation();
1319 LocalSymbol =
nullptr;
1327 Reader->linearAddress(
Range.ISectStart,
Range.OffsetStart);
1330 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1373 W.printString(
"DisplayName",
Data.Name);
1376 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1379 ObjDelegate->getLinkageName(
Data.getRelocationOffset(),
Data.DataOffset,
1382 Symbol->setName(
Data.Name);
1391 if (
getReader().isSystemEntry(Symbol) && !
options().getAttributeSystem()) {
1392 Symbol->resetIncludeInPrint();
1396 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Data.Name)) {
1399 if (Symbol->getParentScope()->removeElement(Symbol))
1400 Namespace->addElement(Symbol);
1403 Symbol->setType(LogicalVisitor->getElement(
StreamTPI,
Data.Type));
1404 if (
Record.kind() == SymbolKind::S_GDATA32)
1405 Symbol->setIsExternal();
1416 if (
LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1417 LVScope *AbstractFunction = Reader->createScopeFunction();
1418 AbstractFunction->setIsSubprogram();
1419 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1421 AbstractFunction->setIsInlinedAbstract();
1424 LogicalVisitor->startProcessArgumentList();
1427 if (
Error Err = LogicalVisitor->finishVisitation(
1428 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1430 LogicalVisitor->stopProcessArgumentList();
1435 InlinedFunction->setName(
Name);
1436 InlinedFunction->setLinkageName(
Name);
1439 if (
Error Err = LogicalVisitor->inlineSiteAnnotation(
1440 AbstractFunction, InlinedFunction,
InlineSite))
1452 W.printString(
"VarName",
Local.Name);
1455 if (
LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1456 Symbol->setName(
Local.Name);
1459 Symbol->resetIsVariable();
1463 Local.Name ==
"this") {
1464 Symbol->setIsArtificial();
1465 Symbol->setIsParameter();
1468 : Symbol->setIsVariable();
1472 if (Symbol->getIsParameter())
1473 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1475 setLocalVariableType(Symbol,
Local.Type);
1480 LocalSymbol = Symbol;
1489 W.printHex(
"Signature", ObjName.
Signature);
1490 W.printString(
"ObjectName", ObjName.
Name);
1493 CurrentObjectName = ObjName.
Name;
1499 if (InFunctionScope)
1503 InFunctionScope =
true;
1507 W.printHex(
"Segment", Proc.
Segment);
1508 W.printFlags(
"Flags",
static_cast<uint8_t>(Proc.
Flags),
1510 W.printString(
"DisplayName", Proc.
Name);
1559 if (
options().getGeneralCollectRanges()) {
1565 Function->addObject(LowPC, HighPC);
1568 if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1570 Reader->getCompileUnit()->addPublicName(
Function, LowPC, HighPC);
1591 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
1593 std::optional<CVType> CVFunctionType;
1594 auto GetRecordType = [&]() ->
bool {
1595 CVFunctionType = Ids.tryGetType(TIFunctionType);
1596 if (!CVFunctionType)
1601 if (CVFunctionType->kind() == LF_FUNC_ID)
1605 return (CVFunctionType->kind() == LF_MFUNC_ID);
1609 if (!GetRecordType()) {
1610 CVFunctionType = Types.tryGetType(TIFunctionType);
1611 if (!CVFunctionType)
1615 if (
Error Err = LogicalVisitor->finishVisitation(
1616 *CVFunctionType, TIFunctionType,
Function))
1620 if (
Record.kind() == SymbolKind::S_GPROC32 ||
1621 Record.kind() == SymbolKind::S_GPROC32_ID)
1627 if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1632 if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1644 InFunctionScope =
false;
1650 if (InFunctionScope)
1654 InFunctionScope =
true;
1657 W.printHex(
"Segment",
Thunk.Segment);
1658 W.printString(
"Name",
Thunk.Name);
1671 W.printString(
"UDTName",
UDT.Name);
1674 if (
LVType *
Type = LogicalVisitor->CurrentType) {
1675 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
UDT.Name)) {
1676 if (
Type->getParentScope()->removeElement(
Type))
1677 Namespace->addElement(
Type);
1690 Type->resetIncludeInPrint();
1693 if (
UDT.Name == RecordName)
1694 Type->resetIncludeInPrint();
1713 W.printHex(
"BaseOffset",
JumpTable.BaseOffset);
1714 W.printNumber(
"BaseSegment",
JumpTable.BaseSegment);
1717 W.printHex(
"BranchOffset",
JumpTable.BranchOffset);
1718 W.printHex(
"TableOffset",
JumpTable.TableOffset);
1719 W.printNumber(
"BranchSegment",
JumpTable.BranchSegment);
1720 W.printNumber(
"TableSegment",
JumpTable.TableSegment);
1721 W.printNumber(
"EntriesCount",
JumpTable.EntriesCount);
1730 switch (
Caller.getKind()) {
1731 case SymbolRecordKind::CallerSym:
1732 FieldName =
"Callee";
1734 case SymbolRecordKind::CalleeSym:
1735 FieldName =
"Caller";
1737 case SymbolRecordKind::InlineesSym:
1738 FieldName =
"Inlinee";
1742 "Unknown CV Record type for a CallerSym object!");
1744 for (
auto FuncID :
Caller.Indices) {
1753 if (Element && Element->getIsScoped()) {
1772#define DEBUG_TYPE "CodeViewLogicalVisitor"
1779 : Reader(Reader), W(W), Input(Input) {
1782 Shared = std::make_shared<LVShared>(Reader,
this);
1788 StreamIdx ==
StreamTPI ? types() : ids());
1793 W.getOStream() <<
"\n";
1796 W.getOStream() <<
" {\n";
1801 << Element->
getName() <<
"\n";
1806 W.startLine() <<
"}\n";
1812 W.getOStream() <<
"\n";
1815 W.getOStream() <<
" {\n";
1820 << Element->
getName() <<
"\n";
1825 W.startLine() <<
"}\n";
1843 W.printNumber(
"NumArgs",
Size);
1852 TypeIndex ParameterType = Indices[Index];
1866 W.printNumber(
"SizeOf", AT.
getSize());
1867 W.printString(
"Name", AT.
getName());
1871 if (Element->getIsFinalized())
1873 Element->setIsFinalized();
1879 Reader->getCompileUnit()->addElement(Array);
1882 LVType *PrevSubrange =
nullptr;
1890 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1915 while (CVEntry.
kind() == LF_ARRAY) {
1926 AddSubrangeType(AR);
1927 TIArrayType = TIElementType;
1933 CVType CVElementType =
Types.getType(TIElementType);
1934 if (CVElementType.
kind() == LF_MODIFIER) {
1936 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1949 CVEntry =
Types.getType(TIElementType);
1951 const_cast<CVType &
>(CVEntry), AR)) {
1961 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
2022 W.printNumber(
"MemberCount",
Class.getMemberCount());
2026 W.printNumber(
"SizeOf",
Class.getSize());
2027 W.printString(
"Name",
Class.getName());
2028 if (
Class.hasUniqueName())
2029 W.printString(
"UniqueName",
Class.getUniqueName());
2033 if (Element->getIsFinalized())
2035 Element->setIsFinalized();
2041 Scope->setName(
Class.getName());
2042 if (
Class.hasUniqueName())
2043 Scope->setLinkageName(
Class.getUniqueName());
2046 if (
Class.isNested()) {
2047 Scope->setIsNested();
2048 createParents(
Class.getName(), Scope);
2051 if (
Class.isScoped())
2052 Scope->setIsScoped();
2056 if (!(
Class.isNested() ||
Class.isScoped())) {
2057 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2058 Namespace->addElement(Scope);
2060 Reader->getCompileUnit()->addElement(Scope);
2066 TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2072 const_cast<CVType &
>(CVReference), ReferenceRecord))
2093 W.printNumber(
"NumEnumerators",
Enum.getMemberCount());
2096 W.printString(
"Name",
Enum.getName());
2104 if (Scope->getIsFinalized())
2106 Scope->setIsFinalized();
2110 Scope->setName(
Enum.getName());
2111 if (
Enum.hasUniqueName())
2112 Scope->setLinkageName(
Enum.getUniqueName());
2116 if (
Enum.isNested()) {
2117 Scope->setIsNested();
2118 createParents(
Enum.getName(), Scope);
2121 if (
Enum.isScoped()) {
2122 Scope->setIsScoped();
2123 Scope->setIsEnumClass();
2127 if (!(
Enum.isNested() ||
Enum.isScoped())) {
2128 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2129 Namespace->addElement(Scope);
2131 Reader->getCompileUnit()->addElement(Scope);
2154 if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2168 W.printString(
"Name", Func.getName());
2180 TypeIndex TIParent = Func.getParentScope();
2181 if (FunctionDcl->getIsInlinedAbstract()) {
2182 FunctionDcl->setName(Func.getName());
2184 Reader->getCompileUnit()->addElement(FunctionDcl);
2188 CVType CVParentScope = ids().getType(TIParent);
2193 TypeIndex TIFunctionType = Func.getFunctionType();
2194 CVType CVFunctionType =
Types.getType(TIFunctionType);
2199 FunctionDcl->setIsFinalized();
2223 W.printString(
"Name", Id.getName());
2228 if (FunctionDcl->getIsInlinedAbstract()) {
2234 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2235 Class->addElement(FunctionDcl);
2238 TypeIndex TIFunctionType = Id.getFunctionType();
2239 CVType CVFunction = types().getType(TIFunctionType);
2264 MemberFunction->setIsFinalized();
2266 MemberFunction->setOffset(TI.
getIndex());
2267 MemberFunction->setOffsetFromTypeIndex();
2269 if (ProcessArgumentList) {
2270 ProcessArgumentList =
false;
2272 if (!MemberFunction->getIsStatic()) {
2277 createParameter(ThisPointer,
StringRef(), MemberFunction);
2278 This->setIsArtificial();
2305 Method.Name = OverloadedMethodName;
2337 bool SeenModifier =
false;
2340 SeenModifier =
true;
2341 LastLink->
setTag(dwarf::DW_TAG_const_type);
2342 LastLink->setIsConst();
2353 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2354 LastLink->setIsVolatile();
2355 LastLink->
setName(
"volatile");
2366 LastLink->setIsUnaligned();
2367 LastLink->
setName(
"unaligned");
2370 LastLink->
setType(ModifiedType);
2380 W.printNumber(
"IsFlat", Ptr.
isFlat());
2381 W.printNumber(
"IsConst", Ptr.
isConst());
2382 W.printNumber(
"IsVolatile", Ptr.
isVolatile());
2384 W.printNumber(
"IsRestrict", Ptr.
isRestrict());
2387 W.printNumber(
"SizeOf", Ptr.
getSize());
2412 bool SeenModifier =
false;
2418 SeenModifier =
true;
2420 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2429 LVType *LReference = Reader->createType();
2430 LReference->setIsModifier();
2431 LastLink->
setType(LReference);
2432 LastLink = LReference;
2435 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2436 LastLink->setIsReference();
2441 LVType *RReference = Reader->createType();
2442 RReference->setIsModifier();
2443 LastLink->
setType(RReference);
2444 LastLink = RReference;
2447 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2448 LastLink->setIsRvalueReference();
2474 if (ProcessArgumentList) {
2475 ProcessArgumentList =
false;
2493 W.printNumber(
"MemberCount",
Union.getMemberCount());
2495 W.printNumber(
"SizeOf",
Union.getSize());
2496 W.printString(
"Name",
Union.getName());
2497 if (
Union.hasUniqueName())
2498 W.printString(
"UniqueName",
Union.getUniqueName());
2506 if (Scope->getIsFinalized())
2508 Scope->setIsFinalized();
2510 Scope->setName(
Union.getName());
2511 if (
Union.hasUniqueName())
2512 Scope->setLinkageName(
Union.getUniqueName());
2515 if (
Union.isNested()) {
2516 Scope->setIsNested();
2517 createParents(
Union.getName(), Scope);
2519 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2520 Namespace->addElement(Scope);
2522 Reader->getCompileUnit()->addElement(Scope);
2525 if (!
Union.getFieldList().isNoneType()) {
2542 W.printNumber(
"Age", TS.
getAge());
2543 W.printString(
"Name", TS.
getName());
2557 W.printString(
"VFTableName", VFT.
getName());
2559 W.printString(
"MethodName",
N);
2586 W.printNumber(
"NumStrings",
Size);
2602 W.printString(
"StringData",
String.getString());
2605 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2606 String.getString(),
false)) {
2610 Scope->removeElement(Element);
2611 Namespace->addElement(Element);
2642 W.printNumber(
"Module", ModSourceLine.
getModule());
2687 W.printHex(
"BaseOffset",
Base.getBaseOffset());
2696 Symbol->setAccessibilityCode(
Base.getAccess());
2710 W.printHex(
"FieldOffset",
Field.getFieldOffset());
2711 W.printString(
"Name",
Field.getName());
2727 W.printNumber(
"EnumValue",
Enum.getValue());
2728 W.printString(
"Name",
Enum.getName());
2736 Enum.getValue().toString(
Value, 16,
true,
true);
2763 W.printString(
"Name",
Nested.getName());
2774 if (NestedType && NestedType->getIsNested()) {
2780 if (NestedTypeName.
size() && RecordName.
size()) {
2782 std::tie(OuterComponent, std::ignore) =
2786 if (OuterComponent.
size() && OuterComponent == RecordName) {
2787 if (!NestedType->getIsScopedAlready()) {
2788 Scope->addElement(NestedType);
2789 NestedType->setIsScopedAlready();
2792 Typedef->resetIncludeInPrint();
2809 if (Method.isIntroducingVirtual())
2810 W.printHex(
"VFTableOffset", Method.getVFTableOffset());
2811 W.printString(
"Name", Method.getName());
2818 ProcessArgumentList =
true;
2820 MemberFunction->setIsFinalized();
2823 MemberFunction->
setName(Method.getName());
2824 MemberFunction->setAccessibilityCode(Method.getAccess());
2828 MemberFunction->setIsStatic();
2829 MemberFunction->setVirtualityCode(
Kind);
2834 MemberFunction->setIsArtificial();
2837 CVType CVMethodType =
Types.getType(Method.getType());
2842 ProcessArgumentList =
false;
2853 W.printHex(
"MethodCount", Method.getNumOverloads());
2855 W.printString(
"Name", Method.getName());
2862 OverloadedMethodName = Method.getName();
2863 CVType CVMethods =
Types.getType(Method.getMethodList());
2877 W.printString(
"Name",
Field.getName());
2907 W.printHex(
"VBPtrOffset",
Base.getVBPtrOffset());
2908 W.printHex(
"VBTableIndex",
Base.getVTableIndex());
2917 Symbol->setAccessibilityCode(
Base.getAccess());
2936#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2939 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2943#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2944 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2945#define TYPE_RECORD(EnumName, EnumVal, Name)
2946#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2947#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2963#define TYPE_RECORD(EnumName, EnumVal, Name) \
2965 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2969#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2970 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2971#define MEMBER_RECORD(EnumName, EnumVal, Name)
2972#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2973#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2980Error LVLogicalVisitor::visitFieldListMemberStream(
2989 while (!Reader.empty()) {
2990 if (
Error Err = Reader.readEnum(Leaf))
3008 if (!ScopeStack.empty())
3010 InCompileUnitScope =
true;
3014 ReaderParent->addElement(Scope);
3018 ReaderScope->addElement(Symbol);
3022 ReaderScope->addElement(
Type);
3034 if (
options().getAttributeBase())
3041 case TypeLeafKind::LF_ENUMERATE:
3045 case TypeLeafKind::LF_MODIFIER:
3049 case TypeLeafKind::LF_POINTER:
3057 case TypeLeafKind::LF_BCLASS:
3058 case TypeLeafKind::LF_IVBCLASS:
3059 case TypeLeafKind::LF_VBCLASS:
3064 case TypeLeafKind::LF_MEMBER:
3065 case TypeLeafKind::LF_STMEMBER:
3072 case TypeLeafKind::LF_ARRAY:
3076 case TypeLeafKind::LF_CLASS:
3081 case TypeLeafKind::LF_ENUM:
3085 case TypeLeafKind::LF_METHOD:
3086 case TypeLeafKind::LF_ONEMETHOD:
3087 case TypeLeafKind::LF_PROCEDURE:
3092 case TypeLeafKind::LF_STRUCTURE:
3097 case TypeLeafKind::LF_UNION:
3116 case SymbolKind::S_UDT:
3122 case SymbolKind::S_CONSTANT:
3128 case SymbolKind::S_BPREL32:
3129 case SymbolKind::S_REGREL32:
3130 case SymbolKind::S_REGREL32_INDIR:
3131 case SymbolKind::S_GDATA32:
3132 case SymbolKind::S_LDATA32:
3133 case SymbolKind::S_LOCAL:
3143 case SymbolKind::S_BLOCK32:
3148 case SymbolKind::S_COMPILE2:
3149 case SymbolKind::S_COMPILE3:
3154 case SymbolKind::S_INLINESITE:
3155 case SymbolKind::S_INLINESITE2:
3158 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3160 case SymbolKind::S_LPROC32:
3161 case SymbolKind::S_GPROC32:
3162 case SymbolKind::S_LPROC32_ID:
3163 case SymbolKind::S_GPROC32_ID:
3164 case SymbolKind::S_SEPCODE:
3165 case SymbolKind::S_THUNK32:
3185 Element->setIsFinalized();
3195 Element->setOffsetFromTypeIndex();
3199 W.printString(
"** Not implemented. **");
3206 Element->setOffsetFromTypeIndex();
3220 Symbol->setName(
Name);
3225 CVType CVMemberType = Types.getType(TI);
3226 if (CVMemberType.
kind() == LF_BITFIELD) {
3241 LVSymbol *
Parameter = Reader->createSymbol();
3244 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3255LVType *LVLogicalVisitor::createBaseType(
TypeIndex TI, StringRef TypeName) {
3257 TypeIndex TIR = (TypeIndex)SimpleKind;
3260 W.printString(
"TypeName", TypeName);
3263 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TIR))
3264 return static_cast<LVType *
>(Element);
3269 Reader->getCompileUnit()->addElement(
CurrentType);
3274LVType *LVLogicalVisitor::createPointerType(
TypeIndex TI, StringRef TypeName) {
3277 W.printString(
"TypeName", TypeName);
3280 if (LVElement *Element = Shared->TypeRecords.find(
StreamTPI, TI))
3281 return static_cast<LVType *
>(Element);
3283 LVType *Pointee = createBaseType(TI,
TypeName.drop_back(1));
3287 Reader->getCompileUnit()->addElement(
CurrentType);
3292void LVLogicalVisitor::createParents(StringRef ScopedName,
LVElement *Element) {
3312 if (Components.size() < 2)
3314 Components.pop_back();
3316 LVStringRefs::size_type FirstNamespace;
3317 LVStringRefs::size_type FirstAggregate;
3318 std::tie(FirstNamespace, FirstAggregate) =
3319 Shared->NamespaceDeduction.find(Components);
3322 W.printString(
"First Namespace", Components[FirstNamespace]);
3323 W.printString(
"First NonNamespace", Components[FirstAggregate]);
3327 if (FirstNamespace < FirstAggregate) {
3328 Shared->NamespaceDeduction.get(
3330 Components.begin() + FirstAggregate));
3336 LVScope *Aggregate =
nullptr;
3337 TypeIndex TIAggregate;
3339 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3342 for (LVStringRefs::size_type Index = FirstAggregate;
3345 Components.begin() + Index + 1),
3347 TIAggregate = Shared->ForwardReferences.remap(
3348 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3358 if (Aggregate && !Element->getIsScopedAlready()) {
3360 Element->setIsScopedAlready();
3367 TI = Shared->ForwardReferences.remap(TI);
3370 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3378 return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3379 : createBaseType(TI, TypeName);
3387 if (Element->getIsFinalized())
3401 Element->setIsFinalized();
3408 for (
const TypeIndex &Entry : Shared->LineRecords) {
3418 W.printNumber(
"LineNumber",
Line.getLineNumber());
3424 if (
LVElement *Element = Shared->TypeRecords.find(
3428 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3436 Shared->NamespaceDeduction.init();
3442 if (!
options().getInternalTag())
3447 auto NewLine = [&]() {
3460 Shared->TypeKinds.clear();
3463 OS <<
"\nSymbols:\n";
3466 Shared->SymbolKinds.clear();
3480 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3487 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3488 if (Iter != InlineeInfo.end()) {
3489 LineNumber = Iter->second.first;
3498 dbgs() <<
"inlineSiteAnnotation\n"
3499 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n"
3500 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n"
3501 <<
"Parent: " << Parent->
getName() <<
"\n"
3502 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3506 if (!
options().getPrintLines())
3513 int32_t LineOffset = LineNumber;
3517 auto UpdateCodeOffset = [&](
uint32_t Delta) {
3524 auto UpdateLineOffset = [&](int32_t Delta) {
3525 LineOffset += Delta;
3527 char Sign = Delta > 0 ?
'+' :
'-';
3528 dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3532 auto UpdateFileOffset = [&](int32_t
Offset) {
3538 auto CreateLine = [&]() {
3542 Line->setLineNumber(LineOffset);
3549 bool SeenLowAddress =
false;
3550 bool SeenHighAddress =
false;
3554 for (
auto &Annot :
InlineSite.annotations()) {
3561 switch (Annot.OpCode) {
3565 UpdateCodeOffset(Annot.U1);
3570 SeenLowAddress =
true;
3575 SeenHighAddress =
true;
3579 UpdateCodeOffset(Annot.U2);
3584 UpdateCodeOffset(Annot.U1);
3585 UpdateLineOffset(Annot.S1);
3592 UpdateFileOffset(Annot.U1);
3598 if (SeenLowAddress && SeenHighAddress) {
3599 SeenLowAddress =
false;
3600 SeenHighAddress =
false;
3601 InlinedFunction->
addObject(LowPC, HighPC);
3605 Reader->addInlineeLines(InlinedFunction,
InlineeLines);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Lower Kernel Arguments
OptimizedStructLayoutField Field
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Provides read only access to a subclass of BinaryStream.
This is an important base class in LLVM.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringRef getName() const
void setName(const Init *Name)
virtual void printString(StringRef Value)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Value(Type *Ty, unsigned scid)
TypeIndex getElementType() const
TypeIndex getIndexType() const
StringRef getName() const
uint8_t getBitSize() const
TypeIndex getType() const
uint8_t getBitOffset() const
@ CurrentDirectory
Absolute CWD path.
@ SourceFile
Path to main source file, relative or absolute.
ArrayRef< TypeIndex > getArgs() const
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
uint8_t getLanguage() const
uint32_t getFlags() const
CompileSym3Flags getFlags() const
SourceLanguage getLanguage() const
Represents a read-only view of a CodeView string table.
LLVM_ABI Expected< StringRef > getString(uint32_t Offset) const
DefRangeFramePointerRelHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
S_DEFRANGE_REGISTER_REL_INDIR.
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
bool hasSpilledUDTMember() const
DefRangeRegisterRelIndirHeader Hdr
LocalVariableAddrRange Range
DefRangeRegisterRelHeader Hdr
bool hasSpilledUDTMember() const
uint32_t getRelocationOffset() const
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
DefRangeRegisterHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldRegisterHeader Hdr
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
LocalVariableAddrRange Range
uint32_t getSignature() const
RegisterId getLocalFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to local variables.
RegisterId getParamFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to parameters.
FrameProcedureOptions Flags
Provides amortized O(1) random access to a CodeView type stream.
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
TypeIndex getContinuationIndex() const
TypeIndex getReturnType() const
int32_t getThisPointerAdjustment() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
TypeIndex getThisType() const
TypeIndex getClassType() const
std::vector< OneMethodRecord > Methods
For method overload sets. LF_METHOD.
bool isRValueReferenceThisPtr() const
TypeIndex getReferentType() const
MemberPointerInfo getMemberInfo() const
bool isPointerToMember() const
bool isLValueReferenceThisPtr() const
PointerMode getMode() const
uint32_t getSignature() const
StringRef getPrecompFilePath() const
uint32_t getTypesCount() const
uint32_t getStartTypeIndex() const
uint32_t getRelocationOffset() const
TypeIndex getReturnType() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
ArrayRef< TypeIndex > getIndices() const
TypeIndex getFieldList() const
static Error deserializeAs(CVType &CVT, T &Record)
static TypeIndex fromArrayIndex(uint32_t Index)
SimpleTypeKind getSimpleKind() const
void setIndex(uint32_t I)
static const uint32_t FirstNonSimpleIndex
static LLVM_ABI StringRef simpleTypeName(TypeIndex TI)
uint32_t getIndex() const
StringRef getName() const
const GUID & getGuid() const
void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks)
virtual Error visitUnknownMember(CVMemberRecord &Record)
virtual Error visitMemberEnd(CVMemberRecord &Record)
virtual Error visitMemberBegin(CVMemberRecord &Record)
TypeIndex getSourceFile() const
uint16_t getModule() const
uint32_t getLineNumber() const
uint32_t getLineNumber() const
TypeIndex getSourceFile() const
TypeIndex getType() const
uint32_t getVFPtrOffset() const
TypeIndex getOverriddenVTable() const
ArrayRef< StringRef > getMethodNames() const
StringRef getName() const
TypeIndex getCompleteClass() const
uint32_t getEntryCount() const
Stores all information relating to a compile unit, be it in its original instance in the object file ...
static StringRef getSymbolKindName(SymbolKind Kind)
virtual void setCount(int64_t Value)
virtual void setBitSize(uint32_t Size)
LVScope * getFunctionParent() const
virtual void updateLevel(LVScope *Parent, bool Moved=false)
virtual int64_t getCount() const
void setInlineCode(uint32_t Code)
virtual void setReference(LVElement *Element)
void setName(StringRef ElementName) override
StringRef getName() const override
void setType(LVElement *Element=nullptr)
void setFilenameIndex(size_t Index)
LLVM_ABI Error visitKnownRecord(CVType &Record, ArgListRecord &Args, TypeIndex TI, LVElement *Element)
LLVM_ABI void printRecords(raw_ostream &OS) const
LLVM_ABI void printTypeEnd(CVType &Record)
LLVM_ABI Error visitMemberRecord(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks, TypeIndex TI, LVElement *Element)
LLVM_ABI Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base, TypeIndex TI, LVElement *Element)
LLVM_ABI void printMemberEnd(CVMemberRecord &Record)
LLVM_ABI Error inlineSiteAnnotation(LVScope *AbstractFunction, LVScope *InlinedFunction, InlineSiteSym &InlineSite)
LLVM_ABI LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W, llvm::pdb::InputFile &Input)
LLVM_ABI void printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx)
LLVM_ABI Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI)
void pushScope(LVScope *Scope)
LLVM_ABI Error visitUnknownType(CVType &Record, TypeIndex TI)
LLVM_ABI void processNamespaces()
LLVM_ABI void addElement(LVScope *Scope, bool IsCompileUnit)
LLVM_ABI void printTypeBegin(CVType &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
LLVM_ABI void processLines()
LLVM_ABI LVElement * getElement(uint32_t StreamIdx, TypeIndex TI, LVScope *Parent=nullptr)
LLVM_ABI void printMemberBegin(CVMemberRecord &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
LLVM_ABI Error finishVisitation(CVType &Record, TypeIndex TI, LVElement *Element)
LLVM_ABI LVElement * createElement(TypeLeafKind Kind)
LLVM_ABI void processFiles()
LVScope * getParentScope() const
void setOffset(LVOffset DieOffset)
LVOffset getOffset() const
void setLineNumber(uint32_t Number)
void setTag(dwarf::Tag Tag)
virtual bool isSystemEntry(LVElement *Element, StringRef Name={}) const
LVScopeCompileUnit * getCompileUnit() const
void addElement(LVElement *Element)
void addObject(LVLocation *Location)
const LVLocations * getRanges() const
void getLinkageName(uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
void printRelocatedField(StringRef Label, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
DebugStringTableSubsectionRef getStringTable() override
StringRef getFileNameForFileOffset(uint32_t FileOffset) override
Error visitSymbolEnd(CVSymbol &Record) override
Error visitKnownRecord(CVSymbol &Record, BlockSym &Block) override
Error visitSymbolBegin(CVSymbol &Record) override
Error visitUnknownSymbol(CVSymbol &Record) override
Action to take on unknown symbols. By default, they are ignored.
Error visitMemberEnd(CVMemberRecord &Record) override
Error visitUnknownMember(CVMemberRecord &Record) override
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Error visitMemberBegin(CVMemberRecord &Record) override
Error visitKnownRecord(CVType &Record, BuildInfoRecord &Args) override
Error visitUnknownType(CVType &Record) override
Action to take on unknown types. By default, they are ignored.
This class implements an extremely fast bulk output stream that can only output to a stream.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
@ ChangeCodeLengthAndCodeOffset
@ ChangeCodeOffsetAndLineOffset
PointerMode
Equivalent to CV_ptrmode_e.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
CVRecord< TypeLeafKind > CVType
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
LLVM_ABI EnumStrings< SourceLanguage, 1 > getSourceLanguageNames()
LLVM_ABI EnumStrings< unsigned, 1 > getCPUTypeNames()
LLVM_ABI EnumStrings< uint16_t, 1 > getJumpTableEntrySizeNames()
CVRecord< SymbolKind > CVSymbol
bool symbolEndsScope(SymbolKind Kind)
Return true if this ssymbol ends a scope.
LLVM_ABI EnumStrings< uint16_t, 1 > getLocalFlagNames()
MethodOptions
Equivalent to CV_fldattr_t bitfield.
LLVM_ABI EnumStrings< uint32_t, 1 > getCompileSym3FlagNames()
MemberAccess
Source-level access specifier. (CV_access_e)
bool symbolOpensScope(SymbolKind Kind)
Return true if this symbol opens a scope.
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
LLVM_ABI EnumStrings< SymbolKind, 1 > getSymbolTypeNames()
bool isAggregate(CVType CVT)
Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, LF_CLASS, LF_INTERFACE,...
LLVM_ABI EnumStrings< uint16_t, 1 > getRegisterNames(CPUType Cpu)
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
LLVM_ABI uint64_t getSizeInBytesForTypeRecord(CVType CVT)
Given an arbitrary codeview type, return the type's size in the case of aggregate (LF_STRUCTURE,...
LLVM_ABI EnumStrings< uint8_t, 1 > getProcSymFlagNames()
LLVM_ABI EnumStrings< TypeLeafKind, 1 > getTypeLeafNames()
LLVM_ABI uint64_t getSizeInBytesForTypeIndex(TypeIndex TI)
Given an arbitrary codeview type index, determine its size.
LLVM_ABI TypeIndex getModifiedType(const CVType &CVT)
Given a CVType which is assumed to be an LF_MODIFIER, return the TypeIndex of the type that the LF_MO...
SourceLanguage
These values correspond to the CV_CFL_LANG enumeration in the Microsoft Debug Interface Access SDK,...
LLVM_ABI void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types)
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
@ DW_INL_declared_inlined
constexpr Tag DW_TAG_unaligned
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
static TypeIndex getTrueType(TypeIndex &TI)
std::vector< TypeIndex > LVLineRecords
std::set< SymbolKind > LVSymbolKinds
static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI)
constexpr unsigned int DWARF_CHAR_BIT
LLVM_ABI LVStringRefs getAllLexicalComponents(StringRef Name)
std::vector< StringRef > LVStringRefs
LLVM_ABI std::string transformPath(StringRef Path)
LLVM_ABI LVLexicalComponent getInnerComponent(StringRef Name)
std::tuple< LVStringRefs::size_type, LVStringRefs::size_type > LVLexicalIndex
std::set< TypeLeafKind > LVTypeKinds
SmallVector< LVLine *, 8 > LVLines
LLVM_ABI std::string getScopedName(const LVStringRefs &Components, StringRef BaseName={})
SmallVector< LVLocation *, 8 > LVLocations
@ Parameter
An inlay hint that is for a parameter.
LLVM_ABI std::string formatTypeLeafKind(codeview::TypeLeafKind K)
Print(const T &, const DataFlowGraph &) -> Print< T >
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
std::tuple< uint64_t, uint32_t > InlineSite
LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
@ Mod
The access may modify the value stored in memory.
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void consumeError(Error Err)
Consume a Error without doing anything.
DEMANGLE_ABI std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)
LVLineRecords LineRecords
LVTypeRecords TypeRecords
LVCodeViewReader * Reader
LVLogicalVisitor * Visitor
LVNamespaceDeduction NamespaceDeduction
LVSymbolKinds SymbolKinds
LVStringRecords StringRecords
LVForwardReferences ForwardReferences
A source language supported by any of the debug info representations.