mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
Semiwrap / meson / robotpy define `NDEBUG` when building their software in all modes, while `allwplib` only does it when building debug. This causes the size of `DenseMap` to differ between the shared libraries built here, and the extension modules built in `mostrobotpy`, causing segfaults when you try to execute code that uses `DenseMap`. This is not a problem with the robotpy code in `allwpilib`, because bazel uses the exact same compiler flags when building the shared libraries and pybind11 extensions.
218 lines
7.5 KiB
Diff
218 lines
7.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: PJ Reiniger <pj.reiniger@gmail.com>
|
|
Date: Tue, 3 May 2022 20:22:38 -0400
|
|
Subject: [PATCH 16/35] Windows support
|
|
|
|
---
|
|
.../llvm/Support/Windows/WindowsSupport.h | 45 +++++----
|
|
llvm/lib/Support/ConvertUTF.cpp | 95 +++++++++++++++++++
|
|
llvm/lib/Support/raw_ostream.cpp | 1 -
|
|
3 files changed, 124 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h
|
|
index 83d5586ae8a77ec585e7e59df3075ca59cfb9d0c..395965bc6fc969ed9a2d92743a0010ddf3923394 100644
|
|
--- a/llvm/include/llvm/Support/Windows/WindowsSupport.h
|
|
+++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h
|
|
@@ -33,8 +33,6 @@
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
-#include "llvm/Config/llvm-config.h" // Get build system configuration settings
|
|
-#include "llvm/Support/Allocator.h"
|
|
#include "llvm/Support/Chrono.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
@@ -42,18 +40,46 @@
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <system_error>
|
|
+#define WIN32_NO_STATUS
|
|
#include <windows.h>
|
|
+#undef WIN32_NO_STATUS
|
|
+#include <winternl.h>
|
|
+#include <ntstatus.h>
|
|
|
|
// Must be included after windows.h
|
|
#include <wincrypt.h>
|
|
|
|
namespace llvm {
|
|
|
|
+/// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
|
|
+/// RtlGetVersion or GetVersionEx under the hood depending on what is available.
|
|
+/// GetVersionEx is deprecated, but this API exposes the build number which can
|
|
+/// be useful for working around certain kernel bugs.
|
|
+inline llvm::VersionTuple GetWindowsOSVersion() {
|
|
+ typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
|
+ HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
|
|
+ if (hMod) {
|
|
+ auto getVer = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
|
|
+ if (getVer) {
|
|
+ RTL_OSVERSIONINFOEXW info{};
|
|
+ info.dwOSVersionInfoSize = sizeof(info);
|
|
+ if (getVer((PRTL_OSVERSIONINFOW)&info) == ((NTSTATUS)0x00000000L)) {
|
|
+ return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion, 0,
|
|
+ info.dwBuildNumber);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return llvm::VersionTuple(0, 0, 0, 0);
|
|
+}
|
|
+
|
|
/// Determines if the program is running on Windows 8 or newer. This
|
|
/// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
|
|
/// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't
|
|
/// yet have VersionHelpers.h, so we have our own helper.
|
|
-bool RunningWindows8OrGreater();
|
|
+inline bool RunningWindows8OrGreater() {
|
|
+ // Windows 8 is version 6.2, service pack 0.
|
|
+ return GetWindowsOSVersion() >= llvm::VersionTuple(6, 2, 0, 0);
|
|
+}
|
|
|
|
/// Determines if the program is running on Windows 11 or Windows Server 2022.
|
|
bool RunningWindows11OrGreater();
|
|
@@ -229,19 +255,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) {
|
|
return Time;
|
|
}
|
|
|
|
-namespace windows {
|
|
-// Returns command line arguments. Unlike arguments given to main(),
|
|
-// this function guarantees that the returned arguments are encoded in
|
|
-// UTF-8 regardless of the current code page setting.
|
|
-std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
|
|
- BumpPtrAllocator &Alloc);
|
|
-
|
|
-/// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
|
|
-/// File API.
|
|
-std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
|
|
- size_t MaxPathLen = MAX_PATH);
|
|
-
|
|
-} // end namespace windows
|
|
} // end namespace sys
|
|
} // end namespace llvm.
|
|
|
|
diff --git a/llvm/lib/Support/ConvertUTF.cpp b/llvm/lib/Support/ConvertUTF.cpp
|
|
index bc04c5ab5113563fb82d7b3b168985369b611f4b..b865b5589df961813007e57a910dbc14f875426b 100644
|
|
--- a/llvm/lib/Support/ConvertUTF.cpp
|
|
+++ b/llvm/lib/Support/ConvertUTF.cpp
|
|
@@ -67,6 +67,11 @@
|
|
#endif
|
|
#include <assert.h>
|
|
|
|
+#ifdef _WIN32
|
|
+#include "wpi/util/WindowsError.hpp"
|
|
+#include "Windows/WindowsSupport.hpp"
|
|
+#endif
|
|
+
|
|
/*
|
|
* This code extensively uses fall-through switches.
|
|
* Keep the compiler from warning about that.
|
|
@@ -759,6 +764,96 @@ ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart,
|
|
|
|
--------------------------------------------------------------------- */
|
|
|
|
+#ifdef _WIN32
|
|
+
|
|
+namespace sys {
|
|
+namespace windows {
|
|
+std::error_code CodePageToUTF16(unsigned codepage,
|
|
+ std::string_view original,
|
|
+ wpi::util::SmallVectorImpl<wchar_t> &utf16) {
|
|
+ if (!original.empty()) {
|
|
+ int len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.data(),
|
|
+ original.size(), utf16.begin(), 0);
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+
|
|
+ utf16.reserve(len + 1);
|
|
+ utf16.resize_for_overwrite(len);
|
|
+
|
|
+ len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.data(),
|
|
+ original.size(), utf16.begin(), utf16.size());
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Make utf16 null terminated.
|
|
+ utf16.push_back(0);
|
|
+ utf16.pop_back();
|
|
+
|
|
+ return std::error_code();
|
|
+}
|
|
+
|
|
+std::error_code UTF8ToUTF16(std::string_view utf8,
|
|
+ wpi::util::SmallVectorImpl<wchar_t> &utf16) {
|
|
+ return CodePageToUTF16(CP_UTF8, utf8, utf16);
|
|
+}
|
|
+
|
|
+std::error_code CurCPToUTF16(std::string_view curcp,
|
|
+ wpi::util::SmallVectorImpl<wchar_t> &utf16) {
|
|
+ return CodePageToUTF16(CP_ACP, curcp, utf16);
|
|
+}
|
|
+
|
|
+static
|
|
+std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
|
|
+ size_t utf16_len,
|
|
+ wpi::util::SmallVectorImpl<char> &converted) {
|
|
+ if (utf16_len) {
|
|
+ // Get length.
|
|
+ int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.begin(),
|
|
+ 0, NULL, NULL);
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+
|
|
+ converted.reserve(len);
|
|
+ converted.resize_for_overwrite(len);
|
|
+
|
|
+ // Now do the actual conversion.
|
|
+ len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.data(),
|
|
+ converted.size(), NULL, NULL);
|
|
+
|
|
+ if (len == 0) {
|
|
+ return mapWindowsError(::GetLastError());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Make the new string null terminated.
|
|
+ converted.push_back(0);
|
|
+ converted.pop_back();
|
|
+
|
|
+ return std::error_code();
|
|
+}
|
|
+
|
|
+std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
|
+ wpi::util::SmallVectorImpl<char> &utf8) {
|
|
+ return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
|
|
+}
|
|
+
|
|
+std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
|
+ wpi::util::SmallVectorImpl<char> &curcp) {
|
|
+ return UTF16ToCodePage(CP_ACP, utf16, utf16_len, curcp);
|
|
+}
|
|
+
|
|
+} // end namespace windows
|
|
+} // end namespace sys
|
|
+
|
|
+#endif // _WIN32
|
|
+
|
|
} // namespace llvm
|
|
|
|
ConvertUTF_RESTORE_WARNINGS
|
|
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
|
|
index d8f0c5c7f0f4d5e468b30d53dc6eb8d777a0da9f..a1b40ae78da9fed4bb9d489f298c7adc9cf437b9 100644
|
|
--- a/llvm/lib/Support/raw_ostream.cpp
|
|
+++ b/llvm/lib/Support/raw_ostream.cpp
|
|
@@ -524,7 +524,6 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
|
|
DWORD WinLastError = GetLastError();
|
|
if (WinLastError == ERROR_BROKEN_PIPE ||
|
|
(WinLastError == ERROR_NO_DATA && errno == EINVAL)) {
|
|
- llvm::sys::CallOneShotPipeSignalHandler();
|
|
errno = EPIPE;
|
|
}
|
|
#endif
|