cl::init(false));
namespace {
-enum DefaultOnOff {
- Default,
- Enable,
- Disable
-};
+enum DefaultOnOff { Default, Enable, Disable };
}
static cl::opt<DefaultOnOff>
: Asm(A), MMI(Asm->MMI), FirstCU(0), SourceIdMap(DIEValueAllocator),
PrevLabel(NULL), GlobalRangeCount(0),
InfoHolder(A, "info_string", DIEValueAllocator), HasCURanges(false),
+ UsedNonDefaultText(false),
SkeletonHolder(A, "skel_string", DIEValueAllocator) {
DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = 0;
SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, FunctionBeginSym);
SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, FunctionEndSym);
- // Add this range to the list of ranges for the CU.
- RangeSpan Span(FunctionBeginSym, FunctionEndSym);
- SPCU->addRange(llvm_move(Span));
-
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
const MDNode *N) {
DIImportedEntity Module(N);
- if (!Module.Verify())
- return;
+ assert(Module.Verify());
if (DIE *D = TheCU->getOrCreateContextDIE(Module.getContext()))
constructImportedEntityDIE(TheCU, Module, D);
}
void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
const MDNode *N, DIE *Context) {
DIImportedEntity Module(N);
- if (!Module.Verify())
- return;
+ assert(Module.Verify());
return constructImportedEntityDIE(TheCU, Module, Context);
}
// FIXME: We should use ranges if we have multiple compile units or
// allow reordering of code ala .subsections_via_symbols in mach-o.
DwarfCompileUnit *U = SkCU ? SkCU : static_cast<DwarfCompileUnit *>(TheU);
- if (useCURanges() && TheU->getRanges().size())
+ if (useCURanges() && TheU->getRanges().size()) {
addSectionLabel(Asm, U, U->getUnitDie(), dwarf::DW_AT_ranges,
Asm->GetTempSymbol("cu_ranges", U->getUniqueID()),
DwarfDebugRangeSectionSym);
- else
+
+ // A DW_AT_low_pc attribute may also be specified in combination with
+ // DW_AT_ranges to specify the default base address for use in location
+ // lists (see Section 2.6.2) and range lists (see Section 2.17.3).
+ U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ 0);
+ } else
U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
0);
}
if (Section) {
// We can't call MCSection::getLabelEndName, as it's only safe to do so
// if we know the section name up-front. For user-created sections, the
- // resulting
- // label may not be valid to use as a label. (section names can use a
- // greater
- // set of characters on some systems)
+ // resulting label may not be valid to use as a label. (section names can
+ // use a greater set of characters on some systems)
Sym = Asm->GetTempSymbol("debug_end", ID);
Asm->OutStreamer.SwitchSection(Section);
Asm->OutStreamer.EmitLabel(Sym);
}
// For now only turn on CU ranges if we've explicitly asked for it,
- // we have -ffunction-sections enabled, or we've emitted a function
- // into a unique section. At this point all sections should be finalized
- // except for dwarf sections.
- HasCURanges = DwarfCURanges || Asm->TM.debugUseUniqueSections() ||
+ // we have -ffunction-sections enabled, we've emitted a function
+ // into a unique section, or we're using LTO. If we're using LTO then
+ // we can't know that any particular function in the module is correlated
+ // to a particular CU and so we need to be conservative. At this point all
+ // sections should be finalized except for dwarf sections.
+ HasCURanges = DwarfCURanges || UsedNonDefaultText || (CUMap.size() > 1) ||
TargetMachine::getFunctionSections();
}
}
}
-// Get MDNode for DebugLoc's scope.
-static MDNode *getScopeNode(DebugLoc DL, const LLVMContext &Ctx) {
- if (MDNode *InlinedAt = DL.getInlinedAt(Ctx))
- return getScopeNode(DebugLoc::getFromDILocation(InlinedAt), Ctx);
- return DL.getScope(Ctx);
-}
-
-// Walk up the scope chain of given debug loc and find line number info
-// for the function.
-static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) {
- const MDNode *Scope = getScopeNode(DL, Ctx);
- DISubprogram SP = getDISubprogram(Scope);
- if (SP.isSubprogram()) {
- // Check for number of operands since the compatibility is
- // cheap here.
- if (SP->getNumOperands() > 19)
- return DebugLoc::get(SP.getScopeLineNumber(), 0, SP);
- else
- return DebugLoc::get(SP.getLineNumber(), 0, SP);
- }
-
- return DebugLoc();
-}
-
// Gather pre-function debug information. Assumes being called immediately
// after the function entry point has been emitted.
void DwarfDebug::beginFunction(const MachineFunction *MF) {
else
Asm->OutStreamer.getContext().setDwarfCompileUnitID(TheCU->getUniqueID());
+ // Check the current section against the standard text section. If different
+ // keep track so that we will know when we're emitting functions into multiple
+ // sections.
+ if (Asm->getObjFileLowering().getTextSection() != Asm->getCurrentSection())
+ UsedNonDefaultText = true;
+
// Emit a label for the function so that we have a beginning address.
FunctionBeginSym = Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber());
// Assumes in correct section after the entry point.
// Record beginning of function.
if (!PrologEndLoc.isUnknown()) {
DebugLoc FnStartDL =
- getFnDebugLoc(PrologEndLoc, MF->getFunction()->getContext());
+ PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext());
recordSourceLine(
FnStartDL.getLine(), FnStartDL.getCol(),
FnStartDL.getScope(MF->getFunction()->getContext()),
FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber());
// Assumes in correct section after the entry point.
Asm->OutStreamer.EmitLabel(FunctionEndSym);
+
// Set DwarfDwarfCompileUnitID in MCContext to default value.
Asm->OutStreamer.getContext().setDwarfCompileUnitID(0);
}
DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope);
-
if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn))
TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr);
+ // Add the range of this function to the list of ranges for the CU.
+ RangeSpan Span(FunctionBeginSym, FunctionEndSym);
+ TheCU->addRange(llvm_move(Span));
+
// Clear debug info
for (ScopeVariablesMap::iterator I = ScopeVariables.begin(),
E = ScopeVariables.end();
unsigned char Size = Asm->getDataLayout().getPointerSize();
// Grab the specific ranges for the compile units in the module.
- for (DenseMap<const MDNode *, DwarfCompileUnit *>::iterator I = CUMap.begin(),
- E = CUMap.end();
+ for (MapVector<const MDNode *, DwarfCompileUnit *>::iterator
+ I = CUMap.begin(),
+ E = CUMap.end();
I != E; ++I) {
DwarfCompileUnit *TheCU = I->second;
void DwarfDebug::addDwarfTypeUnitType(DICompileUnit CUNode,
StringRef Identifier, DIE *RefDie,
DICompositeType CTy) {
+ // Flag the type unit reference as a declaration so that if it contains
+ // members (implicit special members, static data member definitions, member
+ // declarations for definitions in this CU, etc) consumers don't get confused
+ // and think this is a full definition.
+ CUMap.begin()->second->addFlag(RefDie, dwarf::DW_AT_declaration);
const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy];
if (TU) {