Mercurial > hg > CbC > CbC_llvm
diff tools/bugpoint/ToolRunner.cpp @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 803732b1fca8 |
children |
line wrap: on
line diff
--- a/tools/bugpoint/ToolRunner.cpp Sat Feb 17 09:57:20 2018 +0900 +++ b/tools/bugpoint/ToolRunner.cpp Wed Aug 14 16:55:33 2019 +0900 @@ -1,9 +1,8 @@ //===-- ToolRunner.cpp ----------------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -53,13 +52,14 @@ /// RunProgramWithTimeout - This function provides an alternate interface /// to the sys::Program::ExecuteAndWait interface. /// @see sys::Program::ExecuteAndWait -static int RunProgramWithTimeout(StringRef ProgramPath, const char **Args, - StringRef StdInFile, StringRef StdOutFile, - StringRef StdErrFile, unsigned NumSeconds = 0, +static int RunProgramWithTimeout(StringRef ProgramPath, + ArrayRef<StringRef> Args, StringRef StdInFile, + StringRef StdOutFile, StringRef StdErrFile, + unsigned NumSeconds = 0, unsigned MemoryLimit = 0, std::string *ErrMsg = nullptr) { Optional<StringRef> Redirects[3] = {StdInFile, StdOutFile, StdErrFile}; - return sys::ExecuteAndWait(ProgramPath, Args, nullptr, Redirects, NumSeconds, + return sys::ExecuteAndWait(ProgramPath, Args, None, Redirects, NumSeconds, MemoryLimit, ErrMsg); } @@ -69,24 +69,22 @@ /// fails. Remote client is required to return 255 if it failed or program exit /// code otherwise. /// @see sys::Program::ExecuteAndWait -static int RunProgramRemotelyWithTimeout(StringRef RemoteClientPath, - const char **Args, StringRef StdInFile, - StringRef StdOutFile, - StringRef StdErrFile, - unsigned NumSeconds = 0, - unsigned MemoryLimit = 0) { +static int RunProgramRemotelyWithTimeout( + StringRef RemoteClientPath, ArrayRef<StringRef> Args, StringRef StdInFile, + StringRef StdOutFile, StringRef StdErrFile, unsigned NumSeconds = 0, + unsigned MemoryLimit = 0) { Optional<StringRef> Redirects[3] = {StdInFile, StdOutFile, StdErrFile}; // Run the program remotely with the remote client - int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, nullptr, - Redirects, NumSeconds, MemoryLimit); + int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, None, Redirects, + NumSeconds, MemoryLimit); // Has the remote client fail? if (255 == ReturnCode) { std::ostringstream OS; OS << "\nError running remote client:\n "; - for (const char **Arg = Args; *Arg; ++Arg) - OS << " " << *Arg; + for (StringRef Arg : Args) + OS << " " << Arg.str(); OS << "\n"; // The error message is in the output file, let's print it out from there. @@ -105,12 +103,12 @@ return ReturnCode; } -static Error ProcessFailure(StringRef ProgPath, const char **Args, +static Error ProcessFailure(StringRef ProgPath, ArrayRef<StringRef> Args, unsigned Timeout = 0, unsigned MemoryLimit = 0) { std::ostringstream OS; OS << "\nError running tool:\n "; - for (const char **Arg = Args; *Arg; ++Arg) - OS << " " << *Arg; + for (StringRef Arg : Args) + OS << " " << Arg.str(); OS << "\n"; // Rerun the compiler, capturing any error messages to print them. @@ -171,7 +169,7 @@ const std::vector<std::string> &CCArgs, const std::vector<std::string> &SharedLibs, unsigned Timeout, unsigned MemoryLimit) { - std::vector<const char *> LLIArgs; + std::vector<StringRef> LLIArgs; LLIArgs.push_back(LLIPath.c_str()); LLIArgs.push_back("-force-interpreter=true"); @@ -179,44 +177,31 @@ e = SharedLibs.end(); i != e; ++i) { LLIArgs.push_back("-load"); - LLIArgs.push_back((*i).c_str()); + LLIArgs.push_back(*i); } // Add any extra LLI args. for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) - LLIArgs.push_back(ToolArgs[i].c_str()); + LLIArgs.push_back(ToolArgs[i]); - LLIArgs.push_back(Bitcode.c_str()); + LLIArgs.push_back(Bitcode); // Add optional parameters to the running program from Argv for (unsigned i = 0, e = Args.size(); i != e; ++i) - LLIArgs.push_back(Args[i].c_str()); - LLIArgs.push_back(nullptr); + LLIArgs.push_back(Args[i]); outs() << "<lli>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = LLIArgs.size() - 1; i != e; ++i) errs() - << " " << LLIArgs[i]; - errs() << "\n";); - return RunProgramWithTimeout(LLIPath, &LLIArgs[0], InputFile, OutputFile, + LLVM_DEBUG(errs() << "\nAbout to run:\t"; + for (unsigned i = 0, e = LLIArgs.size() - 1; i != e; ++i) errs() + << " " << LLIArgs[i]; + errs() << "\n";); + return RunProgramWithTimeout(LLIPath, LLIArgs, InputFile, OutputFile, OutputFile, Timeout, MemoryLimit); } void AbstractInterpreter::anchor() {} -#if defined(LLVM_ON_UNIX) -const char EXESuffix[] = ""; -#elif defined(LLVM_ON_WIN32) -const char EXESuffix[] = "exe"; -#endif - -/// Prepend the path to the program being executed -/// to \p ExeName, given the value of argv[0] and the address of main() -/// itself. This allows us to find another LLVM tool if it is built in the same -/// directory. An empty string is returned on error; note that this function -/// just mainpulates the path and doesn't check for executability. -/// @brief Find a named executable. -static std::string PrependMainExecutablePath(const std::string &ExeName, +ErrorOr<std::string> llvm::FindProgramByName(const std::string &ExeName, const char *Argv0, void *MainAddr) { // Check the directory that the calling program is in. We can do @@ -224,30 +209,25 @@ // is a relative path to the executable itself. std::string Main = sys::fs::getMainExecutable(Argv0, MainAddr); StringRef Result = sys::path::parent_path(Main); + if (ErrorOr<std::string> Path = sys::findProgramByName(ExeName, Result)) + return *Path; - if (!Result.empty()) { - SmallString<128> Storage = Result; - sys::path::append(Storage, ExeName); - sys::path::replace_extension(Storage, EXESuffix); - return Storage.str(); - } - - return Result.str(); + // Check the user PATH. + return sys::findProgramByName(ExeName); } // LLI create method - Try to find the LLI executable AbstractInterpreter * AbstractInterpreter::createLLI(const char *Argv0, std::string &Message, const std::vector<std::string> *ToolArgs) { - std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI); - if (!LLIPath.empty()) { - Message = "Found lli: " + LLIPath + "\n"; - return new LLI(LLIPath, ToolArgs); + if (ErrorOr<std::string> LLIPath = + FindProgramByName("lli", Argv0, (void *)(intptr_t)&createLLI)) { + Message = "Found lli: " + *LLIPath + "\n"; + return new LLI(*LLIPath, ToolArgs); + } else { + Message = LLIPath.getError().message() + "\n"; + return nullptr; } - - Message = "Cannot find `lli' in executable directory!\n"; - return nullptr; } //===---------------------------------------------------------------------===// @@ -285,22 +265,20 @@ Error CustomCompiler::compileProgram(const std::string &Bitcode, unsigned Timeout, unsigned MemoryLimit) { - std::vector<const char *> ProgramArgs; + std::vector<StringRef> 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(nullptr); + ProgramArgs.push_back(Bitcode); // 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(CompilerCommand, &ProgramArgs[0], "", "", "", - Timeout, MemoryLimit)) - return ProcessFailure(CompilerCommand, &ProgramArgs[0], Timeout, - MemoryLimit); + if (RunProgramWithTimeout(CompilerCommand, ProgramArgs, "", "", "", Timeout, + MemoryLimit)) + return ProcessFailure(CompilerCommand, ProgramArgs, Timeout, MemoryLimit); return Error::success(); } @@ -336,19 +314,18 @@ const std::vector<std::string> &SharedLibs, unsigned Timeout, unsigned MemoryLimit) { - std::vector<const char *> ProgramArgs; - ProgramArgs.push_back(ExecutionCommand.c_str()); + std::vector<StringRef> ProgramArgs; + ProgramArgs.push_back(ExecutionCommand); for (std::size_t i = 0; i < ExecutorArgs.size(); ++i) - ProgramArgs.push_back(ExecutorArgs.at(i).c_str()); - ProgramArgs.push_back(Bitcode.c_str()); - ProgramArgs.push_back(nullptr); + ProgramArgs.push_back(ExecutorArgs[i]); + ProgramArgs.push_back(Bitcode); // Add optional parameters to the running program from Argv for (unsigned i = 0, e = Args.size(); i != e; ++i) - ProgramArgs.push_back(Args[i].c_str()); + ProgramArgs.push_back(Args[i]); - return RunProgramWithTimeout(ExecutionCommand, &ProgramArgs[0], InputFile, + return RunProgramWithTimeout(ExecutionCommand, ProgramArgs, InputFile, OutputFile, OutputFile, Timeout, MemoryLimit); } @@ -373,8 +350,9 @@ // '\ ' -> ' ' // 'exa\mple' -> 'example' // -static void lexCommand(std::string &Message, const std::string &CommandLine, - std::string &CmdPath, std::vector<std::string> &Args) { +static void lexCommand(const char *Argv0, std::string &Message, + const std::string &CommandLine, std::string &CmdPath, + std::vector<std::string> &Args) { std::string Token; std::string Command; @@ -407,7 +385,7 @@ Token.push_back(CommandLine[Pos]); } - auto Path = sys::findProgramByName(Command); + auto Path = FindProgramByName(Command, Argv0, (void *)(intptr_t)&lexCommand); if (!Path) { Message = std::string("Cannot find '") + Command + "' in PATH: " + Path.getError().message() + "\n"; @@ -421,11 +399,12 @@ // Custom execution environment create method, takes the execution command // as arguments AbstractInterpreter *AbstractInterpreter::createCustomCompiler( - std::string &Message, const std::string &CompileCommandLine) { + const char *Argv0, std::string &Message, + const std::string &CompileCommandLine) { std::string CmdPath; std::vector<std::string> Args; - lexCommand(Message, CompileCommandLine, CmdPath, Args); + lexCommand(Argv0, Message, CompileCommandLine, CmdPath, Args); if (CmdPath.empty()) return nullptr; @@ -435,12 +414,13 @@ // Custom execution environment create method, takes the execution command // as arguments AbstractInterpreter * -AbstractInterpreter::createCustomExecutor(std::string &Message, +AbstractInterpreter::createCustomExecutor(const char *Argv0, + std::string &Message, const std::string &ExecCommandLine) { std::string CmdPath; std::vector<std::string> Args; - lexCommand(Message, ExecCommandLine, CmdPath, Args); + lexCommand(Argv0, Message, ExecCommandLine, CmdPath, Args); if (CmdPath.empty()) return nullptr; @@ -463,31 +443,28 @@ exit(1); } OutputAsmFile = UniqueFile.str(); - std::vector<const char *> LLCArgs; - LLCArgs.push_back(LLCPath.c_str()); + std::vector<StringRef> LLCArgs; + LLCArgs.push_back(LLCPath); // Add any extra LLC args. for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) - LLCArgs.push_back(ToolArgs[i].c_str()); + LLCArgs.push_back(ToolArgs[i]); LLCArgs.push_back("-o"); - LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file - LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode + LLCArgs.push_back(OutputAsmFile); // Output to the Asm file + LLCArgs.push_back(Bitcode); // This is the input bitcode if (UseIntegratedAssembler) LLCArgs.push_back("-filetype=obj"); - LLCArgs.push_back(nullptr); - outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>"); outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = LLCArgs.size() - 1; i != e; ++i) errs() - << " " << LLCArgs[i]; - errs() << "\n";); - if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], "", "", "", Timeout, - MemoryLimit)) - return ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); + LLVM_DEBUG(errs() << "\nAbout to run:\t"; + for (unsigned i = 0, e = LLCArgs.size() - 1; i != e; ++i) errs() + << " " << LLCArgs[i]; + errs() << "\n";); + if (RunProgramWithTimeout(LLCPath, LLCArgs, "", "", "", Timeout, MemoryLimit)) + return ProcessFailure(LLCPath, LLCArgs, Timeout, MemoryLimit); return UseIntegratedAssembler ? CC::ObjectFile : CC::AsmFile; } @@ -532,20 +509,20 @@ const std::vector<std::string> *Args, const std::vector<std::string> *CCArgs, bool UseIntegratedAssembler) { - std::string LLCPath = - PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC); - if (LLCPath.empty()) { - Message = "Cannot find `llc' in executable directory!\n"; + ErrorOr<std::string> LLCPath = + FindProgramByName("llc", Argv0, (void *)(intptr_t)&createLLC); + if (!LLCPath) { + Message = LLCPath.getError().message() + "\n"; return nullptr; } - CC *cc = CC::create(Message, CCBinary, CCArgs); + CC *cc = CC::create(Argv0, Message, CCBinary, CCArgs); if (!cc) { errs() << Message << "\n"; exit(1); } - Message = "Found llc: " + LLCPath + "\n"; - return new LLC(LLCPath, cc, Args, UseIntegratedAssembler); + Message = "Found llc: " + *LLCPath + "\n"; + return new LLC(*LLCPath, cc, Args, UseIntegratedAssembler); } //===---------------------------------------------------------------------===// @@ -581,32 +558,31 @@ const std::vector<std::string> &SharedLibs, unsigned Timeout, unsigned MemoryLimit) { // Construct a vector of parameters, incorporating those from the command-line - std::vector<const char *> JITArgs; + std::vector<StringRef> JITArgs; JITArgs.push_back(LLIPath.c_str()); JITArgs.push_back("-force-interpreter=false"); // Add any extra LLI args. for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) - JITArgs.push_back(ToolArgs[i].c_str()); + JITArgs.push_back(ToolArgs[i]); for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) { JITArgs.push_back("-load"); - JITArgs.push_back(SharedLibs[i].c_str()); + JITArgs.push_back(SharedLibs[i]); } JITArgs.push_back(Bitcode.c_str()); // Add optional parameters to the running program from Argv for (unsigned i = 0, e = Args.size(); i != e; ++i) - JITArgs.push_back(Args[i].c_str()); - JITArgs.push_back(nullptr); + JITArgs.push_back(Args[i]); outs() << "<jit>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = JITArgs.size() - 1; i != e; ++i) errs() - << " " << JITArgs[i]; - errs() << "\n";); - DEBUG(errs() << "\nSending output to " << OutputFile << "\n"); - return RunProgramWithTimeout(LLIPath, &JITArgs[0], InputFile, OutputFile, + LLVM_DEBUG(errs() << "\nAbout to run:\t"; + for (unsigned i = 0, e = JITArgs.size() - 1; i != e; ++i) errs() + << " " << JITArgs[i]; + errs() << "\n";); + LLVM_DEBUG(errs() << "\nSending output to " << OutputFile << "\n"); + return RunProgramWithTimeout(LLIPath, JITArgs, InputFile, OutputFile, OutputFile, Timeout, MemoryLimit); } @@ -615,30 +591,29 @@ AbstractInterpreter * AbstractInterpreter::createJIT(const char *Argv0, std::string &Message, const std::vector<std::string> *Args) { - std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT); - if (!LLIPath.empty()) { - Message = "Found lli: " + LLIPath + "\n"; - return new JIT(LLIPath, Args); + if (ErrorOr<std::string> LLIPath = + FindProgramByName("lli", Argv0, (void *)(intptr_t)&createJIT)) { + Message = "Found lli: " + *LLIPath + "\n"; + return new JIT(*LLIPath, Args); + } else { + Message = LLIPath.getError().message() + "\n"; + return nullptr; } - - Message = "Cannot find `lli' in executable directory!\n"; - return nullptr; } //===---------------------------------------------------------------------===// // CC abstraction // -static bool IsARMArchitecture(std::vector<const char *> Args) { - for (std::vector<const char *>::const_iterator I = Args.begin(), - E = Args.end(); - I != E; ++I) { - if (StringRef(*I).equals_lower("-arch")) { - ++I; - if (I != E && StringRef(*I).startswith_lower("arm")) - return true; - } +static bool IsARMArchitecture(std::vector<StringRef> Args) { + for (size_t I = 0; I < Args.size(); ++I) { + if (!Args[I].equals_lower("-arch")) + continue; + ++I; + if (I == Args.size()) + break; + if (Args[I].startswith_lower("arm")) + return true; } return false; @@ -651,9 +626,9 @@ const std::string &OutputFile, const std::vector<std::string> &ArgsForCC, unsigned Timeout, unsigned MemoryLimit) { - std::vector<const char *> CCArgs; + std::vector<StringRef> CCArgs; - CCArgs.push_back(CCPath.c_str()); + CCArgs.push_back(CCPath); if (TargetTriple.getArch() == Triple::x86) CCArgs.push_back("-m32"); @@ -661,7 +636,7 @@ for (std::vector<std::string>::const_iterator I = ccArgs.begin(), E = ccArgs.end(); I != E; ++I) - CCArgs.push_back(I->c_str()); + CCArgs.push_back(*I); // Specify -x explicitly in case the extension is wonky if (fileType != ObjectFile) { @@ -680,7 +655,7 @@ } } - CCArgs.push_back(ProgramFile.c_str()); // Specify the input filename. + CCArgs.push_back(ProgramFile); // Specify the input filename. CCArgs.push_back("-x"); CCArgs.push_back("none"); @@ -693,51 +668,50 @@ errs() << "Error making unique filename: " << EC.message() << "\n"; exit(1); } - CCArgs.push_back(OutputBinary.c_str()); // Output to the right file... + CCArgs.push_back(OutputBinary); // Output to the right file... // Add any arguments intended for CC. We locate them here because this is // most likely -L and -l options that need to come before other libraries but // after the source. Other options won't be sensitive to placement on the // command line, so this should be safe. for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i) - CCArgs.push_back(ArgsForCC[i].c_str()); + CCArgs.push_back(ArgsForCC[i]); CCArgs.push_back("-lm"); // Hard-code the math library... CCArgs.push_back("-O2"); // Optimize the program a bit... if (TargetTriple.getArch() == Triple::sparc) CCArgs.push_back("-mcpu=v9"); - CCArgs.push_back(nullptr); // NULL terminator outs() << "<CC>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() - << " " << CCArgs[i]; - errs() << "\n";); - if (RunProgramWithTimeout(CCPath, &CCArgs[0], "", "", "")) - return ProcessFailure(CCPath, &CCArgs[0]); + LLVM_DEBUG(errs() << "\nAbout to run:\t"; + for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() + << " " << CCArgs[i]; + errs() << "\n";); + if (RunProgramWithTimeout(CCPath, CCArgs, "", "", "")) + return ProcessFailure(CCPath, CCArgs); - std::vector<const char *> ProgramArgs; + std::vector<StringRef> ProgramArgs; // Declared here so that the destructor only runs after // ProgramArgs is used. std::string Exec; if (RemoteClientPath.empty()) - ProgramArgs.push_back(OutputBinary.c_str()); + ProgramArgs.push_back(OutputBinary); else { - ProgramArgs.push_back(RemoteClientPath.c_str()); - ProgramArgs.push_back(RemoteHost.c_str()); + ProgramArgs.push_back(RemoteClientPath); + ProgramArgs.push_back(RemoteHost); if (!RemoteUser.empty()) { ProgramArgs.push_back("-l"); - ProgramArgs.push_back(RemoteUser.c_str()); + ProgramArgs.push_back(RemoteUser); } if (!RemotePort.empty()) { ProgramArgs.push_back("-p"); - ProgramArgs.push_back(RemotePort.c_str()); + ProgramArgs.push_back(RemotePort); } if (!RemoteExtra.empty()) { - ProgramArgs.push_back(RemoteExtra.c_str()); + ProgramArgs.push_back(RemoteExtra); } // Full path to the binary. We need to cd to the exec directory because @@ -747,28 +721,28 @@ Exec += env_pwd; Exec += "; ./"; Exec += OutputBinary.c_str(); - ProgramArgs.push_back(Exec.c_str()); + ProgramArgs.push_back(Exec); } // Add optional parameters to the running program from Argv for (unsigned i = 0, e = Args.size(); i != e; ++i) - ProgramArgs.push_back(Args[i].c_str()); - ProgramArgs.push_back(nullptr); // NULL terminator + ProgramArgs.push_back(Args[i]); // Now that we have a binary, run it! outs() << "<program>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = ProgramArgs.size() - 1; i != e; ++i) errs() - << " " << ProgramArgs[i]; - errs() << "\n";); + LLVM_DEBUG( + errs() << "\nAbout to run:\t"; + for (unsigned i = 0, e = ProgramArgs.size() - 1; i != e; ++i) errs() + << " " << ProgramArgs[i]; + errs() << "\n";); FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps); if (RemoteClientPath.empty()) { - DEBUG(errs() << "<run locally>"); + LLVM_DEBUG(errs() << "<run locally>"); std::string Error; - int ExitCode = RunProgramWithTimeout(OutputBinary.str(), &ProgramArgs[0], + int ExitCode = RunProgramWithTimeout(OutputBinary.str(), ProgramArgs, InputFile, OutputFile, OutputFile, Timeout, MemoryLimit, &Error); // Treat a signal (usually SIGSEGV) or timeout as part of the program output @@ -782,7 +756,7 @@ } else { outs() << "<run remotely>"; outs().flush(); - return RunProgramRemotelyWithTimeout(RemoteClientPath, &ProgramArgs[0], + return RunProgramRemotelyWithTimeout(RemoteClientPath, ProgramArgs, InputFile, OutputFile, OutputFile, Timeout, MemoryLimit); } @@ -800,9 +774,9 @@ } OutputFile = UniqueFilename.str(); - std::vector<const char *> CCArgs; + std::vector<StringRef> CCArgs; - CCArgs.push_back(CCPath.c_str()); + CCArgs.push_back(CCPath); if (TargetTriple.getArch() == Triple::x86) CCArgs.push_back("-m32"); @@ -810,7 +784,7 @@ for (std::vector<std::string>::const_iterator I = ccArgs.begin(), E = ccArgs.end(); I != E; ++I) - CCArgs.push_back(I->c_str()); + CCArgs.push_back(*I); // Compile the C/asm file into a shared object if (fileType != ObjectFile) { @@ -818,7 +792,7 @@ CCArgs.push_back(fileType == AsmFile ? "assembler" : "c"); } CCArgs.push_back("-fno-strict-aliasing"); - CCArgs.push_back(InputFile.c_str()); // Specify the input filename. + CCArgs.push_back(InputFile); // Specify the input filename. CCArgs.push_back("-x"); CCArgs.push_back("none"); if (TargetTriple.getArch() == Triple::sparc) @@ -842,7 +816,7 @@ CCArgs.push_back("-mcpu=v9"); CCArgs.push_back("-o"); - CCArgs.push_back(OutputFile.c_str()); // Output to the right filename. + CCArgs.push_back(OutputFile); // Output to the right filename. CCArgs.push_back("-O2"); // Optimize the program a bit. // Add any arguments intended for CC. We locate them here because this is @@ -850,25 +824,25 @@ // after the source. Other options won't be sensitive to placement on the // command line, so this should be safe. for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i) - CCArgs.push_back(ArgsForCC[i].c_str()); - CCArgs.push_back(nullptr); // NULL terminator + CCArgs.push_back(ArgsForCC[i]); outs() << "<CC>"; outs().flush(); - DEBUG(errs() << "\nAbout to run:\t"; - for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() - << " " << CCArgs[i]; - errs() << "\n";); - if (RunProgramWithTimeout(CCPath, &CCArgs[0], "", "", "")) - return ProcessFailure(CCPath, &CCArgs[0]); + LLVM_DEBUG(errs() << "\nAbout to run:\t"; + for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() + << " " << CCArgs[i]; + errs() << "\n";); + if (RunProgramWithTimeout(CCPath, CCArgs, "", "", "")) + return ProcessFailure(CCPath, CCArgs); return Error::success(); } /// create - Try to find the CC executable /// -CC *CC::create(std::string &Message, const std::string &CCBinary, +CC *CC::create(const char *Argv0, std::string &Message, + const std::string &CCBinary, const std::vector<std::string> *Args) { - auto CCPath = sys::findProgramByName(CCBinary); + auto CCPath = FindProgramByName(CCBinary, Argv0, (void *)(intptr_t)&create); if (!CCPath) { Message = "Cannot find `" + CCBinary + "' in PATH: " + CCPath.getError().message() + "\n";