diff --git a/llvm/tools/llvmc/CompilerDriver.cpp b/llvm/tools/llvmc/CompilerDriver.cpp
index 4784bde..b890220 100644
--- a/llvm/tools/llvmc/CompilerDriver.cpp
+++ b/llvm/tools/llvmc/CompilerDriver.cpp
@@ -26,812 +26,823 @@
 
 namespace {
 
-  void WriteAction(CompilerDriver::Action* action ) {
-    std::cerr << action->program.c_str();
-    std::vector<std::string>::iterator I = action->args.begin();
-    while (I != action->args.end()) {
-      std::cerr << " " + *I;
+void WriteAction(CompilerDriver::Action* action ) {
+  std::cerr << action->program.c_str();
+  std::vector<std::string>::iterator I = action->args.begin();
+  while (I != action->args.end()) {
+    std::cerr << " " + *I;
+    ++I;
+  }
+  std::cerr << "\n";
+}
+
+void DumpAction(CompilerDriver::Action* action) {
+  std::cerr << "command = " << action->program.c_str();
+  std::vector<std::string>::iterator I = action->args.begin();
+  while (I != action->args.end()) {
+    std::cerr << " " + *I;
+    ++I;
+  }
+  std::cerr << "\n";
+  std::cerr << "flags = " << action->flags << "\n";
+}
+
+void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
+  std::cerr << "Configuration Data For '" << cd->langName << "' (" << type 
+    << ")\n";
+  std::cerr << "PreProcessor: ";
+  DumpAction(&cd->PreProcessor);
+  std::cerr << "Translator: ";
+  DumpAction(&cd->Translator);
+  std::cerr << "Optimizer: ";
+  DumpAction(&cd->Optimizer);
+  std::cerr << "Assembler: ";
+  DumpAction(&cd->Assembler);
+  std::cerr << "Linker: ";
+  DumpAction(&cd->Linker);
+}
+
+/// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
+/// which should reduce the volume of code and make compilation
+/// faster. This is also safe on any llvm module. 
+static const char* DefaultFastCompileOptimizations[] = {
+  "-simplifycfg", "-mem2reg", "-instcombine"
+};
+
+class CompilerDriverImpl : public CompilerDriver {
+/// @name Constructors
+/// @{
+public:
+  CompilerDriverImpl(ConfigDataProvider& confDatProv )
+    : cdp(&confDatProv)
+    , finalPhase(LINKING)
+    , optLevel(OPT_FAST_COMPILE) 
+    , Flags(0)
+    , machine()
+    , LibraryPaths()
+    , TempDir()
+    , AdditionalArgs()
+  {
+    TempDir = sys::Path::GetTemporaryDirectory();
+    sys::RemoveDirectoryOnSignal(TempDir);
+    AdditionalArgs.reserve(NUM_PHASES);
+    StringVector emptyVec;
+    for (unsigned i = 0; i < NUM_PHASES; ++i)
+      AdditionalArgs.push_back(emptyVec);
+  }
+
+  virtual ~CompilerDriverImpl() {
+    cleanup();
+    cdp = 0;
+    LibraryPaths.clear();
+    IncludePaths.clear();
+    Defines.clear();
+    TempDir.clear();
+    AdditionalArgs.clear();
+    fOptions.clear();
+    MOptions.clear();
+    WOptions.clear();
+  }
+
+/// @}
+/// @name Methods
+/// @{
+public:
+  virtual void setFinalPhase( Phases phase ) { 
+    finalPhase = phase; 
+  }
+
+  virtual void setOptimization( OptimizationLevels level ) { 
+    optLevel = level; 
+  }
+
+  virtual void setDriverFlags( unsigned flags ) {
+    Flags = flags & DRIVER_FLAGS_MASK; 
+  }
+
+  virtual void setOutputMachine( const std::string& machineName ) {
+    machine = machineName;
+  }
+
+  virtual void setPhaseArgs(Phases phase, const StringVector& opts) {
+    assert(phase <= LINKING && phase >= PREPROCESSING);
+    AdditionalArgs[phase] = opts;
+  }
+
+  virtual void setIncludePaths(const StringVector& paths) {
+    StringVector::const_iterator I = paths.begin();
+    StringVector::const_iterator E = paths.end();
+    while (I != E) {
+      sys::Path tmp;
+      tmp.set_directory(*I);
+      IncludePaths.push_back(tmp);
       ++I;
     }
-    std::cerr << "\n";
   }
 
-  void DumpAction(CompilerDriver::Action* action) {
-    std::cerr << "command = " << action->program.c_str();
-    std::vector<std::string>::iterator I = action->args.begin();
-    while (I != action->args.end()) {
-      std::cerr << " " + *I;
+  virtual void setSymbolDefines(const StringVector& defs) {
+    Defines = defs;
+  }
+
+  virtual void setLibraryPaths(const StringVector& paths) {
+    StringVector::const_iterator I = paths.begin();
+    StringVector::const_iterator E = paths.end();
+    while (I != E) {
+      sys::Path tmp;
+      tmp.set_directory(*I);
+      LibraryPaths.push_back(tmp);
       ++I;
     }
-    std::cerr << "\n";
-    std::cerr << "flags = " << action->flags << "\n";
   }
 
-  void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
-    std::cerr << "Configuration Data For '" << cd->langName << "' (" << type 
-      << ")\n";
-    std::cerr << "PreProcessor: ";
-    DumpAction(&cd->PreProcessor);
-    std::cerr << "Translator: ";
-    DumpAction(&cd->Translator);
-    std::cerr << "Optimizer: ";
-    DumpAction(&cd->Optimizer);
-    std::cerr << "Assembler: ";
-    DumpAction(&cd->Assembler);
-    std::cerr << "Linker: ";
-    DumpAction(&cd->Linker);
+  virtual void addLibraryPath( const sys::Path& libPath ) {
+    LibraryPaths.push_back(libPath);
   }
 
-  /// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
-  /// which should reduce the volume of code and make compilation
-  /// faster. This is also safe on any llvm module. 
-  static const char* DefaultFastCompileOptimizations[] = {
-    "-simplifycfg", "-mem2reg", "-instcombine"
-  };
+  virtual void setfPassThrough(const StringVector& fOpts) {
+    fOptions = fOpts;
+  }
 
-  class CompilerDriverImpl : public CompilerDriver {
-    /// @name Constructors
-    /// @{
-    public:
-      CompilerDriverImpl(ConfigDataProvider& confDatProv )
-        : cdp(&confDatProv)
-        , finalPhase(LINKING)
-        , optLevel(OPT_FAST_COMPILE) 
-        , Flags(0)
-        , machine()
-        , LibraryPaths()
-        , TempDir()
-        , AdditionalArgs()
-      {
-        TempDir = sys::Path::GetTemporaryDirectory();
-        sys::RemoveDirectoryOnSignal(TempDir);
-        AdditionalArgs.reserve(NUM_PHASES);
-        StringVector emptyVec;
-        for (unsigned i = 0; i < NUM_PHASES; ++i)
-          AdditionalArgs.push_back(emptyVec);
-      }
+  /// @brief Set the list of -M options to be passed through
+  virtual void setMPassThrough(const StringVector& MOpts) {
+    MOptions = MOpts;
+  }
 
-      virtual ~CompilerDriverImpl() {
-        cleanup();
-        cdp = 0;
-        LibraryPaths.clear();
-        AdditionalArgs.clear();
-      }
+  /// @brief Set the list of -W options to be passed through
+  virtual void setWPassThrough(const StringVector& WOpts) {
+    WOptions = WOpts;
+  }
+/// @}
+/// @name Functions
+/// @{
+private:
+  bool isSet(DriverFlags flag) {
+    return 0 != ((flag & DRIVER_FLAGS_MASK) & Flags);
+  }
 
-    /// @}
-    /// @name Methods
-    /// @{
-    public:
-      virtual void setFinalPhase( Phases phase ) { 
-        finalPhase = phase; 
-      }
+  void cleanup() {
+    if (!isSet(KEEP_TEMPS_FLAG)) {
+      if (TempDir.is_directory() && TempDir.writable())
+        TempDir.destroy_directory(/*remove_contents=*/true);
+    } else {
+      std::cout << "Temporary files are in " << TempDir.get() << "\n";
+    }
+  }
 
-      virtual void setOptimization( OptimizationLevels level ) { 
-        optLevel = level; 
-      }
+  sys::Path MakeTempFile(const std::string& basename, 
+                         const std::string& suffix ) {
+    sys::Path result(TempDir);
+    if (!result.append_file(basename))
+      throw basename + ": can't use this file name";
+    if (!result.append_suffix(suffix))
+      throw suffix + ": can't use this file suffix";
+    return result;
+  }
 
-      virtual void setDriverFlags( unsigned flags ) {
-        Flags = flags & DRIVER_FLAGS_MASK; 
-      }
+  Action* GetAction(ConfigData* cd, 
+                    const sys::Path& input, 
+                    const sys::Path& output,
+                    Phases phase)
+  {
+    Action* pat = 0; ///< The pattern/template for the action
+    Action* action = new Action; ///< The actual action to execute
 
-      virtual void setOutputMachine( const std::string& machineName ) {
-        machine = machineName;
-      }
+    // Get the action pattern
+    switch (phase) {
+      case PREPROCESSING: pat = &cd->PreProcessor; break;
+      case TRANSLATION:   pat = &cd->Translator; break;
+      case OPTIMIZATION:  pat = &cd->Optimizer; break;
+      case ASSEMBLY:      pat = &cd->Assembler; break;
+      case LINKING:       pat = &cd->Linker; break;
+      default:
+        assert(!"Invalid driver phase!");
+        break;
+    }
+    assert(pat != 0 && "Invalid command pattern");
 
-      virtual void setPhaseArgs(Phases phase, const StringVector& opts) {
-        assert(phase <= LINKING && phase >= PREPROCESSING);
-        AdditionalArgs[phase] = opts;
-      }
+    // Copy over some pattern things that don't need to change
+    action->program = pat->program;
+    action->flags = pat->flags;
 
-      virtual void setIncludePaths(const StringVector& paths) {
-        StringVector::const_iterator I = paths.begin();
-        StringVector::const_iterator E = paths.end();
-        while (I != E) {
-          sys::Path tmp;
-          tmp.set_directory(*I);
-          IncludePaths.push_back(tmp);
-          ++I;
-        }
-      }
-
-      virtual void setSymbolDefines(const StringVector& defs) {
-        Defines = defs;
-      }
-
-      virtual void setLibraryPaths(const StringVector& paths) {
-        StringVector::const_iterator I = paths.begin();
-        StringVector::const_iterator E = paths.end();
-        while (I != E) {
-          sys::Path tmp;
-          tmp.set_directory(*I);
-          LibraryPaths.push_back(tmp);
-          ++I;
-        }
-      }
-
-      virtual void addLibraryPath( const sys::Path& libPath ) {
-        LibraryPaths.push_back(libPath);
-      }
-
-      virtual void setfPassThrough(const StringVector& fOpts) {
-        fOptions = fOpts;
-      }
-
-      /// @brief Set the list of -M options to be passed through
-      virtual void setMPassThrough(const StringVector& MOpts) {
-        MOptions = MOpts;
-      }
-
-      /// @brief Set the list of -W options to be passed through
-      virtual void setWPassThrough(const StringVector& WOpts) {
-        WOptions = WOpts;
-      }
-    /// @}
-    /// @name Functions
-    /// @{
-    private:
-      bool isSet(DriverFlags flag) {
-        return 0 != ((flag & DRIVER_FLAGS_MASK) & Flags);
-      }
-
-      void cleanup() {
-        if (!isSet(KEEP_TEMPS_FLAG)) {
-          if (TempDir.is_directory() && TempDir.writable())
-            TempDir.destroy_directory(/*remove_contents=*/true);
-        } else {
-          std::cout << "Temporary files are in " << TempDir.get() << "\n";
-        }
-      }
-
-      sys::Path MakeTempFile(const std::string& basename, const std::string& suffix ) {
-        sys::Path result(TempDir);
-        if (!result.append_file(basename))
-          throw basename + ": can't use this file name";
-        if (!result.append_suffix(suffix))
-          throw suffix + ": can't use this file suffix";
-        return result;
-      }
-
-      Action* GetAction(ConfigData* cd, 
-                        const sys::Path& input, 
-                        const sys::Path& output,
-                        Phases phase)
-      {
-        Action* pat = 0; ///< The pattern/template for the action
-        Action* action = new Action; ///< The actual action to execute
-
-        // Get the action pattern
-        switch (phase) {
-          case PREPROCESSING: pat = &cd->PreProcessor; break;
-          case TRANSLATION:   pat = &cd->Translator; break;
-          case OPTIMIZATION:  pat = &cd->Optimizer; break;
-          case ASSEMBLY:      pat = &cd->Assembler; break;
-          case LINKING:       pat = &cd->Linker; break;
+    // Do the substitutions from the pattern to the actual
+    StringVector::iterator PI = pat->args.begin();
+    StringVector::iterator PE = pat->args.end();
+    while (PI != PE) {
+      if ((*PI)[0] == '%' && PI->length() >2) {
+        bool found = true;
+        switch ((*PI)[1]) {
+          case 'a':
+            if (*PI == "%args%") {
+              if (AdditionalArgs.size() > unsigned(phase))
+                if (!AdditionalArgs[phase].empty()) {
+                  // Get specific options for each kind of action type
+                  StringVector& addargs = AdditionalArgs[phase];
+                  // Add specific options for each kind of action type
+                  action->args.insert(action->args.end(), addargs.begin(), 
+                                      addargs.end());
+                }
+            } else
+              found = false;
+            break;
+          case 'd':
+            if (*PI == "%defs%") {
+              StringVector::iterator I = Defines.begin();
+              StringVector::iterator E = Defines.end();
+              while (I != E) {
+                action->args.push_back( std::string("-D") + *I);
+                ++I;
+              }
+            } else
+              found = false;
+            break;
+          case 'f':
+            if (*PI == "%fOpts%") {
+              action->args.insert(action->args.end(), fOptions.begin(), 
+                                  fOptions.end());
+            } else
+              found = false;
+            break;
+          case 'i':
+            if (*PI == "%in%") {
+              action->args.push_back(input.get());
+            } else if (*PI == "%incls%") {
+              PathVector::iterator I = IncludePaths.begin();
+              PathVector::iterator E = IncludePaths.end();
+              while (I != E) {
+                action->args.push_back( std::string("-I") + I->get() );
+                ++I;
+              }
+            } else
+              found = false;
+            break;
+          case 'l':
+            if (*PI == "%libs%") {
+              PathVector::iterator I = LibraryPaths.begin();
+              PathVector::iterator E = LibraryPaths.end();
+              while (I != E) {
+                action->args.push_back( std::string("-L") + I->get() );
+                ++I;
+              }
+            } else
+              found = false;
+            break;
+          case 'o':
+            if (*PI == "%out%") {
+              action->args.push_back(output.get());
+            } else if (*PI == "%opt%") {
+              if (!isSet(EMIT_RAW_FLAG)) {
+                if (cd->opts.size() > static_cast<unsigned>(optLevel) && 
+                    !cd->opts[optLevel].empty())
+                  action->args.insert(action->args.end(), 
+                                      cd->opts[optLevel].begin(),
+                                      cd->opts[optLevel].end());
+                else
+                  throw std::string("Optimization options for level ") + 
+                        utostr(unsigned(optLevel)) + " were not specified";
+              }
+            } else
+              found = false;
+            break;
+          case 's':
+            if (*PI == "%stats%") {
+              if (isSet(SHOW_STATS_FLAG))
+                action->args.push_back("-stats");
+            } else
+              found = false;
+            break;
+          case 't':
+            if (*PI == "%target%") {
+              action->args.push_back(std::string("-march=") + machine);
+            } else if (*PI == "%time%") {
+              if (isSet(TIME_PASSES_FLAG))
+                action->args.push_back("-time-passes");
+            } else
+              found = false;
+            break;
+          case 'v':
+            if (*PI == "%verbose%") {
+              if (isSet(VERBOSE_FLAG))
+                action->args.push_back("-v");
+            } else
+              found  = false;
+            break;
+          case 'M':
+            if (*PI == "%Mopts") {
+              action->args.insert(action->args.end(), MOptions.begin(), 
+                                  MOptions.end());
+            } else
+              found = false;
+            break;
+          case 'W':
+            if (*PI == "%Wopts") {
+              action->args.insert(action->args.end(), WOptions.begin(), 
+                                  WOptions.end());
+            } else
+              found = false;
+            break;
           default:
-            assert(!"Invalid driver phase!");
+            found = false;
             break;
         }
-        assert(pat != 0 && "Invalid command pattern");
-
-        // Copy over some pattern things that don't need to change
-        action->program = pat->program;
-        action->flags = pat->flags;
-
-        // Do the substitutions from the pattern to the actual
-        StringVector::iterator PI = pat->args.begin();
-        StringVector::iterator PE = pat->args.end();
-        while (PI != PE) {
-          if ((*PI)[0] == '%' && PI->length() >2) {
-            bool found = true;
-            switch ((*PI)[1]) {
-              case 'a':
-                if (*PI == "%args%") {
-                  if (AdditionalArgs.size() > unsigned(phase))
-                    if (!AdditionalArgs[phase].empty()) {
-                      // Get specific options for each kind of action type
-                      StringVector& addargs = AdditionalArgs[phase];
-                      // Add specific options for each kind of action type
-                      action->args.insert(action->args.end(), addargs.begin(), addargs.end());
-                    }
-                } else
-                  found = false;
-                break;
-              case 'd':
-                if (*PI == "%defs%") {
-                  StringVector::iterator I = Defines.begin();
-                  StringVector::iterator E = Defines.end();
-                  while (I != E) {
-                    action->args.push_back( std::string("-D") + *I);
-                    ++I;
-                  }
-                } else
-                  found = false;
-                break;
-              case 'f':
-                if (*PI == "%force%") {
-                  if (isSet(FORCE_FLAG))
-                    action->args.push_back("-f");
-                } else if (*PI == "%fOpts%") {
-                    action->args.insert(action->args.end(), fOptions.begin(), 
-                                        fOptions.end());
-                } else
-                  found = false;
-                break;
-              case 'i':
-                if (*PI == "%in%") {
-                  action->args.push_back(input.get());
-                } else if (*PI == "%incls%") {
-                  PathVector::iterator I = IncludePaths.begin();
-                  PathVector::iterator E = IncludePaths.end();
-                  while (I != E) {
-                    action->args.push_back( std::string("-I") + I->get() );
-                    ++I;
-                  }
-                } else
-                  found = false;
-                break;
-              case 'l':
-                if (*PI == "%libs%") {
-                  PathVector::iterator I = LibraryPaths.begin();
-                  PathVector::iterator E = LibraryPaths.end();
-                  while (I != E) {
-                    action->args.push_back( std::string("-L") + I->get() );
-                    ++I;
-                  }
-                } else
-                  found = false;
-                break;
-              case 'o':
-                if (*PI == "%out%") {
-                  action->args.push_back(output.get());
-                } else if (*PI == "%opt%") {
-                  if (!isSet(EMIT_RAW_FLAG)) {
-                    if (cd->opts.size() > static_cast<unsigned>(optLevel) && 
-                        !cd->opts[optLevel].empty())
-                      action->args.insert(action->args.end(), cd->opts[optLevel].begin(),
-                          cd->opts[optLevel].end());
-                    else
-                      throw std::string("Optimization options for level ") + 
-                            utostr(unsigned(optLevel)) + " were not specified";
-                  }
-                } else
-                  found = false;
-                break;
-              case 's':
-                if (*PI == "%stats%") {
-                  if (isSet(SHOW_STATS_FLAG))
-                    action->args.push_back("-stats");
-                } else
-                  found = false;
-                break;
-              case 't':
-                if (*PI == "%target%") {
-                  action->args.push_back(std::string("-march=") + machine);
-                } else if (*PI == "%time%") {
-                  if (isSet(TIME_PASSES_FLAG))
-                    action->args.push_back("-time-passes");
-                } else
-                  found = false;
-                break;
-              case 'v':
-                if (*PI == "%verbose%") {
-                  if (isSet(VERBOSE_FLAG))
-                    action->args.push_back("-v");
-                } else
-                  found  = false;
-                break;
-              case 'M':
-                if (*PI == "%Mopts") {
-                  action->args.insert(action->args.end(), MOptions.begin(), 
-                                      MOptions.end());
-                } else
-                  found = false;
-                break;
-              case 'W':
-                if (*PI == "%Wopts") {
-                  action->args.insert(action->args.end(), WOptions.begin(), 
-                                      WOptions.end());
-                } else
-                  found = false;
-                break;
-              default:
-                found = false;
-                break;
-            }
-            if (!found) {
-              // Did it even look like a substitution?
-              if (PI->length()>1 && (*PI)[0] == '%' && 
-                  (*PI)[PI->length()-1] == '%') {
-                throw std::string("Invalid substitution token: '") + *PI +
-                      "' for command '" + pat->program.get() + "'";
-              } else {
-                // It's not a legal substitution, just pass it through
-                action->args.push_back(*PI);
-              }
-            }
+        if (!found) {
+          // Did it even look like a substitution?
+          if (PI->length()>1 && (*PI)[0] == '%' && 
+              (*PI)[PI->length()-1] == '%') {
+            throw std::string("Invalid substitution token: '") + *PI +
+                  "' for command '" + pat->program.get() + "'";
           } else {
-            // Its not a substitution, just put it in the action
+            // It's not a legal substitution, just pass it through
             action->args.push_back(*PI);
           }
-          PI++;
         }
-
-        // Finally, we're done
-        return action;
+      } else {
+        // Its not a substitution, just put it in the action
+        action->args.push_back(*PI);
       }
+      PI++;
+    }
 
-      bool DoAction(Action*action) {
-        assert(action != 0 && "Invalid Action!");
-        if (isSet(VERBOSE_FLAG))
-          WriteAction(action);
-        if (!isSet(DRY_RUN_FLAG)) {
-          action->program = sys::Program::FindProgramByName(action->program.get());
-          if (action->program.is_empty())
-            throw std::string("Can't find program '") + action->program.get() + "'";
+    // Finally, we're done
+    return action;
+  }
 
-          // Invoke the program
-          if (isSet(TIME_ACTIONS_FLAG)) {
-            Timer timer(action->program.get());
-            timer.startTimer();
-            int resultCode = sys::Program::ExecuteAndWait(action->program,action->args);
-            timer.stopTimer();
-            timer.print(timer,std::cerr);
-            return resultCode == 0;
-          }
-          else
-            return 0 == sys::Program::ExecuteAndWait(action->program, action->args);
-        }
-        return true;
+  bool DoAction(Action*action) {
+    assert(action != 0 && "Invalid Action!");
+    if (isSet(VERBOSE_FLAG))
+      WriteAction(action);
+    if (!isSet(DRY_RUN_FLAG)) {
+      sys::Path progpath = sys::Program::FindProgramByName(
+        action->program.get());
+      if (progpath.is_empty())
+        throw std::string("Can't find program '"+progpath.get()+"'");
+      else if (progpath.executable())
+        action->program = progpath;
+      else
+        throw std::string("Program '"+progpath.get()+"' is not executable.");
+
+      // Invoke the program
+      if (isSet(TIME_ACTIONS_FLAG)) {
+        Timer timer(action->program.get());
+        timer.startTimer();
+        int resultCode = 
+          sys::Program::ExecuteAndWait(action->program,action->args);
+        timer.stopTimer();
+        timer.print(timer,std::cerr);
+        return resultCode == 0;
       }
+      else
+        return 0 == 
+          sys::Program::ExecuteAndWait(action->program, action->args);
+    }
+    return true;
+  }
 
-      /// This method tries various variants of a linkage item's file
-      /// name to see if it can find an appropriate file to link with
-      /// in the directory specified.
-      llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
-                                            const sys::Path& dir,
-                                            bool native = false) {
-        sys::Path fullpath(dir);
-        fullpath.append_file(link_item);
-        if (native) {
-          fullpath.append_suffix("a");
-        } else {
-          fullpath.append_suffix("bc");
-          if (fullpath.readable()) 
-            return fullpath;
-          fullpath.elide_suffix();
-          fullpath.append_suffix("o");
-          if (fullpath.readable()) 
-            return fullpath;
-          fullpath = dir;
-          fullpath.append_file(std::string("lib") + link_item);
-          fullpath.append_suffix("a");
-          if (fullpath.readable())
-            return fullpath;
-          fullpath.elide_suffix();
-          fullpath.append_suffix("so");
-          if (fullpath.readable())
-            return fullpath;
-        }
-
-        // Didn't find one.
-        fullpath.clear();
+  /// This method tries various variants of a linkage item's file
+  /// name to see if it can find an appropriate file to link with
+  /// in the directory specified.
+  llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
+                                        const sys::Path& dir,
+                                        bool native = false) {
+    sys::Path fullpath(dir);
+    fullpath.append_file(link_item);
+    if (native) {
+      fullpath.append_suffix("a");
+    } else {
+      fullpath.append_suffix("bc");
+      if (fullpath.readable()) 
         return fullpath;
+      fullpath.elide_suffix();
+      fullpath.append_suffix("o");
+      if (fullpath.readable()) 
+        return fullpath;
+      fullpath = dir;
+      fullpath.append_file(std::string("lib") + link_item);
+      fullpath.append_suffix("a");
+      if (fullpath.readable())
+        return fullpath;
+      fullpath.elide_suffix();
+      fullpath.append_suffix("so");
+      if (fullpath.readable())
+        return fullpath;
+    }
+
+    // Didn't find one.
+    fullpath.clear();
+    return fullpath;
+  }
+
+  /// This method processes a linkage item. The item could be a
+  /// Bytecode file needing translation to native code and that is
+  /// dependent on other bytecode libraries, or a native code
+  /// library that should just be linked into the program.
+  bool ProcessLinkageItem(const llvm::sys::Path& link_item,
+                          SetVector<sys::Path>& set,
+                          std::string& err) {
+    // First, see if the unadorned file name is not readable. If so,
+    // we must track down the file in the lib search path.
+    sys::Path fullpath;
+    if (!link_item.readable()) {
+      // First, look for the library using the -L arguments specified
+      // on the command line.
+      PathVector::iterator PI = LibraryPaths.begin();
+      PathVector::iterator PE = LibraryPaths.end();
+      while (PI != PE && fullpath.is_empty()) {
+        fullpath = GetPathForLinkageItem(link_item.get(),*PI);
+        ++PI;
       }
 
-      /// This method processes a linkage item. The item could be a
-      /// Bytecode file needing translation to native code and that is
-      /// dependent on other bytecode libraries, or a native code
-      /// library that should just be linked into the program.
-      bool ProcessLinkageItem(const llvm::sys::Path& link_item,
-                              SetVector<sys::Path>& set,
-                              std::string& err) {
-        // First, see if the unadorned file name is not readable. If so,
-        // we must track down the file in the lib search path.
-        sys::Path fullpath;
-        if (!link_item.readable()) {
-          // First, look for the library using the -L arguments specified
-          // on the command line.
-          PathVector::iterator PI = LibraryPaths.begin();
-          PathVector::iterator PE = LibraryPaths.end();
-          while (PI != PE && fullpath.is_empty()) {
-            fullpath = GetPathForLinkageItem(link_item.get(),*PI);
-            ++PI;
-          }
+      // If we didn't find the file in any of the library search paths
+      // so we have to bail. No where else to look.
+      if (fullpath.is_empty()) {
+        err = 
+          std::string("Can't find linkage item '") + link_item.get() + "'";
+        return false;
+      }
+    } else {
+      fullpath = link_item;
+    }
 
-          // If we didn't find the file in any of the library search paths
-          // so we have to bail. No where else to look.
-          if (fullpath.is_empty()) {
-            err = std::string("Can't find linkage item '") + link_item.get() + "'";
-            return false;
-          }
-        } else {
-          fullpath = link_item;
-        }
+    // If we got here fullpath is the path to the file, and its readable.
+    set.insert(fullpath);
 
-        // If we got here fullpath is the path to the file, and its readable.
-        set.insert(fullpath);
-
-        // If its an LLVM bytecode file ...
-        if (fullpath.is_bytecode_file()) {
-          // Process the dependent libraries recursively
-          Module::LibraryListType modlibs;
-          if (GetBytecodeDependentLibraries(fullpath.get(),modlibs)) {
-            // Traverse the dependent libraries list
-            Module::lib_iterator LI = modlibs.begin();
-            Module::lib_iterator LE = modlibs.end();
-            while ( LI != LE ) {
-              if (!ProcessLinkageItem(sys::Path(*LI),set,err)) {
-                if (err.empty()) {
-                  err = std::string("Library '") + *LI + 
-                        "' is not valid for linking but is required by file '" +
-                        fullpath.get() + "'";
-                } else {
-                  err += " which is required by file '" + fullpath.get() + "'";
-                }
-                return false;
-              }
-              ++LI;
+    // If its an LLVM bytecode file ...
+    if (fullpath.is_bytecode_file()) {
+      // Process the dependent libraries recursively
+      Module::LibraryListType modlibs;
+      if (GetBytecodeDependentLibraries(fullpath.get(),modlibs)) {
+        // Traverse the dependent libraries list
+        Module::lib_iterator LI = modlibs.begin();
+        Module::lib_iterator LE = modlibs.end();
+        while ( LI != LE ) {
+          if (!ProcessLinkageItem(sys::Path(*LI),set,err)) {
+            if (err.empty()) {
+              err = std::string("Library '") + *LI + 
+                    "' is not valid for linking but is required by file '" +
+                    fullpath.get() + "'";
+            } else {
+              err += " which is required by file '" + fullpath.get() + "'";
             }
-          } else if (err.empty()) {
-            err = std::string("The dependent libraries could not be extracted from '")
-                              + fullpath.get();
             return false;
           }
+          ++LI;
         }
-        return true;
+      } else if (err.empty()) {
+        err = std::string(
+          "The dependent libraries could not be extracted from '") + 
+          fullpath.get();
+        return false;
+      }
+    }
+    return true;
+  }
+
+/// @}
+/// @name Methods
+/// @{
+public:
+  virtual int execute(const InputList& InpList, const sys::Path& Output ) {
+    try {
+      // Echo the configuration of options if we're running verbose
+      if (isSet(DEBUG_FLAG)) {
+        std::cerr << "Compiler Driver Options:\n";
+        std::cerr << "DryRun = " << isSet(DRY_RUN_FLAG) << "\n";
+        std::cerr << "Verbose = " << isSet(VERBOSE_FLAG) << " \n";
+        std::cerr << "TimeActions = " << isSet(TIME_ACTIONS_FLAG) << "\n";
+        std::cerr << "TimePasses = " << isSet(TIME_PASSES_FLAG) << "\n";
+        std::cerr << "ShowStats = " << isSet(SHOW_STATS_FLAG) << "\n";
+        std::cerr << "EmitRawCode = " << isSet(EMIT_RAW_FLAG) << "\n";
+        std::cerr << "EmitNativeCode = " << isSet(EMIT_NATIVE_FLAG) << "\n";
+        std::cerr << "KeepTemps = " << isSet(KEEP_TEMPS_FLAG) << "\n";
+        std::cerr << "OutputMachine = " << machine << "\n";
+        InputList::const_iterator I = InpList.begin();
+        while ( I != InpList.end() ) {
+          std::cerr << "Input: " << I->first.get() << "(" << I->second 
+                    << ")\n";
+          ++I;
+        }
+        std::cerr << "Output: " << Output.get() << "\n";
       }
 
-    /// @}
-    /// @name Methods
-    /// @{
-    public:
-      virtual int execute(const InputList& InpList, const sys::Path& Output ) {
-        try {
-          // Echo the configuration of options if we're running verbose
-          if (isSet(DEBUG_FLAG)) {
-            std::cerr << "Compiler Driver Options:\n";
-            std::cerr << "DryRun = " << isSet(DRY_RUN_FLAG) << "\n";
-            std::cerr << "Verbose = " << isSet(VERBOSE_FLAG) << " \n";
-            std::cerr << "TimeActions = " << isSet(TIME_ACTIONS_FLAG) << "\n";
-            std::cerr << "TimePasses = " << isSet(TIME_PASSES_FLAG) << "\n";
-            std::cerr << "ShowStats = " << isSet(SHOW_STATS_FLAG) << "\n";
-            std::cerr << "EmitRawCode = " << isSet(EMIT_RAW_FLAG) << "\n";
-            std::cerr << "EmitNativeCode = " << isSet(EMIT_NATIVE_FLAG) << "\n";
-            std::cerr << "ForceOutput = " << isSet(FORCE_FLAG) << "\n";
-            std::cerr << "KeepTemps = " << isSet(KEEP_TEMPS_FLAG) << "\n";
-            std::cerr << "OutputMachine = " << machine << "\n";
-            InputList::const_iterator I = InpList.begin();
-            while ( I != InpList.end() ) {
-              std::cerr << "Input: " << I->first.get() << "(" << I->second << ")\n";
-              ++I;
-            }
-            std::cerr << "Output: " << Output.get() << "\n";
-          }
+      // If there's no input, we're done.
+      if (InpList.empty())
+        throw std::string("Nothing to compile.");
 
-          // If there's no input, we're done.
-          if (InpList.empty())
-            throw std::string("Nothing to compile.");
+      // If they are asking for linking and didn't provide an output
+      // file then its an error (no way for us to "make up" a meaningful
+      // file name based on the various linker input files).
+      if (finalPhase == LINKING && Output.is_empty())
+        throw std::string(
+          "An output file name must be specified for linker output");
 
-          // If they are asking for linking and didn't provide an output
-          // file then its an error (no way for us to "make up" a meaningful
-          // file name based on the various linker input files).
-          if (finalPhase == LINKING && Output.is_empty())
+      // If they are not asking for linking, provided an output file and
+      // there is more than one input file, its an error
+      if (finalPhase != LINKING && !Output.is_empty() && InpList.size() > 1)
+        throw std::string("An output file name cannot be specified ") +
+          "with more than one input file name when not linking";
+
+      // This vector holds all the resulting actions of the following loop.
+      std::vector<Action*> actions;
+
+      /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
+      // for each input item
+      SetVector<sys::Path> LinkageItems;
+      std::vector<std::string> LibFiles;
+      InputList::const_iterator I = InpList.begin();
+      while ( I != InpList.end() ) {
+        // Get the suffix of the file name
+        const std::string& ftype = I->second;
+
+        // If its a library, bytecode file, or object file, save 
+        // it for linking below and short circuit the 
+        // pre-processing/translation/assembly phases
+        if (ftype.empty() ||  ftype == "o" || ftype == "bc" || ftype=="a") {
+          // We shouldn't get any of these types of files unless we're 
+          // later going to link. Enforce this limit now.
+          if (finalPhase != LINKING) {
             throw std::string(
-              "An output file name must be specified for linker output");
+              "Pre-compiled objects found but linking not requested");
+          }
+          if (ftype.empty())
+            LibFiles.push_back(I->first.get());
+          else
+            LinkageItems.insert(I->first);
+          ++I; continue; // short circuit remainder of loop
+        }
 
-          // If they are not asking for linking, provided an output file and
-          // there is more than one input file, its an error
-          if (finalPhase != LINKING && !Output.is_empty() && 
-              InpList.size() > 1) 
-            throw std::string("An output file name cannot be specified ") +
-              "with more than one input file name when not linking";
+        // At this point, we know its something we need to translate
+        // and/or optimize. See if we can get the configuration data
+        // for this kind of file.
+        ConfigData* cd = cdp->ProvideConfigData(I->second);
+        if (cd == 0)
+          throw std::string("Files of type '") + I->second + 
+                "' are not recognized."; 
+        if (isSet(DEBUG_FLAG))
+          DumpConfigData(cd,I->second);
 
-          // This vector holds all the resulting actions of the following loop.
-          std::vector<Action*> actions;
+        // Initialize the input and output files
+        sys::Path InFile(I->first);
+        sys::Path OutFile(I->first.get_basename());
 
-          /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
-          // for each input item
-          SetVector<sys::Path> LinkageItems;
-          std::vector<std::string> LibFiles;
-          sys::Path OutFile(Output);
-          InputList::const_iterator I = InpList.begin();
-          while ( I != InpList.end() ) {
-            // Get the suffix of the file name
-            const std::string& ftype = I->second;
+        // PRE-PROCESSING PHASE
+        Action& action = cd->PreProcessor;
 
-            // If its a library, bytecode file, or object file, save 
-            // it for linking below and short circuit the 
-            // pre-processing/translation/assembly phases
-            if (ftype.empty() ||  ftype == "o" || ftype == "bc" || ftype=="a") {
-              // We shouldn't get any of these types of files unless we're 
-              // later going to link. Enforce this limit now.
-              if (finalPhase != LINKING) {
-                throw std::string(
-                  "Pre-compiled objects found but linking not requested");
-              }
-              if (ftype.empty())
-                LibFiles.push_back(I->first.get());
-              else
-                LinkageItems.insert(I->first);
-              ++I; continue; // short circuit remainder of loop
+        // Get the preprocessing action, if needed, or error if appropriate
+        if (!action.program.is_empty()) {
+          if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
+            if (finalPhase == PREPROCESSING) {
+              OutFile.append_suffix("E");
+              actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
+            } else {
+              sys::Path TempFile(MakeTempFile(I->first.get_basename(),"E"));
+              actions.push_back(GetAction(cd,InFile,TempFile,
+                PREPROCESSING));
+              InFile = TempFile;
+            }
+          }
+        } else if (finalPhase == PREPROCESSING) {
+          throw cd->langName + " does not support pre-processing";
+        } else if (action.isSet(REQUIRED_FLAG)) {
+          throw std::string("Don't know how to pre-process ") + 
+                cd->langName + " files";
+        }
+
+        // Short-circuit remaining actions if all they want is 
+        // pre-processing
+        if (finalPhase == PREPROCESSING) { ++I; continue; };
+
+        /// TRANSLATION PHASE
+        action = cd->Translator;
+
+        // Get the translation action, if needed, or error if appropriate
+        if (!action.program.is_empty()) {
+          if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
+            if (finalPhase == TRANSLATION) {
+              OutFile.append_suffix("o");
+              actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
+            } else {
+              sys::Path TempFile(MakeTempFile(I->first.get_basename(),"trans")); 
+              actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
+              InFile = TempFile;
             }
 
-            // At this point, we know its something we need to translate
-            // and/or optimize. See if we can get the configuration data
-            // for this kind of file.
-            ConfigData* cd = cdp->ProvideConfigData(I->second);
-            if (cd == 0)
-              throw std::string("Files of type '") + I->second + 
-                    "' are not recognized."; 
-            if (isSet(DEBUG_FLAG))
-              DumpConfigData(cd,I->second);
-
-            // Initialize the input file
-            sys::Path InFile(I->first);
-
-            // PRE-PROCESSING PHASE
-            Action& action = cd->PreProcessor;
-
-            // Get the preprocessing action, if needed, or error if appropriate
-            if (!action.program.is_empty()) {
-              if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
-                if (finalPhase == PREPROCESSING) {
-                  if (OutFile.is_empty()) {
-                    OutFile = I->first;
-                    OutFile.append_suffix("E");
-                  }
-                  actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
-                } else {
-                  sys::Path TempFile(MakeTempFile(I->first.get(),"E"));
-                  actions.push_back(GetAction(cd,InFile,TempFile,PREPROCESSING));
-                  InFile = TempFile;
-                }
-              }
-            } else if (finalPhase == PREPROCESSING) {
-              throw cd->langName + " does not support pre-processing";
-            } else if (action.isSet(REQUIRED_FLAG)) {
-              throw std::string("Don't know how to pre-process ") + 
-                    cd->langName + " files";
+            // ll -> bc Helper
+            if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
+              /// The output of the translator is an LLVM Assembly program
+              /// We need to translate it to bytecode
+              Action* action = new Action();
+              action->program.set_file("llvm-as");
+              action->args.push_back(InFile.get());
+              action->args.push_back("-o");
+              InFile.append_suffix("bc");
+              action->args.push_back(InFile.get());
+              actions.push_back(action);
             }
+          }
+        } else if (finalPhase == TRANSLATION) {
+          throw cd->langName + " does not support translation";
+        } else if (action.isSet(REQUIRED_FLAG)) {
+          throw std::string("Don't know how to translate ") + 
+                cd->langName + " files";
+        }
 
-            // Short-circuit remaining actions if all they want is pre-processing
-            if (finalPhase == PREPROCESSING) { ++I; continue; };
+        // Short-circuit remaining actions if all they want is translation
+        if (finalPhase == TRANSLATION) { ++I; continue; }
 
-            /// TRANSLATION PHASE
-            action = cd->Translator;
+        /// OPTIMIZATION PHASE
+        action = cd->Optimizer;
 
-            // Get the translation action, if needed, or error if appropriate
-            if (!action.program.is_empty()) {
-              if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
-                if (finalPhase == TRANSLATION) {
-                  if (OutFile.is_empty()) {
-                    OutFile = I->first;
-                    OutFile.append_suffix("o");
-                  }
-                  actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
-                } else {
-                  sys::Path TempFile(MakeTempFile(I->first.get(),"trans")); 
-                  actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
-                  InFile = TempFile;
-                }
-
-                // ll -> bc Helper
-                if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
-                  /// The output of the translator is an LLVM Assembly program
-                  /// We need to translate it to bytecode
-                  Action* action = new Action();
-                  action->program.set_file("llvm-as");
-                  action->args.push_back(InFile.get());
-                  action->args.push_back("-o");
-                  InFile.append_suffix("bc");
-                  action->args.push_back(InFile.get());
-                  actions.push_back(action);
-                }
-              }
-            } else if (finalPhase == TRANSLATION) {
-              throw cd->langName + " does not support translation";
-            } else if (action.isSet(REQUIRED_FLAG)) {
-              throw std::string("Don't know how to translate ") + 
-                    cd->langName + " files";
-            }
-
-            // Short-circuit remaining actions if all they want is translation
-            if (finalPhase == TRANSLATION) { ++I; continue; }
-
-            /// OPTIMIZATION PHASE
-            action = cd->Optimizer;
-
-            // Get the optimization action, if needed, or error if appropriate
-            if (!isSet(EMIT_RAW_FLAG)) {
-              if (!action.program.is_empty()) {
-                if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
-                  if (finalPhase == OPTIMIZATION) {
-                    if (OutFile.is_empty()) {
-                      OutFile = I->first;
-                      OutFile.append_suffix("o");
-                    }
-                    actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
-                  } else {
-                    sys::Path TempFile(MakeTempFile(I->first.get(),"opt"));
-                    actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
-                    InFile = TempFile;
-                  }
-                  // ll -> bc Helper
-                  if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
-                    /// The output of the optimizer is an LLVM Assembly program
-                    /// We need to translate it to bytecode with llvm-as
-                    Action* action = new Action();
-                    action->program.set_file("llvm-as");
-                    action->args.push_back(InFile.get());
-                    action->args.push_back("-f");
-                    action->args.push_back("-o");
-                    InFile.append_suffix("bc");
-                    action->args.push_back(InFile.get());
-                    actions.push_back(action);
-                  }
-                }
-              } else if (finalPhase == OPTIMIZATION) {
-                throw cd->langName + " does not support optimization";
-              } else if (action.isSet(REQUIRED_FLAG)) {
-                throw std::string("Don't know how to optimize ") + 
-                    cd->langName + " files";
-              }
-            }
-
-            // Short-circuit remaining actions if all they want is optimization
-            if (finalPhase == OPTIMIZATION) { ++I; continue; }
-
-            /// ASSEMBLY PHASE
-            action = cd->Assembler;
-
-            if (finalPhase == ASSEMBLY) {
-              if (isSet(EMIT_NATIVE_FLAG)) {
-                // Use llc to get the native assembly file
-                Action* action = new Action();
-                action->program.set_file("llc");
-                action->args.push_back(InFile.get());
-                action->args.push_back("-f");
-                action->args.push_back("-o");
-                if (OutFile.is_empty()) {
-                  OutFile = I->first;
-                  OutFile.append_suffix("s");
-                }
-                action->args.push_back(OutFile.get());
+        // Get the optimization action, if needed, or error if appropriate
+        if (!isSet(EMIT_RAW_FLAG)) {
+          if (!action.program.is_empty()) {
+            if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
+              if (finalPhase == OPTIMIZATION) {
+                OutFile.append_suffix("o");
+                actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
               } else {
-                // Just convert back to llvm assembly with llvm-dis
+                sys::Path TempFile(MakeTempFile(I->first.get_basename(),"opt"));
+                actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
+                InFile = TempFile;
+              }
+              // ll -> bc Helper
+              if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
+                /// The output of the optimizer is an LLVM Assembly program
+                /// We need to translate it to bytecode with llvm-as
                 Action* action = new Action();
-                action->program.set_file("llvm-dis");
+                action->program.set_file("llvm-as");
                 action->args.push_back(InFile.get());
                 action->args.push_back("-f");
                 action->args.push_back("-o");
-                action->args.push_back(OutFile.get());
+                InFile.append_suffix("bc");
+                action->args.push_back(InFile.get());
                 actions.push_back(action);
               }
-
-              // Short circuit the rest of the loop, we don't want to link 
-              ++I; 
-              continue;
             }
-
-            // Register the result of the actions as a link candidate
-            LinkageItems.insert(InFile);
-
-            // Go to next file to be processed
-            ++I;
-          } // end while loop over each input file
-
-          /// RUN THE COMPILATION ACTIONS
-          std::vector<Action*>::iterator AI = actions.begin();
-          std::vector<Action*>::iterator AE = actions.end();
-          while (AI != AE) {
-            if (!DoAction(*AI))
-              throw std::string("Action failed");
-            AI++;
+          } else if (finalPhase == OPTIMIZATION) {
+            throw cd->langName + " does not support optimization";
+          } else if (action.isSet(REQUIRED_FLAG)) {
+            throw std::string("Don't know how to optimize ") + 
+                cd->langName + " files";
           }
-
-          /// LINKING PHASE
-          if (finalPhase == LINKING) {
-            // Insert the platform-specific system libraries to the path list
-            LibraryPaths.push_back(sys::Path::GetSystemLibraryPath1());
-            LibraryPaths.push_back(sys::Path::GetSystemLibraryPath2());
-
-            // We're emitting native code so let's build an gccld Action
-            Action* link = new Action();
-            link->program.set_file("llvm-ld");
-
-            // Add in the optimization level requested
-            switch (optLevel) {
-              case OPT_FAST_COMPILE:
-                link->args.push_back("-O1");
-                break;
-              case OPT_SIMPLE:
-                link->args.push_back("-O2");
-                break;
-              case OPT_AGGRESSIVE:
-                link->args.push_back("-O3");
-                break;
-              case OPT_LINK_TIME:
-                link->args.push_back("-O4");
-                break;
-              case OPT_AGGRESSIVE_LINK_TIME:
-                link->args.push_back("-O5");
-                break;
-              case OPT_NONE:
-                break;
-            }
-
-            // Add in all the linkage items we generated. This includes the
-            // output from the translation/optimization phases as well as any
-            // -l arguments specified.
-            for (PathVector::const_iterator I=LinkageItems.begin(), 
-                 E=LinkageItems.end(); I != E; ++I )
-              link->args.push_back(I->get());
-
-            // Add in all the libraries we found.
-            for (std::vector<std::string>::const_iterator I=LibFiles.begin(),
-                 E=LibFiles.end(); I != E; ++I )
-              link->args.push_back(std::string("-l")+*I);
-
-            // Add in all the library paths to the command line
-            for (PathVector::const_iterator I=LibraryPaths.begin(),
-                 E=LibraryPaths.end(); I != E; ++I)
-              link->args.push_back( std::string("-L") + I->get());
-
-            // Add in other optional flags
-            if (isSet(EMIT_NATIVE_FLAG))
-              link->args.push_back("-native");
-            if (isSet(VERBOSE_FLAG))
-              link->args.push_back("-v");
-            if (isSet(TIME_PASSES_FLAG))
-              link->args.push_back("-time-passes");
-            if (isSet(SHOW_STATS_FLAG))
-              link->args.push_back("-stats");
-            if (isSet(STRIP_OUTPUT_FLAG))
-              link->args.push_back("-s");
-            if (isSet(DEBUG_FLAG)) {
-              link->args.push_back("-debug");
-              link->args.push_back("-debug-pass=Details");
-            }
-
-            // Add in mandatory flags
-            link->args.push_back("-o");
-            link->args.push_back(OutFile.get());
-
-            // Execute the link
-            if (!DoAction(link))
-                throw std::string("Action failed");
-          }
-        } catch (std::string& msg) {
-          cleanup();
-          throw;
-        } catch (...) {
-          cleanup();
-          throw std::string("Unspecified error");
         }
-        cleanup();
-        return 0;
+
+        // Short-circuit remaining actions if all they want is optimization
+        if (finalPhase == OPTIMIZATION) { ++I; continue; }
+
+        /// ASSEMBLY PHASE
+        action = cd->Assembler;
+
+        if (finalPhase == ASSEMBLY) {
+          if (isSet(EMIT_NATIVE_FLAG)) {
+            // Use llc to get the native assembly file
+            Action* action = new Action();
+            action->program.set_file("llc");
+            action->args.push_back(InFile.get());
+            action->args.push_back("-f");
+            action->args.push_back("-o");
+            OutFile.append_suffix("s");
+            action->args.push_back(OutFile.get());
+          } else {
+            // Just convert back to llvm assembly with llvm-dis
+            Action* action = new Action();
+            action->program.set_file("llvm-dis");
+            action->args.push_back(InFile.get());
+            action->args.push_back("-f");
+            action->args.push_back("-o");
+            OutFile.append_suffix("ll");
+            action->args.push_back(OutFile.get());
+            actions.push_back(action);
+          }
+
+          // Short circuit the rest of the loop, we don't want to link 
+          ++I; 
+          continue;
+        }
+
+        // Register the result of the actions as a link candidate
+        LinkageItems.insert(InFile);
+
+        // Go to next file to be processed
+        ++I;
+      } // end while loop over each input file
+
+      /// RUN THE COMPILATION ACTIONS
+      std::vector<Action*>::iterator AI = actions.begin();
+      std::vector<Action*>::iterator AE = actions.end();
+      while (AI != AE) {
+        if (!DoAction(*AI))
+          throw std::string("Action failed");
+        AI++;
       }
 
-    /// @}
-    /// @name Data
-    /// @{
-    private:
-      ConfigDataProvider* cdp;      ///< Where we get configuration data from
-      Phases finalPhase;            ///< The final phase of compilation
-      OptimizationLevels optLevel;  ///< The optimization level to apply
-      unsigned Flags;               ///< The driver flags
-      std::string machine;          ///< Target machine name
-      PathVector LibraryPaths;      ///< -L options
-      PathVector IncludePaths;      ///< -I options
-      StringVector Defines;         ///< -D options
-      sys::Path TempDir;            ///< Name of the temporary directory.
-      StringTable AdditionalArgs;   ///< The -Txyz options
-      StringVector fOptions;        ///< -f options
-      StringVector MOptions;        ///< -M options
-      StringVector WOptions;        ///< -W options
+      /// LINKING PHASE
+      if (finalPhase == LINKING) {
 
-    /// @}
-  };
+        // Insert the platform-specific system libraries to the path list
+        LibraryPaths.push_back(sys::Path::GetSystemLibraryPath1());
+        LibraryPaths.push_back(sys::Path::GetSystemLibraryPath2());
+
+        // Set up the linking action with llvm-ld
+        Action* link = new Action();
+        link->program.set_file("llvm-ld");
+
+        // Add in the optimization level requested
+        switch (optLevel) {
+          case OPT_FAST_COMPILE:
+            link->args.push_back("-O1");
+            break;
+          case OPT_SIMPLE:
+            link->args.push_back("-O2");
+            break;
+          case OPT_AGGRESSIVE:
+            link->args.push_back("-O3");
+            break;
+          case OPT_LINK_TIME:
+            link->args.push_back("-O4");
+            break;
+          case OPT_AGGRESSIVE_LINK_TIME:
+            link->args.push_back("-O5");
+            break;
+          case OPT_NONE:
+            break;
+        }
+
+        // Add in all the linkage items we generated. This includes the
+        // output from the translation/optimization phases as well as any
+        // -l arguments specified.
+        for (PathVector::const_iterator I=LinkageItems.begin(), 
+             E=LinkageItems.end(); I != E; ++I )
+          link->args.push_back(I->get());
+
+        // Add in all the libraries we found.
+        for (std::vector<std::string>::const_iterator I=LibFiles.begin(),
+             E=LibFiles.end(); I != E; ++I )
+          link->args.push_back(std::string("-l")+*I);
+
+        // Add in all the library paths to the command line
+        for (PathVector::const_iterator I=LibraryPaths.begin(),
+             E=LibraryPaths.end(); I != E; ++I)
+          link->args.push_back( std::string("-L") + I->get());
+
+        // Add in the additional linker arguments requested
+        for (StringVector::const_iterator I=AdditionalArgs[LINKING].begin(),
+             E=AdditionalArgs[LINKING].end(); I != E; ++I)
+          link->args.push_back( *I );
+
+        // Add in other optional flags
+        if (isSet(EMIT_NATIVE_FLAG))
+          link->args.push_back("-native");
+        if (isSet(VERBOSE_FLAG))
+          link->args.push_back("-v");
+        if (isSet(TIME_PASSES_FLAG))
+          link->args.push_back("-time-passes");
+        if (isSet(SHOW_STATS_FLAG))
+          link->args.push_back("-stats");
+        if (isSet(STRIP_OUTPUT_FLAG))
+          link->args.push_back("-s");
+        if (isSet(DEBUG_FLAG)) {
+          link->args.push_back("-debug");
+          link->args.push_back("-debug-pass=Details");
+        }
+
+        // Add in mandatory flags
+        link->args.push_back("-o");
+        link->args.push_back(Output.get());
+
+        // Execute the link
+        if (!DoAction(link))
+            throw std::string("Action failed");
+      }
+    } catch (std::string& msg) {
+      cleanup();
+      throw;
+    } catch (...) {
+      cleanup();
+      throw std::string("Unspecified error");
+    }
+    cleanup();
+    return 0;
+  }
+
+/// @}
+/// @name Data
+/// @{
+private:
+  ConfigDataProvider* cdp;      ///< Where we get configuration data from
+  Phases finalPhase;            ///< The final phase of compilation
+  OptimizationLevels optLevel;  ///< The optimization level to apply
+  unsigned Flags;               ///< The driver flags
+  std::string machine;          ///< Target machine name
+  PathVector LibraryPaths;      ///< -L options
+  PathVector IncludePaths;      ///< -I options
+  StringVector Defines;         ///< -D options
+  sys::Path TempDir;            ///< Name of the temporary directory.
+  StringTable AdditionalArgs;   ///< The -Txyz options
+  StringVector fOptions;        ///< -f options
+  StringVector MOptions;        ///< -M options
+  StringVector WOptions;        ///< -W options
+
+/// @}
+};
 }
 
 CompilerDriver::~CompilerDriver() {
