Simplify use of formatted_raw_ostream.

formatted_raw_ostream is a wrapper over another stream to add column and line
number tracking.

It is used only for asm printing.

This patch moves the its creation down to where we know we are printing
assembly. This has the following advantages:

* Simpler lifetime management: std::unique_ptr
* We don't compute column and line number of object files :-)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234535 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2015-04-09 21:06:08 +00:00
parent 66649e00c9
commit 427c073035
13 changed files with 81 additions and 101 deletions

View File

@ -746,7 +746,8 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
/// ///
/// \param ShowInst - Whether to show the MCInst representation inline with /// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly. /// the assembly.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, MCStreamer *createAsmStreamer(MCContext &Ctx,
std::unique_ptr<formatted_raw_ostream> OS,
bool isVerboseAsm, bool useDwarfDirectory, bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst); MCAsmBackend *TAB, bool ShowInst);

View File

@ -25,27 +25,11 @@ namespace llvm {
/// boundaries and querying the number of lines written to the stream. /// boundaries and querying the number of lines written to the stream.
/// ///
class formatted_raw_ostream : public raw_ostream { class formatted_raw_ostream : public raw_ostream {
public:
/// DELETE_STREAM - Tell the destructor to delete the held stream.
///
static const bool DELETE_STREAM = true;
/// PRESERVE_STREAM - Tell the destructor to not delete the held
/// stream.
///
static const bool PRESERVE_STREAM = false;
private:
/// TheStream - The real stream we output to. We set it to be /// TheStream - The real stream we output to. We set it to be
/// unbuffered, since we're already doing our own buffering. /// unbuffered, since we're already doing our own buffering.
/// ///
raw_ostream *TheStream; raw_ostream *TheStream;
/// DeleteStream - Do we need to delete TheStream in the
/// destructor?
///
bool DeleteStream;
/// Position - The current output column and line of the data that's /// Position - The current output column and line of the data that's
/// been flushed and the portion of the buffer that's been /// been flushed and the portion of the buffer that's been
/// scanned. The line and column scheme is zero-based. /// scanned. The line and column scheme is zero-based.
@ -73,36 +57,10 @@ private:
/// ///
void ComputePosition(const char *Ptr, size_t size); void ComputePosition(const char *Ptr, size_t size);
public: void setStream(raw_ostream &Stream) {
/// formatted_raw_ostream - Open the specified file for
/// writing. If an error occurs, information about the error is
/// put into ErrorInfo, and the stream should be immediately
/// destroyed; the string will be empty if no error occurred.
///
/// As a side effect, the given Stream is set to be Unbuffered.
/// This is because formatted_raw_ostream does its own buffering,
/// so it doesn't want another layer of buffering to be happening
/// underneath it.
///
formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
: TheStream(nullptr), DeleteStream(false), Position(0, 0) {
setStream(Stream, Delete);
}
explicit formatted_raw_ostream()
: TheStream(nullptr), DeleteStream(false), Position(0, 0) {
Scanned = nullptr;
}
~formatted_raw_ostream() {
flush();
releaseStream();
}
void setStream(raw_ostream &Stream, bool Delete = false) {
releaseStream(); releaseStream();
TheStream = &Stream; TheStream = &Stream;
DeleteStream = Delete;
// This formatted_raw_ostream inherits from raw_ostream, so it'll do its // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
// own buffering, and it doesn't need or want TheStream to do another // own buffering, and it doesn't need or want TheStream to do another
@ -117,6 +75,30 @@ public:
Scanned = nullptr; Scanned = nullptr;
} }
public:
/// formatted_raw_ostream - Open the specified file for
/// writing. If an error occurs, information about the error is
/// put into ErrorInfo, and the stream should be immediately
/// destroyed; the string will be empty if no error occurred.
///
/// As a side effect, the given Stream is set to be Unbuffered.
/// This is because formatted_raw_ostream does its own buffering,
/// so it doesn't want another layer of buffering to be happening
/// underneath it.
///
formatted_raw_ostream(raw_ostream &Stream)
: TheStream(nullptr), Position(0, 0) {
setStream(Stream);
}
explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
Scanned = nullptr;
}
~formatted_raw_ostream() {
flush();
releaseStream();
}
/// PadToColumn - Align the output to some column number. If the current /// PadToColumn - Align the output to some column number. If the current
/// column is already equal to or more than NewCol, PadToColumn inserts one /// column is already equal to or more than NewCol, PadToColumn inserts one
/// space. /// space.
@ -151,13 +133,11 @@ public:
private: private:
void releaseStream() { void releaseStream() {
// Delete the stream if needed. Otherwise, transfer the buffer // Transfer the buffer settings from this raw_ostream back to the underlying
// settings from this raw_ostream back to the underlying stream. // stream.
if (!TheStream) if (!TheStream)
return; return;
if (DeleteStream) if (size_t BufferSize = GetBufferSize())
delete TheStream;
else if (size_t BufferSize = GetBufferSize())
TheStream->SetBufferSize(BufferSize); TheStream->SetBufferSize(BufferSize);
else else
TheStream->SetUnbuffered(); TheStream->SetUnbuffered();

View File

@ -22,6 +22,7 @@
#include "llvm-c/Disassembler.h" #include "llvm-c/Disassembler.h"
#include "llvm/ADT/Triple.h" #include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h" #include "llvm/Support/CodeGen.h"
#include "llvm/Support/FormattedStream.h"
#include <cassert> #include <cassert>
#include <memory> #include <memory>
#include <string> #include <string>
@ -52,7 +53,8 @@ namespace llvm {
class formatted_raw_ostream; class formatted_raw_ostream;
MCStreamer *createNullStreamer(MCContext &Ctx); MCStreamer *createNullStreamer(MCContext &Ctx);
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, MCStreamer *createAsmStreamer(MCContext &Ctx,
std::unique_ptr<formatted_raw_ostream> OS,
bool isVerboseAsm, bool useDwarfDirectory, bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst); MCAsmBackend *TAB, bool ShowInst);
@ -469,14 +471,16 @@ namespace llvm {
return S; return S;
} }
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, MCStreamer *createAsmStreamer(MCContext &Ctx,
std::unique_ptr<formatted_raw_ostream> OS,
bool IsVerboseAsm, bool UseDwarfDirectory, bool IsVerboseAsm, bool UseDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst) const { MCAsmBackend *TAB, bool ShowInst) const {
MCStreamer *S = formatted_raw_ostream &OSRef = *OS;
llvm::createAsmStreamer(Ctx, OS, IsVerboseAsm, UseDwarfDirectory, MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IsVerboseAsm,
InstPrint, CE, TAB, ShowInst); UseDwarfDirectory, InstPrint, CE,
createAsmTargetStreamer(*S, OS, InstPrint, IsVerboseAsm); TAB, ShowInst);
createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
return S; return S;
} }

View File

@ -207,8 +207,7 @@ public:
/// emitted. Typically this will involve several steps of code generation. /// emitted. Typically this will involve several steps of code generation.
/// This method should return true if emission of this file type is not /// This method should return true if emission of this file type is not
/// supported, or false on success. /// supported, or false on success.
virtual bool addPassesToEmitFile(PassManagerBase &, virtual bool addPassesToEmitFile(PassManagerBase &, raw_ostream &,
formatted_raw_ostream &,
CodeGenFileType, CodeGenFileType,
bool /*DisableVerify*/ = true, bool /*DisableVerify*/ = true,
AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StartAfter*/ = nullptr,
@ -257,7 +256,7 @@ public:
/// Add passes to the specified pass manager to get the specified file /// Add passes to the specified pass manager to get the specified file
/// emitted. Typically this will involve several steps of code generation. /// emitted. Typically this will involve several steps of code generation.
bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, bool addPassesToEmitFile(PassManagerBase &PM, raw_ostream &Out,
CodeGenFileType FileType, bool DisableVerify = true, CodeGenFileType FileType, bool DisableVerify = true,
AnalysisID StartAfter = nullptr, AnalysisID StartAfter = nullptr,
AnalysisID StopAfter = nullptr) override; AnalysisID StopAfter = nullptr) override;

View File

@ -140,12 +140,9 @@ static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
return &MMI->getContext(); return &MMI->getContext();
} }
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, bool LLVMTargetMachine::addPassesToEmitFile(
formatted_raw_ostream &Out, PassManagerBase &PM, raw_ostream &Out, CodeGenFileType FileType,
CodeGenFileType FileType, bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {
bool DisableVerify,
AnalysisID StartAfter,
AnalysisID StopAfter) {
// Add common CodeGen passes. // Add common CodeGen passes.
MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
StartAfter, StopAfter); StartAfter, StopAfter);
@ -184,8 +181,9 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(),
TargetCPU); TargetCPU);
auto FOut = llvm::make_unique<formatted_raw_ostream>(Out);
MCStreamer *S = getTarget().createAsmStreamer( MCStreamer *S = getTarget().createAsmStreamer(
*Context, Out, Options.MCOptions.AsmVerbose, *Context, std::move(FOut), Options.MCOptions.AsmVerbose,
Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB, Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB,
Options.MCOptions.ShowMCInst); Options.MCOptions.ShowMCInst);
AsmStreamer.reset(S); AsmStreamer.reset(S);

