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);
1123 if (!SysRoot.
empty())
1124 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1125 StringRef SDK = DIUnit->
getSDK();
1127 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1138 if (!CompilationDir.empty())
1139 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1140 addGnuPubAttributes(NewCU, Die);
1145 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1149 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1152 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1153 dwarf::DW_FORM_data1, RVer);
1158 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1163 ? dwarf::DW_AT_dwo_name
1164 : dwarf::DW_AT_GNU_dwo_name;
1171 if (
auto *
CU = CUMap.lookup(DIUnit))
1178 return CUMap.begin()->second;
1186DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1187 if (
auto *
CU = getDwarfCompileUnit(DIUnit))
1192 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1194 DwarfCompileUnit &NewCU = *OwnedUnit;
1201 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1202 Asm->OutStreamer->emitDwarfFile0Directive(
1208 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1210 finishUnitAttributes(DIUnit, NewCU);
1211 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1214 CUMap.insert({DIUnit, &NewCU});
1215 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1229 if (!
A.Expr || !
B.Expr)
1231 auto FragmentA =
A.Expr->getFragmentInfo();
1232 auto FragmentB =
B.Expr->getFragmentInfo();
1233 if (!FragmentA || !FragmentB)
1235 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1240 return A.Expr ==
B.Expr;
1255 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1256 M->debug_compile_units_end());
1257 if (NumDebugCUs == 0)
1260 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1261 SingleCU = NumDebugCUs == 1;
1268 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1276 Asm->createTempSymbol(
"rnglists_table_base"));
1280 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1285 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1286 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1289 if (CUNode->getImportedEntities().empty() &&
1290 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1291 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1296 for (
auto *Ty : CUNode->getEnumTypes()) {
1298 "Unexpected function-local entity in 'enums' CU field.");
1302 for (
auto *Ty : CUNode->getRetainedTypes()) {
1305 CU.getOrCreateTypeDIE(RT);
1310void DwarfDebug::finishEntityDefinitions() {
1311 for (
const auto &Entity : ConcreteEntities) {
1312 DIE *Die = Entity->getDIE();
1319 Unit->finishEntityDefinition(Entity.get());
1323void DwarfDebug::finishSubprogramDefinitions() {
1324 for (
const DISubprogram *SP : ProcessedSPNodes) {
1327 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1328 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1332void DwarfDebug::finalizeModuleInfo() {
1333 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1335 finishSubprogramDefinitions();
1337 finishEntityDefinitions();
1339 bool HasEmittedSplitCU =
false;
1343 for (
const auto &
P : CUMap) {
1344 auto &TheCU = *
P.second;
1345 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1347 TheCU.attachLexicalScopesAbstractOrigins();
1350 TheCU.constructContainingTypeDIEs();
1355 auto *SkCU = TheCU.getSkeleton();
1357 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1360 (void)HasEmittedSplitCU;
1362 "Multiple CUs emitted into a single dwo file");
1363 HasEmittedSplitCU =
true;
1365 ? dwarf::DW_AT_dwo_name
1366 : dwarf::DW_AT_GNU_dwo_name;
1367 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1368 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1369 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1370 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1376 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1381 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1382 dwarf::DW_FORM_data8,
ID);
1383 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1384 dwarf::DW_FORM_data8,
ID);
1387 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1389 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1393 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1402 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1404 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1411 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1414 U.setBaseAddress(TheCU.getRanges().front().Begin);
1415 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1422 U.addAddrTableBase();
1425 if (
U.hasRangeLists())
1426 U.addRnglistsBase();
1429 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1438 if (CUNode->getMacros()) {
1439 if (UseDebugMacroSection) {
1441 TheCU.addSectionDelta(
1442 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1446 ? dwarf::DW_AT_macros
1447 : dwarf::DW_AT_GNU_macros;
1448 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1453 TheCU.addSectionDelta(
1454 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1455 U.getMacroLabelBegin(),
1458 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1459 U.getMacroLabelBegin(),
1466 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1467 if (CUNode->getDWOId())
1468 getOrCreateDwarfCompileUnit(CUNode);
1473 SkeletonHolder.computeSizeAndOffsets();
1477 AccelDebugNames.convertDieToOffset();
1486 assert(CurFn ==
nullptr);
1496 Global.getDebugInfo(GVs);
1497 for (
auto *GVE : GVs)
1498 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1509 for (
auto *GVE : CUNode->getGlobalVariables()) {
1513 auto &GVMapEntry = GVMap[GVE->getVariable()];
1514 auto *Expr = GVE->getExpression();
1515 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1516 GVMapEntry.push_back({
nullptr, Expr});
1519 for (
auto *GVE : CUNode->getGlobalVariables()) {
1521 if (Processed.
insert(GV).second)
1526 for (
auto *IE : CUNode->getImportedEntities()) {
1528 "Unexpected function-local entity in 'imports' CU field.");
1529 CU->getOrCreateImportedEntityDIE(IE);
1533 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1535 CU->getOrCreateImportedEntityDIE(IE);
1537 CU->getOrCreateTypeDIE(Ty);
1543 CU->createBaseTypeDIEs();
1548 if (!
Asm || !
Asm->hasDebugInfo())
1552 finalizeModuleInfo();
1562 emitAbbreviations();
1568 if (UseARangesSection)
1576 emitDebugMacinfoDWO();
1586 emitDebugAbbrevDWO();
1588 emitDebugRangesDWO();
1598 emitAccelNamespaces();
1602 emitAccelDebugNames();
1611 emitDebugPubSections();
1619 if (
CU.getExistingAbstractEntity(
Node))
1624 CU.createAbstractEntity(
Node, Scope);
1633void DwarfDebug::collectVariableInfoFromMFTable(
1635 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1636 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1637 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1640 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1641 "Expected inlined-at fields to agree");
1643 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1650 <<
", no variable scope found\n");
1654 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1658 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1659 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1660 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1662 if (PreviousMMI &&
VI.inStackSlot())
1663 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1665 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1666 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1671 if (PreviousLoc->holds<Loc::MMI>())
1672 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1675 <<
", conflicting fragment location types\n");
1680 auto RegVar = std::make_unique<DbgVariable>(
1682 if (
VI.inStackSlot())
1683 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1685 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1688 InfoHolder.addScopeVariable(Scope, RegVar.get());
1689 MFVars.
insert({Var, RegVar.get()});
1690 ConcreteEntities.push_back(std::move(RegVar));
1702 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1710 if (LSRange.size() == 0)
1713 const MachineInstr *LScopeBegin = LSRange.front().first;
1717 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1723 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1726 auto PredDL = Pred->getDebugLoc();
1727 if (!PredDL || Pred->isMetaInstruction())
1731 if (
DL->getScope() == PredDL->getScope())
1734 if (!PredScope || LScope->dominates(PredScope))
1747 if (
MBB->pred_empty() &&
1754 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1798 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1800 bool isSafeForSingleLocation =
true;
1801 const MachineInstr *StartDebugMI =
nullptr;
1802 const MachineInstr *EndMI =
nullptr;
1804 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1805 const MachineInstr *
Instr = EI->getInstr();
1808 size_t Index = std::distance(EB, EI);
1809 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1816 "Forgot label before/after instruction starting a range!");
1819 if (std::next(EI) == Entries.
end()) {
1820 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1822 if (EI->isClobber())
1823 EndMI = EI->getInstr();
1825 else if (std::next(EI)->isClobber())
1829 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1831 if (EI->isDbgValue())
1837 if (EI->isDbgValue()) {
1844 if (!
Instr->isUndefDebugValue()) {
1849 if (
Instr->getDebugExpression()->isFragment())
1850 isSafeForSingleLocation =
false;
1853 StartDebugMI =
Instr;
1855 isSafeForSingleLocation =
false;
1861 if (OpenRanges.
empty())
1865 if (StartLabel == EndLabel) {
1866 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1871 for (
auto &R : OpenRanges)
1879 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1880 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1881 for (
const auto &[MBBSectionId, MBBSectionRange] :
1882 Asm->MBBSectionRanges) {
1883 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1884 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1887 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1888 MBBSectionRange.EndLabel, Values);
1891 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1898 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1899 for (
auto &
Value : CurEntry->getValues())
1901 dbgs() <<
"-----\n";
1904 auto PrevEntry = std::next(CurEntry);
1905 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1909 if (!isSafeForSingleLocation ||
1916 if (!
Asm->MF->hasBBSections())
1924 const MachineBasicBlock *RangeMBB =
nullptr;
1925 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1926 RangeMBB = &
Asm->MF->front();
1928 RangeMBB = Entries.
begin()->getInstr()->getParent();
1930 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1931 "Range MBB not found in MBBSectionRanges!");
1933 auto *NextEntry = std::next(CurEntry);
1934 auto NextRangeIt = std::next(RangeIt);
1935 while (NextEntry !=
DebugLoc.end()) {
1936 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1943 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1944 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1945 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1946 CurEntry->getValues() != NextEntry->getValues())
1948 RangeIt = NextRangeIt;
1949 NextRangeIt = std::next(RangeIt);
1950 CurEntry = NextEntry;
1951 NextEntry = std::next(CurEntry);
1961 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1963 ConcreteEntities.push_back(
1969 ConcreteEntities.push_back(
1975 return ConcreteEntities.back().get();
1983 collectVariableInfoFromMFTable(TheCU, Processed);
1986 InlinedEntity
IV =
I.first;
1991 const auto &HistoryMapEntries =
I.second;
1995 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
1998 LexicalScope *
Scope =
nullptr;
2000 if (
const DILocation *IA =
IV.second)
2010 *Scope, LocalVar,
IV.second));
2012 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
2018 size_t HistSize = HistoryMapEntries.size();
2019 bool SingleValueWithClobber =
2020 HistSize == 2 && HistoryMapEntries[1].isClobber();
2021 if (HistSize == 1 || SingleValueWithClobber) {
2023 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
2025 RegVar->emplace<Loc::Single>(MInsn);
2031 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
2035 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
2040 if (isValidSingleLocation) {
2041 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
2052 for (
auto &Entry : Entries)
2059 InlinedEntity IL =
I.first;
2060 const MachineInstr *
MI =
I.second;
2064 LexicalScope *
Scope =
nullptr;
2067 const DILocalScope *LocalScope =
2068 Label->getScope()->getNonLexicalBlockFileScope();
2070 if (
const DILocation *IA = IL.second)
2083 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2087 for (
const DINode *DN :
SP->getRetainedNodes()) {
2090 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2092 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2094 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2096 LocalDeclsPerLS[
LS].insert(DN);
2110 if (!
MI.isBundledWithSucc())
2112 auto Suc = std::next(
MI.getIterator());
2117 assert(Suc->isBundledWithPred() &&
2118 "Call bundle instructions are out of order");
2123 if (!NoDebug && SP->areAllCallsDescribed() &&
2125 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2127 bool IsTail =
TII->isTailCall(*
MI);
2145 auto RecordLineZero = [&]() {
2149 const MDNode *Scope =
nullptr;
2150 unsigned Column = 0;
2155 recordSourceLine(0, Column, Scope, 0);
2160 unsigned LastAsmLine =
2161 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2166 if (
MI->isMetaInstruction())
2187 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2189 if (
Asm->OutStreamer->isVerboseAsm()) {
2193 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2202 bool ScopeUsesKeyInstructions =
2204 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2207 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2208 IsKey = KeyInstructions.contains(
MI);
2214 assert(
MI->getParent() == &*
MI->getMF()->begin());
2215 recordSourceLine(SP->getScopeLine(), 0, SP,
2220 bool PrevInstInSameSection =
2222 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2223 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2224 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2234 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2236 RecordSourceLine(
DL, Flags);
2249 if (LastAsmLine == 0)
2270 if (
DL.getLine() == 0 && LastAsmLine == 0)
2277 if (ScopeUsesKeyInstructions) {
2284 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2299 if (
Asm->OutStreamer->isVerboseAsm()) {
2303 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2312static std::pair<const MachineInstr *, bool>
2323 bool IsEmptyPrologue =
2324 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2329 -> std::optional<std::pair<const MachineInstr *, bool>> {
2331 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2332 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2335 if (!isFrameSetup &&
MI.getDebugLoc()) {
2341 if (
MI.getDebugLoc().getLine())
2342 return std::make_pair(&
MI, IsEmptyPrologue);
2347 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2348 NonTrivialInst = &
MI;
2350 IsEmptyPrologue =
false;
2351 return std::nullopt;
2359 auto CurBlock = MF->
begin();
2360 auto CurInst = CurBlock->begin();
2364 while (CurBlock->empty())
2365 CurInst = (++CurBlock)->begin();
2366 assert(CurInst != CurBlock->end());
2370 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2372 if (CurInst->isTerminator()) {
2381 if (CurBlock->pred_size() > 1)
2392 if (CurBlock == MF->
end())
2394 }
while (CurBlock->empty());
2395 CurInst = CurBlock->begin();
2401 if (!CurInst->isMetaInstruction()) {
2402 auto FoundInst = ExamineInst(*CurInst);
2413 if (CurInst->isCall()) {
2415 Loc &&
Loc->getLine() == 0) {
2417 unsigned ScopeLine = SP->getScopeLine();
2420 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2423 return std::make_pair(&*CurInst,
false);
2429 auto NextInst = std::next(CurInst);
2430 if (NextInst != CurInst->getParent()->end()) {
2447 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2448 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2449 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2453 return std::make_pair(
nullptr, IsEmptyPrologue);
2459 const MDNode *S,
unsigned Flags,
unsigned CUID,
2461 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2464 unsigned FileNo = 1;
2467 Fn =
Scope->getFilename();
2468 if (Line != 0 && DwarfVersion >= 4)
2473 .getOrCreateSourceID(
Scope->getFile());
2475 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2476 Discriminator, Fn, Comment);
2487 bool IsEmptyPrologue = PrologEnd.second;
2490 if (IsEmptyPrologue) {
2498 if (!
DL ||
DL->getLine() != 0)
2509 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2519 KeyInstructions.clear();
2526 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2543 for (
auto &
MBB : *MF) {
2555 for (
auto &
MI :
MBB) {
2556 if (
MI.isMetaInstruction())
2560 if (!
Loc || !
Loc->getLine())
2571 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2576 KeyInstructions.insert(Buoy);
2582 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2586 auto *InlinedAt = Loc->getInlinedAt();
2589 if (!Group || !Rank)
2593 if (BuoyAtom && BuoyAtom != Group) {
2598 auto &[CandidateRank, CandidateInsts] =
2599 GroupCandidates[{InlinedAt, Group}];
2605 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2606 (CandidateRank != 0 && !CandidateInsts.empty()));
2608 assert(Rank &&
"expected nonzero rank");
2611 if (CandidateRank && CandidateRank < Rank)
2618 if (CandidateRank == Rank)
2622 else if (CandidateRank > Rank)
2623 CandidateInsts.clear();
2627 CandidateInsts.push_back(Buoy);
2628 CandidateRank = Rank;
2636 if (CandidateInsts.empty())
2642 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2643 for (
auto *
I : Insts)
2644 KeyInstructions.insert(
I);
2652 ForceIsStmtInstrs.clear();
2684 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2685 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2688 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2691 for (
auto &
MI :
MBB) {
2692 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2705 for (
auto *
MBB : PredMBBsToExamine) {
2706 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2707 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2708 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2710 MachineInstr *
MI = MBBInstrIt->second;
2711 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2713 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2714 ForceIsStmtInstrs.insert(
MI);
2721 CheckMBBEdge(Succ, 0);
2727 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2735 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2742 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2745 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2746 CheckMBBEdge(FBB, FBBLine);
2770 unsigned LastLine = 0;
2772 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2773 LastLine =
DL->getLine();
2778 for (
auto *Succ : SuccessorBBs)
2779 CheckMBBEdge(Succ, LastLine);
2794 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2795 ?
Asm->OutStreamer->emitLineTableLabel()
2798 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2806 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2812 computeKeyInstructions(MF);
2813 findForceIsStmtInstrs(MF);
2821 if (
Asm->OutStreamer->hasRawTextSupport())
2825 return CU.getUniqueID();
2829 const auto &CURanges =
CU->getRanges();
2830 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2833 LineTable.getMCLineSections().addEndEntry(
2834 const_cast<MCSymbol *
>(CURanges.back().End));
2854 "endFunction should be called with the same function as beginFunction");
2857 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2869 collectEntityInfo(TheCU, SP, Processed);
2873 for (
const auto &R :
Asm->MBBSectionRanges)
2874 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2881 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2882 for (
const auto &R :
Asm->MBBSectionRanges)
2892 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2896 for (
const DINode *DN : SP->getRetainedNodes()) {
2899 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2900 assert(LexS &&
"Expected the LexicalScope to be created.");
2903 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2909 LocalDeclsPerLS[LS].insert(DN);
2912 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2913 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2915 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2918 ProcessedSPNodes.insert(SP);
2922 if (!
LScopes.getAbstractScopesList().empty() &&
2924 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2925 FunctionLineTableLabel);
2927 FunctionLineTableLabel =
nullptr;
2930 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2938 LocalDeclsPerLS.clear();
2945void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2957void DwarfDebug::emitDebugInfo() {
2963void DwarfDebug::emitAbbreviations() {
2966 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2969void DwarfDebug::emitStringOffsetsTableHeader() {
2972 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2976template <
typename AccelTableT>
2977void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2979 Asm->OutStreamer->switchSection(Section);
2985void DwarfDebug::emitAccelDebugNames() {
2994void DwarfDebug::emitAccelNames() {
2995 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
3001void DwarfDebug::emitAccelObjC() {
3002 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
3007void DwarfDebug::emitAccelNamespaces() {
3008 emitAccel(AccelNamespace,
3009 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
3014void DwarfDebug::emitAccelTypes() {
3015 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
3045 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
3053 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
3060 case dwarf::DW_TAG_class_type:
3061 case dwarf::DW_TAG_structure_type:
3062 case dwarf::DW_TAG_union_type:
3063 case dwarf::DW_TAG_enumeration_type:
3068 case dwarf::DW_TAG_typedef:
3069 case dwarf::DW_TAG_base_type:
3070 case dwarf::DW_TAG_subrange_type:
3071 case dwarf::DW_TAG_template_alias:
3073 case dwarf::DW_TAG_namespace:
3075 case dwarf::DW_TAG_subprogram:
3077 case dwarf::DW_TAG_variable:
3079 case dwarf::DW_TAG_enumerator:
3089void DwarfDebug::emitDebugPubSections() {
3090 for (
const auto &NU : CUMap) {
3091 DwarfCompileUnit *TheU = NU.second;
3098 Asm->OutStreamer->switchSection(
3099 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3100 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3101 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3103 Asm->OutStreamer->switchSection(
3104 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3105 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3106 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3112 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3113 CU.getDebugSectionOffset());
3115 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3118void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3126 "pub" + Name,
"Length of Public " + Name +
" Info");
3128 Asm->OutStreamer->AddComment(
"DWARF Version");
3131 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3132 emitSectionReference(*TheU);
3134 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3139 for (
const auto &GI : Globals)
3142 return A.second->getOffset() <
B.second->getOffset();
3144 for (
const auto &[Name, Entity] : Vec) {
3145 Asm->OutStreamer->AddComment(
"DIE offset");
3146 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3150 Asm->OutStreamer->AddComment(
3156 Asm->OutStreamer->AddComment(
"External Name");
3157 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3160 Asm->OutStreamer->AddComment(
"End Mark");
3161 Asm->emitDwarfLengthOrOffset(0);
3162 Asm->OutStreamer->emitLabel(EndLabel);
3166void DwarfDebug::emitDebugStr() {
3167 MCSection *StringOffsetsSection =
nullptr;
3169 emitStringOffsetsTableHeader();
3170 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3173 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3174 StringOffsetsSection,
true);
3180 auto &&Comments = DebugLocs.getComments(Entry);
3181 auto Comment = Comments.begin();
3182 auto End = Comments.end();
3189 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3191 DebugLocs.getBytes(Entry).size()),
3192 Asm->getDataLayout().isLittleEndian(), PtrSize);
3197 for (
const auto &
Op : Expr) {
3198 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3199 "3 operand ops not yet supported");
3200 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3201 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3203 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3204 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3206 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3208 for (
unsigned J = 0; J <
Length; ++J)
3213 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3224 auto *DIExpr =
Value.getExpression();
3230 if (DIExpr && DIExpr->isEntryValue()) {
3247 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3250 if (Entry.isInt()) {
3251 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3253 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3254 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3258 }
else if (Entry.isLocation()) {
3260 if (Location.isIndirect())
3266 }
else if (Entry.isTargetIndexLocation()) {
3272 }
else if (Entry.isConstantFP()) {
3275 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3276 }
else if (Entry.getConstantFP()
3279 .getBitWidth() <= 64 ) {
3281 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3284 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3285 << Entry.getConstantFP()
3296 if (!
Value.isVariadic()) {
3297 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3306 return Entry.isLocation() && !Entry.getLoc().getReg();
3311 std::move(ExprCursor),
3312 [EmitValueLocEntry, &
Value](
unsigned Idx,
3314 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3322 assert(!Values.empty() &&
3323 "location list entries without values are redundant");
3324 assert(Begin != End &&
"unexpected location list entry with empty range");
3329 if (
Value.isFragment()) {
3332 return P.isFragment();
3333 }) &&
"all values are expected to be fragments");
3336 for (
const auto &Fragment : Values)
3340 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3351 Asm->OutStreamer->AddComment(
"Loc expr size");
3353 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3354 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3355 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3374 Asm->OutStreamer->AddComment(
"Offset entry count");
3380 Asm->getDwarfOffsetByteSize());
3394 Asm->OutStreamer->AddComment(
"Offset entry count");
3395 Asm->emitInt32(DebugLocs.getLists().size());
3396 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3398 for (
const auto &List : DebugLocs.getLists())
3399 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3400 Asm->getDwarfOffsetByteSize());
3405template <
typename Ranges,
typename PayloadEmitter>
3409 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3411 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3412 auto Size = Asm->MAI->getCodePointerSize();
3416 Asm->OutStreamer->emitLabel(Sym);
3423 for (
const auto &
Range : R)
3424 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3426 const MCSymbol *CUBase =
CU.getBaseAddress();
3427 bool BaseIsSet =
false;
3428 for (
const auto &
P : SectionRanges) {
3429 auto *
Base = CUBase;
3431 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3434 }
else if (!
Base && ShouldUseBaseAddress) {
3435 const MCSymbol *Begin =
P.second.front()->Begin;
3440 Asm->OutStreamer->emitIntValue(-1,
Size);
3441 Asm->OutStreamer->AddComment(
" base address");
3442 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3443 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3449 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3450 Asm->emitInt8(BaseAddressx);
3451 Asm->OutStreamer->AddComment(
" base address index");
3454 }
else if (BaseIsSet && !UseDwarf5) {
3457 Asm->OutStreamer->emitIntValue(-1,
Size);
3458 Asm->OutStreamer->emitIntValue(0,
Size);
3461 for (
const auto *RS :
P.second) {
3464 assert(Begin &&
"Range without a begin symbol?");
3465 assert(End &&
"Range without an end symbol?");
3469 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3470 Asm->emitInt8(OffsetPair);
3471 Asm->OutStreamer->AddComment(
" starting offset");
3472 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3473 Asm->OutStreamer->AddComment(
" ending offset");
3474 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3476 Asm->emitLabelDifference(Begin,
Base,
Size);
3477 Asm->emitLabelDifference(End,
Base,
Size);
3479 }
else if (UseDwarf5) {
3487 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3488 Asm->emitInt8(StartxEndx);
3489 Asm->OutStreamer->AddComment(
" start index");
3491 Asm->OutStreamer->AddComment(
" end index");
3494 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3495 Asm->emitInt8(StartxLength);
3496 Asm->OutStreamer->AddComment(
" start index");
3498 Asm->OutStreamer->AddComment(
" length");
3499 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3502 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3503 Asm->OutStreamer->emitSymbolValue(End,
Size);
3510 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3514 Asm->OutStreamer->emitIntValue(0,
Size);
3515 Asm->OutStreamer->emitIntValue(0,
Size);
3523 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3524 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3527 DD.emitDebugLocEntryLocation(E, List.CU);
3531void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3532 if (DebugLocs.getLists().empty())
3535 Asm->OutStreamer->switchSection(Sec);
3541 for (
const auto &
List : DebugLocs.getLists())
3545 Asm->OutStreamer->emitLabel(TableEnd);
3549void DwarfDebug::emitDebugLoc() {
3552 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3553 :
Asm->getObjFileLowering().getDwarfLocSection());
3557void DwarfDebug::emitDebugLocDWO() {
3560 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3565 for (
const auto &
List : DebugLocs.getLists()) {
3566 Asm->OutStreamer->switchSection(
3567 Asm->getObjFileLowering().getDwarfLocDWOSection());
3568 Asm->OutStreamer->emitLabel(
List.Label);
3570 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3579 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3580 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3581 Asm->emitULEB128(idx);
3587 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3597void DwarfDebug::emitDebugARanges() {
3598 if (ArangeLabels.empty())
3605 for (
const SymbolCU &SCU : ArangeLabels) {
3606 if (SCU.Sym->isInSection()) {
3608 MCSection *Section = &SCU.Sym->getSection();
3609 SectionMap[Section].push_back(SCU);
3614 SectionMap[
nullptr].push_back(SCU);
3618 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3620 for (
auto &
I : SectionMap) {
3628 for (
const SymbolCU &Cur :
List) {
3630 Span.
Start = Cur.Sym;
3633 Spans[Cur.CU].push_back(Span);
3639 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3643 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3644 const SymbolCU &Prev =
List[n - 1];
3645 const SymbolCU &Cur =
List[n];
3648 if (Cur.
CU != Prev.
CU) {
3650 Span.
Start = StartSym;
3653 Spans[Prev.
CU].push_back(Span);
3660 Asm->OutStreamer->switchSection(
3661 Asm->getObjFileLowering().getDwarfARangesSection());
3663 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3666 std::vector<DwarfCompileUnit *> CUs;
3667 for (
const auto &it : Spans) {
3668 DwarfCompileUnit *
CU = it.first;
3673 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3674 return A->getUniqueID() <
B->getUniqueID();
3678 for (DwarfCompileUnit *
CU : CUs) {
3679 std::vector<ArangeSpan> &
List = Spans[
CU];
3682 if (
auto *Skel =
CU->getSkeleton())
3686 unsigned ContentSize =
3688 Asm->getDwarfOffsetByteSize() +
3693 unsigned TupleSize = PtrSize * 2;
3697 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3700 ContentSize += (
List.size() + 1) * TupleSize;
3703 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3704 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3706 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3707 emitSectionReference(*
CU);
3708 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3709 Asm->emitInt8(PtrSize);
3710 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3713 Asm->OutStreamer->emitFill(Padding, 0xff);
3715 for (
const ArangeSpan &Span :
List) {
3716 Asm->emitLabelReference(Span.Start, PtrSize);
3723 auto SizeRef = SymSize.find(Span.Start);
3724 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3725 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3730 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3733 Size = SizeRef->second;
3735 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3739 Asm->OutStreamer->AddComment(
"ARange terminator");
3740 Asm->OutStreamer->emitIntValue(0, PtrSize);
3741 Asm->OutStreamer->emitIntValue(0, PtrSize);
3749 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3750 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3752 List.CU->getCUNode()->getRangesBaseAddress() ||
3764 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3767 Asm->OutStreamer->switchSection(Section);
3777 Asm->OutStreamer->emitLabel(TableEnd);
3782void DwarfDebug::emitDebugRanges() {
3785 emitDebugRangesImpl(Holder,
3787 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3788 :
Asm->getObjFileLowering().getDwarfRangesSection());
3791void DwarfDebug::emitDebugRangesDWO() {
3793 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3800 enum HeaderFlagMask {
3801#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3802#include "llvm/BinaryFormat/Dwarf.def"
3804 Asm->OutStreamer->AddComment(
"Macro information version");
3805 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3808 if (Asm->isDwarf64()) {
3809 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3810 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3812 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3813 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3815 Asm->OutStreamer->AddComment(
"debug_line_offset");
3817 Asm->emitDwarfLengthOrOffset(0);
3819 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3822void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3823 for (
auto *MN : Nodes) {
3827 emitMacroFile(*
F, U);
3833void DwarfDebug::emitMacro(
DIMacro &M) {
3834 StringRef
Name =
M.getName();
3835 StringRef
Value =
M.getValue();
3841 if (UseDebugMacroSection) {
3844 ? dwarf::DW_MACRO_define_strx
3845 : dwarf::DW_MACRO_undef_strx;
3848 Asm->OutStreamer->AddComment(
"Line Number");
3849 Asm->emitULEB128(
M.getLine());
3850 Asm->OutStreamer->AddComment(
"Macro String");
3852 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3855 ? dwarf::DW_MACRO_GNU_define_indirect
3856 : dwarf::DW_MACRO_GNU_undef_indirect;
3859 Asm->OutStreamer->AddComment(
"Line Number");
3860 Asm->emitULEB128(
M.getLine());
3861 Asm->OutStreamer->AddComment(
"Macro String");
3862 Asm->emitDwarfSymbolReference(
3863 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3867 Asm->emitULEB128(
M.getMacinfoType());
3868 Asm->OutStreamer->AddComment(
"Line Number");
3869 Asm->emitULEB128(
M.getLine());
3870 Asm->OutStreamer->AddComment(
"Macro String");
3871 Asm->OutStreamer->emitBytes(Str);
3872 Asm->emitInt8(
'\0');
3876void DwarfDebug::emitMacroFileImpl(
3878 StringRef (*MacroFormToString)(
unsigned Form)) {
3880 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3881 Asm->emitULEB128(StartFile);
3882 Asm->OutStreamer->AddComment(
"Line Number");
3884 Asm->OutStreamer->AddComment(
"File Number");
3887 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3889 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3891 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3893 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3894 Asm->emitULEB128(EndFile);
3901 if (UseDebugMacroSection)
3903 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3910void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3911 for (
const auto &
P : CUMap) {
3912 auto &TheCU = *
P.second;
3914 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3916 DIMacroNodeArray Macros = CUNode->getMacros();
3919 Asm->OutStreamer->switchSection(Section);
3920 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3921 if (UseDebugMacroSection)
3923 handleMacroNodes(Macros, U);
3924 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3930void DwarfDebug::emitDebugMacinfo() {
3931 auto &ObjLower =
Asm->getObjFileLowering();
3932 emitDebugMacinfoImpl(UseDebugMacroSection
3933 ? ObjLower.getDwarfMacroSection()
3934 : ObjLower.getDwarfMacinfoSection());
3937void DwarfDebug::emitDebugMacinfoDWO() {
3938 auto &ObjLower =
Asm->getObjFileLowering();
3939 emitDebugMacinfoImpl(UseDebugMacroSection
3940 ? ObjLower.getDwarfMacroDWOSection()
3941 : ObjLower.getDwarfMacinfoDWOSection());
3946void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3947 std::unique_ptr<DwarfCompileUnit> NewU) {
3949 if (!CompilationDir.empty())
3950 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3951 addGnuPubAttributes(*NewU, Die);
3953 SkeletonHolder.addUnit(std::move(NewU));
3958 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3959 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3961 DwarfCompileUnit &NewCU = *OwnedUnit;
3962 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3969 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3976void DwarfDebug::emitDebugInfoDWO() {
3984void DwarfDebug::emitDebugAbbrevDWO() {
3986 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3989void DwarfDebug::emitDebugLineDWO() {
3991 SplitTypeUnitFileTable.Emit(
3992 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3993 Asm->getObjFileLowering().getDwarfLineDWOSection());
3996void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3998 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
3999 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
4006void DwarfDebug::emitDebugStrDWO() {
4008 emitStringOffsetsTableHeaderDWO();
4010 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
4011 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
4016void DwarfDebug::emitDebugAddr() {
4017 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
4023 const DICompileUnit *DIUnit =
CU.getCUNode();
4024 SplitTypeUnitFileTable.maybeSetRootFile(
4027 return &SplitTypeUnitFileTable;
4038 return Result.high();
4047 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4050 auto Ins = TypeSignatures.try_emplace(CTy);
4052 CU.addDIETypeSignature(RefDie, Ins.first->second);
4057 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4058 AddrPool.resetUsedFlag();
4060 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4064 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4066 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4067 CU.getSourceLanguage());
4071 Ins.first->second = Signature;
4079 if (!CompilationDir.empty())
4080 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4081 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4082 Asm->TM.Options.MCOptions.SplitDwarfFile);
4086 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4087 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4092 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4093 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4096 CU.applyStmtList(UnitDie);
4107 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4108 TypeUnitsUnderConstruction.clear();
4112 if (AddrPool.hasBeenUsed()) {
4113 AccelTypeUnitsDebugNames.clear();
4117 for (
const auto &
TU : TypeUnitsToAdd)
4118 TypeSignatures.erase(
TU.second);
4126 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4132 for (
auto &
TU : TypeUnitsToAdd) {
4133 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4138 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4140 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4143 AccelTypeUnitsDebugNames.convertDieToOffset();
4144 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4145 AccelTypeUnitsDebugNames.clear();
4148 CU.addDIETypeSignature(RefDie, Signature);
4155template <
typename DataT>
4156void DwarfDebug::addAccelNameImpl(
4161 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4178 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4179 ((&Current == &AccelDebugNames) &&
4180 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4181 "Kind is CU but TU is being processed.");
4182 assert(((&Current == &AccelDebugNames) ||
4183 ((&Current == &AccelTypeUnitsDebugNames) &&
4184 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4185 "Kind is TU but CU is being processed.");
4188 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4189 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4203 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4212 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4219 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4225 const DIE &Die,
char Flags) {
4226 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4230 return Asm->OutStreamer->getContext().getDwarfVersion();
4234 if (
Asm->getDwarfVersion() >= 4)
4235 return dwarf::Form::DW_FORM_sec_offset;
4236 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4237 "DWARF64 is not defined prior DWARFv3");
4238 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4239 : dwarf::Form::DW_FORM_data4;
4243 return SectionLabels.lookup(S);
4247 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4252std::optional<MD5::MD5Result>
4256 return std::nullopt;
4257 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4259 return std::nullopt;
4264 std::string ChecksumString =
fromHex(Checksum->Value);
4281 if (
MBB.getAlignment() ==
Align(1))
4284 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4291 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4292 if (PrevLoc.getLine()) {
4293 Asm->OutStreamer->emitDwarfLocDirective(
4294 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4296 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.
ArrayRef - 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
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
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.
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.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - 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.