//===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the 
// University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file implements the bulk of the LLVM Compiler Driver (llvmc).
//
//===------------------------------------------------------------------------===

#include "CompilerDriver.h"
#include "ConfigLexer.h"
#include "llvm/Module.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Support/Timer.h"
#include "llvm/System/Signals.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include <iostream>
#include "llvm/Config/alloca.h"

using namespace llvm;

namespace {

void WriteAction(CompilerDriver::Action* action ) {
  std::cerr << action->program.c_str();
  std::vector<std::string>::const_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>::const_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.setDirectory(*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.setDirectory(*I);
      LibraryPaths.push_back(tmp);
      ++I;
    }
  }

  virtual void addLibraryPath( const sys::Path& libPath ) {
    LibraryPaths.push_back(libPath);
  }

  virtual void addToolPath( const sys::Path& toolPath ) {
    ToolPaths.push_back(toolPath);
  }

  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.isDirectory() && TempDir.writable())
        TempDir.destroyDirectory(/*remove_contents=*/true);
    } else {
      std::cout << "Temporary files are in " << TempDir << "\n";
    }
  }

  sys::Path MakeTempFile(const std::string& basename, 
                         const std::string& suffix ) {
    sys::Path result(TempDir);
    if (!result.appendFile(basename))
      throw basename + ": can't use this file name";
    if (!result.appendSuffix(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;
      default:
        assert(!"Invalid driver phase!");
        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 == "%fOpts%") {
              if (!fOptions.empty())
                action->args.insert(action->args.end(), fOptions.begin(), 
                                    fOptions.end());
            } else
              found = false;
            break;
          case 'i':
            if (*PI == "%in%") {
              action->args.push_back(input.toString());
            } 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->toString() );
                ++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->toString() );
                ++I;
              }
            } else
              found = false;
            break;
          case 'o':
            if (*PI == "%out%") {
              action->args.push_back(output.toString());
            } 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%") {
              if (!MOptions.empty())
                action->args.insert(action->args.end(), MOptions.begin(), 
                                    MOptions.end());
            } else
              found = false;
            break;
          case 'W':
            if (*PI == "%Wopts%") {
              for (StringVector::iterator I = WOptions.begin(),
                   E = WOptions.end(); I != E ; ++I ) {
                action->args.push_back( std::string("-W") + *I );
              }
            } 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.toString() + "'";
          } else if (!PI->empty()) {
            // It's not a legal substitution, just pass it through
            action->args.push_back(*PI);
          }
        }
      } else if (!PI->empty()) {
        // Its not a substitution, just put it in the action
        action->args.push_back(*PI);
      }
      PI++;
    }

    // Finally, we're done
    return action;
  }

  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.toString());
      if (progpath.isEmpty())
        throw std::string("Can't find program '" +
                          action->program.toString()+"'");
      else if (progpath.executable())
        action->program = progpath;
      else
        throw std::string("Program '"+action->program.toString()+
                          "' is not executable.");

      // Invoke the program
      const char** Args = (const char**) 
        alloca(sizeof(const char*)*(action->args.size()+1));
      for (unsigned i = 0; i != action->args.size(); ++i)
        Args[i] = action->args[i].c_str();
      Args[action->args.size()] = 0;  // null terminate list.
      if (isSet(TIME_ACTIONS_FLAG)) {
        Timer timer(action->program.toString());
        timer.startTimer();
        int resultCode = sys::Program::ExecuteAndWait(action->program, Args);
        timer.stopTimer();
        timer.print(timer,std::cerr);
        return resultCode == 0;
      }
      else
        return 0 == sys::Program::ExecuteAndWait(action->program, 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 directories of the LibraryPaths.
  llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
                                        bool native = false) {
    sys::Path fullpath;
    fullpath.setFile(link_item);
    if (fullpath.readable())
      return fullpath;
    for (PathVector::iterator PI = LibraryPaths.begin(), 
         PE = LibraryPaths.end(); PI != PE; ++PI) {
      fullpath.setDirectory(PI->toString());
      fullpath.appendFile(link_item);
      if (fullpath.readable())
        return fullpath;
      if (native) {
        fullpath.appendSuffix("a");
      } else {
        fullpath.appendSuffix("bc");
        if (fullpath.readable()) 
          return fullpath;
        fullpath.elideSuffix();
        fullpath.appendSuffix("o");
        if (fullpath.readable()) 
          return fullpath;
        fullpath = *PI;
        fullpath.appendFile(std::string("lib") + link_item);
        fullpath.appendSuffix("a");
        if (fullpath.readable())
          return fullpath;
        fullpath.elideSuffix();
        fullpath.appendSuffix("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()) {
      // look for the library using the -L arguments specified
      // on the command line.
      fullpath = GetPathForLinkageItem(link_item.toString());

      // If we didn't find the file in any of the library search paths
      // we have to bail. No where else to look.
      if (fullpath.isEmpty()) {
        err = 
          std::string("Can't find linkage item '") + link_item.toString() + "'";
        return false;
      }
    } else {
      fullpath = link_item;
    }

    // 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.isBytecodeFile()) {
      // Process the dependent libraries recursively
      Module::LibraryListType modlibs;
      if (GetBytecodeDependentLibraries(fullpath.toString(),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.toString() + "'";
            } else {
              err += " which is required by file '" + fullpath.toString() + "'";
            }
            return false;
          }
          ++LI;
        }
      } else if (err.empty()) {
        err = std::string(
          "The dependent libraries could not be extracted from '") + 
          fullpath.toString();
        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 << "(" << I->second 
                    << ")\n";
          ++I;
        }
        std::cerr << "Output: " << Output << "\n";
      }

      // 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.isEmpty())
        throw std::string(
          "An output file name must be specified for linker output");

      // 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.isEmpty() && 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;
      StringVector LibFiles;
      InputList::const_iterator I = InpList.begin();
      for (InputList::const_iterator I = InpList.begin(), E = InpList.end();
           I != E; ++I ) {
        // 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(
              "Pre-compiled objects found but linking not requested");
          }
          if (ftype.empty())
            LibFiles.push_back(I->first.toString());
          else
            LinkageItems.insert(I->first);
          continue; // short circuit remainder of loop
        }

        // 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);

        // Add the config data's library paths to the end of the list
        for (StringVector::iterator LPI = cd->libpaths.begin(),
             LPE = cd->libpaths.end(); LPI != LPE; ++LPI){
          LibraryPaths.push_back(sys::Path(*LPI));
        }

        // Initialize the input and output files
        sys::Path InFile(I->first);
        sys::Path OutFile(I->first.getBasename());

        // PRE-PROCESSING PHASE
        Action& action = cd->PreProcessor;

        // Get the preprocessing action, if needed, or error if appropriate
        if (!action.program.isEmpty()) {
          if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
            if (finalPhase == PREPROCESSING) {
              if (Output.isEmpty()) {
                OutFile.appendSuffix("E");
                actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
              } else {
                actions.push_back(GetAction(cd,InFile,Output,PREPROCESSING));
              }
            } else {
              sys::Path TempFile(MakeTempFile(I->first.getBasename(),"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) { continue; };

        /// TRANSLATION PHASE
        action = cd->Translator;

        // Get the translation action, if needed, or error if appropriate
        if (!action.program.isEmpty()) {
          if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
            if (finalPhase == TRANSLATION) {
              if (Output.isEmpty()) {
                OutFile.appendSuffix("o");
                actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
              } else {
                actions.push_back(GetAction(cd,InFile,Output,TRANSLATION));
              }
            } else {
              sys::Path TempFile(MakeTempFile(I->first.getBasename(),"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.setFile("llvm-as");
              action->args.push_back(InFile.toString());
              action->args.push_back("-o");
              InFile.appendSuffix("bc");
              action->args.push_back(InFile.toString());
              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) { continue; }

        /// OPTIMIZATION PHASE
        action = cd->Optimizer;

        // Get the optimization action, if needed, or error if appropriate
        if (!isSet(EMIT_RAW_FLAG)) {
          if (!action.program.isEmpty()) {
            if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
              if (finalPhase == OPTIMIZATION) {
                if (Output.isEmpty()) {
                  OutFile.appendSuffix("o");
                  actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
                } else {
                  actions.push_back(GetAction(cd,InFile,Output,OPTIMIZATION));
                }
              } else {
                sys::Path TempFile(MakeTempFile(I->first.getBasename(),"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.setFile("llvm-as");
                action->args.push_back(InFile.toString());
                action->args.push_back("-f");
                action->args.push_back("-o");
                InFile.appendSuffix("bc");
                action->args.push_back(InFile.toString());
                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) { continue; }

        /// ASSEMBLY PHASE
        action = cd->Assembler;

        if (finalPhase == ASSEMBLY) {

          // Build either a native compilation action or a disassembly action
          Action* action = new Action();
          if (isSet(EMIT_NATIVE_FLAG)) {
            // Use llc to get the native assembly file
            action->program.setFile("llc");
            action->args.push_back(InFile.toString());
            action->args.push_back("-f");
            action->args.push_back("-o");
            if (Output.isEmpty()) {
              OutFile.appendSuffix("o");
              action->args.push_back(OutFile.toString());
            } else {
              action->args.push_back(Output.toString());
            }
            actions.push_back(action);
          } else {
            // Just convert back to llvm assembly with llvm-dis
            action->program.setFile("llvm-dis");
            action->args.push_back(InFile.toString());
            action->args.push_back("-f");
            action->args.push_back("-o");
            if (Output.isEmpty()) {
              OutFile.appendSuffix("ll");
              action->args.push_back(OutFile.toString());
            } else {
              action->args.push_back(Output.toString());
            }
          }

          // Put the action on the list
          actions.push_back(action);

          // Short circuit the rest of the loop, we don't want to link 
          continue;
        }

        // Register the result of the actions as a link candidate
        LinkageItems.insert(InFile);

      } // 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++;
      }

      /// LINKING PHASE
      if (finalPhase == LINKING) {

        // Insert the platform-specific system libraries to the path list
        std::vector<sys::Path> SysLibs;
        sys::Path::GetSystemLibraryPaths(SysLibs);
        LibraryPaths.insert(LibraryPaths.end(), SysLibs.begin(), SysLibs.end());

        // Set up the linking action with llvm-ld
        Action* link = new Action();
        link->program.setFile("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->toString());

        // Add in all the libraries we found.
        for (StringVector::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->toString());

        // 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.toString());

        // 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
  PathVector ToolPaths;         ///< -B 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() {
}

CompilerDriver*
CompilerDriver::Get(ConfigDataProvider& CDP) {
  return new CompilerDriverImpl(CDP);
}

CompilerDriver::ConfigData::ConfigData()
  : langName()
  , PreProcessor()
  , Translator()
  , Optimizer()
  , Assembler()
  , Linker()
{
  StringVector emptyVec;
  for (unsigned i = 0; i < NUM_PHASES; ++i)
    opts.push_back(emptyVec);
}

// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
