summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Driver/Job.cpp14
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp4
-rw-r--r--clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp23
-rw-r--r--lld/COFF/DriverUtils.cpp7
-rw-r--r--lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp5
-rw-r--r--lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp5
-rw-r--r--llvm/include/llvm/ADT/StringExtras.h10
-rw-r--r--llvm/include/llvm/Support/Program.h15
-rw-r--r--llvm/lib/Support/GraphWriter.cpp64
-rw-r--r--llvm/lib/Support/Program.cpp16
-rw-r--r--llvm/lib/Support/Signals.cpp17
-rw-r--r--llvm/lib/Support/Unix/Program.inc35
-rw-r--r--llvm/lib/Support/Windows/Program.inc21
-rw-r--r--llvm/tools/bugpoint/OptimizerDriver.cpp15
-rw-r--r--llvm/tools/bugpoint/ToolRunner.cpp174
-rw-r--r--llvm/tools/dsymutil/MachOUtils.cpp15
-rw-r--r--llvm/tools/llvm-cov/CodeCoverage.cpp11
-rw-r--r--llvm/unittests/Support/Host.cpp4
-rw-r--r--llvm/unittests/Support/ProgramTest.cpp60
-rw-r--r--llvm/utils/not/not.cpp6
20 files changed, 254 insertions, 267 deletions
diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp
index 71cda621043..74af597ad36 100644
--- a/clang/lib/Driver/Job.cpp
+++ b/clang/lib/Driver/Job.cpp
@@ -317,13 +317,11 @@ int Command::Execute(ArrayRef<llvm::Optional<StringRef>> Redirects,
std::string *ErrMsg, bool *ExecutionFailed) const {
SmallVector<const char*, 128> Argv;
- const char **Envp;
- if (Environment.empty()) {
- Envp = nullptr;
- } else {
+ Optional<ArrayRef<StringRef>> Env;
+ if (!Environment.empty()) {
assert(Environment.back() == nullptr &&
"Environment vector should be null-terminated by now");
- Envp = const_cast<const char **>(Environment.data());
+ Env = llvm::toStringRefArray(Environment.data());
}
if (ResponseFile == nullptr) {
@@ -331,8 +329,9 @@ int Command::Execute(ArrayRef<llvm::Optional<StringRef>> Redirects,
Argv.append(Arguments.begin(), Arguments.end());
Argv.push_back(nullptr);
+ auto Args = llvm::toStringRefArray(Argv.data());
return llvm::sys::ExecuteAndWait(
- Executable, Argv.data(), Envp, Redirects, /*secondsToWait*/ 0,
+ Executable, Args, Env, Redirects, /*secondsToWait*/ 0,
/*memoryLimit*/ 0, ErrMsg, ExecutionFailed);
}
@@ -357,7 +356,8 @@ int Command::Execute(ArrayRef<llvm::Optional<StringRef>> Redirects,
return -1;
}
- return llvm::sys::ExecuteAndWait(Executable, Argv.data(), Envp, Redirects,
+ auto Args = llvm::toStringRefArray(Argv.data());
+ return llvm::sys::ExecuteAndWait(Executable, Args, Env, Redirects,
/*secondsToWait*/ 0,
/*memoryLimit*/ 0, ErrMsg, ExecutionFailed);
}
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 9c5e04cc3c5..3d86945a55c 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -883,9 +883,9 @@ UbigraphViz::~UbigraphViz() {
std::string Ubiviz;
if (auto Path = llvm::sys::findProgramByName("ubiviz"))
Ubiviz = *Path;
- const char *args[] = {Ubiviz.c_str(), Filename.c_str(), nullptr};
+ std::array<StringRef, 2> Args = {Ubiviz, Filename};
- if (llvm::sys::ExecuteAndWait(Ubiviz, &args[0], nullptr, {}, 0, 0, &ErrMsg)) {
+ if (llvm::sys::ExecuteAndWait(Ubiviz, Args, llvm::None, {}, 0, 0, &ErrMsg)) {
llvm::errs() << "Error viewing graph: " << ErrMsg << "\n";
}
diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index d9fb3898b51..29cd9848d11 100644
--- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -536,23 +536,22 @@ public:
// close it and use the name to pass down to clang.
OS.close();
SmallString<128> TargetName = getTriple(TargetNames[HostInputIndex]);
- const char *ClangArgs[] = {"clang",
- "-r",
- "-target",
- TargetName.c_str(),
- "-o",
- OutputFileNames.front().c_str(),
- InputFileNames[HostInputIndex].c_str(),
- BitcodeFileName.c_str(),
- "-nostdlib",
- nullptr};
+ std::vector<StringRef> ClangArgs = {"clang",
+ "-r",
+ "-target",
+ TargetName.c_str(),
+ "-o",
+ OutputFileNames.front().c_str(),
+ InputFileNames[HostInputIndex].c_str(),
+ BitcodeFileName.c_str(),
+ "-nostdlib"};
// If the user asked for the commands to be printed out, we do that instead
// of executing it.
if (PrintExternalCommands) {
errs() << "\"" << ClangBinary.get() << "\"";
- for (unsigned I = 1; ClangArgs[I]; ++I)
- errs() << " \"" << ClangArgs[I] << "\"";
+ for (StringRef Arg : ClangArgs)
+ errs() << " \"" << Arg << "\"";
errs() << "\n";
} else {
// Write the bitcode contents to the temporary file.
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index 98751193f26..d534d858efe 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -61,12 +61,7 @@ public:
StringRef Exe = Saver.save(*ExeOrErr);
Args.insert(Args.begin(), Exe);
- std::vector<const char *> Vec;
- for (StringRef S : Args)
- Vec.push_back(S.data());
- Vec.push_back(nullptr);
-
- if (sys::ExecuteAndWait(Args[0], Vec.data()) != 0)
+ if (sys::ExecuteAndWait(Args[0], Args) != 0)
fatal("ExecuteAndWait failed: " +
llvm::join(Args.begin(), Args.end(), " "));
}
diff --git a/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp b/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
index bec46bb037e..9051ddfd01a 100644
--- a/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
+++ b/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
@@ -61,11 +61,12 @@ TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {
"sections-resolve-consistently-%%%%%%", "obj", obj));
llvm::FileRemover remover(obj);
- const char *args[] = {YAML2OBJ, yaml.c_str(), nullptr};
+ llvm::StringRef args[] = {YAML2OBJ, yaml};
llvm::StringRef obj_ref = obj;
const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, obj_ref,
llvm::None};
- ASSERT_EQ(0, llvm::sys::ExecuteAndWait(YAML2OBJ, args, nullptr, redirects));
+ ASSERT_EQ(0,
+ llvm::sys::ExecuteAndWait(YAML2OBJ, args, llvm::None, redirects));
uint64_t size;
ASSERT_NO_ERROR(llvm::sys::fs::file_size(obj, size));
ASSERT_GT(size, 0u);
diff --git a/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp b/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
index 85cb4a72b95..c8d560f03de 100644
--- a/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
+++ b/lldb/unittests/Symbol/TestDWARFCallFrameInfo.cpp
@@ -96,11 +96,12 @@ void DWARFCallFrameInfoTest::TestBasic(DWARFCallFrameInfo::Type type,
"basic-call-frame-info-%%%%%%", "obj", obj));
llvm::FileRemover obj_remover(obj);
- const char *args[] = {YAML2OBJ, yaml.c_str(), nullptr};
+ llvm::StringRef args[] = {YAML2OBJ, yaml};
llvm::StringRef obj_ref = obj;
const llvm::Optional<llvm::StringRef> redirects[] = {llvm::None, obj_ref,
llvm::None};
- ASSERT_EQ(0, llvm::sys::ExecuteAndWait(YAML2OBJ, args, nullptr, redirects));
+ ASSERT_EQ(0,
+ llvm::sys::ExecuteAndWait(YAML2OBJ, args, llvm::None, redirects));
uint64_t size;
ASSERT_NO_ERROR(llvm::sys::fs::file_size(obj, size));
diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h
index 21a1bbcfad2..12a685cec8a 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/include/llvm/ADT/StringExtras.h
@@ -39,6 +39,16 @@ inline char hexdigit(unsigned X, bool LowerCase = false) {
return X < 10 ? '0' + X : HexChar + X - 10;
}
+/// Given an array of c-style strings terminated by a null pointer, construct
+/// a vector of StringRefs representing the same strings without the terminating
+/// null string.
+inline std::vector<StringRef> toStringRefArray(const char *const *Strings) {
+ std::vector<StringRef> Result;
+ while (*Strings)
+ Result.push_back(*Strings++);
+ return Result;
+}
+
/// Construct a string ref from a boolean.
inline StringRef toStringRef(bool B) { return StringRef(B ? "true" : "false"); }
diff --git a/llvm/include/llvm/Support/Program.h b/llvm/include/llvm/Support/Program.h
index e64bfb2948a..1f4dbdce332 100644
--- a/llvm/include/llvm/Support/Program.h
+++ b/llvm/include/llvm/Support/Program.h
@@ -89,12 +89,13 @@ namespace sys {
int ExecuteAndWait(
StringRef Program, ///< Path of the program to be executed. It is
///< presumed this is the result of the findProgramByName method.
- const char **Args, ///< A vector of strings that are passed to the
+ ArrayRef<StringRef> Args, ///< An array of strings that are passed to the
///< program. The first element should be the name of the program.
- ///< The list *must* be terminated by a null char* entry.
- const char **Env = nullptr, ///< An optional vector of strings to use for
- ///< the program's environment. If not provided, the current program's
- ///< environment will be used.
+ ///< The array should **not** be terminated by an empty StringRef.
+ Optional<ArrayRef<StringRef>> Env = None, ///< An optional vector of
+ ///< strings to use for the program's environment. If not provided, the
+ ///< current program's environment will be used. If specified, the
+ ///< vector should **not** be terminated by an empty StringRef.
ArrayRef<Optional<StringRef>> Redirects = {}, ///<
///< An array of optional paths. Should have a size of zero or three.
///< If the array is empty, no redirections are performed.
@@ -123,8 +124,8 @@ namespace sys {
/// \note On Microsoft Windows systems, users will need to either call
/// \see Wait until the process finished execution or win32 CloseHandle() API
/// on ProcessInfo.ProcessHandle to avoid memory leaks.
- ProcessInfo ExecuteNoWait(StringRef Program, const char **Args,
- const char **Env = nullptr,
+ ProcessInfo ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
+ Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects = {},
unsigned MemoryLimit = 0,
std::string *ErrMsg = nullptr,
diff --git a/llvm/lib/Support/GraphWriter.cpp b/llvm/lib/Support/GraphWriter.cpp
index 794c6ba3a85..9335daffc3e 100644
--- a/llvm/lib/Support/GraphWriter.cpp
+++ b/llvm/lib/Support/GraphWriter.cpp
@@ -91,20 +91,18 @@ std::string llvm::createGraphFilename(const Twine &Name, int &FD) {
}
// Execute the graph viewer. Return true if there were errors.
-static bool ExecGraphViewer(StringRef ExecPath, std::vector<const char *> &args,
+static bool ExecGraphViewer(StringRef ExecPath, std::vector<StringRef> &args,
StringRef Filename, bool wait,
std::string &ErrMsg) {
- assert(args.back() == nullptr);
if (wait) {
- if (sys::ExecuteAndWait(ExecPath, args.data(), nullptr, {}, 0, 0,
- &ErrMsg)) {
+ if (sys::ExecuteAndWait(ExecPath, args, None, {}, 0, 0, &ErrMsg)) {
errs() << "Error: " << ErrMsg << "\n";
return true;
}
sys::fs::remove(Filename);
errs() << " done. \n";
} else {
- sys::ExecuteNoWait(ExecPath, args.data(), nullptr, {}, 0, &ErrMsg);
+ sys::ExecuteNoWait(ExecPath, args, None, {}, 0, &ErrMsg);
errs() << "Remember to erase graph file: " << Filename << "\n";
}
return false;
@@ -158,22 +156,20 @@ bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
#ifdef __APPLE__
wait &= !ViewBackground;
if (S.TryFindProgram("open", ViewerPath)) {
- std::vector<const char *> args;
- args.push_back(ViewerPath.c_str());
+ std::vector<StringRef> args;
+ args.push_back(ViewerPath);
if (wait)
args.push_back("-W");
- args.push_back(Filename.c_str());
- args.push_back(nullptr);
+ args.push_back(Filename);
errs() << "Trying 'open' program... ";
if (!ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg))
return false;
}
#endif
if (S.TryFindProgram("xdg-open", ViewerPath)) {
- std::vector<const char *> args;
- args.push_back(ViewerPath.c_str());
- args.push_back(Filename.c_str());
- args.push_back(nullptr);
+ std::vector<StringRef> args;
+ args.push_back(ViewerPath);
+ args.push_back(Filename);
errs() << "Trying 'xdg-open' program... ";
if (!ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg))
return false;
@@ -181,10 +177,9 @@ bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
// Graphviz
if (S.TryFindProgram("Graphviz", ViewerPath)) {
- std::vector<const char *> args;
- args.push_back(ViewerPath.c_str());
- args.push_back(Filename.c_str());
- args.push_back(nullptr);
+ std::vector<StringRef> args;
+ args.push_back(ViewerPath);
+ args.push_back(Filename);
errs() << "Running 'Graphviz' program... ";
return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg);
@@ -192,15 +187,13 @@ bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
// xdot
if (S.TryFindProgram("xdot|xdot.py", ViewerPath)) {
- std::vector<const char *> args;
- args.push_back(ViewerPath.c_str());
- args.push_back(Filename.c_str());
+ std::vector<StringRef> args;
+ args.push_back(ViewerPath);
+ args.push_back(Filename);
args.push_back("-f");
args.push_back(getProgramName(program));
- args.push_back(nullptr);
-
errs() << "Running 'xdot.py' program... ";
return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg);
}
@@ -235,18 +228,17 @@ bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
std::string OutputFilename =
Filename + (Viewer == VK_CmdStart ? ".pdf" : ".ps");
- std::vector<const char *> args;
- args.push_back(GeneratorPath.c_str());
+ std::vector<StringRef> args;
+ args.push_back(GeneratorPath);
if (Viewer == VK_CmdStart)
args.push_back("-Tpdf");
else
args.push_back("-Tps");
args.push_back("-Nfontname=Courier");
args.push_back("-Gsize=7.5,10");
- args.push_back(Filename.c_str());
+ args.push_back(Filename);
args.push_back("-o");
- args.push_back(OutputFilename.c_str());
- args.push_back(nullptr);
+ args.push_back(OutputFilename);
errs() << "Running '" << GeneratorPath << "' program... ";
@@ -258,31 +250,30 @@ bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
std::string StartArg;
args.clear();
- args.push_back(ViewerPath.c_str());
+ args.push_back(ViewerPath);
switch (Viewer) {
case VK_OSXOpen:
args.push_back("-W");
- args.push_back(OutputFilename.c_str());
+ args.push_back(OutputFilename);
break;
case VK_XDGOpen:
wait = false;
- args.push_back(OutputFilename.c_str());
+ args.push_back(OutputFilename);
break;
case VK_Ghostview:
args.push_back("--spartan");
- args.push_back(OutputFilename.c_str());
+ args.push_back(OutputFilename);
break;
case VK_CmdStart:
args.push_back("/S");
args.push_back("/C");
StartArg =
(StringRef("start ") + (wait ? "/WAIT " : "") + OutputFilename).str();
- args.push_back(StartArg.c_str());
+ args.push_back(StartArg);
break;
case VK_None:
llvm_unreachable("Invalid viewer");
}
- args.push_back(nullptr);
ErrMsg.clear();
return ExecGraphViewer(ViewerPath, args, OutputFilename, wait, ErrMsg);
@@ -290,10 +281,9 @@ bool llvm::DisplayGraph(StringRef FilenameRef, bool wait,
// dotty
if (S.TryFindProgram("dotty", ViewerPath)) {
- std::vector<const char *> args;
- args.push_back(ViewerPath.c_str());
- args.push_back(Filename.c_str());
- args.push_back(nullptr);
+ std::vector<StringRef> args;
+ args.push_back(ViewerPath);
+ args.push_back(Filename);
// Dotty spawns another app and doesn't wait until it returns
#ifdef _WIN32
diff --git a/llvm/lib/Support/Program.cpp b/llvm/lib/Support/Program.cpp
index 8c56fb6db2d..63cdcdaabee 100644
--- a/llvm/lib/Support/Program.cpp
+++ b/llvm/lib/Support/Program.cpp
@@ -23,17 +23,19 @@ using namespace sys;
//=== independent code.
//===----------------------------------------------------------------------===//
-static bool Execute(ProcessInfo &PI, StringRef Program, const char **Args,
- const char **Env, ArrayRef<Optional<StringRef>> Redirects,
+static bool Execute(ProcessInfo &PI, StringRef Program,
+ ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
+ ArrayRef<Optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg);
-int sys::ExecuteAndWait(StringRef Program, const char **Args, const char **Envp,
+int sys::ExecuteAndWait(StringRef Program, ArrayRef<StringRef> Args,
+ Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects,
unsigned SecondsToWait, unsigned MemoryLimit,
std::string *ErrMsg, bool *ExecutionFailed) {
assert(Redirects.empty() || Redirects.size() == 3);
ProcessInfo PI;
- if (Execute(PI, Program, Args, Envp, Redirects, MemoryLimit, ErrMsg)) {
+ if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) {
if (ExecutionFailed)
*ExecutionFailed = false;
ProcessInfo Result = Wait(
@@ -47,8 +49,8 @@ int sys::ExecuteAndWait(StringRef Program, const char **Args, const char **Envp,
return -1;
}
-ProcessInfo sys::ExecuteNoWait(StringRef Program, const char **Args,
- const char **Envp,
+ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
+ Optional<ArrayRef<StringRef>> Env,
ArrayRef<Optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg,
bool *ExecutionFailed) {
@@ -56,7 +58,7 @@ ProcessInfo sys::ExecuteNoWait(StringRef Program, const char **Args,
ProcessInfo PI;
if (ExecutionFailed)
*ExecutionFailed = false;
- if (!Execute(PI, Program, Args, Envp, Redirects, MemoryLimit, ErrMsg))
+ if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg))
if (ExecutionFailed)
*ExecutionFailed = true;
diff --git a/llvm/lib/Support/Signals.cpp b/llvm/lib/Support/Signals.cpp
index 76a3c6bed41..6534ff69b84 100644
--- a/llvm/lib/Support/Signals.cpp
+++ b/llvm/lib/Support/Signals.cpp
@@ -154,17 +154,18 @@ static bool printSymbolizedStackTrace(StringRef Argv0, void **StackTrace,
}
}
- Optional<StringRef> Redirects[] = {InputFile.str(), OutputFile.str(), llvm::None};
- const char *Args[] = {"llvm-symbolizer", "--functions=linkage", "--inlining",
+ Optional<StringRef> Redirects[] = {StringRef(InputFile),
+ StringRef(OutputFile), llvm::None};
+ StringRef Args[] = {"llvm-symbolizer", "--functions=linkage", "--inlining",
#ifdef _WIN32
- // Pass --relative-address on Windows so that we don't
- // have to add ImageBase from PE file.
- // FIXME: Make this the default for llvm-symbolizer.
- "--relative-address",
+ // Pass --relative-address on Windows so that we don't
+ // have to add ImageBase from PE file.
+ // FIXME: Make this the default for llvm-symbolizer.
+ "--relative-address",
#endif
- "--demangle", nullptr};
+ "--demangle"};
int RunResult =
- sys::ExecuteAndWait(LLVMSymbolizerPath, Args, nullptr, Redirects);
+ sys::ExecuteAndWait(LLVMSymbolizerPath, Args, None, Redirects);
if (RunResult != 0)
return false;
diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc
index be971555b82..d0abc3763e8 100644
--- a/llvm/lib/Support/Unix/Program.inc
+++ b/llvm/lib/Support/Unix/Program.inc
@@ -23,6 +23,7 @@
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/StringSaver.h"
#include "llvm/Support/raw_ostream.h"
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -164,8 +165,18 @@ static void SetMemoryLimits(unsigned size) {
}
-static bool Execute(ProcessInfo &PI, StringRef Program, const char **Args,
- const char **Envp, ArrayRef<Optional<StringRef>> Redirects,
+static std::vector<const char *>
+toNullTerminatedCStringArray(ArrayRef<StringRef> Strings, StringSaver &Saver) {
+ std::vector<const char *> Result;
+ for (StringRef S : Strings)
+ Result.push_back(Saver.save(S).data());
+ Result.push_back(nullptr);
+ return Result;
+}
+
+static bool Execute(ProcessInfo &PI, StringRef Program,
+ ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
+ ArrayRef<Optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg) {
if (!llvm::sys::fs::exists(Program)) {
if (ErrMsg)
@@ -174,6 +185,18 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **Args,
return false;
}
+ BumpPtrAllocator Allocator;
+ StringSaver Saver(Allocator);
+ std::vector<const char *> ArgVector, EnvVector;
+ const char **Argv = nullptr;
+ const char **Envp = nullptr;
+ ArgVector = toNullTerminatedCStringArray(Args, Saver);
+ Argv = ArgVector.data();
+ if (Env) {
+ EnvVector = toNullTerminatedCStringArray(*Env, Saver);
+ Envp = EnvVector.data();
+ }
+
// If this OS has posix_spawn and there is no memory limit being implied, use
// posix_spawn. It is more efficient than fork/exec.
#ifdef HAVE_POSIX_SPAWN
@@ -227,7 +250,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **Args,
// positive.
pid_t PID = 0;
int Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
- /*attrp*/nullptr, const_cast<char **>(Args),
+ /*attrp*/ nullptr, const_cast<char **>(Argv),
const_cast<char **>(Envp));
if (FileActions)
@@ -280,12 +303,10 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **Args,
// Execute!
std::string PathStr = Program;
if (Envp != nullptr)
- execve(PathStr.c_str(),
- const_cast<char **>(Args),
+ execve(PathStr.c_str(), const_cast<char **>(Argv),
const_cast<char **>(Envp));
else
- execv(PathStr.c_str(),
- const_cast<char **>(Args));
+ execv(PathStr.c_str(), const_cast<char **>(Argv));
// If the execve() failed, we should exit. Follow Unix protocol and
// return 127 if the executable was not found, and 126 otherwise.
// Use _exit rather than exit so that atexit functions and static
diff --git a/llvm/lib/Support/Windows/Program.inc b/llvm/lib/Support/Windows/Program.inc
index 19a38c78432..cb68c5b10e5 100644
--- a/llvm/lib/Support/Windows/Program.inc
+++ b/llvm/lib/Support/Windows/Program.inc
@@ -149,15 +149,9 @@ static HANDLE RedirectIO(Optional<StringRef> Path, int fd,
}
-static SmallVector<StringRef, 8> buildArgVector(const char **Args) {
- SmallVector<StringRef, 8> Result;
- for (unsigned I = 0; Args[I]; ++I)
- Result.push_back(StringRef(Args[I]));
- return Result;
-}
-
-static bool Execute(ProcessInfo &PI, StringRef Program, const char **Args,
- const char **Envp, ArrayRef<Optional<StringRef>> Redirects,
+static bool Execute(ProcessInfo &PI, StringRef Program,
+ ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
+ ArrayRef<Optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg) {
if (!sys::fs::can_execute(Program)) {
if (ErrMsg)
@@ -176,19 +170,18 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **Args,
// Windows wants a command line, not an array of args, to pass to the new
// process. We have to concatenate them all, while quoting the args that
// have embedded spaces (or are empty).
- auto ArgVector = buildArgVector(Args);
- std::string Command = flattenWindowsCommandLine(ArgVector);
+ std::string Command = flattenWindowsCommandLine(Args);
// The pointer to the environment block for the new process.
std::vector<wchar_t> EnvBlock;
- if (Envp) {
+ if (Env) {
// An environment block consists of a null-terminated block of
// null-terminated strings. Convert the array of environment variables to
// an environment block by concatenating them.
- for (unsigned i = 0; Envp[i]; ++i) {
+ for (const auto E : *Env) {
SmallVector<wchar_t, MAX_PATH> EnvString;
- if (std::error_code ec = windows::UTF8ToUTF16(Envp[i], EnvString)) {
+ if (std::error_code ec = windows::UTF8ToUTF16(E, EnvString)) {
SetLastError(ec.value());
MakeErrMsg(ErrMsg, "Unable to convert environment variable to UTF-16");
return false;
diff --git a/llvm/tools/bugpoint/OptimizerDriver.cpp b/llvm/tools/bugpoint/OptimizerDriver.cpp
index bdb6c5f1941..cbb048db8fe 100644
--- a/llvm/tools/bugpoint/OptimizerDriver.cpp
+++ b/llvm/tools/bugpoint/OptimizerDriver.cpp
@@ -194,20 +194,20 @@ bool BugDriver::runPasses(Module &Program,
}
// setup the child process' arguments
- SmallVector<const char *, 8> Args;
+ SmallVector<StringRef, 8> Args;
if (UseValgrind) {
Args.push_back("valgrind");
Args.push_back("--error-exitcode=1");
Args.push_back("-q");
- Args.push_back(tool.c_str());
+ Args.push_back(tool);
} else
- Args.push_back(tool.c_str());
+ Args.push_back(tool);
for (unsigned i = 0, e = OptArgs.size(); i != e; ++i)
- Args.push_back(OptArgs[i].c_str());
+ Args.push_back(OptArgs[i]);
Args.push_back("-disable-symbolication");
Args.push_back("-o");
- Args.push_back(OutputFilename.c_str());
+ Args.push_back(OutputFilename);
std::vector<std::string> pass_args;
for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) {
pass_args.push_back(std::string("-load"));
@@ -224,7 +224,6 @@ bool BugDriver::runPasses(Module &Program,
Args.push_back(Temp->TmpName.c_str());
for (unsigned i = 0; i < NumExtraArgs; ++i)
Args.push_back(*ExtraArgs);
- Args.push_back(nullptr);
LLVM_DEBUG(errs() << "\nAbout to run:\t";
for (unsigned i = 0, e = Args.size() - 1; i != e; ++i) errs()
@@ -239,8 +238,8 @@ bool BugDriver::runPasses(Module &Program,
}
std::string ErrMsg;
- int result = sys::ExecuteAndWait(Prog, Args.data(), nullptr, Redirects,
- Timeout, MemoryLimit, &ErrMsg);
+ int result = sys::ExecuteAndWait(Prog, Args, None, Redirects, Timeout,
+ MemoryLimit, &ErrMsg);
// If we are supposed to delete the bitcode file or if the passes crashed,
// remove it now. This may fail if the file was never created, but that's ok.
diff --git a/llvm/tools/bugpoint/ToolRunner.cpp b/llvm/tools/bugpoint/ToolRunner.cpp
index 2fb9f93ad7d..812e8e3bbae 100644
--- a/llvm/tools/bugpoint/ToolRunner.cpp
+++ b/llvm/tools/bugpoint/ToolRunner.cpp
@@ -53,13 +53,14 @@ cl::opt<std::string>
/// 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 +70,22 @@ static int RunProgramWithTimeout(StringRef ProgramPath, const char **Args,
/// 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 +104,12 @@ static int RunProgramRemotelyWithTimeout(StringRef RemoteClientPath,
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 +170,7 @@ Expected<int> LLI::ExecuteProgram(const std::string &Bitcode,
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,18 +178,17 @@ Expected<int> LLI::ExecuteProgram(const std::string &Bitcode,
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();
@@ -198,7 +196,7 @@ Expected<int> LLI::ExecuteProgram(const std::string &Bitcode,
for (unsigned i = 0, e = LLIArgs.size() - 1; i != e; ++i) errs()
<< " " << LLIArgs[i];
errs() << "\n";);
- return RunProgramWithTimeout(LLIPath, &LLIArgs[0], InputFile, OutputFile,
+ return RunProgramWithTimeout(LLIPath, LLIArgs, InputFile, OutputFile,
OutputFile, Timeout, MemoryLimit);
}
@@ -285,22 +283,20 @@ public:
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 +332,18 @@ Expected<int> CustomExecutor::ExecuteProgram(
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);
}
@@ -463,31 +458,28 @@ Expected<CC::FileType> LLC::OutputCode(const std::string &Bitcode,
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();
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[0], "", "", "", Timeout,
- MemoryLimit))
- return ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit);
+ if (RunProgramWithTimeout(LLCPath, LLCArgs, "", "", "", Timeout, MemoryLimit))
+ return ProcessFailure(LLCPath, LLCArgs, Timeout, MemoryLimit);
return UseIntegratedAssembler ? CC::ObjectFile : CC::AsmFile;
}
@@ -581,23 +573,22 @@ Expected<int> JIT::ExecuteProgram(const std::string &Bitcode,
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();
@@ -606,7 +597,7 @@ Expected<int> JIT::ExecuteProgram(const std::string &Bitcode,
<< " " << JITArgs[i];
errs() << "\n";);
LLVM_DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
- return RunProgramWithTimeout(LLIPath, &JITArgs[0], InputFile, OutputFile,
+ return RunProgramWithTimeout(LLIPath, JITArgs, InputFile, OutputFile,
OutputFile, Timeout, MemoryLimit);
}
@@ -630,15 +621,15 @@ AbstractInterpreter::createJIT(const char *Argv0, std::string &Message,
// 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 +642,9 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
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 +652,7 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
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 +671,7 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
}
}
- 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,20 +684,19 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
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();
@@ -714,30 +704,30 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
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]);
+ 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,13 +737,12 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
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>";
@@ -769,7 +758,7 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
if (RemoteClientPath.empty()) {
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
@@ -783,7 +772,7 @@ Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
} else {
outs() << "<run remotely>";
outs().flush();
- return RunProgramRemotelyWithTimeout(RemoteClientPath, &ProgramArgs[0],
+ return RunProgramRemotelyWithTimeout(RemoteClientPath, ProgramArgs,
InputFile, OutputFile, OutputFile,
Timeout, MemoryLimit);
}
@@ -801,9 +790,9 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
}
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");
@@ -811,7 +800,7 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
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) {
@@ -819,7 +808,7 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
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)
@@ -843,7 +832,7 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
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
@@ -851,8 +840,7 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
// 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();
@@ -860,8 +848,8 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
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]);
+ if (RunProgramWithTimeout(CCPath, CCArgs, "", "", ""))
+ return ProcessFailure(CCPath, CCArgs);
return Error::success();
}
diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp
index cd9fbe09cfc..c683b6a786f 100644
--- a/llvm/tools/dsymutil/MachOUtils.cpp
+++ b/llvm/tools/dsymutil/MachOUtils.cpp
@@ -33,7 +33,7 @@ std::string getArchName(StringRef Arch) {
return Arch;
}
-static bool runLipo(StringRef SDKPath, SmallVectorImpl<const char *> &Args) {
+static bool runLipo(StringRef SDKPath, SmallVectorImpl<StringRef> &Args) {
auto Path = sys::findProgramByName("lipo", makeArrayRef(SDKPath));
if (!Path)
Path = sys::findProgramByName("lipo");
@@ -44,8 +44,7 @@ static bool runLipo(StringRef SDKPath, SmallVectorImpl<const char *> &Args) {
}
std::string ErrMsg;
- int result =
- sys::ExecuteAndWait(*Path, Args.data(), nullptr, {}, 0, 0, &ErrMsg);
+ int result = sys::ExecuteAndWait(*Path, Args, None, {}, 0, 0, &ErrMsg);
if (result) {
WithColor::error() << "lipo: " << ErrMsg << "\n";
return false;
@@ -73,29 +72,29 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFilename> &ArchFiles,
return true;
}
- SmallVector<const char *, 8> Args;
+ SmallVector<StringRef, 8> Args;
Args.push_back("lipo");
Args.push_back("-create");
for (auto &Thin : ArchFiles)
- Args.push_back(Thin.Path.c_str());
+ Args.push_back(Thin.Path);
// Align segments to match dsymutil-classic alignment
for (auto &Thin : ArchFiles) {
Thin.Arch = getArchName(Thin.Arch);
Args.push_back("-segalign");
- Args.push_back(Thin.Arch.c_str());
+ Args.push_back(Thin.Arch);
Args.push_back("20");
}
Args.push_back("-output");
Args.push_back(OutputFileName.data());
- Args.push_back(nullptr);
if (Options.Verbose) {
outs() << "Running lipo\n";
for (auto Arg : Args)
- outs() << ' ' << ((Arg == nullptr) ? "\n" : Arg);
+ outs() << ' ' << Arg;
+ outs() << "\n";
}
return Options.NoOutput ? true : runLipo(SDKPath, Args);
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index e40cc5c386e..e93b63d388e 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -478,14 +478,13 @@ void CodeCoverageTool::demangleSymbols(const CoverageMapping &Coverage) {
OutputTOF.os().close();
// Invoke the demangler.
- std::vector<const char *> ArgsV;
- for (const std::string &Arg : ViewOpts.DemanglerOpts)
- ArgsV.push_back(Arg.c_str());
- ArgsV.push_back(nullptr);
+ std::vector<StringRef> ArgsV;
+ for (StringRef Arg : ViewOpts.DemanglerOpts)
+ ArgsV.push_back(Arg);
Optional<StringRef> Redirects[] = {InputPath.str(), OutputPath.str(), {""}};
std::string ErrMsg;
- int RC = sys::ExecuteAndWait(ViewOpts.DemanglerOpts[0], ArgsV.data(),
- /*env=*/nullptr, Redirects, /*secondsToWait=*/0,
+ int RC = sys::ExecuteAndWait(ViewOpts.DemanglerOpts[0], ArgsV,
+ /*env=*/None, Redirects, /*secondsToWait=*/0,
/*memoryLimit=*/0, &ErrMsg);
if (RC) {
error(ErrMsg, ViewOpts.DemanglerOpts[0]);
diff --git a/llvm/unittests/Support/Host.cpp b/llvm/unittests/Support/Host.cpp
index 736b04c2049..e07d4151bb6 100644
--- a/llvm/unittests/Support/Host.cpp
+++ b/llvm/unittests/Support/Host.cpp
@@ -185,12 +185,12 @@ TEST_F(HostTest, getMacOSHostVersion) {
path::append(OutputFile, "out");
const char *SwVersPath = "/usr/bin/sw_vers";
- const char *argv[] = {SwVersPath, "-productVersion", nullptr};
+ StringRef argv[] = {SwVersPath, "-productVersion"};
StringRef OutputPath = OutputFile.str();
const Optional<StringRef> Redirects[] = {/*STDIN=*/None,
/*STDOUT=*/OutputPath,
/*STDERR=*/None};
- int RetCode = ExecuteAndWait(SwVersPath, argv, /*env=*/nullptr, Redirects);
+ int RetCode = ExecuteAndWait(SwVersPath, argv, /*env=*/llvm::None, Redirects);
ASSERT_EQ(0, RetCode);
int FD = 0;
diff --git a/llvm/unittests/Support/ProgramTest.cpp b/llvm/unittests/Support/ProgramTest.cpp
index 7a0676c7a48..ec1c85a9f25 100644
--- a/llvm/unittests/Support/ProgramTest.cpp
+++ b/llvm/unittests/Support/ProgramTest.cpp
@@ -60,7 +60,7 @@ static cl::opt<std::string>
ProgramTestStringArg2("program-test-string-arg2");
class ProgramEnvTest : public testing::Test {
- std::vector<const char *> EnvTable;
+ std::vector<StringRef> EnvTable;
std::vector<std::string> EnvStorage;
protected:
@@ -77,7 +77,7 @@ protected:
}();
ASSERT_TRUE(EnvP);
- auto prepareEnvVar = [this](decltype(*EnvP) Var) {
+ auto prepareEnvVar = [this](decltype(*EnvP) Var) -> StringRef {
#if defined(_WIN32)
// On Windows convert UTF16 encoded variable to UTF8
auto Len = wcslen(Var);
@@ -86,10 +86,10 @@ protected:
EnvStorage.emplace_back();
auto convStatus = convertUTF16ToUTF8String(Ref, EnvStorage.back());
EXPECT_TRUE(convStatus);
- return EnvStorage.back().c_str();
+ return EnvStorage.back();
#else
(void)this;
- return Var;
+ return StringRef(Var);
#endif
};
@@ -104,16 +104,9 @@ protected:
EnvStorage.clear();
}
- void addEnvVar(const char *Var) {
- ASSERT_TRUE(EnvTable.empty() || EnvTable.back()) << "Env table sealed";
- EnvTable.emplace_back(Var);
- }
+ void addEnvVar(StringRef Var) { EnvTable.emplace_back(Var); }
- const char **getEnviron() {
- if (EnvTable.back() != nullptr)
- EnvTable.emplace_back(nullptr); // Seal table.
- return &EnvTable[0];
- }
+ ArrayRef<StringRef> getEnviron() const { return EnvTable; }
};
#ifdef _WIN32
@@ -129,11 +122,8 @@ TEST_F(ProgramEnvTest, CreateProcessLongPath) {
MyExe.append("\\\\?\\");
MyExe.append(MyAbsExe);
- const char *ArgV[] = {
- MyExe.c_str(),
- "--gtest_filter=ProgramEnvTest.CreateProcessLongPath",
- nullptr
- };
+ StringRef ArgV[] = {MyExe,
+ "--gtest_filter=ProgramEnvTest.CreateProcessLongPath"};
// Add LLVM_PROGRAM_TEST_LONG_PATH to the environment of the child.
addEnvVar("LLVM_PROGRAM_TEST_LONG_PATH=1");
@@ -173,13 +163,13 @@ TEST_F(ProgramEnvTest, CreateProcessTrailingSlash) {
std::string my_exe =
sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
- const char *argv[] = {
- my_exe.c_str(),
- "--gtest_filter=ProgramEnvTest.CreateProcessTrailingSlash",
- "-program-test-string-arg1", "has\\\\ trailing\\",
- "-program-test-string-arg2", "has\\\\ trailing\\",
- nullptr
- };
+ StringRef argv[] = {
+ my_exe,
+ "--gtest_filter=ProgramEnvTest.CreateProcessTrailingSlash",
+ "-program-test-string-arg1",
+ "has\\\\ trailing\\",
+ "-program-test-string-arg2",
+ "has\\\\ trailing\\"};
// Add LLVM_PROGRAM_TEST_CHILD to the environment of the child.
addEnvVar("LLVM_PROGRAM_TEST_CHILD=1");
@@ -210,11 +200,8 @@ TEST_F(ProgramEnvTest, TestExecuteNoWait) {
std::string Executable =
sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
- const char *argv[] = {
- Executable.c_str(),
- "--gtest_filter=ProgramEnvTest.TestExecuteNoWait",
- nullptr
- };
+ StringRef argv[] = {Executable,
+ "--gtest_filter=ProgramEnvTest.TestExecuteNoWait"};
// Add LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT to the environment of the child.
addEnvVar("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT=1");
@@ -268,11 +255,8 @@ TEST_F(ProgramEnvTest, TestExecuteAndWaitTimeout) {
std::string Executable =
sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
- const char *argv[] = {
- Executable.c_str(),
- "--gtest_filter=ProgramEnvTest.TestExecuteAndWaitTimeout",
- nullptr
- };
+ StringRef argv[] = {
+ Executable, "--gtest_filter=ProgramEnvTest.TestExecuteAndWaitTimeout"};
// Add LLVM_PROGRAM_TEST_TIMEOUT to the environment of the child.
addEnvVar("LLVM_PROGRAM_TEST_TIMEOUT=1");
@@ -287,12 +271,12 @@ TEST_F(ProgramEnvTest, TestExecuteAndWaitTimeout) {
TEST(ProgramTest, TestExecuteNegative) {
std::string Executable = "i_dont_exist";
- const char *argv[] = { Executable.c_str(), nullptr };
+ StringRef argv[] = {Executable};
{
std::string Error;
bool ExecutionFailed;
- int RetCode = ExecuteAndWait(Executable, argv, nullptr, {}, 0, 0, &Error,
+ int RetCode = ExecuteAndWait(Executable, argv, llvm::None, {}, 0, 0, &Error,
&ExecutionFailed);
ASSERT_TRUE(RetCode < 0) << "On error ExecuteAndWait should return 0 or "
"positive value indicating the result code";
@@ -303,7 +287,7 @@ TEST(ProgramTest, TestExecuteNegative) {
{
std::string Error;
bool ExecutionFailed;
- ProcessInfo PI = ExecuteNoWait(Executable, argv, nullptr, {}, 0, &Error,
+ ProcessInfo PI = ExecuteNoWait(Executable, argv, llvm::None, {}, 0, &Error,
&ExecutionFailed);
ASSERT_EQ(PI.Pid, ProcessInfo::InvalidPid)
<< "On error ExecuteNoWait should return an invalid ProcessInfo";
diff --git a/llvm/utils/not/not.cpp b/llvm/utils/not/not.cpp
index de71b4c6887..f48079d8875 100644
--- a/llvm/utils/not/not.cpp
+++ b/llvm/utils/not/not.cpp
@@ -38,8 +38,12 @@ int main(int argc, const char **argv) {
return 1;
}
+ std::vector<StringRef> Argv;
+ Argv.reserve(argc);
+ for (int i = 0; i < argc; ++i)
+ Argv.push_back(argv[i]);
std::string ErrMsg;
- int Result = sys::ExecuteAndWait(*Program, argv, nullptr, {}, 0, 0, &ErrMsg);
+ int Result = sys::ExecuteAndWait(*Program, Argv, None, {}, 0, 0, &ErrMsg);
#ifdef _WIN32
// Handle abort() in msvcrt -- It has exit code as 3. abort(), aka
// unreachable, should be recognized as a crash. However, some binaries use
OpenPOWER on IntegriCloud