LLVM  14.0.0git
Program.inc
Go to the documentation of this file.
1 //===- llvm/Support/Unix/Program.cpp -----------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Unix specific portion of the Program class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 //===----------------------------------------------------------------------===//
14 //=== WARNING: Implementation here must contain only generic UNIX code that
15 //=== is guaranteed to work on *all* UNIX variants.
16 //===----------------------------------------------------------------------===//
17 
18 #include "llvm/Support/Program.h"
19 
20 #include "Unix.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/Config/config.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/Errc.h"
26 #include "llvm/Support/Path.h"
29 #if HAVE_SYS_STAT_H
30 #include <sys/stat.h>
31 #endif
32 #if HAVE_SYS_RESOURCE_H
33 #include <sys/resource.h>
34 #endif
35 #if HAVE_SIGNAL_H
36 #include <signal.h>
37 #endif
38 #if HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41 #if HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #ifdef HAVE_POSIX_SPAWN
45 #include <spawn.h>
46 
47 #if defined(__APPLE__)
48 #include <TargetConditionals.h>
49 #endif
50 
51 #if defined(__APPLE__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
52 #define USE_NSGETENVIRON 1
53 #else
54 #define USE_NSGETENVIRON 0
55 #endif
56 
57 #if !USE_NSGETENVIRON
58  extern char **environ;
59 #else
60 #include <crt_externs.h> // _NSGetEnviron
61 #endif
62 #endif
63 
64 using namespace llvm;
65 using namespace sys;
66 
67 ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {}
68 
70  ArrayRef<StringRef> Paths) {
71  assert(!Name.empty() && "Must have a name!");
72  // Use the given path verbatim if it contains any slashes; this matches
73  // the behavior of sh(1) and friends.
74  if (Name.contains('/'))
75  return std::string(Name);
76 
77  SmallVector<StringRef, 16> EnvironmentPaths;
78  if (Paths.empty())
79  if (const char *PathEnv = std::getenv("PATH")) {
80  SplitString(PathEnv, EnvironmentPaths, ":");
81  Paths = EnvironmentPaths;
82  }
83 
84  for (auto Path : Paths) {
85  if (Path.empty())
86  continue;
87 
88  // Check to see if this first directory contains the executable...
89  SmallString<128> FilePath(Path);
90  sys::path::append(FilePath, Name);
91  if (sys::fs::can_execute(FilePath.c_str()))
92  return std::string(FilePath.str()); // Found the executable!
93  }
95 }
96 
97 static bool RedirectIO(Optional<StringRef> Path, int FD, std::string* ErrMsg) {
98  if (!Path) // Noop
99  return false;
100  std::string File;
101  if (Path->empty())
102  // Redirect empty paths to /dev/null
103  File = "/dev/null";
104  else
105  File = std::string(*Path);
106 
107  // Open the file
108  int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
109  if (InFD == -1) {
110  MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
111  + (FD == 0 ? "input" : "output"));
112  return true;
113  }
114 
115  // Install it as the requested FD
116  if (dup2(InFD, FD) == -1) {
117  MakeErrMsg(ErrMsg, "Cannot dup2");
118  close(InFD);
119  return true;
120  }
121  close(InFD); // Close the original FD
122  return false;
123 }
124 
125 #ifdef HAVE_POSIX_SPAWN
126 static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg,
127  posix_spawn_file_actions_t *FileActions) {
128  if (!Path) // Noop
129  return false;
130  const char *File;
131  if (Path->empty())
132  // Redirect empty paths to /dev/null
133  File = "/dev/null";
134  else
135  File = Path->c_str();
136 
137  if (int Err = posix_spawn_file_actions_addopen(
138  FileActions, FD, File,
139  FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666))
140  return MakeErrMsg(ErrMsg, "Cannot posix_spawn_file_actions_addopen", Err);
141  return false;
142 }
143 #endif
144 
145 static void TimeOutHandler(int Sig) {
146 }
147 
148 static void SetMemoryLimits(unsigned size) {
149 #if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
150  struct rlimit r;
151  __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
152 
153  // Heap size
154  getrlimit (RLIMIT_DATA, &r);
155  r.rlim_cur = limit;
156  setrlimit (RLIMIT_DATA, &r);
157 #ifdef RLIMIT_RSS
158  // Resident set size.
159  getrlimit (RLIMIT_RSS, &r);
160  r.rlim_cur = limit;
161  setrlimit (RLIMIT_RSS, &r);
162 #endif
163 #endif
164 }
165 
166 static std::vector<const char *>
167 toNullTerminatedCStringArray(ArrayRef<StringRef> Strings, StringSaver &Saver) {
168  std::vector<const char *> Result;
169  for (StringRef S : Strings)
170  Result.push_back(Saver.save(S).data());
171  Result.push_back(nullptr);
172  return Result;
173 }
174 
175 static bool Execute(ProcessInfo &PI, StringRef Program,
177  ArrayRef<Optional<StringRef>> Redirects,
178  unsigned MemoryLimit, std::string *ErrMsg,
179  BitVector *AffinityMask) {
180  if (!llvm::sys::fs::exists(Program)) {
181  if (ErrMsg)
182  *ErrMsg = std::string("Executable \"") + Program.str() +
183  std::string("\" doesn't exist!");
184  return false;
185  }
186 
187  assert(!AffinityMask && "Starting a process with an affinity mask is "
188  "currently not supported on Unix!");
189 
191  StringSaver Saver(Allocator);
192  std::vector<const char *> ArgVector, EnvVector;
193  const char **Argv = nullptr;
194  const char **Envp = nullptr;
195  ArgVector = toNullTerminatedCStringArray(Args, Saver);
196  Argv = ArgVector.data();
197  if (Env) {
198  EnvVector = toNullTerminatedCStringArray(*Env, Saver);
199  Envp = EnvVector.data();
200  }
201 
202  // If this OS has posix_spawn and there is no memory limit being implied, use
203  // posix_spawn. It is more efficient than fork/exec.
204 #ifdef HAVE_POSIX_SPAWN
205  if (MemoryLimit == 0) {
206  posix_spawn_file_actions_t FileActionsStore;
207  posix_spawn_file_actions_t *FileActions = nullptr;
208 
209  // If we call posix_spawn_file_actions_addopen we have to make sure the
210  // c strings we pass to it stay alive until the call to posix_spawn,
211  // so we copy any StringRefs into this variable.
212  std::string RedirectsStorage[3];
213 
214  if (!Redirects.empty()) {
215  assert(Redirects.size() == 3);
216  std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr};
217  for (int I = 0; I < 3; ++I) {
218  if (Redirects[I]) {
219  RedirectsStorage[I] = std::string(*Redirects[I]);
220  RedirectsStr[I] = &RedirectsStorage[I];
221  }
222  }
223 
224  FileActions = &FileActionsStore;
225  posix_spawn_file_actions_init(FileActions);
226 
227  // Redirect stdin/stdout.
228  if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) ||
229  RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions))
230  return false;
231  if (!Redirects[1] || !Redirects[2] || *Redirects[1] != *Redirects[2]) {
232  // Just redirect stderr
233  if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions))
234  return false;
235  } else {
236  // If stdout and stderr should go to the same place, redirect stderr
237  // to the FD already open for stdout.
238  if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2))
239  return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
240  }
241  }
242 
243  if (!Envp)
244 #if !USE_NSGETENVIRON
245  Envp = const_cast<const char **>(environ);
246 #else
247  // environ is missing in dylibs.
248  Envp = const_cast<const char **>(*_NSGetEnviron());
249 #endif
250 
251  constexpr int maxRetries = 8;
252  int retries = 0;
253  pid_t PID;
254  int Err;
255  do {
256  PID = 0; // Make Valgrind happy.
257  Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
258  /*attrp*/ nullptr, const_cast<char **>(Argv),
259  const_cast<char **>(Envp));
260  } while (Err == EINTR && ++retries < maxRetries);
261 
262  if (FileActions)
263  posix_spawn_file_actions_destroy(FileActions);
264 
265  if (Err)
266  return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
267 
268  PI.Pid = PID;
269  PI.Process = PID;
270 
271  return true;
272  }
273 #endif
274 
275  // Create a child process.
276  int child = fork();
277  switch (child) {
278  // An error occurred: Return to the caller.
279  case -1:
280  MakeErrMsg(ErrMsg, "Couldn't fork");
281  return false;
282 
283  // Child process: Execute the program.
284  case 0: {
285  // Redirect file descriptors...
286  if (!Redirects.empty()) {
287  // Redirect stdin
288  if (RedirectIO(Redirects[0], 0, ErrMsg)) { return false; }
289  // Redirect stdout
290  if (RedirectIO(Redirects[1], 1, ErrMsg)) { return false; }
291  if (Redirects[1] && Redirects[2] && *Redirects[1] == *Redirects[2]) {
292  // If stdout and stderr should go to the same place, redirect stderr
293  // to the FD already open for stdout.
294  if (-1 == dup2(1,2)) {
295  MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
296  return false;
297  }
298  } else {
299  // Just redirect stderr
300  if (RedirectIO(Redirects[2], 2, ErrMsg)) { return false; }
301  }
302  }
303 
304  // Set memory limits
305  if (MemoryLimit!=0) {
306  SetMemoryLimits(MemoryLimit);
307  }
308 
309  // Execute!
310  std::string PathStr = std::string(Program);
311  if (Envp != nullptr)
312  execve(PathStr.c_str(), const_cast<char **>(Argv),
313  const_cast<char **>(Envp));
314  else
315  execv(PathStr.c_str(), const_cast<char **>(Argv));
316  // If the execve() failed, we should exit. Follow Unix protocol and
317  // return 127 if the executable was not found, and 126 otherwise.
318  // Use _exit rather than exit so that atexit functions and static
319  // object destructors cloned from the parent process aren't
320  // redundantly run, and so that any data buffered in stdio buffers
321  // cloned from the parent aren't redundantly written out.
322  _exit(errno == ENOENT ? 127 : 126);
323  }
324 
325  // Parent process: Break out of the switch to do our processing.
326  default:
327  break;
328  }
329 
330  PI.Pid = child;
331  PI.Process = child;
332 
333  return true;
334 }
335 
336 namespace llvm {
337 namespace sys {
338 
339 #ifndef _AIX
340 using ::wait4;
341 #else
342 static pid_t (wait4)(pid_t pid, int *status, int options, struct rusage *usage);
343 #endif
344 
345 } // namespace sys
346 } // namespace llvm
347 
348 #ifdef _AIX
349 #ifndef _ALL_SOURCE
350 extern "C" pid_t (wait4)(pid_t pid, int *status, int options,
351  struct rusage *usage);
352 #endif
353 pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
354  struct rusage *usage) {
355  assert(pid > 0 && "Only expecting to handle actual PID values!");
356  assert((options & ~WNOHANG) == 0 && "Expecting WNOHANG at most!");
357  assert(usage && "Expecting usage collection!");
358 
359  // AIX wait4 does not work well with WNOHANG.
360  if (!(options & WNOHANG))
361  return ::wait4(pid, status, options, usage);
362 
363  // For WNOHANG, we use waitid (which supports WNOWAIT) until the child process
364  // has terminated.
365  siginfo_t WaitIdInfo;
366  WaitIdInfo.si_pid = 0;
367  int WaitIdRetVal =
368  waitid(P_PID, pid, &WaitIdInfo, WNOWAIT | WEXITED | options);
369 
370  if (WaitIdRetVal == -1 || WaitIdInfo.si_pid == 0)
371  return WaitIdRetVal;
372 
373  assert(WaitIdInfo.si_pid == pid);
374 
375  // The child has already terminated, so a blocking wait on it is okay in the
376  // absence of indiscriminate `wait` calls from the current process (which
377  // would cause the call here to fail with ECHILD).
378  return ::wait4(pid, status, options & ~WNOHANG, usage);
379 }
380 #endif
381 
382 ProcessInfo llvm::sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
383  bool WaitUntilTerminates, std::string *ErrMsg,
384  Optional<ProcessStatistics> *ProcStat) {
385  struct sigaction Act, Old;
386  assert(PI.Pid && "invalid pid to wait on, process not started?");
387 
388  int WaitPidOptions = 0;
389  pid_t ChildPid = PI.Pid;
390  if (WaitUntilTerminates) {
391  SecondsToWait = 0;
392  } else if (SecondsToWait) {
393  // Install a timeout handler. The handler itself does nothing, but the
394  // simple fact of having a handler at all causes the wait below to return
395  // with EINTR, unlike if we used SIG_IGN.
396  memset(&Act, 0, sizeof(Act));
397  Act.sa_handler = TimeOutHandler;
398  sigemptyset(&Act.sa_mask);
399  sigaction(SIGALRM, &Act, &Old);
400  // FIXME The alarm signal may be delivered to another thread.
401  alarm(SecondsToWait);
402  } else if (SecondsToWait == 0)
403  WaitPidOptions = WNOHANG;
404 
405  // Parent process: Wait for the child process to terminate.
406  int status;
407  ProcessInfo WaitResult;
408  rusage Info;
409  if (ProcStat)
410  ProcStat->reset();
411 
412  do {
413  WaitResult.Pid = sys::wait4(ChildPid, &status, WaitPidOptions, &Info);
414  } while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR);
415 
416  if (WaitResult.Pid != PI.Pid) {
417  if (WaitResult.Pid == 0) {
418  // Non-blocking wait.
419  return WaitResult;
420  } else {
421  if (SecondsToWait && errno == EINTR) {
422  // Kill the child.
423  kill(PI.Pid, SIGKILL);
424 
425  // Turn off the alarm and restore the signal handler
426  alarm(0);
427  sigaction(SIGALRM, &Old, nullptr);
428 
429  // Wait for child to die
430  // FIXME This could grab some other child process out from another
431  // waiting thread and then leave a zombie anyway.
432  if (wait(&status) != ChildPid)
433  MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
434  else
435  MakeErrMsg(ErrMsg, "Child timed out", 0);
436 
437  WaitResult.ReturnCode = -2; // Timeout detected
438  return WaitResult;
439  } else if (errno != EINTR) {
440  MakeErrMsg(ErrMsg, "Error waiting for child process");
441  WaitResult.ReturnCode = -1;
442  return WaitResult;
443  }
444  }
445  }
446 
447  // We exited normally without timeout, so turn off the timer.
448  if (SecondsToWait && !WaitUntilTerminates) {
449  alarm(0);
450  sigaction(SIGALRM, &Old, nullptr);
451  }
452 
453  if (ProcStat) {
454  std::chrono::microseconds UserT = toDuration(Info.ru_utime);
455  std::chrono::microseconds KernelT = toDuration(Info.ru_stime);
456  uint64_t PeakMemory = 0;
457 #ifndef __HAIKU__
458  PeakMemory = static_cast<uint64_t>(Info.ru_maxrss);
459 #endif
460  *ProcStat = ProcessStatistics{UserT + KernelT, UserT, PeakMemory};
461  }
462 
463  // Return the proper exit status. Detect error conditions
464  // so we can return -1 for them and set ErrMsg informatively.
465  int result = 0;
466  if (WIFEXITED(status)) {
467  result = WEXITSTATUS(status);
468  WaitResult.ReturnCode = result;
469 
470  if (result == 127) {
471  if (ErrMsg)
472  *ErrMsg = llvm::sys::StrError(ENOENT);
473  WaitResult.ReturnCode = -1;
474  return WaitResult;
475  }
476  if (result == 126) {
477  if (ErrMsg)
478  *ErrMsg = "Program could not be executed";
479  WaitResult.ReturnCode = -1;
480  return WaitResult;
481  }
482  } else if (WIFSIGNALED(status)) {
483  if (ErrMsg) {
484  *ErrMsg = strsignal(WTERMSIG(status));
485 #ifdef WCOREDUMP
486  if (WCOREDUMP(status))
487  *ErrMsg += " (core dumped)";
488 #endif
489  }
490  // Return a special value to indicate that the process received an unhandled
491  // signal during execution as opposed to failing to execute.
492  WaitResult.ReturnCode = -2;
493  }
494  return WaitResult;
495 }
496 
497 std::error_code llvm::sys::ChangeStdinMode(fs::OpenFlags Flags){
498  if (!(Flags & fs::OF_Text))
499  return ChangeStdinToBinary();
500  return std::error_code();
501 }
502 
503 std::error_code llvm::sys::ChangeStdoutMode(fs::OpenFlags Flags){
504  if (!(Flags & fs::OF_Text))
505  return ChangeStdoutToBinary();
506  return std::error_code();
507 }
508 
509 std::error_code llvm::sys::ChangeStdinToBinary() {
510  // Do nothing, as Unix doesn't differentiate between text and binary.
511  return std::error_code();
512 }
513 
514 std::error_code llvm::sys::ChangeStdoutToBinary() {
515  // Do nothing, as Unix doesn't differentiate between text and binary.
516  return std::error_code();
517 }
518 
519 std::error_code
521  WindowsEncodingMethod Encoding /*unused*/) {
522  std::error_code EC;
524 
525  if (EC)
526  return EC;
527 
528  OS << Contents;
529 
530  if (OS.has_error())
532 
533  return EC;
534 }
535 
538  static long ArgMax = sysconf(_SC_ARG_MAX);
539  // POSIX requires that _POSIX_ARG_MAX is 4096, which is the lowest possible
540  // value for ARG_MAX on a POSIX compliant system.
541  static long ArgMin = _POSIX_ARG_MAX;
542 
543  // This the same baseline used by xargs.
544  long EffectiveArgMax = 128 * 1024;
545 
546  if (EffectiveArgMax > ArgMax)
547  EffectiveArgMax = ArgMax;
548  else if (EffectiveArgMax < ArgMin)
549  EffectiveArgMax = ArgMin;
550 
551  // System says no practical limit.
552  if (ArgMax == -1)
553  return true;
554 
555  // Conservatively account for space required by environment variables.
556  long HalfArgMax = EffectiveArgMax / 2;
557 
558  size_t ArgLength = Program.size() + 1;
559  for (StringRef Arg : Args) {
560  // Ensure that we do not exceed the MAX_ARG_STRLEN constant on Linux, which
561  // does not have a constant unlike what the man pages would have you
562  // believe. Since this limit is pretty high, perform the check
563  // unconditionally rather than trying to be aggressive and limiting it to
564  // Linux only.
565  if (Arg.size() >= (32 * 4096))
566  return false;
567 
568  ArgLength += Arg.size() + 1;
569  if (ArgLength > size_t(HalfArgMax)) {
570  return false;
571  }
572  }
573 
574  return true;
575 }
llvm::sys::StrError
std::string StrError()
Returns a string representation of the errno value, using whatever thread-safe variant of strerror() ...
Definition: Errno.cpp:31
llvm::sys::findProgramByName
ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths={})
Find the first executable file Name in Paths.
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:152
FileSystem.h
llvm::sys::ChangeStdoutMode
std::error_code ChangeStdoutMode(fs::OpenFlags Flags)
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
Path.h
Errc.h
llvm::sys::writeFileWithEncoding
std::error_code writeFileWithEncoding(StringRef FileName, StringRef Contents, WindowsEncodingMethod Encoding=WEM_UTF8)
Saves the UTF8-encoded contents string into the file FileName using a specific encoding.
llvm::Optional
Definition: APInt.h:33
llvm::errc::no_such_file_or_directory
@ no_such_file_or_directory
Unix.h
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
result
It looks like we only need to define PPCfmarto for these because according to these instructions perform RTO on fma s result
Definition: README_P9.txt:256
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:206
llvm::sys::ProcessInfo::ProcessInfo
ProcessInfo()
llvm::sys::ChangeStdoutToBinary
std::error_code ChangeStdoutToBinary()
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::BitVector
Definition: BitVector.h:74
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:244
llvm::SmallString< 128 >
llvm::sys::fs::OF_TextWithCRLF
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
Definition: FileSystem.h:770
StringSaver.h
llvm::sys::ChangeStdinToBinary
std::error_code ChangeStdinToBinary()
llvm::sys::fs::exists
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1073
uint64_t
llvm::sys::fs::OF_Text
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
Definition: FileSystem.h:761
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
llvm::sys::WindowsEncodingMethod
WindowsEncodingMethod
File encoding options when writing contents that a non-UTF8 tool will read (on Windows systems).
Definition: Program.h:168
I
#define I(x, y, z)
Definition: MD5.cpp:59
StringExtras.h
llvm::MakeErrMsg
bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix)
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::codeview::CompileSym2Flags::EC
@ EC
llvm::StringSaver
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition: StringSaver.h:21
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1581
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Compiler.h
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
Execute
static bool Execute(ProcessInfo &PI, StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env, ArrayRef< Optional< StringRef >> Redirects, unsigned MemoryLimit, std::string *ErrMsg, BitVector *AffinityMask)
llvm::raw_fd_ostream
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:443
llvm::make_error_code
std::error_code make_error_code(BitcodeError E)
Definition: BitcodeReader.h:270
llvm::sys::ChangeStdinMode
std::error_code ChangeStdinMode(fs::OpenFlags Flags)
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
options
The object format emitted by the WebAssembly backed is documented see the home and packaging for producing WebAssembly applications that can run in browsers and other environments wasi sdk provides a more minimal C C SDK based on llvm and a libc based on for producing WebAssemmbly applictions that use the WASI ABI Rust provides WebAssembly support integrated into Cargo There are two main options
Definition: README.txt:24
llvm::sys::toDuration
std::chrono::nanoseconds toDuration(FILETIME Time)
Definition: WindowsSupport.h:201
llvm::errc::io_error
@ io_error
llvm::sys::fs::OpenFlags
OpenFlags
Definition: FileSystem.h:756
Allocator
Basic Register Allocator
Definition: RegAllocBasic.cpp:146
llvm::sys::fs::status
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
Program.h
llvm::ErrorOr
Represents either an error or a value T.
Definition: ErrorOr.h:56
llvm::StringSaver::save
StringRef save(const char *S)
Definition: StringSaver.h:28
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:148
llvm::sys::Wait
ProcessInfo Wait(const ProcessInfo &PI, unsigned SecondsToWait, bool WaitUntilTerminates, std::string *ErrMsg=nullptr, Optional< ProcessStatistics > *ProcStat=nullptr)
This function waits for the process specified by PI to finish.
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
raw_ostream.h
llvm::sys::commandLineFitsWithinSystemLimits
bool commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef< StringRef > Args)
Return true if the given arguments fit within system-specific argument length limits.
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:156
llvm::sys::fs::can_execute
bool can_execute(const Twine &Path)
Can we execute this file?
File
Instrumentation for Order File
Definition: InstrOrderFile.cpp:205