View File

@ -38,7 +38,6 @@
#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h" #include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h" #include "llvm/Support/Signals.h"
@ -574,13 +573,11 @@ bool LTOCodeGenerator::compileOptimized(raw_ostream &out, std::string &errMsg) {
legacy::PassManager codeGenPasses; legacy::PassManager codeGenPasses;
formatted_raw_ostream Out(out);
// If the bitcode files contain ARC code and were compiled with optimization, // If the bitcode files contain ARC code and were compiled with optimization,
// the ObjCARCContractPass must be run, so do it unconditionally here. // the ObjCARCContractPass must be run, so do it unconditionally here.
codeGenPasses.add(createObjCARCContractPass()); codeGenPasses.add(createObjCARCContractPass());
if (TargetMach->addPassesToEmitFile(codeGenPasses, Out, if (TargetMach->addPassesToEmitFile(codeGenPasses, out,
TargetMachine::CGFT_ObjectFile)) { TargetMachine::CGFT_ObjectFile)) {
errMsg = "target file type not supported"; errMsg = "target file type not supported";
return false; return false;

View File

@ -37,6 +37,7 @@ using namespace llvm;
namespace { namespace {
class MCAsmStreamer final : public MCStreamer { class MCAsmStreamer final : public MCStreamer {
std::unique_ptr<formatted_raw_ostream> OSOwner;
formatted_raw_ostream &OS; formatted_raw_ostream &OS;
const MCAsmInfo *MAI; const MCAsmInfo *MAI;
std::unique_ptr<MCInstPrinter> InstPrinter; std::unique_ptr<MCInstPrinter> InstPrinter;
@ -55,14 +56,15 @@ class MCAsmStreamer final : public MCStreamer {
void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
public: public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
bool isVerboseAsm, bool useDwarfDirectory, bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *printer, MCCodeEmitter *emitter, MCInstPrinter *printer, MCCodeEmitter *emitter,
MCAsmBackend *asmbackend, bool showInst) MCAsmBackend *asmbackend, bool showInst)
: MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter),
CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), AsmBackend(asmbackend), CommentStream(CommentToEmit),
ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) { IsVerboseAsm(isVerboseAsm), ShowInst(showInst),
UseDwarfDirectory(useDwarfDirectory) {
if (InstPrinter && IsVerboseAsm) if (InstPrinter && IsVerboseAsm)
InstPrinter->setCommentStream(CommentStream); InstPrinter->setCommentStream(CommentStream);
} }
@ -1312,10 +1314,10 @@ void MCAsmStreamer::FinishImpl() {
} }
MCStreamer *llvm::createAsmStreamer(MCContext &Context, MCStreamer *llvm::createAsmStreamer(MCContext &Context,
formatted_raw_ostream &OS, std::unique_ptr<formatted_raw_ostream> OS,
bool isVerboseAsm, bool useDwarfDirectory, bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *IP, MCCodeEmitter *CE, MCInstPrinter *IP, MCCodeEmitter *CE,
MCAsmBackend *MAB, bool ShowInst) { MCAsmBackend *MAB, bool ShowInst) {
return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE, return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
MAB, ShowInst); useDwarfDirectory, IP, CE, MAB, ShowInst);
} }

