aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-11-13 18:32:08 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-11-13 18:32:08 +0000
commitf482d59386dbc70716f7a5f65adb37ff86b501e6 (patch)
treec4b9754f2d3f893b61e263634d5b53785d38626b
parenta0fdd916bbaede20b4ef257af0f61487cb6ed85a (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.h34
-rw-r--r--lib/Frontend/CompilerInstance.cpp62
-rw-r--r--tools/clang-cc/clang-cc.cpp64
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.