30 :
DwarfUnit(GlobalData,
ID, ClangModuleName), File(File),
31 getUnitFromOffset(UnitFromOffset),
Stage(
Stage::CreatedNotLoaded),
32 AcceleratorRecords(&GlobalData.getAllocator()) {
42 :
DwarfUnit(GlobalData,
ID, ClangModuleName), File(File),
43 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
45 AcceleratorRecords(&GlobalData.getAllocator()) {
53 if (std::optional<DWARFFormValue> Val = CUDie.
find(dwarf::DW_AT_language)) {
84 Info.unsetFlagsWhichSetDuringLiveAnalysis();
90 Dependencies.reset(
nullptr);
97 AcceleratorRecords.
erase();
101 DebugAddrIndexMap.
clear();
126 bool IsODRUnavailableFunctionScope) {
133 bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
135 if (DieInfo.getIsInMouduleScope())
136 ChildInfo.setIsInMouduleScope();
138 if (DieInfo.getIsInFunctionScope())
139 ChildInfo.setIsInFunctionScope();
141 if (DieInfo.getIsInAnonNamespaceScope())
142 ChildInfo.setIsInAnonNamespaceScope();
144 switch (CurChild->getTag()) {
145 case dwarf::DW_TAG_module:
146 ChildInfo.setIsInMouduleScope();
147 if (DieEntry->
getTag() == dwarf::DW_TAG_compile_unit &&
152 case dwarf::DW_TAG_subprogram:
153 ChildInfo.setIsInFunctionScope();
154 if (!ChildIsODRUnavailableFunctionScope &&
155 !ChildInfo.getIsInMouduleScope()) {
157 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
158 ChildIsODRUnavailableFunctionScope =
true;
161 case dwarf::DW_TAG_namespace: {
164 if (
find(CurChild, dwarf::DW_AT_extension))
167 if (!NamespaceEntry.
CU->
find(NamespaceEntry.
DieEntry, dwarf::DW_AT_name))
168 ChildInfo.setIsInAnonNamespaceScope();
175 ChildInfo.setTrackLiveness();
177 if ((!ChildInfo.getIsInAnonNamespaceScope() &&
178 !ChildIsODRUnavailableFunctionScope && !NoODR))
179 ChildInfo.setODRAvailable();
181 if (CurChild->hasChildren())
182 analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
193 if (It == ResolvedFullPaths.
end()) {
194 std::string OrigFileName;
197 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
200 assert(FoundFileName &&
"Must get file name from line table");
210 ResolvedParentPaths.find(ParentPath);
211 if (ParentIt == ResolvedParentPaths.end()) {
216 .insert({ParentPath, GlobalStrings.
insert(RealPath).first})
224 It = ResolvedFullPaths
226 FileIdx, GlobalStrings.
insert(ResolvedPath).first))
240 ResolvedParentPaths.clear();
245 Dependencies.reset(
nullptr);
259 Result +=
"/Toolchains";
266 if (!Language || Language != dwarf::DW_LANG_Swift)
274 if (!Path.endswith(
".swiftinterface"))
286 if (!Toolchain.
empty() && Path.startswith(Toolchain))
288 if (std::optional<DWARFFormValue> Val =
find(DieEntry, dwarf::DW_AT_name)) {
303 if (!Entry.empty() && Entry != ResolvedPath) {
305 warn(
Twine(
"conflicting parseable interfaces for Swift Module ") + *
Name +
306 ": " + Entry +
" and " + Path +
".",
309 Entry = std::string(ResolvedPath.
str());
331 assert(ChildInfo.getODRAvailable());
334 ChildrenIndexAssigner.getChildIndex(*
this, CurChild)))
337 if (
Error Err = assignTypeNamesRec(CurChild, NameBuilder))
345 if (std::optional<SectionDescriptor *> DebugInfoSection =
357 ->ListDebugULEB128DieRefPatch.forEach(
366 if (std::optional<SectionDescriptor *> DebugLocSection =
369 ->ListDebugULEB128DieRefPatch.forEach(
378 if (std::optional<SectionDescriptor *> DebugLocListsSection =
380 (*DebugLocListsSection)
381 ->ListDebugULEB128DieRefPatch.forEach(
394 if (std::optional<DWARFFormValue::UnitOffset>
Ref =
396 if (
Ref->Unit == OrigUnit) {
398 if (std::optional<uint32_t> RefDieIdx =
403 Ref->Unit ?
Ref->Unit->getOffset() +
Ref->Offset :
Ref->Offset;
404 if (
CompileUnit *RefCU = getUnitFromOffset(RefDIEOffset)) {
407 if (std::optional<uint32_t> RefDieIdx =
410 }
else if (CanResolveInterCUReferences) {
414 enum Stage ReferredCUStage = RefCU->getStage();
415 if (ReferredCUStage < Stage::Loaded || ReferredCUStage >
Stage::Cloned)
418 if (std::optional<uint32_t> RefDieIdx =
419 RefCU->getDIEIndexForOffset(RefDIEOffset))
432 if (std::optional<DWARFFormValue> AttrVal =
find(DieEntry, Attr))
440 std::lock_guard<std::mutex> Guard(RangesMutex);
442 Ranges.
insert({FuncLowPc, FuncHighPc}, PcOffset);
444 LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
446 LowPc = FuncLowPc + PcOffset;
447 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
451 std::lock_guard<std::mutex> Guard(LabelsMutex);
452 Labels.
insert({LabelLowPc, PcOffset});
472 if (!DebugInfoSection.ListDebugLocPatch.empty()) {
477 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
479 DebugInfoSection.ListDebugLocPatch.forEach([&](
DebugLocPatch &Patch) {
488 if (!OriginalLocations) {
489 warn(OriginalLocations.takeError());
493 LinkedLocationExpressionsVector LinkedLocationExpressions;
495 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
497 if (CurExpression.Range) {
499 LinkedExpression.Expression.Range = {
510 LinkedExpression.Expression.Expr,
512 LinkedExpression.Patches);
514 LinkedLocationExpressions.push_back({LinkedExpression});
519 OutLocationSection.
OS.
tell());
520 emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
523 if (OffsetAfterUnitLength > 0) {
524 assert(OffsetAfterUnitLength -
526 OffsetAfterUnitLength);
527 OutLocationSection.
apply(
528 OffsetAfterUnitLength -
530 dwarf::DW_FORM_sec_offset,
531 OutLocationSection.
OS.
tell() - OffsetAfterUnitLength);
557 return OffsetAfterUnitLength;
561uint64_t CompileUnit::emitLocListFragment(
562 const LinkedLocationExpressionsVector &LinkedLocationExpression,
564 uint64_t OffsetBeforeLocationExpression = 0;
568 if (std::optional<uint64_t> LowPC =
getLowPc())
569 BaseAddress = *LowPC;
571 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
572 LinkedLocationExpression) {
573 if (LocExpression.Expression.Range) {
575 LocExpression.Expression.Range->LowPC - BaseAddress,
578 LocExpression.Expression.Range->HighPC - BaseAddress,
582 OutLocationSection.
emitIntVal(LocExpression.Expression.Expr.size(), 2);
583 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
584 for (
uint64_t *OffsetPtr : LocExpression.Patches)
585 *OffsetPtr += OffsetBeforeLocationExpression;
587 OutLocationSection.
OS
588 <<
StringRef((
const char *)LocExpression.Expression.Expr.data(),
589 LocExpression.Expression.Expr.size());
597 return OffsetBeforeLocationExpression;
600 std::optional<uint64_t> BaseAddress;
601 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
602 LinkedLocationExpression) {
603 if (LocExpression.Expression.Range) {
607 BaseAddress = LocExpression.Expression.Range->LowPC;
610 OutLocationSection.
emitIntVal(dwarf::DW_LLE_base_addressx, 1);
612 OutLocationSection.
OS);
616 OutLocationSection.
emitIntVal(dwarf::DW_LLE_offset_pair, 1);
619 encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
620 OutLocationSection.
OS);
623 encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
624 OutLocationSection.
OS);
627 OutLocationSection.
emitIntVal(dwarf::DW_LLE_default_location, 1);
629 encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.
OS);
630 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
631 for (
uint64_t *OffsetPtr : LocExpression.Patches)
632 *OffsetPtr += OffsetBeforeLocationExpression;
635 (
const char *)LocExpression.Expression.Expr.data(),
636 LocExpression.Expression.Expr.size());
640 OutLocationSection.
emitIntVal(dwarf::DW_LLE_end_of_list, 1);
641 return OffsetBeforeLocationExpression;
644Error CompileUnit::emitDebugAddrSection() {
651 if (DebugAddrIndexMap.
empty())
677 OutAddrSection.
apply(
678 OffsetAfterSectionLength -
680 dwarf::DW_FORM_sec_offset,
681 OutAddrSection.
OS.
tell() - OffsetAfterSectionLength);
693 LinkedFunctionRanges.
insert(
694 {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
696 emitAranges(LinkedFunctionRanges);
714 if (!DebugInfoSection.ListDebugRangePatch.empty()) {
715 std::optional<AddressRangeValuePair> CachedRange;
716 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
719 DebugInfoSection.ListDebugRangePatch.forEach([&](
DebugRangePatch &Patch) {
721 CompileUnitRangePtr = &Patch;
725 AddressRanges LinkedRanges;
726 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
728 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
729 if (Expected<DWARFAddressRangesVector> InputRanges =
730 getOrigUnit().findRnglistFromOffset(
731 InputDebugRangesSectionOffset)) {
733 for (const auto &Range : *InputRanges) {
734 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
736 getFunctionRanges().getRangeThatContains(Range.LowPC);
740 warn(
"inconsistent range data.");
745 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
746 Range.HighPC + CachedRange->Value});
749 llvm::consumeError(InputRanges.takeError());
750 warn(
"invalid range list ignored.");
755 OutRangeSection.
OS.
tell());
756 emitRangeListFragment(LinkedRanges, OutRangeSection);
760 if (CompileUnitRangePtr !=
nullptr) {
764 dwarf::DW_FORM_sec_offset,
765 OutRangeSection.
OS.
tell());
766 emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
769 if (OffsetAfterUnitLength > 0) {
770 assert(OffsetAfterUnitLength -
772 OffsetAfterUnitLength);
773 OutRangeSection.
apply(
774 OffsetAfterUnitLength -
776 dwarf::DW_FORM_sec_offset,
777 OutRangeSection.
OS.
tell() - OffsetAfterUnitLength);
802 return OffsetAfterUnitLength;
805void CompileUnit::emitRangeListFragment(
const AddressRanges &LinkedRanges,
810 if (std::optional<uint64_t> LowPC =
getLowPc())
811 BaseAddress = *LowPC;
826 std::optional<uint64_t> BaseAddress;
829 BaseAddress =
Range.start();
832 OutRangeSection.
emitIntVal(dwarf::DW_RLE_base_addressx, 1);
837 OutRangeSection.
emitIntVal(dwarf::DW_RLE_offset_pair, 1);
847 OutRangeSection.
emitIntVal(dwarf::DW_RLE_end_of_list, 1);
850void CompileUnit::emitAranges(
AddressRanges &LinkedFunctionRanges) {
851 if (LinkedFunctionRanges.
empty())
871 uint64_t OffsetAfterArangesLengthField = OutArangesSection.
OS.
tell();
874 OutArangesSection.notePatch(
885 for (
const AddressRange &Range : LinkedFunctionRanges) {
899 OutArangesSection.
apply(
900 OffsetAfterArangesLengthField -
902 dwarf::DW_FORM_sec_offset,
903 OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
914 if (std::optional<uint64_t> MacroAttr =
918 emitMacroTableImpl(Table, *MacroAttr,
true);
923 if (std::optional<uint64_t> MacroAttr =
927 emitMacroTableImpl(Table, *MacroAttr,
false);
936 bool hasDWARFv5Header) {
942 bool DefAttributeIsReported =
false;
943 bool UndefAttributeIsReported =
false;
944 bool ImportAttributeIsReported =
false;
946 for (
const DWARFDebugMacro::MacroList &
List : MacroTable->MacroLists) {
947 if (OffsetToMacroTable ==
List.Offset) {
949 if (hasDWARFv5Header) {
953 uint8_t Flags =
List.Header.Flags;
957 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
960 warn(
"opcode_operands_table is not supported yet.");
964 std::optional<uint64_t> StmtListOffset;
965 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
968 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
969 StmtListOffset = V.getDIEInteger().getValue();
974 if (!StmtListOffset) {
976 warn(
"couldn`t find line table for macro table.");
984 if (StmtListOffset) {
995 for (
const DWARFDebugMacro::Entry &MacroEntry :
List.Macros) {
996 if (MacroEntry.Type == 0) {
1001 uint8_t MacroType = MacroEntry.Type;
1002 switch (MacroType) {
1004 bool HasVendorSpecificExtension =
1005 (!hasDWARFv5Header &&
1010 if (HasVendorSpecificExtension) {
1018 OutSection.
emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1020 warn(
"unknown macro type. skip.");
1028 case dwarf::DW_MACRO_define:
1029 case dwarf::DW_MACRO_undef: {
1037 OutSection.
emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1039 case dwarf::DW_MACRO_define_strp:
1040 case dwarf::DW_MACRO_undef_strp:
1041 case dwarf::DW_MACRO_define_strx:
1042 case dwarf::DW_MACRO_undef_strx: {
1045 switch (MacroType) {
1046 case dwarf::DW_MACRO_define_strx: {
1047 MacroType = dwarf::DW_MACRO_define_strp;
1048 if (!DefAttributeIsReported) {
1049 warn(
"DW_MACRO_define_strx unsupported yet. Convert to "
1050 "DW_MACRO_define_strp.");
1051 DefAttributeIsReported =
true;
1054 case dwarf::DW_MACRO_undef_strx: {
1055 MacroType = dwarf::DW_MACRO_undef_strp;
1056 if (!UndefAttributeIsReported) {
1057 warn(
"DW_MACRO_undef_strx unsupported yet. Convert to "
1058 "DW_MACRO_undef_strp.");
1059 UndefAttributeIsReported =
true;
1074 OutSection.
emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1077 case dwarf::DW_MACRO_start_file: {
1085 case dwarf::DW_MACRO_end_file: {
1089 case dwarf::DW_MACRO_import:
1090 case dwarf::DW_MACRO_import_sup: {
1091 if (!ImportAttributeIsReported) {
1092 warn(
"DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1094 ImportAttributeIsReported =
true;
1108 std::optional<int64_t> VarAddressAdjustment,
1116 for (
auto &
Op : InputExpression) {
1122 Desc.
Op[0] != Encoding::Size1))
1123 warn(
"unsupported DW_OP encoding.");
1127 Desc.
Op[0] == Encoding::Size1)) {
1145 unsigned RealSize = 0;
1149 if (RefOffset > 0 ||
Op.
getCode() != dwarf::DW_OP_convert) {
1152 if (std::optional<uint32_t>
Idx =
1162 Section.notePatchWithOffsetUpdate(
1169 if (RealSize > ULEBsize) {
1172 warn(
"base type ref doesn't fit.");
1174 assert(RealSize == ULEBsize &&
"padding failed");
1177 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1179 if (std::optional<object::SectionedAddress> SA =
1185 OutputExpression.
push_back(dwarf::DW_OP_addr);
1187 SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1191 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1192 OrigAddressByteSize);
1193 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1195 warn(
"cann't read DW_OP_addrx operand.");
1196 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1198 if (std::optional<object::SectionedAddress> SA =
1204 std::optional<uint8_t> OutOperandKind;
1205 switch (OrigAddressByteSize) {
1207 OutOperandKind = dwarf::DW_OP_const2u;
1210 OutOperandKind = dwarf::DW_OP_const4u;
1213 OutOperandKind = dwarf::DW_OP_const8u;
1217 formatv((
"unsupported address size: {0}."), OrigAddressByteSize));
1221 if (OutOperandKind) {
1222 OutputExpression.
push_back(*OutOperandKind);
1224 SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1228 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1229 OrigAddressByteSize);
1230 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1233 warn(
"cann't read DW_OP_constx operand.");
1253 if (ArtificialTypeUnit)
1257 std::pair<DIE *, TypeEntry *> OutCUDie =
cloneDIE(
1259 std::nullopt, std::nullopt,
Allocator, ArtificialTypeUnit);
1262 if (
getGlobalData().getOptions().NoOutput || (OutCUDie.first ==
nullptr))
1265 assert(TargetTriple.has_value());
1286 if (
Error Err = emitDebugAddrSection())
1302 uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1308 bool NeedToClonePlainDIE =
Info.needToKeepInPlainDwarf();
1309 bool NeedToCloneTypeDIE =
1310 (InputDieEntry->
getTag() != dwarf::DW_TAG_compile_unit) &&
1311 Info.needToPlaceInTypeTable();
1312 std::pair<DIE *, TypeEntry *> ClonedDIE;
1316 if (NeedToClonePlainDIE)
1319 ClonedDIE.first = createPlainDIEandCloneAttributes(
1320 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1321 VarAddressAdjustment);
1322 if (NeedToCloneTypeDIE) {
1325 assert(ArtificialTypeUnit !=
nullptr);
1329 ClonedDIE.second = createTypeDIEandCloneAttributes(
1330 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1331 ArtificialTypeUnit);
1334 ClonedDIE.
second ? ClonedDIE.second : ClonedParentTypeDIE;
1336 bool HasPlainChildrenToClone =
1337 (ClonedDIE.first &&
Info.getKeepPlainChildren());
1339 bool HasTypeChildrenToClone =
1340 ((ClonedDIE.second ||
1341 InputDieEntry->
getTag() == dwarf::DW_TAG_compile_unit) &&
1342 Info.getKeepTypeChildren());
1345 if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1350 std::pair<DIE *, TypeEntry *> ClonedChild =
cloneDIE(
1351 CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
1352 VarAddressAdjustment,
Allocator, ArtificialTypeUnit);
1354 if (ClonedChild.first) {
1356 ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1357 PlainDIEGenerator.
addChild(ClonedChild.first);
1360 assert(ClonedDIE.first ==
nullptr ||
1361 HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1364 if (HasPlainChildrenToClone)
1365 OutOffset +=
sizeof(int8_t);
1369 if (ClonedDIE.first !=
nullptr)
1370 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1375DIE *CompileUnit::createPlainDIEandCloneAttributes(
1377 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1378 std::optional<int64_t> &VarAddressAdjustment) {
1381 DIE *ClonedDIE =
nullptr;
1382 bool HasLocationExpressionAddress =
false;
1383 if (InputDieEntry->
getTag() == dwarf::DW_TAG_subprogram) {
1385 FuncAddressAdjustment =
1388 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_label) {
1390 std::optional<uint64_t> lowPC =
1394 if (It != Labels.
end())
1395 FuncAddressAdjustment = It->second;
1397 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_variable) {
1399 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1403 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1404 if (LocExprAddrAndRelocAdjustment.first &&
1405 LocExprAddrAndRelocAdjustment.second)
1406 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1409 ClonedDIE = PlainDIEGenerator.
createDIE(InputDieEntry->
getTag(), OutOffset);
1417 PlainDIEGenerator, FuncAddressAdjustment,
1418 VarAddressAdjustment,
1419 HasLocationExpressionAddress);
1420 AttributesCloner.clone();
1424 AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1428 AttributesCloner.finalizeAbbreviations(
Info.getKeepPlainChildren());
1437 bool IsParentDeclaration) {
1438 DIE *DefinitionDie = TypeDescriptor->
Die;
1446 if (IsDeclaration && !DeclarationDie) {
1449 if (TypeDescriptor->
DeclarationDie.compare_exchange_weak(DeclarationDie,
1452 }
else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
1456 OldParentIsDeclaration,
false)) {
1461 }
else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
1465 if (TypeDescriptor->
DeclarationDie.compare_exchange_weak(DeclarationDie,
1468 }
else if (!IsDeclaration && !IsParentDeclaration) {
1471 if (TypeDescriptor->
Die.compare_exchange_weak(DefinitionDie, NewDie)) {
1480TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1483 assert(ArtificialTypeUnit !=
nullptr);
1487 assert(Entry !=
nullptr);
1488 assert(ClonedParentTypeDIE !=
nullptr);
1491 Entry, ClonedParentTypeDIE);
1494 bool IsDeclaration =
1497 bool ParentIsDeclaration =
false;
1498 if (std::optional<uint32_t> ParentIdx = InputDieEntry->
getParentIdx())
1499 ParentIsDeclaration =
1503 allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->
getTag(),
1504 IsDeclaration, ParentIsDeclaration);
1506 if (OutDIE !=
nullptr) {
1507 assert(ArtificialTypeUnit !=
nullptr);
1511 InputDieEntry, TypeDIEGenerator,
1512 std::nullopt, std::nullopt,
false);
1513 AttributesCloner.clone();
1517 ArtificialTypeUnit);
1518 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1523 OutDIE->
setSize(AttributesCloner.getOutOffset() + 1);
1532 if (InputLineTable ==
nullptr) {
1534 warn(
"cann't load line table.");
1546 OutLineTable.
Rows = InputLineTable->
Rows;
1549 if (OutLineTable.
Rows.size() == 1 && OutLineTable.
Rows[0].EndSequence)
1550 OutLineTable.
Rows.clear();
1555 std::vector<DWARFDebugLine::Row> NewRows;
1556 NewRows.reserve(InputLineTable->
Rows.size());
1560 std::vector<DWARFDebugLine::Row> Seq;
1563 std::optional<AddressRangeValuePair> CurrRange;
1582 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1586 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1587 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1588 if (StopAddress != -1ULL && !Seq.empty()) {
1591 auto NextLine = Seq.back();
1592 NextLine.Address.Address = StopAddress;
1593 NextLine.EndSequence = 1;
1594 NextLine.PrologueEnd = 0;
1595 NextLine.BasicBlock = 0;
1596 NextLine.EpilogueBegin = 0;
1597 Seq.push_back(NextLine);
1598 insertLineSequence(Seq, NewRows);
1606 if (Row.EndSequence && Seq.empty())
1610 Row.Address.Address += CurrRange->Value;
1611 Seq.emplace_back(Row);
1613 if (Row.EndSequence)
1614 insertLineSequence(Seq, NewRows);
1617 OutLineTable.
Rows = std::move(NewRows);
1623void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1624 std::vector<DWARFDebugLine::Row> &Rows) {
1628 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1642 if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1643 InsertPoint->EndSequence) {
1644 *InsertPoint = Seq.front();
1645 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
1647 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1653#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1673 llvm::errs() <<
" KeepPlainChildren: " << getKeepPlainChildren();
1674 llvm::errs() <<
" KeepTypeChildren: " << getKeepTypeChildren();
1675 llvm::errs() <<
" IsInMouduleScope: " << getIsInMouduleScope();
1676 llvm::errs() <<
" IsInFunctionScope: " << getIsInFunctionScope();
1677 llvm::errs() <<
" IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1678 llvm::errs() <<
" ODRAvailable: " << getODRAvailable();
1679 llvm::errs() <<
" TrackLiveness: " << getTrackLiveness();
1684std::optional<std::pair<StringRef, StringRef>>
1695 return std::nullopt;
1708std::optional<std::pair<StringRef, StringRef>>
1712 return std::make_pair(
StringRef(FileData->second.first),
1717 if (LineTable->hasFileAtIndex(FileIdx)) {
1720 LineTable->Prologue.getFileNameEntry(FileIdx);
1725 return std::nullopt;
1728 std::string FileName = *
Name;
1734 std::make_pair(std::string(
""), std::move(FileName))))
1736 return std::make_pair(
StringRef(FileData->second.first),
1746 if ((Entry.DirIdx != 0) &&
1747 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1749 LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1752 IncludeDir = *DirName;
1755 return std::nullopt;
1759 if (0 < Entry.DirIdx &&
1760 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1762 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1765 IncludeDir = *DirName;
1768 return std::nullopt;
1784 std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
1785 std::move(FileName))))
1787 return std::make_pair(
StringRef(FileData->second.first),
1792 return std::nullopt;
1795#define MAX_REFERENCIES_DEPTH 1000
1798 std::optional<UnitEntryPairTy> RefDiePair;
1802 CUDiePair.
DieEntry, dwarf::DW_AT_extension,
1804 if (!RefDiePair || !RefDiePair->DieEntry)
1807 CUDiePair = *RefDiePair;
1814 if (std::optional<uint32_t> ParentIdx = DieEntry->
getParentIdx())
1817 return std::nullopt;
1831 return getAsCompileUnit();
1833 return getAsTypeUnit();
1853 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1854 if (!Dependencies.get())
1857 return Dependencies->resolveDependenciesAndMarkLiveness(
1858 InterCUProcessingStarted, HasNewInterconnectedCUs);
1862 assert(Dependencies.get());
1864 return Dependencies.get()->updateDependenciesCompleteness();
1868 assert(Dependencies.get());
1870 Dependencies.get()->verifyKeepChain();
1875 dwarf::DW_AT_type, dwarf::DW_AT_specification,
1876 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};
1878 return ODRAttributes;
Analysis containing CSE Info
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
#define MAX_REFERENCIES_DEPTH
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Mark the given Function as meaning that it cannot be changed in any way mark any values that are used as this function s parameters or by its return values(according to Uses) live as well. void DeadArgumentEliminationPass
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A class that represents an address range.
void insert(AddressRange Range, int64_t Value)
The AddressRanges class helps normalize address range collections.
Collection::const_iterator insert(AddressRange Range)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Allocate memory in an ever growing pool, as if by bump-pointer.
CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, StringRef ClangModuleName)
std::pair< KeyDataTy *, bool > insert(const KeyTy &NewValue)
Insert new value NewValue or return already existing entry.
A structured debug information entry.
DWARFDebugInfoEntry - A DIE with only the minimum required data.
dwarf::Tag getTag() const
std::optional< uint32_t > getParentIdx() const
Returns index of the parent die.
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
const DWARFDebugInfoEntry * getDebugInfoEntry() const
const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
This class represents an Operation in the Expression.
std::optional< unsigned > getSubCode() const
uint64_t getEndOffset() const
Encoding
Size and signedness of expression operations' operands.
const Description & getDescription() const
uint64_t getRawOperand(unsigned Idx) const
StringRef getData() const
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
Return DWARFDebugInfoEntry for the specified index Index.
const dwarf::FormParams & getFormParams() const
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
uint8_t getAddressByteSize() const
const char * getCompilationDir()
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
Return the DIE index for a given offset Offset inside the unit's DIE vector.
Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)
bool isLittleEndian() const
std::optional< object::SectionedAddress > getAddrOffsetSectionItem(uint32_t Index) const
uint64_t getOffset() const
iterator find(const_arg_type_t< KeyT > Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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.
Error takeError()
Take ownership of the stored error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class helps to store information for accelerator entries.
TypeUnit * getAsTypeUnit()
Returns TypeUnit if applicable.
DwarfUnit * operator->()
Accessor for common functionality.
CompileUnit * getAsCompileUnit()
Returns CompileUnit if applicable.
OutputUnitVariantPtr(CompileUnit *U)
Stores all information related to a compile unit, be it in its original instance of the object file o...
Error cloneAndEmitDebugLocations()
Clone and emit debug locations(.debug_loc/.debug_loclists).
void cloneDieAttrExpression(const DWARFExpression &InputExpression, SmallVectorImpl< uint8_t > &OutputExpression, SectionDescriptor &Section, std::optional< int64_t > VarAddressAdjustment, OffsetsPtrVector &PatchesOffsets)
Clone attribute location axpression.
void maybeResetToLoadedStage()
Reset compile units data(results of liveness analysis, clonning) if current stage greater than Stage:...
void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry)
Collect references to parseable Swift interfaces in imported DW_TAG_module blocks.
Stage
The stages of new compile unit processing.
@ Cloned
Output DWARF is generated.
@ CreatedNotLoaded
Created, linked with input DWARF file.
@ Loaded
Input DWARF is loaded.
std::pair< DIE *, TypeEntry * > cloneDIE(const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset, std::optional< int64_t > FuncAddressAdjustment, std::optional< int64_t > VarAddressAdjustment, BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit)
void cleanupDataAfterClonning()
Cleanup unneeded resources after compile unit is cloned.
Error assignTypeNames(TypePool &TypePoolRef)
Search for type entries and assign names.
@ TypeTable
Corresponding DIE goes to the type table only.
@ PlainDwarf
Corresponding DIE goes to the plain dwarf only.
@ Both
Corresponding DIE goes to type table and to plain dwarf.
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset)
Add a function range [LowPC, HighPC) that is relocated by applying offset PCOffset.
Error cloneAndEmitRanges()
Clone and emit ranges.
Stage getStage() const
Returns stage of overall processing.
const RangesTy & getFunctionRanges() const
Returns function ranges of this unit.
void updateDieRefPatchesWithClonedOffsets()
After cloning stage the output DIEs offsets are deallocated.
bool resolveDependenciesAndMarkLiveness(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)
Search for subprograms and variables referencing live code and discover dependend DIEs.
bool updateDependenciesCompleteness()
Check dependend DIEs for incompatible placement.
bool loadInputDIEs()
Load DIEs of input compilation unit.
void setStage(Stage Stage)
Set stage of overall processing.
std::optional< uint64_t > getLowPc() const
Returns value of DW_AT_low_pc attribute.
Error cloneAndEmitDebugMacro()
Clone and emit debug macros(.debug_macinfo/.debug_macro).
uint64_t getDebugAddrIndex(uint64_t Addr)
Returns index(inside .debug_addr) of an address.
CompileUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName, DWARFFile &File, OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format, llvm::endianness Endianess)
const DWARFFile & getContaingFile() const
Returns DWARFFile containing this compile unit.
void verifyDependencies()
Check DIEs to have a consistent marking(keep marking, placement marking).
void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset)
Add the low_pc of a label that is relocated by applying offset PCOffset.
std::optional< std::pair< StringRef, StringRef > > getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue)
Returns directory and file from the line table by index.
Error cloneAndEmit(std::optional< Triple > TargetTriple, TypeUnit *ArtificialTypeUnit)
Clone and emit this compilation unit.
std::optional< UnitEntryPairTy > resolveDIEReference(const DWARFFormValue &RefValue, ResolveInterCUReferencesMode CanResolveInterCUReferences)
Resolve the DIE attribute reference that has been extracted in RefValue.
void loadLineTable()
Loads unit line table.
Error cloneAndEmitLineTable(Triple &TargetTriple)
StringEntry * getFileName(unsigned FileIdx, StringPool &GlobalStrings)
Returns name of the file for the FileIdx from the unit`s line table.
This class creates clones of input DIE attributes.
This class is a helper to create output DIE tree.
DIE * createDIE(dwarf::Tag DieTag, uint32_t OutOffset)
Creates a DIE of specified tag DieTag and OutOffset.
void addChild(DIE *Child)
Adds a specified Child to the current DIE.
This class represents DWARF information for source file and it's address map.
std::unique_ptr< DWARFContext > Dwarf
Source DWARF information.
std::unique_ptr< AddressesMap > Addresses
Helpful address information(list of valid address ranges, relocations).
@ Pub
.debug_pubnames, .debug_pubtypes
This class discovers DIEs dependencies: marks "live" DIEs, marks DIE locations (whether DIE should be...
Base class for all Dwarf units(Compile unit/Type table unit).
std::vector< std::unique_ptr< DIEAbbrev > > Abbreviations
Storage for the unique Abbreviations.
std::string UnitName
The name of this unit.
const std::string & getClangModuleName() const
Return Clang module name;.
FoldingSet< DIEAbbrev > AbbreviationsSet
FoldingSet that uniques the abbreviations.
DIE * OutUnitDIE
Output unit DIE.
LinkingGlobalData & getGlobalData()
Return global data.
bool isClangModule() const
Return true if this compile unit is from Clang module.
DIE * getOutUnitDIE()
Returns output unit DIE.
StringRef getSysRoot()
Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
void setOutUnitDIE(DIE *UnitDie)
Set output unit DIE.
std::string SysRoot
The DW_AT_LLVM_sysroot of this unit.
const SmallVector< T > & getValues()
uint64_t getValueIndex(T Value)
This class keeps data and services common for the whole linking process.
const DWARFLinkerOptions & getOptions() const
Returns linking options.
This class helps to assign indexes for DIE children.
uint16_t getVersion() const
Return DWARF version.
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness)
Sets output format for all keeping sections.
void eraseSections()
Erases data of all sections.
LinkingGlobalData & GlobalData
const SectionDescriptor & getSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
llvm::endianness getEndianness() const
Endiannes for the sections.
const dwarf::FormParams & getFormParams() const
Return size of address.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
uint16_t getDebugInfoHeaderSize() const
Return size of header of debug_info table.
dwarf::FormParams Format
Format for sections.
std::optional< const SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
The helper class to build type name based on DIE properties.
Error assignName(UnitEntryPairTy InputUnitEntryPair, std::optional< std::pair< size_t, size_t > > ChildIndex)
Create synthetic name for the specified DIE InputUnitEntryPair and assign created name to the DIE typ...
Keeps cloned data for the type DIE.
std::atomic< DIE * > DeclarationDie
std::atomic< DIE * > Die
TypeEntryBody keeps partially cloned DIEs corresponding to this type.
std::atomic< bool > ParentIsDeclaration
TypePool keeps type descriptors which contain partially cloned DIE correspinding to each type.
TypeEntry * getRoot() const
Return root for all type entries.
TypeEntryBody * getOrCreateTypeEntryBody(TypeEntry *Entry, TypeEntry *ParentEntry)
Create or return existing type entry body for the specified Entry.
BumpPtrAllocator & getThreadLocalAllocator()
Return thread local allocator used by pool.
Type Unit is used to represent an artificial compilation unit which keeps all type information.
TypePool & getTypePool()
Returns global type pool.
uint64_t tell() const
tell - Return the current offset with the file.
uint64_t getDieOutOffset(uint32_t Idx)
Idx index of the DIE.
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
TypeEntry * getDieTypeEntry(uint32_t Idx)
Idx index of the DIE.
void rememberDieOutOffset(uint32_t Idx, uint64_t Offset)
Idx index of the DIE.
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
std::optional< DWARFFormValue > find(uint32_t DieIdx, ArrayRef< dwarf::Attribute > Attrs) const
const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const
DWARFDie getDIE(const DWARFDebugInfoEntry *Die)
DWARFUnit & getOrigUnit() const
Returns paired compile unit from input DWARF.
Error emitDebugInfo(const Triple &TargetTriple)
Emit .debug_info section for unit DIEs.
void emitPubAccelerators()
Emit .debug_pubnames and .debug_pubtypes for Unit.
void warn(const Twine &Warning, const DWARFDie *DIE=nullptr)
Error emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable)
Emit .debug_line section.
Error emitDebugStringOffsetSection()
Emit the .debug_str_offsets section for current unit.
Error emitAbbreviations()
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
DebugSectionKind
List of tracked debug tables.
bool isODRLanguage(uint16_t Language)
ResolveInterCUReferencesMode
ArrayRef< dwarf::Attribute > getODRAttributes()
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
static SmallString< 128 > guessToolchainBaseDir(StringRef SysRoot)
Make a best effort to guess the Xcode.app/Contents/Developer/Toolchains/ path from an SDK path.
@ Dwarf
DWARF v5 .debug_names.
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
bool isCompileUnit(const std::unique_ptr< DWARFUnit > &U)
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool hasFileAtIndex(uint64_t FileIndex) const
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
Standard .debug_line state machine structure.
Description of the encoding of one expression Op.
SmallVector< Encoding > Op
Encoding for Op operands.
Represents a single DWARF expression, whose value is location-dependent.
Information gathered about source DIEs.
LLVM_DUMP_METHOD void dump()
DieOutputPlacement getPlacement() const
bool needToPlaceInTypeTable() const
SmallVector< DWARFLinker::AccelTableKind, 1 > AccelTables
The accelerator table kinds.
bool UpdateIndexTablesOnly
Update index tables.
bool NoODR
Do not unique types according to ODR.
DWARFLinker::SwiftInterfacesMapTy * ParseableSwiftInterfaces
A list of all .swiftinterface files referenced by the debug info, mapping Module name to path on disk...
This structure is used to update reference to the DIE.
PointerIntPair< CompileUnit *, 1 > RefCU
uint64_t RefDieIdxOrClonedOffset
This structure is used to update location list offset into .debug_loc/.debug_loclists.
int64_t AddrAdjustmentValue
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
bool IsCompileUnitRanges
Indicates patch which points to immediate compile unit's attribute.
This structure is used to update reference to the DIE of ULEB128 form.
PointerIntPair< CompileUnit *, 1 > RefCU
uint64_t RefDieIdxOrClonedOffset
This structure is used to keep data of the concrete section.
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size)
Returns integer value of Size located by specified PatchOffset.
void emitOffset(uint64_t Val)
Emit specified offset value into the current section contents.
void emitString(dwarf::Form StringForm, const char *StringVal)
raw_svector_ostream OS
Stream which stores data to the Contents.
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
void emitUnitLength(uint64_t Length)
Emit unit length into the current section contents.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
This is a helper structure which keeps a debug info entry with it's containing compilation unit.
const DWARFDebugInfoEntry * DieEntry
std::optional< UnitEntryPairTy > getParent()
UnitEntryPairTy getNamespaceOrigin()