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())
355 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
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();
380 bool Dwarf64 = DwarfVersion >= 3 &&
389 ((
Asm->TM.Options.MCOptions.Dwarf64 ||
MMI->getModule()->isDwarf64()) &&
390 TT.isOSBinFormatELF()) ||
391 TT.isOSBinFormatXCOFF();
393 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
400 UseSectionsAsReferences = TT.isNVPTX();
405 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
406 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
410 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
417 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
419 UseDWARF2Bitfields = DwarfVersion < 4;
425 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
429 EmitDebugEntryValues =
Asm->TM.Options.ShouldEmitDebugEntryValues();
433 UseDebugMacroSection =
442 if (DwarfVersion >= 5)
445 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
454 return Name.starts_with(
"+") || Name.starts_with(
"-");
461 return Name.contains(
") ");
467 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
472 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
473 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
477 return In.slice(In.find(
' ') + 1, In.find(
']'));
490 if (!SP->isDefinition())
493 if (SP->getName() !=
"")
524 if (Scope->isAbstractScope())
542 if (
auto *SkelCU =
CU.getSkeleton())
543 if (
CU.getCUNode()->getSplitDebugInlining())
554 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
555 if (
CU.getSkeleton())
561void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
563 assert(Scope && Scope->getScopeNode());
564 assert(Scope->isAbstractScope());
565 assert(!Scope->getInlinedAt());
571 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
573 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
574 if (
auto *SkelCU =
CU.getSkeleton())
575 if (
CU.getCUNode()->getSplitDebugInlining())
576 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
610template <
typename ValT>
614 for (
auto Param : DescribedParams) {
615 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
625 "Combined debug expression is invalid");
640 auto &ParamsForFwdReg = Worklist[
Reg];
641 for (
auto Param : ParamsToAdd) {
644 return D.ParamReg == Param.ParamReg;
646 "Same parameter described twice by forwarding reg");
653 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
673 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
674 for (
auto &RegUnit : ClobberedRegUnits)
675 if (
TRI.hasRegUnit(
Reg, RegUnit))
680 auto DescribeFwdRegsByCalleeSavedCopy = [&](
const DestSourcePair &CopyInst) {
681 Register CopyDestReg = CopyInst.Destination->getReg();
682 Register CopySrcReg = CopyInst.Source->getReg();
683 if (IsRegClobberedInMeantime(CopyDestReg))
687 if (!
TRI.isCalleeSavedPhysReg(CopyDestReg, *MF))
694 for (
auto FwdRegIt = ForwardedRegWorklist.
begin();
695 FwdRegIt != ForwardedRegWorklist.
end();) {
697 if (FwdRegIt->first == CopySrcReg)
699 else if (
unsigned SubRegIdx =
700 TRI.getSubRegIndex(CopySrcReg, FwdRegIt->first))
701 if (
Register CopyDestSubReg =
TRI.getSubReg(CopyDestReg, SubRegIdx))
711 FwdRegIt = ForwardedRegWorklist.
erase(FwdRegIt);
719 if (
auto CopyInst =
TII.isCopyInstr(*CurMI))
720 DescribeFwdRegsByCalleeSavedCopy(*CopyInst);
748 if (
MI.isDebugInstr())
752 if (MO.getReg().isPhysical()) {
753 for (
auto &FwdReg : ForwardedRegWorklist)
754 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
755 Defs.insert(FwdReg.first);
764 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
765 if (FwdRegDefs.
empty()) {
771 for (
auto ParamFwdReg : FwdRegDefs) {
772 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
773 if (ParamValue->first.isImm()) {
774 int64_t Val = ParamValue->first.getImm();
776 ForwardedRegWorklist[ParamFwdReg], Params);
777 }
else if (ParamValue->first.isReg()) {
778 Register RegLoc = ParamValue->first.getReg();
779 Register SP = TLI.getStackPointerRegisterToSaveRestore();
781 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
784 if (!IsRegClobberedInMeantime(RegLoc) &&
785 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
788 ForwardedRegWorklist[ParamFwdReg], Params);
797 ForwardedRegWorklist[ParamFwdReg]);
804 for (
auto ParamFwdReg : FwdRegDefs)
805 ForwardedRegWorklist.
erase(ParamFwdReg);
812 for (
auto &New : TmpWorklistItems)
814 TmpWorklistItems.
clear();
831 if (ForwardedRegWorklist.
empty())
838 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
849 auto CSInfo = CalleesMap.
find(CallMI);
852 if (CSInfo == CalleesMap.end())
866 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
868 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
870 assert(InsertedReg &&
"Single register used to forward two arguments?");
875 for (
const auto &MO : CallMI->
uses())
876 if (MO.isReg() && MO.isUndef())
877 ForwardedRegWorklist.
erase(MO.getReg());
887 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
896 assert(std::next(Suc) == BundleEnd &&
897 "More than one instruction in call delay slot");
904 for (;
I !=
MBB->rend(); ++
I) {
911 if (ShouldTryEmitEntryVals) {
915 for (
auto &RegEntry : ForwardedRegWorklist) {
922void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
927 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
934 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
937 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
940 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
941 if (!
MI.isBundledWithSucc())
943 auto Suc = std::next(
MI.getIterator());
945 (void)CallInstrBundle;
947 (void)DelaySlotBundle;
954 "Call and its successor instruction don't have same label after.");
959 auto addCallSiteTargetForIndirectCalls = [&](
const MachineInstr *
MI,
961 const MachineFunction *MF =
MI->getMF();
963 auto CSInfo = CalleesMap.
find(
MI);
965 if (CSInfo == CalleesMap.end() || !CSInfo->second.CallTarget)
968 MDNode *CallTarget = CSInfo->second.CallTarget;
970 assert(!CallSiteDIE.findAttribute(dwarf::DW_AT_LLVM_virtual_call_origin) &&
971 "DW_AT_LLVM_virtual_call_origin already exists");
973 DIE *CalleeDIE =
CU.getOrCreateSubprogramDIE(CalleeSP,
nullptr);
974 assert(CalleeDIE &&
"Could not create DIE for call site entry origin");
975 CU.addDIEEntry(CallSiteDIE,
976 CU.getDwarf5OrGNUAttr(dwarf::DW_AT_LLVM_virtual_call_origin),
979 CU.addLinkageNamesToDeclarations(*
this, *CalleeSP, *CalleeDIE);
983 for (
const MachineBasicBlock &
MBB : MF) {
993 if (!
MI.isCandidateForAdditionalCallInfo())
1002 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
1010 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
1011 bool PhysRegCalleeOperand =
1013 MachineLocation CallTarget{0};
1015 const DISubprogram *CalleeSP =
nullptr;
1016 const Function *CalleeDecl =
nullptr;
1017 if (PhysRegCalleeOperand) {
1018 bool Scalable =
false;
1019 const MachineOperand *BaseOp =
nullptr;
1020 const TargetRegisterInfo &
TRI =
1021 *
Asm->MF->getSubtarget().getRegisterInfo();
1022 if (
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, Scalable, &
TRI)) {
1023 if (BaseOp && BaseOp->
isReg() && !Scalable)
1024 CallTarget = MachineLocation(BaseOp->
getReg(),
true);
1028 CallTarget = MachineLocation(CalleeOp.
getReg());
1037 if (CalleeSP ==
nullptr && CallTarget.
getReg() == 0 &&
1038 AllocSiteTy ==
nullptr)
1048 const MachineInstr *TopLevelCallMI =
1055 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1064 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1067 dbgs() <<
"CallSiteEntry: " << MF.getName() <<
" -> "
1071 MF.getSubtarget().getRegisterInfo()->getName(
1073 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1075 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1076 ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
1080 addCallSiteTargetForIndirectCalls(TopLevelCallMI, CallSiteDIE);
1087 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1094 if (!
U.hasDwarfPubSections())
1097 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1100void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1108 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1109 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1111 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1114 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1117 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1118 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1121 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1125 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1127 if (!SysRoot.
empty())
1128 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1129 StringRef SDK = DIUnit->
getSDK();
1131 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1142 if (!CompilationDir.empty())
1143 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1144 addGnuPubAttributes(NewCU, Die);
1149 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1153 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1156 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1157 dwarf::DW_FORM_data1, RVer);
1162 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1167 ? dwarf::DW_AT_dwo_name
1168 : dwarf::DW_AT_GNU_dwo_name;
1176DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1177 if (
auto *
CU = CUMap.lookup(DIUnit))
1185 return *CUMap.begin()->second;
1189 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1191 DwarfCompileUnit &NewCU = *OwnedUnit;
1198 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1199 Asm->OutStreamer->emitDwarfFile0Directive(
1205 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1207 finishUnitAttributes(DIUnit, NewCU);
1208 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1211 CUMap.insert({DIUnit, &NewCU});
1212 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1226 if (!
A.Expr || !
B.Expr)
1228 auto FragmentA =
A.Expr->getFragmentInfo();
1229 auto FragmentB =
B.Expr->getFragmentInfo();
1230 if (!FragmentA || !FragmentB)
1232 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1237 return A.Expr ==
B.Expr;
1252 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1253 M->debug_compile_units_end());
1254 if (NumDebugCUs == 0)
1257 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1258 SingleCU = NumDebugCUs == 1;
1263 Global.getDebugInfo(GVs);
1264 for (
auto *GVE : GVs)
1265 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1273 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1281 Asm->createTempSymbol(
"rnglists_table_base"));
1285 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1290 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1291 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1294 if (CUNode->getImportedEntities().empty() &&
1295 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1296 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1302 for (
auto *GVE : CUNode->getGlobalVariables()) {
1306 auto &GVMapEntry = GVMap[GVE->getVariable()];
1307 auto *Expr = GVE->getExpression();
1308 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1309 GVMapEntry.push_back({
nullptr, Expr});
1313 for (
auto *GVE : CUNode->getGlobalVariables()) {
1315 if (Processed.
insert(GV).second)
1319 for (
auto *Ty : CUNode->getEnumTypes()) {
1321 "Unexpected function-local entity in 'enums' CU field.");
1325 for (
auto *Ty : CUNode->getRetainedTypes()) {
1328 CU.getOrCreateTypeDIE(RT);
1333void DwarfDebug::finishEntityDefinitions() {
1334 for (
const auto &Entity : ConcreteEntities) {
1335 DIE *Die = Entity->getDIE();
1342 Unit->finishEntityDefinition(Entity.get());
1346void DwarfDebug::finishSubprogramDefinitions() {
1347 for (
const DISubprogram *SP : ProcessedSPNodes) {
1350 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1351 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1355void DwarfDebug::finalizeModuleInfo() {
1356 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1358 finishSubprogramDefinitions();
1360 finishEntityDefinitions();
1362 bool HasEmittedSplitCU =
false;
1366 for (
const auto &
P : CUMap) {
1367 auto &TheCU = *
P.second;
1368 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1370 TheCU.attachLexicalScopesAbstractOrigins();
1373 TheCU.constructContainingTypeDIEs();
1378 auto *SkCU = TheCU.getSkeleton();
1380 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1383 (void)HasEmittedSplitCU;
1385 "Multiple CUs emitted into a single dwo file");
1386 HasEmittedSplitCU =
true;
1388 ? dwarf::DW_AT_dwo_name
1389 : dwarf::DW_AT_GNU_dwo_name;
1390 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1391 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1392 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1393 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1399 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1404 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1405 dwarf::DW_FORM_data8,
ID);
1406 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1407 dwarf::DW_FORM_data8,
ID);
1410 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1412 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1416 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1425 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1427 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1432 if (!(
Asm->TM.getTargetTriple().isNVPTX() &&
tuneForGDB())) {
1438 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1441 U.setBaseAddress(TheCU.getRanges().front().Begin);
1442 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1449 U.addAddrTableBase();
1452 if (
U.hasRangeLists())
1453 U.addRnglistsBase();
1456 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1465 if (CUNode->getMacros()) {
1466 if (UseDebugMacroSection) {
1468 TheCU.addSectionDelta(
1469 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1473 ? dwarf::DW_AT_macros
1474 : dwarf::DW_AT_GNU_macros;
1475 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1480 TheCU.addSectionDelta(
1481 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1482 U.getMacroLabelBegin(),
1485 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1486 U.getMacroLabelBegin(),
1493 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1494 if (CUNode->getDWOId())
1495 getOrCreateDwarfCompileUnit(CUNode);
1500 SkeletonHolder.computeSizeAndOffsets();
1504 AccelDebugNames.convertDieToOffset();
1513 assert(CurFn ==
nullptr);
1516 for (
const auto &
P : CUMap) {
1521 for (
auto *IE : CUNode->getImportedEntities()) {
1523 "Unexpected function-local entity in 'imports' CU field.");
1524 CU->getOrCreateImportedEntityDIE(IE);
1528 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1530 CU->getOrCreateImportedEntityDIE(IE);
1532 CU->getOrCreateTypeDIE(Ty);
1538 CU->createBaseTypeDIEs();
1543 if (!
Asm || !
Asm->hasDebugInfo())
1547 finalizeModuleInfo();
1557 emitAbbreviations();
1563 if (UseARangesSection)
1571 emitDebugMacinfoDWO();
1581 emitDebugAbbrevDWO();
1583 emitDebugRangesDWO();
1593 emitAccelNamespaces();
1597 emitAccelDebugNames();
1606 emitDebugPubSections();
1614 if (
CU.getExistingAbstractEntity(
Node))
1619 CU.createAbstractEntity(
Node, Scope);
1628void DwarfDebug::collectVariableInfoFromMFTable(
1630 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1631 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1632 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1635 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1636 "Expected inlined-at fields to agree");
1638 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1645 <<
", no variable scope found\n");
1649 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1653 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1654 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1655 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1657 if (PreviousMMI &&
VI.inStackSlot())
1658 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1660 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1661 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1666 if (PreviousLoc->holds<Loc::MMI>())
1667 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1670 <<
", conflicting fragment location types\n");
1675 auto RegVar = std::make_unique<DbgVariable>(
1677 if (
VI.inStackSlot())
1678 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1680 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1683 InfoHolder.addScopeVariable(Scope, RegVar.get());
1684 MFVars.
insert({Var, RegVar.get()});
1685 ConcreteEntities.push_back(std::move(RegVar));
1697 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1705 if (LSRange.size() == 0)
1708 const MachineInstr *LScopeBegin = LSRange.front().first;
1712 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1718 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1721 auto PredDL = Pred->getDebugLoc();
1722 if (!PredDL || Pred->isMetaInstruction())
1726 if (
DL->getScope() == PredDL->getScope())
1729 if (!PredScope || LScope->dominates(PredScope))
1742 if (
MBB->pred_empty() &&
1749 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1793 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1795 bool isSafeForSingleLocation =
true;
1796 const MachineInstr *StartDebugMI =
nullptr;
1797 const MachineInstr *EndMI =
nullptr;
1799 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1800 const MachineInstr *
Instr = EI->getInstr();
1803 size_t Index = std::distance(EB, EI);
1804 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1811 "Forgot label before/after instruction starting a range!");
1814 if (std::next(EI) == Entries.
end()) {
1815 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1817 if (EI->isClobber())
1818 EndMI = EI->getInstr();
1820 else if (std::next(EI)->isClobber())
1824 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1826 if (EI->isDbgValue())
1832 if (EI->isDbgValue()) {
1839 if (!
Instr->isUndefDebugValue()) {
1844 if (
Instr->getDebugExpression()->isFragment())
1845 isSafeForSingleLocation =
false;
1848 StartDebugMI =
Instr;
1850 isSafeForSingleLocation =
false;
1856 if (OpenRanges.
empty())
1860 if (StartLabel == EndLabel) {
1861 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1866 for (
auto &R : OpenRanges)
1874 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1875 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1876 for (
const auto &[MBBSectionId, MBBSectionRange] :
1877 Asm->MBBSectionRanges) {
1878 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1879 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1882 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1883 MBBSectionRange.EndLabel, Values);
1886 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1893 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1894 for (
auto &
Value : CurEntry->getValues())
1896 dbgs() <<
"-----\n";
1899 auto PrevEntry = std::next(CurEntry);
1900 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1904 if (!isSafeForSingleLocation ||
1911 if (!
Asm->MF->hasBBSections())
1919 const MachineBasicBlock *RangeMBB =
nullptr;
1920 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1921 RangeMBB = &
Asm->MF->front();
1923 RangeMBB = Entries.
begin()->getInstr()->getParent();
1925 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1926 "Range MBB not found in MBBSectionRanges!");
1928 auto *NextEntry = std::next(CurEntry);
1929 auto NextRangeIt = std::next(RangeIt);
1930 while (NextEntry !=
DebugLoc.end()) {
1931 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1938 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1939 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1940 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1941 CurEntry->getValues() != NextEntry->getValues())
1943 RangeIt = NextRangeIt;
1944 NextRangeIt = std::next(RangeIt);
1945 CurEntry = NextEntry;
1946 NextEntry = std::next(CurEntry);
1956 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1958 ConcreteEntities.push_back(
1964 ConcreteEntities.push_back(
1970 return ConcreteEntities.back().get();
1978 collectVariableInfoFromMFTable(TheCU, Processed);
1981 InlinedEntity
IV =
I.first;
1986 const auto &HistoryMapEntries =
I.second;
1990 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
1993 LexicalScope *
Scope =
nullptr;
1995 if (
const DILocation *IA =
IV.second)
2005 *Scope, LocalVar,
IV.second));
2007 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
2013 size_t HistSize = HistoryMapEntries.size();
2014 bool SingleValueWithClobber =
2015 HistSize == 2 && HistoryMapEntries[1].isClobber();
2016 if (HistSize == 1 || SingleValueWithClobber) {
2018 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
2020 RegVar->emplace<Loc::Single>(MInsn);
2026 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
2030 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
2035 if (isValidSingleLocation) {
2036 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
2047 for (
auto &Entry : Entries)
2054 InlinedEntity IL =
I.first;
2055 const MachineInstr *
MI =
I.second;
2059 LexicalScope *
Scope =
nullptr;
2062 const DILocalScope *LocalScope =
2063 Label->getScope()->getNonLexicalBlockFileScope();
2065 if (
const DILocation *IA = IL.second)
2078 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2082 for (
const DINode *DN :
SP->getRetainedNodes()) {
2085 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2087 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2089 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2091 LocalDeclsPerLS[
LS].insert(DN);
2105 if (!
MI.isBundledWithSucc())
2107 auto Suc = std::next(
MI.getIterator());
2112 assert(Suc->isBundledWithPred() &&
2113 "Call bundle instructions are out of order");
2118 if (!NoDebug && SP->areAllCallsDescribed() &&
2120 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2122 bool IsTail =
TII->isTailCall(*
MI);
2140 auto RecordLineZero = [&]() {
2144 const MDNode *Scope =
nullptr;
2145 unsigned Column = 0;
2150 recordSourceLine(0, Column, Scope, 0);
2155 unsigned LastAsmLine =
2156 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2161 if (
MI->isMetaInstruction())
2182 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2184 if (
Asm->OutStreamer->isVerboseAsm()) {
2188 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2197 bool ScopeUsesKeyInstructions =
2199 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2202 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2203 IsKey = KeyInstructions.contains(
MI);
2209 assert(
MI->getParent() == &*
MI->getMF()->begin());
2210 recordSourceLine(SP->getScopeLine(), 0, SP,
2215 bool PrevInstInSameSection =
2217 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2218 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2219 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2229 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2231 RecordSourceLine(
DL, Flags);
2244 if (LastAsmLine == 0)
2265 if (
DL.getLine() == 0 && LastAsmLine == 0)
2272 if (ScopeUsesKeyInstructions) {
2279 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2294 if (
Asm->OutStreamer->isVerboseAsm()) {
2298 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2307static std::pair<const MachineInstr *, bool>
2318 bool IsEmptyPrologue =
2319 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2324 -> std::optional<std::pair<const MachineInstr *, bool>> {
2326 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2327 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2330 if (!isFrameSetup &&
MI.getDebugLoc()) {
2336 if (
MI.getDebugLoc().getLine())
2337 return std::make_pair(&
MI, IsEmptyPrologue);
2342 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2343 NonTrivialInst = &
MI;
2345 IsEmptyPrologue =
false;
2346 return std::nullopt;
2354 auto CurBlock = MF->
begin();
2355 auto CurInst = CurBlock->begin();
2359 while (CurBlock->empty())
2360 CurInst = (++CurBlock)->begin();
2361 assert(CurInst != CurBlock->end());
2365 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2367 if (CurInst->isTerminator()) {
2376 if (CurBlock->pred_size() > 1)
2387 if (CurBlock == MF->
end())
2389 }
while (CurBlock->empty());
2390 CurInst = CurBlock->begin();
2396 if (!CurInst->isMetaInstruction()) {
2397 auto FoundInst = ExamineInst(*CurInst);
2408 if (CurInst->isCall()) {
2410 Loc &&
Loc->getLine() == 0) {
2412 unsigned ScopeLine = SP->getScopeLine();
2415 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2418 return std::make_pair(&*CurInst,
false);
2424 auto NextInst = std::next(CurInst);
2425 if (NextInst != CurInst->getParent()->end()) {
2442 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2443 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2444 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2448 return std::make_pair(
nullptr, IsEmptyPrologue);
2454 const MDNode *S,
unsigned Flags,
unsigned CUID,
2456 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2459 unsigned FileNo = 1;
2462 Fn =
Scope->getFilename();
2463 if (Line != 0 && DwarfVersion >= 4)
2468 .getOrCreateSourceID(
Scope->getFile());
2470 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2471 Discriminator, Fn, Comment);
2482 bool IsEmptyPrologue = PrologEnd.second;
2485 if (IsEmptyPrologue) {
2493 if (!
DL ||
DL->getLine() != 0)
2504 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2514 KeyInstructions.clear();
2521 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2538 for (
auto &
MBB : *MF) {
2550 for (
auto &
MI :
MBB) {
2551 if (
MI.isMetaInstruction())
2555 if (!
Loc || !
Loc->getLine())
2566 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2571 KeyInstructions.insert(Buoy);
2577 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2581 auto *InlinedAt = Loc->getInlinedAt();
2584 if (!Group || !Rank)
2588 if (BuoyAtom && BuoyAtom != Group) {
2593 auto &[CandidateRank, CandidateInsts] =
2594 GroupCandidates[{InlinedAt, Group}];
2600 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2601 (CandidateRank != 0 && !CandidateInsts.empty()));
2603 assert(Rank &&
"expected nonzero rank");
2606 if (CandidateRank && CandidateRank < Rank)
2613 if (CandidateRank == Rank)
2617 else if (CandidateRank > Rank)
2618 CandidateInsts.clear();
2622 CandidateInsts.push_back(Buoy);
2623 CandidateRank = Rank;
2631 if (CandidateInsts.empty())
2637 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2638 for (
auto *
I : Insts)
2639 KeyInstructions.insert(
I);
2647 ForceIsStmtInstrs.clear();
2679 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2680 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2683 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2686 for (
auto &
MI :
MBB) {
2687 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2700 for (
auto *
MBB : PredMBBsToExamine) {
2701 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2702 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2703 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2705 MachineInstr *
MI = MBBInstrIt->second;
2706 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2708 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2709 ForceIsStmtInstrs.insert(
MI);
2716 CheckMBBEdge(Succ, 0);
2722 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2730 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2737 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2740 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2741 CheckMBBEdge(FBB, FBBLine);
2765 unsigned LastLine = 0;
2767 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2768 LastLine =
DL->getLine();
2773 for (
auto *Succ : SuccessorBBs)
2774 CheckMBBEdge(Succ, LastLine);
2789 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2790 ?
Asm->OutStreamer->emitLineTableLabel()
2793 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2801 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2807 computeKeyInstructions(MF);
2808 findForceIsStmtInstrs(MF);
2816 if (
Asm->OutStreamer->hasRawTextSupport())
2820 return CU.getUniqueID();
2824 const auto &CURanges =
CU->getRanges();
2825 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2828 LineTable.getMCLineSections().addEndEntry(
2829 const_cast<MCSymbol *
>(CURanges.back().End));
2849 "endFunction should be called with the same function as beginFunction");
2852 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2864 collectEntityInfo(TheCU, SP, Processed);
2868 for (
const auto &R :
Asm->MBBSectionRanges)
2869 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2876 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2877 for (
const auto &R :
Asm->MBBSectionRanges)
2887 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2891 for (
const DINode *DN : SP->getRetainedNodes()) {
2894 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2895 assert(LexS &&
"Expected the LexicalScope to be created.");
2898 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2904 LocalDeclsPerLS[LS].insert(DN);
2907 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2908 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2910 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2913 ProcessedSPNodes.insert(SP);
2917 if (!
LScopes.getAbstractScopesList().empty() &&
2919 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2920 FunctionLineTableLabel);
2922 FunctionLineTableLabel =
nullptr;
2925 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2933 LocalDeclsPerLS.clear();
2940void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2952void DwarfDebug::emitDebugInfo() {
2958void DwarfDebug::emitAbbreviations() {
2961 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2964void DwarfDebug::emitStringOffsetsTableHeader() {
2967 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2971template <
typename AccelTableT>
2972void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2974 Asm->OutStreamer->switchSection(Section);
2980void DwarfDebug::emitAccelDebugNames() {
2989void DwarfDebug::emitAccelNames() {
2990 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
2996void DwarfDebug::emitAccelObjC() {
2997 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
3002void DwarfDebug::emitAccelNamespaces() {
3003 emitAccel(AccelNamespace,
3004 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
3009void DwarfDebug::emitAccelTypes() {
3010 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
3040 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
3048 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
3055 case dwarf::DW_TAG_class_type:
3056 case dwarf::DW_TAG_structure_type:
3057 case dwarf::DW_TAG_union_type:
3058 case dwarf::DW_TAG_enumeration_type:
3063 case dwarf::DW_TAG_typedef:
3064 case dwarf::DW_TAG_base_type:
3065 case dwarf::DW_TAG_subrange_type:
3066 case dwarf::DW_TAG_template_alias:
3068 case dwarf::DW_TAG_namespace:
3070 case dwarf::DW_TAG_subprogram:
3072 case dwarf::DW_TAG_variable:
3074 case dwarf::DW_TAG_enumerator:
3084void DwarfDebug::emitDebugPubSections() {
3085 for (
const auto &NU : CUMap) {
3086 DwarfCompileUnit *TheU = NU.second;
3093 Asm->OutStreamer->switchSection(
3094 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3095 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3096 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3098 Asm->OutStreamer->switchSection(
3099 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3100 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3101 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3107 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3108 CU.getDebugSectionOffset());
3110 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3113void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3121 "pub" + Name,
"Length of Public " + Name +
" Info");
3123 Asm->OutStreamer->AddComment(
"DWARF Version");
3126 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3127 emitSectionReference(*TheU);
3129 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3134 for (
const auto &GI : Globals)
3137 return A.second->getOffset() <
B.second->getOffset();
3139 for (
const auto &[Name, Entity] : Vec) {
3140 Asm->OutStreamer->AddComment(
"DIE offset");
3141 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3145 Asm->OutStreamer->AddComment(
3151 Asm->OutStreamer->AddComment(
"External Name");
3152 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3155 Asm->OutStreamer->AddComment(
"End Mark");
3156 Asm->emitDwarfLengthOrOffset(0);
3157 Asm->OutStreamer->emitLabel(EndLabel);
3161void DwarfDebug::emitDebugStr() {
3162 MCSection *StringOffsetsSection =
nullptr;
3164 emitStringOffsetsTableHeader();
3165 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3168 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3169 StringOffsetsSection,
true);
3175 auto &&Comments = DebugLocs.getComments(Entry);
3176 auto Comment = Comments.begin();
3177 auto End = Comments.end();
3184 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3186 DebugLocs.getBytes(Entry).size()),
3187 Asm->getDataLayout().isLittleEndian(), PtrSize);
3192 for (
const auto &
Op : Expr) {
3193 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3194 "3 operand ops not yet supported");
3195 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3196 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3198 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3199 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3201 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3203 for (
unsigned J = 0; J <
Length; ++J)
3208 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3219 auto *DIExpr =
Value.getExpression();
3225 if (DIExpr && DIExpr->isEntryValue()) {
3242 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3245 if (Entry.isInt()) {
3246 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3248 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3249 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3253 }
else if (Entry.isLocation()) {
3255 if (Location.isIndirect())
3261 }
else if (Entry.isTargetIndexLocation()) {
3267 }
else if (Entry.isConstantFP()) {
3270 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3271 }
else if (Entry.getConstantFP()
3274 .getBitWidth() <= 64 ) {
3276 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3279 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3280 << Entry.getConstantFP()
3291 if (!
Value.isVariadic()) {
3292 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3301 return Entry.isLocation() && !Entry.getLoc().getReg();
3306 std::move(ExprCursor),
3307 [EmitValueLocEntry, &
Value](
unsigned Idx,
3309 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3317 assert(!Values.empty() &&
3318 "location list entries without values are redundant");
3319 assert(Begin != End &&
"unexpected location list entry with empty range");
3324 if (
Value.isFragment()) {
3327 return P.isFragment();
3328 }) &&
"all values are expected to be fragments");
3331 for (
const auto &Fragment : Values)
3335 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3346 Asm->OutStreamer->AddComment(
"Loc expr size");
3348 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3349 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3350 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3369 Asm->OutStreamer->AddComment(
"Offset entry count");
3375 Asm->getDwarfOffsetByteSize());
3389 Asm->OutStreamer->AddComment(
"Offset entry count");
3390 Asm->emitInt32(DebugLocs.getLists().size());
3391 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3393 for (
const auto &List : DebugLocs.getLists())
3394 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3395 Asm->getDwarfOffsetByteSize());
3400template <
typename Ranges,
typename PayloadEmitter>
3404 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3406 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3407 auto Size = Asm->MAI->getCodePointerSize();
3411 Asm->OutStreamer->emitLabel(Sym);
3418 for (
const auto &
Range : R)
3419 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3421 const MCSymbol *CUBase =
CU.getBaseAddress();
3422 bool BaseIsSet =
false;
3423 for (
const auto &
P : SectionRanges) {
3424 auto *
Base = CUBase;
3425 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB()) ||
3426 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3436 }
else if (!
Base && ShouldUseBaseAddress) {
3437 const MCSymbol *Begin =
P.second.front()->Begin;
3442 Asm->OutStreamer->emitIntValue(-1,
Size);
3443 Asm->OutStreamer->AddComment(
" base address");
3444 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3445 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3451 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3452 Asm->emitInt8(BaseAddressx);
3453 Asm->OutStreamer->AddComment(
" base address index");
3456 }
else if (BaseIsSet && !UseDwarf5) {
3459 Asm->OutStreamer->emitIntValue(-1,
Size);
3460 Asm->OutStreamer->emitIntValue(0,
Size);
3463 for (
const auto *RS :
P.second) {
3466 assert(Begin &&
"Range without a begin symbol?");
3467 assert(End &&
"Range without an end symbol?");
3471 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3472 Asm->emitInt8(OffsetPair);
3473 Asm->OutStreamer->AddComment(
" starting offset");
3474 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3475 Asm->OutStreamer->AddComment(
" ending offset");
3476 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3478 Asm->emitLabelDifference(Begin,
Base,
Size);
3479 Asm->emitLabelDifference(End,
Base,
Size);
3481 }
else if (UseDwarf5) {
3489 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3490 Asm->emitInt8(StartxEndx);
3491 Asm->OutStreamer->AddComment(
" start index");
3493 Asm->OutStreamer->AddComment(
" end index");
3496 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3497 Asm->emitInt8(StartxLength);
3498 Asm->OutStreamer->AddComment(
" start index");
3500 Asm->OutStreamer->AddComment(
" length");
3501 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3504 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3505 Asm->OutStreamer->emitSymbolValue(End,
Size);
3512 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3516 Asm->OutStreamer->emitIntValue(0,
Size);
3517 Asm->OutStreamer->emitIntValue(0,
Size);
3525 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3526 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3529 DD.emitDebugLocEntryLocation(E, List.CU);
3533void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3534 if (DebugLocs.getLists().empty())
3537 Asm->OutStreamer->switchSection(Sec);
3543 for (
const auto &
List : DebugLocs.getLists())
3547 Asm->OutStreamer->emitLabel(TableEnd);
3551void DwarfDebug::emitDebugLoc() {
3554 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3555 :
Asm->getObjFileLowering().getDwarfLocSection());
3559void DwarfDebug::emitDebugLocDWO() {
3562 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3567 for (
const auto &
List : DebugLocs.getLists()) {
3568 Asm->OutStreamer->switchSection(
3569 Asm->getObjFileLowering().getDwarfLocDWOSection());
3570 Asm->OutStreamer->emitLabel(
List.Label);
3572 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3581 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3582 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3583 Asm->emitULEB128(idx);
3589 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3599void DwarfDebug::emitDebugARanges() {
3600 if (ArangeLabels.empty())
3607 for (
const SymbolCU &SCU : ArangeLabels) {
3608 if (SCU.Sym->isInSection()) {
3610 MCSection *Section = &SCU.Sym->getSection();
3611 SectionMap[Section].push_back(SCU);
3616 SectionMap[
nullptr].push_back(SCU);
3620 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3622 for (
auto &
I : SectionMap) {
3630 for (
const SymbolCU &Cur :
List) {
3632 Span.
Start = Cur.Sym;
3635 Spans[Cur.CU].push_back(Span);
3641 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3645 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3646 const SymbolCU &Prev =
List[n - 1];
3647 const SymbolCU &Cur =
List[n];
3650 if (Cur.
CU != Prev.
CU) {
3652 Span.
Start = StartSym;
3655 Spans[Prev.
CU].push_back(Span);
3662 Asm->OutStreamer->switchSection(
3663 Asm->getObjFileLowering().getDwarfARangesSection());
3665 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3668 std::vector<DwarfCompileUnit *> CUs;
3669 for (
const auto &it : Spans) {
3670 DwarfCompileUnit *
CU = it.first;
3675 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3676 return A->getUniqueID() <
B->getUniqueID();
3680 for (DwarfCompileUnit *
CU : CUs) {
3681 std::vector<ArangeSpan> &
List = Spans[
CU];
3684 if (
auto *Skel =
CU->getSkeleton())
3688 unsigned ContentSize =
3690 Asm->getDwarfOffsetByteSize() +
3695 unsigned TupleSize = PtrSize * 2;
3699 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3702 ContentSize += (
List.size() + 1) * TupleSize;
3705 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3706 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3708 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3709 emitSectionReference(*
CU);
3710 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3711 Asm->emitInt8(PtrSize);
3712 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3715 Asm->OutStreamer->emitFill(Padding, 0xff);
3717 for (
const ArangeSpan &Span :
List) {
3718 Asm->emitLabelReference(Span.Start, PtrSize);
3725 auto SizeRef = SymSize.find(Span.Start);
3726 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3727 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3732 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3735 Size = SizeRef->second;
3737 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3741 Asm->OutStreamer->AddComment(
"ARange terminator");
3742 Asm->OutStreamer->emitIntValue(0, PtrSize);
3743 Asm->OutStreamer->emitIntValue(0, PtrSize);
3751 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3752 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3754 List.CU->getCUNode()->getRangesBaseAddress() ||
3766 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3769 Asm->OutStreamer->switchSection(Section);
3779 Asm->OutStreamer->emitLabel(TableEnd);
3784void DwarfDebug::emitDebugRanges() {
3787 emitDebugRangesImpl(Holder,
3789 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3790 :
Asm->getObjFileLowering().getDwarfRangesSection());
3793void DwarfDebug::emitDebugRangesDWO() {
3795 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3802 enum HeaderFlagMask {
3803#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3804#include "llvm/BinaryFormat/Dwarf.def"
3806 Asm->OutStreamer->AddComment(
"Macro information version");
3807 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3810 if (Asm->isDwarf64()) {
3811 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3812 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3814 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3815 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3817 Asm->OutStreamer->AddComment(
"debug_line_offset");
3819 Asm->emitDwarfLengthOrOffset(0);
3821 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3824void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3825 for (
auto *MN : Nodes) {
3829 emitMacroFile(*
F, U);
3835void DwarfDebug::emitMacro(
DIMacro &M) {
3836 StringRef
Name =
M.getName();
3837 StringRef
Value =
M.getValue();
3843 if (UseDebugMacroSection) {
3846 ? dwarf::DW_MACRO_define_strx
3847 : dwarf::DW_MACRO_undef_strx;
3850 Asm->OutStreamer->AddComment(
"Line Number");
3851 Asm->emitULEB128(
M.getLine());
3852 Asm->OutStreamer->AddComment(
"Macro String");
3854 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3857 ? dwarf::DW_MACRO_GNU_define_indirect
3858 : dwarf::DW_MACRO_GNU_undef_indirect;
3861 Asm->OutStreamer->AddComment(
"Line Number");
3862 Asm->emitULEB128(
M.getLine());
3863 Asm->OutStreamer->AddComment(
"Macro String");
3864 Asm->emitDwarfSymbolReference(
3865 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3869 Asm->emitULEB128(
M.getMacinfoType());
3870 Asm->OutStreamer->AddComment(
"Line Number");
3871 Asm->emitULEB128(
M.getLine());
3872 Asm->OutStreamer->AddComment(
"Macro String");
3873 Asm->OutStreamer->emitBytes(Str);
3874 Asm->emitInt8(
'\0');
3878void DwarfDebug::emitMacroFileImpl(
3880 StringRef (*MacroFormToString)(
unsigned Form)) {
3882 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3883 Asm->emitULEB128(StartFile);
3884 Asm->OutStreamer->AddComment(
"Line Number");
3886 Asm->OutStreamer->AddComment(
"File Number");
3889 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3891 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3893 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3895 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3896 Asm->emitULEB128(EndFile);
3903 if (UseDebugMacroSection)
3905 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3912void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3913 for (
const auto &
P : CUMap) {
3914 auto &TheCU = *
P.second;
3916 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3918 DIMacroNodeArray Macros = CUNode->getMacros();
3921 Asm->OutStreamer->switchSection(Section);
3922 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3923 if (UseDebugMacroSection)
3925 handleMacroNodes(Macros, U);
3926 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3932void DwarfDebug::emitDebugMacinfo() {
3933 auto &ObjLower =
Asm->getObjFileLowering();
3934 emitDebugMacinfoImpl(UseDebugMacroSection
3935 ? ObjLower.getDwarfMacroSection()
3936 : ObjLower.getDwarfMacinfoSection());
3939void DwarfDebug::emitDebugMacinfoDWO() {
3940 auto &ObjLower =
Asm->getObjFileLowering();
3941 emitDebugMacinfoImpl(UseDebugMacroSection
3942 ? ObjLower.getDwarfMacroDWOSection()
3943 : ObjLower.getDwarfMacinfoDWOSection());
3948void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3949 std::unique_ptr<DwarfCompileUnit> NewU) {
3951 if (!CompilationDir.empty())
3952 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3953 addGnuPubAttributes(*NewU, Die);
3955 SkeletonHolder.addUnit(std::move(NewU));
3960 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3961 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3963 DwarfCompileUnit &NewCU = *OwnedUnit;
3964 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3971 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3978void DwarfDebug::emitDebugInfoDWO() {
3986void DwarfDebug::emitDebugAbbrevDWO() {
3988 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3991void DwarfDebug::emitDebugLineDWO() {
3993 SplitTypeUnitFileTable.Emit(
3994 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3995 Asm->getObjFileLowering().getDwarfLineDWOSection());
3998void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
4000 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
4001 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
4008void DwarfDebug::emitDebugStrDWO() {
4010 emitStringOffsetsTableHeaderDWO();
4012 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
4013 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
4018void DwarfDebug::emitDebugAddr() {
4019 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
4025 const DICompileUnit *DIUnit =
CU.getCUNode();
4026 SplitTypeUnitFileTable.maybeSetRootFile(
4029 return &SplitTypeUnitFileTable;
4040 return Result.high();
4049 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4052 auto Ins = TypeSignatures.try_emplace(CTy);
4054 CU.addDIETypeSignature(RefDie, Ins.first->second);
4059 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4060 AddrPool.resetUsedFlag();
4062 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4066 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4068 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4069 CU.getSourceLanguage());
4073 Ins.first->second = Signature;
4081 if (!CompilationDir.empty())
4082 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4083 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4084 Asm->TM.Options.MCOptions.SplitDwarfFile);
4088 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4089 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4094 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4095 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4098 CU.applyStmtList(UnitDie);
4109 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4110 TypeUnitsUnderConstruction.clear();
4114 if (AddrPool.hasBeenUsed()) {
4115 AccelTypeUnitsDebugNames.clear();
4119 for (
const auto &
TU : TypeUnitsToAdd)
4120 TypeSignatures.erase(
TU.second);
4128 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4134 for (
auto &
TU : TypeUnitsToAdd) {
4135 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4140 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4142 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4145 AccelTypeUnitsDebugNames.convertDieToOffset();
4146 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4147 AccelTypeUnitsDebugNames.clear();
4150 CU.addDIETypeSignature(RefDie, Signature);
4157template <
typename DataT>
4158void DwarfDebug::addAccelNameImpl(
4163 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4180 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4181 ((&Current == &AccelDebugNames) &&
4182 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4183 "Kind is CU but TU is being processed.");
4184 assert(((&Current == &AccelDebugNames) ||
4185 ((&Current == &AccelTypeUnitsDebugNames) &&
4186 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4187 "Kind is TU but CU is being processed.");
4190 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4191 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4205 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4214 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4221 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4227 const DIE &Die,
char Flags) {
4228 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4232 return Asm->OutStreamer->getContext().getDwarfVersion();
4236 if (
Asm->getDwarfVersion() >= 4)
4237 return dwarf::Form::DW_FORM_sec_offset;
4238 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4239 "DWARF64 is not defined prior DWARFv3");
4240 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4241 : dwarf::Form::DW_FORM_data4;
4245 return SectionLabels.lookup(S);
4249 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4254std::optional<MD5::MD5Result>
4258 return std::nullopt;
4259 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4261 return std::nullopt;
4266 std::string ChecksumString =
fromHex(Checksum->Value);
4283 if (
MBB.getAlignment() ==
Align(1))
4286 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4293 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4294 if (PrevLoc.getLine()) {
4295 Asm->OutStreamer->emitDwarfLocDirective(
4296 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4298 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 ...
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.
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...
@ Global
Append to llvm.global_dtors.
@ 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.