Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines things specific to Windows implementations.  In addition to
  10. // providing some helpers for working with win32 APIs, this header wraps
  11. // <windows.h> with some portability macros.  Always include WindowsSupport.h
  12. // instead of including <windows.h> directly.
  13. //
  14. //===----------------------------------------------------------------------===//
  15.  
  16. //===----------------------------------------------------------------------===//
  17. //=== WARNING: Implementation here must contain only generic Win32 code that
  18. //===          is guaranteed to work on *all* Win32 variants.
  19. //===----------------------------------------------------------------------===//
  20.  
  21. #ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H
  22. #define LLVM_SUPPORT_WINDOWSSUPPORT_H
  23.  
  24. // mingw-w64 tends to define it as 0x0502 in its headers.
  25. #undef _WIN32_WINNT
  26. #undef _WIN32_IE
  27.  
  28. // Require at least Windows 7 API.
  29. #define _WIN32_WINNT 0x0601
  30. #define _WIN32_IE    0x0800 // MinGW at it again. FIXME: verify if still needed.
  31. #define WIN32_LEAN_AND_MEAN
  32. #ifndef NOMINMAX
  33. #define NOMINMAX
  34. #endif
  35.  
  36. #include "llvm/ADT/SmallVector.h"
  37. #include "llvm/ADT/StringExtras.h"
  38. #include "llvm/ADT/StringRef.h"
  39. #include "llvm/ADT/Twine.h"
  40. #include "llvm/Config/llvm-config.h" // Get build system configuration settings
  41. #include "llvm/Support/Allocator.h"
  42. #include "llvm/Support/Chrono.h"
  43. #include "llvm/Support/Compiler.h"
  44. #include "llvm/Support/ErrorHandling.h"
  45. #include "llvm/Support/VersionTuple.h"
  46. #include <cassert>
  47. #include <string>
  48. #include <system_error>
  49. #include <windows.h>
  50.  
  51. // Must be included after windows.h
  52. #include <wincrypt.h>
  53.  
  54. namespace llvm {
  55.  
  56. /// Determines if the program is running on Windows 8 or newer. This
  57. /// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
  58. /// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't
  59. /// yet have VersionHelpers.h, so we have our own helper.
  60. bool RunningWindows8OrGreater();
  61.  
  62. /// Determines if the program is running on Windows 11 or Windows Server 2022.
  63. bool RunningWindows11OrGreater();
  64.  
  65. /// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
  66. /// RtlGetVersion or GetVersionEx under the hood depending on what is available.
  67. /// GetVersionEx is deprecated, but this API exposes the build number which can
  68. /// be useful for working around certain kernel bugs.
  69. llvm::VersionTuple GetWindowsOSVersion();
  70.  
  71. bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix);
  72.  
  73. // Include GetLastError() in a fatal error message.
  74. [[noreturn]] inline void ReportLastErrorFatal(const char *Msg) {
  75.   std::string ErrMsg;
  76.   MakeErrMsg(&ErrMsg, Msg);
  77.   llvm::report_fatal_error(Twine(ErrMsg));
  78. }
  79.  
  80. template <typename HandleTraits>
  81. class ScopedHandle {
  82.   typedef typename HandleTraits::handle_type handle_type;
  83.   handle_type Handle;
  84.  
  85.   ScopedHandle(const ScopedHandle &other) = delete;
  86.   void operator=(const ScopedHandle &other) = delete;
  87. public:
  88.   ScopedHandle()
  89.     : Handle(HandleTraits::GetInvalid()) {}
  90.  
  91.   explicit ScopedHandle(handle_type h)
  92.     : Handle(h) {}
  93.  
  94.   ~ScopedHandle() {
  95.     if (HandleTraits::IsValid(Handle))
  96.       HandleTraits::Close(Handle);
  97.   }
  98.  
  99.   handle_type take() {
  100.     handle_type t = Handle;
  101.     Handle = HandleTraits::GetInvalid();
  102.     return t;
  103.   }
  104.  
  105.   ScopedHandle &operator=(handle_type h) {
  106.     if (HandleTraits::IsValid(Handle))
  107.       HandleTraits::Close(Handle);
  108.     Handle = h;
  109.     return *this;
  110.   }
  111.  
  112.   // True if Handle is valid.
  113.   explicit operator bool() const {
  114.     return HandleTraits::IsValid(Handle) ? true : false;
  115.   }
  116.  
  117.   operator handle_type() const {
  118.     return Handle;
  119.   }
  120. };
  121.  
  122. struct CommonHandleTraits {
  123.   typedef HANDLE handle_type;
  124.  
  125.   static handle_type GetInvalid() {
  126.     return INVALID_HANDLE_VALUE;
  127.   }
  128.  
  129.   static void Close(handle_type h) {
  130.     ::CloseHandle(h);
  131.   }
  132.  
  133.   static bool IsValid(handle_type h) {
  134.     return h != GetInvalid();
  135.   }
  136. };
  137.  
  138. struct JobHandleTraits : CommonHandleTraits {
  139.   static handle_type GetInvalid() {
  140.     return NULL;
  141.   }
  142. };
  143.  
  144. struct CryptContextTraits : CommonHandleTraits {
  145.   typedef HCRYPTPROV handle_type;
  146.  
  147.   static handle_type GetInvalid() {
  148.     return 0;
  149.   }
  150.  
  151.   static void Close(handle_type h) {
  152.     ::CryptReleaseContext(h, 0);
  153.   }
  154.  
  155.   static bool IsValid(handle_type h) {
  156.     return h != GetInvalid();
  157.   }
  158. };
  159.  
  160. struct RegTraits : CommonHandleTraits {
  161.   typedef HKEY handle_type;
  162.  
  163.   static handle_type GetInvalid() {
  164.     return NULL;
  165.   }
  166.  
  167.   static void Close(handle_type h) {
  168.     ::RegCloseKey(h);
  169.   }
  170.  
  171.   static bool IsValid(handle_type h) {
  172.     return h != GetInvalid();
  173.   }
  174. };
  175.  
  176. struct FindHandleTraits : CommonHandleTraits {
  177.   static void Close(handle_type h) {
  178.     ::FindClose(h);
  179.   }
  180. };
  181.  
  182. struct FileHandleTraits : CommonHandleTraits {};
  183.  
  184. typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
  185. typedef ScopedHandle<FileHandleTraits>   ScopedFileHandle;
  186. typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
  187. typedef ScopedHandle<RegTraits>          ScopedRegHandle;
  188. typedef ScopedHandle<FindHandleTraits>   ScopedFindHandle;
  189. typedef ScopedHandle<JobHandleTraits>    ScopedJobHandle;
  190.  
  191. template <class T>
  192. class SmallVectorImpl;
  193.  
  194. template <class T>
  195. typename SmallVectorImpl<T>::const_pointer
  196. c_str(SmallVectorImpl<T> &str) {
  197.   str.push_back(0);
  198.   str.pop_back();
  199.   return str.data();
  200. }
  201.  
  202. namespace sys {
  203.  
  204. inline std::chrono::nanoseconds toDuration(FILETIME Time) {
  205.   ULARGE_INTEGER TimeInteger;
  206.   TimeInteger.LowPart = Time.dwLowDateTime;
  207.   TimeInteger.HighPart = Time.dwHighDateTime;
  208.  
  209.   // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
  210.   return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
  211. }
  212.  
  213. inline TimePoint<> toTimePoint(FILETIME Time) {
  214.   ULARGE_INTEGER TimeInteger;
  215.   TimeInteger.LowPart = Time.dwLowDateTime;
  216.   TimeInteger.HighPart = Time.dwHighDateTime;
  217.  
  218.   // Adjust for different epoch
  219.   TimeInteger.QuadPart -= 11644473600ll * 10000000;
  220.  
  221.   // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
  222.   return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
  223. }
  224.  
  225. inline FILETIME toFILETIME(TimePoint<> TP) {
  226.   ULARGE_INTEGER TimeInteger;
  227.   TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
  228.   TimeInteger.QuadPart += 11644473600ll * 10000000;
  229.  
  230.   FILETIME Time;
  231.   Time.dwLowDateTime = TimeInteger.LowPart;
  232.   Time.dwHighDateTime = TimeInteger.HighPart;
  233.   return Time;
  234. }
  235.  
  236. namespace windows {
  237. // Returns command line arguments. Unlike arguments given to main(),
  238. // this function guarantees that the returned arguments are encoded in
  239. // UTF-8 regardless of the current code page setting.
  240. std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
  241.                                         BumpPtrAllocator &Alloc);
  242.  
  243. /// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
  244. /// File API.
  245. std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
  246.                           size_t MaxPathLen = MAX_PATH);
  247.  
  248. } // end namespace windows
  249. } // end namespace sys
  250. } // end namespace llvm.
  251.  
  252. #endif
  253.