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"),
99 clEnumValN(AccelTableKind::None,
"Disable",
"Disabled."),
100 clEnumValN(AccelTableKind::Apple,
"Apple",
"Apple"),
101 clEnumValN(AccelTableKind::Dwarf,
"Dwarf",
"DWARF")),
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"),
158 clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges,
"Ranges",
159 "Use rnglists for contiguous ranges if that allows "
160 "using a pre-existing base address"),
161 clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions,
163 "Use exprloc addrx+offset expressions for any "
164 "address with a prior base address"),
165 clEnumValN(DwarfDebug::MinimizeAddrInV5::Form,
"Form",
166 "Use addrx+offset extension form for any address "
167 "with a prior base address"),
168 clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled,
"Disabled",
170 cl::init(DwarfDebug::MinimizeAddrInV5::Default));
174void DebugLocDwarfExpression::emitOp(uint8_t Op,
const char *Comment) {
180void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
188void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
192void DebugLocDwarfExpression::emitBaseTypeRef(
uint64_t Idx) {
203void DebugLocDwarfExpression::enableTemporaryBuffer() {
204 assert(!IsBuffering &&
"Already buffering?");
210void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering =
false; }
212unsigned DebugLocDwarfExpression::getTemporaryBufferSize() {
213 return TmpBuf ? TmpBuf->Bytes.size() : 0;
216void DebugLocDwarfExpression::commitTemporaryBuffer() {
219 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
220 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
221 ? TmpBuf->Comments[
Byte.index()].c_str()
225 TmpBuf->Bytes.clear();
226 TmpBuf->Comments.clear();
236 const bool IsVariadic =
MI->isDebugValueList();
242 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
244 }
else if (Op.isTargetIndex()) {
247 }
else if (Op.isImm())
249 else if (Op.isFPImm())
251 else if (Op.isCImm())
256 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
260 assert(FrameIndexExprs.
empty() &&
"Already initialized?");
261 assert(!ValueLoc.get() &&
"Already initialized?");
268 if (
auto *
E =
DbgValue->getDebugExpression())
269 if (
E->getNumElements())
274 if (FrameIndexExprs.
size() == 1)
275 return FrameIndexExprs;
278 [](
const FrameIndexExpr &
A) {
279 return A.Expr->isFragment();
281 "multiple FI expressions without DW_OP_LLVM_fragment");
283 [](
const FrameIndexExpr &
A,
const FrameIndexExpr &
B) ->
bool {
284 return A.Expr->getFragmentInfo()->OffsetInBits <
285 B.Expr->getFragmentInfo()->OffsetInBits;
288 return FrameIndexExprs;
292 assert(DebugLocListIndex == ~0U && !ValueLoc.get() &&
"not an MMI entry");
293 assert(V.DebugLocListIndex == ~0U && !V.ValueLoc.get() &&
"not an MMI entry");
297 assert(!FrameIndexExprs.
empty() &&
"Expected an MMI entry");
298 assert(!V.FrameIndexExprs.empty() &&
"Expected an MMI entry");
304 if (FrameIndexExprs.
size()) {
305 auto *Expr = FrameIndexExprs.
back().Expr;
306 if (!Expr || !Expr->isFragment())
310 for (
const auto &FIE : V.FrameIndexExprs)
313 return FIE.FI ==
Other.FI && FIE.Expr ==
Other.Expr;
319 [](FrameIndexExpr &FIE) {
320 return FIE.Expr && FIE.Expr->isFragment();
322 "conflicting locations for variable");
326 bool GenerateTypeUnits,
334 if (GenerateTypeUnits)
340 if (DwarfVersion >= 5)
350 InfoHolder(
A,
"info_string", DIEValueAllocator),
351 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
352 IsDarwin(
A->
TM.getTargetTriple().isOSDarwin()) {
363 else if (TT.isOSAIX())
369 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
373 UseLocSection = !TT.isNVPTX();
387 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
393 bool Dwarf64 = DwarfVersion >= 3 &&
403 TT.isOSBinFormatELF()) ||
404 TT.isOSBinFormatXCOFF();
406 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
413 UseSectionsAsReferences = TT.isNVPTX();
418 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
419 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
423 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
430 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
432 UseDWARF2Bitfields = DwarfVersion < 4;
438 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
446 UseDebugMacroSection =
455 if (DwarfVersion >= 5) {
473 return Name.startswith(
"+") ||
Name.startswith(
"-");
480 return Name.contains(
") ");
486 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
491 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
492 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
496 return In.slice(In.find(
' ') + 1, In.find(
']'));
506 if (!SP->isDefinition())
515 if (SP->getLinkageName() !=
"" && SP->
getName() != SP->getLinkageName() &&
535 if (Scope->isAbstractScope())
553 if (
auto *SkelCU =
CU.getSkeleton())
554 if (
CU.getCUNode()->getSplitDebugInlining())
562void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
564 assert(Scope && Scope->getScopeNode());
565 assert(Scope->isAbstractScope());
566 assert(!Scope->getInlinedAt());
568 auto *SP = cast<DISubprogram>(Scope->getScopeNode());
576 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
577 if (
auto *SkelCU =
CU.getSkeleton()) {
579 .constructAbstractSubprogramScopeDIE(Scope);
580 if (
CU.getCUNode()->getSplitDebugInlining())
581 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
583 CU.constructAbstractSubprogramScopeDIE(Scope);
618template <
typename ValT>
622 for (
auto Param : DescribedParams) {
623 bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0;
638 "Combined debug expression is invalid");
653 auto I = Worklist.
insert({Reg, {}});
654 auto &ParamsForFwdReg =
I.first->second;
655 for (
auto Param : ParamsToAdd) {
658 return D.ParamReg == Param.ParamReg;
660 "Same parameter described twice by forwarding reg");
667 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
710 if (
MI.isDebugInstr())
714 if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical()) {
715 for (
auto &FwdReg : ForwardedRegWorklist)
716 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
717 Defs.
insert(FwdReg.first);
719 NewClobberedRegUnits.
insert(*Units);
727 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
728 if (FwdRegDefs.
empty()) {
730 ClobberedRegUnits.
insert(NewClobberedRegUnits.
begin(),
731 NewClobberedRegUnits.
end());
738 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
739 for (
auto &RegUnit : ClobberedRegUnits)
740 if (
TRI.hasRegUnit(Reg, RegUnit))
745 for (
auto ParamFwdReg : FwdRegDefs) {
746 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
747 if (ParamValue->first.isImm()) {
748 int64_t Val = ParamValue->first.getImm();
750 ForwardedRegWorklist[ParamFwdReg], Params);
751 }
else if (ParamValue->first.isReg()) {
752 Register RegLoc = ParamValue->first.getReg();
753 Register SP = TLI.getStackPointerRegisterToSaveRestore();
755 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
756 if (!IsRegClobberedInMeantime(RegLoc) &&
757 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
760 ForwardedRegWorklist[ParamFwdReg], Params);
769 ForwardedRegWorklist[ParamFwdReg]);
776 for (
auto ParamFwdReg : FwdRegDefs)
777 ForwardedRegWorklist.
erase(ParamFwdReg);
780 ClobberedRegUnits.
insert(NewClobberedRegUnits.
begin(),
781 NewClobberedRegUnits.
end());
785 for (
auto &New : TmpWorklistItems)
787 TmpWorklistItems.
clear();
804 if (ForwardedRegWorklist.
empty())
811 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
822 auto CallFwdRegsInfo = CalleesMap.
find(CallMI);
825 if (CallFwdRegsInfo == CalleesMap.end())
839 for (
const auto &ArgReg : CallFwdRegsInfo->second) {
841 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
843 assert(InsertedReg &&
"Single register used to forward two arguments?");
848 for (
const auto &MO : CallMI->
uses())
849 if (MO.isReg() && MO.isUndef())
850 ForwardedRegWorklist.
erase(MO.getReg());
869 assert(std::next(Suc) == BundleEnd &&
870 "More than one instruction in call delay slot");
884 if (ShouldTryEmitEntryVals) {
888 for (
auto &RegEntry : ForwardedRegWorklist) {
895void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
900 if (!SP.areAllCallsDescribed() || !SP.isDefinition())
907 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
910 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
914 if (!
MI.isBundledWithSucc())
916 auto Suc = std::next(
MI.getIterator());
918 (void)CallInstrBundle;
920 (void)DelaySlotBundle;
927 "Call and its successor instruction don't have same label after.");
942 if (!
MI.isCandidateForCallSiteEntry())
951 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
962 unsigned CallReg = 0;
964 const Function *CalleeDecl =
nullptr;
965 if (CalleeOp.
isReg()) {
966 CallReg = CalleeOp.
getReg();
970 CalleeDecl = dyn_cast<Function>(CalleeOp.
getGlobal());
991 (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1000 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1003 << (CalleeDecl ? CalleeDecl->
getName()
1006 ->getName(CallReg)))
1007 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1009 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1010 ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg);
1017 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1024 if (!
U.hasDwarfPubSections())
1027 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1030void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1038 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1039 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1041 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1043 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1045 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1047 if (!SysRoot.
empty())
1048 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1051 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1062 if (!CompilationDir.
empty())
1063 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1064 addGnuPubAttributes(NewCU, Die);
1069 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1073 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1076 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1077 dwarf::DW_FORM_data1, RVer);
1082 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1087 ? dwarf::DW_AT_dwo_name
1088 : dwarf::DW_AT_GNU_dwo_name;
1096DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1097 if (
auto *
CU = CUMap.lookup(DIUnit))
1102 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1103 InfoHolder.
getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1105 InfoHolder.
addUnit(std::move(OwnedUnit));
1123 finishUnitAttributes(DIUnit, NewCU);
1127 CUMap.insert({DIUnit, &NewCU});
1128 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1134 if (isa<DILocalScope>(
N->getScope()))
1150 if (!
A.Expr || !
B.Expr)
1152 auto FragmentA =
A.Expr->getFragmentInfo();
1153 auto FragmentB =
B.Expr->getFragmentInfo();
1154 if (!FragmentA || !FragmentB)
1156 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1161 return A.Expr == B.Expr;
1176 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1177 M->debug_compile_units_end());
1178 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1180 "DebugInfoAvailabilty unexpectedly not initialized");
1181 SingleCU = NumDebugCUs == 1;
1186 Global.getDebugInfo(GVs);
1187 for (
auto *GVE : GVs)
1188 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1222 return !isa<DILocalScope>(IE->getScope());
1225 if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() &&
1226 CUNode->getRetainedTypes().empty() &&
1227 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1233 for (
auto *GVE : CUNode->getGlobalVariables()) {
1237 auto &GVMapEntry = GVMap[GVE->getVariable()];
1238 auto *Expr = GVE->getExpression();
1239 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1240 GVMapEntry.push_back({
nullptr, Expr});
1244 for (
auto *GVE : CUNode->getGlobalVariables()) {
1246 if (Processed.
insert(GV).second)
1250 for (
auto *Ty : CUNode->getEnumTypes())
1251 CU.getOrCreateTypeDIE(cast<DIType>(Ty));
1253 for (
auto *Ty : CUNode->getRetainedTypes()) {
1256 if (
DIType *RT = dyn_cast<DIType>(Ty))
1258 CU.getOrCreateTypeDIE(RT);
1262 for (
auto *IE : CUNode->getImportedEntities())
1263 constructAndAddImportedEntityDIE(
CU, IE);
1267void DwarfDebug::finishEntityDefinitions() {
1268 for (
const auto &Entity : ConcreteEntities) {
1269 DIE *Die = Entity->getDIE();
1276 Unit->finishEntityDefinition(Entity.get());
1280void DwarfDebug::finishSubprogramDefinitions() {
1284 getOrCreateDwarfCompileUnit(SP->getUnit()),
1289void DwarfDebug::finalizeModuleInfo() {
1292 finishSubprogramDefinitions();
1294 finishEntityDefinitions();
1300 if (CUMap.size() > 1)
1305 for (
const auto &
P : CUMap) {
1306 auto &TheCU = *
P.second;
1322 ? dwarf::DW_AT_dwo_name
1323 : dwarf::DW_AT_GNU_dwo_name;
1324 finishUnitAttributes(TheCU.
getCUNode(), TheCU);
1327 SkCU->addString(SkCU->getUnitDie(), attrDWOName,
1337 dwarf::DW_FORM_data8,
ID);
1338 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1339 dwarf::DW_FORM_data8,
ID);
1344 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1348 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1359 if (
unsigned NumRanges = TheCU.
getRanges().size()) {
1365 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
1367 U.setBaseAddress(TheCU.
getRanges().front().Begin);
1368 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.
takeRanges());
1374 U.addAddrTableBase();
1377 if (
U.hasRangeLists())
1378 U.addRnglistsBase();
1380 if (!DebugLocs.
getLists().empty()) {
1382 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1388 auto *CUNode = cast<DICompileUnit>(
P.first);
1391 if (CUNode->getMacros()) {
1392 if (UseDebugMacroSection) {
1395 TheCU.
getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1399 ? dwarf::DW_AT_macros
1400 : dwarf::DW_AT_GNU_macros;
1401 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1408 U.getMacroLabelBegin(),
1411 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1412 U.getMacroLabelBegin(),
1420 if (CUNode->getDWOId())
1421 getOrCreateDwarfCompileUnit(CUNode);
1435 assert(CurFn ==
nullptr);
1438 for (
const auto &
P : CUMap) {
1439 auto &
CU = *
P.second;
1440 CU.createBaseTypeDIEs();
1449 finalizeModuleInfo();
1459 emitAbbreviations();
1473 emitDebugMacinfoDWO();
1483 emitDebugAbbrevDWO();
1485 emitDebugRangesDWO();
1495 emitAccelNamespaces();
1499 emitAccelDebugNames();
1508 emitDebugPubSections();
1516 const MDNode *ScopeNode) {
1517 if (
CU.getExistingAbstractEntity(Node))
1521 cast<DILocalScope>(ScopeNode)));
1526 if (
CU.getExistingAbstractEntity(
Node))
1531 CU.createAbstractEntity(
Node, Scope);
1535void DwarfDebug::collectVariableInfoFromMFTable(
1538 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1542 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1543 "Expected inlined-at fields to agree");
1545 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1552 <<
", no variable scope found\n");
1556 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1557 auto RegVar = std::make_unique<DbgVariable>(
1558 cast<DILocalVariable>(Var.first), Var.second);
1559 RegVar->initializeMMI(
VI.Expr,
VI.Slot);
1564 DbgVar->addMMIEntry(*RegVar);
1566 MFVars.
insert({Var, RegVar.get()});
1567 ConcreteEntities.push_back(std::move(RegVar));
1580 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1588 if (LSRange.size() == 0)
1591 const MachineInstr *LScopeBegin = LSRange.front().first;
1601 for (++Pred; Pred !=
MBB->
rend(); ++Pred) {
1604 auto PredDL = Pred->getDebugLoc();
1605 if (!PredDL || Pred->isMetaInstruction())
1609 if (
DL->getScope() == PredDL->getScope())
1612 if (!PredScope || LScope->dominates(PredScope))
1632 if (Ordering.
isBefore(RangeEnd, LScopeEnd))
1676 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1678 bool isSafeForSingleLocation =
true;
1682 for (
auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {
1686 size_t Index = std::distance(EB, EI);
1687 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1694 "Forgot label before/after instruction starting a range!");
1697 if (std::next(EI) == Entries.end()) {
1700 if (EI->isClobber())
1701 EndMI = EI->getInstr();
1703 else if (std::next(EI)->isClobber())
1707 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1709 if (EI->isDbgValue())
1715 if (EI->isDbgValue()) {
1728 isSafeForSingleLocation =
false;
1731 StartDebugMI = Instr;
1733 isSafeForSingleLocation =
false;
1739 if (OpenRanges.
empty())
1743 if (StartLabel == EndLabel) {
1744 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1749 for (
auto &R : OpenRanges)
1759 const MCSymbol *BeginSectionLabel = StartLabel;
1766 DebugLoc.emplace_back(BeginSectionLabel, EndLabel, Values);
1773 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1780 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1781 for (
auto &
Value : CurEntry->getValues())
1783 dbgs() <<
"-----\n";
1786 auto PrevEntry = std::next(CurEntry);
1787 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1791 if (!isSafeForSingleLocation ||
1810 RangeMBB = Entries.begin()->getInstr()->getParent();
1812 auto *NextEntry = std::next(CurEntry);
1813 while (NextEntry !=
DebugLoc.end()) {
1822 if (CurEntry->getEndSym() != RangeMBB->
getEndSymbol() ||
1824 CurEntry->getValues() != NextEntry->getValues())
1827 CurEntry = NextEntry;
1828 NextEntry = std::next(CurEntry);
1838 ensureAbstractEntityIsCreatedIfScoped(TheCU,
Node,
Scope.getScopeNode());
1839 if (isa<const DILocalVariable>(
Node)) {
1840 ConcreteEntities.push_back(
1841 std::make_unique<DbgVariable>(cast<const DILocalVariable>(
Node),
1844 cast<DbgVariable>(ConcreteEntities.back().get()));
1845 }
else if (isa<const DILabel>(
Node)) {
1846 ConcreteEntities.push_back(
1847 std::make_unique<DbgLabel>(cast<const DILabel>(
Node),
1850 cast<DbgLabel>(ConcreteEntities.back().get()));
1852 return ConcreteEntities.back().get();
1860 collectVariableInfoFromMFTable(TheCU, Processed);
1863 InlinedEntity
IV =
I.first;
1868 const auto &HistoryMapEntries =
I.second;
1886 DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
1887 *Scope, LocalVar,
IV.second));
1889 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1895 size_t HistSize = HistoryMapEntries.size();
1896 bool SingleValueWithClobber =
1897 HistSize == 2 && HistoryMapEntries[1].isClobber();
1898 if (HistSize == 1 || SingleValueWithClobber) {
1900 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1916 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1921 if (isValidSingleLocation) {
1933 for (
auto &Entry : Entries)
1940 InlinedEntity IL =
I.first;
1949 Label->getScope()->getNonLexicalBlockFileScope();
1964 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
1968 for (
const DINode *DN : SP->getRetainedNodes()) {
1969 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
1972 if (
auto *DV = dyn_cast<DILocalVariable>(DN)) {
1974 }
else if (
auto *
DL = dyn_cast<DILabel>(DN)) {
1979 createConcreteEntity(TheCU, *Scope, DN,
nullptr);
1992 if (!
MI.isBundledWithSucc())
1994 auto Suc = std::next(
MI.getIterator());
1999 assert(Suc->isBundledWithPred() &&
2000 "Call bundle instructions are out of order");
2005 if (!NoDebug && SP->areAllCallsDescribed() &&
2007 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2046 unsigned LastAsmLine =
2055 if ((LastAsmLine == 0 &&
DL.getLine() != 0) ||
Flags) {
2057 const MDNode *Scope =
DL.getScope();
2058 recordSourceLine(
DL.getLine(),
DL.getCol(), Scope,
Flags);
2066 if (LastAsmLine == 0)
2083 const MDNode *Scope =
nullptr;
2084 unsigned Column = 0;
2089 recordSourceLine(0, Column, Scope, 0);
2097 if (
DL.getLine() == 0 && LastAsmLine == 0)
2106 if (
DL.getLine() &&
DL.getLine() != OldLine)
2109 const MDNode *Scope =
DL.getScope();
2110 recordSourceLine(
DL.getLine(),
DL.getCol(), Scope,
Flags);
2121 for (
const auto &
MBB : *MF) {
2122 for (
const auto &
MI :
MBB) {
2129 if (
MI.getDebugLoc().getLine())
2130 return MI.getDebugLoc();
2131 LineZeroLoc =
MI.getDebugLoc();
2141 const MDNode *S,
unsigned Flags,
unsigned CUID,
2143 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs) {
2145 unsigned FileNo = 1;
2146 unsigned Discriminator = 0;
2147 if (
auto *Scope = cast_or_null<DIScope>(S)) {
2148 Fn = Scope->getFilename();
2149 if (Line != 0 && DwarfVersion >= 4)
2150 if (
auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
2151 Discriminator = LBF->getDiscriminator();
2154 .getOrCreateSourceID(Scope->getFile());
2156 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col,
Flags, 0,
2166 (void)getOrCreateDwarfCompileUnit(
2207 return CU.getUniqueID();
2211 const auto &CURanges =
CU->getRanges();
2212 auto &LineTable =
Asm->
OutStreamer->getContext().getMCDwarfLineTable(
2215 LineTable.getMCLineSections().addEndEntry(
2216 const_cast<MCSymbol *
>(CURanges.back().End));
2235 "endFunction should be called with the same function as beginFunction");
2250 collectEntityInfo(TheCU, SP, Processed);
2255 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2277 const auto *SP = cast<DISubprogram>(AScope->getScopeNode());
2278 for (
const DINode *DN : SP->getRetainedNodes()) {
2279 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2282 const MDNode *Scope =
nullptr;
2283 if (
auto *DV = dyn_cast<DILocalVariable>(DN))
2284 Scope = DV->getScope();
2285 else if (
auto *
DL = dyn_cast<DILabel>(DN))
2286 Scope =
DL->getScope();
2291 ensureAbstractEntityIsCreated(TheCU, DN, Scope);
2293 &&
"ensureAbstractEntityIsCreated inserted abstract scopes");
2295 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2298 ProcessedSPNodes.insert(SP);
2303 SkelCU->constructSubprogramScopeDIE(SP, FnScope);
2306 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2320void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2322 ::recordSourceLine(*
Asm, Line, Col, S, Flags,
2332void DwarfDebug::emitDebugInfo() {
2338void DwarfDebug::emitAbbreviations() {
2344void DwarfDebug::emitStringOffsetsTableHeader() {
2351template <
typename AccelTableT>
2352void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2360void DwarfDebug::emitAccelDebugNames() {
2362 if (getUnits().empty())
2369void DwarfDebug::emitAccelNames() {
2376void DwarfDebug::emitAccelObjC() {
2382void DwarfDebug::emitAccelNamespaces() {
2383 emitAccel(AccelNamespace,
2389void DwarfDebug::emitAccelTypes() {
2420 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2428 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2435 case dwarf::DW_TAG_class_type:
2436 case dwarf::DW_TAG_structure_type:
2437 case dwarf::DW_TAG_union_type:
2438 case dwarf::DW_TAG_enumeration_type:
2444 case dwarf::DW_TAG_typedef:
2445 case dwarf::DW_TAG_base_type:
2446 case dwarf::DW_TAG_subrange_type:
2448 case dwarf::DW_TAG_namespace:
2450 case dwarf::DW_TAG_subprogram:
2452 case dwarf::DW_TAG_variable:
2454 case dwarf::DW_TAG_enumerator:
2464void DwarfDebug::emitDebugPubSections() {
2465 for (
const auto &NU : CUMap) {
2476 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
2481 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
2488 CU.getDebugSectionOffset());
2493void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
2501 "pub" +
Name,
"Length of Public " +
Name +
" Info");
2507 emitSectionReference(*TheU);
2513 for (
const auto &GI : Globals) {
2514 const char *
Name = GI.getKeyData();
2515 const DIE *Entity = GI.second;
2538void DwarfDebug::emitDebugStr() {
2539 MCSection *StringOffsetsSection =
nullptr;
2541 emitStringOffsetsTableHeader();
2546 StringOffsetsSection,
true);
2553 auto Comment = Comments.begin();
2554 auto End = Comments.end();
2569 for (
const auto &Op : Expr) {
2570 assert(Op.getCode() != dwarf::DW_OP_const_type &&
2571 "3 operand ops not yet supported");
2572 Streamer.
emitInt8(Op.getCode(), Comment != End ? *(Comment++) :
"");
2574 for (
unsigned I = 0;
I < 2; ++
I) {
2575 if (Op.getDescription().Op[
I] == Encoding::SizeNA)
2577 if (Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
2579 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[Op.getRawOperand(
I)].Die);
2581 for (
unsigned J = 0; J <
Length; ++J)
2586 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
2588 Offset = Op.getOperandEndOffset(
I);
2597 auto *DIExpr =
Value.getExpression();
2603 if (DIExpr && DIExpr->isEntryValue()) {
2620 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
2623 if (Entry.isInt()) {
2624 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
2625 BT->getEncoding() == dwarf::DW_ATE_signed_char))
2629 }
else if (Entry.isLocation()) {
2631 if (Location.isIndirect())
2637 }
else if (Entry.isTargetIndexLocation()) {
2643 }
else if (Entry.isConstantFP()) {
2646 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
2647 }
else if (Entry.getConstantFP()
2650 .getBitWidth() <= 64 ) {
2652 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
2655 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
2656 << Entry.getConstantFP()
2667 if (!
Value.isVariadic()) {
2668 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
2677 return Entry.isLocation() && !Entry.getLoc().getReg();
2682 std::move(ExprCursor),
2683 [EmitValueLocEntry, &
Value](
unsigned Idx,
2685 return EmitValueLocEntry(
Value.getLocEntries()[
Idx], Cursor);
2694 "location list entries without values are redundant");
2695 assert(Begin != End &&
"unexpected location list entry with empty range");
2700 if (
Value.isFragment()) {
2703 return P.isFragment();
2704 }) &&
"all values are expected to be fragments");
2707 for (
const auto &Fragment : Values)
2711 assert(Values.
size() == 1 &&
"only fragments may have >1 value");
2725 else if (DebugLocs.
getBytes(Entry).
size() <= std::numeric_limits<uint16_t>::max())
2745 Asm->OutStreamer->AddComment(
"Offset entry count");
2751 Asm->getDwarfOffsetByteSize());
2765 Asm->OutStreamer->AddComment(
"Offset entry count");
2766 Asm->emitInt32(DebugLocs.getLists().size());
2767 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
2769 for (
const auto &
List : DebugLocs.getLists())
2770 Asm->emitLabelDifference(
List.Label, DebugLocs.getSym(),
2771 Asm->getDwarfOffsetByteSize());
2776template <
typename Ranges,
typename PayloadEmitter>
2780 unsigned StartxLength,
unsigned EndOfList,
2782 bool ShouldUseBaseAddress,
2783 PayloadEmitter EmitPayload) {
2785 auto Size = Asm->MAI->getCodePointerSize();
2789 Asm->OutStreamer->emitLabel(Sym);
2795 for (
const auto &Range : R)
2796 SectionRanges[&Range.Begin->getSection()].push_back(&Range);
2798 const MCSymbol *CUBase =
CU.getBaseAddress();
2799 bool BaseIsSet =
false;
2800 for (
const auto &
P : SectionRanges) {
2801 auto *
Base = CUBase;
2802 if (!
Base && ShouldUseBaseAddress) {
2803 const MCSymbol *Begin =
P.second.front()->Begin;
2808 Asm->OutStreamer->emitIntValue(-1,
Size);
2809 Asm->OutStreamer->AddComment(
" base address");
2810 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
2811 }
else if (NewBase != Begin ||
P.second.size() > 1) {
2817 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
2818 Asm->emitInt8(BaseAddressx);
2819 Asm->OutStreamer->AddComment(
" base address index");
2822 }
else if (BaseIsSet && !UseDwarf5) {
2825 Asm->OutStreamer->emitIntValue(-1,
Size);
2826 Asm->OutStreamer->emitIntValue(0,
Size);
2829 for (
const auto *RS :
P.second) {
2832 assert(Begin &&
"Range without a begin symbol?");
2833 assert(End &&
"Range without an end symbol?");
2837 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
2838 Asm->emitInt8(OffsetPair);
2839 Asm->OutStreamer->AddComment(
" starting offset");
2840 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
2841 Asm->OutStreamer->AddComment(
" ending offset");
2842 Asm->emitLabelDifferenceAsULEB128(End,
Base);
2844 Asm->emitLabelDifference(Begin,
Base,
Size);
2845 Asm->emitLabelDifference(End,
Base,
Size);
2847 }
else if (UseDwarf5) {
2848 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
2849 Asm->emitInt8(StartxLength);
2850 Asm->OutStreamer->AddComment(
" start index");
2852 Asm->OutStreamer->AddComment(
" length");
2853 Asm->emitLabelDifferenceAsULEB128(End, Begin);
2855 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
2856 Asm->OutStreamer->emitSymbolValue(End,
Size);
2863 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
2867 Asm->OutStreamer->emitIntValue(0,
Size);
2868 Asm->OutStreamer->emitIntValue(0,
Size);
2875 *
List.CU, dwarf::DW_LLE_base_addressx,
2876 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
2880 DD.emitDebugLocEntryLocation(E, List.CU);
2884void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
2902void DwarfDebug::emitDebugLoc() {
2910void DwarfDebug::emitDebugLocDWO() {
2933 unsigned idx = AddrPool.
getIndex(Entry.Begin);
2950void DwarfDebug::emitDebugARanges() {
2955 for (
const SymbolCU &SCU : ArangeLabels) {
2956 if (SCU.Sym->isInSection()) {
2958 MCSection *Section = &SCU.Sym->getSection();
2959 if (!Section->getKind().isMetadata())
2960 SectionMap[Section].push_back(SCU);
2965 SectionMap[
nullptr].push_back(SCU);
2971 for (
auto &
I : SectionMap) {
2974 if (
List.size() < 1)
2982 Span.
Start = Cur.Sym;
2985 Spans[Cur.CU].push_back(Span);
3009 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3014 if (Cur.
CU != Prev.
CU) {
3016 Span.
Start = StartSym;
3019 Spans[Prev.
CU].push_back(Span);
3032 std::vector<DwarfCompileUnit *> CUs;
3033 for (
const auto &it : Spans) {
3040 return A->getUniqueID() <
B->getUniqueID();
3045 std::vector<ArangeSpan> &
List = Spans[
CU];
3048 if (
auto *Skel =
CU->getSkeleton())
3052 unsigned ContentSize =
3059 unsigned TupleSize = PtrSize * 2;
3066 ContentSize += (
List.size() + 1) * TupleSize;
3073 emitSectionReference(*
CU);
3089 auto SizeRef = SymSize.find(Span.Start);
3090 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3096 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3099 Size = SizeRef->second;
3115 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3116 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3118 List.CU->getCUNode()->getRangesBaseAddress() ||
3130 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3148void DwarfDebug::emitDebugRanges() {
3149 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3151 emitDebugRangesImpl(Holder,
3157void DwarfDebug::emitDebugRangesDWO() {
3158 emitDebugRangesImpl(InfoHolder,
3166 enum HeaderFlagMask {
3167#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3168#include "llvm/BinaryFormat/Dwarf.def"
3170 Asm->OutStreamer->AddComment(
"Macro information version");
3171 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3174 if (Asm->isDwarf64()) {
3175 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3176 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3178 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3179 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3181 Asm->OutStreamer->AddComment(
"debug_line_offset");
3183 Asm->emitDwarfLengthOrOffset(0);
3185 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3188void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3189 for (
auto *MN : Nodes) {
3190 if (
auto *M = dyn_cast<DIMacro>(MN))
3192 else if (
auto *
F = dyn_cast<DIMacroFile>(MN))
3193 emitMacroFile(*
F, U);
3199void DwarfDebug::emitMacro(
DIMacro &M) {
3207 if (UseDebugMacroSection) {
3210 ? dwarf::DW_MACRO_define_strx
3211 : dwarf::DW_MACRO_undef_strx;
3221 ? dwarf::DW_MACRO_GNU_define_indirect
3222 : dwarf::DW_MACRO_GNU_undef_indirect;
3242void DwarfDebug::emitMacroFileImpl(
3267 if (UseDebugMacroSection)
3269 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3276void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3277 for (
const auto &
P : CUMap) {
3278 auto &TheCU = *
P.second;
3281 auto *CUNode = cast<DICompileUnit>(
P.first);
3282 DIMacroNodeArray Macros = CUNode->getMacros();
3287 if (UseDebugMacroSection)
3289 handleMacroNodes(Macros, U);
3296void DwarfDebug::emitDebugMacinfo() {
3298 emitDebugMacinfoImpl(UseDebugMacroSection
3299 ? ObjLower.getDwarfMacroSection()
3300 : ObjLower.getDwarfMacinfoSection());
3303void DwarfDebug::emitDebugMacinfoDWO() {
3305 emitDebugMacinfoImpl(UseDebugMacroSection
3306 ? ObjLower.getDwarfMacroDWOSection()
3307 : ObjLower.getDwarfMacinfoDWOSection());
3312void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3313 std::unique_ptr<DwarfCompileUnit> NewU) {
3315 if (!CompilationDir.
empty())
3316 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3317 addGnuPubAttributes(*NewU, Die);
3319 SkeletonHolder.
addUnit(std::move(NewU));
3324 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3325 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3335 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3342void DwarfDebug::emitDebugInfoDWO() {
3350void DwarfDebug::emitDebugAbbrevDWO() {
3355void DwarfDebug::emitDebugLineDWO() {
3357 SplitTypeUnitFileTable.
Emit(
3362void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3372void DwarfDebug::emitDebugStrDWO() {
3374 emitStringOffsetsTableHeaderDWO();
3382void DwarfDebug::emitDebugAddr() {
3393 return &SplitTypeUnitFileTable;
3404 return Result.high();
3413 if (!TypeUnitsUnderConstruction.empty() && AddrPool.
hasBeenUsed())
3416 auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0));
3418 CU.addDIETypeSignature(RefDie, Ins.first->second);
3422 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3425 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
CU,
Asm,
this, &InfoHolder,
3426 getDwoLineTable(
CU));
3429 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3431 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3436 Ins.first->second = Signature;
3451 CU.applyStmtList(UnitDie);
3462 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
3463 TypeUnitsUnderConstruction.clear();
3472 for (
const auto &TU : TypeUnitsToAdd)
3473 TypeSignatures.erase(TU.second);
3479 CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));
3485 for (
auto &TU : TypeUnitsToAdd) {
3490 CU.addDIETypeSignature(RefDie, Signature);
3497template <
typename DataT>
3516 AccelDebugNames.addName(
Ref, Die);
3527 addAccelNameImpl(
CU, AccelNames,
Name, Die);
3534 addAccelNameImpl(
CU, AccelObjC,
Name, Die);
3539 addAccelNameImpl(
CU, AccelNamespace,
Name, Die);
3543 const DIE &Die,
char Flags) {
3544 addAccelNameImpl(
CU, AccelTypes,
Name, Die);
3553 return dwarf::Form::DW_FORM_sec_offset;
3555 "DWARF64 is not defined prior DWARFv3");
3557 : dwarf::Form::DW_FORM_data4;
3561 auto I = SectionLabels.find(S);
3562 if (
I == SectionLabels.end())
3567 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
3572std::optional<MD5::MD5Result>
3576 return std::nullopt;
3577 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
3579 return std::nullopt;
3584 std::string ChecksumString = fromHex(Checksum->Value);
3586 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 cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
static DebugLoc findPrologueEndLoc(const MachineFunction *MF)
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 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 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
DIImportedEntityArray getImportedEntities() 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.
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
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.
bool isFragment() const
Return whether this is a piece of an aggregate variable.
static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
bool isImplicit() const
Return whether this is an implicit location description.
ArrayRef< uint64_t > getElements() const
An imported module (C++ using directive or similar).
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
StringRef getFilename() const
StringRef getName() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
Encoding
Size and signedness of expression operations' operands.
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...
const DILocation * getInlinedAt() const
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
void initializeDbgValue(DbgValueLoc Value)
const DIType * getType() const
void addMMIEntry(const DbgVariable &V)
ArrayRef< FrameIndexExpr > getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
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)
SmallVector< RangeSpan, 2 > takeRanges()
DIE * constructImportedEntityDIE(const DIImportedEntity *Module)
Construct import_module DIE.
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
void addImportedEntity(const DIImportedEntity *IE)
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
void setDWOId(uint64_t DwoId)
const SmallVectorImpl< RangeSpan > & getRanges() const
getRanges - Get the list of ranges for this unit.
const StringMap< const DIE * > & getGlobalNames() const
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 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()
bool addScopeVariable(LexicalScope *LS, DbgVariable *Var)
DenseMap< const MDNode *, DIE * > & getAbstractSPDies()
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.
DIE * getOrCreateContextDIE(const DIScope *Context)
Get context owner's 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.
void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)
addSectionDelta - Add a label delta 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 constructContainingTypeDIEs()
Construct DIEs for types that contain vtables.
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.
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
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
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.
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
bool isDebugValue() const
bool isUndefDebugValue() const
Return true if the instruction is a debug value which describes a part of a variable as unavailable.
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.
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)
StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
StringRef MacroString(unsigned Encoding)
StringRef LocListEncodingString(unsigned Encoding)
StringRef GnuMacroString(unsigned Encoding)
StringRef MacinfoString(unsigned Encoding)
StringRef OperationEncodingString(unsigned Encoding)
StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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)