]> granicus.if.org Git - clang/commitdiff
Add CompilerInstance utility functions for creating output files.
authorDaniel Dunbar <daniel@zuster.org>
Fri, 13 Nov 2009 18:32:08 +0000 (18:32 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 13 Nov 2009 18:32:08 +0000 (18:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88667 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/CompilerInstance.h
lib/Frontend/CompilerInstance.cpp
tools/clang-cc/clang-cc.cpp

index 0623b2de1a8debe23710db52ea5449da6e8cef79..b7b3e8c9981f2121e59eac2ec4df6e6de4b7cc2b 100644 (file)
@@ -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);
+
   /// }
 };
 
index a7c6d5b48894b4e579d98fd7ffa7ddec000d34b2..af3733d892b1d22a4f52077ba1cf607755f312ba 100644 (file)
@@ -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;
+}
index ff6ac83582175be9cc1404311d26205da864cfdc..16af1cb203dea04a4a712bf1319c610ae939a307 100644 (file)
@@ -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.