View File

@ -15,6 +15,7 @@
#include "CPPTargetMachine.h" #include "CPPTargetMachine.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h" #include "llvm/Config/config.h"
#include "llvm/IR/CallingConv.h" #include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
@ -91,6 +92,7 @@ namespace {
/// CppWriter - This class is the main chunk of code that converts an LLVM /// CppWriter - This class is the main chunk of code that converts an LLVM
/// module to a C++ translation unit. /// module to a C++ translation unit.
class CppWriter : public ModulePass { class CppWriter : public ModulePass {
std::unique_ptr<formatted_raw_ostream> OutOwner;
formatted_raw_ostream &Out; formatted_raw_ostream &Out;
const Module *TheModule; const Module *TheModule;
uint64_t uniqueNum; uint64_t uniqueNum;
@ -105,8 +107,9 @@ namespace {
public: public:
static char ID; static char ID;
explicit CppWriter(formatted_raw_ostream &o) : explicit CppWriter(std::unique_ptr<formatted_raw_ostream> o)
ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){} : ModulePass(ID), OutOwner(std::move(o)), Out(*OutOwner), uniqueNum(0),
is_inline(false), indent_level(0) {}
const char *getPassName() const override { return "C++ backend"; } const char *getPassName() const override { return "C++ backend"; }
@ -2146,13 +2149,14 @@ char CppWriter::ID = 0;
// External Interface declaration // External Interface declaration
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM, bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM, raw_ostream &o,
formatted_raw_ostream &o,
CodeGenFileType FileType, CodeGenFileType FileType,
bool DisableVerify, bool DisableVerify,
AnalysisID StartAfter, AnalysisID StartAfter,
AnalysisID StopAfter) { AnalysisID StopAfter) {
if (FileType != TargetMachine::CGFT_AssemblyFile) return true; if (FileType != TargetMachine::CGFT_AssemblyFile)
PM.add(new CppWriter(o)); return true;
auto FOut = llvm::make_unique<formatted_raw_ostream>(o);
PM.add(new CppWriter(std::move(FOut)));
return false; return false;
} }

View File

@ -29,7 +29,7 @@ struct CPPTargetMachine : public TargetMachine {
: TargetMachine(T, "", TT, CPU, FS, Options) {} : TargetMachine(T, "", TT, CPU, FS, Options) {}
public: public:
bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, bool addPassesToEmitFile(PassManagerBase &PM, raw_ostream &Out,
CodeGenFileType FileType, bool DisableVerify, CodeGenFileType FileType, bool DisableVerify,
AnalysisID StartAfter, AnalysisID StartAfter,
AnalysisID StopAfter) override; AnalysisID StopAfter) override;

View File

@ -183,7 +183,7 @@ void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
} }
static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
formatted_raw_ostream &OS, raw_ostream &OS,
LLVMCodeGenFileType codegen, LLVMCodeGenFileType codegen,
char **ErrorMessage) { char **ErrorMessage) {
TargetMachine* TM = unwrap(T); TargetMachine* TM = unwrap(T);
@ -231,8 +231,7 @@ LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
*ErrorMessage = strdup(EC.message().c_str()); *ErrorMessage = strdup(EC.message().c_str());
return true; return true;
} }
formatted_raw_ostream destf(dest); bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
dest.flush(); dest.flush();
return Result; return Result;
} }
@ -242,8 +241,7 @@ LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
LLVMMemoryBufferRef *OutMemBuf) { LLVMMemoryBufferRef *OutMemBuf) {
SmallString<0> CodeString; SmallString<0> CodeString;
raw_svector_ostream OStream(CodeString); raw_svector_ostream OStream(CodeString);
formatted_raw_ostream Out(OStream); bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
OStream.flush(); OStream.flush();
StringRef Data = OStream.str(); StringRef Data = OStream.str();

View File

@ -31,7 +31,7 @@
#include "llvm/Linker/Linker.h" #include "llvm/Linker/Linker.h"
#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/IRObjectFile.h"
#include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Host.h" #include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
@ -804,9 +804,8 @@ static void codegen(Module &M) {
{ {
raw_fd_ostream OS(FD, true); raw_fd_ostream OS(FD, true);
formatted_raw_ostream FOS(OS);
if (TM->addPassesToEmitFile(CodeGenPasses, FOS, if (TM->addPassesToEmitFile(CodeGenPasses, OS,
TargetMachine::CGFT_ObjectFile)) TargetMachine::CGFT_ObjectFile))
message(LDPL_FATAL, "Failed to setup codegen"); message(LDPL_FATAL, "Failed to setup codegen");
CodeGenPasses.run(M); CodeGenPasses.run(M);

View File

@ -335,8 +335,6 @@ static int compileModule(char **argv, LLVMContext &Context) {
<< ": warning: ignoring -mc-relax-all because filetype != obj"; << ": warning: ignoring -mc-relax-all because filetype != obj";
{ {
formatted_raw_ostream FOS(Out->os());
AnalysisID StartAfterID = nullptr; AnalysisID StartAfterID = nullptr;
AnalysisID StopAfterID = nullptr; AnalysisID StopAfterID = nullptr;
const PassRegistry *PR = PassRegistry::getPassRegistry(); const PassRegistry *PR = PassRegistry::getPassRegistry();
@ -358,7 +356,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
} }
// Ask the target to add backend passes as necessary. // Ask the target to add backend passes as necessary.
if (Target->addPassesToEmitFile(PM, FOS, FileType, NoVerify, if (Target->addPassesToEmitFile(PM, Out->os(), FileType, NoVerify,
StartAfterID, StopAfterID)) { StartAfterID, StopAfterID)) {
errs() << argv[0] << ": target does not support generation of this" errs() << argv[0] << ": target does not support generation of this"
<< " file type!\n"; << " file type!\n";

View File

@ -439,7 +439,6 @@ int main(int argc, char **argv) {
if (!Out) if (!Out)
return 1; return 1;
formatted_raw_ostream FOS(Out->os());
std::unique_ptr<MCStreamer> Str; std::unique_ptr<MCStreamer> Str;
std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
@ -461,9 +460,10 @@ int main(int argc, char **argv) {
CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
} }
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/ true, auto FOut = llvm::make_unique<formatted_raw_ostream>(Out->os());
/*useDwarfDirectory*/ true, IP, CE, Str.reset(TheTarget->createAsmStreamer(
MAB, ShowInst)); Ctx, std::move(FOut), /*asmverbose*/ true,
/*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst));
} else if (FileType == OFT_Null) { } else if (FileType == OFT_Null) {
Str.reset(TheTarget->createNullStreamer(Ctx)); Str.reset(TheTarget->createNullStreamer(Ctx));
@ -471,8 +471,8 @@ int main(int argc, char **argv) {
assert(FileType == OFT_ObjectFile && "Invalid file type!"); assert(FileType == OFT_ObjectFile && "Invalid file type!");
MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, FOS, CE, Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, Out->os(),
*STI, RelaxAll, CE, *STI, RelaxAll,
/*DWARFMustBeAtTheEnd*/ false)); /*DWARFMustBeAtTheEnd*/ false));
if (NoExecStack) if (NoExecStack)
Str->InitSections(true); Str->InitSections(true);