summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp80
1 files changed, 46 insertions, 34 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index ee14423ca3d0..047676d4c11e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -480,7 +480,7 @@ static bool hasObjCCategory(StringRef Name) {
if (!isObjCClass(Name))
return false;
- return Name.find(") ") != StringRef::npos;
+ return Name.contains(") ");
}
static void getObjCClassCategory(StringRef In, StringRef &Class,
@@ -587,14 +587,6 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
}
}
-DIE &DwarfDebug::constructSubprogramDefinitionDIE(const DISubprogram *SP) {
- DICompileUnit *Unit = SP->getUnit();
- assert(SP->isDefinition() && "Subprogram not a definition");
- assert(Unit && "Subprogram definition without parent unit");
- auto &CU = getOrCreateDwarfCompileUnit(Unit);
- return *CU.getOrCreateSubprogramDIE(SP);
-}
-
/// Represents a parameter whose call site value can be described by applying a
/// debug expression to a register in the forwarded register worklist.
struct FwdRegParamInfo {
@@ -945,7 +937,7 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
continue;
unsigned CallReg = 0;
- DIE *CalleeDIE = nullptr;
+ const DISubprogram *CalleeSP = nullptr;
const Function *CalleeDecl = nullptr;
if (CalleeOp.isReg()) {
CallReg = CalleeOp.getReg();
@@ -955,19 +947,7 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
CalleeDecl = dyn_cast<Function>(CalleeOp.getGlobal());
if (!CalleeDecl || !CalleeDecl->getSubprogram())
continue;
- const DISubprogram *CalleeSP = CalleeDecl->getSubprogram();
-
- if (CalleeSP->isDefinition()) {
- // Ensure that a subprogram DIE for the callee is available in the
- // appropriate CU.
- CalleeDIE = &constructSubprogramDefinitionDIE(CalleeSP);
- } else {
- // Create the declaration DIE if it is missing. This is required to
- // support compilation of old bitcode with an incomplete list of
- // retained metadata.
- CalleeDIE = CU.getOrCreateSubprogramDIE(CalleeSP);
- }
- assert(CalleeDIE && "Must have a DIE for the callee");
+ CalleeSP = CalleeDecl->getSubprogram();
}
// TODO: Omit call site entries for runtime calls (objc_msgSend, etc).
@@ -1004,7 +984,7 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
<< (IsTail ? " [IsTail]" : "") << "\n");
DIE &CallSiteDIE = CU.constructCallSiteEntryDIE(
- ScopeDIE, CalleeDIE, IsTail, PCAddr, CallAddr, CallReg);
+ ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg);
// Optionally emit call-site-param debug info.
if (emitDebugEntryValues()) {
@@ -1427,6 +1407,10 @@ void DwarfDebug::finalizeModuleInfo() {
// Emit all Dwarf sections that should come after the content.
void DwarfDebug::endModule() {
+ // Terminate the pending line table.
+ if (PrevCU)
+ terminateLineTable(PrevCU);
+ PrevCU = nullptr;
assert(CurFn == nullptr);
assert(CurMI == nullptr);
@@ -2102,12 +2086,22 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {
// First known non-DBG_VALUE and non-frame setup location marks
// the beginning of the function body.
- for (const auto &MBB : *MF)
- for (const auto &MI : MBB)
+ DebugLoc LineZeroLoc;
+ for (const auto &MBB : *MF) {
+ for (const auto &MI : MBB) {
if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) &&
- MI.getDebugLoc())
- return MI.getDebugLoc();
- return DebugLoc();
+ MI.getDebugLoc()) {
+ // Scan forward to try to find a non-zero line number. The prologue_end
+ // marks the first breakpoint in the function after the frame setup, and
+ // a compiler-generated line 0 location is not a meaningful breakpoint.
+ // If none is found, return the first location after the frame setup.
+ if (MI.getDebugLoc().getLine())
+ return MI.getDebugLoc();
+ LineZeroLoc = MI.getDebugLoc();
+ }
+ }
+ }
+ return LineZeroLoc;
}
/// Register a source line with debug info. Returns the unique label that was
@@ -2162,24 +2156,42 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
+ Asm->OutStreamer->getContext().setDwarfCompileUnitID(
+ getDwarfCompileUnitIDForLineTable(CU));
+
+ // Record beginning of function.
+ PrologEndLoc = emitInitialLocDirective(
+ *MF, Asm->OutStreamer->getContext().getDwarfCompileUnitID());
+}
+
+unsigned
+DwarfDebug::getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU) {
// Set DwarfDwarfCompileUnitID in MCContext to the Compile Unit this function
// belongs to so that we add to the correct per-cu line table in the
// non-asm case.
if (Asm->OutStreamer->hasRawTextSupport())
// Use a single line table if we are generating assembly.
- Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
+ return 0;
else
- Asm->OutStreamer->getContext().setDwarfCompileUnitID(CU.getUniqueID());
+ return CU.getUniqueID();
+}
- // Record beginning of function.
- PrologEndLoc = emitInitialLocDirective(
- *MF, Asm->OutStreamer->getContext().getDwarfCompileUnitID());
+void DwarfDebug::terminateLineTable(const DwarfCompileUnit *CU) {
+ const auto &CURanges = CU->getRanges();
+ auto &LineTable = Asm->OutStreamer->getContext().getMCDwarfLineTable(
+ getDwarfCompileUnitIDForLineTable(*CU));
+ // Add the last range label for the given CU.
+ LineTable.getMCLineSections().addEndEntry(
+ const_cast<MCSymbol *>(CURanges.back().End));
}
void DwarfDebug::skippedNonDebugFunction() {
// If we don't have a subprogram for this function then there will be a hole
// in the range information. Keep note of this by setting the previously used
// section to nullptr.
+ // Terminate the pending line table.
+ if (PrevCU)
+ terminateLineTable(PrevCU);
PrevCU = nullptr;
CurFn = nullptr;
}