65#define DEBUG_TYPE "dwarfdebug"
67STATISTIC(NumCSParams,
"Number of dbg call site params created");
70 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
80 cl::desc(
"Generate DWARF4 type units."),
91 cl::desc(
"Make an absence of debug location information explicit."),
99 "Default for platform"),
100 clEnumValN(AccelTableKind::None,
"Disable",
"Disabled."),
101 clEnumValN(AccelTableKind::Apple,
"Apple",
"Apple"),
102 clEnumValN(AccelTableKind::Dwarf,
"Dwarf",
"DWARF")),
107 cl::desc(
"Use inlined strings rather than string section."),
115 cl::desc(
"Disable emission .debug_ranges section."),
120 cl::desc(
"Use sections+offset as references rather than labels."),
127 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
132 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
145 cl::desc(
"Which DWARF linkage-name attributes to emit."),
147 "Default for platform"),
150 "Abstract subprograms")),
155 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
156 "address pool entry sharing to reduce relocations/object size"),
158 "Default address minimization strategy"),
159 clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges,
"Ranges",
160 "Use rnglists for contiguous ranges if that allows "
161 "using a pre-existing base address"),
162 clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions,
164 "Use exprloc addrx+offset expressions for any "
165 "address with a prior base address"),
166 clEnumValN(DwarfDebug::MinimizeAddrInV5::Form,
"Form",
167 "Use addrx+offset extension form for any address "
168 "with a prior base address"),
169 clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled,
"Disabled",
171 cl::init(DwarfDebug::MinimizeAddrInV5::Default));
175void DebugLocDwarfExpression::emitOp(uint8_t
Op,
const char *Comment) {
181void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
189void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
193void DebugLocDwarfExpression::emitBaseTypeRef(
uint64_t Idx) {
204void DebugLocDwarfExpression::enableTemporaryBuffer() {
205 assert(!IsBuffering &&
"Already buffering?");
211void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering =
false; }
213unsigned DebugLocDwarfExpression::getTemporaryBufferSize() {
214 return TmpBuf ? TmpBuf->Bytes.size() : 0;
217void DebugLocDwarfExpression::commitTemporaryBuffer() {
220 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
221 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
222 ? TmpBuf->Comments[
Byte.index()].c_str()
226 TmpBuf->Bytes.clear();
227 TmpBuf->Comments.clear();
238 const bool IsVariadic = !SingleLocExprOpt;
241 if (!IsVariadic && !
MI->isNonListDebugValue()) {
242 assert(
MI->getNumDebugOperands() == 1 &&
243 "Mismatched DIExpression and debug operands for debug instruction.");
244 Expr = *SingleLocExprOpt;
251 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
253 }
else if (
Op.isTargetIndex()) {
256 }
else if (
Op.isImm())
258 else if (
Op.isFPImm())
260 else if (
Op.isCImm())
265 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
269 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
270 return Fragment ? Fragment->OffsetInBits : 0;
284 Expr(ValueLoc.getExpression()) {
293 return FrameIndexExprs;
297 FrameIndexExprs.insert({FI, Expr});
298 assert((FrameIndexExprs.size() == 1 ||
301 return FIE.Expr && FIE.Expr->isFragment();
303 "conflicting locations for variable");
307 bool GenerateTypeUnits,
315 if (GenerateTypeUnits)
321 if (DwarfVersion >= 5)
331 InfoHolder(
A,
"info_string", DIEValueAllocator),
332 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
333 IsDarwin(
A->
TM.getTargetTriple().isOSDarwin()) {
344 else if (TT.isOSAIX())
350 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
354 UseLocSection = !TT.isNVPTX();
368 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
374 bool Dwarf64 = DwarfVersion >= 3 &&
384 TT.isOSBinFormatELF()) ||
385 TT.isOSBinFormatXCOFF();
387 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
394 UseSectionsAsReferences = TT.isNVPTX();
399 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
400 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
404 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
411 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
413 UseDWARF2Bitfields = DwarfVersion < 4;
419 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
427 UseDebugMacroSection =
436 if (DwarfVersion >= 5)
448 return Name.startswith(
"+") ||
Name.startswith(
"-");
455 return Name.contains(
") ");
461 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
466 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
467 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
471 return In.slice(In.find(
' ') + 1, In.find(
']'));
482 if (!SP->isDefinition())
491 if (SP->getLinkageName() !=
"" && SP->
getName() != SP->getLinkageName() &&
511 if (Scope->isAbstractScope())
529 if (
auto *SkelCU =
CU.getSkeleton())
530 if (
CU.getCUNode()->getSplitDebugInlining())
538void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
540 assert(Scope && Scope->getScopeNode());
541 assert(Scope->isAbstractScope());
542 assert(!Scope->getInlinedAt());
544 auto *SP = cast<DISubprogram>(Scope->getScopeNode());
552 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
553 if (
auto *SkelCU =
CU.getSkeleton()) {
555 .constructAbstractSubprogramScopeDIE(Scope);
556 if (
CU.getCUNode()->getSplitDebugInlining())
557 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
559 CU.constructAbstractSubprogramScopeDIE(Scope);
594template <
typename ValT>
598 for (
auto Param : DescribedParams) {
599 bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0;
614 "Combined debug expression is invalid");
629 auto I = Worklist.
insert({Reg, {}});
630 auto &ParamsForFwdReg =
I.first->second;
631 for (
auto Param : ParamsToAdd) {
634 return D.ParamReg == Param.ParamReg;
636 "Same parameter described twice by forwarding reg");
643 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
686 if (
MI.isDebugInstr())
690 if (MO.getReg().isPhysical()) {
691 for (
auto &FwdReg : ForwardedRegWorklist)
692 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
693 Defs.
insert(FwdReg.first);
695 NewClobberedRegUnits.
insert(Unit);
703 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
704 if (FwdRegDefs.
empty()) {
706 ClobberedRegUnits.
insert(NewClobberedRegUnits.
begin(),
707 NewClobberedRegUnits.
end());
714 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
715 for (
auto &RegUnit : ClobberedRegUnits)
716 if (
TRI.hasRegUnit(Reg, RegUnit))
721 for (
auto ParamFwdReg : FwdRegDefs) {
722 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
723 if (ParamValue->first.isImm()) {
724 int64_t Val = ParamValue->first.getImm();
726 ForwardedRegWorklist[ParamFwdReg], Params);
727 }
else if (ParamValue->first.isReg()) {
728 Register RegLoc = ParamValue->first.getReg();
729 Register SP = TLI.getStackPointerRegisterToSaveRestore();
731 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
732 if (!IsRegClobberedInMeantime(RegLoc) &&
733 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
736 ForwardedRegWorklist[ParamFwdReg], Params);
745 ForwardedRegWorklist[ParamFwdReg]);
752 for (
auto ParamFwdReg : FwdRegDefs)
753 ForwardedRegWorklist.
erase(ParamFwdReg);
756 ClobberedRegUnits.
insert(NewClobberedRegUnits.
begin(),
757 NewClobberedRegUnits.
end());
761 for (
auto &New : TmpWorklistItems)
763 TmpWorklistItems.
clear();
780 if (ForwardedRegWorklist.
empty())
787 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
798 auto CallFwdRegsInfo = CalleesMap.
find(CallMI);
801 if (CallFwdRegsInfo == CalleesMap.end())
815 for (
const auto &ArgReg : CallFwdRegsInfo->second) {
817 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
819 assert(InsertedReg &&
"Single register used to forward two arguments?");
824 for (
const auto &MO : CallMI->
uses())
825 if (MO.isReg() && MO.isUndef())
826 ForwardedRegWorklist.
erase(MO.getReg());
845 assert(std::next(Suc) == BundleEnd &&
846 "More than one instruction in call delay slot");
860 if (ShouldTryEmitEntryVals) {
864 for (
auto &RegEntry : ForwardedRegWorklist) {
871void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
876 if (!SP.areAllCallsDescribed() || !SP.isDefinition())
883 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
886 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
890 if (!
MI.isBundledWithSucc())
892 auto Suc = std::next(
MI.getIterator());
894 (void)CallInstrBundle;
896 (void)DelaySlotBundle;
903 "Call and its successor instruction don't have same label after.");
918 if (!
MI.isCandidateForCallSiteEntry())
927 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
938 unsigned CallReg = 0;
940 const Function *CalleeDecl =
nullptr;
941 if (CalleeOp.
isReg()) {
942 CallReg = CalleeOp.
getReg();
946 CalleeDecl = dyn_cast<Function>(CalleeOp.
getGlobal());
967 (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
976 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
979 << (CalleeDecl ? CalleeDecl->
getName()
983 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
985 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
986 ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg);
993 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1000 if (!
U.hasDwarfPubSections())
1003 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1006void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1014 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1015 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1017 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1019 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1021 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1023 if (!SysRoot.
empty())
1024 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1027 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1038 if (!CompilationDir.
empty())
1039 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1040 addGnuPubAttributes(NewCU, Die);
1045 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1049 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1052 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1053 dwarf::DW_FORM_data1, RVer);
1058 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1063 ? dwarf::DW_AT_dwo_name
1064 : dwarf::DW_AT_GNU_dwo_name;
1072DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1073 if (
auto *
CU = CUMap.lookup(DIUnit))
1081 return *CUMap.begin()->second;
1085 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1086 InfoHolder.
getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1088 InfoHolder.
addUnit(std::move(OwnedUnit));
1103 finishUnitAttributes(DIUnit, NewCU);
1107 CUMap.insert({DIUnit, &NewCU});
1108 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1122 if (!
A.Expr || !
B.Expr)
1124 auto FragmentA =
A.Expr->getFragmentInfo();
1125 auto FragmentB =
B.Expr->getFragmentInfo();
1126 if (!FragmentA || !FragmentB)
1128 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1133 return A.Expr == B.Expr;
1148 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1149 M->debug_compile_units_end());
1150 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1152 "DebugInfoAvailabilty unexpectedly not initialized");
1153 SingleCU = NumDebugCUs == 1;
1158 Global.getDebugInfo(GVs);
1159 for (
auto *GVE : GVs)
1160 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1189 if (CUNode->getImportedEntities().empty() &&
1190 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1191 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1197 for (
auto *GVE : CUNode->getGlobalVariables()) {
1201 auto &GVMapEntry = GVMap[GVE->getVariable()];
1202 auto *Expr = GVE->getExpression();
1203 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1204 GVMapEntry.push_back({
nullptr, Expr});
1208 for (
auto *GVE : CUNode->getGlobalVariables()) {
1210 if (Processed.
insert(GV).second)
1214 for (
auto *Ty : CUNode->getEnumTypes())
1215 CU.getOrCreateTypeDIE(cast<DIType>(Ty));
1217 for (
auto *Ty : CUNode->getRetainedTypes()) {
1220 if (
DIType *RT = dyn_cast<DIType>(Ty))
1222 CU.getOrCreateTypeDIE(RT);
1227void DwarfDebug::finishEntityDefinitions() {
1228 for (
const auto &Entity : ConcreteEntities) {
1229 DIE *Die = Entity->getDIE();
1236 Unit->finishEntityDefinition(Entity.get());
1240void DwarfDebug::finishSubprogramDefinitions() {
1244 getOrCreateDwarfCompileUnit(SP->getUnit()),
1249void DwarfDebug::finalizeModuleInfo() {
1252 finishSubprogramDefinitions();
1254 finishEntityDefinitions();
1260 if (CUMap.size() > 1)
1263 bool HasEmittedSplitCU =
false;
1267 for (
const auto &
P : CUMap) {
1268 auto &TheCU = *
P.second;
1269 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1273 TheCU.constructContainingTypeDIEs();
1278 auto *SkCU = TheCU.getSkeleton();
1280 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1283 (void)HasEmittedSplitCU;
1285 "Multiple CUs emitted into a single dwo file");
1286 HasEmittedSplitCU =
true;
1288 ? dwarf::DW_AT_dwo_name
1289 : dwarf::DW_AT_GNU_dwo_name;
1290 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1291 TheCU.addString(TheCU.getUnitDie(), attrDWOName,
1293 SkCU->addString(SkCU->getUnitDie(), attrDWOName,
1302 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1303 dwarf::DW_FORM_data8,
ID);
1304 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1305 dwarf::DW_FORM_data8,
ID);
1310 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1314 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1325 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1331 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
1333 U.setBaseAddress(TheCU.getRanges().front().Begin);
1334 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1340 U.addAddrTableBase();
1343 if (
U.hasRangeLists())
1344 U.addRnglistsBase();
1347 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1353 auto *CUNode = cast<DICompileUnit>(
P.first);
1356 if (CUNode->getMacros()) {
1357 if (UseDebugMacroSection) {
1359 TheCU.addSectionDelta(
1360 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1364 ? dwarf::DW_AT_macros
1365 : dwarf::DW_AT_GNU_macros;
1366 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1371 TheCU.addSectionDelta(
1372 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1373 U.getMacroLabelBegin(),
1376 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1377 U.getMacroLabelBegin(),
1385 if (CUNode->getDWOId())
1386 getOrCreateDwarfCompileUnit(CUNode);
1400 assert(CurFn ==
nullptr);
1403 for (
const auto &
P : CUMap) {
1404 const auto *CUNode = cast<DICompileUnit>(
P.first);
1408 for (
auto *IE : CUNode->getImportedEntities()) {
1409 assert(!isa_and_nonnull<DILocalScope>(IE->getScope()) &&
1410 "Unexpected function-local entity in 'imports' CU field.");
1411 CU->getOrCreateImportedEntityDIE(IE);
1413 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1414 if (
auto *IE = dyn_cast<DIImportedEntity>(
D))
1415 CU->getOrCreateImportedEntityDIE(IE);
1421 CU->createBaseTypeDIEs();
1430 finalizeModuleInfo();
1440 emitAbbreviations();
1454 emitDebugMacinfoDWO();
1464 emitDebugAbbrevDWO();
1466 emitDebugRangesDWO();
1476 emitAccelNamespaces();
1480 emitAccelDebugNames();
1489 emitDebugPubSections();
1497 if (
CU.getExistingAbstractEntity(Node))
1502 CU.createAbstractEntity(Node, Scope);
1507 if (
const auto *LV = dyn_cast<DILocalVariable>(
N))
1509 else if (
const auto *L = dyn_cast<DILabel>(
N))
1511 else if (
const auto *IE = dyn_cast<DIImportedEntity>(
N))
1517 return cast<DILocalScope>(S)->getNonLexicalBlockFileScope();
1521void DwarfDebug::collectVariableInfoFromMFTable(
1524 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1528 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1529 "Expected inlined-at fields to agree");
1531 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1538 <<
", no variable scope found\n");
1542 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1547 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1548 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1550 if (PreviousMMI &&
VI.inStackSlot())
1551 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1553 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1554 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1559 if (PreviousLoc->holds<
Loc::MMI>())
1563 <<
", conflicting fragment location types\n");
1568 auto RegVar = std::make_unique<DbgVariable>(
1569 cast<DILocalVariable>(Var.first), Var.second);
1570 if (
VI.inStackSlot())
1577 MFVars.
insert({Var, RegVar.get()});
1578 ConcreteEntities.push_back(std::move(RegVar));
1590 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1598 if (LSRange.size() == 0)
1601 const MachineInstr *LScopeBegin = LSRange.front().first;
1611 for (++Pred; Pred !=
MBB->
rend(); ++Pred) {
1614 auto PredDL = Pred->getDebugLoc();
1615 if (!PredDL || Pred->isMetaInstruction())
1619 if (
DL->getScope() == PredDL->getScope())
1622 if (!PredScope || LScope->dominates(PredScope))
1642 if (Ordering.
isBefore(RangeEnd, LScopeEnd))
1686 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1688 bool isSafeForSingleLocation =
true;
1692 for (
auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {
1696 size_t Index = std::distance(EB, EI);
1697 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1704 "Forgot label before/after instruction starting a range!");
1707 if (std::next(EI) == Entries.end()) {
1710 if (EI->isClobber())
1711 EndMI = EI->getInstr();
1713 else if (std::next(EI)->isClobber())
1717 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1719 if (EI->isDbgValue())
1725 if (EI->isDbgValue()) {
1732 if (!
Instr->isUndefDebugValue()) {
1737 if (
Instr->getDebugExpression()->isFragment())
1738 isSafeForSingleLocation =
false;
1741 StartDebugMI =
Instr;
1743 isSafeForSingleLocation =
false;
1749 if (OpenRanges.
empty())
1753 if (StartLabel == EndLabel) {
1754 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1759 for (
auto &R : OpenRanges)
1769 const MCSymbol *BeginSectionLabel = StartLabel;
1776 DebugLoc.emplace_back(BeginSectionLabel, EndLabel, Values);
1783 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1790 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1791 for (
auto &
Value : CurEntry->getValues())
1793 dbgs() <<
"-----\n";
1796 auto PrevEntry = std::next(CurEntry);
1797 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1801 if (!isSafeForSingleLocation ||
1820 RangeMBB = Entries.begin()->getInstr()->getParent();
1822 auto *NextEntry = std::next(CurEntry);
1823 while (NextEntry !=
DebugLoc.end()) {
1832 if (CurEntry->getEndSym() != RangeMBB->
getEndSymbol() ||
1834 CurEntry->getValues() != NextEntry->getValues())
1837 CurEntry = NextEntry;
1838 NextEntry = std::next(CurEntry);
1848 ensureAbstractEntityIsCreatedIfScoped(TheCU,
Node,
Scope.getScopeNode());
1849 if (isa<const DILocalVariable>(
Node)) {
1850 ConcreteEntities.push_back(
1851 std::make_unique<DbgVariable>(cast<const DILocalVariable>(
Node),
1854 cast<DbgVariable>(ConcreteEntities.back().get()));
1855 }
else if (isa<const DILabel>(
Node)) {
1856 ConcreteEntities.push_back(
1857 std::make_unique<DbgLabel>(cast<const DILabel>(
Node),
1860 cast<DbgLabel>(ConcreteEntities.back().get()));
1862 return ConcreteEntities.back().get();
1870 collectVariableInfoFromMFTable(TheCU, Processed);
1873 InlinedEntity
IV =
I.first;
1878 const auto &HistoryMapEntries =
I.second;
1896 DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
1897 *Scope, LocalVar,
IV.second));
1899 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1905 size_t HistSize = HistoryMapEntries.size();
1906 bool SingleValueWithClobber =
1907 HistSize == 2 && HistoryMapEntries[1].isClobber();
1908 if (HistSize == 1 || SingleValueWithClobber) {
1910 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1926 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1931 if (isValidSingleLocation) {
1932 RegVar->emplace<
Loc::Single>(Entries[0].getValues()[0]);
1943 for (
auto &Entry : Entries)
1950 InlinedEntity IL =
I.first;
1959 Label->getScope()->getNonLexicalBlockFileScope();
1974 createConcreteEntity(TheCU, *Scope, Label, IL.second,
Sym);
1978 for (
const DINode *DN : SP->getRetainedNodes()) {
1980 if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
1981 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
1985 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
1987 LocalDeclsPerLS[
LS].insert(DN);
2001 if (!
MI.isBundledWithSucc())
2003 auto Suc = std::next(
MI.getIterator());
2008 assert(Suc->isBundledWithPred() &&
2009 "Call bundle instructions are out of order");
2014 if (!NoDebug && SP->areAllCallsDescribed() &&
2016 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2055 unsigned LastAsmLine =
2058 bool PrevInstInSameSection =
2067 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2069 const MDNode *Scope =
DL.getScope();
2070 recordSourceLine(
DL.getLine(),
DL.getCol(), Scope, Flags);
2078 if (LastAsmLine == 0)
2095 const MDNode *Scope =
nullptr;
2096 unsigned Column = 0;
2101 recordSourceLine(0, Column, Scope, 0);
2109 if (
DL.getLine() == 0 && LastAsmLine == 0)
2118 if (
DL.getLine() &&
DL.getLine() != OldLine)
2121 const MDNode *Scope =
DL.getScope();
2122 recordSourceLine(
DL.getLine(),
DL.getCol(), Scope, Flags);
2137 bool IsEmptyPrologue =
2138 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2139 for (
const auto &
MBB : *MF) {
2140 for (
const auto &
MI :
MBB) {
2141 if (!
MI.isMetaInstruction()) {
2148 if (
MI.getDebugLoc().getLine())
2149 return std::make_pair(
MI.getDebugLoc(), IsEmptyPrologue);
2151 LineZeroLoc =
MI.getDebugLoc();
2153 IsEmptyPrologue =
false;
2157 return std::make_pair(LineZeroLoc, IsEmptyPrologue);
2163 const MDNode *S,
unsigned Flags,
unsigned CUID,
2165 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs) {
2167 unsigned FileNo = 1;
2168 unsigned Discriminator = 0;
2169 if (
auto *Scope = cast_or_null<DIScope>(S)) {
2170 Fn = Scope->getFilename();
2171 if (Line != 0 && DwarfVersion >= 4)
2172 if (
auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
2173 Discriminator = LBF->getDiscriminator();
2176 .getOrCreateSourceID(Scope->getFile());
2178 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2186 bool IsEmptyPrologue = PrologEnd.second;
2191 if (IsEmptyPrologue)
2196 (void)getOrCreateDwarfCompileUnit(
2237 return CU.getUniqueID();
2241 const auto &CURanges =
CU->getRanges();
2242 auto &LineTable =
Asm->
OutStreamer->getContext().getMCDwarfLineTable(
2245 LineTable.getMCLineSections().addEndEntry(
2246 const_cast<MCSymbol *
>(CURanges.back().End));
2265 "endFunction should be called with the same function as beginFunction");
2280 collectEntityInfo(TheCU, SP, Processed);
2285 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2306 const auto *SP = cast<DISubprogram>(AScope->getScopeNode());
2307 for (
const DINode *DN : SP->getRetainedNodes()) {
2311 assert(LexS &&
"Expected the LexicalScope to be created.");
2312 if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
2314 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2320 LocalDeclsPerLS[LS].insert(DN);
2324 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2326 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2329 ProcessedSPNodes.insert(SP);
2334 SkelCU->constructSubprogramScopeDIE(SP, FnScope);
2337 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2345 LocalDeclsPerLS.clear();
2352void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2354 ::recordSourceLine(*
Asm, Line, Col, S, Flags,
2364void DwarfDebug::emitDebugInfo() {
2370void DwarfDebug::emitAbbreviations() {
2376void DwarfDebug::emitStringOffsetsTableHeader() {
2383template <
typename AccelTableT>
2384void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2392void DwarfDebug::emitAccelDebugNames() {
2394 if (getUnits().empty())
2401void DwarfDebug::emitAccelNames() {
2408void DwarfDebug::emitAccelObjC() {
2414void DwarfDebug::emitAccelNamespaces() {
2415 emitAccel(AccelNamespace,
2421void DwarfDebug::emitAccelTypes() {
2452 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2460 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2467 case dwarf::DW_TAG_class_type:
2468 case dwarf::DW_TAG_structure_type:
2469 case dwarf::DW_TAG_union_type:
2470 case dwarf::DW_TAG_enumeration_type:
2476 case dwarf::DW_TAG_typedef:
2477 case dwarf::DW_TAG_base_type:
2478 case dwarf::DW_TAG_subrange_type:
2480 case dwarf::DW_TAG_namespace:
2482 case dwarf::DW_TAG_subprogram:
2484 case dwarf::DW_TAG_variable:
2486 case dwarf::DW_TAG_enumerator:
2496void DwarfDebug::emitDebugPubSections() {
2497 for (
const auto &NU : CUMap) {
2508 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
2513 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
2520 CU.getDebugSectionOffset());
2525void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
2533 "pub" +
Name,
"Length of Public " +
Name +
" Info");
2539 emitSectionReference(*TheU);
2546 for (
const auto &GI : Globals)
2549 return A.second->getOffset() <
B.second->getOffset();
2551 for (
const auto &[
Name, Entity] : Vec) {
2573void DwarfDebug::emitDebugStr() {
2574 MCSection *StringOffsetsSection =
nullptr;
2576 emitStringOffsetsTableHeader();
2581 StringOffsetsSection,
true);
2588 auto Comment = Comments.begin();
2589 auto End = Comments.end();
2604 for (
const auto &
Op : Expr) {
2606 "3 operand ops not yet supported");
2615 for (
unsigned J = 0; J <
Length; ++J)
2620 Streamer.
emitInt8(
Data.getData()[J], Comment !=
End ? *(Comment++) :
"");
2631 auto *DIExpr =
Value.getExpression();
2637 if (DIExpr && DIExpr->isEntryValue()) {
2654 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
2657 if (Entry.isInt()) {
2658 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
2659 BT->getEncoding() == dwarf::DW_ATE_signed_char))
2663 }
else if (Entry.isLocation()) {
2665 if (Location.isIndirect())
2671 }
else if (Entry.isTargetIndexLocation()) {
2677 }
else if (Entry.isConstantFP()) {
2680 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
2681 }
else if (Entry.getConstantFP()
2684 .getBitWidth() <= 64 ) {
2686 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
2689 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
2690 << Entry.getConstantFP()
2701 if (!
Value.isVariadic()) {
2702 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
2711 return Entry.isLocation() && !Entry.getLoc().getReg();
2716 std::move(ExprCursor),
2717 [EmitValueLocEntry, &
Value](
unsigned Idx,
2719 return EmitValueLocEntry(
Value.getLocEntries()[
Idx], Cursor);
2728 "location list entries without values are redundant");
2729 assert(Begin != End &&
"unexpected location list entry with empty range");
2734 if (
Value.isFragment()) {
2737 return P.isFragment();
2738 }) &&
"all values are expected to be fragments");
2741 for (
const auto &Fragment : Values)
2745 assert(Values.
size() == 1 &&
"only fragments may have >1 value");
2759 else if (DebugLocs.
getBytes(Entry).
size() <= std::numeric_limits<uint16_t>::max())
2779 Asm->OutStreamer->AddComment(
"Offset entry count");
2785 Asm->getDwarfOffsetByteSize());
2799 Asm->OutStreamer->AddComment(
"Offset entry count");
2800 Asm->emitInt32(DebugLocs.getLists().size());
2801 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
2803 for (
const auto &
List : DebugLocs.getLists())
2804 Asm->emitLabelDifference(
List.Label, DebugLocs.getSym(),
2805 Asm->getDwarfOffsetByteSize());
2810template <
typename Ranges,
typename PayloadEmitter>
2814 unsigned StartxLength,
unsigned EndOfList,
2816 bool ShouldUseBaseAddress,
2817 PayloadEmitter EmitPayload) {
2819 auto Size = Asm->MAI->getCodePointerSize();
2823 Asm->OutStreamer->emitLabel(
Sym);
2829 for (
const auto &Range : R)
2830 SectionRanges[&Range.Begin->getSection()].push_back(&Range);
2832 const MCSymbol *CUBase =
CU.getBaseAddress();
2833 bool BaseIsSet =
false;
2834 for (
const auto &
P : SectionRanges) {
2835 auto *
Base = CUBase;
2836 if (!
Base && ShouldUseBaseAddress) {
2837 const MCSymbol *Begin =
P.second.front()->Begin;
2842 Asm->OutStreamer->emitIntValue(-1,
Size);
2843 Asm->OutStreamer->AddComment(
" base address");
2844 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
2845 }
else if (NewBase != Begin ||
P.second.size() > 1) {
2851 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
2852 Asm->emitInt8(BaseAddressx);
2853 Asm->OutStreamer->AddComment(
" base address index");
2856 }
else if (BaseIsSet && !UseDwarf5) {
2859 Asm->OutStreamer->emitIntValue(-1,
Size);
2860 Asm->OutStreamer->emitIntValue(0,
Size);
2863 for (
const auto *RS :
P.second) {
2866 assert(Begin &&
"Range without a begin symbol?");
2867 assert(
End &&
"Range without an end symbol?");
2871 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
2872 Asm->emitInt8(OffsetPair);
2873 Asm->OutStreamer->AddComment(
" starting offset");
2874 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
2875 Asm->OutStreamer->AddComment(
" ending offset");
2876 Asm->emitLabelDifferenceAsULEB128(
End,
Base);
2878 Asm->emitLabelDifference(Begin,
Base,
Size);
2881 }
else if (UseDwarf5) {
2882 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
2883 Asm->emitInt8(StartxLength);
2884 Asm->OutStreamer->AddComment(
" start index");
2886 Asm->OutStreamer->AddComment(
" length");
2887 Asm->emitLabelDifferenceAsULEB128(
End, Begin);
2889 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
2890 Asm->OutStreamer->emitSymbolValue(
End,
Size);
2897 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
2901 Asm->OutStreamer->emitIntValue(0,
Size);
2902 Asm->OutStreamer->emitIntValue(0,
Size);
2909 *
List.CU, dwarf::DW_LLE_base_addressx,
2910 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
2914 DD.emitDebugLocEntryLocation(E, List.CU);
2918void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
2936void DwarfDebug::emitDebugLoc() {
2944void DwarfDebug::emitDebugLocDWO() {
2967 unsigned idx = AddrPool.
getIndex(Entry.Begin);
2984void DwarfDebug::emitDebugARanges() {
2989 for (
const SymbolCU &SCU : ArangeLabels) {
2990 if (SCU.Sym->isInSection()) {
2992 MCSection *Section = &SCU.Sym->getSection();
2993 if (!Section->getKind().isMetadata())
2994 SectionMap[Section].push_back(SCU);
2999 SectionMap[
nullptr].push_back(SCU);
3005 for (
auto &
I : SectionMap) {
3008 if (
List.size() < 1)
3016 Span.
Start = Cur.Sym;
3019 Spans[Cur.CU].push_back(Span);
3043 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3048 if (Cur.
CU != Prev.
CU) {
3050 Span.
Start = StartSym;
3053 Spans[Prev.
CU].push_back(Span);
3066 std::vector<DwarfCompileUnit *> CUs;
3067 for (
const auto &it : Spans) {
3074 return A->getUniqueID() <
B->getUniqueID();
3079 std::vector<ArangeSpan> &
List = Spans[
CU];
3082 if (
auto *Skel =
CU->getSkeleton())
3086 unsigned ContentSize =
3093 unsigned TupleSize = PtrSize * 2;
3100 ContentSize += (
List.size() + 1) * TupleSize;
3107 emitSectionReference(*
CU);
3123 auto SizeRef = SymSize.find(Span.Start);
3124 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3130 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3133 Size = SizeRef->second;
3149 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3150 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3152 List.CU->getCUNode()->getRangesBaseAddress() ||
3164 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3182void DwarfDebug::emitDebugRanges() {
3183 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3185 emitDebugRangesImpl(Holder,
3191void DwarfDebug::emitDebugRangesDWO() {
3192 emitDebugRangesImpl(InfoHolder,
3200 enum HeaderFlagMask {
3201#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3202#include "llvm/BinaryFormat/Dwarf.def"
3204 Asm->OutStreamer->AddComment(
"Macro information version");
3205 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3208 if (Asm->isDwarf64()) {
3209 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3210 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3212 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3213 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3215 Asm->OutStreamer->AddComment(
"debug_line_offset");
3217 Asm->emitDwarfLengthOrOffset(0);
3219 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3222void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3223 for (
auto *MN : Nodes) {
3224 if (
auto *M = dyn_cast<DIMacro>(MN))
3226 else if (
auto *
F = dyn_cast<DIMacroFile>(MN))
3227 emitMacroFile(*
F, U);
3233void DwarfDebug::emitMacro(
DIMacro &M) {
3241 if (UseDebugMacroSection) {
3244 ? dwarf::DW_MACRO_define_strx
3245 : dwarf::DW_MACRO_undef_strx;
3255 ? dwarf::DW_MACRO_GNU_define_indirect
3256 : dwarf::DW_MACRO_GNU_undef_indirect;
3276void DwarfDebug::emitMacroFileImpl(
3301 if (UseDebugMacroSection)
3303 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3310void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3311 for (
const auto &
P : CUMap) {
3312 auto &TheCU = *
P.second;
3315 auto *CUNode = cast<DICompileUnit>(
P.first);
3316 DIMacroNodeArray Macros = CUNode->getMacros();
3321 if (UseDebugMacroSection)
3323 handleMacroNodes(Macros, U);
3330void DwarfDebug::emitDebugMacinfo() {
3332 emitDebugMacinfoImpl(UseDebugMacroSection
3333 ? ObjLower.getDwarfMacroSection()
3334 : ObjLower.getDwarfMacinfoSection());
3337void DwarfDebug::emitDebugMacinfoDWO() {
3339 emitDebugMacinfoImpl(UseDebugMacroSection
3340 ? ObjLower.getDwarfMacroDWOSection()
3341 : ObjLower.getDwarfMacinfoDWOSection());
3346void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3347 std::unique_ptr<DwarfCompileUnit> NewU) {
3349 if (!CompilationDir.
empty())
3350 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3351 addGnuPubAttributes(*NewU, Die);
3353 SkeletonHolder.
addUnit(std::move(NewU));
3358 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3359 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3369 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3376void DwarfDebug::emitDebugInfoDWO() {
3384void DwarfDebug::emitDebugAbbrevDWO() {
3389void DwarfDebug::emitDebugLineDWO() {
3391 SplitTypeUnitFileTable.
Emit(
3396void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3406void DwarfDebug::emitDebugStrDWO() {
3408 emitStringOffsetsTableHeaderDWO();
3416void DwarfDebug::emitDebugAddr() {
3427 return &SplitTypeUnitFileTable;
3438 return Result.high();
3447 if (!TypeUnitsUnderConstruction.empty() && AddrPool.
hasBeenUsed())
3450 auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0));
3452 CU.addDIETypeSignature(RefDie, Ins.first->second);
3456 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3459 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
CU,
Asm,
this, &InfoHolder,
3460 getDwoLineTable(
CU));
3463 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3465 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3470 Ins.first->second = Signature;
3485 CU.applyStmtList(UnitDie);
3496 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
3497 TypeUnitsUnderConstruction.clear();
3506 for (
const auto &TU : TypeUnitsToAdd)
3507 TypeSignatures.erase(TU.second);
3513 CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));
3519 for (
auto &TU : TypeUnitsToAdd) {
3524 CU.addDIETypeSignature(RefDie, Signature);
3531template <
typename DataT>
3551 AccelDebugNames.addName(
Ref, Die);
3562 addAccelNameImpl(
CU, AccelNames,
Name, Die);
3569 addAccelNameImpl(
CU, AccelObjC,
Name, Die);
3574 addAccelNameImpl(
CU, AccelNamespace,
Name, Die);
3578 const DIE &Die,
char Flags) {
3579 addAccelNameImpl(
CU, AccelTypes,
Name, Die);
3588 return dwarf::Form::DW_FORM_sec_offset;
3590 "DWARF64 is not defined prior DWARFv3");
3592 : dwarf::Form::DW_FORM_data4;
3596 return SectionLabels.lookup(S);
3600 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
3605std::optional<MD5::MD5Result>
3609 return std::nullopt;
3610 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
3612 return std::nullopt;
3617 std::string ChecksumString = fromHex(Checksum->Value);
3619 std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.data());
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements a class to represent arbitrary precision integral constant values and operations...
static Expected< bool > hasObjCCategory(BitstreamCursor &Stream)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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 std::pair< DebugLoc, bool > findPrologueEndLoc(const MachineFunction *MF)
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
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 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 void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, const MDNode *S, unsigned Flags, unsigned CUID, uint16_t DwarfVersion, ArrayRef< std::unique_ptr< DwarfCompileUnit > > DCUs)
Register a source line with debug info.
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))
static cl::opt< bool > UseDwarfRangesBaseAddressSpecifier("use-dwarf-ranges-base-address-specifier", cl::Hidden, cl::desc("Use base address specifiers in debug_ranges"), cl::init(false))
static void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegSet &ClobberedRegUnits)
Interpret values loaded into registers by CurMI.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegSet &ClobberedRegUnits)
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
static constexpr unsigned ULEB128PadSize
static cl::opt< DefaultOnOff > DwarfSectionsAsReferences("dwarf-sections-as-references", cl::Hidden, cl::desc("Use sections+offset as references rather than labels."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
static void forBothCUs(DwarfCompileUnit &CU, Func F)
static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD)
static const DILocalScope * getRetainedNodeScope(const MDNode *N)
static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
static 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 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 void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, unsigned StartxLength, unsigned EndOfList, StringRef(*StringifyEnum)(unsigned), bool ShouldUseBaseAddress, PayloadEmitter EmitPayload)
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
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 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.
void emit(AsmPrinter &Asm, MCSection *AddrSection)
void setLabel(MCSymbol *Sym)
void resetUsedFlag(bool HasBeenUsed=false)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
size_t size() const
size - Get the array size.
This class is intended to be used as a driving class for all asm writers.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
DwarfDebug * getDwarfDebug()
void emitDwarfLengthOrOffset(uint64_t Value) const
Emit 32- or 64-bit value depending on the DWARF format.
unsigned int getUnitLengthFieldByteSize() const
Returns 4 for DWARF32 and 12 for DWARF64.
TargetMachine & TM
Target machine description.
MCSymbol * getFunctionBegin() const
void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const
Emit something like ".long Hi-Lo" where the size in bytes of the directive is specified by Size and H...
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset" or ".quad Label + Offset" depending on the DWARF format.
void emitInt8(int Value) const
Emit a byte directive and value.
MapVector< unsigned, MBBSectionRange > MBBSectionRanges
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const
Emit a unit length field.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * createTempSymbol(const Twine &Name) const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
void emitLabelReference(const MCSymbol *Label, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label" where the size in bytes of the directive is specified by Size and L...
unsigned int getDwarfOffsetByteSize() const
Returns 4 for DWARF32 and 8 for DWARF64.
void emitInt16(int Value) const
Emit a short directive and value.
const DataLayout & getDataLayout() const
Return information about data layout.
uint16_t getDwarfVersion() const
void emitInt8(uint8_t Byte, const Twine &Comment) override
const bool GenerateComments
Only verbose textual output needs comments.
virtual void emitULEB128(uint64_t DWord, const Twine &Comment="", unsigned PadTo=0)=0
virtual void emitSLEB128(uint64_t DWord, const Twine &Comment="")=0
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 std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
unsigned getRuntimeVersion() const
bool getSplitDebugInlining() const
StringRef getSysRoot() const
StringRef getProducer() const
unsigned getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
An object containing the capability of hashing and adding hash attributes onto a DIE.
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die)
Computes the CU signature.
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
A structured debug information entry.
DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
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.
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
bool isImplicit() const
Return whether this is an implicit location description.
static std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
Base class for scope-like contexts.
StringRef getFilename() const
StringRef getName() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
DIScope * getScope() const
This class represents an Operation in the Expression.
std::optional< unsigned > getSubCode() const
uint64_t getEndOffset() const
Encoding
Size and signedness of expression operations' operands.
const Description & getDescription() const
uint64_t getOperandEndOffset(unsigned Idx) const
uint64_t getRawOperand(unsigned Idx) const
bool isLittleEndian() const
Layout endianness...
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...
bool hasNonEmptyLocation(const Entries &Entries) const
Test whether a vector of entries features any non-empty locations.
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.
This class is used to track local variable information.
const DILocalVariable * getVariable() const
const DIType * getType() const
Base class for debug information backends.
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.
DebugLoc PrologEndLoc
This location indicates end of function prologue and beginning of function body.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
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.
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< std::string > getComments(const Entry &E) const
ArrayRef< Entry > getEntries(const List &L) const
ArrayRef< char > getBytes(const Entry &E) const
MCSymbol * getSym() const
void setSym(MCSymbol *Sym)
ArrayRef< List > getLists() const
MDNode * getScope() 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)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope)
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope)
Construct a DIE for this subprogram scope.
DwarfCompileUnit * getSkeleton() const
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
unsigned getUniqueID() const
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.
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.
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
void addSubprogramNames(const DICompileUnit &CU, const DISubprogram *SP, 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()
void addAccelNamespace(const DICompileUnit &CU, StringRef Name, const DIE &Die)
void addAccelType(const DICompileUnit &CU, StringRef Name, const DIE &Die, char Flags)
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.
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
void addAccelName(const DICompileUnit &CU, StringRef Name, const DIE &Die)
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.
bool useLocSection() const
Returns whether .debug_loc section should be emitted.
unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU)
Get Dwarf compile unit ID for line table.
DebugLoc emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
bool useRangesSection() const
Returns whether ranges section should be emitted.
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 addAccelObjC(const DICompileUnit &CU, StringRef Name, const DIE &Die)
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.
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 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.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void addScopeLabel(LexicalScope *LS, DbgLabel *Label)
void addUnit(std::unique_ptr< DwarfCompileUnit > U)
Add a unit to the list of CUs.
void computeSizeAndOffsets()
Compute the size and offset of all the DIEs.
void setRnglistsTableBaseSym(MCSymbol *Sym)
DenseMap< LexicalScope *, ScopeVars > & getScopeVariables()
unsigned computeSizeAndOffsetsForUnit(DwarfUnit *TheU)
Compute the size and offset of all the DIEs in the given unit.
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
void emitUnit(DwarfUnit *TheU, bool UseOffsets)
Emit the given unit to its 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.
DenseMap< LexicalScope *, LabelList > & getScopeLabels()
void addScopeVariable(LexicalScope *LS, DbgVariable *Var)
DenseMap< const DILocalScope *, DIE * > & getAbstractScopeDIEs()
const SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
unsigned getIndex() const
MCSymbol * getSymbol() const
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str)
Same as getEntry, except that you can use EntryRef::getIndex to obtain a unique ID of this entry (e....
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.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isTailCall(const MachineInstr &MI) const override
Record instruction ordering so we can query their relative positions within a function.
bool isBefore(const MachineInstr *A, const MachineInstr *B) const
Check if instruction A comes before B, where A and B both belong to the MachineFunction passed to ini...
LexicalScope - This class is used to track scope information.
SmallVectorImpl< InsnRange > & getRanges()
const DILocalScope * getScopeNode() const
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
ArrayRef< LexicalScope * > getAbstractScopesList() const
getAbstractScopesList - Return a reference to list of abstract scopes.
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
LexicalScope * findAbstractScope(const DILocalScope *N)
findAbstractScope - Find an abstract scope or return null.
bool empty()
empty - Return true if there is any lexical scope information available.
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
Single value location description.
Single(DbgValueLoc ValueLoc)
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
uint16_t getDwarfVersion() const
dwarf::DwarfFormat getDwarfFormat() const
void maybeSetRootFile(StringRef Directory, StringRef FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source)
void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
MCSection * getDwarfLoclistsSection() const
MCSection * getDwarfAccelTypesSection() const
MCSection * getDwarfGnuPubNamesSection() const
MCSection * getDwarfStrOffDWOSection() const
MCSection * getDwarfRangesSection() const
MCSection * getDwarfAccelNamespaceSection() const
MCSection * getDwarfLineDWOSection() const
MCSection * getDwarfStrOffSection() const
MCSection * getDwarfInfoDWOSection() const
MCSection * getDwarfTypesDWOSection() const
MCSection * getDwarfPubNamesSection() const
MCSection * getDwarfMacroSection() const
MCSection * getDwarfStrSection() const
MCSection * getDwarfLoclistsDWOSection() const
MCSection * getDwarfMacinfoDWOSection() const
MCSection * getDwarfRnglistsSection() const
MCSection * getDwarfAddrSection() const
MCSection * getDwarfInfoSection() const
MCSection * getDwarfPubTypesSection() const
MCSection * getDwarfTypesSection(uint64_t Hash) const
MCSection * getDwarfGnuPubTypesSection() const
MCSection * getDwarfStrDWOSection() const
MCSection * getDwarfAccelNamesSection() const
MCSection * getDwarfAbbrevDWOSection() const
MCSection * getDwarfRnglistsDWOSection() const
MCSection * getDwarfAbbrevSection() const
MCSection * getDwarfMacinfoSection() const
MCSection * getDwarfLocDWOSection() const
MCSection * getDwarfARangesSection() const
MCSection * getDwarfAccelObjCSection() const
MCSection * getDwarfLocSection() 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 ...
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
std::string SplitDwarfFile
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
MCSymbol * getEndSymbol() const
Returns the MCSymbol marking the end of this basic block.
bool sameSection(const MachineBasicBlock *MBB) const
Returns true if this and MBB belong to the same section.
unsigned getSectionIDNum() const
Returns the unique section ID number of this basic block.
bool isBeginSection() const
Returns true if this block begins any section.
bool isEndSection() const
Returns true if this block ends any section.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const CallSiteInfoMap & getCallSitesInfo() const
bool hasBBSections() const
Returns true if this function has basic block sections enabled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & back() const
VariableDbgInfoMapTy & getVariableDbgInfo()
const MachineBasicBlock & front() const
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i....
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
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...
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
bool isDebugValue() const
const Module * getModule() const
bool hasDebugInfo() const
Returns true if valid debug info is present.
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.
iterator_range< debug_compile_units_iterator > debug_compile_units() const
Return an iterator for all DICompileUnits listed in this Module's llvm.dbg.cu named metadata node and...
unsigned getDwarfVersion() const
Returns the Dwarf Version by checking module flags.
bool isDwarf64() const
Returns the DWARF format by checking module flags.
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...
const_iterator begin() const
const_iterator end() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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
MCTargetOptions MCOptions
Machine level options.
DebuggerKind DebuggerTuning
Which debugger to tune for.
bool ShouldEmitDebugEntryValues() const
NOTE: There are targets that still do not support the debug entry values production.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
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...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
StringRef getName() const
Return a constant reference to the value's name.
void dump() const
Support for debugging, callable in GDB: V->dump()
std::pair< iterator, bool > insert(const ValueT &V)
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()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
StringRef RangeListEncodingString(unsigned Encoding)