summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/System/Win32
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/System/Win32')
-rw-r--r--contrib/llvm/lib/System/Win32/Alarm.inc43
-rw-r--r--contrib/llvm/lib/System/Win32/DynamicLibrary.inc200
-rw-r--r--contrib/llvm/lib/System/Win32/Host.inc23
-rw-r--r--contrib/llvm/lib/System/Win32/Memory.inc73
-rw-r--r--contrib/llvm/lib/System/Win32/Mutex.inc58
-rw-r--r--contrib/llvm/lib/System/Win32/Path.inc874
-rw-r--r--contrib/llvm/lib/System/Win32/Process.inc221
-rw-r--r--contrib/llvm/lib/System/Win32/Program.inc409
-rw-r--r--contrib/llvm/lib/System/Win32/RWMutex.inc58
-rw-r--r--contrib/llvm/lib/System/Win32/Signals.inc318
-rw-r--r--contrib/llvm/lib/System/Win32/ThreadLocal.inc49
-rw-r--r--contrib/llvm/lib/System/Win32/TimeValue.inc51
-rw-r--r--contrib/llvm/lib/System/Win32/Win32.h57
13 files changed, 2434 insertions, 0 deletions
diff --git a/contrib/llvm/lib/System/Win32/Alarm.inc b/contrib/llvm/lib/System/Win32/Alarm.inc
new file mode 100644
index 0000000..e0d00a0
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Alarm.inc
@@ -0,0 +1,43 @@
+//===-- Alarm.inc - Implement Win32 Alarm Support ---------------*- 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 Win32 Alarm support.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cassert>
+using namespace llvm;
+
+/// NestedSOI - Sanity check. Alarms cannot be nested or run in parallel.
+/// This ensures that they never do.
+static bool NestedSOI = false;
+
+void sys::SetupAlarm(unsigned seconds) {
+ assert(!NestedSOI && "sys::SetupAlarm calls cannot be nested!");
+ NestedSOI = true;
+ // FIXME: Implement for Win32
+}
+
+void sys::TerminateAlarm() {
+ assert(NestedSOI && "sys::TerminateAlarm called without sys::SetupAlarm!");
+ // FIXME: Implement for Win32
+ NestedSOI = false;
+}
+
+int sys::AlarmStatus() {
+ // FIXME: Implement for Win32
+ return 0;
+}
+
+// Don't pull in all of the Windows headers.
+extern "C" void __stdcall Sleep(unsigned long);
+
+void sys::Sleep(unsigned n) {
+ ::Sleep(n*1000);
+}
diff --git a/contrib/llvm/lib/System/Win32/DynamicLibrary.inc b/contrib/llvm/lib/System/Win32/DynamicLibrary.inc
new file mode 100644
index 0000000..c9a89e5
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/DynamicLibrary.inc
@@ -0,0 +1,200 @@
+//===- Win32/DynamicLibrary.cpp - Win32 DL Implementation -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of DynamicLibrary.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+
+#ifdef __MINGW32__
+ #include <imagehlp.h>
+#else
+ #include <dbghelp.h>
+#endif
+
+#ifdef _MSC_VER
+ #include <ntverp.h>
+#endif
+
+#ifdef __MINGW32__
+ #if (HAVE_LIBIMAGEHLP != 1)
+ #error "libimagehlp.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "dbghelp.lib")
+#endif
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code.
+//===----------------------------------------------------------------------===//
+
+static std::vector<HMODULE> OpenedHandles;
+
+#ifdef _WIN64
+ typedef DWORD64 ModuleBaseType;
+#else
+ typedef ULONG ModuleBaseType;
+#endif
+
+extern "C" {
+// Use old callback if:
+// - Not using Visual Studio
+// - Visual Studio 2005 or earlier but only if we are not using the Windows SDK
+// or Windows SDK version is older than 6.0
+// Use new callback if:
+// - Newer Visual Studio (comes with newer SDK).
+// - Visual Studio 2005 with Windows SDK 6.0+
+#if !defined(_MSC_VER) || _MSC_VER < 1500 && (!defined(VER_PRODUCTBUILD) || VER_PRODUCTBUILD < 6000)
+ static BOOL CALLBACK ELM_Callback(PSTR ModuleName,
+ ModuleBaseType ModuleBase,
+ ULONG ModuleSize,
+ PVOID UserContext)
+#else
+ static BOOL CALLBACK ELM_Callback(PCSTR ModuleName,
+ ModuleBaseType ModuleBase,
+ ULONG ModuleSize,
+ PVOID UserContext)
+#endif
+ {
+ // Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded
+ // into the process.
+ if (stricmp(ModuleName, "msvci70") != 0 &&
+ stricmp(ModuleName, "msvcirt") != 0 &&
+ stricmp(ModuleName, "msvcp50") != 0 &&
+ stricmp(ModuleName, "msvcp60") != 0 &&
+ stricmp(ModuleName, "msvcp70") != 0 &&
+ stricmp(ModuleName, "msvcr70") != 0 &&
+#ifndef __MINGW32__
+ // Mingw32 uses msvcrt.dll by default. Don't ignore it.
+ // Otherwise, user should be aware, what he's doing :)
+ stricmp(ModuleName, "msvcrt") != 0 &&
+#endif
+ stricmp(ModuleName, "msvcrt20") != 0 &&
+ stricmp(ModuleName, "msvcrt40") != 0) {
+ OpenedHandles.push_back((HMODULE)ModuleBase);
+ }
+ return TRUE;
+ }
+}
+
+bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
+ std::string *ErrMsg) {
+ if (filename) {
+ HMODULE a_handle = LoadLibrary(filename);
+
+ if (a_handle == 0)
+ return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : ");
+
+ OpenedHandles.push_back(a_handle);
+ } else {
+ // When no file is specified, enumerate all DLLs and EXEs in the
+ // process.
+ EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
+ }
+
+ // Because we don't remember the handle, we will never free it; hence,
+ // it is loaded permanently.
+ return false;
+}
+
+// Stack probing routines are in the support library (e.g. libgcc), but we don't
+// have dynamic linking on windows. Provide a hook.
+#if defined(__MINGW32__) || defined (_MSC_VER)
+ #define EXPLICIT_SYMBOL(SYM) \
+ if (!strcmp(symbolName, #SYM)) return (void*)&SYM
+ #define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
+ if (!strcmp(symbolName, #SYMFROM)) return (void*)&SYMTO
+ #define EXPLICIT_SYMBOL_DEF(SYM) \
+ extern "C" { extern void *SYM; }
+
+ #if defined(__MINGW32__)
+ EXPLICIT_SYMBOL_DEF(_alloca)
+ EXPLICIT_SYMBOL_DEF(__main)
+ EXPLICIT_SYMBOL_DEF(__ashldi3)
+ EXPLICIT_SYMBOL_DEF(__ashrdi3)
+ EXPLICIT_SYMBOL_DEF(__cmpdi2)
+ EXPLICIT_SYMBOL_DEF(__divdi3)
+ EXPLICIT_SYMBOL_DEF(__fixdfdi)
+ EXPLICIT_SYMBOL_DEF(__fixsfdi)
+ EXPLICIT_SYMBOL_DEF(__fixunsdfdi)
+ EXPLICIT_SYMBOL_DEF(__fixunssfdi)
+ EXPLICIT_SYMBOL_DEF(__floatdidf)
+ EXPLICIT_SYMBOL_DEF(__floatdisf)
+ EXPLICIT_SYMBOL_DEF(__lshrdi3)
+ EXPLICIT_SYMBOL_DEF(__moddi3)
+ EXPLICIT_SYMBOL_DEF(__udivdi3)
+ EXPLICIT_SYMBOL_DEF(__umoddi3)
+ #elif defined(_MSC_VER)
+ EXPLICIT_SYMBOL_DEF(_alloca_probe)
+ #endif
+#endif
+
+void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
+ // First check symbols added via AddSymbol().
+ if (ExplicitSymbols) {
+ std::map<std::string, void *>::iterator I =
+ ExplicitSymbols->find(symbolName);
+ std::map<std::string, void *>::iterator E = ExplicitSymbols->end();
+ if (I != E)
+ return I->second;
+ }
+
+ // Now search the libraries.
+ for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(),
+ E = OpenedHandles.end(); I != E; ++I) {
+ FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
+ if (ptr) {
+ return (void *) ptr;
+ }
+ }
+
+#if defined(__MINGW32__)
+ {
+ EXPLICIT_SYMBOL(_alloca);
+ EXPLICIT_SYMBOL(__main);
+ EXPLICIT_SYMBOL(__ashldi3);
+ EXPLICIT_SYMBOL(__ashrdi3);
+ EXPLICIT_SYMBOL(__cmpdi2);
+ EXPLICIT_SYMBOL(__divdi3);
+ EXPLICIT_SYMBOL(__fixdfdi);
+ EXPLICIT_SYMBOL(__fixsfdi);
+ EXPLICIT_SYMBOL(__fixunsdfdi);
+ EXPLICIT_SYMBOL(__fixunssfdi);
+ EXPLICIT_SYMBOL(__floatdidf);
+ EXPLICIT_SYMBOL(__floatdisf);
+ EXPLICIT_SYMBOL(__lshrdi3);
+ EXPLICIT_SYMBOL(__moddi3);
+ EXPLICIT_SYMBOL(__udivdi3);
+ EXPLICIT_SYMBOL(__umoddi3);
+
+ EXPLICIT_SYMBOL2(alloca, _alloca);
+#undef EXPLICIT_SYMBOL
+#undef EXPLICIT_SYMBOL2
+#undef EXPLICIT_SYMBOL_DEF
+ }
+#elif defined(_MSC_VER)
+ {
+ EXPLICIT_SYMBOL2(alloca, _alloca_probe);
+ EXPLICIT_SYMBOL2(_alloca, _alloca_probe);
+#undef EXPLICIT_SYMBOL
+#undef EXPLICIT_SYMBOL2
+#undef EXPLICIT_SYMBOL_DEF
+ }
+#endif
+
+ return 0;
+}
+
+}
+
diff --git a/contrib/llvm/lib/System/Win32/Host.inc b/contrib/llvm/lib/System/Win32/Host.inc
new file mode 100644
index 0000000..18f00f8
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Host.inc
@@ -0,0 +1,23 @@
+//===- llvm/System/Win32/Host.inc -------------------------------*- 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 Win32 Host support.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include <cstdio>
+#include <string>
+
+using namespace llvm;
+
+std::string sys::getHostTriple() {
+ // FIXME: Adapt to running version.
+ return LLVM_HOSTTRIPLE;
+}
diff --git a/contrib/llvm/lib/System/Win32/Memory.inc b/contrib/llvm/lib/System/Win32/Memory.inc
new file mode 100644
index 0000000..19fccbd
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Memory.inc
@@ -0,0 +1,73 @@
+//===- Win32/Memory.cpp - Win32 Memory Implementation -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of various Memory
+// management utilities
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include "llvm/System/DataTypes.h"
+#include "llvm/System/Process.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+MemoryBlock Memory::AllocateRWX(size_t NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg) {
+ if (NumBytes == 0) return MemoryBlock();
+
+ static const size_t pageSize = Process::GetPageSize();
+ size_t NumPages = (NumBytes+pageSize-1)/pageSize;
+
+ //FIXME: support NearBlock if ever needed on Win64.
+
+ void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE);
+ if (pa == NULL) {
+ MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: ");
+ return MemoryBlock();
+ }
+
+ MemoryBlock result;
+ result.Address = pa;
+ result.Size = NumPages*pageSize;
+ return result;
+}
+
+bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
+ if (M.Address == 0 || M.Size == 0) return false;
+ if (!VirtualFree(M.Address, 0, MEM_RELEASE))
+ return MakeErrMsg(ErrMsg, "Can't release RWX Memory: ");
+ return false;
+}
+
+bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) {
+ return true;
+}
+
+bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) {
+ return false;
+}
+
+bool Memory::setRangeWritable(const void *Addr, size_t Size) {
+ return true;
+}
+
+bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
+ return false;
+}
+
+}
diff --git a/contrib/llvm/lib/System/Win32/Mutex.inc b/contrib/llvm/lib/System/Win32/Mutex.inc
new file mode 100644
index 0000000..75f01fe
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Mutex.inc
@@ -0,0 +1,58 @@
+//===- llvm/System/Win32/Mutex.inc - Win32 Mutex Implementation -*- 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 Win32 specific (non-pthread) Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include "llvm/System/Mutex.h"
+
+namespace llvm {
+using namespace sys;
+
+MutexImpl::MutexImpl(bool /*recursive*/)
+{
+ data_ = new CRITICAL_SECTION;
+ InitializeCriticalSection((LPCRITICAL_SECTION)data_);
+}
+
+MutexImpl::~MutexImpl()
+{
+ DeleteCriticalSection((LPCRITICAL_SECTION)data_);
+ delete (LPCRITICAL_SECTION)data_;
+ data_ = 0;
+}
+
+bool
+MutexImpl::acquire()
+{
+ EnterCriticalSection((LPCRITICAL_SECTION)data_);
+ return true;
+}
+
+bool
+MutexImpl::release()
+{
+ LeaveCriticalSection((LPCRITICAL_SECTION)data_);
+ return true;
+}
+
+bool
+MutexImpl::tryacquire()
+{
+ return TryEnterCriticalSection((LPCRITICAL_SECTION)data_);
+}
+
+}
diff --git a/contrib/llvm/lib/System/Win32/Path.inc b/contrib/llvm/lib/System/Win32/Path.inc
new file mode 100644
index 0000000..5a0052f
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Path.inc
@@ -0,0 +1,874 @@
+//===- llvm/System/Win32/Path.cpp - Win32 Path Implementation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// Modified by Henrik Bach to comply with at least MinGW.
+// Ported to Win32 by Jeff Cohen.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Path class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include <malloc.h>
+#include <cstdio>
+
+// We need to undo a macro defined in Windows.h, otherwise we won't compile:
+#undef CopyFile
+#undef GetCurrentDirectory
+
+// Windows happily accepts either forward or backward slashes, though any path
+// returned by a Win32 API will have backward slashes. As LLVM code basically
+// assumes forward slashes are used, backward slashs are converted where they
+// can be introduced into a path.
+//
+// Another invariant is that a path ends with a slash if and only if the path
+// is a root directory. Any other use of a trailing slash is stripped. Unlike
+// in Unix, Windows has a rather complicated notion of a root path and this
+// invariant helps simply the code.
+
+static void FlipBackSlashes(std::string& s) {
+ for (size_t i = 0; i < s.size(); i++)
+ if (s[i] == '\\')
+ s[i] = '/';
+}
+
+namespace llvm {
+namespace sys {
+const char PathSeparator = ';';
+
+Path::Path(llvm::StringRef p)
+ : path(p) {
+ FlipBackSlashes(path);
+}
+
+Path::Path(const char *StrStart, unsigned StrLen)
+ : path(StrStart, StrLen) {
+ FlipBackSlashes(path);
+}
+
+Path&
+Path::operator=(StringRef that) {
+ path.assign(that.data(), that.size());
+ FlipBackSlashes(path);
+ return *this;
+}
+
+bool
+Path::isValid() const {
+ if (path.empty())
+ return false;
+
+ // If there is a colon, it must be the second character, preceded by a letter
+ // and followed by something.
+ size_t len = path.size();
+ size_t pos = path.rfind(':',len);
+ size_t rootslash = 0;
+ if (pos != std::string::npos) {
+ if (pos != 1 || !isalpha(path[0]) || len < 3)
+ return false;
+ rootslash = 2;
+ }
+
+ // Look for a UNC path, and if found adjust our notion of the root slash.
+ if (len > 3 && path[0] == '/' && path[1] == '/') {
+ rootslash = path.find('/', 2);
+ if (rootslash == std::string::npos)
+ rootslash = 0;
+ }
+
+ // Check for illegal characters.
+ if (path.find_first_of("\\<>\"|\001\002\003\004\005\006\007\010\011\012"
+ "\013\014\015\016\017\020\021\022\023\024\025\026"
+ "\027\030\031\032\033\034\035\036\037")
+ != std::string::npos)
+ return false;
+
+ // Remove trailing slash, unless it's a root slash.
+ if (len > rootslash+1 && path[len-1] == '/')
+ path.erase(--len);
+
+ // Check each component for legality.
+ for (pos = 0; pos < len; ++pos) {
+ // A component may not end in a space.
+ if (path[pos] == ' ') {
+ if (path[pos+1] == '/' || path[pos+1] == '\0')
+ return false;
+ }
+
+ // A component may not end in a period.
+ if (path[pos] == '.') {
+ if (path[pos+1] == '/' || path[pos+1] == '\0') {
+ // Unless it is the pseudo-directory "."...
+ if (pos == 0 || path[pos-1] == '/' || path[pos-1] == ':')
+ return true;
+ // or "..".
+ if (pos > 0 && path[pos-1] == '.') {
+ if (pos == 1 || path[pos-2] == '/' || path[pos-2] == ':')
+ return true;
+ }
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void Path::makeAbsolute() {
+ TCHAR FullPath[MAX_PATH + 1] = {0};
+ LPTSTR FilePart = NULL;
+
+ DWORD RetLength = ::GetFullPathNameA(path.c_str(),
+ sizeof(FullPath)/sizeof(FullPath[0]),
+ FullPath, &FilePart);
+
+ if (0 == RetLength) {
+ // FIXME: Report the error GetLastError()
+ assert(0 && "Unable to make absolute path!");
+ } else if (RetLength > MAX_PATH) {
+ // FIXME: Report too small buffer (needed RetLength bytes).
+ assert(0 && "Unable to make absolute path!");
+ } else {
+ path = FullPath;
+ }
+}
+
+bool
+Path::isAbsolute(const char *NameStart, unsigned NameLen) {
+ assert(NameStart);
+ // FIXME: This does not handle correctly an absolute path starting from
+ // a drive letter or in UNC format.
+ switch (NameLen) {
+ case 0:
+ return false;
+ case 1:
+ case 2:
+ return NameStart[0] == '/';
+ default:
+ return (NameStart[0] == '/' || (NameStart[1] == ':' && NameStart[2] == '/')) ||
+ (NameStart[0] == '\\' || (NameStart[1] == ':' && NameStart[2] == '\\'));
+ }
+}
+
+bool
+Path::isAbsolute() const {
+ // FIXME: This does not handle correctly an absolute path starting from
+ // a drive letter or in UNC format.
+ switch (path.length()) {
+ case 0:
+ return false;
+ case 1:
+ case 2:
+ return path[0] == '/';
+ default:
+ return path[0] == '/' || (path[1] == ':' && path[2] == '/');
+ }
+}
+
+static Path *TempDirectory;
+
+Path
+Path::GetTemporaryDirectory(std::string* ErrMsg) {
+ if (TempDirectory)
+ return *TempDirectory;
+
+ char pathname[MAX_PATH];
+ if (!GetTempPath(MAX_PATH, pathname)) {
+ if (ErrMsg)
+ *ErrMsg = "Can't determine temporary directory";
+ return Path();
+ }
+
+ Path result;
+ result.set(pathname);
+
+ // Append a subdirectory passed on our process id so multiple LLVMs don't
+ // step on each other's toes.
+#ifdef __MINGW32__
+ // Mingw's Win32 header files are broken.
+ sprintf(pathname, "LLVM_%u", unsigned(GetCurrentProcessId()));
+#else
+ sprintf(pathname, "LLVM_%u", GetCurrentProcessId());
+#endif
+ result.appendComponent(pathname);
+
+ // If there's a directory left over from a previous LLVM execution that
+ // happened to have the same process id, get rid of it.
+ result.eraseFromDisk(true);
+
+ // And finally (re-)create the empty directory.
+ result.createDirectoryOnDisk(false);
+ TempDirectory = new Path(result);
+ return *TempDirectory;
+}
+
+// FIXME: the following set of functions don't map to Windows very well.
+Path
+Path::GetRootDirectory() {
+ Path result;
+ result.set("C:/");
+ return result;
+}
+
+void
+Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
+ Paths.push_back(sys::Path("C:/WINDOWS/SYSTEM32"));
+ Paths.push_back(sys::Path("C:/WINDOWS"));
+}
+
+void
+Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
+ char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
+ if (env_var != 0) {
+ getPathList(env_var,Paths);
+ }
+#ifdef LLVM_LIBDIR
+ {
+ Path tmpPath;
+ if (tmpPath.set(LLVM_LIBDIR))
+ if (tmpPath.canRead())
+ Paths.push_back(tmpPath);
+ }
+#endif
+ GetSystemLibraryPaths(Paths);
+}
+
+Path
+Path::GetLLVMDefaultConfigDir() {
+ // TODO: this isn't going to fly on Windows
+ return Path("/etc/llvm");
+}
+
+Path
+Path::GetUserHomeDirectory() {
+ // TODO: Typical Windows setup doesn't define HOME.
+ const char* home = getenv("HOME");
+ if (home) {
+ Path result;
+ if (result.set(home))
+ return result;
+ }
+ return GetRootDirectory();
+}
+
+Path
+Path::GetCurrentDirectory() {
+ char pathname[MAX_PATH];
+ ::GetCurrentDirectoryA(MAX_PATH,pathname);
+ return Path(pathname);
+}
+
+/// 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) {
+ char pathname[MAX_PATH];
+ DWORD ret = ::GetModuleFileNameA(NULL, pathname, MAX_PATH);
+ return ret != MAX_PATH ? Path(pathname) : Path();
+}
+
+
+// FIXME: the above set of functions don't map to Windows very well.
+
+
+bool
+Path::isRootDirectory() const {
+ size_t len = path.size();
+ return len > 0 && path[len-1] == '/';
+}
+
+StringRef Path::getDirname() const {
+ return getDirnameCharSep(path, "/");
+}
+
+StringRef
+Path::getBasename() const {
+ // Find the last slash
+ size_t slash = path.rfind('/');
+ if (slash == std::string::npos)
+ slash = 0;
+ else
+ slash++;
+
+ size_t dot = path.rfind('.');
+ if (dot == std::string::npos || dot < slash)
+ return StringRef(path).substr(slash);
+ else
+ return StringRef(path).substr(slash, dot - slash);
+}
+
+StringRef
+Path::getSuffix() const {
+ // Find the last slash
+ size_t slash = path.rfind('/');
+ if (slash == std::string::npos)
+ slash = 0;
+ else
+ slash++;
+
+ size_t dot = path.rfind('.');
+ if (dot == std::string::npos || dot < slash)
+ return StringRef("");
+ else
+ return StringRef(path).substr(dot + 1);
+}
+
+bool
+Path::exists() const {
+ DWORD attr = GetFileAttributes(path.c_str());
+ return attr != INVALID_FILE_ATTRIBUTES;
+}
+
+bool
+Path::isDirectory() const {
+ DWORD attr = GetFileAttributes(path.c_str());
+ return (attr != INVALID_FILE_ATTRIBUTES) &&
+ (attr & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+bool
+Path::canRead() const {
+ // FIXME: take security attributes into account.
+ DWORD attr = GetFileAttributes(path.c_str());
+ return attr != INVALID_FILE_ATTRIBUTES;
+}
+
+bool
+Path::canWrite() const {
+ // FIXME: take security attributes into account.
+ DWORD attr = GetFileAttributes(path.c_str());
+ return (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_READONLY);
+}
+
+bool
+Path::canExecute() const {
+ // FIXME: take security attributes into account.
+ DWORD attr = GetFileAttributes(path.c_str());
+ return attr != INVALID_FILE_ATTRIBUTES;
+}
+
+bool
+Path::isRegularFile() const {
+ if (isDirectory())
+ return false;
+ return true;
+}
+
+StringRef
+Path::getLast() const {
+ // Find the last slash
+ size_t pos = path.rfind('/');
+
+ // Handle the corner cases
+ if (pos == std::string::npos)
+ return path;
+
+ // If the last character is a slash, we have a root directory
+ if (pos == path.length()-1)
+ return path;
+
+ // Return everything after the last slash
+ return StringRef(path).substr(pos+1);
+}
+
+const FileStatus *
+PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
+ if (!fsIsValid || update) {
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
+ MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
+ ": Can't get status: ");
+ return 0;
+ }
+
+ status.fileSize = fi.nFileSizeHigh;
+ status.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
+ status.fileSize += fi.nFileSizeLow;
+
+ status.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
+ status.user = 9999; // Not applicable to Windows, so...
+ status.group = 9999; // Not applicable to Windows, so...
+
+ // FIXME: this is only unique if the file is accessed by the same file path.
+ // How do we do this for C:\dir\file and ..\dir\file ? Unix has inode
+ // numbers, but the concept doesn't exist in Windows.
+ status.uniqueID = 0;
+ for (unsigned i = 0; i < path.length(); ++i)
+ status.uniqueID += path[i];
+
+ __int64 ft = *reinterpret_cast<__int64*>(&fi.ftLastWriteTime);
+ status.modTime.fromWin32Time(ft);
+
+ status.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ fsIsValid = true;
+ }
+ return &status;
+}
+
+bool Path::makeReadableOnDisk(std::string* ErrMsg) {
+ // All files are readable on Windows (ignoring security attributes).
+ return false;
+}
+
+bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
+ DWORD attr = GetFileAttributes(path.c_str());
+
+ // If it doesn't exist, we're done.
+ if (attr == INVALID_FILE_ATTRIBUTES)
+ return false;
+
+ if (attr & FILE_ATTRIBUTE_READONLY) {
+ if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) {
+ MakeErrMsg(ErrMsg, std::string(path) + ": Can't make file writable: ");
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
+ // All files are executable on Windows (ignoring security attributes).
+ return false;
+}
+
+bool
+Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
+ MakeErrMsg(ErrMsg, path + ": can't get status of file");
+ return true;
+ }
+
+ if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (ErrMsg)
+ *ErrMsg = path + ": not a directory";
+ return true;
+ }
+
+ result.clear();
+ WIN32_FIND_DATA fd;
+ std::string searchpath = path;
+ if (path.size() == 0 || searchpath[path.size()-1] == '/')
+ searchpath += "*";
+ else
+ searchpath += "/*";
+
+ HANDLE h = FindFirstFile(searchpath.c_str(), &fd);
+ if (h == INVALID_HANDLE_VALUE) {
+ if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ return true; // not really an error, now is it?
+ MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
+ return true;
+ }
+
+ do {
+ if (fd.cFileName[0] == '.')
+ continue;
+ Path aPath(path);
+ aPath.appendComponent(&fd.cFileName[0]);
+ result.insert(aPath);
+ } while (FindNextFile(h, &fd));
+
+ DWORD err = GetLastError();
+ FindClose(h);
+ if (err != ERROR_NO_MORE_FILES) {
+ SetLastError(err);
+ MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
+ return true;
+ }
+ return false;
+}
+
+bool
+Path::set(StringRef a_path) {
+ if (a_path.empty())
+ return false;
+ std::string save(path);
+ path = a_path;
+ FlipBackSlashes(path);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+}
+
+bool
+Path::appendComponent(StringRef name) {
+ if (name.empty())
+ return false;
+ std::string save(path);
+ if (!path.empty()) {
+ size_t last = path.size() - 1;
+ if (path[last] != '/')
+ path += '/';
+ }
+ path += name;
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+}
+
+bool
+Path::eraseComponent() {
+ size_t slashpos = path.rfind('/',path.size());
+ if (slashpos == path.size() - 1 || slashpos == std::string::npos)
+ return false;
+ std::string save(path);
+ path.erase(slashpos);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+}
+
+bool
+Path::appendSuffix(StringRef suffix) {
+ std::string save(path);
+ path.append(".");
+ path.append(suffix);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+}
+
+bool
+Path::eraseSuffix() {
+ size_t dotpos = path.rfind('.',path.size());
+ size_t slashpos = path.rfind('/',path.size());
+ if (dotpos != std::string::npos) {
+ if (slashpos == std::string::npos || dotpos > slashpos+1) {
+ std::string save(path);
+ path.erase(dotpos, path.size()-dotpos);
+ if (!isValid()) {
+ path = save;
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool PathMsg(std::string* ErrMsg, const char* pathname, const char*msg) {
+ if (ErrMsg)
+ *ErrMsg = std::string(pathname) + ": " + std::string(msg);
+ return true;
+}
+
+bool
+Path::createDirectoryOnDisk(bool create_parents, std::string* ErrMsg) {
+ // Get a writeable copy of the path name
+ size_t len = path.length();
+ char *pathname = reinterpret_cast<char *>(_alloca(len+2));
+ path.copy(pathname, len);
+ pathname[len] = 0;
+
+ // Make sure it ends with a slash.
+ if (len == 0 || pathname[len - 1] != '/') {
+ pathname[len] = '/';
+ pathname[++len] = 0;
+ }
+
+ // Determine starting point for initial / search.
+ char *next = pathname;
+ if (pathname[0] == '/' && pathname[1] == '/') {
+ // Skip host name.
+ next = strchr(pathname+2, '/');
+ if (next == NULL)
+ return PathMsg(ErrMsg, pathname, "badly formed remote directory");
+
+ // Skip share name.
+ next = strchr(next+1, '/');
+ if (next == NULL)
+ return PathMsg(ErrMsg, pathname,"badly formed remote directory");
+
+ next++;
+ if (*next == 0)
+ return PathMsg(ErrMsg, pathname, "badly formed remote directory");
+
+ } else {
+ if (pathname[1] == ':')
+ next += 2; // skip drive letter
+ if (*next == '/')
+ next++; // skip root directory
+ }
+
+ // If we're supposed to create intermediate directories
+ if (create_parents) {
+ // Loop through the directory components until we're done
+ while (*next) {
+ next = strchr(next, '/');
+ *next = 0;
+ if (!CreateDirectory(pathname, NULL) &&
+ GetLastError() != ERROR_ALREADY_EXISTS)
+ return MakeErrMsg(ErrMsg,
+ std::string(pathname) + ": Can't create directory: ");
+ *next++ = '/';
+ }
+ } else {
+ // Drop trailing slash.
+ pathname[len-1] = 0;
+ if (!CreateDirectory(pathname, NULL) &&
+ GetLastError() != ERROR_ALREADY_EXISTS) {
+ return MakeErrMsg(ErrMsg, std::string(pathname) + ": Can't create directory: ");
+ }
+ }
+ return false;
+}
+
+bool
+Path::createFileOnDisk(std::string* ErrMsg) {
+ // Create the file
+ HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return MakeErrMsg(ErrMsg, path + ": Can't create file: ");
+
+ CloseHandle(h);
+ return false;
+}
+
+bool
+Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
+ return true;
+
+ if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ // If it doesn't exist, we're done.
+ if (!exists())
+ return false;
+
+ char *pathname = reinterpret_cast<char *>(_alloca(path.length()+3));
+ int lastchar = path.length() - 1 ;
+ path.copy(pathname, lastchar+1);
+
+ // Make path end with '/*'.
+ if (pathname[lastchar] != '/')
+ pathname[++lastchar] = '/';
+ pathname[lastchar+1] = '*';
+ pathname[lastchar+2] = 0;
+
+ if (remove_contents) {
+ WIN32_FIND_DATA fd;
+ HANDLE h = FindFirstFile(pathname, &fd);
+
+ // It's a bad idea to alter the contents of a directory while enumerating
+ // its contents. So build a list of its contents first, then destroy them.
+
+ if (h != INVALID_HANDLE_VALUE) {
+ std::vector<Path> list;
+
+ do {
+ if (strcmp(fd.cFileName, ".") == 0)
+ continue;
+ if (strcmp(fd.cFileName, "..") == 0)
+ continue;
+
+ Path aPath(path);
+ aPath.appendComponent(&fd.cFileName[0]);
+ list.push_back(aPath);
+ } while (FindNextFile(h, &fd));
+
+ DWORD err = GetLastError();
+ FindClose(h);
+ if (err != ERROR_NO_MORE_FILES) {
+ SetLastError(err);
+ return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
+ }
+
+ for (std::vector<Path>::iterator I = list.begin(); I != list.end();
+ ++I) {
+ Path &aPath = *I;
+ aPath.eraseFromDisk(true);
+ }
+ } else {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
+ }
+ }
+
+ pathname[lastchar] = 0;
+ if (!RemoveDirectory(pathname))
+ return MakeErrMsg(ErrStr,
+ std::string(pathname) + ": Can't destroy directory: ");
+ return false;
+ } else {
+ // Read-only files cannot be deleted on Windows. Must remove the read-only
+ // attribute first.
+ if (fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ if (!SetFileAttributes(path.c_str(),
+ fi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
+ return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
+ }
+
+ if (!DeleteFile(path.c_str()))
+ return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
+ return false;
+ }
+}
+
+bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
+ assert(len < 1024 && "Request for magic string too long");
+ char* buf = (char*) alloca(1 + len);
+
+ HANDLE h = CreateFile(path.c_str(),
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return false;
+
+ DWORD nRead = 0;
+ BOOL ret = ReadFile(h, buf, len, &nRead, NULL);
+ CloseHandle(h);
+
+ if (!ret || nRead != len)
+ return false;
+
+ buf[len] = '\0';
+ Magic = buf;
+ return true;
+}
+
+bool
+Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
+ if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
+ return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path
+ + "': ");
+ return false;
+}
+
+bool
+Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrMsg) const {
+ // FIXME: should work on directories also.
+ if (!si.isFile) {
+ return true;
+ }
+
+ HANDLE h = CreateFile(path.c_str(),
+ FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return true;
+
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ if (!GetFileInformationByHandle(h, &bhfi)) {
+ DWORD err = GetLastError();
+ CloseHandle(h);
+ SetLastError(err);
+ return MakeErrMsg(ErrMsg, path + ": GetFileInformationByHandle: ");
+ }
+
+ FILETIME ft;
+ (uint64_t&)ft = si.modTime.toWin32Time();
+ BOOL ret = SetFileTime(h, NULL, &ft, &ft);
+ DWORD err = GetLastError();
+ CloseHandle(h);
+ if (!ret) {
+ SetLastError(err);
+ return MakeErrMsg(ErrMsg, path + ": SetFileTime: ");
+ }
+
+ // Best we can do with Unix permission bits is to interpret the owner
+ // writable bit.
+ if (si.mode & 0200) {
+ if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ if (!SetFileAttributes(path.c_str(),
+ bhfi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
+ return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
+ }
+ } else {
+ if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
+ if (!SetFileAttributes(path.c_str(),
+ bhfi.dwFileAttributes | FILE_ATTRIBUTE_READONLY))
+ return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
+ }
+ }
+
+ return false;
+}
+
+bool
+CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg) {
+ // Can't use CopyFile macro defined in Windows.h because it would mess up the
+ // above line. We use the expansion it would have in a non-UNICODE build.
+ if (!::CopyFileA(Src.c_str(), Dest.c_str(), false))
+ return MakeErrMsg(ErrMsg, "Can't copy '" + Src.str() +
+ "' to '" + Dest.str() + "': ");
+ return false;
+}
+
+bool
+Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
+ if (reuse_current && !exists())
+ return false; // File doesn't exist already, just use it!
+
+ // Reserve space for -XXXXXX at the end.
+ char *FNBuffer = (char*) alloca(path.size()+8);
+ unsigned offset = path.size();
+ path.copy(FNBuffer, offset);
+
+ // Find a numeric suffix that isn't used by an existing file. Assume there
+ // won't be more than 1 million files with the same prefix. Probably a safe
+ // bet.
+ static unsigned FCounter = 0;
+ do {
+ sprintf(FNBuffer+offset, "-%06u", FCounter);
+ if (++FCounter > 999999)
+ FCounter = 0;
+ path = FNBuffer;
+ } while (exists());
+ return false;
+}
+
+bool
+Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
+ // Make this into a unique file name
+ makeUnique(reuse_current, ErrMsg);
+
+ // Now go and create it
+ HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return MakeErrMsg(ErrMsg, path + ": can't create file");
+
+ CloseHandle(h);
+ return false;
+}
+
+/// MapInFilePages - Not yet implemented on win32.
+const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
+ return 0;
+}
+
+/// MapInFilePages - Not yet implemented on win32.
+void Path::UnMapFilePages(const char *Base, uint64_t FileSize) {
+ assert(0 && "NOT IMPLEMENTED");
+}
+
+}
+}
diff --git a/contrib/llvm/lib/System/Win32/Process.inc b/contrib/llvm/lib/System/Win32/Process.inc
new file mode 100644
index 0000000..feb0806
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Process.inc
@@ -0,0 +1,221 @@
+//===- Win32/Process.cpp - Win32 Process Implementation ------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include <psapi.h>
+#include <malloc.h>
+#include <io.h>
+
+#ifdef __MINGW32__
+ #if (HAVE_LIBPSAPI != 1)
+ #error "libpsapi.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "psapi.lib")
+#endif
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+#ifdef __MINGW32__
+// This ban should be lifted when MinGW 1.0+ has defined this value.
+# define _HEAPOK (-2)
+#endif
+
+namespace llvm {
+using namespace sys;
+
+// This function retrieves the page size using GetSystemInfo and is present
+// solely so it can be called once in Process::GetPageSize to initialize the
+// static variable PageSize.
+inline unsigned GetPageSizeOnce() {
+ // NOTE: A 32-bit application running under WOW64 is supposed to use
+ // GetNativeSystemInfo. However, this interface is not present prior
+ // to Windows XP so to use it requires dynamic linking. It is not clear
+ // how this affects the reported page size, if at all. One could argue
+ // that LLVM ought to run as 64-bits on a 64-bit system, anyway.
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ return static_cast<unsigned>(info.dwPageSize);
+}
+
+unsigned
+Process::GetPageSize() {
+ static const unsigned PageSize = GetPageSizeOnce();
+ return PageSize;
+}
+
+size_t
+Process::GetMallocUsage()
+{
+ _HEAPINFO hinfo;
+ hinfo._pentry = NULL;
+
+ size_t size = 0;
+
+ while (_heapwalk(&hinfo) == _HEAPOK)
+ size += hinfo._size;
+
+ return size;
+}
+
+size_t
+Process::GetTotalMemoryUsage()
+{
+ PROCESS_MEMORY_COUNTERS pmc;
+ GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
+ return pmc.PagefileUsage;
+}
+
+void
+Process::GetTimeUsage(
+ TimeValue& elapsed, TimeValue& user_time, TimeValue& sys_time)
+{
+ elapsed = TimeValue::now();
+
+ uint64_t ProcCreate, ProcExit, KernelTime, UserTime;
+ GetProcessTimes(GetCurrentProcess(), (FILETIME*)&ProcCreate,
+ (FILETIME*)&ProcExit, (FILETIME*)&KernelTime,
+ (FILETIME*)&UserTime);
+
+ // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
+ user_time.seconds( UserTime / 10000000 );
+ user_time.nanoseconds( unsigned(UserTime % 10000000) * 100 );
+ sys_time.seconds( KernelTime / 10000000 );
+ sys_time.nanoseconds( unsigned(KernelTime % 10000000) * 100 );
+}
+
+int Process::GetCurrentUserId()
+{
+ return 65536;
+}
+
+int Process::GetCurrentGroupId()
+{
+ return 65536;
+}
+
+// Some LLVM programs such as bugpoint produce core files as a normal part of
+// their operation. To prevent the disk from filling up, this configuration item
+// does what's necessary to prevent their generation.
+void Process::PreventCoreFiles() {
+ // Windows doesn't do core files, but it does do modal pop-up message
+ // boxes. As this method is used by bugpoint, preventing these pop-ups
+ // is the moral equivalent of suppressing core files.
+ SetErrorMode(SEM_FAILCRITICALERRORS |
+ SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+}
+
+bool Process::StandardInIsUserInput() {
+ return FileDescriptorIsDisplayed(0);
+}
+
+bool Process::StandardOutIsDisplayed() {
+ return FileDescriptorIsDisplayed(1);
+}
+
+bool Process::StandardErrIsDisplayed() {
+ return FileDescriptorIsDisplayed(2);
+}
+
+bool Process::FileDescriptorIsDisplayed(int fd) {
+ return GetFileType((HANDLE)_get_osfhandle(fd)) == FILE_TYPE_CHAR;
+}
+
+unsigned Process::StandardOutColumns() {
+ unsigned Columns = 0;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ Columns = csbi.dwSize.X;
+ return Columns;
+}
+
+unsigned Process::StandardErrColumns() {
+ unsigned Columns = 0;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &csbi))
+ Columns = csbi.dwSize.X;
+ return Columns;
+}
+
+// It always has colors.
+bool Process::StandardErrHasColors() {
+ return StandardErrIsDisplayed();
+}
+
+bool Process::StandardOutHasColors() {
+ return StandardOutIsDisplayed();
+}
+
+namespace {
+class DefaultColors
+{
+ private:
+ WORD defaultColor;
+ public:
+ DefaultColors()
+ :defaultColor(GetCurrentColor()) {}
+ static unsigned GetCurrentColor() {
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
+ return csbi.wAttributes;
+ return 0;
+ }
+ WORD operator()() const { return defaultColor; }
+};
+
+DefaultColors defaultColors;
+}
+
+bool Process::ColorNeedsFlush() {
+ return true;
+}
+
+const char *Process::OutputBold(bool bg) {
+ WORD colors = DefaultColors::GetCurrentColor();
+ if (bg)
+ colors |= BACKGROUND_INTENSITY;
+ else
+ colors |= FOREGROUND_INTENSITY;
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+const char *Process::OutputColor(char code, bool bold, bool bg) {
+ WORD colors;
+ if (bg) {
+ colors = ((code&1) ? BACKGROUND_RED : 0) |
+ ((code&2) ? BACKGROUND_GREEN : 0 ) |
+ ((code&4) ? BACKGROUND_BLUE : 0);
+ if (bold)
+ colors |= BACKGROUND_INTENSITY;
+ } else {
+ colors = ((code&1) ? FOREGROUND_RED : 0) |
+ ((code&2) ? FOREGROUND_GREEN : 0 ) |
+ ((code&4) ? FOREGROUND_BLUE : 0);
+ if (bold)
+ colors |= FOREGROUND_INTENSITY;
+ }
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colors);
+ return 0;
+}
+
+const char *Process::ResetColor() {
+ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
+ return 0;
+}
+
+}
diff --git a/contrib/llvm/lib/System/Win32/Program.inc b/contrib/llvm/lib/System/Win32/Program.inc
new file mode 100644
index 0000000..16bb28e
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Program.inc
@@ -0,0 +1,409 @@
+//===- Win32/Program.cpp - Win32 Program Implementation ------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include <cstdio>
+#include <malloc.h>
+#include <io.h>
+#include <fcntl.h>
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+namespace {
+ struct Win32ProcessInfo {
+ HANDLE hProcess;
+ DWORD dwProcessId;
+ };
+}
+
+namespace llvm {
+using namespace sys;
+
+Program::Program() : Data_(0) {}
+
+Program::~Program() {
+ if (Data_) {
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ CloseHandle(wpi->hProcess);
+ delete wpi;
+ Data_ = 0;
+ }
+}
+
+unsigned Program::GetPid() const {
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ return wpi->dwProcessId;
+}
+
+// This function just uses the PATH environment variable to find the program.
+Path
+Program::FindProgramByName(const std::string& progName) {
+
+ // Check some degenerate cases
+ if (progName.length() == 0) // no program
+ return Path();
+ Path temp;
+ if (!temp.set(progName)) // invalid name
+ return Path();
+ if (temp.canExecute()) // already executable as is
+ return temp;
+
+ // At this point, the file name is valid and its not executable.
+ // Let Windows search for it.
+ char buffer[MAX_PATH];
+ char *dummy = NULL;
+ DWORD len = SearchPath(NULL, progName.c_str(), ".exe", MAX_PATH,
+ buffer, &dummy);
+
+ // See if it wasn't found.
+ if (len == 0)
+ return Path();
+
+ // See if we got the entire path.
+ if (len < MAX_PATH)
+ return Path(buffer);
+
+ // Buffer was too small; grow and retry.
+ while (true) {
+ char *b = reinterpret_cast<char *>(_alloca(len+1));
+ DWORD len2 = SearchPath(NULL, progName.c_str(), ".exe", len+1, b, &dummy);
+
+ // It is unlikely the search failed, but it's always possible some file
+ // was added or removed since the last search, so be paranoid...
+ if (len2 == 0)
+ return Path();
+ else if (len2 <= len)
+ return Path(b);
+
+ len = len2;
+ }
+}
+
+static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) {
+ HANDLE h;
+ if (path == 0) {
+ DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
+ GetCurrentProcess(), &h,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ return h;
+ }
+
+ const char *fname;
+ if (path->isEmpty())
+ fname = "NUL";
+ else
+ fname = path->c_str();
+
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = 0;
+ sa.bInheritHandle = TRUE;
+
+ h = CreateFile(fname, fd ? GENERIC_WRITE : GENERIC_READ, FILE_SHARE_READ,
+ &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
+ (fd ? "input: " : "output: "));
+ }
+
+ return h;
+}
+
+#ifdef __MINGW32__
+ // Due to unknown reason, mingw32's w32api doesn't have this declaration.
+ extern "C"
+ BOOL WINAPI SetInformationJobObject(HANDLE hJob,
+ JOBOBJECTINFOCLASS JobObjectInfoClass,
+ LPVOID lpJobObjectInfo,
+ DWORD cbJobObjectInfoLength);
+#endif
+
+/// ArgNeedsQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess.
+static bool ArgNeedsQuotes(const char *Str) {
+ return Str[0] == '\0' || strchr(Str, ' ') != 0;
+}
+
+
+/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
+/// CreateProcess and returns length of quoted arg with escaped quotes
+static unsigned int ArgLenWithQuotes(const char *Str) {
+ unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;
+
+ while (*Str != '\0') {
+ if (*Str == '\"')
+ ++len;
+
+ ++len;
+ ++Str;
+ }
+
+ return len;
+}
+
+
+bool
+Program::Execute(const Path& path,
+ const char** args,
+ const char** envp,
+ const Path** redirects,
+ unsigned memoryLimit,
+ std::string* ErrMsg) {
+ if (Data_) {
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ CloseHandle(wpi->hProcess);
+ delete wpi;
+ Data_ = 0;
+ }
+
+ if (!path.canExecute()) {
+ if (ErrMsg)
+ *ErrMsg = "program not executable";
+ return false;
+ }
+
+ // 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).
+
+ // First, determine the length of the command line.
+ unsigned len = 0;
+ for (unsigned i = 0; args[i]; i++) {
+ len += ArgLenWithQuotes(args[i]) + 1;
+ }
+
+ // Now build the command line.
+ char *command = reinterpret_cast<char *>(_alloca(len+1));
+ char *p = command;
+
+ for (unsigned i = 0; args[i]; i++) {
+ const char *arg = args[i];
+
+ bool needsQuoting = ArgNeedsQuotes(arg);
+ if (needsQuoting)
+ *p++ = '"';
+
+ while (*arg != '\0') {
+ if (*arg == '\"')
+ *p++ = '\\';
+
+ *p++ = *arg++;
+ }
+
+ if (needsQuoting)
+ *p++ = '"';
+ *p++ = ' ';
+ }
+
+ *p = 0;
+
+ // The pointer to the environment block for the new process.
+ char *envblock = 0;
+
+ if (envp) {
+ // 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.
+
+ // First, determine the length of the environment block.
+ len = 0;
+ for (unsigned i = 0; envp[i]; i++)
+ len += strlen(envp[i]) + 1;
+
+ // Now build the environment block.
+ envblock = reinterpret_cast<char *>(_alloca(len+1));
+ p = envblock;
+
+ for (unsigned i = 0; envp[i]; i++) {
+ const char *ev = envp[i];
+ size_t len = strlen(ev) + 1;
+ memcpy(p, ev, len);
+ p += len;
+ }
+
+ *p = 0;
+ }
+
+ // Create a child process.
+ STARTUPINFO si;
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.hStdInput = INVALID_HANDLE_VALUE;
+ si.hStdOutput = INVALID_HANDLE_VALUE;
+ si.hStdError = INVALID_HANDLE_VALUE;
+
+ if (redirects) {
+ si.dwFlags = STARTF_USESTDHANDLES;
+
+ si.hStdInput = RedirectIO(redirects[0], 0, ErrMsg);
+ if (si.hStdInput == INVALID_HANDLE_VALUE) {
+ MakeErrMsg(ErrMsg, "can't redirect stdin");
+ return false;
+ }
+ si.hStdOutput = RedirectIO(redirects[1], 1, ErrMsg);
+ if (si.hStdOutput == INVALID_HANDLE_VALUE) {
+ CloseHandle(si.hStdInput);
+ MakeErrMsg(ErrMsg, "can't redirect stdout");
+ 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 handle already open for stdout.
+ DuplicateHandle(GetCurrentProcess(), si.hStdOutput,
+ GetCurrentProcess(), &si.hStdError,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ } else {
+ // Just redirect stderr
+ si.hStdError = RedirectIO(redirects[2], 2, ErrMsg);
+ if (si.hStdError == INVALID_HANDLE_VALUE) {
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ MakeErrMsg(ErrMsg, "can't redirect stderr");
+ return false;
+ }
+ }
+ }
+
+ PROCESS_INFORMATION pi;
+ memset(&pi, 0, sizeof(pi));
+
+ fflush(stdout);
+ fflush(stderr);
+ BOOL rc = CreateProcess(path.c_str(), command, NULL, NULL, TRUE, 0,
+ envblock, NULL, &si, &pi);
+ DWORD err = GetLastError();
+
+ // Regardless of whether the process got created or not, we are done with
+ // the handles we created for it to inherit.
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ CloseHandle(si.hStdError);
+
+ // Now return an error if the process didn't get created.
+ if (!rc) {
+ SetLastError(err);
+ MakeErrMsg(ErrMsg, std::string("Couldn't execute program '") +
+ path.str() + "'");
+ return false;
+ }
+ Win32ProcessInfo* wpi = new Win32ProcessInfo;
+ wpi->hProcess = pi.hProcess;
+ wpi->dwProcessId = pi.dwProcessId;
+ Data_ = wpi;
+
+ // Make sure these get closed no matter what.
+ AutoHandle hThread(pi.hThread);
+
+ // Assign the process to a job if a memory limit is defined.
+ AutoHandle hJob(0);
+ if (memoryLimit != 0) {
+ hJob = CreateJobObject(0, 0);
+ bool success = false;
+ if (hJob != 0) {
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
+ memset(&jeli, 0, sizeof(jeli));
+ jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
+ jeli.ProcessMemoryLimit = uintptr_t(memoryLimit) * 1048576;
+ if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
+ &jeli, sizeof(jeli))) {
+ if (AssignProcessToJobObject(hJob, pi.hProcess))
+ success = true;
+ }
+ }
+ if (!success) {
+ SetLastError(GetLastError());
+ MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
+ TerminateProcess(pi.hProcess, 1);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int
+Program::Wait(unsigned secondsToWait,
+ std::string* ErrMsg) {
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return -1;
+ }
+
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ HANDLE hProcess = wpi->hProcess;
+
+ // Wait for the process to terminate.
+ DWORD millisecondsToWait = INFINITE;
+ if (secondsToWait > 0)
+ millisecondsToWait = secondsToWait * 1000;
+
+ if (WaitForSingleObject(hProcess, millisecondsToWait) == WAIT_TIMEOUT) {
+ if (!TerminateProcess(hProcess, 1)) {
+ MakeErrMsg(ErrMsg, "Failed to terminate timed-out program.");
+ return -1;
+ }
+ WaitForSingleObject(hProcess, INFINITE);
+ }
+
+ // Get its exit status.
+ DWORD status;
+ BOOL rc = GetExitCodeProcess(hProcess, &status);
+ DWORD err = GetLastError();
+
+ if (!rc) {
+ SetLastError(err);
+ MakeErrMsg(ErrMsg, "Failed getting status for program.");
+ return -1;
+ }
+
+ return status;
+}
+
+bool
+Program::Kill(std::string* ErrMsg) {
+ if (Data_ == 0) {
+ MakeErrMsg(ErrMsg, "Process not started!");
+ return true;
+ }
+
+ Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
+ HANDLE hProcess = wpi->hProcess;
+ if (TerminateProcess(hProcess, 1) == 0) {
+ MakeErrMsg(ErrMsg, "The process couldn't be killed!");
+ return true;
+ }
+
+ return false;
+}
+
+bool Program::ChangeStdinToBinary(){
+ int result = _setmode( _fileno(stdin), _O_BINARY );
+ return result == -1;
+}
+
+bool Program::ChangeStdoutToBinary(){
+ int result = _setmode( _fileno(stdout), _O_BINARY );
+ return result == -1;
+}
+
+bool Program::ChangeStderrToBinary(){
+ int result = _setmode( _fileno(stderr), _O_BINARY );
+ return result == -1;
+}
+
+}
diff --git a/contrib/llvm/lib/System/Win32/RWMutex.inc b/contrib/llvm/lib/System/Win32/RWMutex.inc
new file mode 100644
index 0000000..e269226
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/RWMutex.inc
@@ -0,0 +1,58 @@
+//= llvm/System/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =//
+//
+// 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 Win32 specific (non-pthread) RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+
+// FIXME: Windows does not have reader-writer locks pre-Vista. If you want
+// real reader-writer locks, you a pthreads implementation for Windows.
+
+namespace llvm {
+using namespace sys;
+
+RWMutexImpl::RWMutexImpl() {
+ data_ = calloc(1, sizeof(CRITICAL_SECTION));
+ InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+}
+
+RWMutexImpl::~RWMutexImpl() {
+ DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ free(data_);
+}
+
+bool RWMutexImpl::reader_acquire() {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+bool RWMutexImpl::reader_release() {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+bool RWMutexImpl::writer_acquire() {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+bool RWMutexImpl::writer_release() {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ return true;
+}
+
+
+}
diff --git a/contrib/llvm/lib/System/Win32/Signals.inc b/contrib/llvm/lib/System/Win32/Signals.inc
new file mode 100644
index 0000000..a3a393c
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Signals.inc
@@ -0,0 +1,318 @@
+//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the Signals class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include <stdio.h>
+#include <vector>
+#include <algorithm>
+
+#ifdef __MINGW32__
+ #include <imagehlp.h>
+#else
+ #include <dbghelp.h>
+#endif
+#include <psapi.h>
+
+#ifdef __MINGW32__
+ #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1))
+ #error "libimagehlp.a & libpsapi.a should be present"
+ #endif
+#else
+ #pragma comment(lib, "psapi.lib")
+ #pragma comment(lib, "dbghelp.lib")
+#endif
+
+// Forward declare.
+static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
+static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
+
+// InterruptFunction - The function to call if ctrl-c is pressed.
+static void (*InterruptFunction)() = 0;
+
+static std::vector<llvm::sys::Path> *FilesToRemove = NULL;
+static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
+static bool RegisteredUnhandledExceptionFilter = false;
+static bool CleanupExecuted = false;
+#ifdef _MSC_VER
+static bool ExitOnUnhandledExceptions = false;
+#endif
+static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
+
+// Windows creates a new thread to execute the console handler when an event
+// (such as CTRL/C) occurs. This causes concurrency issues with the above
+// globals which this critical section addresses.
+static CRITICAL_SECTION CriticalSection;
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code
+//=== and must not be UNIX code
+//===----------------------------------------------------------------------===//
+
+#ifdef _MSC_VER
+/// CRTReportHook - Function called on a CRT debugging event.
+static int CRTReportHook(int ReportType, char *Message, int *Return) {
+ // Don't cause a DebugBreak() on return.
+ if (Return)
+ *Return = 0;
+
+ switch (ReportType) {
+ default:
+ case _CRT_ASSERT:
+ fprintf(stderr, "CRT assert: %s\n", Message);
+ // FIXME: Is there a way to just crash? Perhaps throw to the unhandled
+ // exception code? Perhaps SetErrorMode() handles this.
+ _exit(3);
+ break;
+ case _CRT_ERROR:
+ fprintf(stderr, "CRT error: %s\n", Message);
+ // FIXME: Is there a way to just crash? Perhaps throw to the unhandled
+ // exception code? Perhaps SetErrorMode() handles this.
+ _exit(3);
+ break;
+ case _CRT_WARN:
+ fprintf(stderr, "CRT warn: %s\n", Message);
+ break;
+ }
+
+ // Don't call _CrtDbgReport.
+ return TRUE;
+}
+#endif
+
+static void RegisterHandler() {
+ if (RegisteredUnhandledExceptionFilter) {
+ EnterCriticalSection(&CriticalSection);
+ return;
+ }
+
+ // Now's the time to create the critical section. This is the first time
+ // through here, and there's only one thread.
+ InitializeCriticalSection(&CriticalSection);
+
+ // Enter it immediately. Now if someone hits CTRL/C, the console handler
+ // can't proceed until the globals are updated.
+ EnterCriticalSection(&CriticalSection);
+
+ RegisteredUnhandledExceptionFilter = true;
+ OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
+ SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
+
+ // Environment variable to disable any kind of crash dialog.
+#ifdef _MSC_VER
+ if (getenv("LLVM_DISABLE_CRT_DEBUG")) {
+ _CrtSetReportHook(CRTReportHook);
+ ExitOnUnhandledExceptions = true;
+ }
+#endif
+
+ // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
+ // else multi-threading problems will ensue.
+}
+
+// RemoveFileOnSignal - The public API
+bool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) {
+ RegisterHandler();
+
+ if (CleanupExecuted) {
+ if (ErrMsg)
+ *ErrMsg = "Process terminating -- cannot register for removal";
+ return true;
+ }
+
+ if (FilesToRemove == NULL)
+ FilesToRemove = new std::vector<sys::Path>;
+
+ FilesToRemove->push_back(Filename);
+
+ LeaveCriticalSection(&CriticalSection);
+ return false;
+}
+
+/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
+/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
+void sys::PrintStackTraceOnErrorSignal() {
+ RegisterHandler();
+ LeaveCriticalSection(&CriticalSection);
+}
+
+
+void sys::SetInterruptFunction(void (*IF)()) {
+ RegisterHandler();
+ InterruptFunction = IF;
+ LeaveCriticalSection(&CriticalSection);
+}
+
+
+/// AddSignalHandler - Add a function to be called when a signal is delivered
+/// to the process. The handler can have a cookie passed to it to identify
+/// what instance of the handler it is.
+void sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
+ if (CallBacksToRun == 0)
+ CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
+ CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
+ RegisterHandler();
+ LeaveCriticalSection(&CriticalSection);
+}
+}
+
+static void Cleanup() {
+ EnterCriticalSection(&CriticalSection);
+
+ // Prevent other thread from registering new files and directories for
+ // removal, should we be executing because of the console handler callback.
+ CleanupExecuted = true;
+
+ // FIXME: open files cannot be deleted.
+
+ if (FilesToRemove != NULL)
+ while (!FilesToRemove->empty()) {
+ FilesToRemove->back().eraseFromDisk();
+ FilesToRemove->pop_back();
+ }
+
+ if (CallBacksToRun)
+ for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
+ (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second);
+
+ LeaveCriticalSection(&CriticalSection);
+}
+
+void llvm::sys::RunInterruptHandlers() {
+ Cleanup();
+}
+
+static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
+ try {
+ Cleanup();
+
+#ifdef _WIN64
+ // TODO: provide a x64 friendly version of the following
+#else
+
+ // Initialize the STACKFRAME structure.
+ STACKFRAME StackFrame;
+ memset(&StackFrame, 0, sizeof(StackFrame));
+
+ StackFrame.AddrPC.Offset = ep->ContextRecord->Eip;
+ StackFrame.AddrPC.Mode = AddrModeFlat;
+ StackFrame.AddrStack.Offset = ep->ContextRecord->Esp;
+ StackFrame.AddrStack.Mode = AddrModeFlat;
+ StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp;
+ StackFrame.AddrFrame.Mode = AddrModeFlat;
+
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hThread = GetCurrentThread();
+
+ // Initialize the symbol handler.
+ SymSetOptions(SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES);
+ SymInitialize(hProcess, NULL, TRUE);
+
+ while (true) {
+ if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame,
+ ep->ContextRecord, NULL, SymFunctionTableAccess,
+ SymGetModuleBase, NULL)) {
+ break;
+ }
+
+ if (StackFrame.AddrFrame.Offset == 0)
+ break;
+
+ // Print the PC in hexadecimal.
+ DWORD PC = StackFrame.AddrPC.Offset;
+ fprintf(stderr, "%08lX", PC);
+
+ // Print the parameters. Assume there are four.
+ fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", StackFrame.Params[0],
+ StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3]);
+
+ // Verify the PC belongs to a module in this process.
+ if (!SymGetModuleBase(hProcess, PC)) {
+ fputs(" <unknown module>\n", stderr);
+ continue;
+ }
+
+ // Print the symbol name.
+ char buffer[512];
+ IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(buffer);
+ memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL));
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
+ symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL);
+
+ DWORD dwDisp;
+ if (!SymGetSymFromAddr(hProcess, PC, &dwDisp, symbol)) {
+ fputc('\n', stderr);
+ continue;
+ }
+
+ buffer[511] = 0;
+ if (dwDisp > 0)
+ fprintf(stderr, ", %s()+%04lu bytes(s)", symbol->Name, dwDisp);
+ else
+ fprintf(stderr, ", %s", symbol->Name);
+
+ // Print the source file and line number information.
+ IMAGEHLP_LINE line;
+ memset(&line, 0, sizeof(line));
+ line.SizeOfStruct = sizeof(line);
+ if (SymGetLineFromAddr(hProcess, PC, &dwDisp, &line)) {
+ fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber);
+ if (dwDisp > 0)
+ fprintf(stderr, "+%04lu byte(s)", dwDisp);
+ }
+
+ fputc('\n', stderr);
+ }
+
+#endif
+
+ } catch (...) {
+ assert(0 && "Crashed in LLVMUnhandledExceptionFilter");
+ }
+
+#ifdef _MSC_VER
+ if (ExitOnUnhandledExceptions)
+ _exit(-3);
+#endif
+
+ // Allow dialog box to pop up allowing choice to start debugger.
+ if (OldFilter)
+ return (*OldFilter)(ep);
+ else
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
+ // We are running in our very own thread, courtesy of Windows.
+ EnterCriticalSection(&CriticalSection);
+ Cleanup();
+
+ // If an interrupt function has been set, go and run one it; otherwise,
+ // the process dies.
+ void (*IF)() = InterruptFunction;
+ InterruptFunction = 0; // Don't run it on another CTRL-C.
+
+ if (IF) {
+ // Note: if the interrupt function throws an exception, there is nothing
+ // to catch it in this thread so it will kill the process.
+ IF(); // Run it now.
+ LeaveCriticalSection(&CriticalSection);
+ return TRUE; // Don't kill the process.
+ }
+
+ // Allow normal processing to take place; i.e., the process dies.
+ LeaveCriticalSection(&CriticalSection);
+ return FALSE;
+}
+
diff --git a/contrib/llvm/lib/System/Win32/ThreadLocal.inc b/contrib/llvm/lib/System/Win32/ThreadLocal.inc
new file mode 100644
index 0000000..c8f7840
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/ThreadLocal.inc
@@ -0,0 +1,49 @@
+//= llvm/System/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- 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 Win32 specific (non-pthread) ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include "llvm/System/ThreadLocal.h"
+
+namespace llvm {
+using namespace sys;
+
+ThreadLocalImpl::ThreadLocalImpl() {
+ DWORD* tls = new DWORD;
+ *tls = TlsAlloc();
+ assert(*tls != TLS_OUT_OF_INDEXES);
+ data = tls;
+}
+
+ThreadLocalImpl::~ThreadLocalImpl() {
+ DWORD* tls = static_cast<DWORD*>(data);
+ TlsFree(*tls);
+ delete tls;
+}
+
+const void* ThreadLocalImpl::getInstance() {
+ DWORD* tls = static_cast<DWORD*>(data);
+ return TlsGetValue(*tls);
+}
+
+void ThreadLocalImpl::setInstance(const void* d){
+ DWORD* tls = static_cast<DWORD*>(data);
+ int errorcode = TlsSetValue(*tls, const_cast<void*>(d));
+ assert(errorcode != 0);
+}
+
+}
diff --git a/contrib/llvm/lib/System/Win32/TimeValue.inc b/contrib/llvm/lib/System/Win32/TimeValue.inc
new file mode 100644
index 0000000..e37f111
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/TimeValue.inc
@@ -0,0 +1,51 @@
+//===- Win32/TimeValue.cpp - Win32 TimeValue Implementation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 implementation of the TimeValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+#include <time.h>
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only Win32 specific code.
+//===----------------------------------------------------------------------===//
+
+TimeValue TimeValue::now() {
+ uint64_t ft;
+ GetSystemTimeAsFileTime(reinterpret_cast<FILETIME *>(&ft));
+
+ TimeValue t(0, 0);
+ t.fromWin32Time(ft);
+ return t;
+}
+
+std::string TimeValue::str() const {
+#ifdef __MINGW32__
+ // This ban may be lifted by either:
+ // (i) a future MinGW version other than 1.0 inherents the __time64_t type, or
+ // (ii) configure tests for either the time_t or __time64_t type.
+ time_t ourTime = time_t(this->toEpochTime());
+ struct tm *lt = ::localtime(&ourTime);
+#else
+ __time64_t ourTime = this->toEpochTime();
+ struct tm *lt = ::_localtime64(&ourTime);
+#endif
+
+ char buffer[25];
+ strftime(buffer, 25, "%a %b %d %H:%M:%S %Y", lt);
+ return std::string(buffer);
+}
+
+
+}
diff --git a/contrib/llvm/lib/System/Win32/Win32.h b/contrib/llvm/lib/System/Win32/Win32.h
new file mode 100644
index 0000000..8f505b1
--- /dev/null
+++ b/contrib/llvm/lib/System/Win32/Win32.h
@@ -0,0 +1,57 @@
+//===- Win32/Win32.h - Common Win32 Include File ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines things specific to Win32 implementations.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic Win32 code that
+//=== is guaranteed to work on *all* Win32 variants.
+//===----------------------------------------------------------------------===//
+
+// Require at least Windows 2000 API.
+#define _WIN32_WINNT 0x0500
+
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "windows.h"
+#include <cassert>
+#include <string>
+
+inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
+ if (!ErrMsg)
+ return true;
+ char *buffer = NULL;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
+ *ErrMsg = prefix + buffer;
+ LocalFree(buffer);
+ return true;
+}
+
+class AutoHandle {
+ HANDLE handle;
+
+public:
+ AutoHandle(HANDLE h) : handle(h) {}
+
+ ~AutoHandle() {
+ if (handle)
+ CloseHandle(handle);
+ }
+
+ operator HANDLE() {
+ return handle;
+ }
+
+ AutoHandle &operator=(HANDLE h) {
+ handle = h;
+ return *this;
+ }
+};
OpenPOWER on IntegriCloud