diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/AsmPrinter')
29 files changed, 455 insertions, 264 deletions
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h index e0ce3f9..211fc98 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h @@ -48,5 +48,5 @@ public: void resetUsedFlag() { HasBeenUsed = false; } }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 95da588..8a7e9f9 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -179,7 +179,7 @@ bool AsmPrinter::doInitialization(Module &M) { OutStreamer->InitSections(false); - Mang = new Mangler(TM.getDataLayout()); + Mang = new Mangler(); // Emit the version-min deplyment target directive if needed. // @@ -2086,8 +2086,12 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, MCValue MV; if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute()) return; + const MCSymbolRefExpr *SymA = MV.getSymA(); + if (!SymA) + return; - const MCSymbol *GOTEquivSym = &MV.getSymA()->getSymbol(); + // Check that GOT equivalent symbol is cached. + const MCSymbol *GOTEquivSym = &SymA->getSymbol(); if (!AP.GlobalGOTEquivs.count(GOTEquivSym)) return; @@ -2095,8 +2099,11 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, if (!BaseGV) return; + // Check for a valid base symbol const MCSymbol *BaseSym = AP.getSymbol(BaseGV); - if (BaseSym != &MV.getSymB()->getSymbol()) + const MCSymbolRefExpr *SymB = MV.getSymB(); + + if (!SymB || BaseSym != &SymB->getSymbol()) return; // Make sure to match: @@ -2292,11 +2299,10 @@ MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV, TM); } -/// GetExternalSymbolSymbol - Return the MCSymbol for the specified -/// ExternalSymbol. +/// Return the MCSymbol for the specified ExternalSymbol. MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { SmallString<60> NameStr; - Mang->getNameWithPrefix(NameStr, Sym); + Mangler::getNameWithPrefix(NameStr, Sym, *TM.getDataLayout()); return OutContext.getOrCreateSymbol(NameStr); } @@ -2384,8 +2390,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { if (isVerbose()) OutStreamer->AddComment("Block address taken"); - std::vector<MCSymbol*> Symbols = MMI->getAddrLabelSymbolToEmit(BB); - for (auto *Sym : Symbols) + for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB)) OutStreamer->EmitLabel(Sym); } diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 8ee613b..ad180b6 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -261,8 +261,7 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const { // Emit the DIE attribute values. for (const auto &V : Die.values()) { dwarf::Attribute Attr = V.getAttribute(); - dwarf::Form Form = V.getForm(); - assert(Form && "Too many attributes for DIE (check abbreviation)"); + assert(V.getForm() && "Too many attributes for DIE (check abbreviation)"); if (isVerbose()) { OutStreamer->AddComment(dwarf::AttributeString(Attr)); @@ -272,13 +271,13 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const { } // Emit an attribute using the defined form. - V.EmitValue(this, Form); + V.EmitValue(this); } // Emit the DIE children if any. if (Die.hasChildren()) { for (auto &Child : Die.children()) - emitDwarfDIE(*Child); + emitDwarfDIE(Child); OutStreamer->AddComment("End Of Children Mark"); EmitInt8(0); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h b/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h index 7a712a0..0cc829f 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h @@ -103,6 +103,6 @@ public: } }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 4847de4..46dbc76 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -165,25 +165,23 @@ void DIE::print(raw_ostream &O, unsigned IndentCount) const { } IndentCount += 2; - for (unsigned i = 0, N = Values.size(); i < N; ++i) { + unsigned I = 0; + for (const auto &V : Values) { O << Indent; if (!isBlock) - O << dwarf::AttributeString(Values[i].getAttribute()); + O << dwarf::AttributeString(V.getAttribute()); else - O << "Blk[" << i << "]"; + O << "Blk[" << I++ << "]"; - O << " " - << dwarf::FormEncodingString(Values[i].getForm()) - << " "; - Values[i].print(O); + O << " " << dwarf::FormEncodingString(V.getForm()) << " "; + V.print(O); O << "\n"; } IndentCount -= 2; - for (unsigned j = 0, M = Children.size(); j < M; ++j) { - Children[j]->print(O, IndentCount+4); - } + for (const auto &Child : children()) + Child.print(O, IndentCount + 4); if (!isBlock) O << "\n"; } @@ -193,7 +191,7 @@ void DIE::dump() { } #endif -void DIEValue::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { +void DIEValue::EmitValue(const AsmPrinter *AP) const { switch (Ty) { case isNone: llvm_unreachable("Expected valid DIEValue"); @@ -205,7 +203,7 @@ void DIEValue::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { } } -unsigned DIEValue::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { +unsigned DIEValue::SizeOf(const AsmPrinter *AP) const { switch (Ty) { case isNone: llvm_unreachable("Expected valid DIEValue"); @@ -507,8 +505,8 @@ void DIETypeSignature::print(raw_ostream &O) const { /// unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const { if (!Size) { - for (unsigned i = 0, N = Values.size(); i < N; ++i) - Size += Values[i].SizeOf(AP, Values[i].getForm()); + for (const auto &V : Values) + Size += V.SizeOf(AP); } return Size; @@ -527,8 +525,8 @@ void DIELoc::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { Asm->EmitULEB128(Size); break; } - for (unsigned i = 0, N = Values.size(); i < N; ++i) - Values[i].EmitValue(Asm, Values[i].getForm()); + for (const auto &V : Values) + V.EmitValue(Asm); } /// SizeOf - Determine size of location data in bytes. @@ -560,8 +558,8 @@ void DIELoc::print(raw_ostream &O) const { /// unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const { if (!Size) { - for (unsigned i = 0, N = Values.size(); i < N; ++i) - Size += Values[i].SizeOf(AP, Values[i].getForm()); + for (const auto &V : Values) + Size += V.SizeOf(AP); } return Size; @@ -578,8 +576,8 @@ void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break; } - for (unsigned i = 0, N = Values.size(); i < N; ++i) - Values[i].EmitValue(Asm, Values[i].getForm()); + for (const auto &V : Values) + V.EmitValue(Asm); } /// SizeOf - Determine size of block data in bytes. diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp index 1445254..5e60156 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -263,7 +263,7 @@ void DIEHash::hashDIEEntry(dwarf::Attribute Attribute, dwarf::Tag Tag, // Hash all of the values in a block like set of values. This assumes that // all of the data is going to be added as integers. -void DIEHash::hashBlockData(const DIE::value_range &Values) { +void DIEHash::hashBlockData(const DIE::const_value_range &Values) { for (const auto &V : Values) Hash.update((uint64_t)V.getDIEInteger().getValue()); } @@ -454,15 +454,15 @@ void DIEHash::computeHash(const DIE &Die) { for (auto &C : Die.children()) { // 7.27 Step 7 // If C is a nested type entry or a member function entry, ... - if (isType(C->getTag()) || C->getTag() == dwarf::DW_TAG_subprogram) { - StringRef Name = getDIEStringAttr(*C, dwarf::DW_AT_name); + if (isType(C.getTag()) || C.getTag() == dwarf::DW_TAG_subprogram) { + StringRef Name = getDIEStringAttr(C, dwarf::DW_AT_name); // ... and has a DW_AT_name attribute if (!Name.empty()) { - hashNestedType(*C, Name); + hashNestedType(C, Name); continue; } } - computeHash(*C); + computeHash(C); } // Following the last (or if there are no children), append a zero byte. diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h index 789e6dd..833ca02 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DIEHash.h @@ -128,7 +128,7 @@ private: /// \brief Hashes the data in a block like DIEValue, e.g. DW_FORM_block or /// DW_FORM_exprloc. - void hashBlockData(const DIE::value_range &Values); + void hashBlockData(const DIE::const_value_range &Values); /// \brief Hashes the contents pointed to in the .debug_loc section. void hashLocList(const DIELocList &LocList); @@ -157,6 +157,6 @@ private: AsmPrinter *AP; DenseMap<const DIE *, unsigned> Numbering; }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h index 5d40050..546d1b4 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h @@ -55,6 +55,6 @@ public: void calculateDbgValueHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &Result); -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index 083228b..afffa83 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -142,7 +142,7 @@ public: } /// \brief Lower this entry into a DWARF expression. - void finalize(const AsmPrinter &AP, DebugLocStream &Locs, + void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT); }; @@ -175,6 +175,6 @@ inline bool operator<(const DebugLocEntry::Value &A, B.getExpression()->getBitPieceOffset(); } -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp new file mode 100644 index 0000000..7e8ed71 --- /dev/null +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp @@ -0,0 +1,46 @@ +//===- DebugLocStream.cpp - DWARF debug_loc stream --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DebugLocStream.h" +#include "DwarfDebug.h" +#include "llvm/CodeGen/AsmPrinter.h" + +using namespace llvm; + +bool DebugLocStream::finalizeList(AsmPrinter &Asm) { + if (Lists.back().EntryOffset == Entries.size()) { + // Empty list. Delete it. + Lists.pop_back(); + return false; + } + + // Real list. Generate a label for it. + Lists.back().Label = Asm.createTempSymbol("debug_loc"); + return true; +} + +void DebugLocStream::finalizeEntry() { + if (Entries.back().ByteOffset != DWARFBytes.size()) + return; + + // The last entry was empty. Delete it. + Comments.erase(Comments.begin() + Entries.back().CommentOffset, + Comments.end()); + Entries.pop_back(); + + assert(Lists.back().EntryOffset <= Entries.size() && + "Popped off more entries than are in the list"); +} + +DebugLocStream::ListBuilder::~ListBuilder() { + if (!Locs.finalizeList(Asm)) + return; + V.initializeDbgValue(&MI); + V.setDebugLocListIndex(ListIndex); +} diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h index 1ae385d..3656e9d 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h @@ -15,7 +15,11 @@ #include "ByteStreamer.h" namespace llvm { + +class AsmPrinter; +class DbgVariable; class DwarfCompileUnit; +class MachineInstr; class MCSymbol; /// \brief Byte stream of .debug_loc entries. @@ -29,10 +33,10 @@ class DebugLocStream { public: struct List { DwarfCompileUnit *CU; - MCSymbol *Label; + MCSymbol *Label = nullptr; size_t EntryOffset; - List(DwarfCompileUnit *CU, MCSymbol *Label, size_t EntryOffset) - : CU(CU), Label(Label), EntryOffset(EntryOffset) {} + List(DwarfCompileUnit *CU, size_t EntryOffset) + : CU(CU), EntryOffset(EntryOffset) {} }; struct Entry { const MCSymbol *BeginSym; @@ -61,18 +65,30 @@ public: const List &getList(size_t LI) const { return Lists[LI]; } ArrayRef<List> getLists() const { return Lists; } + class ListBuilder; + class EntryBuilder; + +private: /// \brief Start a new .debug_loc entry list. /// /// Start a new .debug_loc entry list. Return the new list's index so it can /// be retrieved later via \a getList(). /// /// Until the next call, \a startEntry() will add entries to this list. - size_t startList(DwarfCompileUnit *CU, MCSymbol *Label) { + size_t startList(DwarfCompileUnit *CU) { size_t LI = Lists.size(); - Lists.emplace_back(CU, Label, Entries.size()); + Lists.emplace_back(CU, Entries.size()); return LI; } + /// Finalize a .debug_loc entry list. + /// + /// If there are no entries in this list, delete it outright. Otherwise, + /// create a label with \a Asm. + /// + /// \return false iff the list is deleted. + bool finalizeList(AsmPrinter &Asm); + /// \brief Start a new .debug_loc entry. /// /// Until the next call, bytes added to the stream will be added to this @@ -81,6 +97,10 @@ public: Entries.emplace_back(BeginSym, EndSym, DWARFBytes.size(), Comments.size()); } + /// Finalize a .debug_loc entry, deleting if it's empty. + void finalizeEntry(); + +public: BufferByteStreamer getStreamer() { return BufferByteStreamer(DWARFBytes, Comments, GenerateComments); } @@ -129,5 +149,45 @@ private: return Entries[EI + 1].CommentOffset - Entries[EI].CommentOffset; } }; + +/// Builder for DebugLocStream lists. +class DebugLocStream::ListBuilder { + DebugLocStream &Locs; + AsmPrinter &Asm; + DbgVariable &V; + const MachineInstr &MI; + size_t ListIndex; + +public: + ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm, + DbgVariable &V, const MachineInstr &MI) + : Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)) {} + + /// Finalize the list. + /// + /// If the list is empty, delete it. Otherwise, finalize it by creating a + /// temp symbol in \a Asm and setting up the \a DbgVariable. + ~ListBuilder(); + + DebugLocStream &getLocs() { return Locs; } +}; + +/// Builder for DebugLocStream entries. +class DebugLocStream::EntryBuilder { + DebugLocStream &Locs; + +public: + EntryBuilder(ListBuilder &List, const MCSymbol *Begin, const MCSymbol *End) + : Locs(List.getLocs()) { + Locs.startEntry(Begin, End); + } + + /// Finalize the entry, deleting it if it's empty. + ~EntryBuilder() { Locs.finalizeEntry(); } + + BufferByteStreamer getStreamer() { return Locs.getStreamer(); } +}; + } // namespace llvm + #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h index cc677c2..4d81441 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -252,5 +252,5 @@ public: void dump() { print(dbgs()); } #endif }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 45c56fb..fc54a29 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -42,7 +42,8 @@ void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, DD->addArangeLabel(SymbolCU(this, Label)); unsigned idx = DD->getAddressPool().getIndex(Label); - Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, DIEInteger(idx)); + Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_GNU_addr_index, + DIEInteger(idx)); } void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, @@ -52,9 +53,11 @@ void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, DD->addArangeLabel(SymbolCU(this, Label)); if (Label) - Die.addValue(Attribute, dwarf::DW_FORM_addr, DIELabel(Label)); + Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, + DIELabel(Label)); else - Die.addValue(Attribute, dwarf::DW_FORM_addr, DIEInteger(0)); + Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr, + DIEInteger(0)); } unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName, @@ -225,16 +228,15 @@ void DwarfCompileUnit::addRange(RangeSpan Range) { CURanges.back().setEnd(Range.getEnd()); } -void DwarfCompileUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute, - const MCSymbol *Label, - const MCSymbol *Sec) { +DIE::value_iterator +DwarfCompileUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute, + const MCSymbol *Label, const MCSymbol *Sec) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - addLabel(Die, Attribute, - DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset - : dwarf::DW_FORM_data4, - Label); - else - addSectionDelta(Die, Attribute, Label, Sec); + return addLabel(Die, Attribute, + DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset + : dwarf::DW_FORM_data4, + Label); + return addSectionDelta(Die, Attribute, Label, Sec); } void DwarfCompileUnit::initStmtList() { @@ -242,20 +244,19 @@ void DwarfCompileUnit::initStmtList() { MCSymbol *LineTableStartSym = Asm->OutStreamer->getDwarfLineTableSymbol(getUniqueID()); - stmtListIndex = std::distance(UnitDie.values_begin(), UnitDie.values_end()); - // DW_AT_stmt_list is a offset of line number information for this // compile unit in debug_line section. For split dwarf this is // left in the skeleton CU and so not included. // The line table entries are not always emitted in assembly, so it // is not okay to use line_table_start here. const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym, - TLOF.getDwarfLineSection()->getBeginSymbol()); + StmtListValue = + addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym, + TLOF.getDwarfLineSection()->getBeginSymbol()); } void DwarfCompileUnit::applyStmtList(DIE &D) { - D.addValue(UnitDie.values_begin()[stmtListIndex]); + D.addValue(DIEValueAllocator, *StmtListValue); } void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, @@ -300,7 +301,7 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) { // Construct a DIE for this scope. void DwarfCompileUnit::constructScopeDIE( - LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) { + LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) { if (!Scope || !Scope->getScopeNode()) return; @@ -311,12 +312,12 @@ void DwarfCompileUnit::constructScopeDIE( "constructSubprogramScopeDIE for non-inlined " "subprograms"); - SmallVector<std::unique_ptr<DIE>, 8> Children; + SmallVector<DIE *, 8> Children; // We try to create the scope DIE first, then the children DIEs. This will // avoid creating un-used children then removing them later when we find out // the scope DIE is null. - std::unique_ptr<DIE> ScopeDIE; + DIE *ScopeDIE; if (Scope->getParent() && isa<DISubprogram>(DS)) { ScopeDIE = constructInlinedScopeDIE(Scope); if (!ScopeDIE) @@ -361,11 +362,13 @@ void DwarfCompileUnit::constructScopeDIE( FinalChildren.push_back(std::move(ScopeDIE)); } -void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, - const MCSymbol *Hi, const MCSymbol *Lo) { - Die.addValue(Attribute, DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset - : dwarf::DW_FORM_data4, - new (DIEValueAllocator) DIEDelta(Hi, Lo)); +DIE::value_iterator +DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, + const MCSymbol *Hi, const MCSymbol *Lo) { + return Die.addValue(DIEValueAllocator, Attribute, + DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset + : dwarf::DW_FORM_data4, + new (DIEValueAllocator) DIEDelta(Hi, Lo)); } void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, @@ -413,8 +416,7 @@ void DwarfCompileUnit::attachRangesOrLowHighPC( // This scope represents inlined body of a function. Construct DIE to // represent this concrete inlined copy of the function. -std::unique_ptr<DIE> -DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { +DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { assert(Scope->getScopeNode()); auto *DS = Scope->getScopeNode(); auto *InlinedSP = getDISubprogram(DS); @@ -423,7 +425,7 @@ DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP]; assert(OriginDIE && "Unable to find original DIE for an inlined subprogram."); - auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_inlined_subroutine); + auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine); addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE); attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges()); @@ -443,12 +445,11 @@ DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) { // Construct new DW_TAG_lexical_block for this scope and attach // DW_AT_low_pc/DW_AT_high_pc labels. -std::unique_ptr<DIE> -DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { +DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { if (DD->isLexicalScopeDIENull(Scope)) return nullptr; - auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_lexical_block); + auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block); if (Scope->isAbstractScope()) return ScopeDIE; @@ -458,18 +459,16 @@ DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) { } /// constructVariableDIE - Construct a DIE for the given DbgVariable. -std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, - bool Abstract) { +DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) { auto D = constructVariableDIEImpl(DV, Abstract); DV.setDIE(*D); return D; } -std::unique_ptr<DIE> -DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, - bool Abstract) { +DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, + bool Abstract) { // Define variable debug information entry. - auto VariableDie = make_unique<DIE>(DV.getTag()); + auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag()); if (Abstract) { applyVariableAttributes(DV, *VariableDie); @@ -508,7 +507,7 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, } // .. else use frame index. - if (DV.getFrameIndex().back() == ~0) + if (DV.getFrameIndex().empty()) return VariableDie; auto Expr = DV.getExpression().begin(); @@ -529,17 +528,18 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, return VariableDie; } -std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE( - DbgVariable &DV, const LexicalScope &Scope, DIE *&ObjectPointer) { +DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, + const LexicalScope &Scope, + DIE *&ObjectPointer) { auto Var = constructVariableDIE(DV, Scope.isAbstractScope()); if (DV.isObjectPointer()) - ObjectPointer = Var.get(); + ObjectPointer = Var; return Var; } -DIE *DwarfCompileUnit::createScopeChildrenDIE( - LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &Children, - unsigned *ChildScopeCount) { +DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, + SmallVectorImpl<DIE *> &Children, + unsigned *ChildScopeCount) { DIE *ObjectPointer = nullptr; for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope)) @@ -580,13 +580,14 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) { // variadic function. if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] && !includeMinimalInlineScopes()) - ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters)); + ScopeDIE.addChild( + DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters)); } DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE) { // We create children when the scope DIE is not null. - SmallVector<std::unique_ptr<DIE>, 8> Children; + SmallVector<DIE *, 8> Children; DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children); // Add children @@ -629,14 +630,16 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); } -std::unique_ptr<DIE> -DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity *Module) { - std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module->getTag()); - insertDIE(Module, IMDie.get()); +DIE *DwarfCompileUnit::constructImportedEntityDIE( + const DIImportedEntity *Module) { + DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag()); + insertDIE(Module, IMDie); DIE *EntityDie; auto *Entity = resolve(Module->getEntity()); if (auto *NS = dyn_cast<DINamespace>(Entity)) EntityDie = getOrCreateNameSpace(NS); + else if (auto *M = dyn_cast<DIModule>(Entity)) + EntityDie = getOrCreateModule(M); else if (auto *SP = dyn_cast<DISubprogram>(Entity)) EntityDie = getOrCreateSubprogramDIE(SP); else if (auto *T = dyn_cast<DIType>(Entity)) @@ -686,7 +689,7 @@ void DwarfCompileUnit::collectDeadVariables(const DISubprogram *SP) { SPDIE = getDIE(SP); assert(SPDIE); for (const DILocalVariable *DV : Variables) { - DbgVariable NewVar(DV, /* IA */ nullptr, /* Expr */ nullptr, DD); + DbgVariable NewVar(DV, /* IA */ nullptr, DD); auto VariableDie = constructVariableDIE(NewVar); applyVariableAttributes(NewVar, *VariableDie); SPDIE->addChild(std::move(VariableDie)); @@ -725,7 +728,7 @@ void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, /// DbgVariable based on provided MachineLocation. void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, MachineLocation Location) { - if (DV.variableHasComplexAddress()) + if (DV.hasComplexAddress()) addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); else if (DV.isBlockByrefVariable()) addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); @@ -781,7 +784,7 @@ void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index) { dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset : dwarf::DW_FORM_data4; - Die.addValue(Attribute, Form, DIELocList(Index)); + Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index)); } void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, @@ -798,7 +801,7 @@ void DwarfCompileUnit::applyVariableAttributes(const DbgVariable &Var, /// Add a Dwarf expression attribute data and value. void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr) { - Die.addValue((dwarf::Attribute)0, Form, DIEExpr(Expr)); + Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr)); } void DwarfCompileUnit::applySubprogramAttributesToDefinition( @@ -817,4 +820,4 @@ bool DwarfCompileUnit::includeMinimalInlineScopes() const { return getCUNode()->getEmissionKind() == DIBuilder::LineTablesOnly || (DD->useSplitDwarf() && !Skeleton); } -} // namespace llvm +} // end llvm namespace diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 48c302b..509c943 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -31,7 +31,7 @@ class LexicalScope; class DwarfCompileUnit : public DwarfUnit { /// The attribute index of DW_AT_stmt_list in the compile unit DIE, avoiding /// the need to search for it in applyStmtList. - unsigned stmtListIndex; + DIE::value_iterator StmtListValue; /// Skeleton unit associated with this unit. DwarfCompileUnit *Skeleton; @@ -58,8 +58,7 @@ class DwarfCompileUnit : public DwarfUnit { /// \brief Construct a DIE for the given DbgVariable without initializing the /// DbgVariable's DIE reference. - std::unique_ptr<DIE> constructVariableDIEImpl(const DbgVariable &DV, - bool Abstract); + DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract); bool isDwoUnit() const override; @@ -92,8 +91,8 @@ public: const MCSymbol *Label); /// addSectionDelta - Add a label delta attribute data and value. - void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, - const MCSymbol *Lo); + DIE::value_iterator addSectionDelta(DIE &Die, dwarf::Attribute Attribute, + const MCSymbol *Hi, const MCSymbol *Lo); DwarfCompileUnit &getCU() override { return *this; } @@ -106,8 +105,9 @@ public: /// addSectionLabel - Add a Dwarf section label attribute data and value. /// - void addSectionLabel(DIE &Die, dwarf::Attribute Attribute, - const MCSymbol *Label, const MCSymbol *Sec); + DIE::value_iterator addSectionLabel(DIE &Die, dwarf::Attribute Attribute, + const MCSymbol *Label, + const MCSymbol *Sec); /// \brief Find DIE for the given subprogram and attach appropriate /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global @@ -116,7 +116,7 @@ public: DIE &updateSubprogramScopeDIE(const DISubprogram *SP); void constructScopeDIE(LexicalScope *Scope, - SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren); + SmallVectorImpl<DIE *> &FinalChildren); /// \brief A helper function to construct a RangeSpanList for a given /// lexical scope. @@ -128,23 +128,21 @@ public: const SmallVectorImpl<InsnRange> &Ranges); /// \brief This scope represents inlined body of a function. Construct /// DIE to represent this concrete inlined copy of the function. - std::unique_ptr<DIE> constructInlinedScopeDIE(LexicalScope *Scope); + DIE *constructInlinedScopeDIE(LexicalScope *Scope); /// \brief Construct new DW_TAG_lexical_block for this scope and /// attach DW_AT_low_pc/DW_AT_high_pc labels. - std::unique_ptr<DIE> constructLexicalScopeDIE(LexicalScope *Scope); + DIE *constructLexicalScopeDIE(LexicalScope *Scope); /// constructVariableDIE - Construct a DIE for the given DbgVariable. - std::unique_ptr<DIE> constructVariableDIE(DbgVariable &DV, - bool Abstract = false); + DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false); - std::unique_ptr<DIE> constructVariableDIE(DbgVariable &DV, - const LexicalScope &Scope, - DIE *&ObjectPointer); + DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope, + DIE *&ObjectPointer); /// A helper function to create children of a Scope DIE. DIE *createScopeChildrenDIE(LexicalScope *Scope, - SmallVectorImpl<std::unique_ptr<DIE>> &Children, + SmallVectorImpl<DIE *> &Children, unsigned *ChildScopeCount = nullptr); /// \brief Construct a DIE for this subprogram scope. @@ -155,8 +153,7 @@ public: void constructAbstractSubprogramScopeDIE(LexicalScope *Scope); /// \brief Construct import_module DIE. - std::unique_ptr<DIE> - constructImportedEntityDIE(const DIImportedEntity *Module); + DIE *constructImportedEntityDIE(const DIImportedEntity *Module); void finishSubprogramDefinition(const DISubprogram *SP); @@ -231,6 +228,6 @@ public: const MCSymbol *getBaseAddress() const { return BaseAddress; } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index fb33169..7d03a39 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -678,8 +678,7 @@ DbgVariable *DwarfDebug::getExistingAbstractVariable(InlinedVariable IV) { void DwarfDebug::createAbstractVariable(const DILocalVariable *Var, LexicalScope *Scope) { - auto AbsDbgVariable = - make_unique<DbgVariable>(Var, /* IA */ nullptr, /* Expr */ nullptr, this); + auto AbsDbgVariable = make_unique<DbgVariable>(Var, /* IA */ nullptr, this); InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get()); AbstractVariables[Var] = std::move(AbsDbgVariable); } @@ -722,10 +721,9 @@ void DwarfDebug::collectVariableInfoFromMMITable( if (!Scope) continue; - const DIExpression *Expr = cast_or_null<DIExpression>(VI.Expr); ensureAbstractVariableIsCreatedIfScoped(Var, Scope->getScopeNode()); - auto RegVar = - make_unique<DbgVariable>(Var.first, Var.second, Expr, this, VI.Slot); + auto RegVar = make_unique<DbgVariable>(Var.first, Var.second, this); + RegVar->initializeMMI(VI.Expr, VI.Slot); if (InfoHolder.addScopeVariable(Scope, RegVar.get())) ConcreteVariables.push_back(std::move(RegVar)); } @@ -870,6 +868,14 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, } } +DbgVariable *DwarfDebug::createConcreteVariable(LexicalScope &Scope, + InlinedVariable IV) { + ensureAbstractVariableIsCreatedIfScoped(IV, Scope.getScopeNode()); + ConcreteVariables.push_back( + make_unique<DbgVariable>(IV.first, IV.second, this)); + InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get()); + return ConcreteVariables.back().get(); +} // Find variables for each lexical scope. void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, @@ -898,20 +904,19 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, continue; Processed.insert(IV); + DbgVariable *RegVar = createConcreteVariable(*Scope, IV); + const MachineInstr *MInsn = Ranges.front().first; assert(MInsn->isDebugValue() && "History must begin with debug value"); - ensureAbstractVariableIsCreatedIfScoped(IV, Scope->getScopeNode()); - ConcreteVariables.push_back(make_unique<DbgVariable>(MInsn, this)); - DbgVariable *RegVar = ConcreteVariables.back().get(); - InfoHolder.addScopeVariable(Scope, RegVar); // Check if the first DBG_VALUE is valid for the rest of the function. - if (Ranges.size() == 1 && Ranges.front().second == nullptr) + if (Ranges.size() == 1 && Ranges.front().second == nullptr) { + RegVar->initializeDbgValue(MInsn); continue; + } // Handle multiple DBG_VALUE instructions describing one variable. - RegVar->setDebugLocListIndex( - DebugLocs.startList(&TheCU, Asm->createTempSymbol("debug_loc"))); + DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar, *MInsn); // Build the location list for this variable. SmallVector<DebugLocEntry, 8> Entries; @@ -925,20 +930,14 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, // Finalize the entry by lowering it into a DWARF bytestream. for (auto &Entry : Entries) - Entry.finalize(*Asm, DebugLocs, BT); + Entry.finalize(*Asm, List, BT); } // Collect info for variables that were optimized out. for (const DILocalVariable *DV : SP->getVariables()) { - if (!Processed.insert(InlinedVariable(DV, nullptr)).second) - continue; - if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) { - ensureAbstractVariableIsCreatedIfScoped(InlinedVariable(DV, nullptr), - Scope->getScopeNode()); - ConcreteVariables.push_back(make_unique<DbgVariable>( - DV, /* IA */ nullptr, /* Expr */ nullptr, this)); - InfoHolder.addScopeVariable(Scope, ConcreteVariables.back().get()); - } + if (Processed.insert(InlinedVariable(DV, nullptr)).second) + if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) + createConcreteVariable(*Scope, InlinedVariable(DV, nullptr)); } } @@ -1505,10 +1504,11 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, // FIXME: ^ } -void DebugLocEntry::finalize(const AsmPrinter &AP, DebugLocStream &Locs, +void DebugLocEntry::finalize(const AsmPrinter &AP, + DebugLocStream::ListBuilder &List, const DIBasicType *BT) { - Locs.startEntry(Begin, End); - BufferByteStreamer Streamer = Locs.getStreamer(); + DebugLocStream::EntryBuilder Entry(List, Begin, End); + BufferByteStreamer Streamer = Entry.getStreamer(); const DebugLocEntry::Value &Value = Values[0]; if (Value.isBitPiece()) { // Emit all pieces that belong to the same variable and range. diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 700f736..1c3e2ae 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -67,42 +67,61 @@ public: }; //===----------------------------------------------------------------------===// -/// \brief This class is used to track local variable information. +/// This class is used to track local variable information. /// -/// - Variables whose location changes over time have a DebugLocListIndex and -/// the other fields are not used. +/// Variables can be created from allocas, in which case they're generated from +/// the MMI table. Such variables can have multiple expressions and frame +/// indices. The \a Expr and \a FrameIndices array must match. /// -/// - Variables that are described by multiple MMI table entries have multiple -/// expressions and frame indices. +/// Variables can be created from \c DBG_VALUE instructions. Those whose +/// location changes over time use \a DebugLocListIndex, while those with a +/// single instruction use \a MInsn and (optionally) a single entry of \a Expr. +/// +/// Variables that have been optimized out use none of these fields. class DbgVariable { - const DILocalVariable *Var; /// Variable Descriptor. - const DILocation *IA; /// Inlined at location. - SmallVector<const DIExpression *, 1> - Expr; /// Complex address location expression. - DIE *TheDIE; /// Variable DIE. - unsigned DebugLocListIndex; /// Offset in DebugLocs. - const MachineInstr *MInsn; /// DBG_VALUE instruction of the variable. - SmallVector<int, 1> FrameIndex; /// Frame index of the variable. + const DILocalVariable *Var; /// Variable Descriptor. + const DILocation *IA; /// Inlined at location. + SmallVector<const DIExpression *, 1> Expr; /// Complex address. + DIE *TheDIE = nullptr; /// Variable DIE. + unsigned DebugLocListIndex = ~0u; /// Offset in DebugLocs. + const MachineInstr *MInsn = nullptr; /// DBG_VALUE instruction. + SmallVector<int, 1> FrameIndex; /// Frame index. DwarfDebug *DD; public: - /// Construct a DbgVariable from a variable. - DbgVariable(const DILocalVariable *V, const DILocation *IA, - const DIExpression *E, DwarfDebug *DD, int FI = ~0) - : Var(V), IA(IA), Expr(1, E), TheDIE(nullptr), DebugLocListIndex(~0U), - MInsn(nullptr), DD(DD) { + /// Construct a DbgVariable. + /// + /// Creates a variable without any DW_AT_location. Call \a initializeMMI() + /// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions. + DbgVariable(const DILocalVariable *V, const DILocation *IA, DwarfDebug *DD) + : Var(V), IA(IA), DD(DD) {} + + /// Initialize from the MMI table. + void initializeMMI(const DIExpression *E, int FI) { + assert(Expr.empty() && "Already initialized?"); + assert(FrameIndex.empty() && "Already initialized?"); + assert(!MInsn && "Already initialized?"); + + assert((!E || E->isValid()) && "Expected valid expression"); + assert(~FI && "Expected valid index"); + + Expr.push_back(E); FrameIndex.push_back(FI); - assert(!E || E->isValid()); } - /// Construct a DbgVariable from a DEBUG_VALUE. - /// AbstractVar may be NULL. - DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD) - : Var(DbgValue->getDebugVariable()), - IA(DbgValue->getDebugLoc()->getInlinedAt()), - Expr(1, DbgValue->getDebugExpression()), TheDIE(nullptr), - DebugLocListIndex(~0U), MInsn(DbgValue), DD(DD) { - FrameIndex.push_back(~0); + /// Initialize from a DBG_VALUE instruction. + void initializeDbgValue(const MachineInstr *DbgValue) { + assert(Expr.empty() && "Already initialized?"); + assert(FrameIndex.empty() && "Already initialized?"); + assert(!MInsn && "Already initialized?"); + + assert(Var == DbgValue->getDebugVariable() && "Wrong variable"); + assert(IA == DbgValue->getDebugLoc()->getInlinedAt() && "Wrong inlined-at"); + + MInsn = DbgValue; + if (auto *E = DbgValue->getDebugExpression()) + if (E->getNumElements()) + Expr.push_back(E); } // Accessors. @@ -123,17 +142,16 @@ public: assert(V.Var == Var && "conflicting variable"); assert(V.IA == IA && "conflicting inlined-at location"); - if (V.getFrameIndex().back() != ~0) { - auto E = V.getExpression(); - auto FI = V.getFrameIndex(); - Expr.append(E.begin(), E.end()); - FrameIndex.append(FI.begin(), FI.end()); - } - assert(Expr.size() > 1 ? std::all_of(Expr.begin(), Expr.end(), - [](const DIExpression *E) { - return E->isBitPiece(); - }) - : (true && "conflicting locations for variable")); + assert(!FrameIndex.empty() && "Expected an MMI entry"); + assert(!V.FrameIndex.empty() && "Expected an MMI entry"); + assert(Expr.size() == FrameIndex.size() && "Mismatched expressions"); + assert(V.Expr.size() == V.FrameIndex.size() && "Mismatched expressions"); + + Expr.append(V.Expr.begin(), V.Expr.end()); + FrameIndex.append(V.FrameIndex.begin(), V.FrameIndex.end()); + assert(std::all_of(Expr.begin(), Expr.end(), [](const DIExpression *E) { + return E && E->isBitPiece(); + }) && "conflicting locations for variable"); } // Translate tag to proper Dwarf tag. @@ -160,11 +178,13 @@ public: return false; } - bool variableHasComplexAddress() const { - assert(Var && "Invalid complex DbgVariable!"); - assert(Expr.size() == 1 && - "variableHasComplexAddress() invoked on multi-FI variable"); - return Expr.back()->getNumElements() > 0; + bool hasComplexAddress() const { + assert(MInsn && "Expected DBG_VALUE, not MMI variable"); + assert(FrameIndex.empty() && "Expected DBG_VALUE, not MMI variable"); + assert( + (Expr.empty() || (Expr.size() == 1 && Expr.back()->getNumElements())) && + "Invalid Expr for DBG_VALUE"); + return !Expr.empty(); } bool isBlockByrefVariable() const; const DIType *getType() const; @@ -344,6 +364,8 @@ class DwarfDebug : public AsmPrinterHandler { void ensureAbstractVariableIsCreatedIfScoped(InlinedVariable Var, const MDNode *Scope); + DbgVariable *createConcreteVariable(LexicalScope &Scope, InlinedVariable IV); + /// \brief Construct a DIE for this abstract scope. void constructAbstractSubprogramScopeDIE(LexicalScope *Scope); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h index a4fd36f..f4667b4 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfException.h @@ -21,7 +21,7 @@ namespace llvm { class MachineFunction; class ARMTargetStreamer; -class DwarfCFIExceptionBase : public EHStreamer { +class LLVM_LIBRARY_VISIBILITY DwarfCFIExceptionBase : public EHStreamer { protected: DwarfCFIExceptionBase(AsmPrinter *A); @@ -31,7 +31,7 @@ protected: void markFunctionEnd() override; }; -class DwarfCFIException : public DwarfCFIExceptionBase { +class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public DwarfCFIExceptionBase { /// Per-function flag to indicate if .cfi_personality should be emitted. bool shouldEmitPersonality; @@ -61,7 +61,7 @@ public: void endFunction(const MachineFunction *) override; }; -class ARMException : public DwarfCFIExceptionBase { +class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase { void emitTypeInfos(unsigned TTypeEncoding) override; ARMTargetStreamer &getTargetStreamer(); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index 154d7d9..78ec937 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -131,6 +131,6 @@ public: void EmitUnsigned(uint64_t Value) override; bool isFrameRegister(unsigned MachineReg) override; }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp index fdefb1d..51b27b4 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -103,7 +103,7 @@ unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { // Size the DIE attribute values. for (const auto &V : Die.values()) // Size attribute value. - Offset += V.SizeOf(Asm, V.getForm()); + Offset += V.SizeOf(Asm); // Size the DIE children if any. if (Die.hasChildren()) { @@ -111,7 +111,7 @@ unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { assert(Abbrev.hasChildren() && "Children flag not set"); for (auto &Child : Die.children()) - Offset = computeSizeAndOffset(*Child, Offset); + Offset = computeSizeAndOffset(Child, Offset); // End of children marker. Offset += sizeof(int8_t); @@ -170,4 +170,4 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { Vars.push_back(Var); return true; } -} // namespace llvm +} diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h index 22759fd..8402027 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -114,5 +114,5 @@ public: return DITypeNodeToDieMap.lookup(TypeMD); } }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h index c107258..93a1684 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h @@ -45,5 +45,5 @@ public: /// Get a reference to an entry in the string pool. EntryRef getEntry(AsmPrinter &Asm, StringRef Str); }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index f4b15ba..3555822 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -66,8 +66,9 @@ bool DIEDwarfExpression::isFrameRegister(unsigned MachineReg) { DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) - : UniqueID(UID), CUNode(Node), UnitDie(UnitTag), DebugInfoOffset(0), Asm(A), - DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) { + : UniqueID(UID), CUNode(Node), + UnitDie(*DIE::get(DIEValueAllocator, UnitTag)), DebugInfoOffset(0), + Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) { assert(UnitTag == dwarf::DW_TAG_compile_unit || UnitTag == dwarf::DW_TAG_type_unit); } @@ -184,16 +185,18 @@ void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) { void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) { if (DD->getDwarfVersion() >= 4) - Die.addValue(Attribute, dwarf::DW_FORM_flag_present, DIEInteger(1)); + Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag_present, + DIEInteger(1)); else - Die.addValue(Attribute, dwarf::DW_FORM_flag, DIEInteger(1)); + Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag, + DIEInteger(1)); } void DwarfUnit::addUInt(DIE &Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form, uint64_t Integer) { if (!Form) Form = DIEInteger::BestForm(false, Integer); - Die.addValue(Attribute, *Form, DIEInteger(Integer)); + Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer)); } void DwarfUnit::addUInt(DIE &Block, dwarf::Form Form, uint64_t Integer) { @@ -204,7 +207,7 @@ void DwarfUnit::addSInt(DIE &Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form, int64_t Integer) { if (!Form) Form = DIEInteger::BestForm(true, Integer); - Die.addValue(Attribute, *Form, DIEInteger(Integer)); + Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer)); } void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form, @@ -214,14 +217,15 @@ void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form, void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute, StringRef String) { - Die.addValue(Attribute, + Die.addValue(DIEValueAllocator, Attribute, isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp, DIEString(DU->getStringPool().getEntry(*Asm, String))); } -void DwarfUnit::addLabel(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form, - const MCSymbol *Label) { - Die.addValue(Attribute, Form, DIELabel(Label)); +DIE::value_iterator DwarfUnit::addLabel(DIE &Die, dwarf::Attribute Attribute, + dwarf::Form Form, + const MCSymbol *Label) { + return Die.addValue(DIEValueAllocator, Attribute, Form, DIELabel(Label)); } void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) { @@ -254,7 +258,7 @@ void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) { void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo) { - Die.addValue(Attribute, dwarf::DW_FORM_data4, + Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_data4, new (DIEValueAllocator) DIEDelta(Hi, Lo)); } @@ -269,8 +273,8 @@ void DwarfUnit::addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type) { // and think this is a full definition. addFlag(Die, dwarf::DW_AT_declaration); - Die.addValue(dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8, - DIETypeSignature(Type)); + Die.addValue(DIEValueAllocator, dwarf::DW_AT_signature, + dwarf::DW_FORM_ref_sig8, DIETypeSignature(Type)); } void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, @@ -282,7 +286,7 @@ void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DieCU = &getUnitDie(); if (!EntryCU) EntryCU = &getUnitDie(); - Die.addValue(Attribute, + Die.addValue(DIEValueAllocator, Attribute, EntryCU == DieCU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr, Entry); } @@ -290,7 +294,7 @@ void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) { assert(Tag != dwarf::DW_TAG_auto_variable && Tag != dwarf::DW_TAG_arg_variable); - DIE &Die = Parent.addChild(make_unique<DIE>((dwarf::Tag)Tag)); + DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, (dwarf::Tag)Tag)); if (N) insertDIE(N, &Die); return Die; @@ -299,14 +303,15 @@ DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) { void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) { Loc->ComputeSize(Asm); DIELocs.push_back(Loc); // Memoize so we can call the destructor later on. - Die.addValue(Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc); + Die.addValue(DIEValueAllocator, Attribute, + Loc->BestForm(DD->getDwarfVersion()), Loc); } void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIEBlock *Block) { Block->ComputeSize(Asm); DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on. - Die.addValue(Attribute, Block->BestForm(), Block); + Die.addValue(DIEValueAllocator, Attribute, Block->BestForm(), Block); } void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, StringRef File, @@ -1064,6 +1069,30 @@ DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) { return &NDie; } +DIE *DwarfUnit::getOrCreateModule(const DIModule *M) { + // Construct the context before querying for the existence of the DIE in case + // such construction creates the DIE. + DIE *ContextDIE = getOrCreateContextDIE(M->getScope()); + + if (DIE *MDie = getDIE(M)) + return MDie; + DIE &MDie = createAndAddDIE(dwarf::DW_TAG_module, *ContextDIE, M); + + if (!M->getName().empty()) { + addString(MDie, dwarf::DW_AT_name, M->getName()); + addGlobalName(M->getName(), MDie, M->getScope()); + } + if (!M->getConfigurationMacros().empty()) + addString(MDie, dwarf::DW_AT_LLVM_config_macros, + M->getConfigurationMacros()); + if (!M->getIncludePath().empty()) + addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath()); + if (!M->getISysRoot().empty()) + addString(MDie, dwarf::DW_AT_LLVM_isysroot, M->getISysRoot()); + + return &MDie; +} + DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) { // Construct the context before querying for the existence of the DIE in case // such construction creates the DIE (as is the case for member function @@ -1340,24 +1369,44 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { // Handle bitfield, assume bytes are 8 bits. addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8); addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size); - + // + // The DWARF 2 DW_AT_bit_offset is counting the bits between the most + // significant bit of the aligned storage unit containing the bit field to + // the most significan bit of the bit field. + // + // FIXME: DWARF 4 states that DW_AT_data_bit_offset (which + // counts from the beginning, regardless of endianness) should + // be used instead. + // + // + // Struct Align Align Align + // v v v v + // +-----------+-----*-----+-----*-----+-- + // | ... |b1|b2|b3|b4| + // +-----------+-----*-----+-----*-----+-- + // | | |<-- Size ->| | + // |<---- Offset --->| |<--->| + // | | | \_ DW_AT_bit_offset (little endian) + // | |<--->| + // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian) + // \ = DW_AT_data_bit_offset (biendian) + // \_ OffsetInBytes uint64_t Offset = DT->getOffsetInBits(); - uint64_t AlignMask = ~(DT->getAlignInBits() - 1); - uint64_t HiMark = (Offset + FieldSize) & AlignMask; - uint64_t FieldOffset = (HiMark - FieldSize); - Offset -= FieldOffset; - - // Maybe we need to work from the other end. - if (Asm->getDataLayout().isLittleEndian()) - Offset = FieldSize - (Offset + Size); - addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset); - - // Here DW_AT_data_member_location points to the anonymous - // field that includes this bit field. - OffsetInBytes = FieldOffset >> 3; + uint64_t Align = DT->getAlignInBits() ? DT->getAlignInBits() : FieldSize; + uint64_t AlignMask = ~(Align - 1); + // The bits from the start of the storage unit to the start of the field. + uint64_t StartBitOffset = Offset - (Offset & AlignMask); + // The endian-dependent DWARF 2 offset. + uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian() + ? OffsetToAlignment(Offset + Size, Align) + : StartBitOffset; + + // The byte offset of the field's aligned storage unit inside the struct. + OffsetInBytes = (Offset - StartBitOffset) / 8; + addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset); } else // This is not a bitfield. - OffsetInBytes = DT->getOffsetInBits() >> 3; + OffsetInBytes = DT->getOffsetInBits() / 8; if (DD->getDwarfVersion() <= 2) { DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc; @@ -1386,8 +1435,8 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { // Objective-C properties. if (DINode *PNode = DT->getObjCProperty()) if (DIE *PDie = getDIE(PNode)) - MemberDie.addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4, - DIEEntry(*PDie)); + MemberDie.addValue(DIEValueAllocator, dwarf::DW_AT_APPLE_property, + dwarf::DW_FORM_ref4, DIEEntry(*PDie)); if (DT->isArtificial()) addFlag(MemberDie, dwarf::DW_AT_artificial); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 200ddf0..4000ae4 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -73,8 +73,11 @@ protected: /// MDNode for the compile unit. const DICompileUnit *CUNode; + // All DIEValues are allocated through this allocator. + BumpPtrAllocator DIEValueAllocator; + /// Unit debug information entry. - DIE UnitDie; + DIE &UnitDie; /// Offset of the UnitDie from beginning of debug info section. unsigned DebugInfoOffset; @@ -104,9 +107,6 @@ protected: /// corresponds to the MDNode mapped with the subprogram DIE. DenseMap<DIE *, const DINode *> ContainingTypeMap; - // All DIEValues are allocated through this allocator. - BumpPtrAllocator DIEValueAllocator; - /// The section this unit will be emitted in. MCSection *Section; @@ -206,8 +206,8 @@ public: void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str); /// \brief Add a Dwarf label attribute data and value. - void addLabel(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form, - const MCSymbol *Label); + DIE::value_iterator addLabel(DIE &Die, dwarf::Attribute Attribute, + dwarf::Form Form, const MCSymbol *Label); void addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label); @@ -291,6 +291,7 @@ public: dwarf::Attribute Attribute = dwarf::DW_AT_type); DIE *getOrCreateNameSpace(const DINamespace *NS); + DIE *getOrCreateModule(const DIModule *M); DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false); void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, @@ -402,5 +403,5 @@ public: } DwarfCompileUnit &getCU() override { return CU; } }; -} // namespace llvm +} // end llvm namespace #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h index 128a8ad..e42e082 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h @@ -30,7 +30,7 @@ template <typename T> class SmallVectorImpl; /// Emits exception handling directives. -class EHStreamer : public AsmPrinterHandler { +class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler { protected: /// Target of directive emission. AsmPrinter *Asm; @@ -132,7 +132,7 @@ public: void beginInstruction(const MachineInstr *MI) override {} void endInstruction() override {} }; -} // namespace llvm +} #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp index 802456b..2ceec61 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -58,7 +58,7 @@ static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) { SymName[Letter] = toupper(SymName[Letter]); SmallString<128> TmpStr; - AP.Mang->getNameWithPrefix(TmpStr, SymName); + Mangler::getNameWithPrefix(TmpStr, SymName, M.getDataLayout()); MCSymbol *Sym = AP.OutContext.getOrCreateSymbol(TmpStr); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp index 11bfe76..535b1f6 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp @@ -378,4 +378,4 @@ void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) { return; maybeRecordLocation(DL, Asm->MF); } -} // namespace llvm +} diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h index c66d141..a5b399f 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h @@ -29,7 +29,7 @@ namespace llvm { /// \brief Collects and handles line tables information in a CodeView format. -class WinCodeViewLineTables : public AsmPrinterHandler { +class LLVM_LIBRARY_VISIBILITY WinCodeViewLineTables : public AsmPrinterHandler { AsmPrinter *Asm; DebugLoc PrevInstLoc; diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 1ba6060..79830bc 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -319,6 +319,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { return; } else { FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName); + emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName); } MCSymbol *UnwindMapXData = nullptr; @@ -547,28 +548,33 @@ void WinException::extendIP2StateTable(const MachineFunction *MF, } } +void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo, + StringRef FLinkageName) { + // Outlined helpers called by the EH runtime need to know the offset of the EH + // registration in order to recover the parent frame pointer. Now that we know + // we've code generated the parent, we can emit the label assignment that + // those helpers use to get the offset of the registration node. + assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX && + "no EH reg node frameescape index"); + MCSymbol *ParentFrameOffset = + Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName); + MCSymbol *RegistrationOffsetSym = Asm->OutContext.getOrCreateFrameAllocSymbol( + FLinkageName, FuncInfo.EHRegNodeEscapeIndex); + const MCExpr *RegistrationOffsetSymRef = + MCSymbolRefExpr::create(RegistrationOffsetSym, Asm->OutContext); + Asm->OutStreamer->EmitAssignment(ParentFrameOffset, RegistrationOffsetSymRef); +} + /// Emit the language-specific data that _except_handler3 and 4 expect. This is /// functionally equivalent to the __C_specific_handler table, except it is /// indexed by state number instead of IP. void WinException::emitExceptHandlerTable(const MachineFunction *MF) { MCStreamer &OS = *Asm->OutStreamer; - - // Define the EH registration node offset label in terms of its frameescape - // label. The WinEHStatePass ensures that the registration node is passed to - // frameescape. This allows SEH filter functions to access the - // EXCEPTION_POINTERS field, which is filled in by the _except_handlerN. const Function *F = MF->getFunction(); - WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F); - assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX && - "no EH reg node frameescape index"); StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName()); - MCSymbol *ParentFrameOffset = - Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName); - MCSymbol *FrameAllocSym = Asm->OutContext.getOrCreateFrameAllocSymbol( - FLinkageName, FuncInfo.EHRegNodeEscapeIndex); - const MCSymbolRefExpr *FrameAllocSymRef = - MCSymbolRefExpr::create(FrameAllocSym, Asm->OutContext); - OS.EmitAssignment(ParentFrameOffset, FrameAllocSymRef); + + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F); + emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName); // Emit the __ehtable label that we use for llvm.x86.seh.lsda. MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h index bbff3c2..669c9cc 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.h @@ -23,7 +23,7 @@ class MachineFunction; class MCExpr; struct WinEHFuncInfo; -class WinException : public EHStreamer { +class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer { /// Per-function flag to indicate if personality info should be emitted. bool shouldEmitPersonality = false; @@ -50,6 +50,11 @@ class WinException : public EHStreamer { void extendIP2StateTable(const MachineFunction *MF, const Function *ParentF, WinEHFuncInfo &FuncInfo); + /// Emits the label used with llvm.x86.seh.recoverfp, which is used by + /// outlined funclets. + void emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo, + StringRef FLinkageName); + const MCExpr *create32bitRef(const MCSymbol *Value); const MCExpr *create32bitRef(const GlobalValue *GV); @@ -70,7 +75,7 @@ public: /// Gather and emit post-function exception information. void endFunction(const MachineFunction *) override; }; -} // namespace llvm +} #endif |