//===- 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>

using namespace llvm;

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;
    ++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.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.get() << "\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%") {
              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);
          }
        }
      } else {
        // 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.get());
      if (progpath.isEmpty())
        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.appendFile(link_item);
    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 = dir;
      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()) {
      // 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.isEmpty()) {
        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.isEmpty()) {
        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 its an LLVM bytecode file ...
    if (fullpath.isBytecodeFile()) {
      // 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;
        }
      } 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";
      }

      // 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;
      std::vector<std::string> 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.get());
          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);

        // 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.get());
              action->args.push_back("-o");
              InFile.appendSuffix("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) { 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.get());
                action->args.push_back("-f");
                action->args.push_back("-o");
                InFile.appendSuffix("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) { 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.get());
            action->args.push_back("-f");
            action->args.push_back("-o");
            if (Output.isEmpty()) {
              OutFile.appendSuffix("o");
              action->args.push_back(OutFile.get());
            } else {
              action->args.push_back(Output.get());
            }
            actions.push_back(action);
          } else {
            // Just convert back to llvm assembly with llvm-dis
            action->program.setFile("llvm-dis");
            action->args.push_back(InFile.get());
            action->args.push_back("-f");
            action->args.push_back("-o");
            if (Output.isEmpty()) {
              OutFile.appendSuffix("ll");
              action->args.push_back(OutFile.get());
            } else {
              action->args.push_back(Output.get());
            }
          }

          // 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
        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.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->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
  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
