+//===---------------------------------------------------------------------===//
+// Custom compiler command implementation of AbstractIntepreter interface
+//
+// Allows using a custom command for compiling the bitcode, thus allows, for
+// example, to compile a bitcode fragment without linking or executing, then
+// using a custom wrapper script to check for compiler errors.
+namespace {
+ class CustomCompiler : public AbstractInterpreter {
+ std::string CompilerCommand;
+ std::vector<std::string> CompilerArgs;
+ public:
+ CustomCompiler(
+ const std::string &CompilerCmd, std::vector<std::string> CompArgs) :
+ CompilerCommand(CompilerCmd), CompilerArgs(CompArgs) {}
+
+ virtual void compileProgram(const std::string &Bitcode,
+ std::string *Error,
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0);
+
+ virtual int ExecuteProgram(const std::string &Bitcode,
+ const std::vector<std::string> &Args,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ std::string *Error,
+ const std::vector<std::string> &GCCArgs =
+ std::vector<std::string>(),
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0) {
+ *Error = "Execution not supported with -compile-custom";
+ return -1;
+ }
+ };
+}
+
+void CustomCompiler::compileProgram(const std::string &Bitcode,
+ std::string *Error,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+
+ std::vector<const char*> ProgramArgs;
+ ProgramArgs.push_back(CompilerCommand.c_str());
+
+ for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
+ ProgramArgs.push_back(CompilerArgs.at(i).c_str());
+ ProgramArgs.push_back(Bitcode.c_str());
+ ProgramArgs.push_back(0);
+
+ // Add optional parameters to the running program from Argv
+ for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
+ ProgramArgs.push_back(CompilerArgs[i].c_str());
+
+ if (RunProgramWithTimeout( sys::Path(CompilerCommand), &ProgramArgs[0],
+ sys::Path(), sys::Path(), sys::Path(),
+ Timeout, MemoryLimit, Error))
+ *Error = ProcessFailure(sys::Path(CompilerCommand), &ProgramArgs[0],
+ Timeout, MemoryLimit);
+}
+