//===-- tools/bugpoint/ToolRunner.h -----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file exposes an abstraction around a platform C compiler, used to
// compile C and assembly code.  It also exposes an "AbstractIntepreter"
// interface, which is used to execute code using one of the LLVM execution
// engines.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_BUGPOINT_TOOLRUNNER_H
#define LLVM_TOOLS_BUGPOINT_TOOLRUNNER_H

#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SystemUtils.h"
#include <exception>
#include <vector>

namespace llvm {

extern cl::opt<bool> SaveTemps;
extern Triple TargetTriple;

class LLC;

//===---------------------------------------------------------------------===//
// CC abstraction
//
class CC {
  std::string CCPath;              // The path to the cc executable.
  std::string RemoteClientPath;    // The path to the rsh / ssh executable.
  std::vector<std::string> ccArgs; // CC-specific arguments.
  CC(StringRef ccPath, StringRef RemotePath,
     const std::vector<std::string> *CCArgs)
      : CCPath(std::string(ccPath)), RemoteClientPath(std::string(RemotePath)) {
    if (CCArgs)
      ccArgs = *CCArgs;
  }

public:
  enum FileType { AsmFile, ObjectFile, CFile };

  static CC *create(const char *Argv0, std::string &Message,
                    const std::string &CCBinary,
                    const std::vector<std::string> *Args);

  /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
  /// either a .s file, or a .c file, specified by FileType), with the specified
  /// arguments.  Standard input is specified with InputFile, and standard
  /// Output is captured to the specified OutputFile location.  The SharedLibs
  /// option specifies optional native shared objects that can be loaded into
  /// the program for execution.
  ///
  Expected<int> ExecuteProgram(
      const std::string &ProgramFile, const std::vector<std::string> &Args,
      FileType fileType, const std::string &InputFile,
      const std::string &OutputFile,
      const std::vector<std::string> &CCArgs = std::vector<std::string>(),
      unsigned Timeout = 0, unsigned MemoryLimit = 0);

  /// MakeSharedObject - This compiles the specified file (which is either a .c
  /// file or a .s file) into a shared object.
  ///
  Error MakeSharedObject(const std::string &InputFile, FileType fileType,
                         std::string &OutputFile,
                         const std::vector<std::string> &ArgsForCC);
};

//===---------------------------------------------------------------------===//
/// AbstractInterpreter Class - Subclasses of this class are used to execute
/// LLVM bitcode in a variety of ways.  This abstract interface hides this
/// complexity behind a simple interface.
///
class AbstractInterpreter {
  virtual void anchor();

public:
  static LLC *createLLC(const char *Argv0, std::string &Message,
                        const std::string &CCBinary,
                        const std::vector<std::string> *Args = nullptr,
                        const std::vector<std::string> *CCArgs = nullptr,
                        bool UseIntegratedAssembler = false);

  static AbstractInterpreter *
  createLLI(const char *Argv0, std::string &Message,
            const std::vector<std::string> *Args = nullptr);

  static AbstractInterpreter *
  createJIT(const char *Argv0, std::string &Message,
            const std::vector<std::string> *Args = nullptr);

  static AbstractInterpreter *
  createCustomCompiler(const char *Argv0, std::string &Message,
                       const std::string &CompileCommandLine);

  static AbstractInterpreter *
  createCustomExecutor(const char *Argv0, std::string &Message,
                       const std::string &ExecCommandLine);

  virtual ~AbstractInterpreter() {}

  /// compileProgram - Compile the specified program from bitcode to executable
  /// code.  This does not produce any output, it is only used when debugging
  /// the code generator.  It returns false if the code generator fails.
  virtual Error compileProgram(const std::string &Bitcode, unsigned Timeout = 0,
                               unsigned MemoryLimit = 0) {
    return Error::success();
  }

  /// Compile the specified program from bitcode to code understood by the CC
  /// driver (either C or asm).  Returns an error if the code generator fails,,
  /// otherwise, the type of code emitted.
  virtual Expected<CC::FileType> OutputCode(const std::string &Bitcode,
                                            std::string &OutFile,
                                            unsigned Timeout = 0,
                                            unsigned MemoryLimit = 0) {
    return make_error<StringError>(
        "OutputCode not supported by this AbstractInterpreter!",
        inconvertibleErrorCode());
  }

  /// ExecuteProgram - Run the specified bitcode file, emitting output to the
  /// specified filename.  This sets RetVal to the exit code of the program or
  /// returns an Error if a problem was encountered that prevented execution of
  /// the program.
  ///
  virtual Expected<int> ExecuteProgram(
      const std::string &Bitcode, const std::vector<std::string> &Args,
      const std::string &InputFile, const std::string &OutputFile,
      const std::vector<std::string> &CCArgs = std::vector<std::string>(),
      const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
      unsigned Timeout = 0, unsigned MemoryLimit = 0) = 0;
};

//===---------------------------------------------------------------------===//
// LLC Implementation of AbstractIntepreter interface
//
class LLC : public AbstractInterpreter {
  std::string LLCPath;               // The path to the LLC executable.
  std::vector<std::string> ToolArgs; // Extra args to pass to LLC.
  CC *cc;
  bool UseIntegratedAssembler;

public:
  LLC(const std::string &llcPath, CC *cc, const std::vector<std::string> *Args,
      bool useIntegratedAssembler)
      : LLCPath(llcPath), cc(cc),
        UseIntegratedAssembler(useIntegratedAssembler) {
    ToolArgs.clear();
    if (Args)
      ToolArgs = *Args;
  }
  ~LLC() override { delete cc; }

  /// compileProgram - Compile the specified program from bitcode to executable
  /// code.  This does not produce any output, it is only used when debugging
  /// the code generator.  Returns false if the code generator fails.
  Error compileProgram(const std::string &Bitcode, unsigned Timeout = 0,
                       unsigned MemoryLimit = 0) override;

  Expected<int> ExecuteProgram(
      const std::string &Bitcode, const std::vector<std::string> &Args,
      const std::string &InputFile, const std::string &OutputFile,
      const std::vector<std::string> &CCArgs = std::vector<std::string>(),
      const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
      unsigned Timeout = 0, unsigned MemoryLimit = 0) override;

  Expected<CC::FileType> OutputCode(const std::string &Bitcode,
                                    std::string &OutFile, unsigned Timeout = 0,
                                    unsigned MemoryLimit = 0) override;
};

/// Find the first executable file \ExeName, either in the user's PATH or,
/// failing that, in the same directory as argv[0]. This allows us to find
/// another LLVM tool if it is built in the same directory. If no executable is
/// found, an error is returned.
ErrorOr<std::string> FindProgramByName(const std::string &ExeName,
                                       const char *Argv0, void *MainAddr);

} // End llvm namespace

#endif
