65#define DEBUG_TYPE "dwarfdebug"
67STATISTIC(NumCSParams,
"Number of dbg call site params created");
70 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
80 cl::desc(
"Generate DWARF4 type units."),
91 cl::desc(
"Make an absence of debug location information explicit."),
99 "Default for platform"),
107 cl::desc(
"Use inlined strings rather than string section."),
115 cl::desc(
"Disable emission .debug_ranges section."),
120 cl::desc(
"Use sections+offset as references rather than labels."),
127 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
132 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
145 cl::desc(
"Which DWARF linkage-name attributes to emit."),
147 "Default for platform"),
150 "Abstract subprograms")),
155 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
156 "address pool entry sharing to reduce relocations/object size"),
158 "Default address minimization strategy"),
160 "Use rnglists for contiguous ranges if that allows "
161 "using a pre-existing base address"),
164 "Use exprloc addrx+offset expressions for any "
165 "address with a prior base address"),
167 "Use addrx+offset extension form for any address "
168 "with a prior base address"),
176 cl::desc(
"Set to false to ignore Key Instructions metadata"));
180void DebugLocDwarfExpression::emitOp(
uint8_t Op,
const char *Comment) {
186void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
187 getActiveStreamer().emitSLEB128(
Value, Twine(
Value));
191 getActiveStreamer().emitULEB128(
Value, Twine(
Value));
194void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
195 getActiveStreamer().emitInt8(
Value, Twine(
Value));
198void DebugLocDwarfExpression::emitBaseTypeRef(
uint64_t Idx) {
210 assert(!IsBuffering &&
"Already buffering?");
212 TmpBuf = std::make_unique<TempBuffer>(OutBS.GenerateComments);
219 return TmpBuf ? TmpBuf->Bytes.size() : 0;
225 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
226 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
227 ? TmpBuf->Comments[
Byte.index()].c_str()
229 OutBS.emitInt8(
Byte.value(), Comment);
231 TmpBuf->Bytes.clear();
232 TmpBuf->Comments.clear();
243 const bool IsVariadic = !SingleLocExprOpt;
246 if (!IsVariadic && !
MI->isNonListDebugValue()) {
247 assert(
MI->getNumDebugOperands() == 1 &&
248 "Mismatched DIExpression and debug operands for debug instruction.");
249 Expr = *SingleLocExprOpt;
256 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
258 }
else if (
Op.isTargetIndex()) {
261 }
else if (
Op.isGlobal()) {
264 }
else if (
Op.isImm())
266 else if (
Op.isFPImm())
268 else if (
Op.isCImm())
273 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
292 Expr(ValueLoc.getExpression()) {
293 if (!Expr->getNumElements())
309 return FIE.Expr && FIE.Expr->isFragment();
311 "conflicting locations for variable");
315 bool GenerateTypeUnits,
324 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
330 if (DwarfVersion >= 5)
340 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
341 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()),
342 DebuggerTuning(
MMI->getModule()->getDebuggerTuning()),
344 const Triple &TT =
Asm->TM.getTargetTriple();
348 EmitDebugEntryValues =
Asm->TM.shouldEmitDebugEntryValues(DebuggerTuning);
361 HasSplitDwarf = !
Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
369 unsigned DwarfVersionNumber =
Asm->TM.Options.MCOptions.DwarfVersion;
370 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
371 :
MMI->getModule()->getDwarfVersion();
375 bool Dwarf64 = DwarfVersion >= 3 &&
384 ((
Asm->TM.Options.MCOptions.Dwarf64 ||
MMI->getModule()->isDwarf64()) &&
385 TT.isOSBinFormatELF()) ||
386 TT.isOSBinFormatXCOFF();
388 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
397 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
398 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
402 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
409 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
411 UseDWARF2Bitfields = DwarfVersion < 4;
417 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
421 UseDebugMacroSection =
430 if (DwarfVersion >= 5)
433 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
442 return Name.starts_with(
"+") || Name.starts_with(
"-");
449 return Name.contains(
") ");
455 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
460 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
461 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
465 return In.slice(In.find(
' ') + 1, In.find(
']'));
478 if (!SP->isDefinition())
481 if (SP->getName() !=
"")
512 if (Scope->isAbstractScope())
530 if (
auto *SkelCU =
CU.getSkeleton())
531 if (
CU.getCUNode()->getSplitDebugInlining())
542 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
543 if (
CU.getSkeleton())
549void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
551 assert(Scope && Scope->getScopeNode());
552 assert(Scope->isAbstractScope());
553 assert(!Scope->getInlinedAt());
559 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
561 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
562 if (
auto *SkelCU =
CU.getSkeleton())
563 if (
CU.getCUNode()->getSplitDebugInlining())
564 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
598template <
typename ValT>
602 for (
auto Param : DescribedParams) {
603 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
613 "Combined debug expression is invalid");
628 auto &ParamsForFwdReg = Worklist[
Reg];
629 for (
auto Param : ParamsToAdd) {
632 return D.ParamReg == Param.ParamReg;
634 "Same parameter described twice by forwarding reg");
641 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
661 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
662 for (
auto &RegUnit : ClobberedRegUnits)
663 if (
TRI.hasRegUnit(
Reg, RegUnit))
668 auto DescribeFwdRegsByCalleeSavedCopy = [&](
const DestSourcePair &CopyInst) {
669 Register CopyDestReg = CopyInst.Destination->getReg();
670 Register CopySrcReg = CopyInst.Source->getReg();
671 if (IsRegClobberedInMeantime(CopyDestReg))
675 if (!
TRI.isCalleeSavedPhysReg(CopyDestReg, *MF))
682 for (
auto FwdRegIt = ForwardedRegWorklist.
begin();
683 FwdRegIt != ForwardedRegWorklist.
end();) {
685 if (FwdRegIt->first == CopySrcReg)
687 else if (
unsigned SubRegIdx =
688 TRI.getSubRegIndex(CopySrcReg, FwdRegIt->first))
689 if (
Register CopyDestSubReg =
TRI.getSubReg(CopyDestReg, SubRegIdx))
699 FwdRegIt = ForwardedRegWorklist.
erase(FwdRegIt);
707 if (
auto CopyInst =
TII.isCopyInstr(*CurMI))
708 DescribeFwdRegsByCalleeSavedCopy(*CopyInst);
736 if (
MI.isDebugInstr())
740 if (MO.getReg().isPhysical()) {
741 for (
auto &FwdReg : ForwardedRegWorklist)
742 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
743 Defs.insert(FwdReg.first);
752 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
753 if (FwdRegDefs.
empty()) {
759 for (
auto ParamFwdReg : FwdRegDefs) {
760 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
761 if (ParamValue->first.isImm()) {
762 int64_t Val = ParamValue->first.getImm();
764 ForwardedRegWorklist[ParamFwdReg], Params);
765 }
else if (ParamValue->first.isReg()) {
766 Register RegLoc = ParamValue->first.getReg();
767 Register SP =
TLI.getStackPointerRegisterToSaveRestore();
769 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
772 if (!IsRegClobberedInMeantime(RegLoc) &&
773 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
776 ForwardedRegWorklist[ParamFwdReg], Params);
785 ForwardedRegWorklist[ParamFwdReg]);
792 for (
auto ParamFwdReg : FwdRegDefs)
793 ForwardedRegWorklist.
erase(ParamFwdReg);
800 for (
auto &New : TmpWorklistItems)
802 TmpWorklistItems.
clear();
819 if (ForwardedRegWorklist.
empty())
826 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
837 auto CSInfo = CalleesMap.
find(CallMI);
840 if (CSInfo == CalleesMap.end())
854 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
856 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
858 assert(InsertedReg &&
"Single register used to forward two arguments?");
863 for (
const auto &MO : CallMI->
uses())
864 if (MO.isReg() && MO.isUndef())
865 ForwardedRegWorklist.
erase(MO.getReg());
875 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
884 assert(std::next(Suc) == BundleEnd &&
885 "More than one instruction in call delay slot");
892 for (;
I !=
MBB->rend(); ++
I) {
899 if (ShouldTryEmitEntryVals) {
903 for (
auto &RegEntry : ForwardedRegWorklist) {
910void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
915 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
922 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
925 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
928 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
929 if (!
MI.isBundledWithSucc())
931 auto Suc = std::next(
MI.getIterator());
933 (void)CallInstrBundle;
935 (void)DelaySlotBundle;
942 "Call and its successor instruction don't have same label after.");
947 auto addCallSiteTargetForIndirectCalls = [&](
const MachineInstr *
MI,
951 auto CSInfo = CalleesMap.
find(
MI);
953 if (CSInfo == CalleesMap.end() || !CSInfo->second.CallTarget)
956 MDNode *CallTarget = CSInfo->second.CallTarget;
958 assert(!CallSiteDIE.findAttribute(dwarf::DW_AT_LLVM_virtual_call_origin) &&
959 "DW_AT_LLVM_virtual_call_origin already exists");
961 DIE *CalleeDIE =
CU.getOrCreateSubprogramDIE(CalleeSP,
nullptr);
962 assert(CalleeDIE &&
"Could not create DIE for call site entry origin");
963 CU.addDIEEntry(CallSiteDIE,
964 CU.getDwarf5OrGNUAttr(dwarf::DW_AT_LLVM_virtual_call_origin),
967 CU.addLinkageNamesToDeclarations(*
this, *CalleeSP, *CalleeDIE);
971 for (
const MachineBasicBlock &
MBB : MF) {
981 if (!
MI.isCandidateForAdditionalCallInfo())
990 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
998 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
999 bool PhysRegCalleeOperand =
1001 MachineLocation CallTarget{0};
1003 const DISubprogram *CalleeSP =
nullptr;
1004 const Function *CalleeDecl =
nullptr;
1005 if (PhysRegCalleeOperand) {
1006 bool Scalable =
false;
1007 const MachineOperand *BaseOp =
nullptr;
1008 if (
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, Scalable)) {
1009 if (BaseOp && BaseOp->
isReg() && !Scalable)
1010 CallTarget = MachineLocation(BaseOp->
getReg(),
true);
1014 CallTarget = MachineLocation(CalleeOp.
getReg());
1023 if (CalleeSP ==
nullptr && CallTarget.
getReg() == 0 &&
1024 AllocSiteTy ==
nullptr)
1034 const MachineInstr *TopLevelCallMI =
1041 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1050 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1053 dbgs() <<
"CallSiteEntry: " << MF.getName() <<
" -> "
1057 MF.getSubtarget().getRegisterInfo()->getName(
1059 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1061 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1062 ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
1066 addCallSiteTargetForIndirectCalls(TopLevelCallMI, CallSiteDIE);
1073 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1080 if (!
U.hasDwarfPubSections())
1083 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1089 case dwarf::DW_LNAME_Fortran:
1090 case dwarf::DW_LNAME_Cobol:
1091 case dwarf::DW_LNAME_Pascal:
1098 case dwarf::DW_LANG_Cobol74:
1099 case dwarf::DW_LANG_Cobol85:
1100 case dwarf::DW_LANG_Fortran77:
1101 case dwarf::DW_LANG_Fortran90:
1102 case dwarf::DW_LANG_Fortran95:
1103 case dwarf::DW_LANG_Fortran03:
1104 case dwarf::DW_LANG_Fortran08:
1105 case dwarf::DW_LANG_Fortran18:
1106 case dwarf::DW_LANG_Fortran23:
1107 case dwarf::DW_LANG_Pascal83:
1114void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1122 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1123 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1125 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1128 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1131 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1132 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1135 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1140 NewCU.
addUInt(Die, dwarf::DW_AT_identifier_case, dwarf::DW_FORM_data1,
1142 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1147 if (!SysRoot.
empty())
1148 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1149 StringRef SDK = DIUnit->
getSDK();
1151 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1162 if (!CompilationDir.empty())
1163 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1164 addGnuPubAttributes(NewCU, Die);
1168 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1173 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1176 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1177 dwarf::DW_FORM_data1, RVer);
1182 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1187 ? dwarf::DW_AT_dwo_name
1188 : dwarf::DW_AT_GNU_dwo_name;
1195 if (
auto *
CU = CUMap.lookup(DIUnit))
1202 return CUMap.begin()->second;
1210DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1211 if (
auto *
CU = getDwarfCompileUnit(DIUnit))
1216 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1218 DwarfCompileUnit &NewCU = *OwnedUnit;
1225 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1226 Asm->OutStreamer->emitDwarfFile0Directive(
1232 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1234 finishUnitAttributes(DIUnit, NewCU);
1235 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1238 CUMap.insert({DIUnit, &NewCU});
1239 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1253 if (!
A.Expr || !
B.Expr)
1255 auto FragmentA =
A.Expr->getFragmentInfo();
1256 auto FragmentB =
B.Expr->getFragmentInfo();
1257 if (!FragmentA || !FragmentB)
1259 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1264 return A.Expr ==
B.Expr;
1279 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1280 M->debug_compile_units_end());
1281 if (NumDebugCUs == 0)
1284 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1285 SingleCU = NumDebugCUs == 1;
1292 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1300 Asm->createTempSymbol(
"rnglists_table_base"));
1304 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1309 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1310 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1313 if (CUNode->getImportedEntities().empty() &&
1314 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1315 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1318 getOrCreateDwarfCompileUnit(CUNode);
1322void DwarfDebug::finishEntityDefinitions() {
1323 for (
const auto &Entity : ConcreteEntities) {
1324 DIE *Die = Entity->getDIE();
1331 Unit->finishEntityDefinition(Entity.get());
1335void DwarfDebug::finishSubprogramDefinitions() {
1336 for (
const DISubprogram *SP : ProcessedSPNodes) {
1339 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1340 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1344void DwarfDebug::finalizeModuleInfo() {
1345 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1347 finishSubprogramDefinitions();
1349 finishEntityDefinitions();
1351 bool HasEmittedSplitCU =
false;
1355 for (
const auto &
P : CUMap) {
1356 auto &TheCU = *
P.second;
1357 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1359 TheCU.attachLexicalScopesAbstractOrigins();
1362 TheCU.constructContainingTypeDIEs();
1363 TheCU.constructPropertyForwardDIEs();
1368 auto *SkCU = TheCU.getSkeleton();
1370 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1373 (void)HasEmittedSplitCU;
1375 "Multiple CUs emitted into a single dwo file");
1376 HasEmittedSplitCU =
true;
1378 ? dwarf::DW_AT_dwo_name
1379 : dwarf::DW_AT_GNU_dwo_name;
1380 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1381 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1382 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1383 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1389 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1394 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1395 dwarf::DW_FORM_data8, ID);
1396 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1397 dwarf::DW_FORM_data8, ID);
1400 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1402 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1406 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1415 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1417 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1424 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1427 U.setBaseAddress(TheCU.getRanges().front().Begin);
1428 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1435 U.addAddrTableBase();
1438 if (
U.hasRangeLists())
1439 U.addRnglistsBase();
1442 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1451 if (CUNode->getMacros()) {
1453 if (UseDebugMacroSection) {
1458 ? dwarf::DW_AT_macros
1459 : dwarf::DW_AT_GNU_macros;
1461 U.getMacroLabelBegin(), Section);
1467 dwarf::DW_AT_macro_info,
1468 U.getMacroLabelBegin(), Section);
1474 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1475 if (CUNode->getDWOId())
1476 getOrCreateDwarfCompileUnit(CUNode);
1481 SkeletonHolder.computeSizeAndOffsets();
1485 AccelDebugNames.convertDieToOffset();
1494 assert(CurFn ==
nullptr);
1500 AllFunctionsProcessed =
true;
1502 for (
const auto &
CU : Holder->getUnits())
1503 CU->resolvePendingLocalScopeDIEs();
1512 Global.getDebugInfo(GVs);
1513 for (
auto *GVE : GVs)
1514 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1525 for (
auto *GVE : CUNode->getGlobalVariables()) {
1529 auto &GVMapEntry = GVMap[GVE->getVariable()];
1530 auto *Expr = GVE->getExpression();
1531 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1532 GVMapEntry.push_back({
nullptr, Expr});
1535 for (
auto *GVE : CUNode->getGlobalVariables()) {
1538 "Unexpected function-local entity in 'globals' CU field.");
1539 if (Processed.
insert(GV).second)
1544 for (
auto *Ty : CUNode->getEnumTypes()) {
1546 "Unexpected function-local entity in 'enums' CU field.");
1550 for (
auto *Ty : CUNode->getRetainedTypes()) {
1553 CU->getOrCreateTypeDIE(RT);
1558 for (
auto *IE : CUNode->getImportedEntities()) {
1560 "Unexpected function-local entity in 'imports' CU field.");
1561 CU->getOrCreateImportedEntityDIE(IE);
1565 const auto Unexpected = [](
const Metadata *
N) {
1568 for (
const auto *
D :
CU->getDeferredLocalDecls())
1569 DISubprogram::visitRetainedNode<void>(
1570 D, Unexpected, Unexpected,
1571 [
CU](
const auto *IE) {
CU->getOrCreateImportedEntityDIE(IE); },
1572 [
CU](
const auto *Ty) {
CU->getOrCreateTypeDIE(Ty); },
1573 [&](
const auto *GVE) {
1575 if (Processed.
insert(GV).second)
1581 CU->createBaseTypeDIEs();
1586 if (!
Asm || !
Asm->hasDebugInfo())
1590 finalizeModuleInfo();
1600 emitAbbreviations();
1606 if (UseARangesSection)
1614 emitDebugMacinfoDWO();
1624 emitDebugAbbrevDWO();
1626 emitDebugRangesDWO();
1636 emitAccelNamespaces();
1640 emitAccelDebugNames();
1649 emitDebugPubSections();
1657 if (
CU.getExistingAbstractEntity(
Node))
1662 CU.createAbstractEntity(
Node, Scope);
1671void DwarfDebug::collectVariableInfoFromMFTable(
1673 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1674 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1675 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1678 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1679 "Expected inlined-at fields to agree");
1681 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1688 <<
", no variable scope found\n");
1692 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1696 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1697 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1698 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1700 if (PreviousMMI &&
VI.inStackSlot())
1701 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1703 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1704 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1709 if (PreviousLoc->holds<Loc::MMI>())
1710 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1713 <<
", conflicting fragment location types\n");
1718 auto RegVar = std::make_unique<DbgVariable>(
1720 if (
VI.inStackSlot())
1721 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1723 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1726 InfoHolder.addScopeVariable(Scope, RegVar.get());
1727 MFVars.
insert({Var, RegVar.get()});
1728 ConcreteEntities.push_back(std::move(RegVar));
1740 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1748 if (LSRange.size() == 0)
1751 const MachineInstr *LScopeBegin = LSRange.front().first;
1755 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1764 auto PredDL =
Pred->getDebugLoc();
1765 if (!PredDL ||
Pred->isMetaInstruction())
1769 if (
DL->getScope() == PredDL->getScope())
1772 if (!PredScope || LScope->dominates(PredScope))
1787 if (
MBB->pred_empty() &&
1789 return Op.isImm() || Op.isGlobal();
1795 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1839 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1841 bool isSafeForSingleLocation =
true;
1842 const MachineInstr *StartDebugMI =
nullptr;
1843 const MachineInstr *EndMI =
nullptr;
1845 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1846 const MachineInstr *
Instr = EI->getInstr();
1849 size_t Index = std::distance(EB, EI);
1850 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1857 "Forgot label before/after instruction starting a range!");
1860 if (std::next(EI) == Entries.
end()) {
1861 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1863 if (EI->isClobber())
1864 EndMI = EI->getInstr();
1866 else if (std::next(EI)->isClobber())
1870 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1872 if (EI->isDbgValue())
1878 if (EI->isDbgValue()) {
1885 if (!
Instr->isUndefDebugValue()) {
1890 if (
Instr->getDebugExpression()->isFragment())
1891 isSafeForSingleLocation =
false;
1894 StartDebugMI =
Instr;
1896 isSafeForSingleLocation =
false;
1902 if (OpenRanges.
empty())
1906 if (StartLabel == EndLabel) {
1907 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1912 for (
auto &R : OpenRanges)
1920 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1921 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1922 for (
const auto &[MBBSectionId, MBBSectionRange] :
1923 Asm->MBBSectionRanges) {
1924 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1925 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel,
Values);
1928 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1929 MBBSectionRange.EndLabel,
Values);
1939 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1940 for (
auto &
Value : CurEntry->getValues())
1942 dbgs() <<
"-----\n";
1945 auto PrevEntry = std::next(CurEntry);
1946 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1950 if (!isSafeForSingleLocation ||
1957 if (!
Asm->MF->hasBBSections())
1965 const MachineBasicBlock *RangeMBB =
nullptr;
1966 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1967 RangeMBB = &
Asm->MF->front();
1969 RangeMBB = Entries.
begin()->getInstr()->getParent();
1971 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1972 "Range MBB not found in MBBSectionRanges!");
1974 auto *NextEntry = std::next(CurEntry);
1975 auto NextRangeIt = std::next(RangeIt);
1976 while (NextEntry !=
DebugLoc.end()) {
1977 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1984 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1985 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1986 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1987 CurEntry->getValues() != NextEntry->getValues())
1989 RangeIt = NextRangeIt;
1990 NextRangeIt = std::next(RangeIt);
1991 CurEntry = NextEntry;
1992 NextEntry = std::next(CurEntry);
2002 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
2004 ConcreteEntities.push_back(
2010 ConcreteEntities.push_back(
2016 return ConcreteEntities.back().get();
2024 collectVariableInfoFromMFTable(TheCU, Processed);
2027 InlinedEntity
IV =
I.first;
2032 const auto &HistoryMapEntries =
I.second;
2036 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
2039 LexicalScope *
Scope =
nullptr;
2041 if (
const DILocation *IA =
IV.second)
2051 *Scope, LocalVar,
IV.second));
2053 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
2059 size_t HistSize = HistoryMapEntries.size();
2060 bool SingleValueWithClobber =
2061 HistSize == 2 && HistoryMapEntries[1].isClobber();
2062 if (HistSize == 1 || SingleValueWithClobber) {
2064 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
2066 RegVar->emplace<Loc::Single>(MInsn);
2072 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
2076 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
2081 if (isValidSingleLocation) {
2082 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
2093 for (
auto &Entry : Entries)
2100 InlinedEntity IL =
I.first;
2101 const MachineInstr *
MI =
I.second;
2105 LexicalScope *
Scope =
nullptr;
2108 const DILocalScope *LocalScope =
2109 Label->getScope()->getNonLexicalBlockFileScope();
2111 if (
const DILocation *IA = IL.second)
2124 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2128 for (
const MDNode *
N :
SP->getRetainedNodes()) {
2132 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2134 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2136 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2138 LocalDeclsPerLS[
LS].insert(
N);
2152 if (!
MI.isBundledWithSucc())
2154 auto Suc = std::next(
MI.getIterator());
2159 assert(Suc->isBundledWithPred() &&
2160 "Call bundle instructions are out of order");
2165 if (!NoDebug && SP->areAllCallsDescribed() &&
2167 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2169 bool IsTail =
TII->isTailCall(*
MI);
2187 auto RecordLineZero = [&]() {
2191 const MDNode *Scope =
nullptr;
2192 unsigned Column = 0;
2197 recordSourceLine(0, Column, Scope, 0);
2202 unsigned LastAsmLine =
2203 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2208 if (
MI->isMetaInstruction())
2229 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2231 if (
Asm->OutStreamer->isVerboseAsm()) {
2235 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2244 bool ScopeUsesKeyInstructions =
2246 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2249 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2250 IsKey = KeyInstructions.contains(
MI);
2256 assert(
MI->getParent() == &*
MI->getMF()->begin());
2257 recordSourceLine(SP->getScopeLine(), 0, SP,
2262 bool PrevInstInSameSection =
2264 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2265 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2266 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2276 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2278 RecordSourceLine(
DL, Flags);
2291 if (LastAsmLine == 0)
2312 if (
DL.getLine() == 0 && LastAsmLine == 0)
2319 if (ScopeUsesKeyInstructions) {
2326 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2341 if (
Asm->OutStreamer->isVerboseAsm()) {
2345 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2354static std::pair<const MachineInstr *, bool>
2365 bool IsEmptyPrologue =
2366 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2371 -> std::optional<std::pair<const MachineInstr *, bool>> {
2373 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2374 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2377 if (!isFrameSetup &&
MI.getDebugLoc()) {
2383 if (
MI.getDebugLoc().getLine())
2384 return std::make_pair(&
MI, IsEmptyPrologue);
2389 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2390 NonTrivialInst = &
MI;
2392 IsEmptyPrologue =
false;
2393 return std::nullopt;
2401 auto CurBlock = MF->
begin();
2402 auto CurInst = CurBlock->begin();
2406 while (CurBlock->empty())
2407 CurInst = (++CurBlock)->begin();
2408 assert(CurInst != CurBlock->end());
2412 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2414 if (CurInst->isTerminator()) {
2423 if (CurBlock->pred_size() > 1)
2434 if (CurBlock == MF->
end())
2436 }
while (CurBlock->empty());
2437 CurInst = CurBlock->begin();
2443 if (!CurInst->isMetaInstruction()) {
2444 auto FoundInst = ExamineInst(*CurInst);
2455 if (CurInst->isCall()) {
2457 Loc &&
Loc->getLine() == 0) {
2459 unsigned ScopeLine = SP->getScopeLine();
2462 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2465 return std::make_pair(&*CurInst,
false);
2471 auto NextInst = std::next(CurInst);
2472 if (NextInst != CurInst->getParent()->end()) {
2489 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2490 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2491 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2495 return std::make_pair(
nullptr, IsEmptyPrologue);
2501 const MDNode *S,
unsigned Flags,
unsigned CUID,
2503 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2506 unsigned FileNo = 1;
2509 Fn =
Scope->getFilename();
2510 if (Line != 0 && DwarfVersion >= 4)
2515 .getOrCreateSourceID(
Scope->getFile());
2517 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2518 Discriminator, Fn, Comment);
2529 bool IsEmptyPrologue = PrologEnd.second;
2532 if (IsEmptyPrologue) {
2540 if (!
DL ||
DL->getLine() != 0)
2551 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2561 KeyInstructions.clear();
2568 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2585 for (
auto &
MBB : *MF) {
2595 uint64_t BuoyAtom = 0;
2597 for (
auto &
MI :
MBB) {
2598 if (
MI.isMetaInstruction())
2602 if (!
Loc || !
Loc->getLine())
2613 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2618 KeyInstructions.insert(Buoy);
2624 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2628 auto *InlinedAt = Loc->getInlinedAt();
2631 if (!Group || !Rank)
2635 if (BuoyAtom && BuoyAtom != Group) {
2640 auto &[CandidateRank, CandidateInsts] =
2641 GroupCandidates[{InlinedAt, Group}];
2647 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2648 (CandidateRank != 0 && !CandidateInsts.empty()));
2650 assert(Rank &&
"expected nonzero rank");
2653 if (CandidateRank && CandidateRank < Rank)
2660 if (CandidateRank == Rank)
2664 else if (CandidateRank > Rank)
2665 CandidateInsts.clear();
2669 CandidateInsts.push_back(Buoy);
2670 CandidateRank = Rank;
2678 if (CandidateInsts.empty())
2684 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2685 for (
auto *
I : Insts)
2686 KeyInstructions.insert(
I);
2694 ForceIsStmtInstrs.clear();
2726 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2727 SmallDenseMap<const MachineBasicBlock *, const MachineInstr *>
2728 PotentialIsStmtMBBInstrs;
2729 for (
const auto &
MBB : *MF) {
2732 for (
auto &
MI :
MBB) {
2733 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2746 for (
auto *
MBB : PredMBBsToExamine) {
2747 auto CheckMBBEdge = [&](
const MachineBasicBlock *Succ,
2748 unsigned OutgoingLine) {
2749 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2750 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2752 const MachineInstr *
MI = MBBInstrIt->second;
2753 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2755 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2756 ForceIsStmtInstrs.insert(
MI);
2763 CheckMBBEdge(Succ, 0);
2769 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2777 const MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2778 SmallVector<MachineOperand, 4>
Cond;
2784 if (!AnalyzeFailed && !
Cond.
empty() && FBB !=
nullptr &&
2787 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2788 CheckMBBEdge(FBB, FBBLine);
2812 unsigned LastLine = 0;
2814 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2815 LastLine =
DL->getLine();
2820 for (
auto *Succ : SuccessorBBs)
2821 CheckMBBEdge(Succ, LastLine);
2836 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2837 ?
Asm->OutStreamer->emitLineTableLabel()
2840 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2848 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2854 computeKeyInstructions(MF);
2855 findForceIsStmtInstrs(MF);
2863 if (
Asm->OutStreamer->hasRawTextSupport())
2867 return CU.getUniqueID();
2871 const auto &CURanges =
CU->getRanges();
2872 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2875 LineTable.getMCLineSections().addEndEntry(
2876 const_cast<MCSymbol *
>(CURanges.back().End));
2896 "endFunction should be called with the same function as beginFunction");
2899 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2911 collectEntityInfo(TheCU, SP, Processed);
2915 for (
const auto &R :
Asm->MBBSectionRanges)
2916 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2923 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2924 for (
const auto &R :
Asm->MBBSectionRanges)
2934 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2938 for (
const MDNode *
N : SP->getRetainedNodes()) {
2941 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2942 assert(LexS &&
"Expected the LexicalScope to be created.");
2946 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2952 LocalDeclsPerLS[LS].insert(
N);
2955 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2956 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2958 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2961 ProcessedSPNodes.insert(SP);
2965 if (!
LScopes.getAbstractScopesList().empty() &&
2967 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2968 FunctionLineTableLabel);
2970 FunctionLineTableLabel =
nullptr;
2973 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2981 LocalDeclsPerLS.clear();
2988void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
3000void DwarfDebug::emitDebugInfo() {
3006void DwarfDebug::emitAbbreviations() {
3009 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
3012void DwarfDebug::emitStringOffsetsTableHeader() {
3015 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
3019template <
typename AccelTableT>
3020void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
3022 Asm->OutStreamer->switchSection(Section);
3028void DwarfDebug::emitAccelDebugNames() {
3037void DwarfDebug::emitAccelNames() {
3038 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
3044void DwarfDebug::emitAccelObjC() {
3045 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
3050void DwarfDebug::emitAccelNamespaces() {
3051 emitAccel(AccelNamespace,
3052 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
3057void DwarfDebug::emitAccelTypes() {
3058 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
3088 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
3096 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
3103 case dwarf::DW_TAG_class_type:
3104 case dwarf::DW_TAG_structure_type:
3105 case dwarf::DW_TAG_union_type:
3106 case dwarf::DW_TAG_enumeration_type:
3111 case dwarf::DW_TAG_typedef:
3112 case dwarf::DW_TAG_base_type:
3113 case dwarf::DW_TAG_subrange_type:
3114 case dwarf::DW_TAG_template_alias:
3116 case dwarf::DW_TAG_namespace:
3118 case dwarf::DW_TAG_subprogram:
3120 case dwarf::DW_TAG_variable:
3122 case dwarf::DW_TAG_enumerator:
3132void DwarfDebug::emitDebugPubSections() {
3133 for (
const auto &NU : CUMap) {
3134 DwarfCompileUnit *TheU = NU.second;
3141 Asm->OutStreamer->switchSection(
3142 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3143 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3144 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3146 Asm->OutStreamer->switchSection(
3147 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3148 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3149 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3155 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3156 CU.getDebugSectionOffset());
3158 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3161void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3169 "pub" + Name,
"Length of Public " + Name +
" Info");
3171 Asm->OutStreamer->AddComment(
"DWARF Version");
3174 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3175 emitSectionReference(*TheU);
3177 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3182 for (
const auto &GI : Globals)
3185 return A.second->getOffset() <
B.second->getOffset();
3187 for (
const auto &[Name, Entity] : Vec) {
3188 Asm->OutStreamer->AddComment(
"DIE offset");
3189 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3193 Asm->OutStreamer->AddComment(
3199 Asm->OutStreamer->AddComment(
"External Name");
3200 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3203 Asm->OutStreamer->AddComment(
"End Mark");
3204 Asm->emitDwarfLengthOrOffset(0);
3205 Asm->OutStreamer->emitLabel(EndLabel);
3209void DwarfDebug::emitDebugStr() {
3210 MCSection *StringOffsetsSection =
nullptr;
3212 emitStringOffsetsTableHeader();
3213 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3216 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3217 StringOffsetsSection,
true);
3223 auto &&Comments = DebugLocs.getComments(Entry);
3224 auto Comment = Comments.begin();
3225 auto End = Comments.end();
3232 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3234 DebugLocs.getBytes(Entry).size()),
3235 Asm->getDataLayout().isLittleEndian(), PtrSize);
3240 for (
const auto &
Op : Expr) {
3241 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3242 "3 operand ops not yet supported");
3243 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3244 Streamer.emitInt8(
Op.getCode(), Comment !=
End ? *(Comment++) :
"");
3246 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3247 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3249 Streamer.emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3251 for (
unsigned J = 0; J <
Length; ++J)
3255 for (uint64_t J =
Offset; J <
Op.getOperandEndOffset(
I); ++J)
3256 Streamer.emitInt8(
Data.getData()[J], Comment !=
End ? *(Comment++) :
"");
3267 auto *DIExpr =
Value.getExpression();
3274 return Entry.isGlobalAddress();
3285 return Op.getOp() == dwarf::DW_OP_LLVM_implicit_pointer;
3293 if (DIExpr && DIExpr->isEntryValue()) {
3311 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3314 if (Entry.isInt()) {
3315 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean)) {
3320 bool IsSigned =
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3321 BT->getEncoding() == dwarf::DW_ATE_signed_char);
3332 uint64_t TypeBitSize =
BT->getSizeInBits();
3333 bool IsByteSized = TypeBitSize % 8 == 0;
3335 IsSigned ? !
isIntN(GenericBitSize, Entry.getInt())
3337 static_cast<uint64_t
>(Entry.getInt()));
3338 if (TypeBitSize > GenericBitSize && IsByteSized && IsOutOfRange) {
3340 APInt(
static_cast<unsigned>(TypeBitSize),
3341 static_cast<uint64_t
>(Entry.getInt()), IsSigned,
3352 }
else if (Entry.isLocation()) {
3354 if (Location.isIndirect())
3360 }
else if (Entry.isTargetIndexLocation()) {
3366 }
else if (Entry.isGlobalAddress()) {
3368 Entry.getGlobalOffset()))
3370 }
else if (Entry.isConstantFP()) {
3373 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3374 }
else if (Entry.getConstantFP()
3377 .getBitWidth() <= 64 ) {
3379 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3382 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3383 << Entry.getConstantFP()
3394 if (!
Value.isVariadic()) {
3395 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3404 return Entry.isLocation() && !Entry.getLoc().getReg();
3409 std::move(ExprCursor),
3410 [EmitValueLocEntry, &
Value](
unsigned Idx,
3412 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3420 assert(!Values.empty() &&
3421 "location list entries without values are redundant");
3422 assert(Begin != End &&
"unexpected location list entry with empty range");
3427 if (
Value.isFragment()) {
3430 return P.isFragment();
3431 }) &&
"all values are expected to be fragments");
3434 for (
const auto &
Fragment : Values)
3438 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3449 Asm->OutStreamer->AddComment(
"Loc expr size");
3451 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3452 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3453 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3472 Asm->OutStreamer->AddComment(
"Offset entry count");
3478 Asm->getDwarfOffsetByteSize());
3492 Asm->OutStreamer->AddComment(
"Offset entry count");
3493 Asm->emitInt32(DebugLocs.getLists().size());
3494 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3496 for (
const auto &List : DebugLocs.getLists())
3497 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3498 Asm->getDwarfOffsetByteSize());
3503template <
typename Ranges,
typename PayloadEmitter>
3507 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3509 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3510 auto Size = Asm->MAI.getCodePointerSize();
3514 Asm->OutStreamer->emitLabel(Sym);
3521 for (
const auto &
Range : R)
3522 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3524 const MCSymbol *CUBase =
CU.getBaseAddress();
3525 bool BaseIsSet =
false;
3526 for (
const auto &
P : SectionRanges) {
3527 auto *
Base = CUBase;
3529 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3532 }
else if (!
Base && ShouldUseBaseAddress) {
3533 const MCSymbol *Begin =
P.second.front()->Begin;
3538 Asm->OutStreamer->emitIntValue(-1,
Size);
3539 Asm->OutStreamer->AddComment(
" base address");
3540 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3541 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3547 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3548 Asm->emitInt8(BaseAddressx);
3549 Asm->OutStreamer->AddComment(
" base address index");
3552 }
else if (BaseIsSet && !UseDwarf5) {
3555 Asm->OutStreamer->emitIntValue(-1,
Size);
3556 Asm->OutStreamer->emitIntValue(0,
Size);
3559 for (
const auto *RS :
P.second) {
3562 assert(Begin &&
"Range without a begin symbol?");
3563 assert(
End &&
"Range without an end symbol?");
3567 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3568 Asm->emitInt8(OffsetPair);
3569 Asm->OutStreamer->AddComment(
" starting offset");
3570 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3571 Asm->OutStreamer->AddComment(
" ending offset");
3572 Asm->emitLabelDifferenceAsULEB128(
End,
Base);
3574 Asm->emitLabelDifference(Begin,
Base,
Size);
3577 }
else if (UseDwarf5) {
3585 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3586 Asm->emitInt8(StartxEndx);
3587 Asm->OutStreamer->AddComment(
" start index");
3589 Asm->OutStreamer->AddComment(
" end index");
3592 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3593 Asm->emitInt8(StartxLength);
3594 Asm->OutStreamer->AddComment(
" start index");
3596 Asm->OutStreamer->AddComment(
" length");
3597 Asm->emitLabelDifferenceAsULEB128(
End, Begin);
3600 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3601 Asm->OutStreamer->emitSymbolValue(
End,
Size);
3608 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3612 Asm->OutStreamer->emitIntValue(0,
Size);
3613 Asm->OutStreamer->emitIntValue(0,
Size);
3621 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3622 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3625 DD.emitDebugLocEntryLocation(E, List.CU);
3629void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3630 if (DebugLocs.getLists().empty())
3633 Asm->OutStreamer->switchSection(Sec);
3639 for (
const auto &
List : DebugLocs.getLists())
3643 Asm->OutStreamer->emitLabel(TableEnd);
3647void DwarfDebug::emitDebugLoc() {
3650 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3651 :
Asm->getObjFileLowering().getDwarfLocSection());
3655void DwarfDebug::emitDebugLocDWO() {
3658 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3663 for (
const auto &
List : DebugLocs.getLists()) {
3664 Asm->OutStreamer->switchSection(
3665 Asm->getObjFileLowering().getDwarfLocDWOSection());
3666 Asm->OutStreamer->emitLabel(
List.Label);
3668 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3677 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3678 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3679 Asm->emitULEB128(idx);
3685 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3695void DwarfDebug::emitDebugARanges() {
3696 if (ArangeLabels.empty())
3703 for (
const SymbolCU &SCU : ArangeLabels) {
3704 if (SCU.Sym->isInSection()) {
3706 MCSection *Section = &SCU.Sym->getSection();
3707 SectionMap[Section].push_back(SCU);
3712 SectionMap[
nullptr].push_back(SCU);
3716 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3718 for (
auto &
I : SectionMap) {
3726 for (
const SymbolCU &Cur :
List) {
3728 Span.
Start = Cur.Sym;
3731 Spans[Cur.CU].push_back(Span);
3737 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3741 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3742 const SymbolCU &Prev =
List[n - 1];
3743 const SymbolCU &Cur =
List[n];
3746 if (Cur.
CU != Prev.
CU) {
3748 Span.
Start = StartSym;
3751 Spans[Prev.
CU].push_back(Span);
3758 Asm->OutStreamer->switchSection(
3759 Asm->getObjFileLowering().getDwarfARangesSection());
3761 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3764 std::vector<DwarfCompileUnit *> CUs;
3765 for (
const auto &it : Spans) {
3766 DwarfCompileUnit *
CU = it.first;
3771 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3772 return A->getUniqueID() <
B->getUniqueID();
3776 for (DwarfCompileUnit *
CU : CUs) {
3777 std::vector<ArangeSpan> &
List = Spans[
CU];
3780 if (
auto *Skel =
CU->getSkeleton())
3784 unsigned ContentSize =
3786 Asm->getDwarfOffsetByteSize() +
3791 unsigned TupleSize = PtrSize * 2;
3795 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3798 ContentSize += (
List.size() + 1) * TupleSize;
3801 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3802 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3804 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3805 emitSectionReference(*
CU);
3806 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3807 Asm->emitInt8(PtrSize);
3808 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3811 Asm->OutStreamer->emitFill(Padding, 0xff);
3813 for (
const ArangeSpan &Span :
List) {
3814 Asm->emitLabelReference(Span.Start, PtrSize);
3821 auto SizeRef = SymSize.find(Span.Start);
3822 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3823 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3828 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3831 Size = SizeRef->second;
3833 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3837 Asm->OutStreamer->AddComment(
"ARange terminator");
3838 Asm->OutStreamer->emitIntValue(0, PtrSize);
3839 Asm->OutStreamer->emitIntValue(0, PtrSize);
3847 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3848 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3850 List.CU->getCUNode()->getRangesBaseAddress() ||
3862 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3865 Asm->OutStreamer->switchSection(Section);
3875 Asm->OutStreamer->emitLabel(TableEnd);
3880void DwarfDebug::emitDebugRanges() {
3883 emitDebugRangesImpl(Holder,
3885 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3886 :
Asm->getObjFileLowering().getDwarfRangesSection());
3889void DwarfDebug::emitDebugRangesDWO() {
3891 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3898 enum HeaderFlagMask {
3899#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3900#include "llvm/BinaryFormat/Dwarf.def"
3902 Asm->OutStreamer->AddComment(
"Macro information version");
3903 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3906 if (Asm->isDwarf64()) {
3907 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3908 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3910 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3911 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3913 Asm->OutStreamer->AddComment(
"debug_line_offset");
3915 Asm->emitDwarfLengthOrOffset(0);
3917 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3920void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3921 for (
auto *MN : Nodes) {
3925 emitMacroFile(*
F, U);
3931void DwarfDebug::emitMacro(
DIMacro &M) {
3932 StringRef
Name =
M.getName();
3933 StringRef
Value =
M.getValue();
3939 if (UseDebugMacroSection) {
3942 ? dwarf::DW_MACRO_define_strx
3943 : dwarf::DW_MACRO_undef_strx;
3946 Asm->OutStreamer->AddComment(
"Line Number");
3947 Asm->emitULEB128(
M.getLine());
3948 Asm->OutStreamer->AddComment(
"Macro String");
3950 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3953 ? dwarf::DW_MACRO_GNU_define_indirect
3954 : dwarf::DW_MACRO_GNU_undef_indirect;
3957 Asm->OutStreamer->AddComment(
"Line Number");
3958 Asm->emitULEB128(
M.getLine());
3959 Asm->OutStreamer->AddComment(
"Macro String");
3960 Asm->emitDwarfSymbolReference(
3961 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3965 Asm->emitULEB128(
M.getMacinfoType());
3966 Asm->OutStreamer->AddComment(
"Line Number");
3967 Asm->emitULEB128(
M.getLine());
3968 Asm->OutStreamer->AddComment(
"Macro String");
3969 Asm->OutStreamer->emitBytes(Str);
3970 Asm->emitInt8(
'\0');
3974void DwarfDebug::emitMacroFileImpl(
3976 StringRef (*MacroFormToString)(
unsigned Form)) {
3978 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3979 Asm->emitULEB128(StartFile);
3980 Asm->OutStreamer->AddComment(
"Line Number");
3982 Asm->OutStreamer->AddComment(
"File Number");
3985 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3987 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3989 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3991 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3992 Asm->emitULEB128(EndFile);
3999 if (UseDebugMacroSection)
4001 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
4008void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
4009 for (
const auto &
P : CUMap) {
4010 auto &TheCU = *
P.second;
4012 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
4014 DIMacroNodeArray Macros = CUNode->getMacros();
4017 Asm->OutStreamer->switchSection(Section);
4018 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
4019 if (UseDebugMacroSection)
4021 handleMacroNodes(Macros, U);
4022 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
4028void DwarfDebug::emitDebugMacinfo() {
4029 auto &ObjLower =
Asm->getObjFileLowering();
4030 emitDebugMacinfoImpl(UseDebugMacroSection
4031 ? ObjLower.getDwarfMacroSection()
4032 : ObjLower.getDwarfMacinfoSection());
4035void DwarfDebug::emitDebugMacinfoDWO() {
4036 auto &ObjLower =
Asm->getObjFileLowering();
4037 emitDebugMacinfoImpl(UseDebugMacroSection
4038 ? ObjLower.getDwarfMacroDWOSection()
4039 : ObjLower.getDwarfMacinfoDWOSection());
4044void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
4045 std::unique_ptr<DwarfCompileUnit> NewU) {
4047 if (!CompilationDir.empty())
4048 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
4049 addGnuPubAttributes(*NewU, Die);
4051 SkeletonHolder.addUnit(std::move(NewU));
4056 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
4057 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
4059 DwarfCompileUnit &NewCU = *OwnedUnit;
4060 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
4067 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
4074void DwarfDebug::emitDebugInfoDWO() {
4082void DwarfDebug::emitDebugAbbrevDWO() {
4084 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
4087void DwarfDebug::emitDebugLineDWO() {
4089 SplitTypeUnitFileTable.Emit(
4090 *
Asm->OutStreamer, MCDwarfLineTableParams(),
4091 Asm->getObjFileLowering().getDwarfLineDWOSection());
4094void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
4096 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
4097 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
4104void DwarfDebug::emitDebugStrDWO() {
4106 emitStringOffsetsTableHeaderDWO();
4108 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
4109 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
4114void DwarfDebug::emitDebugAddr() {
4115 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
4121 const DICompileUnit *DIUnit =
CU.getCUNode();
4122 SplitTypeUnitFileTable.maybeSetRootFile(
4125 return &SplitTypeUnitFileTable;
4136 return Result.high();
4145 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4148 auto Ins = TypeSignatures.try_emplace(CTy);
4150 CU.addDIETypeSignature(RefDie, Ins.first->second);
4155 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4156 AddrPool.resetUsedFlag();
4158 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4162 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4164 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4165 CU.getSourceLanguage());
4169 Ins.first->second = Signature;
4177 if (!CompilationDir.empty())
4178 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4179 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4180 Asm->TM.Options.MCOptions.SplitDwarfFile);
4184 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4185 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4190 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4191 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4194 CU.applyStmtList(UnitDie);
4205 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4206 TypeUnitsUnderConstruction.clear();
4210 if (AddrPool.hasBeenUsed()) {
4211 AccelTypeUnitsDebugNames.clear();
4215 for (
const auto &
TU : TypeUnitsToAdd)
4216 TypeSignatures.erase(
TU.second);
4224 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4230 for (
auto &
TU : TypeUnitsToAdd) {
4231 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4236 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4238 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4241 AccelTypeUnitsDebugNames.convertDieToOffset();
4242 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4243 AccelTypeUnitsDebugNames.clear();
4246 CU.addDIETypeSignature(RefDie, Signature);
4253template <
typename DataT>
4254void DwarfDebug::addAccelNameImpl(
4259 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4276 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4277 ((&Current == &AccelDebugNames) &&
4278 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4279 "Kind is CU but TU is being processed.");
4280 assert(((&Current == &AccelDebugNames) ||
4281 ((&Current == &AccelTypeUnitsDebugNames) &&
4282 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4283 "Kind is TU but CU is being processed.");
4286 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4287 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4301 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4310 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4317 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4323 const DIE &Die,
char Flags) {
4324 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4328 return Asm->OutStreamer->getContext().getDwarfVersion();
4332 if (
Asm->getDwarfVersion() >= 4)
4333 return dwarf::Form::DW_FORM_sec_offset;
4334 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4335 "DWARF64 is not defined prior DWARFv3");
4336 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4337 : dwarf::Form::DW_FORM_data4;
4341 return SectionLabels.lookup(S);
4345 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4350std::optional<MD5::MD5Result>
4354 return std::nullopt;
4355 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4357 return std::nullopt;
4362 std::string ChecksumString =
fromHex(Checksum->Value);
4379 if (
MBB.getAlignment() ==
Align(1))
4382 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4389 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4390 if (PrevLoc.getLine()) {
4391 Asm->OutStreamer->emitDwarfLocDirective(
4392 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4394 Asm->OutStreamer->getCurrentSectionOnly());
const TargetLowering & TLI
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")
static unsigned getDwarfVersion(const MachineFunction &MF)
Resolve the DWARF version the way DwarfDebug does.
#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 bool isLangCaseSensitive(const DISourceLanguageName &Lang)
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))
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))
MapVector< Register, SmallVector< FwdRegParamInfo, 2 > > FwdRegWorklist
Register worklist for finding call site values.
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
SmallVector< MachineOperand, 4 > Cond
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
std::unique_ptr< MCStreamer > && Streamer
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.
Class for arbitrary precision integers.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
This class is intended to be used as a driving class for all asm writers.
DwarfDebug * getDwarfDebug()
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const MCAsmInfo & MAI
Target Asm Printer information.
uint16_t getDwarfVersion() const
virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=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 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.
A lightweight wrapper around an expression operand.
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
Wrapper structure that holds source language identity metadata that includes language name,...
bool hasVersionedName() const
uint16_t getName() const
Returns a versioned or unversioned language name.
Subprogram description. Uses SubclassData1.
static LLVM_ABI DILocalScope * getRetainedNodeScope(MDNode *N)
DIScope * getScope() const
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
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
DwarfCompileUnit * getSkeleton() const
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
const StringMap< const DIE * > & getGlobalNames() const
DbgEntity * getExistingAbstractEntity(const DINode *Node)
const StringMap< const DIE * > & getGlobalTypes() const
bool hasDwarfPubSections() const
Collects and handles dwarf debug information.
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
virtual bool shouldResetBaseAddress(const MCSection &Section) const
Whether the target requires resetting the base address in range/loc lists.
std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
virtual bool shouldAttachCompileUnitRanges() const
Whether to attach ranges/low_pc to the compile unit DIE in endModule.
bool emitDebugEntryValues() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind)
Sets the current DWARF5AccelTable to use.
bool alwaysUseRanges(const DwarfCompileUnit &) const
Returns whether range encodings should be used for single entry range lists.
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
void skippedNonDebugFunction() override
void addArangeLabel(SymbolCU SCU)
Add a label so that arange data can be generated for it.
virtual void finishTargetUnitAttributes(const DICompileUnit &DIUnit, DwarfCompileUnit &NewCU)
Target-specific compile unit attribute finalization.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
AddressPool & getAddressPool()
DWARF5AccelTable & getCurrentDWARF5AccelTable()
Returns either CU or TU DWARF5AccelTable.
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
bool shareAcrossDWOCUs() const
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)
Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
const SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
const MCSymbol * getSectionLabel(const MCSection *S)
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for split DWARF.
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.
bool canAddGlobalAddress() const
Whether addGlobalAddress() can spell a global's address at all.
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.
bool addGlobalAddress(const GlobalValue *GV, int64_t Offset)
Emit the address of GV displaced by Offset as an implicit location description, i....
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.
bool addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
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 addImplicitValue(const APInt &Value, const AsmPrinter &AP)
Emit an implicit value.
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 addSectionLabel(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label, const MCSymbol *Sec)
Add a Dwarf section label attribute data and value.
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)
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
MCSection * getDwarfLoclistsSection() const
MCSection * getDwarfRangesSection() const
MCSection * getDwarfMacroSection() const
MCSection * getDwarfMacinfoDWOSection() const
MCSection * getDwarfMacinfoSection() const
MCSection * getDwarfMacroDWOSection() const
static constexpr unsigned NoRegister
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol * getBeginSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
uint32_t getIndex() const
Get the (implementation defined) index.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
succ_iterator succ_begin()
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const CallSiteInfoMap & getCallSitesInfo() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
unsigned getNumOperands() const
Retuns the total number of operands.
bool hasDelaySlot(QueryType Type=AnyInBundle) const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
mop_range uses()
Returns all operands which may be register uses.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
This class implements a map that also provides access to all stored values in a deterministic order.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool empty() const
Determine if the SetVector is empty or not.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void insert_range(Range &&R)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
const Triple & getTargetTriple() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
Triple - Helper class for working with autoconf configuration names.
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI StringRef RangeListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
LLVM_ABI StringRef MacroString(unsigned Encoding)
LLVM_ABI StringRef LocListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GnuMacroString(unsigned Encoding)
LLVM_ABI StringRef MacinfoString(unsigned Encoding)
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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)
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 ...
RelativeUniformCounterPtr Values
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.
LLVM_ABI bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
AccelTableKind
The kind of accelerator tables we should emit.
@ Default
Platform default.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
@ Dwarf
DWARF v5 .debug_names.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
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...
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
DebuggerKind
Identify a debugger for "tuning" the debug info.
@ LLDB
Tune debug info for lldb.
@ End
Run the machine verifier once, at the end of the pipeline.
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.
This struct describes the address of a global, displaced by a constant.
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.