summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support/Windows
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/Windows')
-rw-r--r--contrib/llvm/lib/Support/Windows/DynamicLibrary.inc72
-rw-r--r--contrib/llvm/lib/Support/Windows/Host.inc2
-rw-r--r--contrib/llvm/lib/Support/Windows/Path.inc378
-rw-r--r--contrib/llvm/lib/Support/Windows/Process.inc41
-rw-r--r--contrib/llvm/lib/Support/Windows/Program.inc200
-rw-r--r--contrib/llvm/lib/Support/Windows/RWMutex.inc8
-rw-r--r--contrib/llvm/lib/Support/Windows/ThreadLocal.inc2
-rw-r--r--contrib/llvm/lib/Support/Windows/WindowsSupport.h9
-rw-r--r--contrib/llvm/lib/Support/Windows/explicit_symbols.inc30
9 files changed, 392 insertions, 350 deletions
diff --git a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
index 5ed0b70..79d5f79 100644
--- a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
+++ b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc
@@ -41,32 +41,11 @@ using namespace sys;
static DenseSet<HMODULE> *OpenedHandles;
-extern "C" {
-
- static BOOL CALLBACK ELM_Callback(WIN32_ELMCB_PCSTR ModuleName,
- ULONG_PTR ModuleBase,
- ULONG ModuleSize,
- PVOID UserContext)
- {
- // 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 the user should be aware what they are doing.
- stricmp(ModuleName, "msvcrt") != 0 &&
-#endif
- stricmp(ModuleName, "msvcrt20") != 0 &&
- stricmp(ModuleName, "msvcrt40") != 0) {
- OpenedHandles->insert((HMODULE)ModuleBase);
- }
- return TRUE;
- }
+static BOOL CALLBACK
+ELM_Callback(WIN32_ELMCB_PCSTR ModuleName, ULONG_PTR ModuleBase,
+ ULONG ModuleSize, PVOID UserContext) {
+ OpenedHandles->insert((HMODULE)ModuleBase);
+ return TRUE;
}
DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
@@ -115,10 +94,24 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
extern "C" { extern void *SYM; }
#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) EXPLICIT_SYMBOL(SYMTO)
+#ifdef _M_IX86
+// Win32 on x86 implements certain single-precision math functions as macros.
+// These functions are not exported by the DLL, but will still be needed
+// for symbol-resolution by the JIT loader. Therefore, this Support libray
+// provides helper functions with the same implementation.
+
+#define INLINE_DEF_SYMBOL1(TYP, SYM) \
+ extern "C" TYP inline_##SYM(TYP _X) { return SYM(_X); }
+#define INLINE_DEF_SYMBOL2(TYP, SYM) \
+ extern "C" TYP inline_##SYM(TYP _X, TYP _Y) { return SYM(_X, _Y); }
+#endif
+
#include "explicit_symbols.inc"
#undef EXPLICIT_SYMBOL
#undef EXPLICIT_SYMBOL2
+#undef INLINE_DEF_SYMBOL1
+#undef INLINE_DEF_SYMBOL2
void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
SmartScopedLock<true> Lock(*SymbolsMutex);
@@ -142,22 +135,32 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
}
}
- #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(SYM) \
+ if (!strcmp(symbolName, #SYM)) \
+ return (void *)&SYM;
+#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
+ if (!strcmp(symbolName, #SYMFROM)) \
+ return (void *)&SYMTO;
+
+#ifdef _M_IX86
+#define INLINE_DEF_SYMBOL1(TYP, SYM) \
+ if (!strcmp(symbolName, #SYM)) \
+ return (void *)&inline_##SYM;
+#define INLINE_DEF_SYMBOL2(TYP, SYM) INLINE_DEF_SYMBOL1(TYP, SYM)
+#endif
{
- #include "explicit_symbols.inc"
+#include "explicit_symbols.inc"
}
- #undef EXPLICIT_SYMBOL
- #undef EXPLICIT_SYMBOL2
+#undef EXPLICIT_SYMBOL
+#undef EXPLICIT_SYMBOL2
+#undef INLINE_DEF_SYMBOL1
+#undef INLINE_DEF_SYMBOL2
return 0;
}
-
void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
if (!isValid())
return NULL;
@@ -166,5 +169,4 @@ void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
}
-
}
diff --git a/contrib/llvm/lib/Support/Windows/Host.inc b/contrib/llvm/lib/Support/Windows/Host.inc
index 0c02bf9..fe89fe0 100644
--- a/contrib/llvm/lib/Support/Windows/Host.inc
+++ b/contrib/llvm/lib/Support/Windows/Host.inc
@@ -1,4 +1,4 @@
-//===- llvm/Support/Win32/Host.inc -------------------------------*- C++ -*-===//
+//===- llvm/Support/Win32/Host.inc ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/contrib/llvm/lib/Support/Windows/Path.inc b/contrib/llvm/lib/Support/Windows/Path.inc
index 7a1bc0447..d8b5702 100644
--- a/contrib/llvm/lib/Support/Windows/Path.inc
+++ b/contrib/llvm/lib/Support/Windows/Path.inc
@@ -44,28 +44,12 @@ using namespace llvm;
using llvm::sys::windows::UTF8ToUTF16;
using llvm::sys::windows::UTF16ToUTF8;
+using llvm::sys::path::widenPath;
static std::error_code windows_error(DWORD E) {
return mapWindowsError(E);
}
-static std::error_code TempDir(SmallVectorImpl<char> &Result) {
- SmallVector<wchar_t, 64> Res;
-retry_temp_dir:
- DWORD Len = ::GetTempPathW(Res.capacity(), Res.begin());
-
- if (Len == 0)
- return windows_error(::GetLastError());
-
- if (Len > Res.capacity()) {
- Res.reserve(Len);
- goto retry_temp_dir;
- }
-
- Res.set_size(Len);
- return UTF16ToUTF8(Res.begin(), Res.size(), Result);
-}
-
static bool is_separator(const wchar_t value) {
switch (value) {
case L'\\':
@@ -78,6 +62,62 @@ static bool is_separator(const wchar_t value) {
namespace llvm {
namespace sys {
+namespace path {
+
+// Convert a UTF-8 path to UTF-16. Also, if the absolute equivalent of the
+// path is longer than CreateDirectory can tolerate, make it absolute and
+// prefixed by '\\?\'.
+std::error_code widenPath(const Twine &Path8,
+ SmallVectorImpl<wchar_t> &Path16) {
+ const size_t MaxDirLen = MAX_PATH - 12; // Must leave room for 8.3 filename.
+
+ // Several operations would convert Path8 to SmallString; more efficient to
+ // do it once up front.
+ SmallString<128> Path8Str;
+ Path8.toVector(Path8Str);
+
+ // If we made this path absolute, how much longer would it get?
+ size_t CurPathLen;
+ if (llvm::sys::path::is_absolute(Twine(Path8Str)))
+ CurPathLen = 0; // No contribution from current_path needed.
+ else {
+ CurPathLen = ::GetCurrentDirectoryW(0, NULL);
+ if (CurPathLen == 0)
+ return windows_error(::GetLastError());
+ }
+
+ // Would the absolute path be longer than our limit?
+ if ((Path8Str.size() + CurPathLen) >= MaxDirLen &&
+ !Path8Str.startswith("\\\\?\\")) {
+ SmallString<2*MAX_PATH> FullPath("\\\\?\\");
+ if (CurPathLen) {
+ SmallString<80> CurPath;
+ if (std::error_code EC = llvm::sys::fs::current_path(CurPath))
+ return EC;
+ FullPath.append(CurPath);
+ }
+ // Traverse the requested path, canonicalizing . and .. as we go (because
+ // the \\?\ prefix is documented to treat them as real components).
+ // The iterators don't report separators and append() always attaches
+ // preferred_separator so we don't need to call native() on the result.
+ for (llvm::sys::path::const_iterator I = llvm::sys::path::begin(Path8Str),
+ E = llvm::sys::path::end(Path8Str);
+ I != E; ++I) {
+ if (I->size() == 1 && *I == ".")
+ continue;
+ if (I->size() == 2 && *I == "..")
+ llvm::sys::path::remove_filename(FullPath);
+ else
+ llvm::sys::path::append(FullPath, *I);
+ }
+ return UTF8ToUTF16(FullPath, Path16);
+ }
+
+ // Just use the caller's original path.
+ return UTF8ToUTF16(Path8Str, Path16);
+}
+} // end namespace path
+
namespace fs {
std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
@@ -147,11 +187,9 @@ std::error_code current_path(SmallVectorImpl<char> &result) {
}
std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
- SmallString<128> path_storage;
SmallVector<wchar_t, 128> path_utf16;
- if (std::error_code ec =
- UTF8ToUTF16(path.toStringRef(path_storage), path_utf16))
+ if (std::error_code ec = widenPath(path, path_utf16))
return ec;
if (!::CreateDirectoryW(path_utf16.begin(), NULL)) {
@@ -163,25 +201,14 @@ std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
return std::error_code();
}
-std::error_code normalize_separators(SmallVectorImpl<char> &Path) {
- (void) Path;
- return std::error_code();
-}
-
// We can't use symbolic links for windows.
std::error_code create_link(const Twine &to, const Twine &from) {
- // Get arguments.
- SmallString<128> from_storage;
- SmallString<128> to_storage;
- StringRef f = from.toStringRef(from_storage);
- StringRef t = to.toStringRef(to_storage);
-
// Convert to utf-16.
SmallVector<wchar_t, 128> wide_from;
SmallVector<wchar_t, 128> wide_to;
- if (std::error_code ec = UTF8ToUTF16(f, wide_from))
+ if (std::error_code ec = widenPath(from, wide_from))
return ec;
- if (std::error_code ec = UTF8ToUTF16(t, wide_to))
+ if (std::error_code ec = widenPath(to, wide_to))
return ec;
if (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL))
@@ -191,7 +218,6 @@ std::error_code create_link(const Twine &to, const Twine &from) {
}
std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
- SmallString<128> path_storage;
SmallVector<wchar_t, 128> path_utf16;
file_status ST;
@@ -201,8 +227,7 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
return std::error_code();
}
- if (std::error_code ec =
- UTF8ToUTF16(path.toStringRef(path_storage), path_utf16))
+ if (std::error_code ec = widenPath(path, path_utf16))
return ec;
if (ST.type() == file_type::directory_file) {
@@ -222,18 +247,12 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
}
std::error_code rename(const Twine &from, const Twine &to) {
- // Get arguments.
- SmallString<128> from_storage;
- SmallString<128> to_storage;
- StringRef f = from.toStringRef(from_storage);
- StringRef t = to.toStringRef(to_storage);
-
// Convert to utf-16.
SmallVector<wchar_t, 128> wide_from;
SmallVector<wchar_t, 128> wide_to;
- if (std::error_code ec = UTF8ToUTF16(f, wide_from))
+ if (std::error_code ec = widenPath(from, wide_from))
return ec;
- if (std::error_code ec = UTF8ToUTF16(t, wide_to))
+ if (std::error_code ec = widenPath(to, wide_to))
return ec;
std::error_code ec = std::error_code();
@@ -253,69 +272,36 @@ std::error_code rename(const Twine &from, const Twine &to) {
return ec;
}
-std::error_code resize_file(const Twine &path, uint64_t size) {
- SmallString<128> path_storage;
- SmallVector<wchar_t, 128> path_utf16;
-
- if (std::error_code ec =
- UTF8ToUTF16(path.toStringRef(path_storage), path_utf16))
- return ec;
-
- int fd = ::_wopen(path_utf16.begin(), O_BINARY | _O_RDWR, S_IWRITE);
- if (fd == -1)
- return std::error_code(errno, std::generic_category());
+std::error_code resize_file(int FD, uint64_t Size) {
#ifdef HAVE__CHSIZE_S
- errno_t error = ::_chsize_s(fd, size);
+ errno_t error = ::_chsize_s(FD, Size);
#else
- errno_t error = ::_chsize(fd, size);
+ errno_t error = ::_chsize(FD, Size);
#endif
- ::close(fd);
return std::error_code(error, std::generic_category());
}
-std::error_code exists(const Twine &path, bool &result) {
- SmallString<128> path_storage;
- SmallVector<wchar_t, 128> path_utf16;
+std::error_code access(const Twine &Path, AccessMode Mode) {
+ SmallVector<wchar_t, 128> PathUtf16;
- if (std::error_code ec =
- UTF8ToUTF16(path.toStringRef(path_storage), path_utf16))
- return ec;
+ if (std::error_code EC = widenPath(Path, PathUtf16))
+ return EC;
- DWORD attributes = ::GetFileAttributesW(path_utf16.begin());
+ DWORD Attributes = ::GetFileAttributesW(PathUtf16.begin());
- if (attributes == INVALID_FILE_ATTRIBUTES) {
+ if (Attributes == INVALID_FILE_ATTRIBUTES) {
// See if the file didn't actually exist.
DWORD LastError = ::GetLastError();
if (LastError != ERROR_FILE_NOT_FOUND &&
LastError != ERROR_PATH_NOT_FOUND)
return windows_error(LastError);
- result = false;
- } else
- result = true;
- return std::error_code();
-}
-
-bool can_write(const Twine &Path) {
- // FIXME: take security attributes into account.
- SmallString<128> PathStorage;
- SmallVector<wchar_t, 128> PathUtf16;
-
- if (UTF8ToUTF16(Path.toStringRef(PathStorage), PathUtf16))
- return false;
-
- DWORD Attr = ::GetFileAttributesW(PathUtf16.begin());
- return (Attr != INVALID_FILE_ATTRIBUTES) && !(Attr & FILE_ATTRIBUTE_READONLY);
-}
-
-bool can_execute(const Twine &Path) {
- SmallString<128> PathStorage;
- SmallVector<wchar_t, 128> PathUtf16;
+ return errc::no_such_file_or_directory;
+ }
- if (UTF8ToUTF16(Path.toStringRef(PathStorage), PathUtf16))
- return false;
+ if (Mode == AccessMode::Write && (Attributes & FILE_ATTRIBUTE_READONLY))
+ return errc::permission_denied;
- DWORD Attr = ::GetFileAttributesW(PathUtf16.begin());
- return Attr != INVALID_FILE_ATTRIBUTES;
+ return std::error_code();
}
bool equivalent(file_status A, file_status B) {
@@ -424,7 +410,7 @@ std::error_code status(const Twine &path, file_status &result) {
return std::error_code();
}
- if (std::error_code ec = UTF8ToUTF16(path8, path_utf16))
+ if (std::error_code ec = widenPath(path8, path_utf16))
return ec;
DWORD attr = ::GetFileAttributesW(path_utf16.begin());
@@ -472,17 +458,15 @@ std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
return std::error_code();
}
-std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) {
- FileDescriptor = FD;
+std::error_code mapped_file_region::init(int FD, uint64_t Offset,
+ mapmode Mode) {
// Make sure that the requested size fits within SIZE_T.
- if (Size > std::numeric_limits<SIZE_T>::max()) {
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
+ if (Size > std::numeric_limits<SIZE_T>::max())
return make_error_code(errc::invalid_argument);
- }
+
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ return make_error_code(errc::bad_file_descriptor);
DWORD flprotect;
switch (Mode) {
@@ -491,18 +475,13 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
case priv: flprotect = PAGE_WRITECOPY; break;
}
- FileMappingHandle =
+ HANDLE FileMappingHandle =
::CreateFileMappingW(FileHandle, 0, flprotect,
(Offset + Size) >> 32,
(Offset + Size) & 0xffffffff,
0);
if (FileMappingHandle == NULL) {
std::error_code ec = windows_error(GetLastError());
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
return ec;
}
@@ -520,11 +499,6 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
if (Mapping == NULL) {
std::error_code ec = windows_error(GetLastError());
::CloseHandle(FileMappingHandle);
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
return ec;
}
@@ -535,11 +509,6 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
std::error_code ec = windows_error(GetLastError());
::UnmapViewOfFile(Mapping);
::CloseHandle(FileMappingHandle);
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
return ec;
}
Size = mbi.RegionSize;
@@ -548,85 +517,15 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
// Close all the handles except for the view. It will keep the other handles
// alive.
::CloseHandle(FileMappingHandle);
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor); // Also closes FileHandle.
- } else
- ::CloseHandle(FileHandle);
return std::error_code();
}
-mapped_file_region::mapped_file_region(const Twine &path,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- std::error_code &ec)
- : Mode(mode)
- , Size(length)
- , Mapping()
- , FileDescriptor()
- , FileHandle(INVALID_HANDLE_VALUE)
- , FileMappingHandle() {
- SmallString<128> path_storage;
- SmallVector<wchar_t, 128> path_utf16;
-
- // Convert path to UTF-16.
- if ((ec = UTF8ToUTF16(path.toStringRef(path_storage), path_utf16)))
- return;
-
- // Get file handle for creating a file mapping.
- FileHandle = ::CreateFileW(c_str(path_utf16),
- Mode == readonly ? GENERIC_READ
- : GENERIC_READ | GENERIC_WRITE,
- Mode == readonly ? FILE_SHARE_READ
- : 0,
- 0,
- Mode == readonly ? OPEN_EXISTING
- : OPEN_ALWAYS,
- Mode == readonly ? FILE_ATTRIBUTE_READONLY
- : FILE_ATTRIBUTE_NORMAL,
- 0);
- if (FileHandle == INVALID_HANDLE_VALUE) {
- ec = windows_error(::GetLastError());
- return;
- }
-
- FileDescriptor = 0;
- ec = init(FileDescriptor, true, offset);
- if (ec) {
- Mapping = FileMappingHandle = 0;
- FileHandle = INVALID_HANDLE_VALUE;
- FileDescriptor = 0;
- }
-}
-
-mapped_file_region::mapped_file_region(int fd,
- bool closefd,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- std::error_code &ec)
- : Mode(mode)
- , Size(length)
- , Mapping()
- , FileDescriptor(fd)
- , FileHandle(INVALID_HANDLE_VALUE)
- , FileMappingHandle() {
- FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
- if (FileHandle == INVALID_HANDLE_VALUE) {
- if (closefd)
- _close(FileDescriptor);
- FileDescriptor = 0;
- ec = make_error_code(errc::bad_file_descriptor);
- return;
- }
-
- ec = init(FileDescriptor, closefd, offset);
- if (ec) {
- Mapping = FileMappingHandle = 0;
- FileHandle = INVALID_HANDLE_VALUE;
- FileDescriptor = 0;
- }
+mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec)
+ : Size(length), Mapping() {
+ ec = init(fd, offset, mode);
+ if (ec)
+ Mapping = 0;
}
mapped_file_region::~mapped_file_region() {
@@ -634,30 +533,12 @@ mapped_file_region::~mapped_file_region() {
::UnmapViewOfFile(Mapping);
}
-mapped_file_region::mapped_file_region(mapped_file_region &&other)
- : Mode(other.Mode)
- , Size(other.Size)
- , Mapping(other.Mapping)
- , FileDescriptor(other.FileDescriptor)
- , FileHandle(other.FileHandle)
- , FileMappingHandle(other.FileMappingHandle) {
- other.Mapping = other.FileMappingHandle = 0;
- other.FileHandle = INVALID_HANDLE_VALUE;
- other.FileDescriptor = 0;
-}
-
-mapped_file_region::mapmode mapped_file_region::flags() const {
- assert(Mapping && "Mapping failed but used anyway!");
- return Mode;
-}
-
uint64_t mapped_file_region::size() const {
assert(Mapping && "Mapping failed but used anyway!");
return Size;
}
char *mapped_file_region::data() const {
- assert(Mode != readonly && "Cannot get non-const data for readonly mapping!");
assert(Mapping && "Mapping failed but used anyway!");
return reinterpret_cast<char*>(Mapping);
}
@@ -677,7 +558,7 @@ std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
StringRef path){
SmallVector<wchar_t, 128> path_utf16;
- if (std::error_code ec = UTF8ToUTF16(path, path_utf16))
+ if (std::error_code ec = widenPath(path, path_utf16))
return ec;
// Convert path to the format that Windows is happy with.
@@ -760,11 +641,9 @@ std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
}
std::error_code openFileForRead(const Twine &Name, int &ResultFD) {
- SmallString<128> PathStorage;
SmallVector<wchar_t, 128> PathUTF16;
- if (std::error_code EC =
- UTF8ToUTF16(Name.toStringRef(PathStorage), PathUTF16))
+ if (std::error_code EC = widenPath(Name, PathUTF16))
return EC;
HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
@@ -799,11 +678,9 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
"Cannot specify both 'excl' and 'append' file creation flags!");
- SmallString<128> PathStorage;
SmallVector<wchar_t, 128> PathUTF16;
- if (std::error_code EC =
- UTF8ToUTF16(Name.toStringRef(PathStorage), PathUTF16))
+ if (std::error_code EC = widenPath(Name, PathUTF16))
return EC;
DWORD CreationDisposition;
@@ -867,6 +744,51 @@ bool home_directory(SmallVectorImpl<char> &result) {
return true;
}
+static bool getTempDirEnvVar(const char *Var, SmallVectorImpl<char> &Res) {
+ SmallVector<wchar_t, 128> NameUTF16;
+ if (windows::UTF8ToUTF16(Var, NameUTF16))
+ return false;
+
+ SmallVector<wchar_t, 1024> Buf;
+ size_t Size = 1024;
+ do {
+ Buf.reserve(Size);
+ Size =
+ GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
+ if (Size == 0)
+ return false;
+
+ // Try again with larger buffer.
+ } while (Size > Buf.capacity());
+ Buf.set_size(Size);
+
+ if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
+ return false;
+ return true;
+}
+
+static bool getTempDirEnvVar(SmallVectorImpl<char> &Res) {
+ const char *EnvironmentVariables[] = {"TMP", "TEMP", "USERPROFILE"};
+ for (const char *Env : EnvironmentVariables) {
+ if (getTempDirEnvVar(Env, Res))
+ return true;
+ }
+ return false;
+}
+
+void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
+ (void)ErasedOnReboot;
+ Result.clear();
+
+ // Check whether the temporary directory is specified by an environment
+ // variable.
+ if (getTempDirEnvVar(Result))
+ return;
+
+ // Fall back to a system default.
+ const char *DefaultResult = "C:\\TEMP";
+ Result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
+}
} // end namespace path
namespace windows {
@@ -896,11 +818,13 @@ std::error_code UTF8ToUTF16(llvm::StringRef utf8,
return std::error_code();
}
-std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
- llvm::SmallVectorImpl<char> &utf8) {
+static
+std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
+ size_t utf16_len,
+ llvm::SmallVectorImpl<char> &utf8) {
if (utf16_len) {
// Get length.
- int len = ::WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8.begin(),
+ int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, utf8.begin(),
0, NULL, NULL);
if (len == 0)
@@ -910,7 +834,7 @@ std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
utf8.set_size(len);
// Now do the actual conversion.
- len = ::WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8.data(),
+ len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, utf8.data(),
utf8.size(), NULL, NULL);
if (len == 0)
@@ -923,6 +847,16 @@ std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
return std::error_code();
}
+
+std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
+ llvm::SmallVectorImpl<char> &utf8) {
+ return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
+}
+
+std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
+ llvm::SmallVectorImpl<char> &utf8) {
+ return UTF16ToCodePage(CP_ACP, utf16, utf16_len, utf8);
+}
} // end namespace windows
} // end namespace sys
} // end namespace llvm
diff --git a/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc
index 61749a7..854eac7 100644
--- a/contrib/llvm/lib/Support/Windows/Process.inc
+++ b/contrib/llvm/lib/Support/Windows/Process.inc
@@ -49,10 +49,6 @@
using namespace llvm;
using namespace sys;
-process::id_type self_process::get_id() {
- return GetCurrentProcessId();
-}
-
static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
ULARGE_INTEGER TimeInteger;
TimeInteger.LowPart = Time.dwLowDateTime;
@@ -65,28 +61,10 @@ static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
(TimeInteger.QuadPart % 10000000) * 100));
}
-TimeValue self_process::get_user_time() const {
- FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
- if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
- &UserTime) == 0)
- return TimeValue();
-
- return getTimeValueFromFILETIME(UserTime);
-}
-
-TimeValue self_process::get_system_time() const {
- FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
- if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
- &UserTime) == 0)
- return TimeValue();
-
- return getTimeValueFromFILETIME(KernelTime);
-}
-
// This function retrieves the page size using GetNativeSystemInfo() and is
// present solely so it can be called once to initialize the self_process member
// below.
-static unsigned getPageSize() {
+static unsigned computePageSize() {
// GetNativeSystemInfo() provides the physical page size which may differ
// from GetSystemInfo() in 32-bit applications running under WOW64.
SYSTEM_INFO info;
@@ -96,12 +74,11 @@ static unsigned getPageSize() {
return static_cast<unsigned>(info.dwPageSize);
}
-// This constructor guaranteed to be run exactly once on a single thread, and
-// sets up various process invariants that can be queried cheaply from then on.
-self_process::self_process() : PageSize(getPageSize()) {
+unsigned Process::getPageSize() {
+ static unsigned Ret = computePageSize();
+ return Ret;
}
-
size_t
Process::GetMallocUsage()
{
@@ -273,6 +250,16 @@ Process::GetArgumentVector(SmallVectorImpl<const char *> &Args,
return ec;
}
+std::error_code Process::FixupStandardFileDescriptors() {
+ return std::error_code();
+}
+
+std::error_code Process::SafelyCloseFileDescriptor(int FD) {
+ if (::close(FD) < 0)
+ return std::error_code(errno, std::generic_category());
+ return std::error_code();
+}
+
bool Process::StandardInIsUserInput() {
return FileDescriptorIsDisplayed(0);
}
diff --git a/contrib/llvm/lib/Support/Windows/Program.inc b/contrib/llvm/lib/Support/Windows/Program.inc
index b2f71ae..c370077 100644
--- a/contrib/llvm/lib/Support/Windows/Program.inc
+++ b/contrib/llvm/lib/Support/Windows/Program.inc
@@ -12,7 +12,11 @@
//===----------------------------------------------------------------------===//
#include "WindowsSupport.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/WindowsError.h"
+#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <fcntl.h>
#include <io.h>
@@ -28,43 +32,68 @@ using namespace sys;
ProcessInfo::ProcessInfo() : ProcessHandle(0), Pid(0), ReturnCode(0) {}
-// This function just uses the PATH environment variable to find the program.
-std::string sys::FindProgramByName(const std::string &progName) {
- // Check some degenerate cases
- if (progName.length() == 0) // no program
- return "";
- std::string temp = progName;
- // Return paths with slashes verbatim.
- if (progName.find('\\') != std::string::npos ||
- progName.find('/') != std::string::npos)
- return temp;
-
- // At this point, the file name is valid and does not contain slashes.
- // Let Windows search for it.
- SmallVector<wchar_t, MAX_PATH> progNameUnicode;
- if (windows::UTF8ToUTF16(progName, progNameUnicode))
- return "";
-
- SmallVector<wchar_t, MAX_PATH> buffer;
- DWORD len = MAX_PATH;
- do {
- buffer.reserve(len);
- len = ::SearchPathW(NULL, progNameUnicode.data(), L".exe",
- buffer.capacity(), buffer.data(), NULL);
-
- // See if it wasn't found.
- if (len == 0)
- return "";
-
- // Buffer was too small; grow and retry.
- } while (len > buffer.capacity());
-
- buffer.set_size(len);
- SmallVector<char, MAX_PATH> result;
- if (windows::UTF16ToUTF8(buffer.begin(), buffer.size(), result))
- return "";
-
- return std::string(result.data(), result.size());
+ErrorOr<std::string> sys::findProgramByName(StringRef Name,
+ ArrayRef<StringRef> Paths) {
+ assert(!Name.empty() && "Must have a name!");
+
+ if (Name.find_first_of("/\\") != StringRef::npos)
+ return std::string(Name);
+
+ const wchar_t *Path = nullptr;
+ std::wstring PathStorage;
+ if (!Paths.empty()) {
+ PathStorage.reserve(Paths.size() * MAX_PATH);
+ for (unsigned i = 0; i < Paths.size(); ++i) {
+ if (i)
+ PathStorage.push_back(L';');
+ StringRef P = Paths[i];
+ SmallVector<wchar_t, MAX_PATH> TmpPath;
+ if (std::error_code EC = windows::UTF8ToUTF16(P, TmpPath))
+ return EC;
+ PathStorage.append(TmpPath.begin(), TmpPath.end());
+ }
+ Path = PathStorage.c_str();
+ }
+
+ SmallVector<wchar_t, MAX_PATH> U16Name;
+ if (std::error_code EC = windows::UTF8ToUTF16(Name, U16Name))
+ return EC;
+
+ SmallVector<StringRef, 12> PathExts;
+ PathExts.push_back("");
+ PathExts.push_back(".exe"); // FIXME: This must be in %PATHEXT%.
+ if (const char *PathExtEnv = std::getenv("PATHEXT"))
+ SplitString(PathExtEnv, PathExts, ";");
+
+ SmallVector<wchar_t, MAX_PATH> U16Result;
+ DWORD Len = MAX_PATH;
+ for (StringRef Ext : PathExts) {
+ SmallVector<wchar_t, MAX_PATH> U16Ext;
+ if (std::error_code EC = windows::UTF8ToUTF16(Ext, U16Ext))
+ return EC;
+
+ do {
+ U16Result.reserve(Len);
+ Len = ::SearchPathW(Path, c_str(U16Name),
+ U16Ext.empty() ? nullptr : c_str(U16Ext),
+ U16Result.capacity(), U16Result.data(), nullptr);
+ } while (Len > U16Result.capacity());
+
+ if (Len != 0)
+ break; // Found it.
+ }
+
+ if (Len == 0)
+ return mapWindowsError(::GetLastError());
+
+ U16Result.set_size(Len);
+
+ SmallVector<char, MAX_PATH> U8Result;
+ if (std::error_code EC =
+ windows::UTF16ToUTF8(U16Result.data(), U16Result.size(), U8Result))
+ return EC;
+
+ return std::string(U8Result.begin(), U8Result.end());
}
static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
@@ -89,14 +118,19 @@ static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
sa.bInheritHandle = TRUE;
SmallVector<wchar_t, 128> fnameUnicode;
- if (windows::UTF8ToUTF16(fname, fnameUnicode))
- return INVALID_HANDLE_VALUE;
-
+ if (path->empty()) {
+ // Don't play long-path tricks on "NUL".
+ if (windows::UTF8ToUTF16(fname, fnameUnicode))
+ return INVALID_HANDLE_VALUE;
+ } else {
+ if (path::widenPath(fname, fnameUnicode))
+ return INVALID_HANDLE_VALUE;
+ }
h = CreateFileW(fnameUnicode.data(), 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 " +
+ MakeErrMsg(ErrMsg, fname + ": Can't open file for " +
(fd ? "input: " : "output: "));
}
@@ -166,19 +200,7 @@ static unsigned int ArgLenWithQuotes(const char *Str) {
}
-static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
- const char **envp, const StringRef **redirects,
- unsigned memoryLimit, std::string *ErrMsg) {
- if (!sys::fs::can_execute(Program)) {
- 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).
-
+static std::unique_ptr<char[]> flattenArgs(const char **args) {
// First, determine the length of the command line.
unsigned len = 0;
for (unsigned i = 0; args[i]; i++) {
@@ -216,6 +238,22 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
}
*p = 0;
+ return command;
+}
+
+static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
+ const char **envp, const StringRef **redirects,
+ unsigned memoryLimit, std::string *ErrMsg) {
+ if (!sys::fs::can_execute(Program)) {
+ 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).
+ std::unique_ptr<char[]> command = flattenArgs(args);
// The pointer to the environment block for the new process.
std::vector<wchar_t> EnvBlock;
@@ -290,7 +328,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
fflush(stderr);
SmallVector<wchar_t, MAX_PATH> ProgramUtf16;
- if (std::error_code ec = windows::UTF8ToUTF16(Program, ProgramUtf16)) {
+ if (std::error_code ec = path::widenPath(Program, ProgramUtf16)) {
SetLastError(ec.value());
MakeErrMsg(ErrMsg,
std::string("Unable to convert application name to UTF-16"));
@@ -422,20 +460,64 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
return WaitResult;
}
- std::error_code sys::ChangeStdinToBinary(){
- int result = _setmode( _fileno(stdin), _O_BINARY );
+std::error_code sys::ChangeStdinToBinary() {
+ int result = _setmode(_fileno(stdin), _O_BINARY);
if (result == -1)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
- std::error_code sys::ChangeStdoutToBinary(){
- int result = _setmode( _fileno(stdout), _O_BINARY );
+std::error_code sys::ChangeStdoutToBinary() {
+ int result = _setmode(_fileno(stdout), _O_BINARY);
if (result == -1)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
+std::error_code
+llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
+ WindowsEncodingMethod Encoding) {
+ std::error_code EC;
+ llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
+ if (EC)
+ return EC;
+
+ if (Encoding == WEM_UTF8) {
+ OS << Contents;
+ } else if (Encoding == WEM_CurrentCodePage) {
+ SmallVector<wchar_t, 1> ArgsUTF16;
+ SmallVector<char, 1> ArgsCurCP;
+
+ if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
+ return EC;
+
+ if ((EC = windows::UTF16ToCurCP(
+ ArgsUTF16.data(), ArgsUTF16.size(), ArgsCurCP)))
+ return EC;
+
+ OS.write(ArgsCurCP.data(), ArgsCurCP.size());
+ } else if (Encoding == WEM_UTF16) {
+ SmallVector<wchar_t, 1> ArgsUTF16;
+
+ if ((EC = windows::UTF8ToUTF16(Contents, ArgsUTF16)))
+ return EC;
+
+ // Endianness guessing
+ char BOM[2];
+ uint16_t src = UNI_UTF16_BYTE_ORDER_MARK_NATIVE;
+ memcpy(BOM, &src, 2);
+ OS.write(BOM, 2);
+ OS.write((char *)ArgsUTF16.data(), ArgsUTF16.size() << 1);
+ } else {
+ llvm_unreachable("Unknown encoding");
+ }
+
+ if (OS.has_error())
+ return std::make_error_code(std::errc::io_error);
+
+ return EC;
+}
+
bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
// The documented max length of the command line passed to CreateProcess.
static const size_t MaxCommandStringLength = 32768;
diff --git a/contrib/llvm/lib/Support/Windows/RWMutex.inc b/contrib/llvm/lib/Support/Windows/RWMutex.inc
index 00d0e93..2d1d25f 100644
--- a/contrib/llvm/lib/Support/Windows/RWMutex.inc
+++ b/contrib/llvm/lib/Support/Windows/RWMutex.inc
@@ -84,12 +84,10 @@ RWMutexImpl::RWMutexImpl() {
}
RWMutexImpl::~RWMutexImpl() {
- if (sHasSRW) {
- // Nothing to do in the case of slim reader/writers
- } else {
+ if (!sHasSRW)
DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
- free(data_);
- }
+ // Nothing to do in the case of slim reader/writers except free the memory.
+ free(data_);
}
bool RWMutexImpl::reader_acquire() {
diff --git a/contrib/llvm/lib/Support/Windows/ThreadLocal.inc b/contrib/llvm/lib/Support/Windows/ThreadLocal.inc
index 14ce619..b9cb8ff 100644
--- a/contrib/llvm/lib/Support/Windows/ThreadLocal.inc
+++ b/contrib/llvm/lib/Support/Windows/ThreadLocal.inc
@@ -34,7 +34,7 @@ ThreadLocalImpl::~ThreadLocalImpl() {
TlsFree(*tls);
}
-const void* ThreadLocalImpl::getInstance() {
+void *ThreadLocalImpl::getInstance() {
DWORD* tls = reinterpret_cast<DWORD*>(&data);
return TlsGetValue(*tls);
}
diff --git a/contrib/llvm/lib/Support/Windows/WindowsSupport.h b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
index f68835b..1d1cedc 100644
--- a/contrib/llvm/lib/Support/Windows/WindowsSupport.h
+++ b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
@@ -30,6 +30,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h" // Get build system configuration settings
#include "llvm/Support/Compiler.h"
#include <system_error>
@@ -162,10 +163,18 @@ c_str(SmallVectorImpl<T> &str) {
}
namespace sys {
+namespace path {
+std::error_code widenPath(const Twine &Path8,
+ SmallVectorImpl<wchar_t> &Path16);
+} // end namespace path
+
namespace windows {
std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
SmallVectorImpl<char> &utf8);
+/// Convert from UTF16 to the current code page used in the system
+std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
+ SmallVectorImpl<char> &utf8);
} // end namespace windows
} // end namespace sys
} // end namespace llvm.
diff --git a/contrib/llvm/lib/Support/Windows/explicit_symbols.inc b/contrib/llvm/lib/Support/Windows/explicit_symbols.inc
index 379645d..cd56b13 100644
--- a/contrib/llvm/lib/Support/Windows/explicit_symbols.inc
+++ b/contrib/llvm/lib/Support/Windows/explicit_symbols.inc
@@ -63,4 +63,34 @@
/* msvcrt */
#if defined(_MSC_VER)
EXPLICIT_SYMBOL2(alloca, _alloca_probe)
+
+#ifdef _M_IX86
+#define INLINE_DEF_FLOAT_SYMBOL(SYM, ARGC) INLINE_DEF_SYMBOL##ARGC(float, SYM)
+ INLINE_DEF_FLOAT_SYMBOL(acosf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(asinf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(atanf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(atan2f, 2)
+ INLINE_DEF_FLOAT_SYMBOL(ceilf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(cosf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(coshf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(expf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(floorf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(fmodf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(logf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(powf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(sinf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(sinhf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(sqrtf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(tanf, 1)
+ INLINE_DEF_FLOAT_SYMBOL(tanhf, 1)
+
+ // These were added in VS 2013.
+#if (1800 <= _MSC_VER && _MSC_VER < 1900)
+ INLINE_DEF_FLOAT_SYMBOL(copysignf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(fminf, 2)
+ INLINE_DEF_FLOAT_SYMBOL(fmaxf, 2)
+#endif
+#undef INLINE_DEF_FLOAT_SYMBOL
+#endif
+
#endif
OpenPOWER on IntegriCloud