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.isImm())
263 else if (
Op.isFPImm())
265 else if (
Op.isCImm())
270 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
274 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
275 return Fragment ? Fragment->OffsetInBits : 0;
289 Expr(ValueLoc.getExpression()) {
290 if (!Expr->getNumElements())
306 return FIE.Expr && FIE.Expr->isFragment();
308 "conflicting locations for variable");
312 bool GenerateTypeUnits,
321 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
327 if (DwarfVersion >= 5)
337 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
338 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()),
340 const Triple &TT =
Asm->TM.getTargetTriple();
345 DebuggerTuning =
Asm->TM.Options.DebuggerTuning;
350 else if (TT.isOSAIX())
366 HasSplitDwarf = !
Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
374 unsigned DwarfVersionNumber =
Asm->TM.Options.MCOptions.DwarfVersion;
375 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
376 :
MMI->getModule()->getDwarfVersion();
380 bool Dwarf64 = DwarfVersion >= 3 &&
389 ((
Asm->TM.Options.MCOptions.Dwarf64 ||
MMI->getModule()->isDwarf64()) &&
390 TT.isOSBinFormatELF()) ||
391 TT.isOSBinFormatXCOFF();
393 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
402 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
403 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
407 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
414 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
416 UseDWARF2Bitfields = DwarfVersion < 4;
422 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
426 EmitDebugEntryValues =
Asm->TM.Options.ShouldEmitDebugEntryValues();
430 UseDebugMacroSection =
439 if (DwarfVersion >= 5)
442 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
451 return Name.starts_with(
"+") || Name.starts_with(
"-");
458 return Name.contains(
") ");
464 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
469 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
470 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
474 return In.slice(In.find(
' ') + 1, In.find(
']'));
487 if (!SP->isDefinition())
490 if (SP->getName() !=
"")
521 if (Scope->isAbstractScope())
539 if (
auto *SkelCU =
CU.getSkeleton())
540 if (
CU.getCUNode()->getSplitDebugInlining())
551 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
552 if (
CU.getSkeleton())
558void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
560 assert(Scope && Scope->getScopeNode());
561 assert(Scope->isAbstractScope());
562 assert(!Scope->getInlinedAt());
568 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
570 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
571 if (
auto *SkelCU =
CU.getSkeleton())
572 if (
CU.getCUNode()->getSplitDebugInlining())
573 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
607template <
typename ValT>
611 for (
auto Param : DescribedParams) {
612 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
622 "Combined debug expression is invalid");
637 auto &ParamsForFwdReg = Worklist[
Reg];
638 for (
auto Param : ParamsToAdd) {
641 return D.ParamReg == Param.ParamReg;
643 "Same parameter described twice by forwarding reg");
650 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
670 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
671 for (
auto &RegUnit : ClobberedRegUnits)
672 if (
TRI.hasRegUnit(
Reg, RegUnit))
677 auto DescribeFwdRegsByCalleeSavedCopy = [&](
const DestSourcePair &CopyInst) {
678 Register CopyDestReg = CopyInst.Destination->getReg();
679 Register CopySrcReg = CopyInst.Source->getReg();
680 if (IsRegClobberedInMeantime(CopyDestReg))
684 if (!
TRI.isCalleeSavedPhysReg(CopyDestReg, *MF))
691 for (
auto FwdRegIt = ForwardedRegWorklist.
begin();
692 FwdRegIt != ForwardedRegWorklist.
end();) {
694 if (FwdRegIt->first == CopySrcReg)
696 else if (
unsigned SubRegIdx =
697 TRI.getSubRegIndex(CopySrcReg, FwdRegIt->first))
698 if (
Register CopyDestSubReg =
TRI.getSubReg(CopyDestReg, SubRegIdx))
708 FwdRegIt = ForwardedRegWorklist.
erase(FwdRegIt);
716 if (
auto CopyInst =
TII.isCopyInstr(*CurMI))
717 DescribeFwdRegsByCalleeSavedCopy(*CopyInst);
745 if (
MI.isDebugInstr())
749 if (MO.getReg().isPhysical()) {
750 for (
auto &FwdReg : ForwardedRegWorklist)
751 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
752 Defs.insert(FwdReg.first);
761 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
762 if (FwdRegDefs.
empty()) {
768 for (
auto ParamFwdReg : FwdRegDefs) {
769 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
770 if (ParamValue->first.isImm()) {
771 int64_t Val = ParamValue->first.getImm();
773 ForwardedRegWorklist[ParamFwdReg], Params);
774 }
else if (ParamValue->first.isReg()) {
775 Register RegLoc = ParamValue->first.getReg();
776 Register SP = TLI.getStackPointerRegisterToSaveRestore();
778 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
781 if (!IsRegClobberedInMeantime(RegLoc) &&
782 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
785 ForwardedRegWorklist[ParamFwdReg], Params);
794 ForwardedRegWorklist[ParamFwdReg]);
801 for (
auto ParamFwdReg : FwdRegDefs)
802 ForwardedRegWorklist.
erase(ParamFwdReg);
809 for (
auto &New : TmpWorklistItems)
811 TmpWorklistItems.
clear();
828 if (ForwardedRegWorklist.
empty())
835 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
846 auto CSInfo = CalleesMap.
find(CallMI);
849 if (CSInfo == CalleesMap.end())
863 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
865 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
867 assert(InsertedReg &&
"Single register used to forward two arguments?");
872 for (
const auto &MO : CallMI->
uses())
873 if (MO.isReg() && MO.isUndef())
874 ForwardedRegWorklist.
erase(MO.getReg());
884 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
893 assert(std::next(Suc) == BundleEnd &&
894 "More than one instruction in call delay slot");
901 for (;
I !=
MBB->rend(); ++
I) {
908 if (ShouldTryEmitEntryVals) {
912 for (
auto &RegEntry : ForwardedRegWorklist) {
919void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
924 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
931 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
934 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
937 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
938 if (!
MI.isBundledWithSucc())
940 auto Suc = std::next(
MI.getIterator());
942 (void)CallInstrBundle;
944 (void)DelaySlotBundle;
951 "Call and its successor instruction don't have same label after.");
956 auto addCallSiteTargetForIndirectCalls = [&](
const MachineInstr *
MI,
960 auto CSInfo = CalleesMap.
find(
MI);
962 if (CSInfo == CalleesMap.end() || !CSInfo->second.CallTarget)
965 MDNode *CallTarget = CSInfo->second.CallTarget;
967 assert(!CallSiteDIE.findAttribute(dwarf::DW_AT_LLVM_virtual_call_origin) &&
968 "DW_AT_LLVM_virtual_call_origin already exists");
970 DIE *CalleeDIE =
CU.getOrCreateSubprogramDIE(CalleeSP,
nullptr);
971 assert(CalleeDIE &&
"Could not create DIE for call site entry origin");
972 CU.addDIEEntry(CallSiteDIE,
973 CU.getDwarf5OrGNUAttr(dwarf::DW_AT_LLVM_virtual_call_origin),
976 CU.addLinkageNamesToDeclarations(*
this, *CalleeSP, *CalleeDIE);
980 for (
const MachineBasicBlock &
MBB : MF) {
990 if (!
MI.isCandidateForAdditionalCallInfo())
999 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
1007 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
1008 bool PhysRegCalleeOperand =
1010 MachineLocation CallTarget{0};
1012 const DISubprogram *CalleeSP =
nullptr;
1013 const Function *CalleeDecl =
nullptr;
1014 if (PhysRegCalleeOperand) {
1015 bool Scalable =
false;
1016 const MachineOperand *BaseOp =
nullptr;
1017 const TargetRegisterInfo &
TRI =
1018 *
Asm->MF->getSubtarget().getRegisterInfo();
1019 if (
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, Scalable, &
TRI)) {
1020 if (BaseOp && BaseOp->
isReg() && !Scalable)
1021 CallTarget = MachineLocation(BaseOp->
getReg(),
true);
1025 CallTarget = MachineLocation(CalleeOp.
getReg());
1034 if (CalleeSP ==
nullptr && CallTarget.
getReg() == 0 &&
1035 AllocSiteTy ==
nullptr)
1045 const MachineInstr *TopLevelCallMI =
1052 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1061 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1064 dbgs() <<
"CallSiteEntry: " << MF.getName() <<
" -> "
1068 MF.getSubtarget().getRegisterInfo()->getName(
1070 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1072 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1073 ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
1077 addCallSiteTargetForIndirectCalls(TopLevelCallMI, CallSiteDIE);
1084 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1091 if (!
U.hasDwarfPubSections())
1094 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1100 case dwarf::DW_LNAME_Fortran:
1101 case dwarf::DW_LNAME_Cobol:
1102 case dwarf::DW_LNAME_Pascal:
1109 case dwarf::DW_LANG_Cobol74:
1110 case dwarf::DW_LANG_Cobol85:
1111 case dwarf::DW_LANG_Fortran77:
1112 case dwarf::DW_LANG_Fortran90:
1113 case dwarf::DW_LANG_Fortran95:
1114 case dwarf::DW_LANG_Fortran03:
1115 case dwarf::DW_LANG_Fortran08:
1116 case dwarf::DW_LANG_Fortran18:
1117 case dwarf::DW_LANG_Fortran23:
1118 case dwarf::DW_LANG_Pascal83:
1125void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1133 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1134 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1136 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1139 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1142 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1143 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1146 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1151 NewCU.
addUInt(Die, dwarf::DW_AT_identifier_case, dwarf::DW_FORM_data1,
1153 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1158 if (!SysRoot.
empty())
1159 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1160 StringRef SDK = DIUnit->
getSDK();
1162 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1173 if (!CompilationDir.empty())
1174 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1175 addGnuPubAttributes(NewCU, Die);
1179 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1184 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1187 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1188 dwarf::DW_FORM_data1, RVer);
1193 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1198 ? dwarf::DW_AT_dwo_name
1199 : dwarf::DW_AT_GNU_dwo_name;
1206 if (
auto *
CU = CUMap.lookup(DIUnit))
1213 return CUMap.begin()->second;
1221DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1222 if (
auto *
CU = getDwarfCompileUnit(DIUnit))
1227 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1229 DwarfCompileUnit &NewCU = *OwnedUnit;
1236 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1237 Asm->OutStreamer->emitDwarfFile0Directive(
1243 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1245 finishUnitAttributes(DIUnit, NewCU);
1246 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1249 CUMap.insert({DIUnit, &NewCU});
1250 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1264 if (!
A.Expr || !
B.Expr)
1266 auto FragmentA =
A.Expr->getFragmentInfo();
1267 auto FragmentB =
B.Expr->getFragmentInfo();
1268 if (!FragmentA || !FragmentB)
1270 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1275 return A.Expr ==
B.Expr;
1290 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1291 M->debug_compile_units_end());
1292 if (NumDebugCUs == 0)
1295 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1296 SingleCU = NumDebugCUs == 1;
1303 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1311 Asm->createTempSymbol(
"rnglists_table_base"));
1315 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1320 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1321 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1324 if (CUNode->getImportedEntities().empty() &&
1325 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1326 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1329 getOrCreateDwarfCompileUnit(CUNode);
1333void DwarfDebug::finishEntityDefinitions() {
1334 for (
const auto &Entity : ConcreteEntities) {
1335 DIE *Die = Entity->getDIE();
1342 Unit->finishEntityDefinition(Entity.get());
1346void DwarfDebug::finishSubprogramDefinitions() {
1347 for (
const DISubprogram *SP : ProcessedSPNodes) {
1350 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1351 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1355void DwarfDebug::finalizeModuleInfo() {
1356 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1358 finishSubprogramDefinitions();
1360 finishEntityDefinitions();
1362 bool HasEmittedSplitCU =
false;
1366 for (
const auto &
P : CUMap) {
1367 auto &TheCU = *
P.second;
1368 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1370 TheCU.attachLexicalScopesAbstractOrigins();
1373 TheCU.constructContainingTypeDIEs();
1374 TheCU.constructPropertyForwardDIEs();
1379 auto *SkCU = TheCU.getSkeleton();
1381 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1384 (void)HasEmittedSplitCU;
1386 "Multiple CUs emitted into a single dwo file");
1387 HasEmittedSplitCU =
true;
1389 ? dwarf::DW_AT_dwo_name
1390 : dwarf::DW_AT_GNU_dwo_name;
1391 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1392 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1393 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1394 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1400 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1405 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1406 dwarf::DW_FORM_data8, ID);
1407 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1408 dwarf::DW_FORM_data8, ID);
1411 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1413 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1417 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1426 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1428 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1435 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1438 U.setBaseAddress(TheCU.getRanges().front().Begin);
1439 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1446 U.addAddrTableBase();
1449 if (
U.hasRangeLists())
1450 U.addRnglistsBase();
1453 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1462 if (CUNode->getMacros()) {
1464 if (UseDebugMacroSection) {
1469 ? dwarf::DW_AT_macros
1470 : dwarf::DW_AT_GNU_macros;
1472 U.getMacroLabelBegin(), Section);
1478 dwarf::DW_AT_macro_info,
1479 U.getMacroLabelBegin(), Section);
1485 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1486 if (CUNode->getDWOId())
1487 getOrCreateDwarfCompileUnit(CUNode);
1492 SkeletonHolder.computeSizeAndOffsets();
1496 AccelDebugNames.convertDieToOffset();
1505 assert(CurFn ==
nullptr);
1515 Global.getDebugInfo(GVs);
1516 for (
auto *GVE : GVs)
1517 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1528 for (
auto *GVE : CUNode->getGlobalVariables()) {
1532 auto &GVMapEntry = GVMap[GVE->getVariable()];
1533 auto *Expr = GVE->getExpression();
1534 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1535 GVMapEntry.push_back({
nullptr, Expr});
1538 for (
auto *GVE : CUNode->getGlobalVariables()) {
1541 "Unexpected function-local entity in 'globals' CU field.");
1542 if (Processed.
insert(GV).second)
1547 for (
auto *Ty : CUNode->getEnumTypes()) {
1549 "Unexpected function-local entity in 'enums' CU field.");
1553 for (
auto *Ty : CUNode->getRetainedTypes()) {
1556 CU->getOrCreateTypeDIE(RT);
1561 for (
auto *IE : CUNode->getImportedEntities()) {
1563 "Unexpected function-local entity in 'imports' CU field.");
1564 CU->getOrCreateImportedEntityDIE(IE);
1568 const auto Unexpected = [](
const Metadata *
N) {
1571 for (
const auto *
D :
CU->getDeferredLocalDecls())
1572 DISubprogram::visitRetainedNode<void>(
1573 D, Unexpected, Unexpected,
1574 [
CU](
const auto *IE) {
CU->getOrCreateImportedEntityDIE(IE); },
1575 [
CU](
const auto *Ty) {
CU->getOrCreateTypeDIE(Ty); },
1576 [&](
const auto *GVE) {
1578 if (Processed.
insert(GV).second)
1584 CU->createBaseTypeDIEs();
1589 if (!
Asm || !
Asm->hasDebugInfo())
1593 finalizeModuleInfo();
1603 emitAbbreviations();
1609 if (UseARangesSection)
1617 emitDebugMacinfoDWO();
1627 emitDebugAbbrevDWO();
1629 emitDebugRangesDWO();
1639 emitAccelNamespaces();
1643 emitAccelDebugNames();
1652 emitDebugPubSections();
1660 if (
CU.getExistingAbstractEntity(
Node))
1665 CU.createAbstractEntity(
Node, Scope);
1674void DwarfDebug::collectVariableInfoFromMFTable(
1676 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1677 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1678 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1681 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1682 "Expected inlined-at fields to agree");
1684 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1691 <<
", no variable scope found\n");
1695 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1699 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1700 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1701 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1703 if (PreviousMMI &&
VI.inStackSlot())
1704 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1706 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1707 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1712 if (PreviousLoc->holds<Loc::MMI>())
1713 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1716 <<
", conflicting fragment location types\n");
1721 auto RegVar = std::make_unique<DbgVariable>(
1723 if (
VI.inStackSlot())
1724 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1726 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1729 InfoHolder.addScopeVariable(Scope, RegVar.get());
1730 MFVars.
insert({Var, RegVar.get()});
1731 ConcreteEntities.push_back(std::move(RegVar));
1743 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1751 if (LSRange.size() == 0)
1754 const MachineInstr *LScopeBegin = LSRange.front().first;
1758 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1764 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1767 auto PredDL = Pred->getDebugLoc();
1768 if (!PredDL || Pred->isMetaInstruction())
1772 if (
DL->getScope() == PredDL->getScope())
1775 if (!PredScope || LScope->dominates(PredScope))
1788 if (
MBB->pred_empty() &&
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<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2733 for (
auto &
MI :
MBB) {
2734 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2747 for (
auto *
MBB : PredMBBsToExamine) {
2748 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2749 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2750 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2752 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 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
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();
3273 if (DIExpr && DIExpr->isEntryValue()) {
3290 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3293 if (Entry.isInt()) {
3294 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean)) {
3299 bool IsSigned =
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3300 BT->getEncoding() == dwarf::DW_ATE_signed_char);
3311 uint64_t TypeBitSize =
BT->getSizeInBits();
3312 bool IsByteSized = TypeBitSize % 8 == 0;
3314 IsSigned ? !
isIntN(GenericBitSize, Entry.getInt())
3316 static_cast<uint64_t
>(Entry.getInt()));
3317 if (TypeBitSize > GenericBitSize && IsByteSized && IsOutOfRange) {
3319 APInt(
static_cast<unsigned>(TypeBitSize),
3320 static_cast<uint64_t
>(Entry.getInt()), IsSigned,
3331 }
else if (Entry.isLocation()) {
3333 if (Location.isIndirect())
3339 }
else if (Entry.isTargetIndexLocation()) {
3345 }
else if (Entry.isConstantFP()) {
3348 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3349 }
else if (Entry.getConstantFP()
3352 .getBitWidth() <= 64 ) {
3354 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3357 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3358 << Entry.getConstantFP()
3369 if (!
Value.isVariadic()) {
3370 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3379 return Entry.isLocation() && !Entry.getLoc().getReg();
3384 std::move(ExprCursor),
3385 [EmitValueLocEntry, &
Value](
unsigned Idx,
3387 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3395 assert(!Values.empty() &&
3396 "location list entries without values are redundant");
3397 assert(Begin != End &&
"unexpected location list entry with empty range");
3402 if (
Value.isFragment()) {
3405 return P.isFragment();
3406 }) &&
"all values are expected to be fragments");
3409 for (
const auto &Fragment : Values)
3413 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3424 Asm->OutStreamer->AddComment(
"Loc expr size");
3426 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3427 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3428 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3447 Asm->OutStreamer->AddComment(
"Offset entry count");
3453 Asm->getDwarfOffsetByteSize());
3467 Asm->OutStreamer->AddComment(
"Offset entry count");
3468 Asm->emitInt32(DebugLocs.getLists().size());
3469 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3471 for (
const auto &List : DebugLocs.getLists())
3472 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3473 Asm->getDwarfOffsetByteSize());
3478template <
typename Ranges,
typename PayloadEmitter>
3482 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3484 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3485 auto Size = Asm->MAI.getCodePointerSize();
3489 Asm->OutStreamer->emitLabel(Sym);
3496 for (
const auto &
Range : R)
3497 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3499 const MCSymbol *CUBase =
CU.getBaseAddress();
3500 bool BaseIsSet =
false;
3501 for (
const auto &
P : SectionRanges) {
3502 auto *
Base = CUBase;
3504 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3507 }
else if (!
Base && ShouldUseBaseAddress) {
3508 const MCSymbol *Begin =
P.second.front()->Begin;
3513 Asm->OutStreamer->emitIntValue(-1,
Size);
3514 Asm->OutStreamer->AddComment(
" base address");
3515 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3516 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3522 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3523 Asm->emitInt8(BaseAddressx);
3524 Asm->OutStreamer->AddComment(
" base address index");
3527 }
else if (BaseIsSet && !UseDwarf5) {
3530 Asm->OutStreamer->emitIntValue(-1,
Size);
3531 Asm->OutStreamer->emitIntValue(0,
Size);
3534 for (
const auto *RS :
P.second) {
3537 assert(Begin &&
"Range without a begin symbol?");
3538 assert(End &&
"Range without an end symbol?");
3542 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3543 Asm->emitInt8(OffsetPair);
3544 Asm->OutStreamer->AddComment(
" starting offset");
3545 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3546 Asm->OutStreamer->AddComment(
" ending offset");
3547 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3549 Asm->emitLabelDifference(Begin,
Base,
Size);
3550 Asm->emitLabelDifference(End,
Base,
Size);
3552 }
else if (UseDwarf5) {
3560 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3561 Asm->emitInt8(StartxEndx);
3562 Asm->OutStreamer->AddComment(
" start index");
3564 Asm->OutStreamer->AddComment(
" end index");
3567 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3568 Asm->emitInt8(StartxLength);
3569 Asm->OutStreamer->AddComment(
" start index");
3571 Asm->OutStreamer->AddComment(
" length");
3572 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3575 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3576 Asm->OutStreamer->emitSymbolValue(End,
Size);
3583 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3587 Asm->OutStreamer->emitIntValue(0,
Size);
3588 Asm->OutStreamer->emitIntValue(0,
Size);
3596 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3597 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3600 DD.emitDebugLocEntryLocation(E, List.CU);
3604void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3605 if (DebugLocs.getLists().empty())
3608 Asm->OutStreamer->switchSection(Sec);
3614 for (
const auto &
List : DebugLocs.getLists())
3618 Asm->OutStreamer->emitLabel(TableEnd);
3622void DwarfDebug::emitDebugLoc() {
3625 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3626 :
Asm->getObjFileLowering().getDwarfLocSection());
3630void DwarfDebug::emitDebugLocDWO() {
3633 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3638 for (
const auto &
List : DebugLocs.getLists()) {
3639 Asm->OutStreamer->switchSection(
3640 Asm->getObjFileLowering().getDwarfLocDWOSection());
3641 Asm->OutStreamer->emitLabel(
List.Label);
3643 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3652 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3653 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3654 Asm->emitULEB128(idx);
3660 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3670void DwarfDebug::emitDebugARanges() {
3671 if (ArangeLabels.empty())
3678 for (
const SymbolCU &SCU : ArangeLabels) {
3679 if (SCU.Sym->isInSection()) {
3681 MCSection *Section = &SCU.Sym->getSection();
3682 SectionMap[Section].push_back(SCU);
3687 SectionMap[
nullptr].push_back(SCU);
3691 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3693 for (
auto &
I : SectionMap) {
3701 for (
const SymbolCU &Cur :
List) {
3703 Span.
Start = Cur.Sym;
3706 Spans[Cur.CU].push_back(Span);
3712 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3716 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3717 const SymbolCU &Prev =
List[n - 1];
3718 const SymbolCU &Cur =
List[n];
3721 if (Cur.
CU != Prev.
CU) {
3723 Span.
Start = StartSym;
3726 Spans[Prev.
CU].push_back(Span);
3733 Asm->OutStreamer->switchSection(
3734 Asm->getObjFileLowering().getDwarfARangesSection());
3736 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3739 std::vector<DwarfCompileUnit *> CUs;
3740 for (
const auto &it : Spans) {
3741 DwarfCompileUnit *
CU = it.first;
3746 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3747 return A->getUniqueID() <
B->getUniqueID();
3751 for (DwarfCompileUnit *
CU : CUs) {
3752 std::vector<ArangeSpan> &
List = Spans[
CU];
3755 if (
auto *Skel =
CU->getSkeleton())
3759 unsigned ContentSize =
3761 Asm->getDwarfOffsetByteSize() +
3766 unsigned TupleSize = PtrSize * 2;
3770 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3773 ContentSize += (
List.size() + 1) * TupleSize;
3776 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3777 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3779 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3780 emitSectionReference(*
CU);
3781 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3782 Asm->emitInt8(PtrSize);
3783 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3786 Asm->OutStreamer->emitFill(Padding, 0xff);
3788 for (
const ArangeSpan &Span :
List) {
3789 Asm->emitLabelReference(Span.Start, PtrSize);
3796 auto SizeRef = SymSize.find(Span.Start);
3797 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3798 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3803 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3806 Size = SizeRef->second;
3808 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3812 Asm->OutStreamer->AddComment(
"ARange terminator");
3813 Asm->OutStreamer->emitIntValue(0, PtrSize);
3814 Asm->OutStreamer->emitIntValue(0, PtrSize);
3822 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3823 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3825 List.CU->getCUNode()->getRangesBaseAddress() ||
3837 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3840 Asm->OutStreamer->switchSection(Section);
3850 Asm->OutStreamer->emitLabel(TableEnd);
3855void DwarfDebug::emitDebugRanges() {
3858 emitDebugRangesImpl(Holder,
3860 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3861 :
Asm->getObjFileLowering().getDwarfRangesSection());
3864void DwarfDebug::emitDebugRangesDWO() {
3866 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3873 enum HeaderFlagMask {
3874#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3875#include "llvm/BinaryFormat/Dwarf.def"
3877 Asm->OutStreamer->AddComment(
"Macro information version");
3878 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3881 if (Asm->isDwarf64()) {
3882 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3883 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3885 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3886 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3888 Asm->OutStreamer->AddComment(
"debug_line_offset");
3890 Asm->emitDwarfLengthOrOffset(0);
3892 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3895void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3896 for (
auto *MN : Nodes) {
3900 emitMacroFile(*
F, U);
3906void DwarfDebug::emitMacro(
DIMacro &M) {
3907 StringRef
Name =
M.getName();
3908 StringRef
Value =
M.getValue();
3914 if (UseDebugMacroSection) {
3917 ? dwarf::DW_MACRO_define_strx
3918 : dwarf::DW_MACRO_undef_strx;
3921 Asm->OutStreamer->AddComment(
"Line Number");
3922 Asm->emitULEB128(
M.getLine());
3923 Asm->OutStreamer->AddComment(
"Macro String");
3925 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3928 ? dwarf::DW_MACRO_GNU_define_indirect
3929 : dwarf::DW_MACRO_GNU_undef_indirect;
3932 Asm->OutStreamer->AddComment(
"Line Number");
3933 Asm->emitULEB128(
M.getLine());
3934 Asm->OutStreamer->AddComment(
"Macro String");
3935 Asm->emitDwarfSymbolReference(
3936 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3940 Asm->emitULEB128(
M.getMacinfoType());
3941 Asm->OutStreamer->AddComment(
"Line Number");
3942 Asm->emitULEB128(
M.getLine());
3943 Asm->OutStreamer->AddComment(
"Macro String");
3944 Asm->OutStreamer->emitBytes(Str);
3945 Asm->emitInt8(
'\0');
3949void DwarfDebug::emitMacroFileImpl(
3951 StringRef (*MacroFormToString)(
unsigned Form)) {
3953 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3954 Asm->emitULEB128(StartFile);
3955 Asm->OutStreamer->AddComment(
"Line Number");
3957 Asm->OutStreamer->AddComment(
"File Number");
3960 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3962 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3964 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3966 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3967 Asm->emitULEB128(EndFile);
3974 if (UseDebugMacroSection)
3976 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3983void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3984 for (
const auto &
P : CUMap) {
3985 auto &TheCU = *
P.second;
3987 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3989 DIMacroNodeArray Macros = CUNode->getMacros();
3992 Asm->OutStreamer->switchSection(Section);
3993 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3994 if (UseDebugMacroSection)
3996 handleMacroNodes(Macros, U);
3997 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
4003void DwarfDebug::emitDebugMacinfo() {
4004 auto &ObjLower =
Asm->getObjFileLowering();
4005 emitDebugMacinfoImpl(UseDebugMacroSection
4006 ? ObjLower.getDwarfMacroSection()
4007 : ObjLower.getDwarfMacinfoSection());
4010void DwarfDebug::emitDebugMacinfoDWO() {
4011 auto &ObjLower =
Asm->getObjFileLowering();
4012 emitDebugMacinfoImpl(UseDebugMacroSection
4013 ? ObjLower.getDwarfMacroDWOSection()
4014 : ObjLower.getDwarfMacinfoDWOSection());
4019void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
4020 std::unique_ptr<DwarfCompileUnit> NewU) {
4022 if (!CompilationDir.empty())
4023 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
4024 addGnuPubAttributes(*NewU, Die);
4026 SkeletonHolder.addUnit(std::move(NewU));
4031 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
4032 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
4034 DwarfCompileUnit &NewCU = *OwnedUnit;
4035 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
4042 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
4049void DwarfDebug::emitDebugInfoDWO() {
4057void DwarfDebug::emitDebugAbbrevDWO() {
4059 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
4062void DwarfDebug::emitDebugLineDWO() {
4064 SplitTypeUnitFileTable.Emit(
4065 *
Asm->OutStreamer, MCDwarfLineTableParams(),
4066 Asm->getObjFileLowering().getDwarfLineDWOSection());
4069void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
4071 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
4072 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
4079void DwarfDebug::emitDebugStrDWO() {
4081 emitStringOffsetsTableHeaderDWO();
4083 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
4084 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
4089void DwarfDebug::emitDebugAddr() {
4090 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
4096 const DICompileUnit *DIUnit =
CU.getCUNode();
4097 SplitTypeUnitFileTable.maybeSetRootFile(
4100 return &SplitTypeUnitFileTable;
4111 return Result.high();
4120 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4123 auto Ins = TypeSignatures.try_emplace(CTy);
4125 CU.addDIETypeSignature(RefDie, Ins.first->second);
4130 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4131 AddrPool.resetUsedFlag();
4133 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4137 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4139 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4140 CU.getSourceLanguage());
4144 Ins.first->second = Signature;
4152 if (!CompilationDir.empty())
4153 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4154 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4155 Asm->TM.Options.MCOptions.SplitDwarfFile);
4159 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4160 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4165 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4166 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4169 CU.applyStmtList(UnitDie);
4180 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4181 TypeUnitsUnderConstruction.clear();
4185 if (AddrPool.hasBeenUsed()) {
4186 AccelTypeUnitsDebugNames.clear();
4190 for (
const auto &
TU : TypeUnitsToAdd)
4191 TypeSignatures.erase(
TU.second);
4199 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4205 for (
auto &
TU : TypeUnitsToAdd) {
4206 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4211 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4213 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4216 AccelTypeUnitsDebugNames.convertDieToOffset();
4217 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4218 AccelTypeUnitsDebugNames.clear();
4221 CU.addDIETypeSignature(RefDie, Signature);
4228template <
typename DataT>
4229void DwarfDebug::addAccelNameImpl(
4234 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4251 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4252 ((&Current == &AccelDebugNames) &&
4253 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4254 "Kind is CU but TU is being processed.");
4255 assert(((&Current == &AccelDebugNames) ||
4256 ((&Current == &AccelTypeUnitsDebugNames) &&
4257 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4258 "Kind is TU but CU is being processed.");
4261 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4262 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4276 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4285 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4292 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4298 const DIE &Die,
char Flags) {
4299 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4303 return Asm->OutStreamer->getContext().getDwarfVersion();
4307 if (
Asm->getDwarfVersion() >= 4)
4308 return dwarf::Form::DW_FORM_sec_offset;
4309 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4310 "DWARF64 is not defined prior DWARFv3");
4311 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4312 : dwarf::Form::DW_FORM_data4;
4316 return SectionLabels.lookup(S);
4320 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4325std::optional<MD5::MD5Result>
4329 return std::nullopt;
4330 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4332 return std::nullopt;
4337 std::string ChecksumString =
fromHex(Checksum->Value);
4354 if (
MBB.getAlignment() ==
Align(1))
4357 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4364 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4365 if (PrevLoc.getLine()) {
4366 Asm->OutStreamer->emitDwarfLocDirective(
4367 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4369 Asm->OutStreamer->getCurrentSectionOnly());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Expected< bool > hasObjCCategory(BitstreamCursor &Stream)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isObjCClass(StringRef Name)
static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))
static void finishCallSiteParams(ValT Val, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > DescribedParams, ParamSet &Params)
Emit call site parameter entries that are described by the given value and debug expression.
static cl::opt< bool > UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden, cl::desc("Emit the GNU .debug_macro format with DWARF <5"), cl::init(false))
static cl::opt< DefaultOnOff > DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden, cl::desc("Use inlined strings rather than string section."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static bool validThroughout(LexicalScopes &LScopes, const MachineInstr *DbgValue, const MachineInstr *RangeEnd, const InstructionOrdering &Ordering)
Determine whether a singular DBG_VALUE is valid for the entirety of its enclosing lexical scope.
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
static cl::opt< LinkageNameOption > DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, cl::desc("Which DWARF linkage-name attributes to emit."), cl::values(clEnumValN(DefaultLinkageNames, "Default", "Default for platform"), clEnumValN(AllLinkageNames, "All", "All"), clEnumValN(AbstractLinkageNames, "Abstract", "Abstract subprograms")), cl::init(DefaultLinkageNames))
static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > ParamsToAdd)
Add Reg to the worklist, if it's not already present, and mark that the given parameter registers' va...
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
SmallSet< MCRegUnit, 16 > ClobberedRegUnitSet
Container for the set of register units known to be clobbered on the path to a call site.
static cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))
Set to false to ignore Key Instructions metadata.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
static 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
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
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 compile unit or type unit DIE that this DIE belongs to.
dwarf::Tag getTag() const
Holds a DIExpression and keeps track of how many operands have been consumed so far.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
LLVM_ABI bool isValid() const
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
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
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
DwarfCompileUnit * getSkeleton() const
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
const StringMap< const DIE * > & getGlobalNames() const
DbgEntity * getExistingAbstractEntity(const DINode *Node)
const StringMap< const DIE * > & getGlobalTypes() const
bool hasDwarfPubSections() const
Collects and handles dwarf debug information.
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
virtual bool shouldResetBaseAddress(const MCSection &Section) const
Whether the target requires resetting the base address in range/loc lists.
std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
virtual bool shouldAttachCompileUnitRanges() const
Whether to attach ranges/low_pc to the compile unit DIE in endModule.
bool emitDebugEntryValues() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind)
Sets the current DWARF5AccelTable to use.
bool alwaysUseRanges(const DwarfCompileUnit &) const
Returns whether range encodings should be used for single entry range lists.
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
void skippedNonDebugFunction() override
void addArangeLabel(SymbolCU SCU)
Add a label so that arange data can be generated for it.
virtual void finishTargetUnitAttributes(const DICompileUnit &DIUnit, DwarfCompileUnit &NewCU)
Target-specific compile unit attribute finalization.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
AddressPool & getAddressPool()
DWARF5AccelTable & getCurrentDWARF5AccelTable()
Returns either CU or TU DWARF5AccelTable.
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
bool shareAcrossDWOCUs() const
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)
Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
const SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
const MCSymbol * getSectionLabel(const MCSection *S)
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for 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.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
void finalize()
This needs to be called last to commit any pending changes.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void setMemoryLocationKind()
Lock this down to become a memory location description.
std::optional< uint8_t > TagOffset
void addBooleanConstant(int64_t Value)
Emit a boolean constant.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void 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.
@ SCE
Tune debug info for SCE targets (e.g. PS4).
@ DBX
Tune debug info for dbx.
@ Default
No specific tuning requested.
@ GDB
Tune debug info for gdb.
@ LLDB
Tune debug info for lldb.
Implement std::hash so that hash_code can be used in STL containers.
Represents a parameter whose call site value can be described by applying a debug expression to a reg...
uint64_t ParamReg
The described parameter register.
const DIExpression * Expr
Debug expression that has been built up when walking through the instruction chain that produces the ...
This struct is a compact representation of a valid (non-zero power of two) alignment.
A pair of GlobalVariable and DIExpression.
Represents an entry-value location, or a fragment of one.
void addFrameIndexExpr(const DIExpression *Expr, int FI)
std::set< FrameIndexExpr > FrameIndexExprs
const std::set< FrameIndexExpr > & getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
A MapVector that performs no allocations if smaller than a certain size.
Helper used to pair up a symbol and its DWARF compile unit.
This struct describes target specific location.
Describes an entry of the various gnu_pub* debug sections.