Get rid of static constructors for pass registration. Instead, every pass exposes...
[oota-llvm.git] / tools / llvm-ld / llvm-ld.cpp
index 9956e23ddd8169cf2e3649d583a5b79a9c83ba4b..d461fef8fec9c5697eb4599195954d960eb52826 100644 (file)
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ToolOutputFile.h"
 #include "llvm/System/Signals.h"
 #include "llvm/Config/config.h"
 #include <memory>
@@ -124,6 +125,10 @@ static cl::opt<std::string> CO9("m", cl::Hidden,
 /// everywhere.
 static std::string progname;
 
+/// FileRemover objects to clean up output files in the event of an error.
+static FileRemover OutputRemover;
+static FileRemover BitcodeOutputRemover;
+
 /// PrintAndExit - Prints a message to standard error and exits with error code
 ///
 /// Inputs:
@@ -140,8 +145,8 @@ static void PrintCommand(const std::vector<const char*> &args) {
   std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); 
   for (; I != E; ++I)
     if (*I)
-      outs() << "'" << *I << "'" << " ";
-  outs() << "\n"; outs().flush();
+      errs() << "'" << *I << "'" << " ";
+  errs() << "\n";
 }
 
 /// CopyEnv - This function takes an array of environment variables and makes a
@@ -227,21 +232,20 @@ static void RemoveEnv(const char * name, char ** const envp) {
 void GenerateBitcode(Module* M, const std::string& FileName) {
 
   if (Verbose)
-    outs() << "Generating Bitcode To " << FileName << '\n';
+    errs() << "Generating Bitcode To " << FileName << '\n';
 
   // Create the output file.
   std::string ErrorInfo;
-  raw_fd_ostream Out(FileName.c_str(), ErrorInfo,
-                     raw_fd_ostream::F_Binary);
-  if (!ErrorInfo.empty())
+  tool_output_file Out(FileName.c_str(), ErrorInfo,
+                       raw_fd_ostream::F_Binary);
+  if (!ErrorInfo.empty()) {
     PrintAndExit(ErrorInfo, M);
-
-  // Ensure that the bitcode file gets removed from the disk if we get a
-  // terminating signal.
-  sys::RemoveFileOnSignal(sys::Path(FileName));
+    return;
+  }
 
   // Write it out
-  WriteBitcodeToFile(M, Out);
+  WriteBitcodeToFile(M, Out.os());
+  Out.keep();
 }
 
 /// GenerateAssembly - generates a native assembly language source file from the
@@ -265,14 +269,13 @@ static int GenerateAssembly(const std::string &OutputFilename,
   // We will use GCC to assemble the program so set the assembly syntax to AT&T,
   // regardless of what the target in the bitcode file is.
   args.push_back("-x86-asm-syntax=att");
-  args.push_back("-f");
   args.push_back("-o");
   args.push_back(OutputFilename.c_str());
   args.push_back(InputFilename.c_str());
   args.push_back(0);
 
   if (Verbose) {
-    outs() << "Generating Assembly With: \n";
+    errs() << "Generating Assembly With: \n";
     PrintCommand(args);
   }
 
@@ -288,14 +291,13 @@ static int GenerateCFile(const std::string &OutputFile,
   std::vector<const char*> args;
   args.push_back(llc.c_str());
   args.push_back("-march=c");
-  args.push_back("-f");
   args.push_back("-o");
   args.push_back(OutputFile.c_str());
   args.push_back(InputFile.c_str());
   args.push_back(0);
 
   if (Verbose) {
-    outs() << "Generating C Source With: \n";
+    errs() << "Generating C Source With: \n";
     PrintCommand(args);
   }
 
@@ -392,13 +394,13 @@ static int GenerateNative(const std::string &OutputFilename,
   Args.push_back(0);
 
   if (Verbose) {
-    outs() << "Generating Native Executable With:\n";
+    errs() << "Generating Native Executable With:\n";
     PrintCommand(Args);
   }
 
   // Run the compiler to assembly and link together the program.
   int R = sys::Program::ExecuteAndWait(
-    gcc, &Args[0], (const char**)clean_env, 0, 0, 0, &ErrMsg);
+    gcc, &Args[0], const_cast<const char **>(clean_env), 0, 0, 0, &ErrMsg);
   delete [] clean_env;
   return R;
 }
@@ -407,7 +409,7 @@ static int GenerateNative(const std::string &OutputFilename,
 /// bitcode file for the program.
 static void EmitShellScript(char **argv, Module *M) {
   if (Verbose)
-    outs() << "Emitting Shell Script\n";
+    errs() << "Emitting Shell Script\n";
 #if defined(_WIN32) || defined(__CYGWIN__)
   // Windows doesn't support #!/bin/sh style shell scripts in .exe files.  To
   // support windows systems, we copy the llvm-stub.exe executable from the
@@ -426,14 +428,14 @@ static void EmitShellScript(char **argv, Module *M) {
 
   // Output the script to start the program...
   std::string ErrorInfo;
-  raw_fd_ostream Out2(OutputFilename.c_str(), ErrorInfo);
+  tool_output_file Out2(OutputFilename.c_str(), ErrorInfo);
   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");
@@ -464,9 +466,10 @@ 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();
 }
 
 // BuildLinkItems -- This function generates a LinkItemList for the LinkItems
@@ -511,12 +514,56 @@ int main(int argc, char **argv, char **envp) {
   LLVMContext &Context = getGlobalContext();
   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
   
+  // Initialize passes
+  PassRegistry &Registry = *PassRegistry::getPassRegistry();
+  initializeCore(Registry);
+  initializeScalarOpts(Registry);
+  initializeIPO(Registry);
+  initializeAnalysis(Registry);
+  initializeIPA(Registry);
+  initializeTransformUtils(Registry);
+  initializeInstCombine(Registry);
+  initializeTarget(Registry);
+  
   // Initial global variable above for convenience printing of program name.
   progname = sys::Path(argv[0]).getBasename();
 
   // Parse the command line options
   cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
 
+#if defined(_WIN32) || defined(__CYGWIN__)
+  if (!LinkAsLibrary) {
+    // Default to "a.exe" instead of "a.out".
+    if (OutputFilename.getNumOccurrences() == 0)
+      OutputFilename = "a.exe";
+
+    // If there is no suffix add an "exe" one.
+    sys::Path ExeFile( OutputFilename );
+    if (ExeFile.getSuffix() == "") {
+      ExeFile.appendSuffix("exe");
+      OutputFilename = ExeFile.str();
+    }
+  }
+#endif
+
+  // Generate the bitcode for the optimized module.
+  // If -b wasn't specified, use the name specified
+  // with -o to construct BitcodeOutputFilename.
+  if (BitcodeOutputFilename.empty()) {
+    BitcodeOutputFilename = OutputFilename;
+    if (!LinkAsLibrary) BitcodeOutputFilename += ".bc";
+  }
+
+  // Arrange for the bitcode output file to be deleted on any errors.
+  BitcodeOutputRemover.setFile(sys::Path(BitcodeOutputFilename));
+  sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename));
+
+  // Arrange for the output file to be deleted on any errors.
+  if (!LinkAsLibrary) {
+    OutputRemover.setFile(sys::Path(OutputFilename));
+    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+  }
+
   // Construct a Linker (now that Verbose is set)
   Linker TheLinker(progname, OutputFilename, Context, Verbose);
 
@@ -559,29 +606,7 @@ int main(int argc, char **argv, char **envp) {
   // Optimize the module
   Optimize(Composite.get());
 
-#if defined(_WIN32) || defined(__CYGWIN__)
-  if (!LinkAsLibrary) {
-    // Default to "a.exe" instead of "a.out".
-    if (OutputFilename.getNumOccurrences() == 0)
-      OutputFilename = "a.exe";
-
-    // If there is no suffix add an "exe" one.
-    sys::Path ExeFile( OutputFilename );
-    if (ExeFile.getSuffix() == "") {
-      ExeFile.appendSuffix("exe");
-      OutputFilename = ExeFile.str();
-    }
-  }
-#endif
-
-  // Generate the bitcode for the optimized module.
-  // If -b wasn't specified, use the name specified
-  // with -o to construct BitcodeOutputFilename.
-  if (BitcodeOutputFilename.empty()) {
-    BitcodeOutputFilename = OutputFilename;
-    if (!LinkAsLibrary) BitcodeOutputFilename += ".bc";
-  }
-
+  // Generate the bitcode output.
   GenerateBitcode(Composite.get(), BitcodeOutputFilename);
 
   // If we are not linking a library, generate either a native executable
@@ -634,9 +659,9 @@ int main(int argc, char **argv, char **envp) {
       sys::Path AssemblyFile ( OutputFilename);
       AssemblyFile.appendSuffix("s");
 
-      // Mark the output files for removal if we get an interrupt.
+      // Mark the output files for removal.
+      FileRemover AssemblyFileRemover(AssemblyFile);
       sys::RemoveFileOnSignal(AssemblyFile);
-      sys::RemoveFileOnSignal(sys::Path(OutputFilename));
 
       // Determine the locations of the llc and gcc programs.
       sys::Path llc = FindExecutable("llc", argv[0],
@@ -657,16 +682,13 @@ int main(int argc, char **argv, char **envp) {
       if (0 != GenerateNative(OutputFilename, AssemblyFile.str(),
                               NativeLinkItems, gcc, envp, ErrMsg))
         PrintAndExit(ErrMsg, Composite.get());
-
-      // Remove the assembly language file.
-      AssemblyFile.eraseFromDisk();
     } else if (NativeCBE) {
       sys::Path CFile (OutputFilename);
       CFile.appendSuffix("cbe.c");
 
-      // Mark the output files for removal if we get an interrupt.
+      // Mark the output files for removal.
+      FileRemover CFileRemover(CFile);
       sys::RemoveFileOnSignal(CFile);
-      sys::RemoveFileOnSignal(sys::Path(OutputFilename));
 
       // Determine the locations of the llc and gcc programs.
       sys::Path llc = FindExecutable("llc", argv[0],
@@ -686,10 +708,6 @@ int main(int argc, char **argv, char **envp) {
       if (GenerateNative(OutputFilename, CFile.str(), 
                          NativeLinkItems, gcc, envp, ErrMsg))
         PrintAndExit(ErrMsg, Composite.get());
-
-      // Remove the assembly language file.
-      CFile.eraseFromDisk();
-
     } else {
       EmitShellScript(argv, Composite.get());
     }
@@ -707,6 +725,11 @@ int main(int argc, char **argv, char **envp) {
       PrintAndExit(ErrMsg, Composite.get());
   }
 
+  // Operations which may fail are now complete.
+  BitcodeOutputRemover.releaseFile();
+  if (!LinkAsLibrary)
+    OutputRemover.releaseFile();
+
   // Graceful exit
   return 0;
 }