64#define DEBUG_TYPE "dwarfdebug"
66STATISTIC(NumCSParams,
"Number of dbg call site params created");
69 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
79 cl::desc(
"Generate DWARF4 type units."),
90 cl::desc(
"Make an absence of debug location information explicit."),
98 "Default for platform"),
106 cl::desc(
"Use inlined strings rather than string section."),
114 cl::desc(
"Disable emission .debug_ranges section."),
119 cl::desc(
"Use sections+offset as references rather than labels."),
126 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
131 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
144 cl::desc(
"Which DWARF linkage-name attributes to emit."),
146 "Default for platform"),
149 "Abstract subprograms")),
154 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
155 "address pool entry sharing to reduce relocations/object size"),
157 "Default address minimization strategy"),
159 "Use rnglists for contiguous ranges if that allows "
160 "using a pre-existing base address"),
163 "Use exprloc addrx+offset expressions for any "
164 "address with a prior base address"),
166 "Use addrx+offset extension form for any address "
167 "with a prior base address"),
175 cl::desc(
"Set to false to ignore Key Instructions metadata"));
179void DebugLocDwarfExpression::emitOp(
uint8_t Op,
const char *Comment) {
185void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
186 getActiveStreamer().emitSLEB128(
Value, Twine(
Value));
189void DebugLocDwarfExpression::emitUnsigned(uint64_t
Value) {
190 getActiveStreamer().emitULEB128(
Value, Twine(
Value));
193void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
194 getActiveStreamer().emitInt8(
Value, Twine(
Value));
197void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
209 assert(!IsBuffering &&
"Already buffering?");
211 TmpBuf = std::make_unique<TempBuffer>(OutBS.GenerateComments);
218 return TmpBuf ? TmpBuf->Bytes.size() : 0;
224 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
225 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
226 ? TmpBuf->Comments[
Byte.index()].c_str()
228 OutBS.emitInt8(
Byte.value(), Comment);
230 TmpBuf->Bytes.clear();
231 TmpBuf->Comments.clear();
242 const bool IsVariadic = !SingleLocExprOpt;
245 if (!IsVariadic && !
MI->isNonListDebugValue()) {
246 assert(
MI->getNumDebugOperands() == 1 &&
247 "Mismatched DIExpression and debug operands for debug instruction.");
248 Expr = *SingleLocExprOpt;
255 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
257 }
else if (
Op.isTargetIndex()) {
260 }
else if (
Op.isImm())
262 else if (
Op.isFPImm())
264 else if (
Op.isCImm())
269 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
273 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
274 return Fragment ? Fragment->OffsetInBits : 0;
288 Expr(ValueLoc.getExpression()) {
289 if (!Expr->getNumElements())
305 return FIE.Expr && FIE.Expr->isFragment();
307 "conflicting locations for variable");
311 bool GenerateTypeUnits,
320 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
326 if (DwarfVersion >= 5)
336 InfoHolder(
A,
"info_string", DIEValueAllocator),
337 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
338 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()) {
339 const Triple &TT =
Asm->TM.getTargetTriple();
344 DebuggerTuning =
Asm->TM.Options.DebuggerTuning;
349 else if (TT.isOSAIX())
355 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
365 HasSplitDwarf = !
Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
373 unsigned DwarfVersionNumber =
Asm->TM.Options.MCOptions.DwarfVersion;
374 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
375 :
MMI->getModule()->getDwarfVersion();
380 bool Dwarf64 = DwarfVersion >= 3 &&
389 ((
Asm->TM.Options.MCOptions.Dwarf64 ||
MMI->getModule()->isDwarf64()) &&
390 TT.isOSBinFormatELF()) ||
391 TT.isOSBinFormatXCOFF();
393 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
400 UseSectionsAsReferences = TT.isNVPTX();
405 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
406 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
410 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
417 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
419 UseDWARF2Bitfields = DwarfVersion < 4;
425 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
429 EmitDebugEntryValues =
Asm->TM.Options.ShouldEmitDebugEntryValues();
433 UseDebugMacroSection =
442 if (DwarfVersion >= 5)
445 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
454 return Name.starts_with(
"+") || Name.starts_with(
"-");
461 return Name.contains(
") ");
467 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
472 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
473 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
477 return In.slice(In.find(
' ') + 1, In.find(
']'));
490 if (!SP->isDefinition())
493 if (SP->getName() !=
"")
524 if (Scope->isAbstractScope())
542 if (
auto *SkelCU =
CU.getSkeleton())
543 if (
CU.getCUNode()->getSplitDebugInlining())
554 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
555 if (
CU.getSkeleton())
561void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
563 assert(Scope && Scope->getScopeNode());
564 assert(Scope->isAbstractScope());
565 assert(!Scope->getInlinedAt());
571 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
573 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
574 if (
auto *SkelCU =
CU.getSkeleton())
575 if (
CU.getCUNode()->getSplitDebugInlining())
576 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
610template <
typename ValT>
614 for (
auto Param : DescribedParams) {
615 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
630 "Combined debug expression is invalid");
645 auto &ParamsForFwdReg = Worklist[
Reg];
646 for (
auto Param : ParamsToAdd) {
649 return D.ParamReg == Param.ParamReg;
651 "Same parameter described twice by forwarding reg");
658 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
701 if (
MI.isDebugInstr())
705 if (MO.getReg().isPhysical()) {
706 for (
auto &FwdReg : ForwardedRegWorklist)
707 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
708 Defs.insert(FwdReg.first);
717 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
718 if (FwdRegDefs.
empty()) {
727 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
728 for (
auto &RegUnit : ClobberedRegUnits)
729 if (
TRI.hasRegUnit(
Reg, RegUnit))
734 for (
auto ParamFwdReg : FwdRegDefs) {
735 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
736 if (ParamValue->first.isImm()) {
737 int64_t Val = ParamValue->first.getImm();
739 ForwardedRegWorklist[ParamFwdReg], Params);
740 }
else if (ParamValue->first.isReg()) {
741 Register RegLoc = ParamValue->first.getReg();
742 Register SP = TLI.getStackPointerRegisterToSaveRestore();
744 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
745 if (!IsRegClobberedInMeantime(RegLoc) &&
746 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
749 ForwardedRegWorklist[ParamFwdReg], Params);
758 ForwardedRegWorklist[ParamFwdReg]);
765 for (
auto ParamFwdReg : FwdRegDefs)
766 ForwardedRegWorklist.
erase(ParamFwdReg);
773 for (
auto &New : TmpWorklistItems)
775 TmpWorklistItems.
clear();
792 if (ForwardedRegWorklist.
empty())
799 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
810 auto CSInfo = CalleesMap.
find(CallMI);
813 if (CSInfo == CalleesMap.end())
827 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
829 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
831 assert(InsertedReg &&
"Single register used to forward two arguments?");
836 for (
const auto &MO : CallMI->
uses())
837 if (MO.isReg() && MO.isUndef())
838 ForwardedRegWorklist.
erase(MO.getReg());
848 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
857 assert(std::next(Suc) == BundleEnd &&
858 "More than one instruction in call delay slot");
865 for (;
I !=
MBB->rend(); ++
I) {
872 if (ShouldTryEmitEntryVals) {
876 for (
auto &RegEntry : ForwardedRegWorklist) {
883void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
888 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
895 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
898 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
901 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
902 if (!
MI.isBundledWithSucc())
904 auto Suc = std::next(
MI.getIterator());
906 (void)CallInstrBundle;
908 (void)DelaySlotBundle;
915 "Call and its successor instruction don't have same label after.");
920 for (
const MachineBasicBlock &
MBB : MF) {
930 if (!
MI.isCandidateForAdditionalCallInfo())
939 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
947 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
948 bool PhysRegCalleeOperand =
950 MachineLocation CallTarget{0};
952 const DISubprogram *CalleeSP =
nullptr;
953 const Function *CalleeDecl =
nullptr;
954 if (PhysRegCalleeOperand) {
955 bool Scalable =
false;
956 const MachineOperand *BaseOp =
nullptr;
957 const TargetRegisterInfo &
TRI =
958 *
Asm->MF->getSubtarget().getRegisterInfo();
959 if (
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, Scalable, &
TRI)) {
960 if (BaseOp && BaseOp->
isReg() && !Scalable)
961 CallTarget = MachineLocation(BaseOp->
getReg(),
true);
965 CallTarget = MachineLocation(CalleeOp.
getReg());
974 if (CalleeSP ==
nullptr && CallTarget.
getReg() == 0 &&
975 AllocSiteTy ==
nullptr)
985 const MachineInstr *TopLevelCallMI =
992 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1001 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1004 dbgs() <<
"CallSiteEntry: " << MF.getName() <<
" -> "
1008 MF.getSubtarget().getRegisterInfo()->getName(
1010 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1012 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1013 ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
1021 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1028 if (!
U.hasDwarfPubSections())
1031 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1034void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1042 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1043 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1045 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1048 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1051 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1052 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1055 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1059 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1061 if (!SysRoot.
empty())
1062 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1063 StringRef SDK = DIUnit->
getSDK();
1065 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1076 if (!CompilationDir.empty())
1077 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1078 addGnuPubAttributes(NewCU, Die);
1083 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1087 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1090 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1091 dwarf::DW_FORM_data1, RVer);
1096 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1101 ? dwarf::DW_AT_dwo_name
1102 : dwarf::DW_AT_GNU_dwo_name;
1110DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1111 if (
auto *
CU = CUMap.lookup(DIUnit))
1119 return *CUMap.begin()->second;
1123 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1124 InfoHolder.getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1125 DwarfCompileUnit &NewCU = *OwnedUnit;
1126 InfoHolder.addUnit(std::move(OwnedUnit));
1132 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1133 Asm->OutStreamer->emitDwarfFile0Directive(
1139 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1141 finishUnitAttributes(DIUnit, NewCU);
1142 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1145 CUMap.insert({DIUnit, &NewCU});
1146 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1160 if (!
A.Expr || !
B.Expr)
1162 auto FragmentA =
A.Expr->getFragmentInfo();
1163 auto FragmentB =
B.Expr->getFragmentInfo();
1164 if (!FragmentA || !FragmentB)
1166 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1171 return A.Expr ==
B.Expr;
1186 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1187 M->debug_compile_units_end());
1188 if (NumDebugCUs == 0)
1191 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1192 SingleCU = NumDebugCUs == 1;
1197 Global.getDebugInfo(GVs);
1198 for (
auto *GVE : GVs)
1199 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1207 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1215 Asm->createTempSymbol(
"rnglists_table_base"));
1218 InfoHolder.setRnglistsTableBaseSym(
1219 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1224 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1225 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1228 if (CUNode->getImportedEntities().empty() &&
1229 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1230 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1236 for (
auto *GVE : CUNode->getGlobalVariables()) {
1240 auto &GVMapEntry = GVMap[GVE->getVariable()];
1241 auto *Expr = GVE->getExpression();
1242 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1243 GVMapEntry.push_back({
nullptr, Expr});
1247 for (
auto *GVE : CUNode->getGlobalVariables()) {
1249 if (Processed.
insert(GV).second)
1253 for (
auto *Ty : CUNode->getEnumTypes())
1256 for (
auto *Ty : CUNode->getRetainedTypes()) {
1261 CU.getOrCreateTypeDIE(RT);
1266void DwarfDebug::finishEntityDefinitions() {
1267 for (
const auto &Entity : ConcreteEntities) {
1268 DIE *Die = Entity->getDIE();
1275 Unit->finishEntityDefinition(Entity.get());
1279void DwarfDebug::finishSubprogramDefinitions() {
1280 for (
const DISubprogram *SP : ProcessedSPNodes) {
1283 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1284 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1288void DwarfDebug::finalizeModuleInfo() {
1289 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1291 finishSubprogramDefinitions();
1293 finishEntityDefinitions();
1295 bool HasEmittedSplitCU =
false;
1299 for (
const auto &
P : CUMap) {
1300 auto &TheCU = *
P.second;
1301 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1303 TheCU.attachLexicalScopesAbstractOrigins();
1306 TheCU.constructContainingTypeDIEs();
1311 auto *SkCU = TheCU.getSkeleton();
1313 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1316 (void)HasEmittedSplitCU;
1318 "Multiple CUs emitted into a single dwo file");
1319 HasEmittedSplitCU =
true;
1321 ? dwarf::DW_AT_dwo_name
1322 : dwarf::DW_AT_GNU_dwo_name;
1323 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1324 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1325 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1326 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1332 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1337 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1338 dwarf::DW_FORM_data8,
ID);
1339 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1340 dwarf::DW_FORM_data8,
ID);
1343 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1345 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1349 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1358 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1360 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1365 if (!(
Asm->TM.getTargetTriple().isNVPTX() &&
tuneForGDB())) {
1371 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1374 U.setBaseAddress(TheCU.getRanges().front().Begin);
1375 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1382 U.addAddrTableBase();
1385 if (
U.hasRangeLists())
1386 U.addRnglistsBase();
1389 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1398 if (CUNode->getMacros()) {
1399 if (UseDebugMacroSection) {
1401 TheCU.addSectionDelta(
1402 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1406 ? dwarf::DW_AT_macros
1407 : dwarf::DW_AT_GNU_macros;
1408 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1413 TheCU.addSectionDelta(
1414 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1415 U.getMacroLabelBegin(),
1418 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1419 U.getMacroLabelBegin(),
1426 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1427 if (CUNode->getDWOId())
1428 getOrCreateDwarfCompileUnit(CUNode);
1431 InfoHolder.computeSizeAndOffsets();
1433 SkeletonHolder.computeSizeAndOffsets();
1437 AccelDebugNames.convertDieToOffset();
1446 assert(CurFn ==
nullptr);
1449 for (
const auto &
P : CUMap) {
1454 for (
auto *IE : CUNode->getImportedEntities()) {
1456 "Unexpected function-local entity in 'imports' CU field.");
1457 CU->getOrCreateImportedEntityDIE(IE);
1459 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1461 CU->getOrCreateImportedEntityDIE(IE);
1467 CU->createBaseTypeDIEs();
1472 if (!
Asm || !
Asm->hasDebugInfo())
1476 finalizeModuleInfo();
1486 emitAbbreviations();
1492 if (UseARangesSection)
1500 emitDebugMacinfoDWO();
1510 emitDebugAbbrevDWO();
1512 emitDebugRangesDWO();
1522 emitAccelNamespaces();
1526 emitAccelDebugNames();
1535 emitDebugPubSections();
1543 if (
CU.getExistingAbstractEntity(
Node))
1548 CU.createAbstractEntity(
Node, Scope);
1557void DwarfDebug::collectVariableInfoFromMFTable(
1559 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1560 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1561 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1564 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1565 "Expected inlined-at fields to agree");
1567 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1574 <<
", no variable scope found\n");
1578 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1582 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1583 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1584 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1586 if (PreviousMMI &&
VI.inStackSlot())
1587 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1589 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1590 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1595 if (PreviousLoc->holds<Loc::MMI>())
1596 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1599 <<
", conflicting fragment location types\n");
1604 auto RegVar = std::make_unique<DbgVariable>(
1606 if (
VI.inStackSlot())
1607 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1609 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1612 InfoHolder.addScopeVariable(Scope, RegVar.get());
1613 MFVars.
insert({Var, RegVar.get()});
1614 ConcreteEntities.push_back(std::move(RegVar));
1626 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1634 if (LSRange.size() == 0)
1637 const MachineInstr *LScopeBegin = LSRange.front().first;
1641 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1647 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1650 auto PredDL = Pred->getDebugLoc();
1651 if (!PredDL || Pred->isMetaInstruction())
1655 if (
DL->getScope() == PredDL->getScope())
1658 if (!PredScope || LScope->dominates(PredScope))
1671 if (
MBB->pred_empty() &&
1678 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1722 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1724 bool isSafeForSingleLocation =
true;
1725 const MachineInstr *StartDebugMI =
nullptr;
1726 const MachineInstr *EndMI =
nullptr;
1728 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1729 const MachineInstr *
Instr = EI->getInstr();
1732 size_t Index = std::distance(EB, EI);
1733 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1740 "Forgot label before/after instruction starting a range!");
1743 if (std::next(EI) == Entries.
end()) {
1744 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1746 if (EI->isClobber())
1747 EndMI = EI->getInstr();
1749 else if (std::next(EI)->isClobber())
1753 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1755 if (EI->isDbgValue())
1761 if (EI->isDbgValue()) {
1768 if (!
Instr->isUndefDebugValue()) {
1773 if (
Instr->getDebugExpression()->isFragment())
1774 isSafeForSingleLocation =
false;
1777 StartDebugMI =
Instr;
1779 isSafeForSingleLocation =
false;
1785 if (OpenRanges.
empty())
1789 if (StartLabel == EndLabel) {
1790 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1795 for (
auto &R : OpenRanges)
1803 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1804 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1805 for (
const auto &[MBBSectionId, MBBSectionRange] :
1806 Asm->MBBSectionRanges) {
1807 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1808 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1811 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1812 MBBSectionRange.EndLabel, Values);
1815 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1822 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1823 for (
auto &
Value : CurEntry->getValues())
1825 dbgs() <<
"-----\n";
1828 auto PrevEntry = std::next(CurEntry);
1829 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1833 if (!isSafeForSingleLocation ||
1840 if (!
Asm->MF->hasBBSections())
1848 const MachineBasicBlock *RangeMBB =
nullptr;
1849 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1850 RangeMBB = &
Asm->MF->front();
1852 RangeMBB = Entries.
begin()->getInstr()->getParent();
1854 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1855 "Range MBB not found in MBBSectionRanges!");
1857 auto *NextEntry = std::next(CurEntry);
1858 auto NextRangeIt = std::next(RangeIt);
1859 while (NextEntry !=
DebugLoc.end()) {
1860 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1867 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1868 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1869 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1870 CurEntry->getValues() != NextEntry->getValues())
1872 RangeIt = NextRangeIt;
1873 NextRangeIt = std::next(RangeIt);
1874 CurEntry = NextEntry;
1875 NextEntry = std::next(CurEntry);
1885 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1887 ConcreteEntities.push_back(
1890 InfoHolder.addScopeVariable(&Scope,
1893 ConcreteEntities.push_back(
1896 InfoHolder.addScopeLabel(&Scope,
1899 return ConcreteEntities.back().get();
1907 collectVariableInfoFromMFTable(TheCU, Processed);
1910 InlinedEntity
IV =
I.first;
1915 const auto &HistoryMapEntries =
I.second;
1919 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
1922 LexicalScope *
Scope =
nullptr;
1924 if (
const DILocation *IA =
IV.second)
1934 *Scope, LocalVar,
IV.second));
1936 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1942 size_t HistSize = HistoryMapEntries.size();
1943 bool SingleValueWithClobber =
1944 HistSize == 2 && HistoryMapEntries[1].isClobber();
1945 if (HistSize == 1 || SingleValueWithClobber) {
1947 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1949 RegVar->emplace<Loc::Single>(MInsn);
1955 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
1959 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1964 if (isValidSingleLocation) {
1965 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
1976 for (
auto &Entry : Entries)
1983 InlinedEntity IL =
I.first;
1984 const MachineInstr *
MI =
I.second;
1988 LexicalScope *
Scope =
nullptr;
1991 const DILocalScope *LocalScope =
1992 Label->getScope()->getNonLexicalBlockFileScope();
1994 if (
const DILocation *IA = IL.second)
2007 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2011 for (
const DINode *DN :
SP->getRetainedNodes()) {
2014 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2016 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2018 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2020 LocalDeclsPerLS[
LS].insert(DN);
2034 if (!
MI.isBundledWithSucc())
2036 auto Suc = std::next(
MI.getIterator());
2041 assert(Suc->isBundledWithPred() &&
2042 "Call bundle instructions are out of order");
2047 if (!NoDebug && SP->areAllCallsDescribed() &&
2049 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2051 bool IsTail =
TII->isTailCall(*
MI);
2069 auto RecordLineZero = [&]() {
2073 const MDNode *Scope =
nullptr;
2074 unsigned Column = 0;
2079 recordSourceLine(0, Column, Scope, 0);
2084 unsigned LastAsmLine =
2085 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2090 if (
MI->isMetaInstruction())
2111 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2113 if (
Asm->OutStreamer->isVerboseAsm()) {
2117 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2126 bool ScopeUsesKeyInstructions =
2128 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2131 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2132 IsKey = KeyInstructions.contains(
MI);
2138 assert(
MI->getParent() == &*
MI->getMF()->begin());
2139 recordSourceLine(SP->getScopeLine(), 0, SP,
2144 bool PrevInstInSameSection =
2146 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2147 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2148 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2158 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2160 RecordSourceLine(
DL, Flags);
2173 if (LastAsmLine == 0)
2194 if (
DL.getLine() == 0 && LastAsmLine == 0)
2201 if (ScopeUsesKeyInstructions) {
2208 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2212 RecordSourceLine(
DL, Flags);
2224static std::pair<const MachineInstr *, bool>
2235 bool IsEmptyPrologue =
2236 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2241 -> std::optional<std::pair<const MachineInstr *, bool>> {
2243 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2244 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2247 if (!isFrameSetup &&
MI.getDebugLoc()) {
2253 if (
MI.getDebugLoc().getLine())
2254 return std::make_pair(&
MI, IsEmptyPrologue);
2259 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2260 NonTrivialInst = &
MI;
2262 IsEmptyPrologue =
false;
2263 return std::nullopt;
2271 auto CurBlock = MF->
begin();
2272 auto CurInst = CurBlock->begin();
2276 while (CurBlock->empty())
2277 CurInst = (++CurBlock)->begin();
2278 assert(CurInst != CurBlock->end());
2282 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2284 if (CurInst->isTerminator()) {
2293 if (CurBlock->pred_size() > 1)
2304 if (CurBlock == MF->
end())
2306 }
while (CurBlock->empty());
2307 CurInst = CurBlock->begin();
2313 if (!CurInst->isMetaInstruction()) {
2314 auto FoundInst = ExamineInst(*CurInst);
2325 if (CurInst->isCall()) {
2327 Loc &&
Loc->getLine() == 0) {
2329 unsigned ScopeLine = SP->getScopeLine();
2332 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2335 return std::make_pair(&*CurInst,
false);
2341 auto NextInst = std::next(CurInst);
2342 if (NextInst != CurInst->getParent()->end()) {
2359 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2360 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2361 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2365 return std::make_pair(
nullptr, IsEmptyPrologue);
2371 const MDNode *S,
unsigned Flags,
unsigned CUID,
2373 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2376 unsigned FileNo = 1;
2379 Fn =
Scope->getFilename();
2380 if (Line != 0 && DwarfVersion >= 4)
2385 .getOrCreateSourceID(
Scope->getFile());
2387 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2388 Discriminator, Fn, Comment);
2399 bool IsEmptyPrologue = PrologEnd.second;
2402 if (IsEmptyPrologue) {
2410 if (!
DL ||
DL->getLine() != 0)
2421 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2431 KeyInstructions.clear();
2438 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2455 for (
auto &
MBB : *MF) {
2467 for (
auto &
MI :
MBB) {
2468 if (
MI.isMetaInstruction())
2472 if (!
Loc || !
Loc->getLine())
2483 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2488 KeyInstructions.insert(Buoy);
2494 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2498 auto *InlinedAt = Loc->getInlinedAt();
2501 if (!Group || !Rank)
2505 if (BuoyAtom && BuoyAtom != Group) {
2510 auto &[CandidateRank, CandidateInsts] =
2511 GroupCandidates[{InlinedAt, Group}];
2517 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2518 (CandidateRank != 0 && !CandidateInsts.empty()));
2520 assert(Rank &&
"expected nonzero rank");
2523 if (CandidateRank && CandidateRank < Rank)
2530 if (CandidateRank == Rank)
2534 else if (CandidateRank > Rank)
2535 CandidateInsts.clear();
2539 CandidateInsts.push_back(Buoy);
2540 CandidateRank = Rank;
2548 if (CandidateInsts.empty())
2554 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2555 for (
auto *
I : Insts)
2556 KeyInstructions.insert(
I);
2564 ForceIsStmtInstrs.clear();
2596 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2597 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2600 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2603 for (
auto &
MI :
MBB) {
2604 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2617 for (
auto *
MBB : PredMBBsToExamine) {
2618 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2619 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2620 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2622 MachineInstr *
MI = MBBInstrIt->second;
2623 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2625 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2626 ForceIsStmtInstrs.insert(
MI);
2633 CheckMBBEdge(Succ, 0);
2639 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2647 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2654 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2657 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2658 CheckMBBEdge(FBB, FBBLine);
2682 unsigned LastLine = 0;
2684 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2685 LastLine =
DL->getLine();
2690 for (
auto *Succ : SuccessorBBs)
2691 CheckMBBEdge(Succ, LastLine);
2706 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2707 ?
Asm->OutStreamer->emitLineTableLabel()
2710 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2715 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2721 computeKeyInstructions(MF);
2722 findForceIsStmtInstrs(MF);
2730 if (
Asm->OutStreamer->hasRawTextSupport())
2734 return CU.getUniqueID();
2738 const auto &CURanges =
CU->getRanges();
2739 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2742 LineTable.getMCLineSections().addEndEntry(
2743 const_cast<MCSymbol *
>(CURanges.back().End));
2763 "endFunction should be called with the same function as beginFunction");
2766 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2778 collectEntityInfo(TheCU, SP, Processed);
2782 for (
const auto &R :
Asm->MBBSectionRanges)
2783 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2790 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2791 for (
const auto &R :
Asm->MBBSectionRanges)
2794 assert(InfoHolder.getScopeVariables().empty());
2801 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2805 for (
const DINode *DN : SP->getRetainedNodes()) {
2808 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2809 assert(LexS &&
"Expected the LexicalScope to be created.");
2812 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2818 LocalDeclsPerLS[LS].insert(DN);
2821 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2822 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2824 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2827 ProcessedSPNodes.insert(SP);
2831 if (!
LScopes.getAbstractScopesList().empty() &&
2833 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2834 FunctionLineTableLabel);
2836 FunctionLineTableLabel =
nullptr;
2839 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2845 InfoHolder.getScopeVariables().clear();
2846 InfoHolder.getScopeLabels().clear();
2847 LocalDeclsPerLS.clear();
2854void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2866void DwarfDebug::emitDebugInfo() {
2872void DwarfDebug::emitAbbreviations() {
2873 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2875 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2878void DwarfDebug::emitStringOffsetsTableHeader() {
2879 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2881 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2885template <
typename AccelTableT>
2886void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2888 Asm->OutStreamer->switchSection(Section);
2894void DwarfDebug::emitAccelDebugNames() {
2896 if (getUnits().
empty())
2903void DwarfDebug::emitAccelNames() {
2904 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
2910void DwarfDebug::emitAccelObjC() {
2911 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
2916void DwarfDebug::emitAccelNamespaces() {
2917 emitAccel(AccelNamespace,
2918 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
2923void DwarfDebug::emitAccelTypes() {
2924 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
2954 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2962 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2969 case dwarf::DW_TAG_class_type:
2970 case dwarf::DW_TAG_structure_type:
2971 case dwarf::DW_TAG_union_type:
2972 case dwarf::DW_TAG_enumeration_type:
2977 case dwarf::DW_TAG_typedef:
2978 case dwarf::DW_TAG_base_type:
2979 case dwarf::DW_TAG_subrange_type:
2980 case dwarf::DW_TAG_template_alias:
2982 case dwarf::DW_TAG_namespace:
2984 case dwarf::DW_TAG_subprogram:
2986 case dwarf::DW_TAG_variable:
2988 case dwarf::DW_TAG_enumerator:
2998void DwarfDebug::emitDebugPubSections() {
2999 for (
const auto &NU : CUMap) {
3000 DwarfCompileUnit *TheU = NU.second;
3007 Asm->OutStreamer->switchSection(
3008 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3009 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3010 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3012 Asm->OutStreamer->switchSection(
3013 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3014 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3015 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3021 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3022 CU.getDebugSectionOffset());
3024 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3027void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3035 "pub" + Name,
"Length of Public " + Name +
" Info");
3037 Asm->OutStreamer->AddComment(
"DWARF Version");
3040 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3041 emitSectionReference(*TheU);
3043 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3048 for (
const auto &GI : Globals)
3051 return A.second->getOffset() <
B.second->getOffset();
3053 for (
const auto &[Name, Entity] : Vec) {
3054 Asm->OutStreamer->AddComment(
"DIE offset");
3055 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3059 Asm->OutStreamer->AddComment(
3065 Asm->OutStreamer->AddComment(
"External Name");
3066 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3069 Asm->OutStreamer->AddComment(
"End Mark");
3070 Asm->emitDwarfLengthOrOffset(0);
3071 Asm->OutStreamer->emitLabel(EndLabel);
3075void DwarfDebug::emitDebugStr() {
3076 MCSection *StringOffsetsSection =
nullptr;
3078 emitStringOffsetsTableHeader();
3079 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3081 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3082 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3083 StringOffsetsSection,
true);
3089 auto &&Comments = DebugLocs.getComments(Entry);
3090 auto Comment = Comments.begin();
3091 auto End = Comments.end();
3098 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3100 DebugLocs.getBytes(Entry).size()),
3101 Asm->getDataLayout().isLittleEndian(), PtrSize);
3106 for (
const auto &
Op : Expr) {
3107 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3108 "3 operand ops not yet supported");
3109 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3110 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3112 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3113 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3115 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3117 for (
unsigned J = 0; J <
Length; ++J)
3122 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3133 auto *DIExpr =
Value.getExpression();
3139 if (DIExpr && DIExpr->isEntryValue()) {
3156 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3159 if (Entry.isInt()) {
3160 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3162 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3163 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3167 }
else if (Entry.isLocation()) {
3169 if (Location.isIndirect())
3175 }
else if (Entry.isTargetIndexLocation()) {
3181 }
else if (Entry.isConstantFP()) {
3184 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3185 }
else if (Entry.getConstantFP()
3188 .getBitWidth() <= 64 ) {
3190 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3193 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3194 << Entry.getConstantFP()
3205 if (!
Value.isVariadic()) {
3206 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3215 return Entry.isLocation() && !Entry.getLoc().getReg();
3220 std::move(ExprCursor),
3221 [EmitValueLocEntry, &
Value](
unsigned Idx,
3223 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3231 assert(!Values.empty() &&
3232 "location list entries without values are redundant");
3233 assert(Begin != End &&
"unexpected location list entry with empty range");
3238 if (
Value.isFragment()) {
3241 return P.isFragment();
3242 }) &&
"all values are expected to be fragments");
3245 for (
const auto &Fragment : Values)
3249 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3260 Asm->OutStreamer->AddComment(
"Loc expr size");
3262 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3263 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3264 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3283 Asm->OutStreamer->AddComment(
"Offset entry count");
3289 Asm->getDwarfOffsetByteSize());
3303 Asm->OutStreamer->AddComment(
"Offset entry count");
3304 Asm->emitInt32(DebugLocs.getLists().size());
3305 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3307 for (
const auto &List : DebugLocs.getLists())
3308 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3309 Asm->getDwarfOffsetByteSize());
3314template <
typename Ranges,
typename PayloadEmitter>
3318 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3320 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3321 auto Size = Asm->MAI->getCodePointerSize();
3325 Asm->OutStreamer->emitLabel(Sym);
3332 for (
const auto &
Range : R)
3333 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3335 const MCSymbol *CUBase =
CU.getBaseAddress();
3336 bool BaseIsSet =
false;
3337 for (
const auto &
P : SectionRanges) {
3338 auto *
Base = CUBase;
3339 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB()) ||
3340 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3350 }
else if (!
Base && ShouldUseBaseAddress) {
3351 const MCSymbol *Begin =
P.second.front()->Begin;
3356 Asm->OutStreamer->emitIntValue(-1,
Size);
3357 Asm->OutStreamer->AddComment(
" base address");
3358 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3359 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3365 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3366 Asm->emitInt8(BaseAddressx);
3367 Asm->OutStreamer->AddComment(
" base address index");
3370 }
else if (BaseIsSet && !UseDwarf5) {
3373 Asm->OutStreamer->emitIntValue(-1,
Size);
3374 Asm->OutStreamer->emitIntValue(0,
Size);
3377 for (
const auto *RS :
P.second) {
3380 assert(Begin &&
"Range without a begin symbol?");
3381 assert(End &&
"Range without an end symbol?");
3385 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3386 Asm->emitInt8(OffsetPair);
3387 Asm->OutStreamer->AddComment(
" starting offset");
3388 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3389 Asm->OutStreamer->AddComment(
" ending offset");
3390 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3392 Asm->emitLabelDifference(Begin,
Base,
Size);
3393 Asm->emitLabelDifference(End,
Base,
Size);
3395 }
else if (UseDwarf5) {
3403 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3404 Asm->emitInt8(StartxEndx);
3405 Asm->OutStreamer->AddComment(
" start index");
3407 Asm->OutStreamer->AddComment(
" end index");
3410 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3411 Asm->emitInt8(StartxLength);
3412 Asm->OutStreamer->AddComment(
" start index");
3414 Asm->OutStreamer->AddComment(
" length");
3415 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3418 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3419 Asm->OutStreamer->emitSymbolValue(End,
Size);
3426 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3430 Asm->OutStreamer->emitIntValue(0,
Size);
3431 Asm->OutStreamer->emitIntValue(0,
Size);
3439 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3440 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3443 DD.emitDebugLocEntryLocation(E, List.CU);
3447void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3448 if (DebugLocs.getLists().empty())
3451 Asm->OutStreamer->switchSection(Sec);
3457 for (
const auto &
List : DebugLocs.getLists())
3461 Asm->OutStreamer->emitLabel(TableEnd);
3465void DwarfDebug::emitDebugLoc() {
3468 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3469 :
Asm->getObjFileLowering().getDwarfLocSection());
3473void DwarfDebug::emitDebugLocDWO() {
3476 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3481 for (
const auto &
List : DebugLocs.getLists()) {
3482 Asm->OutStreamer->switchSection(
3483 Asm->getObjFileLowering().getDwarfLocDWOSection());
3484 Asm->OutStreamer->emitLabel(
List.Label);
3486 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3495 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3496 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3497 Asm->emitULEB128(idx);
3503 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3513void DwarfDebug::emitDebugARanges() {
3514 if (ArangeLabels.empty())
3521 for (
const SymbolCU &SCU : ArangeLabels) {
3522 if (SCU.Sym->isInSection()) {
3524 MCSection *Section = &SCU.Sym->getSection();
3525 SectionMap[Section].push_back(SCU);
3530 SectionMap[
nullptr].push_back(SCU);
3534 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3536 for (
auto &
I : SectionMap) {
3544 for (
const SymbolCU &Cur :
List) {
3546 Span.
Start = Cur.Sym;
3549 Spans[Cur.CU].push_back(Span);
3555 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3559 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3560 const SymbolCU &Prev =
List[n - 1];
3561 const SymbolCU &Cur =
List[n];
3564 if (Cur.
CU != Prev.
CU) {
3566 Span.
Start = StartSym;
3569 Spans[Prev.
CU].push_back(Span);
3576 Asm->OutStreamer->switchSection(
3577 Asm->getObjFileLowering().getDwarfARangesSection());
3579 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3582 std::vector<DwarfCompileUnit *> CUs;
3583 for (
const auto &it : Spans) {
3584 DwarfCompileUnit *
CU = it.first;
3589 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3590 return A->getUniqueID() <
B->getUniqueID();
3594 for (DwarfCompileUnit *
CU : CUs) {
3595 std::vector<ArangeSpan> &
List = Spans[
CU];
3598 if (
auto *Skel =
CU->getSkeleton())
3602 unsigned ContentSize =
3604 Asm->getDwarfOffsetByteSize() +
3609 unsigned TupleSize = PtrSize * 2;
3613 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3616 ContentSize += (
List.size() + 1) * TupleSize;
3619 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3620 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3622 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3623 emitSectionReference(*
CU);
3624 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3625 Asm->emitInt8(PtrSize);
3626 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3629 Asm->OutStreamer->emitFill(Padding, 0xff);
3631 for (
const ArangeSpan &Span :
List) {
3632 Asm->emitLabelReference(Span.Start, PtrSize);
3639 auto SizeRef = SymSize.find(Span.Start);
3640 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3641 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3646 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3649 Size = SizeRef->second;
3651 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3655 Asm->OutStreamer->AddComment(
"ARange terminator");
3656 Asm->OutStreamer->emitIntValue(0, PtrSize);
3657 Asm->OutStreamer->emitIntValue(0, PtrSize);
3665 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3666 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3668 List.CU->getCUNode()->getRangesBaseAddress() ||
3680 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3683 Asm->OutStreamer->switchSection(Section);
3693 Asm->OutStreamer->emitLabel(TableEnd);
3698void DwarfDebug::emitDebugRanges() {
3699 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3701 emitDebugRangesImpl(Holder,
3703 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3704 :
Asm->getObjFileLowering().getDwarfRangesSection());
3707void DwarfDebug::emitDebugRangesDWO() {
3708 emitDebugRangesImpl(InfoHolder,
3709 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3716 enum HeaderFlagMask {
3717#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3718#include "llvm/BinaryFormat/Dwarf.def"
3720 Asm->OutStreamer->AddComment(
"Macro information version");
3721 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3724 if (Asm->isDwarf64()) {
3725 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3726 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3728 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3729 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3731 Asm->OutStreamer->AddComment(
"debug_line_offset");
3733 Asm->emitDwarfLengthOrOffset(0);
3735 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3738void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3739 for (
auto *MN : Nodes) {
3743 emitMacroFile(*
F, U);
3749void DwarfDebug::emitMacro(
DIMacro &M) {
3750 StringRef
Name =
M.getName();
3751 StringRef
Value =
M.getValue();
3757 if (UseDebugMacroSection) {
3760 ? dwarf::DW_MACRO_define_strx
3761 : dwarf::DW_MACRO_undef_strx;
3764 Asm->OutStreamer->AddComment(
"Line Number");
3765 Asm->emitULEB128(
M.getLine());
3766 Asm->OutStreamer->AddComment(
"Macro String");
3768 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3771 ? dwarf::DW_MACRO_GNU_define_indirect
3772 : dwarf::DW_MACRO_GNU_undef_indirect;
3775 Asm->OutStreamer->AddComment(
"Line Number");
3776 Asm->emitULEB128(
M.getLine());
3777 Asm->OutStreamer->AddComment(
"Macro String");
3778 Asm->emitDwarfSymbolReference(
3779 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3783 Asm->emitULEB128(
M.getMacinfoType());
3784 Asm->OutStreamer->AddComment(
"Line Number");
3785 Asm->emitULEB128(
M.getLine());
3786 Asm->OutStreamer->AddComment(
"Macro String");
3787 Asm->OutStreamer->emitBytes(Str);
3788 Asm->emitInt8(
'\0');
3792void DwarfDebug::emitMacroFileImpl(
3794 StringRef (*MacroFormToString)(
unsigned Form)) {
3796 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3797 Asm->emitULEB128(StartFile);
3798 Asm->OutStreamer->AddComment(
"Line Number");
3800 Asm->OutStreamer->AddComment(
"File Number");
3803 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3805 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3807 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3809 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3810 Asm->emitULEB128(EndFile);
3817 if (UseDebugMacroSection)
3819 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3826void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3827 for (
const auto &
P : CUMap) {
3828 auto &TheCU = *
P.second;
3830 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3832 DIMacroNodeArray Macros = CUNode->getMacros();
3835 Asm->OutStreamer->switchSection(Section);
3836 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3837 if (UseDebugMacroSection)
3839 handleMacroNodes(Macros, U);
3840 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3846void DwarfDebug::emitDebugMacinfo() {
3847 auto &ObjLower =
Asm->getObjFileLowering();
3848 emitDebugMacinfoImpl(UseDebugMacroSection
3849 ? ObjLower.getDwarfMacroSection()
3850 : ObjLower.getDwarfMacinfoSection());
3853void DwarfDebug::emitDebugMacinfoDWO() {
3854 auto &ObjLower =
Asm->getObjFileLowering();
3855 emitDebugMacinfoImpl(UseDebugMacroSection
3856 ? ObjLower.getDwarfMacroDWOSection()
3857 : ObjLower.getDwarfMacinfoDWOSection());
3862void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3863 std::unique_ptr<DwarfCompileUnit> NewU) {
3865 if (!CompilationDir.empty())
3866 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3867 addGnuPubAttributes(*NewU, Die);
3869 SkeletonHolder.addUnit(std::move(NewU));
3874 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3875 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3877 DwarfCompileUnit &NewCU = *OwnedUnit;
3878 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3885 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3892void DwarfDebug::emitDebugInfoDWO() {
3895 InfoHolder.emitUnits(
true);
3900void DwarfDebug::emitDebugAbbrevDWO() {
3902 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3905void DwarfDebug::emitDebugLineDWO() {
3907 SplitTypeUnitFileTable.Emit(
3908 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3909 Asm->getObjFileLowering().getDwarfLineDWOSection());
3912void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3914 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
3915 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
3916 InfoHolder.getStringOffsetsStartSym());
3922void DwarfDebug::emitDebugStrDWO() {
3924 emitStringOffsetsTableHeaderDWO();
3926 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
3927 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
3932void DwarfDebug::emitDebugAddr() {
3933 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
3939 const DICompileUnit *DIUnit =
CU.getCUNode();
3940 SplitTypeUnitFileTable.maybeSetRootFile(
3943 return &SplitTypeUnitFileTable;
3954 return Result.high();
3963 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
3966 auto Ins = TypeSignatures.try_emplace(CTy);
3968 CU.addDIETypeSignature(RefDie, Ins.first->second);
3973 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3974 AddrPool.resetUsedFlag();
3976 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
3977 CU,
Asm,
this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(
CU));
3980 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3982 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3983 CU.getSourceLanguage());
3987 Ins.first->second = Signature;
3995 if (!CompilationDir.empty())
3996 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
3997 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
3998 Asm->TM.Options.MCOptions.SplitDwarfFile);
4002 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4003 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4008 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4009 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4012 CU.applyStmtList(UnitDie);
4023 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4024 TypeUnitsUnderConstruction.clear();
4028 if (AddrPool.hasBeenUsed()) {
4029 AccelTypeUnitsDebugNames.clear();
4033 for (
const auto &
TU : TypeUnitsToAdd)
4034 TypeSignatures.erase(
TU.second);
4042 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4048 for (
auto &
TU : TypeUnitsToAdd) {
4049 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4054 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4056 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4059 AccelTypeUnitsDebugNames.convertDieToOffset();
4060 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4061 AccelTypeUnitsDebugNames.clear();
4064 CU.addDIETypeSignature(RefDie, Signature);
4071template <
typename DataT>
4072void DwarfDebug::addAccelNameImpl(
4077 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4094 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4095 ((&Current == &AccelDebugNames) &&
4096 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4097 "Kind is CU but TU is being processed.");
4098 assert(((&Current == &AccelDebugNames) ||
4099 ((&Current == &AccelTypeUnitsDebugNames) &&
4100 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4101 "Kind is TU but CU is being processed.");
4104 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4105 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4119 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4128 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4135 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4141 const DIE &Die,
char Flags) {
4142 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4146 return Asm->OutStreamer->getContext().getDwarfVersion();
4150 if (
Asm->getDwarfVersion() >= 4)
4151 return dwarf::Form::DW_FORM_sec_offset;
4152 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4153 "DWARF64 is not defined prior DWARFv3");
4154 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4155 : dwarf::Form::DW_FORM_data4;
4159 return SectionLabels.lookup(S);
4163 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4168std::optional<MD5::MD5Result>
4172 return std::nullopt;
4173 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4175 return std::nullopt;
4180 std::string ChecksumString =
fromHex(Checksum->Value);
4197 if (
MBB.getAlignment() ==
Align(1))
4200 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4207 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4208 if (PrevLoc.getLine()) {
4209 Asm->OutStreamer->emitDwarfLocDirective(
4210 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4212 Asm->OutStreamer->getCurrentSectionOnly());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Expected< bool > hasObjCCategory(BitstreamCursor &Stream)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isObjCClass(StringRef Name)
static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))
static void finishCallSiteParams(ValT Val, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > DescribedParams, ParamSet &Params)
Emit call site parameter entries that are described by the given value and debug expression.
static cl::opt< bool > UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden, cl::desc("Emit the GNU .debug_macro format with DWARF <5"), cl::init(false))
static cl::opt< DefaultOnOff > DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden, cl::desc("Use inlined strings rather than string section."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static bool validThroughout(LexicalScopes &LScopes, const MachineInstr *DbgValue, const MachineInstr *RangeEnd, const InstructionOrdering &Ordering)
Determine whether a singular DBG_VALUE is valid for the entirety of its enclosing lexical scope.
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
static cl::opt< LinkageNameOption > DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, cl::desc("Which DWARF linkage-name attributes to emit."), cl::values(clEnumValN(DefaultLinkageNames, "Default", "Default for platform"), clEnumValN(AllLinkageNames, "All", "All"), clEnumValN(AbstractLinkageNames, "Abstract", "Abstract subprograms")), cl::init(DefaultLinkageNames))
static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > ParamsToAdd)
Add Reg to the worklist, if it's not already present, and mark that the given parameter registers' va...
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
SmallSet< MCRegUnit, 16 > ClobberedRegUnitSet
Container for the set of register units known to be clobbered on the path to a call site.
static cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))
Set to false to ignore Key Instructions metadata.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr)
static cl::opt< DefaultOnOff > DwarfOpConvert("dwarf-op-convert", cl::Hidden, cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static std::pair< const MachineInstr *, bool > findPrologueEndLoc(const MachineFunction *MF)
static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)
Try to interpret values loaded into registers that forward parameters for CallMI.
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))
MapVector< uint64_t, SmallVector< FwdRegParamInfo, 2 > > FwdRegWorklist
Register worklist for finding call site values.
static cl::opt< bool > UseDwarfRangesBaseAddressSpecifier("use-dwarf-ranges-base-address-specifier", cl::Hidden, cl::desc("Use base address specifiers in debug_ranges"), cl::init(false))
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
static const DILocalScope * getRetainedNodeScope(const MDNode *N)
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 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))
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
static bool isCopy(MachineInstr *MI)
static const uint32_t IV[8]
Class recording the (high level) value of a variable.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
This class is intended to be used as a driving class for all asm writers.
DwarfDebug * getDwarfDebug()
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
uint16_t getDwarfVersion() const
virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=0
virtual unsigned emitDIERef(const DIE &D)=0
Basic type, like 'int' or 'float'.
bool getDebugInfoForProfiling() const
bool isDebugDirectivesOnly() const
StringRef getFlags() const
static LLVM_ABI std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
unsigned getRuntimeVersion() const
bool getSplitDebugInlining() const
StringRef getSysRoot() const
StringRef getProducer() const
DISourceLanguageName getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static LLVM_ABI std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
A structured debug information entry.
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
LLVM_ABI const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
dwarf::Tag getTag() const
Holds a DIExpression and keeps track of how many operands have been consumed so far.
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
LLVM_ABI bool isValid() const
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
bool hasVersionedName() const
Subprogram description. Uses SubclassData1.
DIScope * getScope() const
Encoding
Size and signedness of expression operations' operands.
Used for tracking debug info about call site parameters.
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
SmallVector< Entry, 4 > Entries
A single location or constant within a variable location description, with either a single entry (wit...
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
const DILocalVariable * getVariable() const
const DIType * getType() const
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
AsmPrinter * Asm
Target of debug info emission.
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
MachineModuleInfo * MMI
Collected machine module information.
DebugLoc PrevInstLoc
Previous instruction's location information.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
DebugHandlerBase(AsmPrinter *A)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
const MachineBasicBlock * PrevInstBB
void requestLabelAfterInsn(const MachineInstr *MI)
Ensure that a label will be emitted after MI.
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
DbgLabelInstrMap DbgLabels
Mapping of inlined labels and DBG_LABEL machine instruction.
void beginModule(Module *M) override
const InstructionOrdering & getInstOrdering() const
void requestLabelBeforeInsn(const MachineInstr *MI)
Ensure that a label will be emitted before MI.
const MachineBasicBlock * EpilogBeginBlock
This block includes epilogue instructions.
const MachineInstr * PrologEndLoc
This location indicates end of function prologue and beginning of function body.
DwarfExpression implementation for .debug_loc entries.
void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU)
Lower this entry into a DWARF expression.
Builder for DebugLocStream entries.
Builder for DebugLocStream lists.
ArrayRef< Entry > getEntries(const List &L) const
LLVM_ABI unsigned getLine() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
DwarfCompileUnit * getSkeleton() const
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
const StringMap< const DIE * > & getGlobalNames() const
DbgEntity * getExistingAbstractEntity(const DINode *Node)
const StringMap< const DIE * > & getGlobalTypes() const
bool hasDwarfPubSections() const
Collects and handles dwarf debug information.
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
bool emitDebugEntryValues() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind)
Sets the current DWARF5AccelTable to use.
bool alwaysUseRanges(const DwarfCompileUnit &) const
Returns whether range encodings should be used for single entry range lists.
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
void skippedNonDebugFunction() override
void addArangeLabel(SymbolCU SCU)
Add a label so that arange data can be generated for it.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
AddressPool & getAddressPool()
DWARF5AccelTable & getCurrentDWARF5AccelTable()
Returns either CU or TU DWARF5AccelTable.
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
bool shareAcrossDWOCUs() const
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)
Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
const 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.
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)
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.
void endModule() override
Emit all Dwarf sections that should come after the content.
void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)
void beginCodeAlignment(const MachineBasicBlock &MBB) override
Process beginning of code alignment.
DwarfDebug(AsmPrinter *A)
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
void finalize()
This needs to be called last to commit any pending changes.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void setMemoryLocationKind()
Lock this down to become a memory location description.
std::optional< uint8_t > TagOffset
void addBooleanConstant(int64_t Value)
Emit a boolean constant.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void addSignedConstant(int64_t Value)
Emit a signed constant.
virtual void commitTemporaryBuffer()=0
Commit the data stored in the temporary buffer to the main output.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
virtual void enableTemporaryBuffer()=0
Start emitting data to the temporary buffer.
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void setRnglistsTableBaseSym(MCSymbol *Sym)
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
const SmallVectorImpl< RangeSpanList > & getRangeLists() const
getRangeLists - Get the vector of range lists.
MCSymbol * getStringOffsetsStartSym() const
MCSymbol * getRnglistsTableBaseSym() const
DwarfStringPool & getStringPool()
Returns the string pool.
void emitAbbrevs(MCSection *)
Emit a set of abbreviations to the specific section.
void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)
Emit all of the strings to the section given.
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
LLVM_ABI_FOR_TEST EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
LLVM_ABI_FOR_TEST void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)
void setTypeSignature(uint64_t Signature)
void setType(const DIE *Ty)
This dwarf writer support class manages information associated with a source file.
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)
Creates type DIE with specific context.
const DICompileUnit * getCUNode() const
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
unsigned getUniqueID() const
Gets Unique ID for this unit.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool isTailCall(const MachineInstr &MI) const override
Record instruction ordering so we can query their relative positions within a function.
This class is used to track scope information.
SmallVectorImpl< InsnRange > & getRanges()
const DILocalScope * getScopeNode() const
This class provides interface to collect and use lexical scoping information from machine instruction...
LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)
Find lexical scope, either regular or inlined, for the given DebugLoc.
LexicalScope * findAbstractScope(const DILocalScope *N)
Find an abstract scope or return null.
Single(DbgValueLoc ValueLoc)
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
MCSection * getDwarfLoclistsSection() const
MCSection * getDwarfRangesSection() const
MCSection * getDwarfMacroSection() const
MCSection * getDwarfMacinfoDWOSection() const
MCSection * getDwarfMacinfoSection() const
MCSection * getDwarfMacroDWOSection() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol * getBeginSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
uint32_t getIndex() const
Get the (implementation defined) index.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
succ_iterator succ_begin()
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const CallSiteInfoMap & getCallSitesInfo() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
unsigned getNumOperands() const
Retuns the total number of operands.
bool hasDelaySlot(QueryType Type=AnyInBundle) const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
mop_range uses()
Returns all operands which may be register uses.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool empty() const
Determine if the SetVector is empty or not.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void insert_range(Range &&R)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
const Triple & getTargetTriple() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
Triple - Helper class for working with autoconf configuration names.
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI StringRef RangeListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
LLVM_ABI StringRef MacroString(unsigned Encoding)
LLVM_ABI StringRef LocListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GnuMacroString(unsigned Encoding)
LLVM_ABI StringRef MacinfoString(unsigned Encoding)
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
bool isCPlusPlus(SourceLanguage S)
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
@ DWARF_VERSION
Other constants.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
FunctionAddr VTableAddr Value
MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)
Returns an iterator to the first instruction in the bundle containing I.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation. The return string is half the size of ...
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)
auto cast_or_null(const Y &Val)
auto unique(Range &&R, Predicate P)
bool isa_and_nonnull(const Y &Val)
SmallVector< DbgCallSiteParam, 4 > ParamSet
Collection used for storing debug call site parameters.
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
AccelTableKind
The kind of accelerator tables we should emit.
@ Default
Platform default.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
@ Dwarf
DWARF v5 .debug_names.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Global
Append to llvm.global_dtors.
@ Ref
The access may reference the value stored in memory.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
DebuggerKind
Identify a debugger for "tuning" the debug info.
@ SCE
Tune debug info for SCE targets (e.g. PS4).
@ DBX
Tune debug info for dbx.
@ Default
No specific tuning requested.
@ GDB
Tune debug info for gdb.
@ LLDB
Tune debug info for lldb.
Implement std::hash so that hash_code can be used in STL containers.
Represents a parameter whose call site value can be described by applying a debug expression to a reg...
uint64_t ParamReg
The described parameter register.
const DIExpression * Expr
Debug expression that has been built up when walking through the instruction chain that produces the ...
This struct is a compact representation of a valid (non-zero power of two) alignment.
A pair of GlobalVariable and DIExpression.
Represents an entry-value location, or a fragment of one.
void addFrameIndexExpr(const DIExpression *Expr, int FI)
std::set< FrameIndexExpr > FrameIndexExprs
const std::set< FrameIndexExpr > & getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
A MapVector that performs no allocations if smaller than a certain size.
Helper used to pair up a symbol and its DWARF compile unit.
This struct describes target specific location.
Describes an entry of the various gnu_pub* debug sections.