summaryrefslogtreecommitdiffstats
path: root/lib/System/Unix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/System/Unix')
-rw-r--r--lib/System/Unix/Alarm.inc2
-rw-r--r--lib/System/Unix/Host.inc46
-rw-r--r--lib/System/Unix/Memory.inc7
-rw-r--r--lib/System/Unix/Path.inc73
-rw-r--r--lib/System/Unix/Process.inc29
-rw-r--r--lib/System/Unix/Program.inc131
-rw-r--r--lib/System/Unix/Signals.inc14
-rw-r--r--lib/System/Unix/TimeValue.inc2
8 files changed, 204 insertions, 100 deletions
diff --git a/lib/System/Unix/Alarm.inc b/lib/System/Unix/Alarm.inc
index 28ff1b8..fb42b6c 100644
--- a/lib/System/Unix/Alarm.inc
+++ b/lib/System/Unix/Alarm.inc
@@ -67,6 +67,6 @@ int sys::AlarmStatus() {
return 0;
}
-void Sleep(unsigned n) {
+void sys::Sleep(unsigned n) {
::sleep(n);
}
diff --git a/lib/System/Unix/Host.inc b/lib/System/Unix/Host.inc
index fb319fd..c76d6a4 100644
--- a/lib/System/Unix/Host.inc
+++ b/lib/System/Unix/Host.inc
@@ -16,7 +16,8 @@
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
-#include <llvm/Config/config.h>
+#include "llvm/Config/config.h"
+#include "llvm/ADT/StringRef.h"
#include "Unix.h"
#include <sys/utsname.h>
#include <string>
@@ -33,10 +34,47 @@ static std::string getOSVersion() {
}
std::string sys::getHostTriple() {
- // FIXME: Derive more directly instead of relying on the autoconf
- // generated variable.
+ // FIXME: Derive directly instead of relying on the autoconf generated
+ // variable.
- std::string Triple = LLVM_HOSTTRIPLE;
+ StringRef HostTripleString(LLVM_HOSTTRIPLE);
+ std::pair<StringRef, StringRef> ArchSplit = HostTripleString.split('-');
+
+ // Normalize the arch, since the host triple may not actually match the host.
+ std::string Arch = ArchSplit.first;
+
+ // It would be nice to do this in terms of llvm::Triple, but that is in
+ // Support which is layered above us.
+#if defined(__x86_64__)
+ Arch = "x86_64";
+#elif defined(__i386__)
+ Arch = "i386";
+#elif defined(__ppc64__)
+ Arch = "powerpc64";
+#elif defined(__ppc__)
+ Arch = "powerpc";
+#elif defined(__arm__)
+
+ // FIXME: We need to pick the right ARM triple (which involves querying the
+ // chip). However, for now this is most important for LLVM arch selection, so
+ // we only need to make sure to distinguish ARM and Thumb.
+# if defined(__thumb__)
+ Arch = "thumb";
+# else
+ Arch = "arm";
+# endif
+
+#else
+
+ // FIXME: When enough auto-detection is in place, this should just
+ // #error. Then at least the arch selection is done, and we only need the OS
+ // etc selection to kill off the use of LLVM_HOSTTRIPLE.
+
+#endif
+
+ std::string Triple(Arch);
+ Triple += '-';
+ Triple += ArchSplit.second;
// Force i<N>86 to i386.
if (Triple[0] == 'i' && isdigit(Triple[1]) &&
diff --git a/lib/System/Unix/Memory.inc b/lib/System/Unix/Memory.inc
index b7a7013..a80f56f 100644
--- a/lib/System/Unix/Memory.inc
+++ b/lib/System/Unix/Memory.inc
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "Unix.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/System/Process.h"
#ifdef HAVE_SYS_MMAN_H
@@ -28,12 +29,12 @@
/// is very OS specific.
///
llvm::sys::MemoryBlock
-llvm::sys::Memory::AllocateRWX(unsigned NumBytes, const MemoryBlock* NearBlock,
+llvm::sys::Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
std::string *ErrMsg) {
if (NumBytes == 0) return MemoryBlock();
- unsigned pageSize = Process::GetPageSize();
- unsigned NumPages = (NumBytes+pageSize-1)/pageSize;
+ size_t pageSize = Process::GetPageSize();
+ size_t NumPages = (NumBytes+pageSize-1)/pageSize;
int fd = -1;
#ifdef NEED_DEV_ZERO_FOR_MMAP
diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc
index 1f73571..89285b4 100644
--- a/lib/System/Unix/Path.inc
+++ b/lib/System/Unix/Path.inc
@@ -16,7 +16,7 @@
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
-#include "llvm/Config/alloca.h"
+#include "llvm/ADT/SmallVector.h"
#include "Unix.h"
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -57,6 +57,10 @@
#include <dlfcn.h>
#endif
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
// Put in a hack for Cygwin which falsely reports that the mkdtemp function
// is available when it is not.
#ifdef __CYGWIN__
@@ -92,15 +96,7 @@ Path::isValid() const {
// Check some obvious things
if (path.empty())
return false;
- else if (path.length() >= MAXPATHLEN)
- return false;
-
- // Check that the characters are ascii chars
- size_t len = path.length();
- unsigned i = 0;
- while (i < len && isascii(path[i]))
- ++i;
- return i >= len;
+ return path.length() < MAXPATHLEN;
}
bool
@@ -117,6 +113,19 @@ Path::isAbsolute() const {
return false;
return path[0] == '/';
}
+
+void Path::makeAbsolute() {
+ if (isAbsolute())
+ return;
+
+ Path CWD = Path::GetCurrentDirectory();
+ assert(CWD.isAbsolute() && "GetCurrentDirectory returned relative path!");
+
+ CWD.appendComponent(path);
+
+ path = CWD.str();
+}
+
Path
Path::GetRootDirectory() {
Path result;
@@ -331,7 +340,17 @@ getprogpath(char ret[PATH_MAX], const char *bin)
/// GetMainExecutable - Return the path to the main executable, given the
/// value of argv[0] from program startup.
Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
-#if defined(__FreeBSD__)
+#if defined(__APPLE__)
+ // On OS X the executable path is saved to the stack by dyld. Reading it
+ // from there is much faster than calling dladdr, especially for large
+ // binaries with symbols.
+ char exe_path[MAXPATHLEN];
+ uint32_t size = sizeof(exe_path);
+ if (_NSGetExecutablePath(exe_path, &size) == 0) {
+ char link_path[MAXPATHLEN];
+ return Path(std::string(realpath(exe_path, link_path)));
+ }
+#elif defined(__FreeBSD__)
char exe_path[PATH_MAX];
if (getprogpath(exe_path, argv0) != NULL)
@@ -339,10 +358,8 @@ Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
#elif defined(__linux__) || defined(__CYGWIN__)
char exe_path[MAXPATHLEN];
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
- if (len > 0 && len < MAXPATHLEN - 1) {
- exe_path[len] = '\0';
- return Path(std::string(exe_path));
- }
+ if (len >= 0)
+ return Path(std::string(exe_path, len));
#elif defined(HAVE_DLFCN_H)
// Use dladdr to get executable path if available.
Dl_info DLInfo;
@@ -397,7 +414,9 @@ Path::getSuffix() const {
bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
assert(len < 1024 && "Request for magic string too long");
- char* buf = (char*) alloca(1 + len);
+ SmallVector<char, 128> Buf;
+ Buf.resize(1 + len);
+ char* buf = Buf.data();
int fd = ::open(path.c_str(), O_RDONLY);
if (fd < 0)
return false;
@@ -426,12 +445,12 @@ Path::isDirectory() const {
bool
Path::canRead() const {
- return 0 == access(path.c_str(), F_OK | R_OK );
+ return 0 == access(path.c_str(), R_OK);
}
bool
Path::canWrite() const {
- return 0 == access(path.c_str(), F_OK | W_OK );
+ return 0 == access(path.c_str(), W_OK);
}
bool
@@ -499,7 +518,7 @@ static bool AddPermissionBits(const Path &File, int bits) {
// Get the file's current mode.
struct stat buf;
- if (0 != stat(File.toString().c_str(), &buf))
+ if (0 != stat(File.c_str(), &buf))
return false;
// Change the file to have whichever permissions bits from 'bits'
// that the umask would not disable.
@@ -631,7 +650,7 @@ Path::eraseSuffix() {
static bool createDirectoryHelper(char* beg, char* end, bool create_parents) {
- if (access(beg, F_OK | R_OK | W_OK) == 0)
+ if (access(beg, R_OK | W_OK) == 0)
return false;
if (create_parents) {
@@ -756,7 +775,7 @@ bool
Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
if (0 != ::rename(path.c_str(), newName.c_str()))
return MakeErrMsg(ErrMsg, std::string("can't rename '") + path + "' as '" +
- newName.toString() + "'");
+ newName.str() + "'");
return false;
}
@@ -778,13 +797,13 @@ sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
int outFile = -1;
inFile = ::open(Src.c_str(), O_RDONLY);
if (inFile == -1)
- return MakeErrMsg(ErrMsg, Src.toString() +
+ return MakeErrMsg(ErrMsg, Src.str() +
": can't open source file to copy");
outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666);
if (outFile == -1) {
::close(inFile);
- return MakeErrMsg(ErrMsg, Dest.toString() +
+ return MakeErrMsg(ErrMsg, Dest.str() +
": can't create destination file for copy");
}
@@ -794,7 +813,7 @@ sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
if (errno != EINTR && errno != EAGAIN) {
::close(inFile);
::close(outFile);
- return MakeErrMsg(ErrMsg, Src.toString()+": can't read source file");
+ return MakeErrMsg(ErrMsg, Src.str()+": can't read source file");
}
} else {
char *BufPtr = Buffer;
@@ -804,7 +823,7 @@ sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
if (errno != EINTR && errno != EAGAIN) {
::close(inFile);
::close(outFile);
- return MakeErrMsg(ErrMsg, Dest.toString() +
+ return MakeErrMsg(ErrMsg, Dest.str() +
": can't write destination file");
}
} else {
@@ -826,7 +845,9 @@ Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
// Append an XXXXXX pattern to the end of the file for use with mkstemp,
// mktemp or our own implementation.
- char *FNBuffer = (char*) alloca(path.size()+8);
+ SmallVector<char, 128> Buf;
+ Buf.resize(path.size()+8);
+ char *FNBuffer = Buf.data();
path.copy(FNBuffer,path.size());
if (isDirectory())
strcpy(FNBuffer+path.size(), "/XXXXXX");
diff --git a/lib/System/Unix/Process.inc b/lib/System/Unix/Process.inc
index 2da31c9..94e4c1b 100644
--- a/lib/System/Unix/Process.inc
+++ b/lib/System/Unix/Process.inc
@@ -46,11 +46,11 @@ Process::GetPageSize()
// On Cygwin, getpagesize() returns 64k but the page size for the purposes of
// memory protection and mmap() is 4k.
// See http://www.cygwin.com/ml/cygwin/2009-01/threads.html#00492
- static const int page_size = 0x1000;
+ const int page_size = 0x1000;
#elif defined(HAVE_GETPAGESIZE)
- static const int page_size = ::getpagesize();
+ const int page_size = ::getpagesize();
#elif defined(HAVE_SYSCONF)
- static long page_size = ::sysconf(_SC_PAGE_SIZE);
+ long page_size = ::sysconf(_SC_PAGE_SIZE);
#else
#warning Cannot get the page size on this machine
#endif
@@ -91,7 +91,7 @@ Process::GetTotalMemoryUsage()
malloc_statistics_t Stats;
malloc_zone_statistics(malloc_default_zone(), &Stats);
return Stats.size_allocated; // darwin
-#elif defined(HAVE_GETRUSAGE)
+#elif defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
struct rusage usage;
::getrusage(RUSAGE_SELF, &usage);
return usage.ru_maxrss;
@@ -179,27 +179,24 @@ void Process::PreventCoreFiles() {
}
bool Process::StandardInIsUserInput() {
-#if HAVE_ISATTY
- return isatty(0);
-#endif
- // If we don't have isatty, just return false.
- return false;
+ return FileDescriptorIsDisplayed(STDIN_FILENO);
}
bool Process::StandardOutIsDisplayed() {
-#if HAVE_ISATTY
- return isatty(1);
-#endif
- // If we don't have isatty, just return false.
- return false;
+ return FileDescriptorIsDisplayed(STDOUT_FILENO);
}
bool Process::StandardErrIsDisplayed() {
+ return FileDescriptorIsDisplayed(STDERR_FILENO);
+}
+
+bool Process::FileDescriptorIsDisplayed(int fd) {
#if HAVE_ISATTY
- return isatty(2);
-#endif
+ return isatty(fd);
+#else
// If we don't have isatty, just return false.
return false;
+#endif
}
static unsigned getColumns(int FileID) {
diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc
index cdc6fee..56dea25 100644
--- a/lib/System/Unix/Program.inc
+++ b/lib/System/Unix/Program.inc
@@ -1,10 +1,10 @@
//===- llvm/System/Unix/Program.cpp -----------------------------*- C++ -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific portion of the Program class.
@@ -18,7 +18,6 @@
#include <llvm/Config/config.h>
#include "Unix.h"
-#include <iostream>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
@@ -35,6 +34,15 @@
namespace llvm {
using namespace sys;
+Program::Program() : Data_(0) {}
+
+Program::~Program() {}
+
+unsigned Program::GetPid() const {
+ uint64_t pid = reinterpret_cast<uint64_t>(Data_);
+ return static_cast<unsigned>(pid);
+}
+
// This function just uses the PATH environment variable to find the program.
Path
Program::FindProgramByName(const std::string& progName) {
@@ -45,16 +53,17 @@ Program::FindProgramByName(const std::string& progName) {
Path temp;
if (!temp.set(progName)) // invalid name
return Path();
- // FIXME: have to check for absolute filename - we cannot assume anything
- // about "." being in $PATH
- if (temp.canExecute()) // already executable as is
+ // Use the given path verbatim if it contains any slashes; this matches
+ // the behavior of sh(1) and friends.
+ if (progName.find('/') != std::string::npos)
return temp;
- // At this point, the file name is valid and its not executable
-
+ // At this point, the file name does not contain slashes. Search for it
+ // through the directories specified in the PATH environment variable.
+
// Get the path. If its empty, we can't do anything to find it.
const char *PathStr = getenv("PATH");
- if (PathStr == 0)
+ if (PathStr == 0)
return Path();
// Now we have a colon separated list of directories to search; try them.
@@ -93,7 +102,7 @@ static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
// Redirect empty paths to /dev/null
File = "/dev/null";
else
- File = Path->toString();
+ File = Path->str();
// Open the file
int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
@@ -112,11 +121,6 @@ static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
return false;
}
-static bool Timeout = false;
-static void TimeOutHandler(int Sig) {
- Timeout = true;
-}
-
static void SetMemoryLimits (unsigned size)
{
#if HAVE_SYS_RESOURCE_H
@@ -142,49 +146,47 @@ static void SetMemoryLimits (unsigned size)
#endif
}
-int
-Program::ExecuteAndWait(const Path& path,
- const char** args,
- const char** envp,
- const Path** redirects,
- unsigned secondsToWait,
- unsigned memoryLimit,
- std::string* ErrMsg)
+bool
+Program::Execute(const Path& path,
+ const char** args,
+ const char** envp,
+ const Path** redirects,
+ unsigned memoryLimit,
+ std::string* ErrMsg)
{
if (!path.canExecute()) {
if (ErrMsg)
- *ErrMsg = path.toString() + " is not executable";
- return -1;
+ *ErrMsg = path.str() + " is not executable";
+ return false;
}
-#ifdef HAVE_SYS_WAIT_H
// Create a child process.
int child = fork();
switch (child) {
// An error occured: Return to the caller.
case -1:
MakeErrMsg(ErrMsg, "Couldn't fork");
- return -1;
+ return false;
// Child process: Execute the program.
case 0: {
// Redirect file descriptors...
if (redirects) {
// Redirect stdin
- if (RedirectIO(redirects[0], 0, ErrMsg)) { return -1; }
+ if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
// Redirect stdout
- if (RedirectIO(redirects[1], 1, ErrMsg)) { return -1; }
- if (redirects[1] && redirects[2] &&
+ if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
+ if (redirects[1] && redirects[2] &&
*(redirects[1]) == *(redirects[2])) {
// If stdout and stderr should go to the same place, redirect stderr
// to the FD already open for stdout.
if (-1 == dup2(1,2)) {
MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
- return -1;
+ return false;
}
} else {
// Just redirect stderr
- if (RedirectIO(redirects[2], 2, ErrMsg)) { return -1; }
+ if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
}
}
@@ -192,15 +194,19 @@ Program::ExecuteAndWait(const Path& path,
if (memoryLimit!=0) {
SetMemoryLimits(memoryLimit);
}
-
+
// Execute!
if (envp != 0)
- execve (path.c_str(), (char**)args, (char**)envp);
+ execve(path.c_str(), (char**)args, (char**)envp);
else
- execv (path.c_str(), (char**)args);
- // If the execve() failed, we should exit and let the parent pick up
- // our non-zero exit status.
- exit (errno);
+ execv(path.c_str(), (char**)args);
+ // 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
+ // object destructors cloned from the parent process aren't
+ // redundantly run, and so that any data buffered in stdio buffers
+ // cloned from the parent aren't redundantly written out.
+ _exit(errno == ENOENT ? 127 : 126);
}
// Parent process: Break out of the switch to do our processing.
@@ -208,32 +214,41 @@ Program::ExecuteAndWait(const Path& path,
break;
}
- // Make sure stderr and stdout have been flushed
- std::cerr << std::flush;
- std::cout << std::flush;
- fsync(1);
- fsync(2);
+ Data_ = reinterpret_cast<void*>(child);
+
+ return true;
+}
+int
+Program::Wait(unsigned secondsToWait,
+ std::string* ErrMsg)
+{
+#ifdef HAVE_SYS_WAIT_H
struct sigaction Act, Old;
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return -1;
+ }
+
// Install a timeout handler.
if (secondsToWait) {
- Timeout = false;
- Act.sa_sigaction = 0;
- Act.sa_handler = TimeOutHandler;
+ memset(&Act, 0, sizeof(Act));
+ Act.sa_handler = SIG_IGN;
sigemptyset(&Act.sa_mask);
- Act.sa_flags = 0;
sigaction(SIGALRM, &Act, &Old);
alarm(secondsToWait);
}
// Parent process: Wait for the child process to terminate.
int status;
+ uint64_t pid = reinterpret_cast<uint64_t>(Data_);
+ pid_t child = static_cast<pid_t>(pid);
while (wait(&status) != child)
if (secondsToWait && errno == EINTR) {
// Kill the child.
kill(child, SIGKILL);
-
+
// Turn off the alarm and restore the signal handler
alarm(0);
sigaction(SIGALRM, &Old, 0);
@@ -271,7 +286,25 @@ Program::ExecuteAndWait(const Path& path,
#else
return -99;
#endif
-
+
+}
+
+bool
+Program::Kill(std::string* ErrMsg) {
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return true;
+ }
+
+ uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
+ pid_t pid = static_cast<pid_t>(pid64);
+
+ if (kill(pid, SIGKILL) != 0) {
+ MakeErrMsg(ErrMsg, "The process couldn't be killed!");
+ return true;
+ }
+
+ return false;
}
bool Program::ChangeStdinToBinary(){
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc
index e385e0c..d39e1e9 100644
--- a/lib/System/Unix/Signals.inc
+++ b/lib/System/Unix/Signals.inc
@@ -14,6 +14,7 @@
#include "Unix.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/System/Mutex.h"
#include <vector>
#include <algorithm>
#if HAVE_EXECINFO_H
@@ -33,6 +34,8 @@ using namespace llvm;
static RETSIGTYPE SignalHandler(int Sig); // defined below.
+static SmartMutex<true> SignalsMutex;
+
/// InterruptFunction - The function to call if ctrl-c is pressed.
static void (*InterruptFunction)() = 0;
@@ -113,6 +116,7 @@ static RETSIGTYPE SignalHandler(int Sig) {
sigfillset(&SigMask);
sigprocmask(SIG_UNBLOCK, &SigMask, 0);
+ SignalsMutex.acquire();
if (FilesToRemove != 0)
while (!FilesToRemove->empty()) {
FilesToRemove->back().eraseFromDisk(true);
@@ -122,14 +126,19 @@ static RETSIGTYPE SignalHandler(int Sig) {
if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
if (InterruptFunction) {
void (*IF)() = InterruptFunction;
+ SignalsMutex.release();
InterruptFunction = 0;
IF(); // run the interrupt function.
return;
}
+
+ SignalsMutex.release();
raise(Sig); // Execute the default handler.
return;
}
+ SignalsMutex.release();
+
// Otherwise if it is a fault (like SEGV) run any handler.
if (CallBacksToRun)
for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
@@ -139,18 +148,23 @@ static RETSIGTYPE SignalHandler(int Sig) {
void llvm::sys::SetInterruptFunction(void (*IF)()) {
+ SignalsMutex.acquire();
InterruptFunction = IF;
+ SignalsMutex.release();
RegisterHandlers();
}
// RemoveFileOnSignal - The public API
bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
std::string* ErrMsg) {
+ SignalsMutex.acquire();
if (FilesToRemove == 0)
FilesToRemove = new std::vector<sys::Path>();
FilesToRemove->push_back(Filename);
+ SignalsMutex.release();
+
RegisterHandlers();
return false;
}
diff --git a/lib/System/Unix/TimeValue.inc b/lib/System/Unix/TimeValue.inc
index 8dd30b9..1ae8c71 100644
--- a/lib/System/Unix/TimeValue.inc
+++ b/lib/System/Unix/TimeValue.inc
@@ -21,7 +21,7 @@
namespace llvm {
using namespace sys;
-std::string TimeValue::toString() const {
+std::string TimeValue::str() const {
char buffer[32];
time_t ourTime = time_t(this->toEpochTime());
OpenPOWER on IntegriCloud