diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-11-13 18:32:08 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-11-13 18:32:08 +0000 |
commit | f482d59386dbc70716f7a5f65adb37ff86b501e6 (patch) | |
tree | c4b9754f2d3f893b61e263634d5b53785d38626b | |
parent | a0fdd916bbaede20b4ef257af0f61487cb6ed85a (diff) |
Add CompilerInstance utility functions for creating output files.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88667 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Frontend/CompilerInstance.h | 34 | ||||
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 62 | ||||
-rw-r--r-- | tools/clang-cc/clang-cc.cpp | 64 |
3 files changed, 112 insertions, 48 deletions
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 0623b2de1a..b7b3e8c998 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -20,6 +20,7 @@ namespace llvm { class LLVMContext; class raw_ostream; +class raw_fd_ostream; } namespace clang { @@ -432,6 +433,39 @@ public: bool UseDebugPrinter, bool ShowMacros, llvm::raw_ostream &OS); + /// Create the default output file (from the invocation's options) and add it + /// to the list of tracked output files. + llvm::raw_fd_ostream * + createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "", + llvm::StringRef Extension = ""); + + /// Create a new output file and add it to the list of tracked output files, + /// optionally deriving the output path name. + llvm::raw_fd_ostream * + createOutputFile(llvm::StringRef OutputPath, bool Binary = true, + llvm::StringRef BaseInput = "", + llvm::StringRef Extension = ""); + + /// Create a new output file, optionally deriving the output path name. + /// + /// If \arg OutputPath is empty, then createOutputFile will derive an output + /// path location as \arg BaseInput, with any suffix removed, and \arg + /// Extension appended. + /// + /// \param OutputPath - If given, the path to the output file. + /// \param Error [out] - On failure, the error message. + /// \param BaseInput - If \arg OutputPath is empty, the input path name to use + /// for deriving the output path. + /// \param Extension - The extension to use for derived output names. + /// \param Binary - The mode to open the file in. + /// \param ResultPathName [out] - If given, the result path name will be + /// stored here on success. + static llvm::raw_fd_ostream * + createOutputFile(llvm::StringRef OutputPath, std::string &Error, + bool Binary = true, llvm::StringRef BaseInput = "", + llvm::StringRef Extension = "", + std::string *ResultPathName = 0); + /// } }; diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index a7c6d5b488..af3733d892 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -263,3 +263,65 @@ void CompilerInstance::ClearOutputFiles(bool EraseFiles) { OutputFiles.clear(); } +llvm::raw_fd_ostream * +CompilerInstance::createDefaultOutputFile(bool Binary, + llvm::StringRef InFile, + llvm::StringRef Extension) { + return createOutputFile(getFrontendOpts().OutputFile, Binary, + InFile, Extension); +} + +llvm::raw_fd_ostream * +CompilerInstance::createOutputFile(llvm::StringRef OutputPath, + bool Binary, + llvm::StringRef InFile, + llvm::StringRef Extension) { + std::string Error, OutputPathName; + llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary, + InFile, Extension, + &OutputPathName); + if (!OS) { + // FIXME: Don't fail this way. + llvm::errs() << "ERROR: " << Error << "\n"; + ::exit(1); + } + + // Add the output file -- but don't try to remove "-", since this means we are + // using stdin. + addOutputFile((OutputPathName != "-") ? OutputPathName : "", OS); + + return OS; +} + +llvm::raw_fd_ostream * +CompilerInstance::createOutputFile(llvm::StringRef OutputPath, + std::string &Error, + bool Binary, + llvm::StringRef InFile, + llvm::StringRef Extension, + std::string *ResultPathName) { + std::string OutFile; + if (!OutputPath.empty()) { + OutFile = OutputPath; + } else if (InFile == "-") { + OutFile = "-"; + } else if (!Extension.empty()) { + llvm::sys::Path Path(InFile); + Path.eraseSuffix(); + Path.appendSuffix(Extension); + OutFile = Path.str(); + } else { + OutFile = "-"; + } + + llvm::raw_fd_ostream *OS = + new llvm::raw_fd_ostream(OutFile.c_str(), Error, + (Binary ? llvm::raw_fd_ostream::F_Binary : 0)); + if (!OS) + return 0; + + if (ResultPathName) + *ResultPathName = OutFile; + + return OS; +} diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index ff6ac83582..16af1cb203 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -232,41 +232,6 @@ static void ParseFile(Preprocessor &PP, MinimalAction *PA) { /// anything. llvm::Timer *ClangFrontendTimer = 0; -static llvm::raw_fd_ostream *ComputeOutFile(CompilerInstance &CI, - const std::string &InFile, - const char *Extension, - bool Binary) { - std::string OutFile; - if (!CI.getFrontendOpts().OutputFile.empty()) - OutFile = CI.getFrontendOpts().OutputFile; - else if (InFile == "-") { - OutFile = "-"; - } else if (Extension) { - llvm::sys::Path Path(InFile); - Path.eraseSuffix(); - Path.appendSuffix(Extension); - OutFile = Path.str(); - } else { - OutFile = "-"; - } - - std::string Error; - llvm::raw_fd_ostream *OS = - new llvm::raw_fd_ostream(OutFile.c_str(), Error, - (Binary ? llvm::raw_fd_ostream::F_Binary : 0)); - if (!Error.empty()) { - // FIXME: Don't fail this way. - llvm::errs() << "ERROR: " << Error << "\n"; - ::exit(1); - } - - // Track that this is an output file, so that we remember to close it and so - // we can remove it on errors. - CI.addOutputFile((InFile == "-") ? "" : OutFile, OS); - - return OS; -} - /// AddFixItLocations - Add any individual user specified "fix-it" locations, /// and return true on success (if any were added). static bool AddFixItLocations(FixItRewriter *FixItRewrite, @@ -302,10 +267,11 @@ static ASTConsumer *CreateConsumerAction(CompilerInstance &CI, return 0; case ASTPrint: - return CreateASTPrinter(ComputeOutFile(CI, InFile, 0, false)); + return CreateASTPrinter(CI.createDefaultOutputFile(false, InFile)); case ASTPrintXML: - return CreateASTPrinterXML(ComputeOutFile(CI, InFile, "xml", false)); + return CreateASTPrinterXML(CI.createDefaultOutputFile(false, InFile, + "xml")); case ASTDump: return CreateASTDumper(); @@ -327,15 +293,15 @@ static ASTConsumer *CreateConsumerAction(CompilerInstance &CI, llvm::OwningPtr<llvm::raw_ostream> OS; if (ProgAction == EmitAssembly) { Act = Backend_EmitAssembly; - OS.reset(ComputeOutFile(CI, InFile, "s", true)); + OS.reset(CI.createDefaultOutputFile(false, InFile, "s")); } else if (ProgAction == EmitLLVM) { Act = Backend_EmitLL; - OS.reset(ComputeOutFile(CI, InFile, "ll", true)); + OS.reset(CI.createDefaultOutputFile(false, InFile, "ll")); } else if (ProgAction == EmitLLVMOnly) { Act = Backend_EmitNothing; } else { Act = Backend_EmitBC; - OS.reset(ComputeOutFile(CI, InFile, "bc", true)); + OS.reset(CI.createDefaultOutputFile(true, InFile, "bc")); } // Fix-its can change semantics, disallow with any IRgen action. @@ -350,7 +316,8 @@ static ASTConsumer *CreateConsumerAction(CompilerInstance &CI, } case RewriteObjC: - return CreateObjCRewriter(InFile, ComputeOutFile(CI, InFile, "cpp", true), + return CreateObjCRewriter(InFile, + CI.createDefaultOutputFile(true, InFile, "cpp"), PP.getDiagnostics(), PP.getLangOptions(), CI.getDiagnosticOpts().NoRewriteMacros); @@ -385,7 +352,8 @@ static void ProcessInputFile(CompilerInstance &CI, const std::string &InFile, break; case EmitHTML: - Consumer.reset(CreateHTMLPrinter(ComputeOutFile(CI, InFile, 0, true), PP)); + Consumer.reset(CreateHTMLPrinter(CI.createDefaultOutputFile(false, InFile), + PP)); break; case RunAnalysis: @@ -401,7 +369,7 @@ static void ProcessInputFile(CompilerInstance &CI, const std::string &InFile, Relocatable = false; } - llvm::raw_ostream *OS = ComputeOutFile(CI, InFile, 0, true); + llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile); if (Relocatable) Consumer.reset(CreatePCHGenerator(PP, OS, Sysroot.c_str())); else @@ -514,7 +482,7 @@ static void ProcessInputFile(CompilerInstance &CI, const std::string &InFile, llvm::errs() << "ERROR: PTH requires an seekable file for output!\n"; ::exit(1); } - CacheTokens(PP, ComputeOutFile(CI, InFile, 0, true)); + CacheTokens(PP, CI.createDefaultOutputFile(true, InFile)); break; case ParseNoop: @@ -522,21 +490,21 @@ static void ProcessInputFile(CompilerInstance &CI, const std::string &InFile, break; case ParsePrintCallbacks: { - llvm::raw_ostream *OS = ComputeOutFile(CI, InFile, 0, true); + llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile); ParseFile(PP, CreatePrintParserActionsAction(PP, OS)); break; } case PrintPreprocessedInput: - DoPrintPreprocessedInput(PP, ComputeOutFile(CI, InFile, 0, true), + DoPrintPreprocessedInput(PP, CI.createDefaultOutputFile(false, InFile), CI.getPreprocessorOutputOpts()); break; case RewriteMacros: - RewriteMacrosInInput(PP, ComputeOutFile(CI, InFile, 0, true)); + RewriteMacrosInInput(PP, CI.createDefaultOutputFile(true, InFile)); break; case RewriteTest: - DoRewriteTest(PP, ComputeOutFile(CI, InFile, 0, true)); + DoRewriteTest(PP, CI.createDefaultOutputFile(false, InFile)); break; case RunPreprocessorOnly: { // Just lex as fast as we can, no output. |