Index: llvm/include/llvm/MC/MCAssembler.h =================================================================== --- llvm/include/llvm/MC/MCAssembler.h +++ llvm/include/llvm/MC/MCAssembler.h @@ -99,11 +99,11 @@ private: MCContext &Context; - MCAsmBackend &Backend; + std::unique_ptr Backend; - MCCodeEmitter &Emitter; + std::unique_ptr Emitter; - MCObjectWriter &Writer; + std::unique_ptr Writer; SectionListType Sections; @@ -214,8 +214,9 @@ // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &Context, MCAsmBackend &Backend, - MCCodeEmitter &Emitter, MCObjectWriter &Writer); + MCAssembler(MCContext &Context, std::unique_ptr Backend, + std::unique_ptr Emitter, + std::unique_ptr Writer); MCAssembler(const MCAssembler &) = delete; MCAssembler &operator=(const MCAssembler &) = delete; ~MCAssembler(); @@ -274,11 +275,17 @@ MCContext &getContext() const { return Context; } - MCAsmBackend &getBackend() const { return Backend; } + MCAsmBackend *getBackendPtr() const { return Backend.get(); } - MCCodeEmitter &getEmitter() const { return Emitter; } + MCCodeEmitter *getEmitterPtr() const { return Emitter.get(); } - MCObjectWriter &getWriter() const { return Writer; } + MCObjectWriter *getWriterPtr() const { return Writer.get(); } + + MCAsmBackend &getBackend() const { return *Backend; } + + MCCodeEmitter &getEmitter() const { return *Emitter; } + + MCObjectWriter &getWriter() const { return *Writer; } MCDwarfLineTableParams getDWARFLinetableParams() const { return LTParams; } void setDWARFLinetableParams(MCDwarfLineTableParams P) { LTParams = P; } Index: llvm/include/llvm/MC/MCObjectStreamer.h =================================================================== --- llvm/include/llvm/MC/MCObjectStreamer.h +++ llvm/include/llvm/MC/MCObjectStreamer.h @@ -34,9 +34,6 @@ /// to that file format or custom semantics expected by the object writer /// implementation. class MCObjectStreamer : public MCStreamer { - std::unique_ptr ObjectWriter; - std::unique_ptr TAB; - std::unique_ptr Emitter; std::unique_ptr Assembler; MCSection::iterator CurInsertionPoint; bool EmitEHFrame; Index: llvm/lib/MC/MCAssembler.cpp =================================================================== --- llvm/lib/MC/MCAssembler.cpp +++ llvm/lib/MC/MCAssembler.cpp @@ -83,9 +83,12 @@ /* *** */ -MCAssembler::MCAssembler(MCContext &Context, MCAsmBackend &Backend, - MCCodeEmitter &Emitter, MCObjectWriter &Writer) - : Context(Context), Backend(Backend), Emitter(Emitter), Writer(Writer), +MCAssembler::MCAssembler(MCContext &Context, + std::unique_ptr Backend, + std::unique_ptr Emitter, + std::unique_ptr Writer) + : Context(Context), Backend(std::move(Backend)), + Emitter(std::move(Emitter)), Writer(std::move(Writer)), BundleAlignSize(0), RelaxAll(false), SubsectionsViaSymbols(false), IncrementalLinkerCompatible(false), ELFHeaderEFlags(0) { VersionInfo.Major = 0; // Major version == 0 for "none specified" @@ -110,9 +113,12 @@ VersionInfo.Major = 0; // reset objects owned by us - getBackend().reset(); - getEmitter().reset(); - getWriter().reset(); + if (getBackendPtr()) + getBackendPtr()->reset(); + if (getEmitterPtr()) + getEmitterPtr()->reset(); + if (getWriterPtr()) + getWriterPtr()->reset(); getLOHContainer().reset(); } @@ -215,8 +221,9 @@ } } - bool IsPCRel = Backend.getFixupKindInfo( - Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; + assert(getBackendPtr() && "Expected assembler backend"); + bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; bool IsResolved; if (IsPCRel) { @@ -251,8 +258,8 @@ Value -= Layout.getSymbolOffset(Sym); } - bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags & - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits; + bool ShouldAlignPC = getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits; assert((ShouldAlignPC ? IsPCRel : true) && "FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!"); @@ -266,7 +273,7 @@ } // Let the backend force a relocation if needed. - if (IsResolved && Backend.shouldForceRelocation(*this, Fixup, Target)) + if (IsResolved && getBackend().shouldForceRelocation(*this, Fixup, Target)) IsResolved = false; return IsResolved; @@ -274,6 +281,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const { + assert(getBackendPtr() && "Requires assembler backend"); switch (F.getKind()) { case MCFragment::FT_Data: return cast(F).getContents().size(); @@ -437,6 +445,7 @@ void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, MCObjectWriter *OW) const { + assert(getBackendPtr() && "Expected assembler backend"); // Should NOP padding be written out before this fragment? unsigned BundlePadding = F.getBundlePadding(); if (BundlePadding > 0) { @@ -470,7 +479,8 @@ /// \brief Write the fragment \p F to the output file. static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment &F) { - MCObjectWriter *OW = &Asm.getWriter(); + MCObjectWriter *OW = Asm.getWriterPtr(); + assert(OW && "Need ObjectWriter to write fragment"); // FIXME: Embed in fragments instead? uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); @@ -619,6 +629,8 @@ void MCAssembler::writeSectionData(const MCSection *Sec, const MCAsmLayout &Layout) const { + assert(getBackendPtr() && "Expected assembler backend"); + // Ignore virtual sections. if (Sec->isVirtualSection()) { assert(Layout.getSectionFileSize(Sec) == 0 && "Invalid size for section!"); @@ -688,6 +700,7 @@ } void MCAssembler::layout(MCAsmLayout &Layout) { + assert(getBackendPtr() && "Expected assembler backend"); DEBUG_WITH_TYPE("mc-dump", { errs() << "assembler backend - pre-layout\n--\n"; dump(); }); @@ -788,6 +801,7 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { + assert(getBackendPtr() && "Expected assembler backend"); MCValue Target; uint64_t Value; bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Value); @@ -801,6 +815,7 @@ bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F, const MCAsmLayout &Layout) const { + assert(getBackendPtr() && "Expected assembler backend"); // If this inst doesn't ever need relaxation, ignore it. This occurs when we // are intentionally pushing out inst fragments, or because we relaxed a // previous instruction to one that doesn't need relaxation. @@ -816,6 +831,8 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &F) { + assert(getEmitterPtr() && + "Expected CodeEmitter defined for relaxInstruction"); if (!fragmentNeedsRelaxation(&F, Layout)) return false; @@ -848,6 +865,7 @@ bool MCAssembler::relaxPaddingFragment(MCAsmLayout &Layout, MCPaddingFragment &PF) { + assert(getBackendPtr() && "Expected assembler backend"); uint64_t OldSize = PF.getSize(); if (!getBackend().relaxFragment(&PF, Layout)) return false; @@ -992,6 +1010,7 @@ } void MCAssembler::finishLayout(MCAsmLayout &Layout) { + assert(getBackendPtr() && "Expected assembler backend"); // The layout is done. Mark every fragment as valid. for (unsigned int i = 0, n = Layout.getSectionOrder().size(); i != n; ++i) { MCSection &Section = *Layout.getSectionOrder()[i]; Index: llvm/lib/MC/MCObjectStreamer.cpp =================================================================== --- llvm/lib/MC/MCObjectStreamer.cpp +++ llvm/lib/MC/MCObjectStreamer.cpp @@ -27,10 +27,10 @@ std::unique_ptr TAB, raw_pwrite_stream &OS, std::unique_ptr Emitter) - : MCStreamer(Context), ObjectWriter(TAB->createObjectWriter(OS)), - TAB(std::move(TAB)), Emitter(std::move(Emitter)), - Assembler(llvm::make_unique(Context, *this->TAB, - *this->Emitter, *ObjectWriter)), + : MCStreamer(Context), + Assembler(llvm::make_unique(Context, std::move(TAB), + std::move(Emitter), + TAB->createObjectWriter(OS))), EmitEHFrame(true), EmitDebugFrame(false) {} MCObjectStreamer::~MCObjectStreamer() {}