authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-29 13:54:31-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-29 13:54:31-07:00
loge078b4f20ea0656c02f957520c182735c60593de
treeb14fedec819120cf06f5ea6255b0b194e32812e1
parent0afb5b2ec6de494efe0605b2270f6a01b95237af

zig ar: workaround for LLVM bug

In this file is copy+pasted WindowsSupport.h from LLVM 12.0.1-rc1. This is so that we can patch it. The upstream sources are incorrectly including "llvm/Config/config.h" which is a private header and thus not available in the include files distributed with LLVM. The patch here changes it to include "llvm/Config/config.h" instead. Patch submitted upstream: https://reviews.llvm.org/D103370

1 files changed, 260 insertions(+), 0 deletions(-)

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