///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// 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,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
/// boundaries and querying the number of lines written to the stream.
///
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
/// unbuffered, since we're already doing our own buffering.
///
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
/// been flushed and the portion of the buffer that's been
/// scanned. The line and column scheme is zero-based.
///
void ComputePosition(const char *Ptr, size_t size);
+ void setStream(raw_ostream &Stream) {
+ releaseStream();
+
+ TheStream = &Stream;
+
+ // 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
+ // layer of buffering underneath. Resize the buffer to what TheStream
+ // had been using, and tell TheStream not to do its own buffering.
+ if (size_t BufferSize = TheStream->GetBufferSize())
+ SetBufferSize(BufferSize);
+ else
+ SetUnbuffered();
+ TheStream->SetUnbuffered();
+
+ Scanned = nullptr;
+ }
+
public:
/// formatted_raw_ostream - Open the specified file for
/// writing. If an error occurs, information about the error is
/// 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);
+ formatted_raw_ostream(raw_ostream &Stream)
+ : TheStream(nullptr), Position(0, 0) {
+ setStream(Stream);
}
- explicit formatted_raw_ostream()
- : TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+ explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
Scanned = nullptr;
}
releaseStream();
}
- void setStream(raw_ostream &Stream, bool Delete = false) {
- releaseStream();
-
- TheStream = &Stream;
- DeleteStream = Delete;
-
- // 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
- // layer of buffering underneath. Resize the buffer to what TheStream
- // had been using, and tell TheStream not to do its own buffering.
- if (size_t BufferSize = TheStream->GetBufferSize())
- SetBufferSize(BufferSize);
- else
- SetUnbuffered();
- TheStream->SetUnbuffered();
-
- Scanned = nullptr;
- }
-
/// PadToColumn - Align the output to some column number. If the current
/// column is already equal to or more than NewCol, PadToColumn inserts one
/// space.
private:
void releaseStream() {
- // Delete the stream if needed. Otherwise, transfer the buffer
- // settings from this raw_ostream back to the underlying stream.
+ // Transfer the buffer settings from this raw_ostream back to the underlying
+ // stream.
if (!TheStream)
return;
- if (DeleteStream)
- delete TheStream;
- else if (size_t BufferSize = GetBufferSize())
+ if (size_t BufferSize = GetBufferSize())
TheStream->SetBufferSize(BufferSize);
else
TheStream->SetUnbuffered();
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/FormattedStream.h"
#include <cassert>
#include <memory>
#include <string>
class formatted_raw_ostream;
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,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
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,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst) const {
- MCStreamer *S =
- llvm::createAsmStreamer(Ctx, OS, IsVerboseAsm, UseDwarfDirectory,
- InstPrint, CE, TAB, ShowInst);
- createAsmTargetStreamer(*S, OS, InstPrint, IsVerboseAsm);
+ formatted_raw_ostream &OSRef = *OS;
+ MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IsVerboseAsm,
+ UseDwarfDirectory, InstPrint, CE,
+ TAB, ShowInst);
+ createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
return S;
}
/// emitted. Typically this will involve several steps of code generation.
/// This method should return true if emission of this file type is not
/// supported, or false on success.
- virtual bool addPassesToEmitFile(PassManagerBase &,
- formatted_raw_ostream &,
+ virtual bool addPassesToEmitFile(PassManagerBase &, raw_ostream &,
CodeGenFileType,
bool /*DisableVerify*/ = true,
AnalysisID /*StartAfter*/ = nullptr,
/// Add passes to the specified pass manager to get the specified file
/// 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,
AnalysisID StartAfter = nullptr,
AnalysisID StopAfter = nullptr) override;
return &MMI->getContext();
}
-bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
- formatted_raw_ostream &Out,
- CodeGenFileType FileType,
- bool DisableVerify,
- AnalysisID StartAfter,
- AnalysisID StopAfter) {
+bool LLVMTargetMachine::addPassesToEmitFile(
+ PassManagerBase &PM, raw_ostream &Out, CodeGenFileType FileType,
+ bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) {
// Add common CodeGen passes.
MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
StartAfter, StopAfter);
MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(),
TargetCPU);
+ auto FOut = llvm::make_unique<formatted_raw_ostream>(Out);
MCStreamer *S = getTarget().createAsmStreamer(
- *Context, Out, Options.MCOptions.AsmVerbose,
+ *Context, std::move(FOut), Options.MCOptions.AsmVerbose,
Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB,
Options.MCOptions.ShowMCInst);
AsmStreamer.reset(S);
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
legacy::PassManager codeGenPasses;
- formatted_raw_ostream Out(out);
-
// If the bitcode files contain ARC code and were compiled with optimization,
// the ObjCARCContractPass must be run, so do it unconditionally here.
codeGenPasses.add(createObjCARCContractPass());
- if (TargetMach->addPassesToEmitFile(codeGenPasses, Out,
+ if (TargetMach->addPassesToEmitFile(codeGenPasses, out,
TargetMachine::CGFT_ObjectFile)) {
errMsg = "target file type not supported";
return false;
namespace {
class MCAsmStreamer final : public MCStreamer {
+ std::unique_ptr<formatted_raw_ostream> OSOwner;
formatted_raw_ostream &OS;
const MCAsmInfo *MAI;
std::unique_ptr<MCInstPrinter> InstPrinter;
void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
public:
- MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
+ MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *printer, MCCodeEmitter *emitter,
MCAsmBackend *asmbackend, bool showInst)
- : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
- InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
- CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
- ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
+ : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
+ MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter),
+ AsmBackend(asmbackend), CommentStream(CommentToEmit),
+ IsVerboseAsm(isVerboseAsm), ShowInst(showInst),
+ UseDwarfDirectory(useDwarfDirectory) {
if (InstPrinter && IsVerboseAsm)
InstPrinter->setCommentStream(CommentStream);
}
}
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
- formatted_raw_ostream &OS,
+ std::unique_ptr<formatted_raw_ostream> OS,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *IP, MCCodeEmitter *CE,
MCAsmBackend *MAB, bool ShowInst) {
- return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE,
- MAB, ShowInst);
+ return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
+ useDwarfDirectory, IP, CE, MAB, ShowInst);
}
#include "CPPTargetMachine.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
/// CppWriter - This class is the main chunk of code that converts an LLVM
/// module to a C++ translation unit.
class CppWriter : public ModulePass {
+ std::unique_ptr<formatted_raw_ostream> OutOwner;
formatted_raw_ostream &Out;
const Module *TheModule;
uint64_t uniqueNum;
public:
static char ID;
- explicit CppWriter(formatted_raw_ostream &o) :
- ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){}
+ explicit CppWriter(std::unique_ptr<formatted_raw_ostream> o)
+ : ModulePass(ID), OutOwner(std::move(o)), Out(*OutOwner), uniqueNum(0),
+ is_inline(false), indent_level(0) {}
const char *getPassName() const override { return "C++ backend"; }
// External Interface declaration
//===----------------------------------------------------------------------===//
-bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
- formatted_raw_ostream &o,
+bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM, raw_ostream &o,
CodeGenFileType FileType,
bool DisableVerify,
AnalysisID StartAfter,
AnalysisID StopAfter) {
- if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
- PM.add(new CppWriter(o));
+ if (FileType != TargetMachine::CGFT_AssemblyFile)
+ return true;
+ auto FOut = llvm::make_unique<formatted_raw_ostream>(o);
+ PM.add(new CppWriter(std::move(FOut)));
return false;
}
: TargetMachine(T, "", TT, CPU, FS, Options) {}
public:
- bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out,
+ bool addPassesToEmitFile(PassManagerBase &PM, raw_ostream &Out,
CodeGenFileType FileType, bool DisableVerify,
AnalysisID StartAfter,
AnalysisID StopAfter) override;
}
static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
- formatted_raw_ostream &OS,
+ raw_ostream &OS,
LLVMCodeGenFileType codegen,
char **ErrorMessage) {
TargetMachine* TM = unwrap(T);
*ErrorMessage = strdup(EC.message().c_str());
return true;
}
- formatted_raw_ostream destf(dest);
- bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
+ bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
dest.flush();
return Result;
}
LLVMMemoryBufferRef *OutMemBuf) {
SmallString<0> CodeString;
raw_svector_ostream OStream(CodeString);
- formatted_raw_ostream Out(OStream);
- bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
+ bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
OStream.flush();
StringRef Data = OStream.str();
#include "llvm/Linker/Linker.h"
#include "llvm/MC/SubtargetFeature.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/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
{
raw_fd_ostream OS(FD, true);
- formatted_raw_ostream FOS(OS);
- if (TM->addPassesToEmitFile(CodeGenPasses, FOS,
+ if (TM->addPassesToEmitFile(CodeGenPasses, OS,
TargetMachine::CGFT_ObjectFile))
message(LDPL_FATAL, "Failed to setup codegen");
CodeGenPasses.run(M);
<< ": warning: ignoring -mc-relax-all because filetype != obj";
{
- formatted_raw_ostream FOS(Out->os());
-
AnalysisID StartAfterID = nullptr;
AnalysisID StopAfterID = nullptr;
const PassRegistry *PR = PassRegistry::getPassRegistry();
}
// 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)) {
errs() << argv[0] << ": target does not support generation of this"
<< " file type!\n";
if (!Out)
return 1;
- formatted_raw_ostream FOS(Out->os());
std::unique_ptr<MCStreamer> Str;
std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
}
- Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/ true,
- /*useDwarfDirectory*/ true, IP, CE,
- MAB, ShowInst));
+ auto FOut = llvm::make_unique<formatted_raw_ostream>(Out->os());
+ Str.reset(TheTarget->createAsmStreamer(
+ Ctx, std::move(FOut), /*asmverbose*/ true,
+ /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst));
} else if (FileType == OFT_Null) {
Str.reset(TheTarget->createNullStreamer(Ctx));
assert(FileType == OFT_ObjectFile && "Invalid file type!");
MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
- Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, FOS, CE,
- *STI, RelaxAll,
+ Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, Out->os(),
+ CE, *STI, RelaxAll,
/*DWARFMustBeAtTheEnd*/ false));
if (NoExecStack)
Str->InitSections(true);