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));
190void DebugLocDwarfExpression::emitUnsigned(uint64_t
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,
958 const MachineFunction *MF =
MI->getMF();
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);
1097void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1105 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1106 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1108 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1111 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1114 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1115 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1118 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1122 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1127 if (!SysRoot.
empty())
1128 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1129 StringRef SDK = DIUnit->
getSDK();
1131 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1142 if (!CompilationDir.empty())
1143 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1144 addGnuPubAttributes(NewCU, Die);
1149 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1153 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1156 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1157 dwarf::DW_FORM_data1, RVer);
1162 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1167 ? dwarf::DW_AT_dwo_name
1168 : dwarf::DW_AT_GNU_dwo_name;
1175 if (
auto *
CU = CUMap.lookup(DIUnit))
1182 return CUMap.begin()->second;
1190DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1191 if (
auto *
CU = getDwarfCompileUnit(DIUnit))
1196 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1198 DwarfCompileUnit &NewCU = *OwnedUnit;
1205 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1206 Asm->OutStreamer->emitDwarfFile0Directive(
1212 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1214 finishUnitAttributes(DIUnit, NewCU);
1215 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1218 CUMap.insert({DIUnit, &NewCU});
1219 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1233 if (!
A.Expr || !
B.Expr)
1235 auto FragmentA =
A.Expr->getFragmentInfo();
1236 auto FragmentB =
B.Expr->getFragmentInfo();
1237 if (!FragmentA || !FragmentB)
1239 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1244 return A.Expr ==
B.Expr;
1259 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1260 M->debug_compile_units_end());
1261 if (NumDebugCUs == 0)
1264 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1265 SingleCU = NumDebugCUs == 1;
1272 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1280 Asm->createTempSymbol(
"rnglists_table_base"));
1284 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1289 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1290 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1293 if (CUNode->getImportedEntities().empty() &&
1294 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1295 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1300 for (
auto *Ty : CUNode->getEnumTypes()) {
1302 "Unexpected function-local entity in 'enums' CU field.");
1306 for (
auto *Ty : CUNode->getRetainedTypes()) {
1309 CU.getOrCreateTypeDIE(RT);
1314void DwarfDebug::finishEntityDefinitions() {
1315 for (
const auto &Entity : ConcreteEntities) {
1316 DIE *Die = Entity->getDIE();
1323 Unit->finishEntityDefinition(Entity.get());
1327void DwarfDebug::finishSubprogramDefinitions() {
1328 for (
const DISubprogram *SP : ProcessedSPNodes) {
1331 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1332 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1336void DwarfDebug::finalizeModuleInfo() {
1337 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1339 finishSubprogramDefinitions();
1341 finishEntityDefinitions();
1343 bool HasEmittedSplitCU =
false;
1347 for (
const auto &
P : CUMap) {
1348 auto &TheCU = *
P.second;
1349 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1351 TheCU.attachLexicalScopesAbstractOrigins();
1354 TheCU.constructContainingTypeDIEs();
1359 auto *SkCU = TheCU.getSkeleton();
1361 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1364 (void)HasEmittedSplitCU;
1366 "Multiple CUs emitted into a single dwo file");
1367 HasEmittedSplitCU =
true;
1369 ? dwarf::DW_AT_dwo_name
1370 : dwarf::DW_AT_GNU_dwo_name;
1371 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1372 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1373 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1374 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1380 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1385 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1386 dwarf::DW_FORM_data8,
ID);
1387 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1388 dwarf::DW_FORM_data8,
ID);
1391 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1393 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1397 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1406 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1408 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1415 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1418 U.setBaseAddress(TheCU.getRanges().front().Begin);
1419 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1426 U.addAddrTableBase();
1429 if (
U.hasRangeLists())
1430 U.addRnglistsBase();
1433 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1442 if (CUNode->getMacros()) {
1443 if (UseDebugMacroSection) {
1445 TheCU.addSectionDelta(
1446 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1450 ? dwarf::DW_AT_macros
1451 : dwarf::DW_AT_GNU_macros;
1452 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1457 TheCU.addSectionDelta(
1458 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1459 U.getMacroLabelBegin(),
1462 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1463 U.getMacroLabelBegin(),
1470 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1471 if (CUNode->getDWOId())
1472 getOrCreateDwarfCompileUnit(CUNode);
1477 SkeletonHolder.computeSizeAndOffsets();
1481 AccelDebugNames.convertDieToOffset();
1490 assert(CurFn ==
nullptr);
1500 Global.getDebugInfo(GVs);
1501 for (
auto *GVE : GVs)
1502 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1513 for (
auto *GVE : CUNode->getGlobalVariables()) {
1517 auto &GVMapEntry = GVMap[GVE->getVariable()];
1518 auto *Expr = GVE->getExpression();
1519 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1520 GVMapEntry.push_back({
nullptr, Expr});
1523 for (
auto *GVE : CUNode->getGlobalVariables()) {
1526 "Unexpected function-local entity in 'globals' CU field.");
1527 if (Processed.
insert(GV).second)
1532 for (
auto *IE : CUNode->getImportedEntities()) {
1534 "Unexpected function-local entity in 'imports' CU field.");
1535 CU->getOrCreateImportedEntityDIE(IE);
1539 const auto Unexpected = [](
const Metadata *
N) {
1542 for (
const auto *
D :
CU->getDeferredLocalDecls())
1543 DISubprogram::visitRetainedNode<void>(
1544 D, Unexpected, Unexpected,
1545 [
CU](
const auto *IE) {
CU->getOrCreateImportedEntityDIE(IE); },
1546 [
CU](
const auto *Ty) {
CU->getOrCreateTypeDIE(Ty); },
1547 [&](
const auto *GVE) {
1549 if (Processed.
insert(GV).second)
1555 CU->createBaseTypeDIEs();
1560 if (!
Asm || !
Asm->hasDebugInfo())
1564 finalizeModuleInfo();
1574 emitAbbreviations();
1580 if (UseARangesSection)
1588 emitDebugMacinfoDWO();
1598 emitDebugAbbrevDWO();
1600 emitDebugRangesDWO();
1610 emitAccelNamespaces();
1614 emitAccelDebugNames();
1623 emitDebugPubSections();
1631 if (
CU.getExistingAbstractEntity(
Node))
1636 CU.createAbstractEntity(
Node, Scope);
1645void DwarfDebug::collectVariableInfoFromMFTable(
1647 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1648 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1649 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1652 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1653 "Expected inlined-at fields to agree");
1655 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1662 <<
", no variable scope found\n");
1666 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1670 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1671 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1672 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1674 if (PreviousMMI &&
VI.inStackSlot())
1675 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1677 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1678 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1683 if (PreviousLoc->holds<Loc::MMI>())
1684 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1687 <<
", conflicting fragment location types\n");
1692 auto RegVar = std::make_unique<DbgVariable>(
1694 if (
VI.inStackSlot())
1695 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1697 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1700 InfoHolder.addScopeVariable(Scope, RegVar.get());
1701 MFVars.
insert({Var, RegVar.get()});
1702 ConcreteEntities.push_back(std::move(RegVar));
1714 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1722 if (LSRange.size() == 0)
1725 const MachineInstr *LScopeBegin = LSRange.front().first;
1729 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1735 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1738 auto PredDL = Pred->getDebugLoc();
1739 if (!PredDL || Pred->isMetaInstruction())
1743 if (
DL->getScope() == PredDL->getScope())
1746 if (!PredScope || LScope->dominates(PredScope))
1759 if (
MBB->pred_empty() &&
1766 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1810 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1812 bool isSafeForSingleLocation =
true;
1813 const MachineInstr *StartDebugMI =
nullptr;
1814 const MachineInstr *EndMI =
nullptr;
1816 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1817 const MachineInstr *
Instr = EI->getInstr();
1820 size_t Index = std::distance(EB, EI);
1821 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1828 "Forgot label before/after instruction starting a range!");
1831 if (std::next(EI) == Entries.
end()) {
1832 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1834 if (EI->isClobber())
1835 EndMI = EI->getInstr();
1837 else if (std::next(EI)->isClobber())
1841 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1843 if (EI->isDbgValue())
1849 if (EI->isDbgValue()) {
1856 if (!
Instr->isUndefDebugValue()) {
1861 if (
Instr->getDebugExpression()->isFragment())
1862 isSafeForSingleLocation =
false;
1865 StartDebugMI =
Instr;
1867 isSafeForSingleLocation =
false;
1873 if (OpenRanges.
empty())
1877 if (StartLabel == EndLabel) {
1878 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1883 for (
auto &R : OpenRanges)
1891 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1892 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1893 for (
const auto &[MBBSectionId, MBBSectionRange] :
1894 Asm->MBBSectionRanges) {
1895 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1896 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel,
Values);
1899 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1900 MBBSectionRange.EndLabel,
Values);
1910 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1911 for (
auto &
Value : CurEntry->getValues())
1913 dbgs() <<
"-----\n";
1916 auto PrevEntry = std::next(CurEntry);
1917 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1921 if (!isSafeForSingleLocation ||
1928 if (!
Asm->MF->hasBBSections())
1936 const MachineBasicBlock *RangeMBB =
nullptr;
1937 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1938 RangeMBB = &
Asm->MF->front();
1940 RangeMBB = Entries.
begin()->getInstr()->getParent();
1942 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1943 "Range MBB not found in MBBSectionRanges!");
1945 auto *NextEntry = std::next(CurEntry);
1946 auto NextRangeIt = std::next(RangeIt);
1947 while (NextEntry !=
DebugLoc.end()) {
1948 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1955 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1956 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1957 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1958 CurEntry->getValues() != NextEntry->getValues())
1960 RangeIt = NextRangeIt;
1961 NextRangeIt = std::next(RangeIt);
1962 CurEntry = NextEntry;
1963 NextEntry = std::next(CurEntry);
1973 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1975 ConcreteEntities.push_back(
1981 ConcreteEntities.push_back(
1987 return ConcreteEntities.back().get();
1995 collectVariableInfoFromMFTable(TheCU, Processed);
1998 InlinedEntity
IV =
I.first;
2003 const auto &HistoryMapEntries =
I.second;
2007 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
2010 LexicalScope *
Scope =
nullptr;
2012 if (
const DILocation *IA =
IV.second)
2022 *Scope, LocalVar,
IV.second));
2024 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
2030 size_t HistSize = HistoryMapEntries.size();
2031 bool SingleValueWithClobber =
2032 HistSize == 2 && HistoryMapEntries[1].isClobber();
2033 if (HistSize == 1 || SingleValueWithClobber) {
2035 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
2037 RegVar->emplace<Loc::Single>(MInsn);
2043 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
2047 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
2052 if (isValidSingleLocation) {
2053 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
2064 for (
auto &Entry : Entries)
2071 InlinedEntity IL =
I.first;
2072 const MachineInstr *
MI =
I.second;
2076 LexicalScope *
Scope =
nullptr;
2079 const DILocalScope *LocalScope =
2080 Label->getScope()->getNonLexicalBlockFileScope();
2082 if (
const DILocation *IA = IL.second)
2095 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2099 for (
const MDNode *
N :
SP->getRetainedNodes()) {
2103 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2105 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2107 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2109 LocalDeclsPerLS[
LS].insert(
N);
2123 if (!
MI.isBundledWithSucc())
2125 auto Suc = std::next(
MI.getIterator());
2130 assert(Suc->isBundledWithPred() &&
2131 "Call bundle instructions are out of order");
2136 if (!NoDebug && SP->areAllCallsDescribed() &&
2138 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2140 bool IsTail =
TII->isTailCall(*
MI);
2158 auto RecordLineZero = [&]() {
2162 const MDNode *Scope =
nullptr;
2163 unsigned Column = 0;
2168 recordSourceLine(0, Column, Scope, 0);
2173 unsigned LastAsmLine =
2174 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2179 if (
MI->isMetaInstruction())
2200 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2202 if (
Asm->OutStreamer->isVerboseAsm()) {
2206 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2215 bool ScopeUsesKeyInstructions =
2217 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2220 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2221 IsKey = KeyInstructions.contains(
MI);
2227 assert(
MI->getParent() == &*
MI->getMF()->begin());
2228 recordSourceLine(SP->getScopeLine(), 0, SP,
2233 bool PrevInstInSameSection =
2235 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2236 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2237 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2247 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2249 RecordSourceLine(
DL, Flags);
2262 if (LastAsmLine == 0)
2283 if (
DL.getLine() == 0 && LastAsmLine == 0)
2290 if (ScopeUsesKeyInstructions) {
2297 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2312 if (
Asm->OutStreamer->isVerboseAsm()) {
2316 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2325static std::pair<const MachineInstr *, bool>
2336 bool IsEmptyPrologue =
2337 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2342 -> std::optional<std::pair<const MachineInstr *, bool>> {
2344 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2345 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2348 if (!isFrameSetup &&
MI.getDebugLoc()) {
2354 if (
MI.getDebugLoc().getLine())
2355 return std::make_pair(&
MI, IsEmptyPrologue);
2360 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2361 NonTrivialInst = &
MI;
2363 IsEmptyPrologue =
false;
2364 return std::nullopt;
2372 auto CurBlock = MF->
begin();
2373 auto CurInst = CurBlock->begin();
2377 while (CurBlock->empty())
2378 CurInst = (++CurBlock)->begin();
2379 assert(CurInst != CurBlock->end());
2383 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2385 if (CurInst->isTerminator()) {
2394 if (CurBlock->pred_size() > 1)
2405 if (CurBlock == MF->
end())
2407 }
while (CurBlock->empty());
2408 CurInst = CurBlock->begin();
2414 if (!CurInst->isMetaInstruction()) {
2415 auto FoundInst = ExamineInst(*CurInst);
2426 if (CurInst->isCall()) {
2428 Loc &&
Loc->getLine() == 0) {
2430 unsigned ScopeLine = SP->getScopeLine();
2433 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2436 return std::make_pair(&*CurInst,
false);
2442 auto NextInst = std::next(CurInst);
2443 if (NextInst != CurInst->getParent()->end()) {
2460 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2461 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2462 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2466 return std::make_pair(
nullptr, IsEmptyPrologue);
2472 const MDNode *S,
unsigned Flags,
unsigned CUID,
2474 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2477 unsigned FileNo = 1;
2480 Fn =
Scope->getFilename();
2481 if (Line != 0 && DwarfVersion >= 4)
2486 .getOrCreateSourceID(
Scope->getFile());
2488 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2489 Discriminator, Fn, Comment);
2500 bool IsEmptyPrologue = PrologEnd.second;
2503 if (IsEmptyPrologue) {
2511 if (!
DL ||
DL->getLine() != 0)
2522 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2532 KeyInstructions.clear();
2539 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2556 for (
auto &
MBB : *MF) {
2568 for (
auto &
MI :
MBB) {
2569 if (
MI.isMetaInstruction())
2573 if (!
Loc || !
Loc->getLine())
2584 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2589 KeyInstructions.insert(Buoy);
2595 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2599 auto *InlinedAt = Loc->getInlinedAt();
2602 if (!Group || !Rank)
2606 if (BuoyAtom && BuoyAtom != Group) {
2611 auto &[CandidateRank, CandidateInsts] =
2612 GroupCandidates[{InlinedAt, Group}];
2618 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2619 (CandidateRank != 0 && !CandidateInsts.empty()));
2621 assert(Rank &&
"expected nonzero rank");
2624 if (CandidateRank && CandidateRank < Rank)
2631 if (CandidateRank == Rank)
2635 else if (CandidateRank > Rank)
2636 CandidateInsts.clear();
2640 CandidateInsts.push_back(Buoy);
2641 CandidateRank = Rank;
2649 if (CandidateInsts.empty())
2655 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2656 for (
auto *
I : Insts)
2657 KeyInstructions.insert(
I);
2665 ForceIsStmtInstrs.clear();
2697 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2698 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2701 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2704 for (
auto &
MI :
MBB) {
2705 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2718 for (
auto *
MBB : PredMBBsToExamine) {
2719 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2720 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2721 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2723 MachineInstr *
MI = MBBInstrIt->second;
2724 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2726 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2727 ForceIsStmtInstrs.insert(
MI);
2734 CheckMBBEdge(Succ, 0);
2740 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2748 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2755 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2758 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2759 CheckMBBEdge(FBB, FBBLine);
2783 unsigned LastLine = 0;
2785 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2786 LastLine =
DL->getLine();
2791 for (
auto *Succ : SuccessorBBs)
2792 CheckMBBEdge(Succ, LastLine);
2807 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2808 ?
Asm->OutStreamer->emitLineTableLabel()
2811 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2819 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2825 computeKeyInstructions(MF);
2826 findForceIsStmtInstrs(MF);
2834 if (
Asm->OutStreamer->hasRawTextSupport())
2838 return CU.getUniqueID();
2842 const auto &CURanges =
CU->getRanges();
2843 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2846 LineTable.getMCLineSections().addEndEntry(
2847 const_cast<MCSymbol *
>(CURanges.back().End));
2867 "endFunction should be called with the same function as beginFunction");
2870 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2882 collectEntityInfo(TheCU, SP, Processed);
2886 for (
const auto &R :
Asm->MBBSectionRanges)
2887 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2894 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2895 for (
const auto &R :
Asm->MBBSectionRanges)
2905 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2909 for (
const MDNode *
N : SP->getRetainedNodes()) {
2912 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2913 assert(LexS &&
"Expected the LexicalScope to be created.");
2917 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2923 LocalDeclsPerLS[LS].insert(
N);
2926 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2927 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2929 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2932 ProcessedSPNodes.insert(SP);
2936 if (!
LScopes.getAbstractScopesList().empty() &&
2938 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2939 FunctionLineTableLabel);
2941 FunctionLineTableLabel =
nullptr;
2944 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2952 LocalDeclsPerLS.clear();
2959void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2971void DwarfDebug::emitDebugInfo() {
2977void DwarfDebug::emitAbbreviations() {
2980 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2983void DwarfDebug::emitStringOffsetsTableHeader() {
2986 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2990template <
typename AccelTableT>
2991void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2993 Asm->OutStreamer->switchSection(Section);
2999void DwarfDebug::emitAccelDebugNames() {
3008void DwarfDebug::emitAccelNames() {
3009 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
3015void DwarfDebug::emitAccelObjC() {
3016 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
3021void DwarfDebug::emitAccelNamespaces() {
3022 emitAccel(AccelNamespace,
3023 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
3028void DwarfDebug::emitAccelTypes() {
3029 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
3059 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
3067 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
3074 case dwarf::DW_TAG_class_type:
3075 case dwarf::DW_TAG_structure_type:
3076 case dwarf::DW_TAG_union_type:
3077 case dwarf::DW_TAG_enumeration_type:
3082 case dwarf::DW_TAG_typedef:
3083 case dwarf::DW_TAG_base_type:
3084 case dwarf::DW_TAG_subrange_type:
3085 case dwarf::DW_TAG_template_alias:
3087 case dwarf::DW_TAG_namespace:
3089 case dwarf::DW_TAG_subprogram:
3091 case dwarf::DW_TAG_variable:
3093 case dwarf::DW_TAG_enumerator:
3103void DwarfDebug::emitDebugPubSections() {
3104 for (
const auto &NU : CUMap) {
3105 DwarfCompileUnit *TheU = NU.second;
3112 Asm->OutStreamer->switchSection(
3113 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3114 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3115 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3117 Asm->OutStreamer->switchSection(
3118 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3119 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3120 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3126 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3127 CU.getDebugSectionOffset());
3129 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3132void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3140 "pub" + Name,
"Length of Public " + Name +
" Info");
3142 Asm->OutStreamer->AddComment(
"DWARF Version");
3145 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3146 emitSectionReference(*TheU);
3148 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3153 for (
const auto &GI : Globals)
3156 return A.second->getOffset() <
B.second->getOffset();
3158 for (
const auto &[Name, Entity] : Vec) {
3159 Asm->OutStreamer->AddComment(
"DIE offset");
3160 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3164 Asm->OutStreamer->AddComment(
3170 Asm->OutStreamer->AddComment(
"External Name");
3171 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3174 Asm->OutStreamer->AddComment(
"End Mark");
3175 Asm->emitDwarfLengthOrOffset(0);
3176 Asm->OutStreamer->emitLabel(EndLabel);
3180void DwarfDebug::emitDebugStr() {
3181 MCSection *StringOffsetsSection =
nullptr;
3183 emitStringOffsetsTableHeader();
3184 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3187 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3188 StringOffsetsSection,
true);
3194 auto &&Comments = DebugLocs.getComments(Entry);
3195 auto Comment = Comments.begin();
3196 auto End = Comments.end();
3203 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3205 DebugLocs.getBytes(Entry).size()),
3206 Asm->getDataLayout().isLittleEndian(), PtrSize);
3211 for (
const auto &
Op : Expr) {
3212 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3213 "3 operand ops not yet supported");
3214 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3215 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3217 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3218 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3220 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3222 for (
unsigned J = 0; J <
Length; ++J)
3227 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3238 auto *DIExpr =
Value.getExpression();
3244 if (DIExpr && DIExpr->isEntryValue()) {
3261 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3264 if (Entry.isInt()) {
3265 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean)) {
3270 bool IsSigned =
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3271 BT->getEncoding() == dwarf::DW_ATE_signed_char);
3283 bool IsByteSized = TypeBitSize % 8 == 0;
3285 IsSigned ? !
isIntN(GenericBitSize, Entry.getInt())
3287 static_cast<uint64_t>(Entry.getInt()));
3288 if (TypeBitSize > GenericBitSize && IsByteSized && IsOutOfRange) {
3290 APInt(
static_cast<unsigned>(TypeBitSize),
3291 static_cast<uint64_t>(Entry.getInt()), IsSigned,
3302 }
else if (Entry.isLocation()) {
3304 if (Location.isIndirect())
3310 }
else if (Entry.isTargetIndexLocation()) {
3316 }
else if (Entry.isConstantFP()) {
3319 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3320 }
else if (Entry.getConstantFP()
3323 .getBitWidth() <= 64 ) {
3325 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3328 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3329 << Entry.getConstantFP()
3340 if (!
Value.isVariadic()) {
3341 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3350 return Entry.isLocation() && !Entry.getLoc().getReg();
3355 std::move(ExprCursor),
3356 [EmitValueLocEntry, &
Value](
unsigned Idx,
3358 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3366 assert(!Values.empty() &&
3367 "location list entries without values are redundant");
3368 assert(Begin != End &&
"unexpected location list entry with empty range");
3373 if (
Value.isFragment()) {
3376 return P.isFragment();
3377 }) &&
"all values are expected to be fragments");
3380 for (
const auto &Fragment : Values)
3384 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3395 Asm->OutStreamer->AddComment(
"Loc expr size");
3397 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3398 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3399 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3418 Asm->OutStreamer->AddComment(
"Offset entry count");
3424 Asm->getDwarfOffsetByteSize());
3438 Asm->OutStreamer->AddComment(
"Offset entry count");
3439 Asm->emitInt32(DebugLocs.getLists().size());
3440 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3442 for (
const auto &List : DebugLocs.getLists())
3443 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3444 Asm->getDwarfOffsetByteSize());
3449template <
typename Ranges,
typename PayloadEmitter>
3453 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3455 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3456 auto Size = Asm->MAI.getCodePointerSize();
3460 Asm->OutStreamer->emitLabel(Sym);
3467 for (
const auto &
Range : R)
3468 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3470 const MCSymbol *CUBase =
CU.getBaseAddress();
3471 bool BaseIsSet =
false;
3472 for (
const auto &
P : SectionRanges) {
3473 auto *
Base = CUBase;
3475 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3478 }
else if (!
Base && ShouldUseBaseAddress) {
3479 const MCSymbol *Begin =
P.second.front()->Begin;
3484 Asm->OutStreamer->emitIntValue(-1,
Size);
3485 Asm->OutStreamer->AddComment(
" base address");
3486 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3487 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3493 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3494 Asm->emitInt8(BaseAddressx);
3495 Asm->OutStreamer->AddComment(
" base address index");
3498 }
else if (BaseIsSet && !UseDwarf5) {
3501 Asm->OutStreamer->emitIntValue(-1,
Size);
3502 Asm->OutStreamer->emitIntValue(0,
Size);
3505 for (
const auto *RS :
P.second) {
3508 assert(Begin &&
"Range without a begin symbol?");
3509 assert(End &&
"Range without an end symbol?");
3513 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3514 Asm->emitInt8(OffsetPair);
3515 Asm->OutStreamer->AddComment(
" starting offset");
3516 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3517 Asm->OutStreamer->AddComment(
" ending offset");
3518 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3520 Asm->emitLabelDifference(Begin,
Base,
Size);
3521 Asm->emitLabelDifference(End,
Base,
Size);
3523 }
else if (UseDwarf5) {
3531 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3532 Asm->emitInt8(StartxEndx);
3533 Asm->OutStreamer->AddComment(
" start index");
3535 Asm->OutStreamer->AddComment(
" end index");
3538 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3539 Asm->emitInt8(StartxLength);
3540 Asm->OutStreamer->AddComment(
" start index");
3542 Asm->OutStreamer->AddComment(
" length");
3543 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3546 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3547 Asm->OutStreamer->emitSymbolValue(End,
Size);
3554 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3558 Asm->OutStreamer->emitIntValue(0,
Size);
3559 Asm->OutStreamer->emitIntValue(0,
Size);
3567 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3568 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3571 DD.emitDebugLocEntryLocation(E, List.CU);
3575void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3576 if (DebugLocs.getLists().empty())
3579 Asm->OutStreamer->switchSection(Sec);
3585 for (
const auto &
List : DebugLocs.getLists())
3589 Asm->OutStreamer->emitLabel(TableEnd);
3593void DwarfDebug::emitDebugLoc() {
3596 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3597 :
Asm->getObjFileLowering().getDwarfLocSection());
3601void DwarfDebug::emitDebugLocDWO() {
3604 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3609 for (
const auto &
List : DebugLocs.getLists()) {
3610 Asm->OutStreamer->switchSection(
3611 Asm->getObjFileLowering().getDwarfLocDWOSection());
3612 Asm->OutStreamer->emitLabel(
List.Label);
3614 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3623 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3624 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3625 Asm->emitULEB128(idx);
3631 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3641void DwarfDebug::emitDebugARanges() {
3642 if (ArangeLabels.empty())
3649 for (
const SymbolCU &SCU : ArangeLabels) {
3650 if (SCU.Sym->isInSection()) {
3652 MCSection *Section = &SCU.Sym->getSection();
3653 SectionMap[Section].push_back(SCU);
3658 SectionMap[
nullptr].push_back(SCU);
3662 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3664 for (
auto &
I : SectionMap) {
3672 for (
const SymbolCU &Cur :
List) {
3674 Span.
Start = Cur.Sym;
3677 Spans[Cur.CU].push_back(Span);
3683 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3687 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3688 const SymbolCU &Prev =
List[n - 1];
3689 const SymbolCU &Cur =
List[n];
3692 if (Cur.
CU != Prev.
CU) {
3694 Span.
Start = StartSym;
3697 Spans[Prev.
CU].push_back(Span);
3704 Asm->OutStreamer->switchSection(
3705 Asm->getObjFileLowering().getDwarfARangesSection());
3707 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3710 std::vector<DwarfCompileUnit *> CUs;
3711 for (
const auto &it : Spans) {
3712 DwarfCompileUnit *
CU = it.first;
3717 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3718 return A->getUniqueID() <
B->getUniqueID();
3722 for (DwarfCompileUnit *
CU : CUs) {
3723 std::vector<ArangeSpan> &
List = Spans[
CU];
3726 if (
auto *Skel =
CU->getSkeleton())
3730 unsigned ContentSize =
3732 Asm->getDwarfOffsetByteSize() +
3737 unsigned TupleSize = PtrSize * 2;
3741 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3744 ContentSize += (
List.size() + 1) * TupleSize;
3747 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3748 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3750 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3751 emitSectionReference(*
CU);
3752 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3753 Asm->emitInt8(PtrSize);
3754 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3757 Asm->OutStreamer->emitFill(Padding, 0xff);
3759 for (
const ArangeSpan &Span :
List) {
3760 Asm->emitLabelReference(Span.Start, PtrSize);
3767 auto SizeRef = SymSize.find(Span.Start);
3768 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3769 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3774 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3777 Size = SizeRef->second;
3779 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3783 Asm->OutStreamer->AddComment(
"ARange terminator");
3784 Asm->OutStreamer->emitIntValue(0, PtrSize);
3785 Asm->OutStreamer->emitIntValue(0, PtrSize);
3793 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3794 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3796 List.CU->getCUNode()->getRangesBaseAddress() ||
3808 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3811 Asm->OutStreamer->switchSection(Section);
3821 Asm->OutStreamer->emitLabel(TableEnd);
3826void DwarfDebug::emitDebugRanges() {
3829 emitDebugRangesImpl(Holder,
3831 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3832 :
Asm->getObjFileLowering().getDwarfRangesSection());
3835void DwarfDebug::emitDebugRangesDWO() {
3837 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3844 enum HeaderFlagMask {
3845#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3846#include "llvm/BinaryFormat/Dwarf.def"
3848 Asm->OutStreamer->AddComment(
"Macro information version");
3849 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3852 if (Asm->isDwarf64()) {
3853 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3854 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3856 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3857 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3859 Asm->OutStreamer->AddComment(
"debug_line_offset");
3861 Asm->emitDwarfLengthOrOffset(0);
3863 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3866void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3867 for (
auto *MN : Nodes) {
3871 emitMacroFile(*
F, U);
3877void DwarfDebug::emitMacro(
DIMacro &M) {
3878 StringRef
Name =
M.getName();
3879 StringRef
Value =
M.getValue();
3885 if (UseDebugMacroSection) {
3888 ? dwarf::DW_MACRO_define_strx
3889 : dwarf::DW_MACRO_undef_strx;
3892 Asm->OutStreamer->AddComment(
"Line Number");
3893 Asm->emitULEB128(
M.getLine());
3894 Asm->OutStreamer->AddComment(
"Macro String");
3896 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3899 ? dwarf::DW_MACRO_GNU_define_indirect
3900 : dwarf::DW_MACRO_GNU_undef_indirect;
3903 Asm->OutStreamer->AddComment(
"Line Number");
3904 Asm->emitULEB128(
M.getLine());
3905 Asm->OutStreamer->AddComment(
"Macro String");
3906 Asm->emitDwarfSymbolReference(
3907 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3911 Asm->emitULEB128(
M.getMacinfoType());
3912 Asm->OutStreamer->AddComment(
"Line Number");
3913 Asm->emitULEB128(
M.getLine());
3914 Asm->OutStreamer->AddComment(
"Macro String");
3915 Asm->OutStreamer->emitBytes(Str);
3916 Asm->emitInt8(
'\0');
3920void DwarfDebug::emitMacroFileImpl(
3922 StringRef (*MacroFormToString)(
unsigned Form)) {
3924 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3925 Asm->emitULEB128(StartFile);
3926 Asm->OutStreamer->AddComment(
"Line Number");
3928 Asm->OutStreamer->AddComment(
"File Number");
3931 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3933 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3935 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3937 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3938 Asm->emitULEB128(EndFile);
3945 if (UseDebugMacroSection)
3947 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3954void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3955 for (
const auto &
P : CUMap) {
3956 auto &TheCU = *
P.second;
3958 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3960 DIMacroNodeArray Macros = CUNode->getMacros();
3963 Asm->OutStreamer->switchSection(Section);
3964 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3965 if (UseDebugMacroSection)
3967 handleMacroNodes(Macros, U);
3968 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3974void DwarfDebug::emitDebugMacinfo() {
3975 auto &ObjLower =
Asm->getObjFileLowering();
3976 emitDebugMacinfoImpl(UseDebugMacroSection
3977 ? ObjLower.getDwarfMacroSection()
3978 : ObjLower.getDwarfMacinfoSection());
3981void DwarfDebug::emitDebugMacinfoDWO() {
3982 auto &ObjLower =
Asm->getObjFileLowering();
3983 emitDebugMacinfoImpl(UseDebugMacroSection
3984 ? ObjLower.getDwarfMacroDWOSection()
3985 : ObjLower.getDwarfMacinfoDWOSection());
3990void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3991 std::unique_ptr<DwarfCompileUnit> NewU) {
3993 if (!CompilationDir.empty())
3994 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3995 addGnuPubAttributes(*NewU, Die);
3997 SkeletonHolder.addUnit(std::move(NewU));
4002 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
4003 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
4005 DwarfCompileUnit &NewCU = *OwnedUnit;
4006 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
4013 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
4020void DwarfDebug::emitDebugInfoDWO() {
4028void DwarfDebug::emitDebugAbbrevDWO() {
4030 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
4033void DwarfDebug::emitDebugLineDWO() {
4035 SplitTypeUnitFileTable.Emit(
4036 *
Asm->OutStreamer, MCDwarfLineTableParams(),
4037 Asm->getObjFileLowering().getDwarfLineDWOSection());
4040void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
4042 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
4043 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
4050void DwarfDebug::emitDebugStrDWO() {
4052 emitStringOffsetsTableHeaderDWO();
4054 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
4055 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
4060void DwarfDebug::emitDebugAddr() {
4061 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
4067 const DICompileUnit *DIUnit =
CU.getCUNode();
4068 SplitTypeUnitFileTable.maybeSetRootFile(
4071 return &SplitTypeUnitFileTable;
4082 return Result.high();
4091 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4094 auto Ins = TypeSignatures.try_emplace(CTy);
4096 CU.addDIETypeSignature(RefDie, Ins.first->second);
4101 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4102 AddrPool.resetUsedFlag();
4104 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4108 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4110 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4111 CU.getSourceLanguage());
4115 Ins.first->second = Signature;
4123 if (!CompilationDir.empty())
4124 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4125 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4126 Asm->TM.Options.MCOptions.SplitDwarfFile);
4130 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4131 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4136 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4137 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4140 CU.applyStmtList(UnitDie);
4151 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4152 TypeUnitsUnderConstruction.clear();
4156 if (AddrPool.hasBeenUsed()) {
4157 AccelTypeUnitsDebugNames.clear();
4161 for (
const auto &
TU : TypeUnitsToAdd)
4162 TypeSignatures.erase(
TU.second);
4170 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4176 for (
auto &
TU : TypeUnitsToAdd) {
4177 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4182 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4184 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4187 AccelTypeUnitsDebugNames.convertDieToOffset();
4188 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4189 AccelTypeUnitsDebugNames.clear();
4192 CU.addDIETypeSignature(RefDie, Signature);
4199template <
typename DataT>
4200void DwarfDebug::addAccelNameImpl(
4205 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4222 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4223 ((&Current == &AccelDebugNames) &&
4224 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4225 "Kind is CU but TU is being processed.");
4226 assert(((&Current == &AccelDebugNames) ||
4227 ((&Current == &AccelTypeUnitsDebugNames) &&
4228 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4229 "Kind is TU but CU is being processed.");
4232 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4233 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4247 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4256 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4263 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4269 const DIE &Die,
char Flags) {
4270 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4274 return Asm->OutStreamer->getContext().getDwarfVersion();
4278 if (
Asm->getDwarfVersion() >= 4)
4279 return dwarf::Form::DW_FORM_sec_offset;
4280 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4281 "DWARF64 is not defined prior DWARFv3");
4282 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4283 : dwarf::Form::DW_FORM_data4;
4287 return SectionLabels.lookup(S);
4291 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4296std::optional<MD5::MD5Result>
4300 return std::nullopt;
4301 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4303 return std::nullopt;
4308 std::string ChecksumString =
fromHex(Checksum->Value);
4325 if (
MBB.getAlignment() ==
Align(1))
4328 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4335 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4336 if (PrevLoc.getLine()) {
4337 Asm->OutStreamer->emitDwarfLocDirective(
4338 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4340 Asm->OutStreamer->getCurrentSectionOnly());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Expected< bool > hasObjCCategory(BitstreamCursor &Stream)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isObjCClass(StringRef Name)
static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))
static void finishCallSiteParams(ValT Val, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > DescribedParams, ParamSet &Params)
Emit call site parameter entries that are described by the given value and debug expression.
static cl::opt< bool > UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden, cl::desc("Emit the GNU .debug_macro format with DWARF <5"), cl::init(false))
static cl::opt< DefaultOnOff > DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden, cl::desc("Use inlined strings rather than string section."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static bool validThroughout(LexicalScopes &LScopes, const MachineInstr *DbgValue, const MachineInstr *RangeEnd, const InstructionOrdering &Ordering)
Determine whether a singular DBG_VALUE is valid for the entirety of its enclosing lexical scope.
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
static cl::opt< LinkageNameOption > DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, cl::desc("Which DWARF linkage-name attributes to emit."), cl::values(clEnumValN(DefaultLinkageNames, "Default", "Default for platform"), clEnumValN(AllLinkageNames, "All", "All"), clEnumValN(AbstractLinkageNames, "Abstract", "Abstract subprograms")), cl::init(DefaultLinkageNames))
static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > ParamsToAdd)
Add Reg to the worklist, if it's not already present, and mark that the given parameter registers' va...
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
SmallSet< MCRegUnit, 16 > ClobberedRegUnitSet
Container for the set of register units known to be clobbered on the path to a call site.
static cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))
Set to false to ignore Key Instructions metadata.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr)
static cl::opt< DefaultOnOff > DwarfOpConvert("dwarf-op-convert", cl::Hidden, cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static std::pair< const MachineInstr *, bool > findPrologueEndLoc(const MachineFunction *MF)
static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)
Try to interpret values loaded into registers that forward parameters for CallMI.
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))
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)
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
virtual unsigned emitDIERef(const DIE &D)=0
Basic type, like 'int' or 'float'.
bool getDebugInfoForProfiling() const
bool isDebugDirectivesOnly() const
StringRef getFlags() const
static LLVM_ABI std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
unsigned getRuntimeVersion() const
bool getSplitDebugInlining() const
StringRef getSysRoot() const
StringRef getProducer() const
DISourceLanguageName getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static LLVM_ABI std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
A structured debug information entry.
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
LLVM_ABI const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
dwarf::Tag getTag() const
Holds a DIExpression and keeps track of how many operands have been consumed so far.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
LLVM_ABI bool isValid() const
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
bool hasVersionedName() const
Subprogram description. Uses SubclassData1.
static 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 the split dwarf proposal support.
virtual void initializeTargetDebugInfo(const MachineFunction &MF)
Target-specific debug info initialization at function start.
unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU)
Get Dwarf compile unit ID for line table.
const MachineInstr * emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
bool useRangesSection() const
Returns whether ranges section should be emitted.
void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
virtual void recordTargetSourceLine(const DebugLoc &DL, unsigned Flags)
Target-specific source line recording.
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null.
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)
Add a DIE to the set of types that we're going to pull into type units.
DwarfFile InfoHolder
Holder for the file specific debug information.
void endModule() override
Emit all Dwarf sections that should come after the content.
void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)
void beginCodeAlignment(const MachineBasicBlock &MBB) override
Process beginning of code alignment.
DwarfDebug(AsmPrinter *A)
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
void finalize()
This needs to be called last to commit any pending changes.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void setMemoryLocationKind()
Lock this down to become a memory location description.
std::optional< uint8_t > TagOffset
void addBooleanConstant(int64_t Value)
Emit a boolean constant.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void 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 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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
bool isCPlusPlus(SourceLanguage S)
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
@ DWARF_VERSION
Other constants.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
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.