64#define DEBUG_TYPE "dwarfdebug"
66STATISTIC(NumCSParams,
"Number of dbg call site params created");
69 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
79 cl::desc(
"Generate DWARF4 type units."),
90 cl::desc(
"Make an absence of debug location information explicit."),
98 "Default for platform"),
106 cl::desc(
"Use inlined strings rather than string section."),
114 cl::desc(
"Disable emission .debug_ranges section."),
119 cl::desc(
"Use sections+offset as references rather than labels."),
126 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
131 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
144 cl::desc(
"Which DWARF linkage-name attributes to emit."),
146 "Default for platform"),
149 "Abstract subprograms")),
154 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
155 "address pool entry sharing to reduce relocations/object size"),
157 "Default address minimization strategy"),
159 "Use rnglists for contiguous ranges if that allows "
160 "using a pre-existing base address"),
163 "Use exprloc addrx+offset expressions for any "
164 "address with a prior base address"),
166 "Use addrx+offset extension form for any address "
167 "with a prior base address"),
175 cl::desc(
"Set to false to ignore Key Instructions metadata"));
179void DebugLocDwarfExpression::emitOp(
uint8_t Op,
const char *Comment) {
185void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
186 getActiveStreamer().emitSLEB128(
Value, Twine(
Value));
189void DebugLocDwarfExpression::emitUnsigned(uint64_t
Value) {
190 getActiveStreamer().emitULEB128(
Value, Twine(
Value));
193void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
194 getActiveStreamer().emitInt8(
Value, Twine(
Value));
197void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
209 assert(!IsBuffering &&
"Already buffering?");
211 TmpBuf = std::make_unique<TempBuffer>(OutBS.GenerateComments);
218 return TmpBuf ? TmpBuf->Bytes.size() : 0;
224 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
225 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
226 ? TmpBuf->Comments[
Byte.index()].c_str()
228 OutBS.emitInt8(
Byte.value(), Comment);
230 TmpBuf->Bytes.clear();
231 TmpBuf->Comments.clear();
242 const bool IsVariadic = !SingleLocExprOpt;
245 if (!IsVariadic && !
MI->isNonListDebugValue()) {
246 assert(
MI->getNumDebugOperands() == 1 &&
247 "Mismatched DIExpression and debug operands for debug instruction.");
248 Expr = *SingleLocExprOpt;
255 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
257 }
else if (
Op.isTargetIndex()) {
260 }
else if (
Op.isImm())
262 else if (
Op.isFPImm())
264 else if (
Op.isCImm())
269 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
273 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
274 return Fragment ? Fragment->OffsetInBits : 0;
288 Expr(ValueLoc.getExpression()) {
289 if (!Expr->getNumElements())
305 return FIE.Expr && FIE.Expr->isFragment();
307 "conflicting locations for variable");
311 bool GenerateTypeUnits,
320 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
326 if (DwarfVersion >= 5)
336 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
337 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()),
339 const Triple &TT =
Asm->TM.getTargetTriple();
344 DebuggerTuning =
Asm->TM.Options.DebuggerTuning;
349 else if (TT.isOSAIX())
365 HasSplitDwarf = !
Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
373 unsigned DwarfVersionNumber =
Asm->TM.Options.MCOptions.DwarfVersion;
374 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
375 :
MMI->getModule()->getDwarfVersion();
379 bool Dwarf64 = DwarfVersion >= 3 &&
388 ((
Asm->TM.Options.MCOptions.Dwarf64 ||
MMI->getModule()->isDwarf64()) &&
389 TT.isOSBinFormatELF()) ||
390 TT.isOSBinFormatXCOFF();
392 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
401 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
402 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
406 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
413 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
415 UseDWARF2Bitfields = DwarfVersion < 4;
421 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
425 EmitDebugEntryValues =
Asm->TM.Options.ShouldEmitDebugEntryValues();
429 UseDebugMacroSection =
438 if (DwarfVersion >= 5)
441 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
450 return Name.starts_with(
"+") || Name.starts_with(
"-");
457 return Name.contains(
") ");
463 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
468 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
469 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
473 return In.slice(In.find(
' ') + 1, In.find(
']'));
486 if (!SP->isDefinition())
489 if (SP->getName() !=
"")
520 if (Scope->isAbstractScope())
538 if (
auto *SkelCU =
CU.getSkeleton())
539 if (
CU.getCUNode()->getSplitDebugInlining())
550 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
551 if (
CU.getSkeleton())
557void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
559 assert(Scope && Scope->getScopeNode());
560 assert(Scope->isAbstractScope());
561 assert(!Scope->getInlinedAt());
567 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
569 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
570 if (
auto *SkelCU =
CU.getSkeleton())
571 if (
CU.getCUNode()->getSplitDebugInlining())
572 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
606template <
typename ValT>
610 for (
auto Param : DescribedParams) {
611 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
621 "Combined debug expression is invalid");
636 auto &ParamsForFwdReg = Worklist[
Reg];
637 for (
auto Param : ParamsToAdd) {
640 return D.ParamReg == Param.ParamReg;
642 "Same parameter described twice by forwarding reg");
649 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
669 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
670 for (
auto &RegUnit : ClobberedRegUnits)
671 if (
TRI.hasRegUnit(
Reg, RegUnit))
676 auto DescribeFwdRegsByCalleeSavedCopy = [&](
const DestSourcePair &CopyInst) {
677 Register CopyDestReg = CopyInst.Destination->getReg();
678 Register CopySrcReg = CopyInst.Source->getReg();
679 if (IsRegClobberedInMeantime(CopyDestReg))
683 if (!
TRI.isCalleeSavedPhysReg(CopyDestReg, *MF))
690 for (
auto FwdRegIt = ForwardedRegWorklist.
begin();
691 FwdRegIt != ForwardedRegWorklist.
end();) {
693 if (FwdRegIt->first == CopySrcReg)
695 else if (
unsigned SubRegIdx =
696 TRI.getSubRegIndex(CopySrcReg, FwdRegIt->first))
697 if (
Register CopyDestSubReg =
TRI.getSubReg(CopyDestReg, SubRegIdx))
707 FwdRegIt = ForwardedRegWorklist.
erase(FwdRegIt);
715 if (
auto CopyInst =
TII.isCopyInstr(*CurMI))
716 DescribeFwdRegsByCalleeSavedCopy(*CopyInst);
744 if (
MI.isDebugInstr())
748 if (MO.getReg().isPhysical()) {
749 for (
auto &FwdReg : ForwardedRegWorklist)
750 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
751 Defs.insert(FwdReg.first);
760 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
761 if (FwdRegDefs.
empty()) {
767 for (
auto ParamFwdReg : FwdRegDefs) {
768 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
769 if (ParamValue->first.isImm()) {
770 int64_t Val = ParamValue->first.getImm();
772 ForwardedRegWorklist[ParamFwdReg], Params);
773 }
else if (ParamValue->first.isReg()) {
774 Register RegLoc = ParamValue->first.getReg();
775 Register SP = TLI.getStackPointerRegisterToSaveRestore();
777 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
780 if (!IsRegClobberedInMeantime(RegLoc) &&
781 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
784 ForwardedRegWorklist[ParamFwdReg], Params);
793 ForwardedRegWorklist[ParamFwdReg]);
800 for (
auto ParamFwdReg : FwdRegDefs)
801 ForwardedRegWorklist.
erase(ParamFwdReg);
808 for (
auto &New : TmpWorklistItems)
810 TmpWorklistItems.
clear();
827 if (ForwardedRegWorklist.
empty())
834 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
845 auto CSInfo = CalleesMap.
find(CallMI);
848 if (CSInfo == CalleesMap.end())
862 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
864 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
866 assert(InsertedReg &&
"Single register used to forward two arguments?");
871 for (
const auto &MO : CallMI->
uses())
872 if (MO.isReg() && MO.isUndef())
873 ForwardedRegWorklist.
erase(MO.getReg());
883 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
892 assert(std::next(Suc) == BundleEnd &&
893 "More than one instruction in call delay slot");
900 for (;
I !=
MBB->rend(); ++
I) {
907 if (ShouldTryEmitEntryVals) {
911 for (
auto &RegEntry : ForwardedRegWorklist) {
918void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
923 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
930 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
933 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
936 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
937 if (!
MI.isBundledWithSucc())
939 auto Suc = std::next(
MI.getIterator());
941 (void)CallInstrBundle;
943 (void)DelaySlotBundle;
950 "Call and its successor instruction don't have same label after.");
955 auto addCallSiteTargetForIndirectCalls = [&](
const MachineInstr *
MI,
957 const MachineFunction *MF =
MI->getMF();
959 auto CSInfo = CalleesMap.
find(
MI);
961 if (CSInfo == CalleesMap.end() || !CSInfo->second.CallTarget)
964 MDNode *CallTarget = CSInfo->second.CallTarget;
966 assert(!CallSiteDIE.findAttribute(dwarf::DW_AT_LLVM_virtual_call_origin) &&
967 "DW_AT_LLVM_virtual_call_origin already exists");
969 DIE *CalleeDIE =
CU.getOrCreateSubprogramDIE(CalleeSP,
nullptr);
970 assert(CalleeDIE &&
"Could not create DIE for call site entry origin");
971 CU.addDIEEntry(CallSiteDIE,
972 CU.getDwarf5OrGNUAttr(dwarf::DW_AT_LLVM_virtual_call_origin),
975 CU.addLinkageNamesToDeclarations(*
this, *CalleeSP, *CalleeDIE);
979 for (
const MachineBasicBlock &
MBB : MF) {
989 if (!
MI.isCandidateForAdditionalCallInfo())
998 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
1006 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
1007 bool PhysRegCalleeOperand =
1009 MachineLocation CallTarget{0};
1011 const DISubprogram *CalleeSP =
nullptr;
1012 const Function *CalleeDecl =
nullptr;
1013 if (PhysRegCalleeOperand) {
1014 bool Scalable =
false;
1015 const MachineOperand *BaseOp =
nullptr;
1016 const TargetRegisterInfo &
TRI =
1017 *
Asm->MF->getSubtarget().getRegisterInfo();
1018 if (
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, Scalable, &
TRI)) {
1019 if (BaseOp && BaseOp->
isReg() && !Scalable)
1020 CallTarget = MachineLocation(BaseOp->
getReg(),
true);
1024 CallTarget = MachineLocation(CalleeOp.
getReg());
1033 if (CalleeSP ==
nullptr && CallTarget.
getReg() == 0 &&
1034 AllocSiteTy ==
nullptr)
1044 const MachineInstr *TopLevelCallMI =
1051 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1060 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1063 dbgs() <<
"CallSiteEntry: " << MF.getName() <<
" -> "
1067 MF.getSubtarget().getRegisterInfo()->getName(
1069 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1071 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1072 ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
1076 addCallSiteTargetForIndirectCalls(TopLevelCallMI, CallSiteDIE);
1083 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1090 if (!
U.hasDwarfPubSections())
1093 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1096void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1104 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1105 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1107 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1110 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1113 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1114 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1117 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1121 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1126 if (!SysRoot.
empty())
1127 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1128 StringRef SDK = DIUnit->
getSDK();
1130 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1141 if (!CompilationDir.empty())
1142 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1143 addGnuPubAttributes(NewCU, Die);
1148 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1152 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1155 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1156 dwarf::DW_FORM_data1, RVer);
1161 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1166 ? dwarf::DW_AT_dwo_name
1167 : dwarf::DW_AT_GNU_dwo_name;
1174 if (
auto *
CU = CUMap.lookup(DIUnit))
1181 return CUMap.begin()->second;
1189DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1190 if (
auto *
CU = getDwarfCompileUnit(DIUnit))
1195 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1197 DwarfCompileUnit &NewCU = *OwnedUnit;
1204 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1205 Asm->OutStreamer->emitDwarfFile0Directive(
1211 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1213 finishUnitAttributes(DIUnit, NewCU);
1214 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1217 CUMap.insert({DIUnit, &NewCU});
1218 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1232 if (!
A.Expr || !
B.Expr)
1234 auto FragmentA =
A.Expr->getFragmentInfo();
1235 auto FragmentB =
B.Expr->getFragmentInfo();
1236 if (!FragmentA || !FragmentB)
1238 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1243 return A.Expr ==
B.Expr;
1258 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1259 M->debug_compile_units_end());
1260 if (NumDebugCUs == 0)
1263 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1264 SingleCU = NumDebugCUs == 1;
1271 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1279 Asm->createTempSymbol(
"rnglists_table_base"));
1283 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1288 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1289 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1292 if (CUNode->getImportedEntities().empty() &&
1293 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1294 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1299 for (
auto *Ty : CUNode->getEnumTypes()) {
1301 "Unexpected function-local entity in 'enums' CU field.");
1305 for (
auto *Ty : CUNode->getRetainedTypes()) {
1308 CU.getOrCreateTypeDIE(RT);
1313void DwarfDebug::finishEntityDefinitions() {
1314 for (
const auto &Entity : ConcreteEntities) {
1315 DIE *Die = Entity->getDIE();
1322 Unit->finishEntityDefinition(Entity.get());
1326void DwarfDebug::finishSubprogramDefinitions() {
1327 for (
const DISubprogram *SP : ProcessedSPNodes) {
1330 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1331 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1335void DwarfDebug::finalizeModuleInfo() {
1336 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1338 finishSubprogramDefinitions();
1340 finishEntityDefinitions();
1342 bool HasEmittedSplitCU =
false;
1346 for (
const auto &
P : CUMap) {
1347 auto &TheCU = *
P.second;
1348 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1350 TheCU.attachLexicalScopesAbstractOrigins();
1353 TheCU.constructContainingTypeDIEs();
1358 auto *SkCU = TheCU.getSkeleton();
1360 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1363 (void)HasEmittedSplitCU;
1365 "Multiple CUs emitted into a single dwo file");
1366 HasEmittedSplitCU =
true;
1368 ? dwarf::DW_AT_dwo_name
1369 : dwarf::DW_AT_GNU_dwo_name;
1370 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1371 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1372 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1373 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1379 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1384 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1385 dwarf::DW_FORM_data8,
ID);
1386 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1387 dwarf::DW_FORM_data8,
ID);
1390 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1392 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1396 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1405 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1407 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1414 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1417 U.setBaseAddress(TheCU.getRanges().front().Begin);
1418 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1425 U.addAddrTableBase();
1428 if (
U.hasRangeLists())
1429 U.addRnglistsBase();
1432 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1441 if (CUNode->getMacros()) {
1442 if (UseDebugMacroSection) {
1444 TheCU.addSectionDelta(
1445 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1449 ? dwarf::DW_AT_macros
1450 : dwarf::DW_AT_GNU_macros;
1451 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1456 TheCU.addSectionDelta(
1457 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1458 U.getMacroLabelBegin(),
1461 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1462 U.getMacroLabelBegin(),
1469 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1470 if (CUNode->getDWOId())
1471 getOrCreateDwarfCompileUnit(CUNode);
1476 SkeletonHolder.computeSizeAndOffsets();
1480 AccelDebugNames.convertDieToOffset();
1489 assert(CurFn ==
nullptr);
1499 Global.getDebugInfo(GVs);
1500 for (
auto *GVE : GVs)
1501 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1512 for (
auto *GVE : CUNode->getGlobalVariables()) {
1516 auto &GVMapEntry = GVMap[GVE->getVariable()];
1517 auto *Expr = GVE->getExpression();
1518 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1519 GVMapEntry.push_back({
nullptr, Expr});
1522 for (
auto *GVE : CUNode->getGlobalVariables()) {
1524 if (Processed.
insert(GV).second)
1529 for (
auto *IE : CUNode->getImportedEntities()) {
1531 "Unexpected function-local entity in 'imports' CU field.");
1532 CU->getOrCreateImportedEntityDIE(IE);
1536 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1538 CU->getOrCreateImportedEntityDIE(IE);
1540 CU->getOrCreateTypeDIE(Ty);
1546 CU->createBaseTypeDIEs();
1551 if (!
Asm || !
Asm->hasDebugInfo())
1555 finalizeModuleInfo();
1565 emitAbbreviations();
1571 if (UseARangesSection)
1579 emitDebugMacinfoDWO();
1589 emitDebugAbbrevDWO();
1591 emitDebugRangesDWO();
1601 emitAccelNamespaces();
1605 emitAccelDebugNames();
1614 emitDebugPubSections();
1622 if (
CU.getExistingAbstractEntity(
Node))
1627 CU.createAbstractEntity(
Node, Scope);
1636void DwarfDebug::collectVariableInfoFromMFTable(
1638 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1639 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1640 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1643 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1644 "Expected inlined-at fields to agree");
1646 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1653 <<
", no variable scope found\n");
1657 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1661 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1662 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1663 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1665 if (PreviousMMI &&
VI.inStackSlot())
1666 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1668 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1669 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1674 if (PreviousLoc->holds<Loc::MMI>())
1675 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1678 <<
", conflicting fragment location types\n");
1683 auto RegVar = std::make_unique<DbgVariable>(
1685 if (
VI.inStackSlot())
1686 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1688 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1691 InfoHolder.addScopeVariable(Scope, RegVar.get());
1692 MFVars.
insert({Var, RegVar.get()});
1693 ConcreteEntities.push_back(std::move(RegVar));
1705 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1713 if (LSRange.size() == 0)
1716 const MachineInstr *LScopeBegin = LSRange.front().first;
1720 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1726 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1729 auto PredDL = Pred->getDebugLoc();
1730 if (!PredDL || Pred->isMetaInstruction())
1734 if (
DL->getScope() == PredDL->getScope())
1737 if (!PredScope || LScope->dominates(PredScope))
1750 if (
MBB->pred_empty() &&
1757 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1801 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1803 bool isSafeForSingleLocation =
true;
1804 const MachineInstr *StartDebugMI =
nullptr;
1805 const MachineInstr *EndMI =
nullptr;
1807 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1808 const MachineInstr *
Instr = EI->getInstr();
1811 size_t Index = std::distance(EB, EI);
1812 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1819 "Forgot label before/after instruction starting a range!");
1822 if (std::next(EI) == Entries.
end()) {
1823 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1825 if (EI->isClobber())
1826 EndMI = EI->getInstr();
1828 else if (std::next(EI)->isClobber())
1832 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1834 if (EI->isDbgValue())
1840 if (EI->isDbgValue()) {
1847 if (!
Instr->isUndefDebugValue()) {
1852 if (
Instr->getDebugExpression()->isFragment())
1853 isSafeForSingleLocation =
false;
1856 StartDebugMI =
Instr;
1858 isSafeForSingleLocation =
false;
1864 if (OpenRanges.
empty())
1868 if (StartLabel == EndLabel) {
1869 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1874 for (
auto &R : OpenRanges)
1882 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1883 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1884 for (
const auto &[MBBSectionId, MBBSectionRange] :
1885 Asm->MBBSectionRanges) {
1886 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1887 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1890 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1891 MBBSectionRange.EndLabel, Values);
1894 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1901 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1902 for (
auto &
Value : CurEntry->getValues())
1904 dbgs() <<
"-----\n";
1907 auto PrevEntry = std::next(CurEntry);
1908 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1912 if (!isSafeForSingleLocation ||
1919 if (!
Asm->MF->hasBBSections())
1927 const MachineBasicBlock *RangeMBB =
nullptr;
1928 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1929 RangeMBB = &
Asm->MF->front();
1931 RangeMBB = Entries.
begin()->getInstr()->getParent();
1933 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1934 "Range MBB not found in MBBSectionRanges!");
1936 auto *NextEntry = std::next(CurEntry);
1937 auto NextRangeIt = std::next(RangeIt);
1938 while (NextEntry !=
DebugLoc.end()) {
1939 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1946 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1947 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1948 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1949 CurEntry->getValues() != NextEntry->getValues())
1951 RangeIt = NextRangeIt;
1952 NextRangeIt = std::next(RangeIt);
1953 CurEntry = NextEntry;
1954 NextEntry = std::next(CurEntry);
1964 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1966 ConcreteEntities.push_back(
1972 ConcreteEntities.push_back(
1978 return ConcreteEntities.back().get();
1986 collectVariableInfoFromMFTable(TheCU, Processed);
1989 InlinedEntity
IV =
I.first;
1994 const auto &HistoryMapEntries =
I.second;
1998 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
2001 LexicalScope *
Scope =
nullptr;
2003 if (
const DILocation *IA =
IV.second)
2013 *Scope, LocalVar,
IV.second));
2015 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
2021 size_t HistSize = HistoryMapEntries.size();
2022 bool SingleValueWithClobber =
2023 HistSize == 2 && HistoryMapEntries[1].isClobber();
2024 if (HistSize == 1 || SingleValueWithClobber) {
2026 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
2028 RegVar->emplace<Loc::Single>(MInsn);
2034 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
2038 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
2043 if (isValidSingleLocation) {
2044 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
2055 for (
auto &Entry : Entries)
2062 InlinedEntity IL =
I.first;
2063 const MachineInstr *
MI =
I.second;
2067 LexicalScope *
Scope =
nullptr;
2070 const DILocalScope *LocalScope =
2071 Label->getScope()->getNonLexicalBlockFileScope();
2073 if (
const DILocation *IA = IL.second)
2086 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2090 for (
const DINode *DN :
SP->getRetainedNodes()) {
2093 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2095 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2097 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2099 LocalDeclsPerLS[
LS].insert(DN);
2113 if (!
MI.isBundledWithSucc())
2115 auto Suc = std::next(
MI.getIterator());
2120 assert(Suc->isBundledWithPred() &&
2121 "Call bundle instructions are out of order");
2126 if (!NoDebug && SP->areAllCallsDescribed() &&
2128 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2130 bool IsTail =
TII->isTailCall(*
MI);
2148 auto RecordLineZero = [&]() {
2152 const MDNode *Scope =
nullptr;
2153 unsigned Column = 0;
2158 recordSourceLine(0, Column, Scope, 0);
2163 unsigned LastAsmLine =
2164 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2169 if (
MI->isMetaInstruction())
2190 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2192 if (
Asm->OutStreamer->isVerboseAsm()) {
2196 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2205 bool ScopeUsesKeyInstructions =
2207 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2210 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2211 IsKey = KeyInstructions.contains(
MI);
2217 assert(
MI->getParent() == &*
MI->getMF()->begin());
2218 recordSourceLine(SP->getScopeLine(), 0, SP,
2223 bool PrevInstInSameSection =
2225 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2226 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2227 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2237 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2239 RecordSourceLine(
DL, Flags);
2252 if (LastAsmLine == 0)
2273 if (
DL.getLine() == 0 && LastAsmLine == 0)
2280 if (ScopeUsesKeyInstructions) {
2287 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2302 if (
Asm->OutStreamer->isVerboseAsm()) {
2306 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2315static std::pair<const MachineInstr *, bool>
2326 bool IsEmptyPrologue =
2327 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2332 -> std::optional<std::pair<const MachineInstr *, bool>> {
2334 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2335 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2338 if (!isFrameSetup &&
MI.getDebugLoc()) {
2344 if (
MI.getDebugLoc().getLine())
2345 return std::make_pair(&
MI, IsEmptyPrologue);
2350 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2351 NonTrivialInst = &
MI;
2353 IsEmptyPrologue =
false;
2354 return std::nullopt;
2362 auto CurBlock = MF->
begin();
2363 auto CurInst = CurBlock->begin();
2367 while (CurBlock->empty())
2368 CurInst = (++CurBlock)->begin();
2369 assert(CurInst != CurBlock->end());
2373 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2375 if (CurInst->isTerminator()) {
2384 if (CurBlock->pred_size() > 1)
2395 if (CurBlock == MF->
end())
2397 }
while (CurBlock->empty());
2398 CurInst = CurBlock->begin();
2404 if (!CurInst->isMetaInstruction()) {
2405 auto FoundInst = ExamineInst(*CurInst);
2416 if (CurInst->isCall()) {
2418 Loc &&
Loc->getLine() == 0) {
2420 unsigned ScopeLine = SP->getScopeLine();
2423 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2426 return std::make_pair(&*CurInst,
false);
2432 auto NextInst = std::next(CurInst);
2433 if (NextInst != CurInst->getParent()->end()) {
2450 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2451 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2452 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2456 return std::make_pair(
nullptr, IsEmptyPrologue);
2462 const MDNode *S,
unsigned Flags,
unsigned CUID,
2464 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2467 unsigned FileNo = 1;
2470 Fn =
Scope->getFilename();
2471 if (Line != 0 && DwarfVersion >= 4)
2476 .getOrCreateSourceID(
Scope->getFile());
2478 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2479 Discriminator, Fn, Comment);
2490 bool IsEmptyPrologue = PrologEnd.second;
2493 if (IsEmptyPrologue) {
2501 if (!
DL ||
DL->getLine() != 0)
2512 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2522 KeyInstructions.clear();
2529 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2546 for (
auto &
MBB : *MF) {
2558 for (
auto &
MI :
MBB) {
2559 if (
MI.isMetaInstruction())
2563 if (!
Loc || !
Loc->getLine())
2574 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2579 KeyInstructions.insert(Buoy);
2585 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2589 auto *InlinedAt = Loc->getInlinedAt();
2592 if (!Group || !Rank)
2596 if (BuoyAtom && BuoyAtom != Group) {
2601 auto &[CandidateRank, CandidateInsts] =
2602 GroupCandidates[{InlinedAt, Group}];
2608 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2609 (CandidateRank != 0 && !CandidateInsts.empty()));
2611 assert(Rank &&
"expected nonzero rank");
2614 if (CandidateRank && CandidateRank < Rank)
2621 if (CandidateRank == Rank)
2625 else if (CandidateRank > Rank)
2626 CandidateInsts.clear();
2630 CandidateInsts.push_back(Buoy);
2631 CandidateRank = Rank;
2639 if (CandidateInsts.empty())
2645 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2646 for (
auto *
I : Insts)
2647 KeyInstructions.insert(
I);
2655 ForceIsStmtInstrs.clear();
2687 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2688 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2691 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2694 for (
auto &
MI :
MBB) {
2695 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2708 for (
auto *
MBB : PredMBBsToExamine) {
2709 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2710 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2711 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2713 MachineInstr *
MI = MBBInstrIt->second;
2714 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2716 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2717 ForceIsStmtInstrs.insert(
MI);
2724 CheckMBBEdge(Succ, 0);
2730 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2738 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2745 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2748 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2749 CheckMBBEdge(FBB, FBBLine);
2773 unsigned LastLine = 0;
2775 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2776 LastLine =
DL->getLine();
2781 for (
auto *Succ : SuccessorBBs)
2782 CheckMBBEdge(Succ, LastLine);
2797 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2798 ?
Asm->OutStreamer->emitLineTableLabel()
2801 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2809 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2815 computeKeyInstructions(MF);
2816 findForceIsStmtInstrs(MF);
2824 if (
Asm->OutStreamer->hasRawTextSupport())
2828 return CU.getUniqueID();
2832 const auto &CURanges =
CU->getRanges();
2833 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2836 LineTable.getMCLineSections().addEndEntry(
2837 const_cast<MCSymbol *
>(CURanges.back().End));
2857 "endFunction should be called with the same function as beginFunction");
2860 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2872 collectEntityInfo(TheCU, SP, Processed);
2876 for (
const auto &R :
Asm->MBBSectionRanges)
2877 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2884 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2885 for (
const auto &R :
Asm->MBBSectionRanges)
2895 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2899 for (
const DINode *DN : SP->getRetainedNodes()) {
2902 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2903 assert(LexS &&
"Expected the LexicalScope to be created.");
2906 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2912 LocalDeclsPerLS[LS].insert(DN);
2915 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2916 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2918 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2921 ProcessedSPNodes.insert(SP);
2925 if (!
LScopes.getAbstractScopesList().empty() &&
2927 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2928 FunctionLineTableLabel);
2930 FunctionLineTableLabel =
nullptr;
2933 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2941 LocalDeclsPerLS.clear();
2948void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2960void DwarfDebug::emitDebugInfo() {
2966void DwarfDebug::emitAbbreviations() {
2969 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2972void DwarfDebug::emitStringOffsetsTableHeader() {
2975 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2979template <
typename AccelTableT>
2980void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2982 Asm->OutStreamer->switchSection(Section);
2988void DwarfDebug::emitAccelDebugNames() {
2997void DwarfDebug::emitAccelNames() {
2998 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
3004void DwarfDebug::emitAccelObjC() {
3005 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
3010void DwarfDebug::emitAccelNamespaces() {
3011 emitAccel(AccelNamespace,
3012 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
3017void DwarfDebug::emitAccelTypes() {
3018 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
3048 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
3056 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
3063 case dwarf::DW_TAG_class_type:
3064 case dwarf::DW_TAG_structure_type:
3065 case dwarf::DW_TAG_union_type:
3066 case dwarf::DW_TAG_enumeration_type:
3071 case dwarf::DW_TAG_typedef:
3072 case dwarf::DW_TAG_base_type:
3073 case dwarf::DW_TAG_subrange_type:
3074 case dwarf::DW_TAG_template_alias:
3076 case dwarf::DW_TAG_namespace:
3078 case dwarf::DW_TAG_subprogram:
3080 case dwarf::DW_TAG_variable:
3082 case dwarf::DW_TAG_enumerator:
3092void DwarfDebug::emitDebugPubSections() {
3093 for (
const auto &NU : CUMap) {
3094 DwarfCompileUnit *TheU = NU.second;
3101 Asm->OutStreamer->switchSection(
3102 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3103 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3104 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3106 Asm->OutStreamer->switchSection(
3107 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3108 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3109 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3115 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3116 CU.getDebugSectionOffset());
3118 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3121void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3129 "pub" + Name,
"Length of Public " + Name +
" Info");
3131 Asm->OutStreamer->AddComment(
"DWARF Version");
3134 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3135 emitSectionReference(*TheU);
3137 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3142 for (
const auto &GI : Globals)
3145 return A.second->getOffset() <
B.second->getOffset();
3147 for (
const auto &[Name, Entity] : Vec) {
3148 Asm->OutStreamer->AddComment(
"DIE offset");
3149 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3153 Asm->OutStreamer->AddComment(
3159 Asm->OutStreamer->AddComment(
"External Name");
3160 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3163 Asm->OutStreamer->AddComment(
"End Mark");
3164 Asm->emitDwarfLengthOrOffset(0);
3165 Asm->OutStreamer->emitLabel(EndLabel);
3169void DwarfDebug::emitDebugStr() {
3170 MCSection *StringOffsetsSection =
nullptr;
3172 emitStringOffsetsTableHeader();
3173 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3176 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3177 StringOffsetsSection,
true);
3183 auto &&Comments = DebugLocs.getComments(Entry);
3184 auto Comment = Comments.begin();
3185 auto End = Comments.end();
3192 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3194 DebugLocs.getBytes(Entry).size()),
3195 Asm->getDataLayout().isLittleEndian(), PtrSize);
3200 for (
const auto &
Op : Expr) {
3201 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3202 "3 operand ops not yet supported");
3203 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3204 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3206 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3207 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3209 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3211 for (
unsigned J = 0; J <
Length; ++J)
3216 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3227 auto *DIExpr =
Value.getExpression();
3233 if (DIExpr && DIExpr->isEntryValue()) {
3250 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3253 if (Entry.isInt()) {
3254 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3256 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3257 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3261 }
else if (Entry.isLocation()) {
3263 if (Location.isIndirect())
3269 }
else if (Entry.isTargetIndexLocation()) {
3275 }
else if (Entry.isConstantFP()) {
3278 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3279 }
else if (Entry.getConstantFP()
3282 .getBitWidth() <= 64 ) {
3284 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3287 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3288 << Entry.getConstantFP()
3299 if (!
Value.isVariadic()) {
3300 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3309 return Entry.isLocation() && !Entry.getLoc().getReg();
3314 std::move(ExprCursor),
3315 [EmitValueLocEntry, &
Value](
unsigned Idx,
3317 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3325 assert(!Values.empty() &&
3326 "location list entries without values are redundant");
3327 assert(Begin != End &&
"unexpected location list entry with empty range");
3332 if (
Value.isFragment()) {
3335 return P.isFragment();
3336 }) &&
"all values are expected to be fragments");
3339 for (
const auto &Fragment : Values)
3343 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3354 Asm->OutStreamer->AddComment(
"Loc expr size");
3356 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3357 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3358 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3377 Asm->OutStreamer->AddComment(
"Offset entry count");
3383 Asm->getDwarfOffsetByteSize());
3397 Asm->OutStreamer->AddComment(
"Offset entry count");
3398 Asm->emitInt32(DebugLocs.getLists().size());
3399 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3401 for (
const auto &List : DebugLocs.getLists())
3402 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3403 Asm->getDwarfOffsetByteSize());
3408template <
typename Ranges,
typename PayloadEmitter>
3412 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3414 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3415 auto Size = Asm->MAI.getCodePointerSize();
3419 Asm->OutStreamer->emitLabel(Sym);
3426 for (
const auto &
Range : R)
3427 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3429 const MCSymbol *CUBase =
CU.getBaseAddress();
3430 bool BaseIsSet =
false;
3431 for (
const auto &
P : SectionRanges) {
3432 auto *
Base = CUBase;
3434 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3437 }
else if (!
Base && ShouldUseBaseAddress) {
3438 const MCSymbol *Begin =
P.second.front()->Begin;
3443 Asm->OutStreamer->emitIntValue(-1,
Size);
3444 Asm->OutStreamer->AddComment(
" base address");
3445 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3446 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3452 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3453 Asm->emitInt8(BaseAddressx);
3454 Asm->OutStreamer->AddComment(
" base address index");
3457 }
else if (BaseIsSet && !UseDwarf5) {
3460 Asm->OutStreamer->emitIntValue(-1,
Size);
3461 Asm->OutStreamer->emitIntValue(0,
Size);
3464 for (
const auto *RS :
P.second) {
3467 assert(Begin &&
"Range without a begin symbol?");
3468 assert(End &&
"Range without an end symbol?");
3472 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3473 Asm->emitInt8(OffsetPair);
3474 Asm->OutStreamer->AddComment(
" starting offset");
3475 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3476 Asm->OutStreamer->AddComment(
" ending offset");
3477 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3479 Asm->emitLabelDifference(Begin,
Base,
Size);
3480 Asm->emitLabelDifference(End,
Base,
Size);
3482 }
else if (UseDwarf5) {
3490 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3491 Asm->emitInt8(StartxEndx);
3492 Asm->OutStreamer->AddComment(
" start index");
3494 Asm->OutStreamer->AddComment(
" end index");
3497 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3498 Asm->emitInt8(StartxLength);
3499 Asm->OutStreamer->AddComment(
" start index");
3501 Asm->OutStreamer->AddComment(
" length");
3502 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3505 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3506 Asm->OutStreamer->emitSymbolValue(End,
Size);
3513 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3517 Asm->OutStreamer->emitIntValue(0,
Size);
3518 Asm->OutStreamer->emitIntValue(0,
Size);
3526 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3527 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3530 DD.emitDebugLocEntryLocation(E, List.CU);
3534void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3535 if (DebugLocs.getLists().empty())
3538 Asm->OutStreamer->switchSection(Sec);
3544 for (
const auto &
List : DebugLocs.getLists())
3548 Asm->OutStreamer->emitLabel(TableEnd);
3552void DwarfDebug::emitDebugLoc() {
3555 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3556 :
Asm->getObjFileLowering().getDwarfLocSection());
3560void DwarfDebug::emitDebugLocDWO() {
3563 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3568 for (
const auto &
List : DebugLocs.getLists()) {
3569 Asm->OutStreamer->switchSection(
3570 Asm->getObjFileLowering().getDwarfLocDWOSection());
3571 Asm->OutStreamer->emitLabel(
List.Label);
3573 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3582 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3583 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3584 Asm->emitULEB128(idx);
3590 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3600void DwarfDebug::emitDebugARanges() {
3601 if (ArangeLabels.empty())
3608 for (
const SymbolCU &SCU : ArangeLabels) {
3609 if (SCU.Sym->isInSection()) {
3611 MCSection *Section = &SCU.Sym->getSection();
3612 SectionMap[Section].push_back(SCU);
3617 SectionMap[
nullptr].push_back(SCU);
3621 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3623 for (
auto &
I : SectionMap) {
3631 for (
const SymbolCU &Cur :
List) {
3633 Span.
Start = Cur.Sym;
3636 Spans[Cur.CU].push_back(Span);
3642 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3646 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3647 const SymbolCU &Prev =
List[n - 1];
3648 const SymbolCU &Cur =
List[n];
3651 if (Cur.
CU != Prev.
CU) {
3653 Span.
Start = StartSym;
3656 Spans[Prev.
CU].push_back(Span);
3663 Asm->OutStreamer->switchSection(
3664 Asm->getObjFileLowering().getDwarfARangesSection());
3666 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3669 std::vector<DwarfCompileUnit *> CUs;
3670 for (
const auto &it : Spans) {
3671 DwarfCompileUnit *
CU = it.first;
3676 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3677 return A->getUniqueID() <
B->getUniqueID();
3681 for (DwarfCompileUnit *
CU : CUs) {
3682 std::vector<ArangeSpan> &
List = Spans[
CU];
3685 if (
auto *Skel =
CU->getSkeleton())
3689 unsigned ContentSize =
3691 Asm->getDwarfOffsetByteSize() +
3696 unsigned TupleSize = PtrSize * 2;
3700 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3703 ContentSize += (
List.size() + 1) * TupleSize;
3706 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3707 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3709 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3710 emitSectionReference(*
CU);
3711 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3712 Asm->emitInt8(PtrSize);
3713 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3716 Asm->OutStreamer->emitFill(Padding, 0xff);
3718 for (
const ArangeSpan &Span :
List) {
3719 Asm->emitLabelReference(Span.Start, PtrSize);
3726 auto SizeRef = SymSize.find(Span.Start);
3727 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3728 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3733 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3736 Size = SizeRef->second;
3738 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3742 Asm->OutStreamer->AddComment(
"ARange terminator");
3743 Asm->OutStreamer->emitIntValue(0, PtrSize);
3744 Asm->OutStreamer->emitIntValue(0, PtrSize);
3752 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3753 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3755 List.CU->getCUNode()->getRangesBaseAddress() ||
3767 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3770 Asm->OutStreamer->switchSection(Section);
3780 Asm->OutStreamer->emitLabel(TableEnd);
3785void DwarfDebug::emitDebugRanges() {
3788 emitDebugRangesImpl(Holder,
3790 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3791 :
Asm->getObjFileLowering().getDwarfRangesSection());
3794void DwarfDebug::emitDebugRangesDWO() {
3796 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3803 enum HeaderFlagMask {
3804#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3805#include "llvm/BinaryFormat/Dwarf.def"
3807 Asm->OutStreamer->AddComment(
"Macro information version");
3808 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3811 if (Asm->isDwarf64()) {
3812 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3813 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3815 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3816 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3818 Asm->OutStreamer->AddComment(
"debug_line_offset");
3820 Asm->emitDwarfLengthOrOffset(0);
3822 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3825void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3826 for (
auto *MN : Nodes) {
3830 emitMacroFile(*
F, U);
3836void DwarfDebug::emitMacro(
DIMacro &M) {
3837 StringRef
Name =
M.getName();
3838 StringRef
Value =
M.getValue();
3844 if (UseDebugMacroSection) {
3847 ? dwarf::DW_MACRO_define_strx
3848 : dwarf::DW_MACRO_undef_strx;
3851 Asm->OutStreamer->AddComment(
"Line Number");
3852 Asm->emitULEB128(
M.getLine());
3853 Asm->OutStreamer->AddComment(
"Macro String");
3855 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3858 ? dwarf::DW_MACRO_GNU_define_indirect
3859 : dwarf::DW_MACRO_GNU_undef_indirect;
3862 Asm->OutStreamer->AddComment(
"Line Number");
3863 Asm->emitULEB128(
M.getLine());
3864 Asm->OutStreamer->AddComment(
"Macro String");
3865 Asm->emitDwarfSymbolReference(
3866 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3870 Asm->emitULEB128(
M.getMacinfoType());
3871 Asm->OutStreamer->AddComment(
"Line Number");
3872 Asm->emitULEB128(
M.getLine());
3873 Asm->OutStreamer->AddComment(
"Macro String");
3874 Asm->OutStreamer->emitBytes(Str);
3875 Asm->emitInt8(
'\0');
3879void DwarfDebug::emitMacroFileImpl(
3881 StringRef (*MacroFormToString)(
unsigned Form)) {
3883 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3884 Asm->emitULEB128(StartFile);
3885 Asm->OutStreamer->AddComment(
"Line Number");
3887 Asm->OutStreamer->AddComment(
"File Number");
3890 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3892 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3894 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3896 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3897 Asm->emitULEB128(EndFile);
3904 if (UseDebugMacroSection)
3906 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3913void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3914 for (
const auto &
P : CUMap) {
3915 auto &TheCU = *
P.second;
3917 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3919 DIMacroNodeArray Macros = CUNode->getMacros();
3922 Asm->OutStreamer->switchSection(Section);
3923 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3924 if (UseDebugMacroSection)
3926 handleMacroNodes(Macros, U);
3927 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3933void DwarfDebug::emitDebugMacinfo() {
3934 auto &ObjLower =
Asm->getObjFileLowering();
3935 emitDebugMacinfoImpl(UseDebugMacroSection
3936 ? ObjLower.getDwarfMacroSection()
3937 : ObjLower.getDwarfMacinfoSection());
3940void DwarfDebug::emitDebugMacinfoDWO() {
3941 auto &ObjLower =
Asm->getObjFileLowering();
3942 emitDebugMacinfoImpl(UseDebugMacroSection
3943 ? ObjLower.getDwarfMacroDWOSection()
3944 : ObjLower.getDwarfMacinfoDWOSection());
3949void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3950 std::unique_ptr<DwarfCompileUnit> NewU) {
3952 if (!CompilationDir.empty())
3953 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3954 addGnuPubAttributes(*NewU, Die);
3956 SkeletonHolder.addUnit(std::move(NewU));
3961 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3962 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3964 DwarfCompileUnit &NewCU = *OwnedUnit;
3965 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3972 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3979void DwarfDebug::emitDebugInfoDWO() {
3987void DwarfDebug::emitDebugAbbrevDWO() {
3989 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3992void DwarfDebug::emitDebugLineDWO() {
3994 SplitTypeUnitFileTable.Emit(
3995 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3996 Asm->getObjFileLowering().getDwarfLineDWOSection());
3999void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
4001 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
4002 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
4009void DwarfDebug::emitDebugStrDWO() {
4011 emitStringOffsetsTableHeaderDWO();
4013 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
4014 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
4019void DwarfDebug::emitDebugAddr() {
4020 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
4026 const DICompileUnit *DIUnit =
CU.getCUNode();
4027 SplitTypeUnitFileTable.maybeSetRootFile(
4030 return &SplitTypeUnitFileTable;
4041 return Result.high();
4050 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4053 auto Ins = TypeSignatures.try_emplace(CTy);
4055 CU.addDIETypeSignature(RefDie, Ins.first->second);
4060 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4061 AddrPool.resetUsedFlag();
4063 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4067 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4069 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4070 CU.getSourceLanguage());
4074 Ins.first->second = Signature;
4082 if (!CompilationDir.empty())
4083 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4084 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4085 Asm->TM.Options.MCOptions.SplitDwarfFile);
4089 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4090 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4095 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4096 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4099 CU.applyStmtList(UnitDie);
4110 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4111 TypeUnitsUnderConstruction.clear();
4115 if (AddrPool.hasBeenUsed()) {
4116 AccelTypeUnitsDebugNames.clear();
4120 for (
const auto &
TU : TypeUnitsToAdd)
4121 TypeSignatures.erase(
TU.second);
4129 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4135 for (
auto &
TU : TypeUnitsToAdd) {
4136 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4141 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4143 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4146 AccelTypeUnitsDebugNames.convertDieToOffset();
4147 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4148 AccelTypeUnitsDebugNames.clear();
4151 CU.addDIETypeSignature(RefDie, Signature);
4158template <
typename DataT>
4159void DwarfDebug::addAccelNameImpl(
4164 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4181 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4182 ((&Current == &AccelDebugNames) &&
4183 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4184 "Kind is CU but TU is being processed.");
4185 assert(((&Current == &AccelDebugNames) ||
4186 ((&Current == &AccelTypeUnitsDebugNames) &&
4187 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4188 "Kind is TU but CU is being processed.");
4191 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4192 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4206 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4215 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4222 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4228 const DIE &Die,
char Flags) {
4229 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4233 return Asm->OutStreamer->getContext().getDwarfVersion();
4237 if (
Asm->getDwarfVersion() >= 4)
4238 return dwarf::Form::DW_FORM_sec_offset;
4239 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4240 "DWARF64 is not defined prior DWARFv3");
4241 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4242 : dwarf::Form::DW_FORM_data4;
4246 return SectionLabels.lookup(S);
4250 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4255std::optional<MD5::MD5Result>
4259 return std::nullopt;
4260 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4262 return std::nullopt;
4267 std::string ChecksumString =
fromHex(Checksum->Value);
4284 if (
MBB.getAlignment() ==
Align(1))
4287 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4294 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4295 if (PrevLoc.getLine()) {
4296 Asm->OutStreamer->emitDwarfLocDirective(
4297 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4299 Asm->OutStreamer->getCurrentSectionOnly());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Expected< bool > hasObjCCategory(BitstreamCursor &Stream)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isObjCClass(StringRef Name)
static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))
static void finishCallSiteParams(ValT Val, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > DescribedParams, ParamSet &Params)
Emit call site parameter entries that are described by the given value and debug expression.
static cl::opt< bool > UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden, cl::desc("Emit the GNU .debug_macro format with DWARF <5"), cl::init(false))
static cl::opt< DefaultOnOff > DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden, cl::desc("Use inlined strings rather than string section."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static bool validThroughout(LexicalScopes &LScopes, const MachineInstr *DbgValue, const MachineInstr *RangeEnd, const InstructionOrdering &Ordering)
Determine whether a singular DBG_VALUE is valid for the entirety of its enclosing lexical scope.
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
static cl::opt< LinkageNameOption > DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, cl::desc("Which DWARF linkage-name attributes to emit."), cl::values(clEnumValN(DefaultLinkageNames, "Default", "Default for platform"), clEnumValN(AllLinkageNames, "All", "All"), clEnumValN(AbstractLinkageNames, "Abstract", "Abstract subprograms")), cl::init(DefaultLinkageNames))
static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > ParamsToAdd)
Add Reg to the worklist, if it's not already present, and mark that the given parameter registers' va...
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
SmallSet< MCRegUnit, 16 > ClobberedRegUnitSet
Container for the set of register units known to be clobbered on the path to a call site.
static cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))
Set to false to ignore Key Instructions metadata.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr)
static cl::opt< DefaultOnOff > DwarfOpConvert("dwarf-op-convert", cl::Hidden, cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static std::pair< const MachineInstr *, bool > findPrologueEndLoc(const MachineFunction *MF)
static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)
Try to interpret values loaded into registers that forward parameters for CallMI.
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))
MapVector< uint64_t, SmallVector< FwdRegParamInfo, 2 > > FwdRegWorklist
Register worklist for finding call site values.
static cl::opt< bool > UseDwarfRangesBaseAddressSpecifier("use-dwarf-ranges-base-address-specifier", cl::Hidden, cl::desc("Use base address specifiers in debug_ranges"), cl::init(false))
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
static constexpr unsigned ULEB128PadSize
static cl::opt< DefaultOnOff > DwarfSectionsAsReferences("dwarf-sections-as-references", cl::Hidden, cl::desc("Use sections+offset as references rather than labels."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, unsigned StartxLength, unsigned StartxEndx, unsigned EndOfList, StringRef(*StringifyEnum)(unsigned), bool ShouldUseBaseAddress, PayloadEmitter EmitPayload)
static void forBothCUs(DwarfCompileUnit &CU, Func F)
static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD)
static const DILocalScope * getRetainedNodeScope(const MDNode *N)
static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
static void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
Interpret values loaded into registers by CurMI.
static cl::opt< DefaultOnOff > UnknownLocations("use-unknown-locations", cl::Hidden, cl::desc("Make an absence of debug location information explicit."), cl::values(clEnumVal(Default, "At top of block or after label"), clEnumVal(Enable, "In all cases"), clEnumVal(Disable, "Never")), cl::init(Default))
static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, const MDNode *S, unsigned Flags, unsigned CUID, uint16_t DwarfVersion, ArrayRef< std::unique_ptr< DwarfCompileUnit > > DCUs, StringRef Comment={})
Register a source line with debug info.
static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD, const DwarfCompileUnit &CU, uint16_t DwarfVersion)
Emit the header of a DWARF 5 macro section, or the GNU extension for DWARF 4.
static cl::opt< AccelTableKind > AccelTables("accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."), cl::values(clEnumValN(AccelTableKind::Default, "Default", "Default for platform"), clEnumValN(AccelTableKind::None, "Disable", "Disabled."), clEnumValN(AccelTableKind::Apple, "Apple", "Apple"), clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")), cl::init(AccelTableKind::Default))
static cl::opt< DwarfDebug::MinimizeAddrInV5 > MinimizeAddrInV5Option("minimize-addr-in-v5", cl::Hidden, cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more " "address pool entry sharing to reduce relocations/object size"), cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default", "Default address minimization strategy"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges", "Use rnglists for contiguous ranges if that allows " "using a pre-existing base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions, "Expressions", "Use exprloc addrx+offset expressions for any " "address with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Form, "Form", "Use addrx+offset extension form for any address " "with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled", "Stuff")), cl::init(DwarfDebug::MinimizeAddrInV5::Default))
static StringRef getObjCMethodName(StringRef In)
static DbgValueLoc getDebugLocValue(const MachineInstr *MI)
Get .debug_loc entry for the instruction range starting at MI.
static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static const MCPhysReg CalleeSavedReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
static bool isCopy(MachineInstr *MI)
static const uint32_t IV[8]
Class recording the (high level) value of a variable.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
This class is intended to be used as a driving class for all asm writers.
DwarfDebug * getDwarfDebug()
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
uint16_t getDwarfVersion() const
virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=0
virtual unsigned emitDIERef(const DIE &D)=0
Basic type, like 'int' or 'float'.
bool getDebugInfoForProfiling() const
bool isDebugDirectivesOnly() const
StringRef getFlags() const
static LLVM_ABI std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
unsigned getRuntimeVersion() const
bool getSplitDebugInlining() const
StringRef getSysRoot() const
StringRef getProducer() const
DISourceLanguageName getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static LLVM_ABI std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
A structured debug information entry.
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
LLVM_ABI const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
dwarf::Tag getTag() const
Holds a DIExpression and keeps track of how many operands have been consumed so far.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
LLVM_ABI bool isValid() const
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
bool hasVersionedName() const
Subprogram description. Uses SubclassData1.
static DILocalScope * getRetainedNodeScope(MDNode *N)
DIScope * getScope() const
Encoding
Size and signedness of expression operations' operands.
Used for tracking debug info about call site parameters.
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
SmallVector< Entry, 4 > Entries
A single location or constant within a variable location description, with either a single entry (wit...
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
const DILocalVariable * getVariable() const
const DIType * getType() const
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
AsmPrinter * Asm
Target of debug info emission.
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
MachineModuleInfo * MMI
Collected machine module information.
DebugLoc PrevInstLoc
Previous instruction's location information.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
DebugHandlerBase(AsmPrinter *A)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
const MachineBasicBlock * PrevInstBB
void requestLabelAfterInsn(const MachineInstr *MI)
Ensure that a label will be emitted after MI.
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
DbgLabelInstrMap DbgLabels
Mapping of inlined labels and DBG_LABEL machine instruction.
void beginModule(Module *M) override
const InstructionOrdering & getInstOrdering() const
void requestLabelBeforeInsn(const MachineInstr *MI)
Ensure that a label will be emitted before MI.
const MachineBasicBlock * EpilogBeginBlock
This block includes epilogue instructions.
const MachineInstr * PrologEndLoc
This location indicates end of function prologue and beginning of function body.
DwarfExpression implementation for .debug_loc entries.
void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU)
Lower this entry into a DWARF expression.
Builder for DebugLocStream entries.
Builder for DebugLocStream lists.
ArrayRef< Entry > getEntries(const List &L) const
LLVM_ABI unsigned getLine() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
DwarfCompileUnit * getSkeleton() const
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
const StringMap< const DIE * > & getGlobalNames() const
DbgEntity * getExistingAbstractEntity(const DINode *Node)
const StringMap< const DIE * > & getGlobalTypes() const
bool hasDwarfPubSections() const
Collects and handles dwarf debug information.
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
virtual bool shouldResetBaseAddress(const MCSection &Section) const
Whether the target requires resetting the base address in range/loc lists.
std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
virtual bool shouldAttachCompileUnitRanges() const
Whether to attach ranges/low_pc to the compile unit DIE in endModule.
bool emitDebugEntryValues() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind)
Sets the current DWARF5AccelTable to use.
bool alwaysUseRanges(const DwarfCompileUnit &) const
Returns whether range encodings should be used for single entry range lists.
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
void skippedNonDebugFunction() override
void addArangeLabel(SymbolCU SCU)
Add a label so that arange data can be generated for it.
virtual void finishTargetUnitAttributes(const DICompileUnit &DIUnit, DwarfCompileUnit &NewCU)
Target-specific compile unit attribute finalization.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
AddressPool & getAddressPool()
DWARF5AccelTable & getCurrentDWARF5AccelTable()
Returns either CU or TU DWARF5AccelTable.
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
bool shareAcrossDWOCUs() const
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)
Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
const SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
const MCSymbol * getSectionLabel(const MCSection *S)
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support.
virtual void initializeTargetDebugInfo(const MachineFunction &MF)
Target-specific debug info initialization at function start.
unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU)
Get Dwarf compile unit ID for line table.
const MachineInstr * emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
bool useRangesSection() const
Returns whether ranges section should be emitted.
void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
virtual void recordTargetSourceLine(const DebugLoc &DL, unsigned Flags)
Target-specific source line recording.
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null.
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)
Add a DIE to the set of types that we're going to pull into type units.
DwarfFile InfoHolder
Holder for the file specific debug information.
void endModule() override
Emit all Dwarf sections that should come after the content.
void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)
void beginCodeAlignment(const MachineBasicBlock &MBB) override
Process beginning of code alignment.
DwarfDebug(AsmPrinter *A)
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
void finalize()
This needs to be called last to commit any pending changes.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void setMemoryLocationKind()
Lock this down to become a memory location description.
std::optional< uint8_t > TagOffset
void addBooleanConstant(int64_t Value)
Emit a boolean constant.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void addSignedConstant(int64_t Value)
Emit a signed constant.
virtual void commitTemporaryBuffer()=0
Commit the data stored in the temporary buffer to the main output.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
virtual void enableTemporaryBuffer()=0
Start emitting data to the temporary buffer.
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void setRnglistsTableBaseSym(MCSymbol *Sym)
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
const SmallVectorImpl< RangeSpanList > & getRangeLists() const
getRangeLists - Get the vector of range lists.
MCSymbol * getStringOffsetsStartSym() const
MCSymbol * getRnglistsTableBaseSym() const
DwarfStringPool & getStringPool()
Returns the string pool.
void emitAbbrevs(MCSection *)
Emit a set of abbreviations to the specific section.
void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)
Emit all of the strings to the section given.
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
LLVM_ABI_FOR_TEST EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
LLVM_ABI_FOR_TEST void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)
void setTypeSignature(uint64_t Signature)
void setType(const DIE *Ty)
This dwarf writer support class manages information associated with a source file.
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)
Creates type DIE with specific context.
const DICompileUnit * getCUNode() const
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
unsigned getUniqueID() const
Gets Unique ID for this unit.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool isTailCall(const MachineInstr &MI) const override
Record instruction ordering so we can query their relative positions within a function.
This class is used to track scope information.
SmallVectorImpl< InsnRange > & getRanges()
const DILocalScope * getScopeNode() const
This class provides interface to collect and use lexical scoping information from machine instruction...
LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)
Find lexical scope, either regular or inlined, for the given DebugLoc.
LexicalScope * findAbstractScope(const DILocalScope *N)
Find an abstract scope or return null.
Single(DbgValueLoc ValueLoc)
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
MCSection * getDwarfLoclistsSection() const
MCSection * getDwarfRangesSection() const
MCSection * getDwarfMacroSection() const
MCSection * getDwarfMacinfoDWOSection() const
MCSection * getDwarfMacinfoSection() const
MCSection * getDwarfMacroDWOSection() const
static constexpr unsigned NoRegister
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol * getBeginSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
uint32_t getIndex() const
Get the (implementation defined) index.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
succ_iterator succ_begin()
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const CallSiteInfoMap & getCallSitesInfo() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
unsigned getNumOperands() const
Retuns the total number of operands.
bool hasDelaySlot(QueryType Type=AnyInBundle) const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
mop_range uses()
Returns all operands which may be register uses.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
This class implements a map that also provides access to all stored values in a deterministic order.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool empty() const
Determine if the SetVector is empty or not.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void insert_range(Range &&R)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
const Triple & getTargetTriple() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
Triple - Helper class for working with autoconf configuration names.
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI StringRef RangeListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
LLVM_ABI StringRef MacroString(unsigned Encoding)
LLVM_ABI StringRef LocListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GnuMacroString(unsigned Encoding)
LLVM_ABI StringRef MacinfoString(unsigned Encoding)
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
bool isCPlusPlus(SourceLanguage S)
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
@ DWARF_VERSION
Other constants.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
FunctionAddr VTableAddr Value
MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)
Returns an iterator to the first instruction in the bundle containing I.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation. The return string is half the size of ...
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)
auto cast_or_null(const Y &Val)
auto unique(Range &&R, Predicate P)
bool isa_and_nonnull(const Y &Val)
SmallVector< DbgCallSiteParam, 4 > ParamSet
Collection used for storing debug call site parameters.
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
AccelTableKind
The kind of accelerator tables we should emit.
@ Default
Platform default.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
@ Dwarf
DWARF v5 .debug_names.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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...
@ Ref
The access may reference the value stored in memory.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
DebuggerKind
Identify a debugger for "tuning" the debug info.
@ SCE
Tune debug info for SCE targets (e.g. PS4).
@ DBX
Tune debug info for dbx.
@ Default
No specific tuning requested.
@ GDB
Tune debug info for gdb.
@ LLDB
Tune debug info for lldb.
Implement std::hash so that hash_code can be used in STL containers.
Represents a parameter whose call site value can be described by applying a debug expression to a reg...
uint64_t ParamReg
The described parameter register.
const DIExpression * Expr
Debug expression that has been built up when walking through the instruction chain that produces the ...
This struct is a compact representation of a valid (non-zero power of two) alignment.
A pair of GlobalVariable and DIExpression.
Represents an entry-value location, or a fragment of one.
void addFrameIndexExpr(const DIExpression *Expr, int FI)
std::set< FrameIndexExpr > FrameIndexExprs
const std::set< FrameIndexExpr > & getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
A MapVector that performs no allocations if smaller than a certain size.
Helper used to pair up a symbol and its DWARF compile unit.
This struct describes target specific location.
Describes an entry of the various gnu_pub* debug sections.