83 #define DEBUG_TYPE "dwarfdebug" 87 cl::desc(
"Disable debug info printing"));
90 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
100 cl::desc(
"Generate DWARF4 type units."),
104 "split-dwarf-cross-cu-references",
cl::Hidden,
111 cl::desc(
"Make an absence of debug location information explicit."),
119 "Default for platform"),
127 cl::desc(
"Use inlined strings rather than string section."),
135 cl::desc(
"Disable emission .debug_ranges section."),
140 cl::desc(
"Use sections+offset as references rather than labels."),
153 cl::desc(
"Which DWARF linkage-name attributes to emit."),
155 "Default for platform"),
158 "Abstract subprograms")),
166 void DebugLocDwarfExpression::emitOp(uint8_t
Op,
const char *Comment) {
172 void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
176 void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) {
181 unsigned MachineReg) {
187 assert(getVariable() &&
"Invalid complex DbgVariable!");
188 return getVariable()->getType().resolve()->isBlockByrefStruct();
221 uint16_t tag = Ty->
getTag();
223 if (tag == dwarf::DW_TAG_pointer_type)
224 subType = resolve(cast<DIDerivedType>(Ty)->
getBaseType());
226 auto Elements = cast<DICompositeType>(subType)->getElements();
227 for (
unsigned i = 0,
N = Elements.size(); i <
N; ++i) {
228 auto *DT = cast<DIDerivedType>(Elements[i]);
229 if (
getName() == DT->getName())
230 return resolve(DT->getBaseType());
237 if (FrameIndexExprs.size() == 1)
238 return FrameIndexExprs;
241 [](
const FrameIndexExpr &A) {
242 return A.Expr->isFragment();
244 "multiple FI expressions without DW_OP_LLVM_fragment");
246 [](
const FrameIndexExpr &A,
const FrameIndexExpr &
B) ->
bool {
247 return A.Expr->getFragmentInfo()->OffsetInBits <
248 B.Expr->getFragmentInfo()->OffsetInBits;
251 return FrameIndexExprs;
255 assert(DebugLocListIndex == ~0U && !MInsn &&
"not an MMI entry");
256 assert(V.DebugLocListIndex == ~0U && !V.MInsn &&
"not an MMI entry");
260 assert(!FrameIndexExprs.empty() &&
"Expected an MMI entry");
261 assert(!V.FrameIndexExprs.
empty() &&
"Expected an MMI entry");
267 if (FrameIndexExprs.size()) {
268 auto *Expr = FrameIndexExprs.back().Expr;
269 if (!Expr || !Expr->isFragment())
273 for (
const auto &FIE : V.FrameIndexExprs)
276 return FIE.FI == Other.FI && FIE.Expr == Other.Expr;
278 FrameIndexExprs.push_back(FIE);
280 assert((FrameIndexExprs.size() == 1 ||
282 [](FrameIndexExpr &FIE) {
283 return FIE.Expr && FIE.Expr->isFragment();
285 "conflicting locations for variable");
289 bool GenerateTypeUnits,
297 if (GenerateTypeUnits)
303 if (DwarfVersion >= 5)
313 InfoHolder(A,
"info_string", DIEValueAllocator),
314 SkeletonHolder(A,
"skel_string", DIEValueAllocator),
315 IsDarwin(A->
TM.getTargetTriple().isOSDarwin()) {
329 if (DwarfInlinedStrings ==
Default)
330 UseInlineStrings = TT.
isNVPTX();
332 UseInlineStrings = DwarfInlinedStrings ==
Enable;
348 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
354 UseRangesSection = !NoDwarfRangesSection && !TT.
isNVPTX();
357 if (DwarfSectionsAsReferences ==
Default)
358 UseSectionsAsReferences = TT.
isNVPTX();
360 UseSectionsAsReferences = DwarfSectionsAsReferences ==
Enable;
374 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
377 UseDWARF2Bitfields = (DwarfVersion < 4) ||
tuneForGDB();
383 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
425 if (!SP->isDefinition())
434 if (SP->getLinkageName() !=
"" && SP->
getName() != SP->getLinkageName() &&
462 if (Ranges.
size() > 1)
481 void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
495 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
496 if (
auto *SkelCU =
CU.getSkeleton()) {
498 .constructAbstractSubprogramScopeDIE(Scope);
499 if (
CU.getCUNode()->getSplitDebugInlining())
500 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
502 CU.constructAbstractSubprogramScopeDIE(Scope);
506 void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &
SP,
511 if (!SP.areAllCallsDescribed() || !SP.isDefinition())
518 CU.
addFlag(ScopeDIE, dwarf::DW_AT_call_all_calls);
521 assert(TII &&
"TargetInstrInfo not found: cannot label tail calls");
532 if (
MI.hasDelaySlot())
554 assert((IsTail || PCOffset) &&
"Call without return PC information");
556 << CalleeDecl->
getName() << (IsTail ?
" [tail]" :
"")
568 U.
addFlag(D, dwarf::DW_AT_GNU_pubnames);
571 void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
579 std::string ProducerWithFlags = Producer.
str() +
" " + Flags.
str();
580 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
582 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
584 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
586 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
597 if (!CompilationDir.
empty())
598 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
600 addGnuPubAttributes(NewCU, Die);
605 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
609 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
612 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
613 dwarf::DW_FORM_data1, RVer);
618 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
622 NewCU.
addString(Die, dwarf::DW_AT_GNU_dwo_name,
629 DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
630 if (
auto *CU = CUMap.lookup(DIUnit))
635 auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
636 InfoHolder.
getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
638 InfoHolder.
addUnit(std::move(OwnedUnit));
641 NewCU.addImportedEntity(
IE);
647 if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU)
648 Asm->OutStreamer->emitDwarfFile0Directive(
651 NewCU.getUniqueID());
654 NewCU.setSkeleton(constructSkeletonCU(NewCU));
655 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());
657 finishUnitAttributes(DIUnit, NewCU);
658 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
661 CUMap.insert({DIUnit, &NewCU});
662 CUDieMap.insert({&NewCU.getUnitDie(), &NewCU});
668 if (isa<DILocalScope>(N->
getScope()))
688 if (!FragmentA || !FragmentB)
690 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
718 "DebugInfoAvailabilty initialized unexpectedly");
719 SingleCU = NumDebugCUs == 1;
724 Global.getDebugInfo(GVs);
725 for (
auto *GVE : GVs)
726 GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()});
761 return !isa<DILocalScope>(
IE->getScope());
764 if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() &&
765 CUNode->getRetainedTypes().empty() &&
766 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
772 for (
auto *GVE : CUNode->getGlobalVariables()) {
776 auto &GVMapEntry = GVMap[GVE->getVariable()];
777 auto *Expr = GVE->getExpression();
778 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
779 GVMapEntry.push_back({
nullptr, Expr});
782 for (
auto *GVE : CUNode->getGlobalVariables()) {
784 if (Processed.
insert(GV).second)
788 for (
auto *Ty : CUNode->getEnumTypes()) {
793 for (
auto *Ty : CUNode->getRetainedTypes()) {
796 if (
DIType *RT = dyn_cast<DIType>(Ty))
802 for (
auto *
IE : CUNode->getImportedEntities())
803 constructAndAddImportedEntityDIE(CU,
IE);
807 void DwarfDebug::finishEntityDefinitions() {
808 for (
const auto &Entity : ConcreteEntities) {
809 DIE *Die = Entity->getDIE();
820 void DwarfDebug::finishSubprogramDefinitions() {
824 getOrCreateDwarfCompileUnit(SP->getUnit()),
829 void DwarfDebug::finalizeModuleInfo() {
832 finishSubprogramDefinitions();
834 finishEntityDefinitions();
840 if (CUMap.size() > 1)
845 for (
const auto &
P : CUMap) {
846 auto &TheCU = *
P.second;
858 finishUnitAttributes(TheCU.
getCUNode(), TheCU);
861 SkCU->addString(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_name,
871 dwarf::DW_FORM_data8,
ID);
872 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
873 dwarf::DW_FORM_data8,
ID);
878 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
882 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
900 if (
unsigned NumRanges = TheCU.
getRanges().size()) {
906 U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
908 U.setBaseAddress(TheCU.
getRanges().front().getStart());
909 U.attachRangesOrLowHighPC(U.getUnitDie(), TheCU.
takeRanges());
913 if (U.hasRangeLists())
920 auto *CUNode = cast<DICompileUnit>(
P.first);
922 if (CUNode->getMacros())
923 U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
924 U.getMacroLabelBegin(),
930 if (CUNode->getDWOId())
931 getOrCreateDwarfCompileUnit(CUNode);
951 finalizeModuleInfo();
980 emitDebugAbbrevDWO();
982 emitDebugRangesDWO();
992 emitAccelNamespaces();
996 emitAccelDebugNames();
1005 emitDebugPubSections();
1013 const MDNode *ScopeNode) {
1018 cast<DILocalScope>(ScopeNode)));
1021 void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(
DwarfCompileUnit &CU,
1032 void DwarfDebug::collectVariableInfoFromMFTable(
1038 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1039 "Expected inlined-at fields to agree");
1041 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1049 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->
getScopeNode());
1050 auto RegVar = llvm::make_unique<DbgVariable>(
1051 cast<DILocalVariable>(Var.first), Var.second);
1052 RegVar->initializeMMI(
VI.Expr,
VI.Slot);
1054 DbgVar->addMMIEntry(*RegVar);
1056 MFVars.
insert({Var, RegVar.get()});
1057 ConcreteEntities.push_back(std::move(RegVar));
1071 assert((!Op1.isImm() || (Op1.getImm() == 0)) &&
"unexpected offset");
1090 if (Begin == Next.Begin) {
1091 auto *FirstExpr = cast<DIExpression>(Values[0].Expression);
1092 auto *FirstNextExpr = cast<DIExpression>(Next.Values[0].Expression);
1093 if (!FirstExpr->isFragment() || !FirstNextExpr->isFragment())
1099 for (
unsigned i = 0, j = 0; i < Values.size(); ++i) {
1100 for (; j < Next.Values.size(); ++j) {
1101 int res = cast<DIExpression>(Values[i].Expression)->fragmentCmp(
1102 cast<DIExpression>(Next.Values[j].Expression));
1114 addValues(Next.Values);
1149 for (
auto I = Ranges.
begin(),
E = Ranges.
end();
I !=
E; ++
I) {
1166 OpenRanges.
erase(Last, OpenRanges.
end());
1169 assert(StartLabel &&
"Forgot label before DBG_VALUE starting a range!");
1174 else if (std::next(
I) == Ranges.
end())
1178 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1185 if (StartLabel == EndLabel) {
1191 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1196 bool couldMerge =
false;
1204 if (!DebugLoc.
empty())
1212 if (OpenRanges.
size())
1220 auto CurEntry = DebugLoc.
rbegin();
1222 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1223 for (
auto &Value : CurEntry->getValues())
1225 dbgs() <<
"-----\n";
1228 auto PrevEntry = std::next(CurEntry);
1229 if (PrevEntry != DebugLoc.
rend() && PrevEntry->MergeRanges(*CurEntry))
1239 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node, Scope.
getScopeNode());
1240 if (isa<const DILocalVariable>(Node)) {
1241 ConcreteEntities.push_back(
1242 llvm::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),
1245 cast<DbgVariable>(ConcreteEntities.back().get()));
1246 }
else if (isa<const DILabel>(Node)) {
1247 ConcreteEntities.push_back(
1248 llvm::make_unique<DbgLabel>(cast<const DILabel>(Node),
1251 cast<DbgLabel>(ConcreteEntities.back().get()));
1253 return ConcreteEntities.back().get();
1271 if (LSRange.size() == 0)
1275 const MachineInstr *LScopeBegin = LSRange.front().first;
1280 for (++Pred; Pred != MBB->rend(); ++Pred) {
1283 auto PredDL = Pred->getDebugLoc();
1284 if (!PredDL || Pred->isMetaInstruction())
1288 if (DL->getScope() == PredDL->getScope())
1291 if (!PredScope || LScope->dominates(PredScope))
1319 collectVariableInfoFromMFTable(TheCU, Processed);
1322 InlinedEntity IV =
I.first;
1323 if (Processed.
count(IV))
1327 const auto &Ranges =
I.second;
1342 DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
1343 *Scope, LocalVar, IV.second));
1346 assert(MInsn->isDebugValue() &&
"History must begin with debug value");
1349 if (Ranges.
size() == 1 &&
1363 buildLocationList(Entries, Ranges);
1372 for (
auto &Entry : Entries)
1373 Entry.finalize(*
Asm, List, BT);
1379 InlinedEntity IL =
I.first;
1385 const DILabel *Label = cast<DILabel>(IL.first);
1400 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
1404 for (
const DINode *DN : SP->getRetainedNodes()) {
1405 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
1408 if (
auto *DV = dyn_cast<DILocalVariable>(DN)) {
1410 }
else if (
auto *DL = dyn_cast<DILabel>(DN)) {
1415 createConcreteEntity(TheCU, *Scope, DN,
nullptr);
1436 unsigned LastAsmLine =
1450 if (LastAsmLine == 0 && DL.
getLine() != 0) {
1461 if (LastAsmLine == 0)
1464 if (UnknownLocations == Disable)
1478 const MDNode *Scope =
nullptr;
1479 unsigned Column = 0;
1484 recordSourceLine(0, Column, Scope, 0);
1516 for (
const auto &MBB : *MF)
1517 for (
const auto &
MI : MBB)
1520 return MI.getDebugLoc();
1550 auto *SP =
PrologEndLoc->getInlinedAtScope()->getSubprogram();
1568 "endFunction should be called with the same function as beginFunction");
1576 if (TheCU.getCUNode()->isDebugDirectivesOnly()) {
1583 collectEntityInfo(TheCU, SP, Processed);
1591 if (!TheCU.getCUNode()->getDebugInfoForProfiling() &&
1605 auto *SP = cast<DISubprogram>(AScope->getScopeNode());
1606 for (
const DINode *DN : SP->getRetainedNodes()) {
1607 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
1610 const MDNode *Scope =
nullptr;
1611 if (
auto *DV = dyn_cast<DILocalVariable>(DN))
1612 Scope = DV->getScope();
1613 else if (
auto *DL = dyn_cast<DILabel>(DN))
1614 Scope = DL->getScope();
1619 ensureAbstractEntityIsCreated(TheCU, DN, Scope);
1621 &&
"ensureAbstractEntityIsCreated inserted abstract scopes");
1623 constructAbstractSubprogramScopeDIE(TheCU, AScope);
1626 ProcessedSPNodes.insert(SP);
1627 DIE &ScopeDIE = TheCU.constructSubprogramScopeDIE(SP, FnScope);
1628 if (
auto *SkelCU = TheCU.getSkeleton())
1630 TheCU.getCUNode()->getSplitDebugInlining())
1631 SkelCU->constructSubprogramScopeDIE(SP, FnScope);
1634 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
1648 void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
1651 unsigned FileNo = 1;
1652 unsigned Discriminator = 0;
1653 if (
auto *Scope = cast_or_null<DIScope>(S)) {
1654 Fn = Scope->getFilename();
1656 if (
auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
1657 Discriminator = LBF->getDiscriminator();
1659 unsigned CUID =
Asm->
OutStreamer->getContext().getDwarfCompileUnitID();
1661 .getOrCreateSourceID(Scope->getFile());
1663 Asm->
OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
1672 void DwarfDebug::emitDebugInfo() {
1678 void DwarfDebug::emitAbbreviations() {
1684 void DwarfDebug::emitStringOffsetsTableHeader() {
1691 template <
typename AccelTableT>
1700 void DwarfDebug::emitAccelDebugNames() {
1702 if (getUnits().
empty())
1709 void DwarfDebug::emitAccelNames() {
1716 void DwarfDebug::emitAccelObjC() {
1722 void DwarfDebug::emitAccelNamespaces() {
1723 emitAccel(AccelNamespace,
1729 void DwarfDebug::emitAccelTypes() {
1760 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
1768 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
1775 case dwarf::DW_TAG_class_type:
1776 case dwarf::DW_TAG_structure_type:
1777 case dwarf::DW_TAG_union_type:
1778 case dwarf::DW_TAG_enumeration_type:
1783 case dwarf::DW_TAG_typedef:
1784 case dwarf::DW_TAG_base_type:
1785 case dwarf::DW_TAG_subrange_type:
1787 case dwarf::DW_TAG_namespace:
1789 case dwarf::DW_TAG_subprogram:
1791 case dwarf::DW_TAG_variable:
1793 case dwarf::DW_TAG_enumerator:
1803 void DwarfDebug::emitDebugPubSections() {
1804 for (
const auto &NU : CUMap) {
1815 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
1820 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
1832 void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
1839 Asm->
OutStreamer->AddComment(
"Length of Public " + Name +
" Info");
1850 emitSectionReference(*TheU);
1856 for (
const auto &GI : Globals) {
1857 const char *Name = GI.getKeyData();
1858 const DIE *Entity = GI.second;
1881 void DwarfDebug::emitDebugStr() {
1882 MCSection *StringOffsetsSection =
nullptr;
1884 emitStringOffsetsTableHeader();
1889 StringOffsetsSection,
true);
1895 auto Comment = Comments.begin();
1896 auto End = Comments.end();
1897 for (uint8_t Byte : DebugLocs.
getBytes(Entry))
1898 Streamer.
EmitInt8(Byte, Comment != End ? *(Comment++) :
"");
1908 if (Value.
isInt()) {
1909 if (BT && (BT->
getEncoding() == dwarf::DW_ATE_signed ||
1933 assert(Begin != End &&
"unexpected location list entry with empty range");
1938 if (Value.isFragment()) {
1942 }) &&
"all values are expected to be fragments");
1943 assert(std::is_sorted(Values.begin(), Values.end()) &&
1944 "fragments are expected to be sorted");
1946 for (
auto Fragment : Values)
1950 assert(Values.size() == 1 &&
"only fragments may have >1 value");
1953 DwarfExpr.finalize();
1983 Asm->
OutStreamer->AddComment(
"Segment selector size");
1996 Asm->
OutStreamer->AddComment(
"Offset entry count");
2018 Asm->
OutStreamer->AddComment(
"Offset entry count");
2026 void DwarfDebug::emitDebugLoc() {
2104 void DwarfDebug::emitDebugLocDWO() {
2118 unsigned idx = AddrPool.
getIndex(Entry.BeginSym);
2134 void DwarfDebug::emitDebugARanges() {
2139 for (
const SymbolCU &SCU : ArangeLabels) {
2140 if (SCU.Sym->isInSection()) {
2142 MCSection *Section = &SCU.Sym->getSection();
2144 SectionMap[Section].push_back(SCU);
2149 SectionMap[
nullptr].push_back(SCU);
2155 for (
auto &
I : SectionMap) {
2158 if (List.
size() < 1)
2166 Span.
Start = Cur.Sym;
2169 Spans[Cur.CU].push_back(Span);
2193 const MCSymbol *StartSym = List[0].Sym;
2194 for (
size_t n = 1, e = List.
size(); n < e; n++) {
2195 const SymbolCU &Prev = List[n - 1];
2199 if (Cur.
CU != Prev.
CU) {
2201 Span.
Start = StartSym;
2204 Spans[Prev.
CU].push_back(Span);
2217 std::vector<DwarfCompileUnit *> CUs;
2218 for (
const auto &it : Spans) {
2230 std::vector<ArangeSpan> &
List = Spans[CU];
2237 unsigned ContentSize =
2243 unsigned TupleSize = PtrSize * 2;
2249 ContentSize += Padding;
2250 ContentSize += (List.size() + 1) * TupleSize;
2258 emitSectionReference(*CU);
2275 uint64_t
Size = SymSize[Span.Start];
2303 SectionRanges[&Range.getStart()->getSection()].push_back(&Range);
2307 bool BaseIsSet =
false;
2308 for (
const auto &
P : SectionRanges) {
2315 auto *
Base = CUBase;
2316 if (!
Base && (
P.second.size() > 1 || DwarfVersion < 5) &&
2321 Base =
P.second.front()->getStart();
2322 if (DwarfVersion >= 5) {
2324 Asm->
OutStreamer->AddComment(
"DW_RLE_base_addressx");
2325 Asm->
OutStreamer->EmitIntValue(dwarf::DW_RLE_base_addressx, 1);
2326 Asm->
OutStreamer->AddComment(
" base address index");
2333 }
else if (BaseIsSet && DwarfVersion < 5) {
2340 for (
const auto *RS :
P.second) {
2341 const MCSymbol *Begin = RS->getStart();
2342 const MCSymbol *End = RS->getEnd();
2343 assert(Begin &&
"Range without a begin symbol?");
2344 assert(End &&
"Range without an end symbol?");
2346 if (DwarfVersion >= 5) {
2348 Asm->
OutStreamer->AddComment(
"DW_RLE_offset_pair");
2349 Asm->
OutStreamer->EmitIntValue(dwarf::DW_RLE_offset_pair, 1);
2358 }
else if (DwarfVersion >= 5) {
2359 Asm->
OutStreamer->AddComment(
"DW_RLE_startx_length");
2360 Asm->
OutStreamer->EmitIntValue(dwarf::DW_RLE_startx_length, 1);
2371 if (DwarfVersion >= 5) {
2372 Asm->
OutStreamer->AddComment(
"DW_RLE_end_of_list");
2373 Asm->
OutStreamer->EmitIntValue(dwarf::DW_RLE_end_of_list, 1);
2392 void DwarfDebug::emitDebugRanges() {
2396 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2398 if (Holder.getRangeLists().empty())
2403 return Pair.second->getCUNode()->isDebugDirectivesOnly();
2419 void DwarfDebug::emitDebugRangesDWO() {
2425 const auto &Holder = InfoHolder;
2427 if (Holder.getRangeLists().empty())
2433 return Pair.second->getCUNode()->isDebugDirectivesOnly();
2444 void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
2445 for (
auto *MN : Nodes) {
2446 if (
auto *M = dyn_cast<DIMacro>(MN))
2448 else if (
auto *
F = dyn_cast<DIMacroFile>(MN))
2449 emitMacroFile(*
F, U);
2455 void DwarfDebug::emitMacro(
DIMacro &M) {
2461 if (!Value.
empty()) {
2479 void DwarfDebug::emitDebugMacinfo() {
2483 if (
llvm::all_of(CUMap, [](
const decltype(CUMap)::value_type &Pair) {
2484 return Pair.second->getCUNode()->isDebugDirectivesOnly();
2492 for (
const auto &
P : CUMap) {
2493 auto &TheCU = *
P.second;
2498 auto *CUNode = cast<DICompileUnit>(
P.first);
2499 DIMacroNodeArray Macros = CUNode->getMacros();
2500 if (!Macros.empty()) {
2502 handleMacroNodes(Macros, U);
2511 void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
2512 std::unique_ptr<DwarfCompileUnit> NewU) {
2514 if (!CompilationDir.empty())
2515 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
2517 addGnuPubAttributes(*NewU, Die);
2519 SkeletonHolder.addUnit(std::move(NewU));
2524 auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
2529 NewCU.initStmtList();
2532 NewCU.addStringOffsetsStart();
2534 initSkeletonUnit(CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
2541 void DwarfDebug::emitDebugInfoDWO() {
2544 InfoHolder.emitUnits(
true);
2549 void DwarfDebug::emitDebugAbbrevDWO() {
2554 void DwarfDebug::emitDebugLineDWO() {
2556 SplitTypeUnitFileTable.Emit(
2561 void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
2563 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
2565 InfoHolder.getStringOffsetsStartSym());
2571 void DwarfDebug::emitDebugStrDWO() {
2573 emitStringOffsetsTableHeaderDWO();
2581 void DwarfDebug::emitDebugAddr() {
2589 SplitTypeUnitFileTable.maybeSetRootFile(
2592 return &SplitTypeUnitFileTable;
2603 return Result.
high();
2612 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
2615 auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0));
2621 bool TopLevelType = TypeUnitsUnderConstruction.empty();
2622 AddrPool.resetUsedFlag();
2624 auto OwnedUnit = llvm::make_unique<DwarfTypeUnit>(CU,
Asm,
this, &InfoHolder,
2625 getDwoLineTable(CU));
2628 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
2630 NewTU.addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
2634 NewTU.setTypeSignature(Signature);
2635 Ins.first->second = Signature;
2640 ? Asm->getObjFileLowering().getDwarfTypesDWOSection()
2641 : Asm->getObjFileLowering().getDwarfInfoDWOSection();
2642 NewTU.setSection(Section);
2646 ? Asm->getObjFileLowering().getDwarfTypesSection(Signature)
2647 : Asm->getObjFileLowering().getDwarfInfoSection(Signature);
2648 NewTU.setSection(Section);
2650 CU.applyStmtList(UnitDie);
2656 NewTU.addStringOffsetsStart();
2658 NewTU.setType(NewTU.createTypeDIE(CTy));
2661 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
2662 TypeUnitsUnderConstruction.clear();
2666 if (AddrPool.hasBeenUsed()) {
2671 for (
const auto &TU : TypeUnitsToAdd)
2672 TypeSignatures.erase(TU.second);
2678 CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));
2684 for (
auto &TU : TypeUnitsToAdd) {
2685 InfoHolder.computeSizeAndOffsetsForUnit(TU.first.get());
2689 CU.addDIETypeSignature(RefDie, Signature);
2696 template <
typename DataT>
2715 AccelDebugNames.addName(Ref, Die);
2726 addAccelNameImpl(CU, AccelNames, Name, Die);
2733 addAccelNameImpl(CU, AccelObjC, Name, Die);
2738 addAccelNameImpl(CU, AccelNamespace, Name, Die);
2742 const DIE &Die,
char Flags) {
2743 addAccelNameImpl(CU, AccelTypes, Name, Die);
2751 SectionLabels.insert(std::make_pair(&Sym->
getSection(), Sym));
2755 return SectionLabels.find(S)->second;
const StringMap< const DIE * > & getGlobalTypes() const
const DICompileUnit * getCUNode() const
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry)
Emit the location for a debug loc entry, including the size header.
debug_compile_units_iterator debug_compile_units_end() const
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
An object containing the capability of hashing and adding hash attributes onto a DIE.
const DILocalScope * getScopeNode() const
Builder for DebugLocStream lists.
MCSection * getDwarfStrOffSection() const
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
SectionKind getKind() const
void setLabel(MCSymbol *Sym)
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))
void addUnit(std::unique_ptr< DwarfCompileUnit > U)
Add a unit to the list of CUs.
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
bool isCall(QueryType Type=AnyInBundle) const
void addMMIEntry(const DbgVariable &V)
static cl::opt< bool > DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, cl::desc("Disable debug info printing"))
MCSection * getDwarfAccelObjCSection() const
This struct describes location entries emitted in the .debug_loc section.
const MCSymbol * getBaseAddress() const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
bool hasDebugInfo() const
Returns true if valid debug info is present.
#define DWARF2_FLAG_PROLOGUE_END
MCSection * getDwarfStrSection() const
MCTargetOptions MCOptions
Machine level options.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
This class represents lattice values for constants.
bool isAbstractScope() const
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void setRnglistsTableBaseSym(MCSymbol *Sym)
unsigned getRuntimeVersion() const
MCSection * getDwarfLocSection() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
A Module instance is used to store all the information related to an LLVM module. ...
void setMemoryLocationKind()
Lock this down to become a memory location description.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
const SmallVectorImpl< RangeSpanList > & getRangeLists() const
getRangeLists - Get the vector of range lists.
BufferByteStreamer getStreamer()
Implements a dense probed hash-table based set.
const DIType * getType() const
void push_back(const T &Elt)
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
std::string SplitDwarfFile
uint16_t getDwarfVersion() const
unsigned getReg() const
getReg - Returns the register number.
Collects and handles dwarf debug information.
MCSection * getDwarfAccelNamesSection() const
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
bool hasDelaySlot(QueryType Type=AnyInBundle) const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
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))
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
MD5::MD5Result * getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
SmallVectorImpl< InsnRange > & getRanges()
static enum BaseType getBaseType(const Value *Val)
Return the baseType for Val which states whether Val is exclusively derived from constant/null, or not exclusively derived from constant.
unsigned getDebugSectionOffset() const
static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
This class implements a map that also provides access to all stored values in a deterministic order...
uint64_t getDWOId() const
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
static const char *const DbgTimerName
unsigned const TargetRegisterInfo * TRI
MachineFunction * MF
The current machine function.
MCSection * getDwarfARangesSection() const
StringRef getProducer() const
bool isMetaInstruction() const
Return true if this instruction doesn't produce any output in the form of executable instructions...
LexicalScope - This class is used to track scope information.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
MCSection * getDwarfRnglistsDWOSection() const
VariableDbgInfoMapTy & getVariableDbgInfo()
static void emitListsTableHeaderStart(AsmPrinter *Asm, const DwarfFile &Holder, MCSymbol *TableStart, MCSymbol *TableEnd)
Tagged DWARF-like metadata node.
DebuggerKind
Identify a debugger for "tuning" the debug info.
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support...
void initializeDbgValue(const MachineInstr *DbgValue)
Initialize from a DBG_VALUE instruction.
static const char *const DbgTimerDescription
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
DbgEntity * getExistingAbstractEntity(const DINode *Node)
MCSection * getDwarfRnglistsSection() const
MCSection * getDwarfPubNamesSection() const
virtual void EmitULEB128(uint64_t DWord, const Twine &Comment="")=0
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
DIScope * getScope() const
MCSymbol * getRnglistsTableBaseSym() const
DebugLoc PrevInstLoc
Previous instruction's location information.
DbgLabelInstrMap DbgLabels
Mapping of inlined labels and DBG_LABEL machine instruction.
StringRef getSplitDebugFilename() const
#define DWARF2_FLAG_IS_STMT
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DebugLocEntry::Value &Value, DwarfExpression &DwarfExpr)
StringRef getFlags() const
MCSection * getDwarfMacinfoSection() const
MCSymbol * getLoclistsTableBaseSym() const
LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
MCSection * getDwarfLocDWOSection() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isDebugDirectivesOnly() const
const HexagonInstrInfo * TII
const MCExpr * getFunctionLocalOffsetAfterInsn(const MachineInstr *MI)
Return the function-local offset of an instruction.
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
const ConstantFP * getFPImm() const
unsigned getNumOperands() const
Retuns the total number of operands.
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
This class is basically a combination of TimeRegion and Timer.
static void emitDebugRangesImpl(DwarfDebug &DD, AsmPrinter *Asm, const DwarfFile &Holder, MCSymbol *TableEnd)
const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to...
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
Base class for the full range of assembler expressions which are needed for parsing.
void addSubprogramNames(const DICompileUnit &CU, const DISubprogram *SP, DIE &Die)
The access may reference the value stored in memory.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly...
static StringRef getName(Value *V)
bool getRangesBaseAddress() const
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null. ...
void constructContainingTypeDIEs()
Construct DIEs for types that contain vtables.
void setDWOId(uint64_t DwoId)
virtual void EmitInt8(uint8_t Byte, const Twine &Comment="")=0
void addAccelName(const DICompileUnit &CU, StringRef Name, const DIE &Die)
DenseMap< LexicalScope *, ScopeVars > & getScopeVariables()
Holds a DIExpression and keeps track of how many operands have been consumed so far.
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die)
Computes the CU signature.
AccelTableKind
The kind of accelerator tables we should emit.
#define clEnumVal(ENUMVAL, DESC)
StringRef getFilename() const
DwarfExpression implementation for .debug_loc entries.
This file implements a class to represent arbitrary precision integral constant values and operations...
DIE * getOrCreateTypeDIE(const MDNode *TyNode)
Find existing DIE or create new DIE for the given type.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
static Optional< DebugNameTableKind > getNameTableKind(StringRef Str)
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
const SmallVectorImpl< RangeSpan > & getRanges() const
AddressPool & getAddressPool()
Describes an entry of the various gnu_pub* debug sections.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
unsigned getUniqueID() const
bool isConstantFP() const
MCSymbol * getFunctionBegin() const
static bool validThroughout(LexicalScopes &LScopes, const MachineInstr *DbgValue, const MachineInstr *RangeEnd)
Determine whether a singular DBG_VALUE is valid for the entirety of its enclosing lexical scope...
DenseMap< const MDNode *, DIE * > & getAbstractSPDies()
This class is used to track local variable information.
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
void addAddrTableBase()
Add the DW_AT_addr_base attribute to the unit DIE.
const DILocalVariable * getVariable() const
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
DIMacroNodeArray getElements() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
bool MergeValues(const DebugLocEntry &Next)
If this and Next are describing different pieces of the same variable, merge them by appending Next's...
static Optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
debug_compile_units_iterator debug_compile_units_begin() const
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
const SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
virtual const TargetInstrInfo * getInstrInfo() const
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))
MCSection * getDwarfAccelTypesSection() const
DIE & addChild(DIE *Child)
Add a child to the DIE.
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
void EmitLabelDifferenceAsULEB128(const MCSymbol *Hi, const MCSymbol *Lo) const
Emit something like ".uleb128 Hi-Lo".
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))
MCSection * getDwarfAbbrevSection() const
const DIExpression * Expr
void resolve()
Resolve a unique, unresolved node.
MCSection * getDwarfAbbrevDWOSection() const
TargetInstrInfo - Interface to description of machine instruction set.
LexicalScope * findAbstractScope(const DILocalScope *N)
findAbstractScope - Find an abstract scope or return null.
static void forBothCUs(DwarfCompileUnit &CU, Func F)
MCSymbol * getStringOffsetsStartSym() const
MCSection * getDwarfGnuPubTypesSection() const
DebuggerKind DebuggerTuning
Which debugger to tune for.
This dwarf writer support class manages information associated with a source file.
DwarfStringPool & getStringPool()
Returns the string pool.
initializer< Ty > init(const Ty &Val)
StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
void endModule() override
Emit all Dwarf sections that should come after the content.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MCSymbol * getSym() const
const MachineBasicBlock * PrevInstBB
const MCAsmInfo * MAI
Target Asm Printer information.
static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)
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))
MCSection * getDwarfAddrSection() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
DISubprogram * getSubprogram() const
Get the attached subprogram.
const DILocation * getInlinedAt() const
static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
const DIExpression * getExpression() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const GlobalValue * getGlobal() const
A structured debug information entry.
AsmPrinter * Asm
Target of debug info emission.
std::pair< iterator, bool > insert(const ValueT &V)
ArrayRef< char > getBytes(const Entry &E) const
TargetMachine & TM
Target machine description.
This class is intended to be used as a driving class for all asm writers.
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
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.
unsigned getOrCreateSourceID(const DIFile *File) override
Look up the source ID for the given file.
void finishEntityDefinition(const DbgEntity *Entity)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
DIImportedEntityArray getImportedEntities() const
MCSection * getDwarfLineDWOSection() const
bool isPS4CPU() const
Tests whether the target is the PS4 CPU.
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))
DwarfDebug(AsmPrinter *A, Module *M)
void addAccelType(const DICompileUnit &CU, StringRef Name, const DIE &Die, char Flags)
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...
const Triple & getTargetTriple() const
void computeSizeAndOffsets()
Compute the size and offset of all the DIEs.
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
ArrayRef< Entry > getEntries(const List &L) const
StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
bool addScopeVariable(LexicalScope *LS, DbgVariable *Var)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
GDBIndexEntryLinkage Linkage
MDNode * getScope() const
A pair of GlobalVariable and DIExpression.
void emitDWARF5AccelTable(AsmPrinter *Asm, AccelTable< DWARF5AccelTableData > &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit >> CUs)
Helper used to pair up a symbol and its DWARF compile unit.
StringRef getDirectory() const
iterator erase(const_iterator CI)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
bool hasDwarfPubSections() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const DwarfCompileUnit & getCU() const
unsigned getDwarfVersion() const
Returns the Dwarf Version by checking module flags.
const DILocation * getInlinedAt() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StringRef OperationEncodingString(unsigned Encoding)
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
static const char *const DWARFGroupDescription
Triple - Helper class for working with autoconf configuration names.
ArrayRef< FrameIndexExpr > getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
An imported module (C++ using directive or similar).
bool useLocSection() const
Returns whether .debug_loc section should be emitted.
void sort(IteratorTy Start, IteratorTy End)
DIE * constructImportedEntityDIE(const DIImportedEntity *Module)
Construct import_module DIE.
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
const APFloat & getValueAPF() const
void addSectionLabel(const MCSymbol *Sym)
void addExpression(DIExpressionCursor &&Expr, unsigned FragmentOffsetInBits=0)
Emit all remaining operations in the DIExpressionCursor.
uint16_t getLanguage() const
SmallVector< RangeSpan, 2 > takeRanges()
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope)
void addScopeLabel(LexicalScope *LS, DbgLabel *Label)
static DebugLoc findPrologueEndLoc(const MachineFunction *MF)
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
DenseMap< LexicalScope *, LabelList > & getScopeLabels()
MCSymbol * getMacroLabelBegin() const
static bool hasObjCCategory(StringRef Name)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
const StringMap< const DIE * > & getGlobalNames() const
void addAccelNamespace(const DICompileUnit &CU, StringRef Name, const DIE &Die)
void setDebugInfoAvailability(bool avail)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
StringRef getName() const
MCSection * getSection() const
Return the section that this DIEUnit will be emitted into.
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
virtual void EmitSLEB128(uint64_t DWord, const Twine &Comment="")=0
Module.h This file contains the declarations for the Module class.
void beginModule()
Emit all Dwarf sections that should come prior to the content.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
MCSymbol * getBeginSymbol()
void finishSubprogramDefinition(const DISubprogram *SP)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
MCSection * getDwarfInfoSection() const
bool useAppleExtensionAttributes() const
void emitInt32(int Value) const
Emit a long directive and value.
MCSection * getDwarfStrOffDWOSection() const
virtual bool isTailCall(const MachineInstr &Inst) const
Determines whether Inst is a tail call instruction.
MCSymbol * getFunctionEnd() const
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry)
Emit an entry for the debug loc section.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getSourceLanguage() const
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))
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
This file contains constants used for implementing Dwarf debug support.
Class for arbitrary precision integers.
static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, const RangeSpanList &List)
Emit a single range list. We handle both DWARF v5 and earlier.
ArrayRef< std::string > getComments(const Entry &E) const
bool fragmentsOverlap(const DIExpression *Other) const
Check if fragments overlap between this DIExpression and Other.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
MCSection * getDwarfPubTypesSection() const
bool isBlockByrefStruct() const
DebugLoc PrologEndLoc
This location indicates end of function prologue and beginning of function body.
void setLoclistsTableBaseSym(MCSymbol *Sym)
const SmallVectorImpl< RangeSpan > & getRanges() const
getRanges - Get the list of ranges for this unit.
dwarf::Tag getTag() const
String pool entry reference.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
A single location or constant.
const MachineBasicBlock * getParent() const
void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT)
Lower this entry into a DWARF expression.
void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)
DIE * getOrCreateContextDIE(const DIScope *Context)
Get context owner's DIE.
void requestLabelAfterInsn(const MachineInstr *MI)
Ensure that a label will be emitted after MI.
MCSection * getDwarfStrDWOSection() const
Representation of each machine instruction.
static StringRef getObjCMethodName(StringRef In)
bool getSplitDebugInlining() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
unsigned getEncoding() const
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
void EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset".
DIE * getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, ArrayRef< GlobalExpr > GlobalExprs)
Get or create global variable DIE.
void addAccelObjC(const DICompileUnit &CU, StringRef Name, const DIE &Die)
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
LLVM_NODISCARD bool empty() const
bool useRangesSection() const
Returns whether ranges section should be emitted.
bool isBlockByrefVariable() const
StringRef getName() const
Return a constant reference to the value's name.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
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...
bool shareAcrossDWOCUs() const
MCSection * getDwarfGnuPubNamesSection() const
Optional< StringRef > getSource() 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...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Base class for debug information backends.
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
DIE & constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram &CalleeSP, bool IsTail, const MCExpr *PCOffset)
Construct a call site entry DIE describing a call within Scope to a callee described by CalleeSP...
unsigned getMacinfoType() const
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
StringRef getValue() const
DwarfCompileUnit * getSkeleton() const
void skippedNonDebugFunction() override
const Module * getModule() const
void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)
Emit all of the strings to the section given.
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...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void addDIETypeSignature(DIE &Die, uint64_t Signature)
Add a type's DW_AT_signature and set the declaration flag.
DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
ArrayRef< LexicalScope * > getAbstractScopesList() const
getAbstractScopesList - Return a reference to list of abstract scopes.
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
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...
DITypeRef getType() const
DILocalScope * getScope() const
Get the local scope for this label.
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
reverse_iterator rbegin()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSection * getDwarfAccelNamespaceSection() const
static const char *const DWARFGroupName
const MCSymbol * getSectionLabel(const MCSection *S)
void emitInt8(int Value) const
Emit a byte directive and value.
LLVM Value Representation.
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
void EmitULEB128(uint64_t Value, const char *Desc=nullptr) const
Emit the specified unsigned leb128 value.
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void emitAbbrevs(MCSection *)
Emit a set of abbreviations to the specific section.
void addSignedConstant(int64_t Value)
Emit a signed constant.
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, Optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
MachineModuleInfo * MMI
Collected machine module information.
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
bool isNVPTX() const
Tests whether the target is NVPTX (32- or 64-bit).
iterator_range< global_iterator > globals()
MachineLocation getLoc() const
StringRef - Represent a constant reference to a string, i.e.
APInt bitcastToAPInt() const
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
MCSection * getDwarfRangesSection() const
bool TimePassesIsEnabled
If the user specifies the -time-passes argument on an LLVM tool command line then the value of this b...
static bool isObjCClass(StringRef Name)
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
DILocalScope * getScope() const
Get the local scope for this variable.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Builder for DebugLocStream entries.
for(unsigned i=Desc.getNumOperands(), e=OldMI.getNumOperands();i !=e;++i)
const MachineOperand & getOperand(unsigned i) const
bool isFragment() const
Return whether this is a piece of an aggregate variable.
const ConstantInt * getCImm() const
MCSymbol * getLabelBegin() const
void addValues(ArrayRef< DebugLocEntry::Value > Vals)
MCSymbol * createTempSymbol(const Twine &Name) const
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, unsigned MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
const ConstantFP * getConstantFP() const
ArrayRef< List > getLists() const
bool empty()
empty - Return true if there is any lexical scope information available.
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
void emitInt16(int Value) const
Emit a short directive and value.
StringRef getName() const
MCSection * getDwarfLoclistsSection() const
Basic type, like 'int' or 'float'.
static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.