forked from OSchip/llvm-project
Make tool_output_file's raw_ostream instance a member variable instead
of a base class. This makes it possible to unregister the file from FilesToRemove when the file is done. Also, this eliminates the need for formatted_tool_output_file. llvm-svn: 112706
This commit is contained in:
parent
e201c07d23
commit
a2233f2801
|
@ -19,14 +19,10 @@
|
|||
|
||||
namespace llvm
|
||||
{
|
||||
class formatted_tool_output_file;
|
||||
|
||||
/// formatted_raw_ostream - Formatted raw_fd_ostream to handle
|
||||
/// asm-specific constructs.
|
||||
///
|
||||
class formatted_raw_ostream : public raw_ostream {
|
||||
friend class formatted_tool_output_file;
|
||||
|
||||
public:
|
||||
/// DELETE_STREAM - Tell the destructor to delete the held stream.
|
||||
///
|
||||
|
@ -140,38 +136,6 @@ namespace llvm
|
|||
}
|
||||
};
|
||||
|
||||
/// formatted_tool_output_file - This is a subclass of formatted_raw_ostream
|
||||
/// for use when the underlying stream is a tool_output_file. It exposes
|
||||
/// keep() and several other member functions.
|
||||
class formatted_tool_output_file : public formatted_raw_ostream {
|
||||
private:
|
||||
tool_output_file &get_tool_output_file() const {
|
||||
return *static_cast<tool_output_file *>(TheStream);
|
||||
}
|
||||
|
||||
public:
|
||||
formatted_tool_output_file(tool_output_file &Stream, bool Delete = false)
|
||||
: formatted_raw_ostream(Stream, Delete) {}
|
||||
|
||||
formatted_tool_output_file() {}
|
||||
|
||||
~formatted_tool_output_file();
|
||||
|
||||
void setStream(tool_output_file &Stream, bool Delete = false) {
|
||||
return formatted_raw_ostream::setStream(Stream, Delete);
|
||||
}
|
||||
|
||||
void keep() { return get_tool_output_file().keep(); }
|
||||
bool has_error() const { return get_tool_output_file().has_error(); }
|
||||
void clear_error() { return get_tool_output_file().clear_error(); }
|
||||
void close() {
|
||||
// The inner stream is unbuffered; flush the outer stream's buffer.
|
||||
flush();
|
||||
// The inner stream can close its file descriptor now.
|
||||
return get_tool_output_file().close();
|
||||
}
|
||||
};
|
||||
|
||||
/// fouts() - This returns a reference to a formatted_raw_ostream for
|
||||
/// standard output. Use it like: fouts() << "foo" << "bar";
|
||||
formatted_raw_ostream &fouts();
|
||||
|
|
|
@ -475,23 +475,43 @@ public:
|
|||
~raw_null_ostream();
|
||||
};
|
||||
|
||||
/// tool_output_file - This class behaves like a raw_fd_ostream but adds a
|
||||
/// tool_output_file - This class contains a raw_fd_ostream and adds a
|
||||
/// few extra features commonly needed for compiler-like tool output files:
|
||||
/// - The file is automatically deleted if the process is killed.
|
||||
/// - The file is automatically deleted when the tool_output_file
|
||||
/// object is destroyed unless the client calls keep().
|
||||
class tool_output_file : public raw_fd_ostream {
|
||||
std::string Filename;
|
||||
bool Keep;
|
||||
class tool_output_file {
|
||||
/// Installer - This class is declared before the raw_fd_ostream so that
|
||||
/// it is constructed before the raw_fd_ostream is constructed and
|
||||
/// destructed after the raw_fd_ostream is destructed. It installs
|
||||
/// cleanups in its constructor and uninstalls them in its destructor.
|
||||
class CleanupInstaller {
|
||||
/// Filename - The name of the file.
|
||||
std::string Filename;
|
||||
public:
|
||||
/// Keep - The flag which indicates whether we should not delete the file.
|
||||
bool Keep;
|
||||
|
||||
explicit CleanupInstaller(const char *filename);
|
||||
~CleanupInstaller();
|
||||
} Installer;
|
||||
|
||||
/// OS - The contained stream. This is intentionally declared after
|
||||
/// Installer.
|
||||
raw_fd_ostream OS;
|
||||
|
||||
public:
|
||||
/// tool_output_file - This constructor's arguments are passed to
|
||||
/// to raw_fd_ostream's constructor.
|
||||
tool_output_file(const char *filename, std::string &ErrorInfo,
|
||||
unsigned Flags = 0);
|
||||
|
||||
~tool_output_file();
|
||||
/// os - Return the contained raw_fd_ostream.
|
||||
raw_fd_ostream &os() { return OS; }
|
||||
|
||||
/// keep - Indicate that the tool's job wrt this output file has been
|
||||
/// successful and the file should not be deleted.
|
||||
void keep() { Keep = true; }
|
||||
void keep() { Installer.Keep = true; }
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
|
|
@ -98,6 +98,3 @@ formatted_raw_ostream &llvm::fdbgs() {
|
|||
static formatted_raw_ostream S(dbgs());
|
||||
return S;
|
||||
}
|
||||
|
||||
/// ~formatted_tool_output_file - Out-of-line destructor.
|
||||
formatted_tool_output_file::~formatted_tool_output_file() {}
|
||||
|
|
|
@ -670,25 +670,29 @@ uint64_t raw_null_ostream::current_pos() const {
|
|||
// tool_output_file
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// SetupRemoveOnSignal - This is a helper for tool_output_file's constructor
|
||||
/// to allow the signal handlers to be installed before constructing the
|
||||
/// base class raw_fd_ostream.
|
||||
static const char *SetupRemoveOnSignal(const char *Filename) {
|
||||
tool_output_file::CleanupInstaller::CleanupInstaller(const char *filename)
|
||||
: Filename(filename), Keep(false) {
|
||||
// Arrange for the file to be deleted if the process is killed.
|
||||
if (strcmp(Filename, "-") != 0)
|
||||
if (Filename != "-")
|
||||
sys::RemoveFileOnSignal(sys::Path(Filename));
|
||||
return Filename;
|
||||
}
|
||||
|
||||
tool_output_file::tool_output_file(const char *filename, std::string &ErrorInfo,
|
||||
unsigned Flags)
|
||||
: raw_fd_ostream(SetupRemoveOnSignal(filename), ErrorInfo, Flags),
|
||||
Filename(filename),
|
||||
Keep(!ErrorInfo.empty() /* If open fails, no cleanup is needed. */) {
|
||||
}
|
||||
|
||||
tool_output_file::~tool_output_file() {
|
||||
tool_output_file::CleanupInstaller::~CleanupInstaller() {
|
||||
// Delete the file if the client hasn't told us not to.
|
||||
if (!Keep && Filename != "-")
|
||||
sys::Path(Filename).eraseFromDisk();
|
||||
|
||||
// Ok, the file is successfully written and closed, or deleted. There's no
|
||||
// further need to clean it up on signals.
|
||||
if (Filename != "-")
|
||||
sys::DontRemoveFileOnSignal(sys::Path(Filename));
|
||||
}
|
||||
|
||||
tool_output_file::tool_output_file(const char *filename, std::string &ErrorInfo,
|
||||
unsigned Flags)
|
||||
: Installer(filename),
|
||||
OS(filename, ErrorInfo, Flags) {
|
||||
// If open fails, no cleanup is needed.
|
||||
if (!ErrorInfo.empty())
|
||||
Installer.Keep = true;
|
||||
}
|
||||
|
|
|
@ -339,15 +339,15 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
|
|||
// If the BB doesn't have a name, give it one so we have something to key
|
||||
// off of.
|
||||
if (!BB->hasName()) BB->setName("tmpbb");
|
||||
BlocksToNotExtractFile << BB->getParent()->getNameStr() << " "
|
||||
<< BB->getName() << "\n";
|
||||
BlocksToNotExtractFile.os() << BB->getParent()->getNameStr() << " "
|
||||
<< BB->getName() << "\n";
|
||||
}
|
||||
BlocksToNotExtractFile.close();
|
||||
if (BlocksToNotExtractFile.has_error()) {
|
||||
BlocksToNotExtractFile.os().close();
|
||||
if (BlocksToNotExtractFile.os().has_error()) {
|
||||
errs() << "Error writing list of blocks to not extract: " << ErrorInfo
|
||||
<< "\n";
|
||||
EmitProgressBitcode(M, "basicblockextractfail", true);
|
||||
BlocksToNotExtractFile.clear_error();
|
||||
BlocksToNotExtractFile.os().clear_error();
|
||||
return 0;
|
||||
}
|
||||
BlocksToNotExtractFile.keep();
|
||||
|
|
|
@ -58,14 +58,14 @@ bool BugDriver::writeProgramToFile(const std::string &Filename,
|
|||
tool_output_file Out(Filename.c_str(), ErrInfo,
|
||||
raw_fd_ostream::F_Binary);
|
||||
if (ErrInfo.empty()) {
|
||||
WriteBitcodeToFile(M, Out);
|
||||
Out.close();
|
||||
if (!Out.has_error()) {
|
||||
WriteBitcodeToFile(M, Out.os());
|
||||
Out.os().close();
|
||||
if (!Out.os().has_error()) {
|
||||
Out.keep();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Out.clear_error();
|
||||
Out.os().clear_error();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -140,11 +140,11 @@ bool BugDriver::runPasses(Module *Program,
|
|||
errs() << "Error opening bitcode file: " << inputFilename.str() << "\n";
|
||||
return 1;
|
||||
}
|
||||
WriteBitcodeToFile(Program, InFile);
|
||||
InFile.close();
|
||||
if (InFile.has_error()) {
|
||||
WriteBitcodeToFile(Program, InFile.os());
|
||||
InFile.os().close();
|
||||
if (InFile.os().has_error()) {
|
||||
errs() << "Error writing bitcode file: " << inputFilename.str() << "\n";
|
||||
InFile.clear_error();
|
||||
InFile.os().clear_error();
|
||||
return 1;
|
||||
}
|
||||
InFile.keep();
|
||||
|
|
|
@ -123,9 +123,9 @@ GetFileNameRoot(const std::string &InputFilename) {
|
|||
return outputFilename;
|
||||
}
|
||||
|
||||
static formatted_tool_output_file *GetOutputStream(const char *TargetName,
|
||||
Triple::OSType OS,
|
||||
const char *ProgName) {
|
||||
static tool_output_file *GetOutputStream(const char *TargetName,
|
||||
Triple::OSType OS,
|
||||
const char *ProgName) {
|
||||
// If we don't yet have an output filename, make one.
|
||||
if (OutputFilename.empty()) {
|
||||
if (InputFilename == "-")
|
||||
|
@ -183,11 +183,7 @@ static formatted_tool_output_file *GetOutputStream(const char *TargetName,
|
|||
return 0;
|
||||
}
|
||||
|
||||
formatted_tool_output_file *Out =
|
||||
new formatted_tool_output_file(*FDOut,
|
||||
formatted_raw_ostream::DELETE_STREAM);
|
||||
|
||||
return Out;
|
||||
return FDOut;
|
||||
}
|
||||
|
||||
// main - Entry point for the llc compiler.
|
||||
|
@ -278,7 +274,7 @@ int main(int argc, char **argv) {
|
|||
TargetMachine &Target = *target.get();
|
||||
|
||||
// Figure out where we are going to send the output...
|
||||
OwningPtr<formatted_tool_output_file> Out
|
||||
OwningPtr<tool_output_file> Out
|
||||
(GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
|
||||
if (!Out) return 1;
|
||||
|
||||
|
@ -314,15 +310,18 @@ int main(int argc, char **argv) {
|
|||
Target.setMCRelaxAll(true);
|
||||
}
|
||||
|
||||
// Ask the target to add backend passes as necessary.
|
||||
if (Target.addPassesToEmitFile(PM, *Out, FileType, OLvl,
|
||||
NoVerify)) {
|
||||
errs() << argv[0] << ": target does not support generation of this"
|
||||
<< " file type!\n";
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
formatted_raw_ostream FOS(Out->os());
|
||||
|
||||
PM.run(mod);
|
||||
// Ask the target to add backend passes as necessary.
|
||||
if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) {
|
||||
errs() << argv[0] << ": target does not support generation of this"
|
||||
<< " file type!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
PM.run(mod);
|
||||
}
|
||||
|
||||
// Declare success.
|
||||
Out->keep();
|
||||
|
|
|
@ -77,8 +77,8 @@ static void WriteOutputFile(const Module *M) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (Force || !CheckBitcodeOutputToConsole(*Out, true))
|
||||
WriteBitcodeToFile(M, *Out);
|
||||
if (Force || !CheckBitcodeOutputToConsole(Out->os(), true))
|
||||
WriteBitcodeToFile(M, Out->os());
|
||||
|
||||
// Declare success.
|
||||
Out->keep();
|
||||
|
|
|
@ -98,7 +98,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// All that llvm-dis does is write the assembly to a file.
|
||||
if (!DontPrint)
|
||||
*Out << *M;
|
||||
Out->os() << *M;
|
||||
|
||||
// Declare success.
|
||||
Out->keep();
|
||||
|
|
|
@ -134,9 +134,9 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (OutputAssembly)
|
||||
Passes.add(createPrintModulePass(&Out));
|
||||
else if (Force || !CheckBitcodeOutputToConsole(Out, true))
|
||||
Passes.add(createBitcodeWriterPass(Out));
|
||||
Passes.add(createPrintModulePass(&Out.os()));
|
||||
else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
|
||||
Passes.add(createBitcodeWriterPass(Out.os()));
|
||||
|
||||
Passes.run(*M.get());
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ void GenerateBitcode(Module* M, const std::string& FileName) {
|
|||
}
|
||||
|
||||
// Write it out
|
||||
WriteBitcodeToFile(M, Out);
|
||||
WriteBitcodeToFile(M, Out.os());
|
||||
Out.keep();
|
||||
}
|
||||
|
||||
|
@ -432,10 +432,10 @@ static void EmitShellScript(char **argv, Module *M) {
|
|||
if (!ErrorInfo.empty())
|
||||
PrintAndExit(ErrorInfo, M);
|
||||
|
||||
Out2 << "#!/bin/sh\n";
|
||||
Out2.os() << "#!/bin/sh\n";
|
||||
// Allow user to setenv LLVMINTERP if lli is not in their PATH.
|
||||
Out2 << "lli=${LLVMINTERP-lli}\n";
|
||||
Out2 << "exec $lli \\\n";
|
||||
Out2.os() << "lli=${LLVMINTERP-lli}\n";
|
||||
Out2.os() << "exec $lli \\\n";
|
||||
// gcc accepts -l<lib> and implicitly searches /lib and /usr/lib.
|
||||
LibPaths.push_back("/lib");
|
||||
LibPaths.push_back("/usr/lib");
|
||||
|
@ -466,9 +466,9 @@ static void EmitShellScript(char **argv, Module *M) {
|
|||
if (FullLibraryPath.isEmpty())
|
||||
FullLibraryPath = sys::Path::FindLibrary(*i);
|
||||
if (!FullLibraryPath.isEmpty())
|
||||
Out2 << " -load=" << FullLibraryPath.str() << " \\\n";
|
||||
Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n";
|
||||
}
|
||||
Out2 << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n";
|
||||
Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n";
|
||||
Out2.keep();
|
||||
}
|
||||
|
||||
|
|
|
@ -130,9 +130,9 @@ int main(int argc, char **argv) {
|
|||
|
||||
if (Verbose) errs() << "Writing bitcode...\n";
|
||||
if (OutputAssembly) {
|
||||
Out << *Composite;
|
||||
} else if (Force || !CheckBitcodeOutputToConsole(Out, true))
|
||||
WriteBitcodeToFile(Composite.get(), Out);
|
||||
Out.os() << *Composite;
|
||||
} else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
|
||||
WriteBitcodeToFile(Composite.get(), Out.os());
|
||||
|
||||
// Declare success.
|
||||
Out.keep();
|
||||
|
|
|
@ -140,7 +140,7 @@ static const Target *GetTarget(const char *ProgName) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static formatted_tool_output_file *GetOutputStream() {
|
||||
static tool_output_file *GetOutputStream() {
|
||||
if (OutputFilename == "")
|
||||
OutputFilename = "-";
|
||||
|
||||
|
@ -152,9 +152,8 @@ static formatted_tool_output_file *GetOutputStream() {
|
|||
delete Out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new formatted_tool_output_file(*Out,
|
||||
formatted_raw_ostream::DELETE_STREAM);
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
static int AsLexInput(const char *ProgName) {
|
||||
|
@ -189,7 +188,7 @@ static int AsLexInput(const char *ProgName) {
|
|||
AsmLexer Lexer(*MAI);
|
||||
Lexer.setBuffer(SrcMgr.getMemoryBuffer(0));
|
||||
|
||||
OwningPtr<formatted_tool_output_file> Out(GetOutputStream());
|
||||
OwningPtr<tool_output_file> Out(GetOutputStream());
|
||||
if (!Out)
|
||||
return 1;
|
||||
|
||||
|
@ -204,44 +203,44 @@ static int AsLexInput(const char *ProgName) {
|
|||
Error = true; // error already printed.
|
||||
break;
|
||||
case AsmToken::Identifier:
|
||||
*Out << "identifier: " << Lexer.getTok().getString() << '\n';
|
||||
Out->os() << "identifier: " << Lexer.getTok().getString() << '\n';
|
||||
break;
|
||||
case AsmToken::String:
|
||||
*Out << "string: " << Lexer.getTok().getString() << '\n';
|
||||
Out->os() << "string: " << Lexer.getTok().getString() << '\n';
|
||||
break;
|
||||
case AsmToken::Integer:
|
||||
*Out << "int: " << Lexer.getTok().getString() << '\n';
|
||||
Out->os() << "int: " << Lexer.getTok().getString() << '\n';
|
||||
break;
|
||||
|
||||
case AsmToken::Amp: *Out << "Amp\n"; break;
|
||||
case AsmToken::AmpAmp: *Out << "AmpAmp\n"; break;
|
||||
case AsmToken::Caret: *Out << "Caret\n"; break;
|
||||
case AsmToken::Colon: *Out << "Colon\n"; break;
|
||||
case AsmToken::Comma: *Out << "Comma\n"; break;
|
||||
case AsmToken::Dollar: *Out << "Dollar\n"; break;
|
||||
case AsmToken::EndOfStatement: *Out << "EndOfStatement\n"; break;
|
||||
case AsmToken::Eof: *Out << "Eof\n"; break;
|
||||
case AsmToken::Equal: *Out << "Equal\n"; break;
|
||||
case AsmToken::EqualEqual: *Out << "EqualEqual\n"; break;
|
||||
case AsmToken::Exclaim: *Out << "Exclaim\n"; break;
|
||||
case AsmToken::ExclaimEqual: *Out << "ExclaimEqual\n"; break;
|
||||
case AsmToken::Greater: *Out << "Greater\n"; break;
|
||||
case AsmToken::GreaterEqual: *Out << "GreaterEqual\n"; break;
|
||||
case AsmToken::GreaterGreater: *Out << "GreaterGreater\n"; break;
|
||||
case AsmToken::LParen: *Out << "LParen\n"; break;
|
||||
case AsmToken::Less: *Out << "Less\n"; break;
|
||||
case AsmToken::LessEqual: *Out << "LessEqual\n"; break;
|
||||
case AsmToken::LessGreater: *Out << "LessGreater\n"; break;
|
||||
case AsmToken::LessLess: *Out << "LessLess\n"; break;
|
||||
case AsmToken::Minus: *Out << "Minus\n"; break;
|
||||
case AsmToken::Percent: *Out << "Percent\n"; break;
|
||||
case AsmToken::Pipe: *Out << "Pipe\n"; break;
|
||||
case AsmToken::PipePipe: *Out << "PipePipe\n"; break;
|
||||
case AsmToken::Plus: *Out << "Plus\n"; break;
|
||||
case AsmToken::RParen: *Out << "RParen\n"; break;
|
||||
case AsmToken::Slash: *Out << "Slash\n"; break;
|
||||
case AsmToken::Star: *Out << "Star\n"; break;
|
||||
case AsmToken::Tilde: *Out << "Tilde\n"; break;
|
||||
case AsmToken::Amp: Out->os() << "Amp\n"; break;
|
||||
case AsmToken::AmpAmp: Out->os() << "AmpAmp\n"; break;
|
||||
case AsmToken::Caret: Out->os() << "Caret\n"; break;
|
||||
case AsmToken::Colon: Out->os() << "Colon\n"; break;
|
||||
case AsmToken::Comma: Out->os() << "Comma\n"; break;
|
||||
case AsmToken::Dollar: Out->os() << "Dollar\n"; break;
|
||||
case AsmToken::EndOfStatement: Out->os() << "EndOfStatement\n"; break;
|
||||
case AsmToken::Eof: Out->os() << "Eof\n"; break;
|
||||
case AsmToken::Equal: Out->os() << "Equal\n"; break;
|
||||
case AsmToken::EqualEqual: Out->os() << "EqualEqual\n"; break;
|
||||
case AsmToken::Exclaim: Out->os() << "Exclaim\n"; break;
|
||||
case AsmToken::ExclaimEqual: Out->os() << "ExclaimEqual\n"; break;
|
||||
case AsmToken::Greater: Out->os() << "Greater\n"; break;
|
||||
case AsmToken::GreaterEqual: Out->os() << "GreaterEqual\n"; break;
|
||||
case AsmToken::GreaterGreater: Out->os() << "GreaterGreater\n"; break;
|
||||
case AsmToken::LParen: Out->os() << "LParen\n"; break;
|
||||
case AsmToken::Less: Out->os() << "Less\n"; break;
|
||||
case AsmToken::LessEqual: Out->os() << "LessEqual\n"; break;
|
||||
case AsmToken::LessGreater: Out->os() << "LessGreater\n"; break;
|
||||
case AsmToken::LessLess: Out->os() << "LessLess\n"; break;
|
||||
case AsmToken::Minus: Out->os() << "Minus\n"; break;
|
||||
case AsmToken::Percent: Out->os() << "Percent\n"; break;
|
||||
case AsmToken::Pipe: Out->os() << "Pipe\n"; break;
|
||||
case AsmToken::PipePipe: Out->os() << "PipePipe\n"; break;
|
||||
case AsmToken::Plus: Out->os() << "Plus\n"; break;
|
||||
case AsmToken::RParen: Out->os() << "RParen\n"; break;
|
||||
case AsmToken::Slash: Out->os() << "Slash\n"; break;
|
||||
case AsmToken::Star: Out->os() << "Star\n"; break;
|
||||
case AsmToken::Tilde: Out->os() << "Tilde\n"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,10 +290,11 @@ static int AssembleInput(const char *ProgName) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
OwningPtr<formatted_tool_output_file> Out(GetOutputStream());
|
||||
OwningPtr<tool_output_file> Out(GetOutputStream());
|
||||
if (!Out)
|
||||
return 1;
|
||||
|
||||
formatted_raw_ostream FOS(Out->os());
|
||||
OwningPtr<MCStreamer> Str;
|
||||
|
||||
if (FileType == OFT_AssemblyFile) {
|
||||
|
@ -303,7 +303,7 @@ static int AssembleInput(const char *ProgName) {
|
|||
MCCodeEmitter *CE = 0;
|
||||
if (ShowEncoding)
|
||||
CE = TheTarget->createCodeEmitter(*TM, Ctx);
|
||||
Str.reset(createAsmStreamer(Ctx, *Out,
|
||||
Str.reset(createAsmStreamer(Ctx, FOS,
|
||||
TM->getTargetData()->isLittleEndian(),
|
||||
/*asmverbose*/true, IP, CE, ShowInst));
|
||||
} else if (FileType == OFT_Null) {
|
||||
|
@ -313,7 +313,7 @@ static int AssembleInput(const char *ProgName) {
|
|||
MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
|
||||
TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);
|
||||
Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
|
||||
*Out, CE, RelaxAll));
|
||||
FOS, CE, RelaxAll));
|
||||
}
|
||||
|
||||
if (EnableLogging) {
|
||||
|
@ -359,15 +359,15 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
OwningPtr<formatted_tool_output_file> Out(GetOutputStream());
|
||||
OwningPtr<tool_output_file> Out(GetOutputStream());
|
||||
if (!Out)
|
||||
return 1;
|
||||
|
||||
int Res;
|
||||
if (Enhanced)
|
||||
Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, *Out);
|
||||
Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, Out->os());
|
||||
else
|
||||
Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, *Out);
|
||||
Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, Out->os());
|
||||
|
||||
// Keep output if no errors.
|
||||
if (Res == 0) Out->keep();
|
||||
|
|
|
@ -164,13 +164,13 @@ bool LTOCodeGenerator::writeMergedModules(const char *path,
|
|||
}
|
||||
|
||||
// write bitcode to it
|
||||
WriteBitcodeToFile(_linker.getModule(), Out);
|
||||
Out.close();
|
||||
WriteBitcodeToFile(_linker.getModule(), Out.os());
|
||||
Out.os().close();
|
||||
|
||||
if (Out.has_error()) {
|
||||
if (Out.os().has_error()) {
|
||||
errMsg = "could not write bitcode file: ";
|
||||
errMsg += path;
|
||||
Out.clear_error();
|
||||
Out.os().clear_error();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -190,14 +190,13 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
|
|||
// generate assembly code
|
||||
bool genResult = false;
|
||||
{
|
||||
tool_output_file asmFD(uniqueAsmPath.c_str(), errMsg);
|
||||
formatted_tool_output_file asmFile(asmFD);
|
||||
tool_output_file asmFile(uniqueAsmPath.c_str(), errMsg);
|
||||
if (!errMsg.empty())
|
||||
return NULL;
|
||||
genResult = this->generateAssemblyCode(asmFile, errMsg);
|
||||
asmFile.close();
|
||||
if (asmFile.has_error()) {
|
||||
asmFile.clear_error();
|
||||
genResult = this->generateAssemblyCode(asmFile.os(), errMsg);
|
||||
asmFile.os().close();
|
||||
if (asmFile.os().has_error()) {
|
||||
asmFile.os().clear_error();
|
||||
return NULL;
|
||||
}
|
||||
asmFile.keep();
|
||||
|
@ -368,7 +367,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
|
|||
}
|
||||
|
||||
/// Optimize merged modules using various IPO passes
|
||||
bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out,
|
||||
bool LTOCodeGenerator::generateAssemblyCode(raw_ostream& out,
|
||||
std::string& errMsg)
|
||||
{
|
||||
if ( this->determineTarget(errMsg) )
|
||||
|
@ -403,7 +402,9 @@ bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out,
|
|||
|
||||
codeGenPasses->add(new TargetData(*_target->getTargetData()));
|
||||
|
||||
if (_target->addPassesToEmitFile(*codeGenPasses, out,
|
||||
formatted_raw_ostream Out(out);
|
||||
|
||||
if (_target->addPassesToEmitFile(*codeGenPasses, Out,
|
||||
TargetMachine::CGFT_AssemblyFile,
|
||||
CodeGenOpt::Aggressive)) {
|
||||
errMsg = "target file type not supported";
|
||||
|
|
|
@ -45,7 +45,7 @@ struct LTOCodeGenerator {
|
|||
const void* compile(size_t* length, std::string& errMsg);
|
||||
void setCodeGenDebugOptions(const char *opts);
|
||||
private:
|
||||
bool generateAssemblyCode(llvm::formatted_raw_ostream& out,
|
||||
bool generateAssemblyCode(llvm::raw_ostream& out,
|
||||
std::string& errMsg);
|
||||
bool assemble(const std::string& asmPath,
|
||||
const std::string& objPath, std::string& errMsg);
|
||||
|
|
|
@ -31,16 +31,16 @@ static void WriteGraphToFile(raw_ostream &O, const std::string &GraphName,
|
|||
tool_output_file F(Filename.c_str(), ErrInfo);
|
||||
|
||||
if (ErrInfo.empty()) {
|
||||
WriteGraph(F, GT);
|
||||
F.close();
|
||||
if (!F.has_error()) {
|
||||
WriteGraph(F.os(), GT);
|
||||
F.os().close();
|
||||
if (!F.os().has_error()) {
|
||||
O << "\n";
|
||||
F.keep();
|
||||
return;
|
||||
}
|
||||
}
|
||||
F.clear_error();
|
||||
O << " error opening file for writing!\n";
|
||||
F.os().clear_error();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -359,6 +359,11 @@ void AddStandardLinkPasses(PassManagerBase &PM) {
|
|||
int main(int argc, char **argv) {
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
llvm::PrettyStackTraceProgram X(argc, argv);
|
||||
|
||||
if (AnalyzeOnly && NoOutput) {
|
||||
errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Enable debug stream buffering.
|
||||
EnableDebugBuffering = true;
|
||||
|
@ -408,7 +413,7 @@ int main(int argc, char **argv) {
|
|||
// console, print out a warning message and refuse to do it. We don't
|
||||
// impress anyone by spewing tons of binary goo to a terminal.
|
||||
if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly)
|
||||
if (CheckBitcodeOutputToConsole(*Out, !Quiet))
|
||||
if (CheckBitcodeOutputToConsole(Out->os(), !Quiet))
|
||||
NoOutput = true;
|
||||
|
||||
// Create a PassManager to hold and optimize the collection of passes we are
|
||||
|
@ -484,19 +489,19 @@ int main(int argc, char **argv) {
|
|||
if (AnalyzeOnly) {
|
||||
switch (Kind) {
|
||||
case PT_BasicBlock:
|
||||
Passes.add(new BasicBlockPassPrinter(PassInf, *Out));
|
||||
Passes.add(new BasicBlockPassPrinter(PassInf, Out->os()));
|
||||
break;
|
||||
case PT_Loop:
|
||||
Passes.add(new LoopPassPrinter(PassInf, *Out));
|
||||
Passes.add(new LoopPassPrinter(PassInf, Out->os()));
|
||||
break;
|
||||
case PT_Function:
|
||||
Passes.add(new FunctionPassPrinter(PassInf, *Out));
|
||||
Passes.add(new FunctionPassPrinter(PassInf, Out->os()));
|
||||
break;
|
||||
case PT_CallGraphSCC:
|
||||
Passes.add(new CallGraphSCCPassPrinter(PassInf, *Out));
|
||||
Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os()));
|
||||
break;
|
||||
default:
|
||||
Passes.add(new ModulePassPrinter(PassInf, *Out));
|
||||
Passes.add(new ModulePassPrinter(PassInf, Out->os()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -536,9 +541,9 @@ int main(int argc, char **argv) {
|
|||
// Write bitcode or assembly to the output as the last step...
|
||||
if (!NoOutput && !AnalyzeOnly) {
|
||||
if (OutputAssembly)
|
||||
Passes.add(createPrintModulePass(Out.get()));
|
||||
Passes.add(createPrintModulePass(&Out->os()));
|
||||
else
|
||||
Passes.add(createBitcodeWriterPass(*Out));
|
||||
Passes.add(createBitcodeWriterPass(Out->os()));
|
||||
}
|
||||
|
||||
// Now that we have all of the passes ready, run them.
|
||||
|
|
|
@ -78,7 +78,7 @@ int main(int argc, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
OutStream.write(In->getBufferStart(), In->getBufferSize());
|
||||
OutStream.os().write(In->getBufferStart(), In->getBufferSize());
|
||||
|
||||
// Declare success.
|
||||
OutStream.keep();
|
||||
|
|
|
@ -226,109 +226,109 @@ int main(int argc, char **argv) {
|
|||
try {
|
||||
switch (Action) {
|
||||
case PrintRecords:
|
||||
Out << Records; // No argument, dump all contents
|
||||
Out.os() << Records; // No argument, dump all contents
|
||||
break;
|
||||
case GenEmitter:
|
||||
CodeEmitterGen(Records).run(Out);
|
||||
CodeEmitterGen(Records).run(Out.os());
|
||||
break;
|
||||
|
||||
case GenRegisterEnums:
|
||||
RegisterInfoEmitter(Records).runEnums(Out);
|
||||
RegisterInfoEmitter(Records).runEnums(Out.os());
|
||||
break;
|
||||
case GenRegister:
|
||||
RegisterInfoEmitter(Records).run(Out);
|
||||
RegisterInfoEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenRegisterHeader:
|
||||
RegisterInfoEmitter(Records).runHeader(Out);
|
||||
RegisterInfoEmitter(Records).runHeader(Out.os());
|
||||
break;
|
||||
case GenInstrEnums:
|
||||
InstrEnumEmitter(Records).run(Out);
|
||||
InstrEnumEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenInstrs:
|
||||
InstrInfoEmitter(Records).run(Out);
|
||||
InstrInfoEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenCallingConv:
|
||||
CallingConvEmitter(Records).run(Out);
|
||||
CallingConvEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenAsmWriter:
|
||||
AsmWriterEmitter(Records).run(Out);
|
||||
AsmWriterEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenARMDecoder:
|
||||
ARMDecoderEmitter(Records).run(Out);
|
||||
ARMDecoderEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenAsmMatcher:
|
||||
AsmMatcherEmitter(Records).run(Out);
|
||||
AsmMatcherEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangAttrClasses:
|
||||
ClangAttrClassEmitter(Records).run(Out);
|
||||
ClangAttrClassEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangAttrImpl:
|
||||
ClangAttrImplEmitter(Records).run(Out);
|
||||
ClangAttrImplEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangAttrList:
|
||||
ClangAttrListEmitter(Records).run(Out);
|
||||
ClangAttrListEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangAttrPCHRead:
|
||||
ClangAttrPCHReadEmitter(Records).run(Out);
|
||||
ClangAttrPCHReadEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangAttrPCHWrite:
|
||||
ClangAttrPCHWriteEmitter(Records).run(Out);
|
||||
ClangAttrPCHWriteEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangDiagsDefs:
|
||||
ClangDiagsDefsEmitter(Records, ClangComponent).run(Out);
|
||||
ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os());
|
||||
break;
|
||||
case GenClangDiagGroups:
|
||||
ClangDiagGroupsEmitter(Records).run(Out);
|
||||
ClangDiagGroupsEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangDeclNodes:
|
||||
ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out);
|
||||
ClangDeclContextEmitter(Records).run(Out);
|
||||
ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os());
|
||||
ClangDeclContextEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenClangStmtNodes:
|
||||
ClangASTNodesEmitter(Records, "Stmt", "").run(Out);
|
||||
ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os());
|
||||
break;
|
||||
case GenDisassembler:
|
||||
DisassemblerEmitter(Records).run(Out);
|
||||
DisassemblerEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenOptParserDefs:
|
||||
OptParserEmitter(Records, true).run(Out);
|
||||
OptParserEmitter(Records, true).run(Out.os());
|
||||
break;
|
||||
case GenOptParserImpl:
|
||||
OptParserEmitter(Records, false).run(Out);
|
||||
OptParserEmitter(Records, false).run(Out.os());
|
||||
break;
|
||||
case GenDAGISel:
|
||||
DAGISelEmitter(Records).run(Out);
|
||||
DAGISelEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenFastISel:
|
||||
FastISelEmitter(Records).run(Out);
|
||||
FastISelEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenSubtarget:
|
||||
SubtargetEmitter(Records).run(Out);
|
||||
SubtargetEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenIntrinsic:
|
||||
IntrinsicEmitter(Records).run(Out);
|
||||
IntrinsicEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenTgtIntrinsic:
|
||||
IntrinsicEmitter(Records, true).run(Out);
|
||||
IntrinsicEmitter(Records, true).run(Out.os());
|
||||
break;
|
||||
case GenLLVMCConf:
|
||||
LLVMCConfigurationEmitter(Records).run(Out);
|
||||
LLVMCConfigurationEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenEDInfo:
|
||||
EDEmitter(Records).run(Out);
|
||||
EDEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenArmNeon:
|
||||
NeonEmitter(Records).run(Out);
|
||||
NeonEmitter(Records).run(Out.os());
|
||||
break;
|
||||
case GenArmNeonSema:
|
||||
NeonEmitter(Records).runHeader(Out);
|
||||
NeonEmitter(Records).runHeader(Out.os());
|
||||
break;
|
||||
case PrintEnums:
|
||||
{
|
||||
std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
|
||||
for (unsigned i = 0, e = Recs.size(); i != e; ++i)
|
||||
Out << Recs[i]->getName() << ", ";
|
||||
Out << "\n";
|
||||
Out.os() << Recs[i]->getName() << ", ";
|
||||
Out.os() << "\n";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue