index a7b43d80328417bc1b4d2b59ab720879689e7c4b..2302abef31d61e1fe8d52985048f4ee3f32f6845 100644 (file)
/// DW_FORM_addr or DW_FORM_GNU_addr_index.
///
void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
- MCSymbol *Label) {
+ const MCSymbol *Label) {
+
+ if (!DD->useSplitDwarf())
+ return addLocalLabelAddress(Die, Attribute, Label);
+
if (Label)
DD->addArangeLabel(SymbolCU(this, Label));
- if (!DD->useSplitDwarf()) {
- if (Label) {
- DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
- Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
- } else {
- DIEValue *Value = new (DIEValueAllocator) DIEInteger(0);
- Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
- }
+ unsigned idx = DU->getAddrPoolIndex(Label);
+ DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
+ Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
+}
+
+void DwarfCompileUnit::addLocalLabelAddress(DIE *Die,
+ dwarf::Attribute Attribute,
+ const MCSymbol *Label) {
+ if (Label)
+ DD->addArangeLabel(SymbolCU(this, Label));
+
+ if (Label) {
+ DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
+ Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
} else {
- unsigned idx = DU->getAddrPoolIndex(Label);
- DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
- Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEInteger(0);
+ Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
}
}
DIType Ty(TyNode);
assert(Ty.isType());
+ assert(Ty == resolve(Ty.getRef()) &&
+ "type was not uniqued, possible ODR violation.");
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
DIE *ContextDIE = getOrCreateContextDIE(Context);
assert(ContextDIE);
- // Unique the type. This is a noop if the type has no unique identifier.
- Ty = DIType(resolve(Ty.getRef()));
-
DIE *TyDIE = getDIE(Ty);
if (TyDIE)
return TyDIE;
return NDie;
}
-/// Unique C++ member function declarations based on their
-/// context and mangled name.
-DISubprogram
-DwarfUnit::getOdrUniqueSubprogram(DIScope Context, DISubprogram SP) const {
- if (!hasODR() ||
- !Context.isCompositeType() ||
- SP.getLinkageName().empty() ||
- SP.isDefinition())
- return SP;
- // Create a key with the UID of the parent class and this SP's name.
- Twine Key = SP.getContext().getName() + SP.getLinkageName();
- const MDNode *&Entry = DD->getOrCreateOdrMember(Key.str());
- if (!Entry)
- Entry = &*SP;
-
- return DISubprogram(Entry);
-}
-
/// getOrCreateSubprogramDIE - Create new DIE using SP.
DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
// Construct the context before querying for the existence of the DIE in case
// declarations).
DIScope Context = resolve(SP.getContext());
DIE *ContextDIE = getOrCreateContextDIE(Context);
+
// Unique declarations based on the ODR, where applicable.
- SP = getOdrUniqueSubprogram(Context, SP);
+ SP = DISubprogram(DD->resolve(SP.getRef()));
+ assert(SP.Verify());
DIE *SPDie = getDIE(SP);
if (SPDie)
// Add function template parameters.
addTemplateParams(*SPDie, SP.getTemplateParams());
- // If this DIE is going to refer declaration info using AT_specification
- // then there is no need to add other attributes.
- if (DeclDie) {
+ if (DeclDie)
// Refer function declaration directly.
addDIEEntry(SPDie, dwarf::DW_AT_specification, DeclDie);
- return SPDie;
+ // Add the linkage name if we have one and it isn't in the Decl.
+ StringRef LinkageName = SP.getLinkageName();
+ if (!LinkageName.empty()) {
+ if (SPDecl.isSubprogram() && !SPDecl.getLinkageName().empty())
+ assert(SPDecl.getLinkageName() == SP.getLinkageName() &&
+ "decl has a linkage name and it is different");
+ else
+ addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
+ GlobalValue::getRealLinkageName(LinkageName));
}
- // Add the linkage name if we have one.
- StringRef LinkageName = SP.getLinkageName();
- if (!LinkageName.empty())
- addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
- GlobalValue::getRealLinkageName(LinkageName));
+ // If this DIE is going to refer declaration info using AT_specification
+ // then there is no need to add other attributes.
+ if (DeclDie)
+ return SPDie;
// Constructors and operators for anonymous aggregates do not have names.
if (!SP.getName().empty())
// as different languages may have different sizes for indexes.
DIE *IdxTy = getIndexTyDie();
if (!IdxTy) {
- // Construct an anonymous type for index type.
+ // Construct an integer type to use for indexes.
IdxTy = createAndAddDIE(dwarf::DW_TAG_base_type, *UnitDie);
- addString(IdxTy, dwarf::DW_AT_name, "int");
- addUInt(IdxTy, dwarf::DW_AT_byte_size, None, sizeof(int32_t));
+ addString(IdxTy, dwarf::DW_AT_name, "sizetype");
+ addUInt(IdxTy, dwarf::DW_AT_byte_size, None, sizeof(int64_t));
addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
- dwarf::DW_ATE_signed);
+ dwarf::DW_ATE_unsigned);
setIndexTyDie(IdxTy);
}
return StaticMemberDIE;
}
-void DwarfUnit::emitHeader(const MCSection *ASection,
- const MCSymbol *ASectionSym) const {
+void DwarfUnit::emitHeader(const MCSymbol *ASectionSym) const {
Asm->OutStreamer.AddComment("DWARF version number");
Asm->EmitInt16(DD->getDwarfVersion());
Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
// We share one abbreviations table across all units so it's always at the
// start of the section. Use a relocatable offset where needed to ensure
// linking doesn't invalidate that offset.
- Asm->EmitSectionOffset(ASectionSym, ASectionSym);
+ if (ASectionSym)
+ Asm->EmitSectionOffset(ASectionSym, ASectionSym);
+ else
+ // Use a constant value when no symbol is provided.
+ Asm->EmitInt32(0);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
}
+void DwarfUnit::addRange(RangeSpan Range) {
+ // Only add a range for this unit if we're emitting full debug.
+ if (getCUNode().getEmissionKind() == DIBuilder::FullDebug) {
+ // If we have no current ranges just add the range and return, otherwise,
+ // check the current section and CU against the previous section and CU we
+ // emitted into and the subprogram was contained within. If these are the
+ // same then extend our current range, otherwise add this as a new range.
+ if (CURanges.size() == 0 ||
+ this != DD->getPrevCU() ||
+ Asm->getCurrentSection() != DD->getPrevSection()) {
+ CURanges.push_back(Range);
+ return;
+ }
+
+ assert(&(CURanges.back().getEnd()->getSection()) ==
+ &(Range.getEnd()->getSection()) &&
+ "We can only append to a range in the same section!");
+ CURanges.back().setEnd(Range.getEnd());
+ }
+}
+
void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) {
// Define start line table label for each Compile Unit.
MCSymbol *LineTableStartSym =
- Asm->GetTempSymbol("line_table_start", getUniqueID());
- Asm->OutStreamer.getContext().setMCLineTableSymbol(LineTableStartSym,
- getUniqueID());
-
- // Use a single line table if we are generating assembly.
- bool UseTheFirstCU =
- Asm->OutStreamer.hasRawTextSupport() || (getUniqueID() == 0);
+ Asm->OutStreamer.getDwarfLineTableSymbol(getUniqueID());
stmtListIndex = UnitDie->getValues().size();
// The line table entries are not always emitted in assembly, so it
// is not okay to use line_table_start here.
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- addSectionLabel(UnitDie.get(), dwarf::DW_AT_stmt_list,
- UseTheFirstCU ? DwarfLineSectionSym : LineTableStartSym);
- else if (UseTheFirstCU)
- addSectionOffset(UnitDie.get(), dwarf::DW_AT_stmt_list, 0);
+ addSectionLabel(UnitDie.get(), dwarf::DW_AT_stmt_list, LineTableStartSym);
else
addSectionDelta(UnitDie.get(), dwarf::DW_AT_stmt_list, LineTableStartSym,
DwarfLineSectionSym);
UnitDie->getValues()[stmtListIndex]);
}
-void DwarfTypeUnit::emitHeader(const MCSection *ASection,
- const MCSymbol *ASectionSym) const {
- DwarfUnit::emitHeader(ASection, ASectionSym);
+void DwarfTypeUnit::emitHeader(const MCSymbol *ASectionSym) const {
+ DwarfUnit::emitHeader(ASectionSym);
Asm->OutStreamer.AddComment("Type Signature");
Asm->OutStreamer.EmitIntValue(TypeSignature, sizeof(TypeSignature));
Asm->OutStreamer.AddComment("Type DIE Offset");