yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie HermaszewskaEnable SLANG_ENABLE_DXIL_SUPPORT on non-Windows platforms (#2750)5a629b3cc

master
28.8 KiB1046 linesraw
1//===- WinAdapter.h - Windows Adapter for non-Windows platforms -*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines Windows-specific types, macros, and SAL annotations used
11// in the codebase for non-Windows platforms.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_WIN_ADAPTER_H
16#define LLVM_SUPPORT_WIN_ADAPTER_H
17
18#ifndef _WIN32
19
20#ifdef __cplusplus
21#include <atomic>
22#include <cassert>
23#include <climits>
24#include <cstring>
25#include <cwchar>
26#include <fstream>
27#include <stdarg.h>
28#include <stddef.h>
29#include <stdint.h>
30#include <string>
31#include <typeindex>
32#include <typeinfo>
33#include <vector>
34#endif // __cplusplus
35
36#define COM_NO_WINDOWS_H // needed to inform d3d headers that this isn't windows
37
38//===----------------------------------------------------------------------===//
39//
40//                             Begin: Macro Definitions
41//
42//===----------------------------------------------------------------------===//
43#define C_ASSERT(expr) static_assert((expr), "")
44#define ATLASSERT assert
45
46#define CoTaskMemAlloc malloc
47#define CoTaskMemFree free
48
49#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
50
51#define _countof(a) (sizeof(a) / sizeof(*(a)))
52
53// If it is GCC, there is no UUID support and we must emulate it.
54#ifndef __clang__
55#define __EMULATE_UUID 1
56#endif // __clang__
57
58#ifdef __EMULATE_UUID
59#define __declspec(x)
60#endif // __EMULATE_UUID
61
62#define DECLSPEC_SELECTANY
63
64#ifdef __EMULATE_UUID
65#define uuid(id)
66#endif // __EMULATE_UUID
67
68#define STDMETHODCALLTYPE
69#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
70#define STDMETHODIMP STDMETHODIMP_(HRESULT)
71#define STDMETHOD_(type,name) virtual STDMETHODIMP_(type) name
72#define STDMETHOD(name) STDMETHOD_(HRESULT, name)
73#define EXTERN_C extern "C"
74
75
76#define UNREFERENCED_PARAMETER(P) (void)(P)
77
78#define RtlEqualMemory(Destination, Source, Length)                            \
79  (!memcmp((Destination), (Source), (Length)))
80#define RtlMoveMemory(Destination, Source, Length)                             \
81  memmove((Destination), (Source), (Length))
82#define RtlCopyMemory(Destination, Source, Length)                             \
83  memcpy((Destination), (Source), (Length))
84#define RtlFillMemory(Destination, Length, Fill)                               \
85  memset((Destination), (Fill), (Length))
86#define RtlZeroMemory(Destination, Length) memset((Destination), 0, (Length))
87#define MoveMemory RtlMoveMemory
88#define CopyMemory RtlCopyMemory
89#define FillMemory RtlFillMemory
90#define ZeroMemory RtlZeroMemory
91
92#define FALSE 0
93#define TRUE 1
94
95// We ignore the code page completely on Linux.
96#define GetConsoleOutputCP() 0
97
98#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
99#define DISP_E_BADINDEX _HRESULT_TYPEDEF_(0x8002000BL)
100#define REGDB_E_CLASSNOTREG _HRESULT_TYPEDEF_(0x80040154L)
101
102// This is an unsafe conversion. If needed, we can later implement a safe
103// conversion that throws exceptions for overflow cases.
104#define UIntToInt(uint_arg, int_ptr_arg) *int_ptr_arg = uint_arg
105
106#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
107
108// Use errno to implement {Get|Set}LastError
109#define GetLastError() errno
110#define SetLastError(ERR) errno = ERR
111
112// Map these errors to equivalent errnos.
113#define ERROR_SUCCESS 0L
114#define ERROR_ARITHMETIC_OVERFLOW EOVERFLOW
115#define ERROR_FILE_NOT_FOUND ENOENT
116#define ERROR_FUNCTION_NOT_CALLED ENOSYS
117#define ERROR_IO_DEVICE EIO
118#define ERROR_INSUFFICIENT_BUFFER ENOBUFS
119#define ERROR_INVALID_HANDLE EBADF
120#define ERROR_INVALID_PARAMETER EINVAL
121#define ERROR_OUT_OF_STRUCTURES ENOMEM
122#define ERROR_NOT_CAPABLE EPERM
123#define ERROR_NOT_FOUND ENOTSUP
124#define ERROR_UNHANDLED_EXCEPTION EBADF
125
126// Used by HRESULT <--> WIN32 error code conversion
127#define SEVERITY_ERROR 1
128#define FACILITY_WIN32 7
129#define HRESULT_CODE(hr) ((hr)&0xFFFF)
130#define MAKE_HRESULT(severity, facility, code)                                 \
131  ((HRESULT)(((unsigned long)(severity) << 31) |                               \
132             ((unsigned long)(facility) << 16) | ((unsigned long)(code))))
133
134#define FILE_TYPE_UNKNOWN 0x0000
135#define FILE_TYPE_DISK 0x0001
136#define FILE_TYPE_CHAR 0x0002
137#define FILE_TYPE_PIPE 0x0003
138#define FILE_TYPE_REMOTE 0x8000
139
140#define FILE_ATTRIBUTE_NORMAL 0x00000080
141#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
142#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
143
144#define STDOUT_FILENO 1
145#define STDERR_FILENO 2
146
147// STGTY ENUMS
148#define STGTY_STORAGE 1
149#define STGTY_STREAM 2
150#define STGTY_LOCKBYTES 3
151#define STGTY_PROPERTY 4
152
153// Storage errors
154#define STG_E_INVALIDFUNCTION 1L
155#define STG_E_ACCESSDENIED 2L
156
157#define STREAM_SEEK_SET 0
158#define STREAM_SEEK_CUR 1
159#define STREAM_SEEK_END 2
160
161#define HEAP_NO_SERIALIZE 0x1
162#define HEAP_ZERO_MEMORY 0x8
163
164#define MB_ERR_INVALID_CHARS 0x00000008 // error for invalid chars
165
166// File IO
167
168#define CREATE_ALWAYS 2
169#define CREATE_NEW 1
170#define OPEN_ALWAYS 4
171#define OPEN_EXISTING 3
172#define TRUNCATE_EXISTING 5
173
174#define FILE_SHARE_DELETE 0x00000004
175#define FILE_SHARE_READ 0x00000001
176#define FILE_SHARE_WRITE 0x00000002
177
178#define GENERIC_READ 0x80000000
179#define GENERIC_WRITE 0x40000000
180
181#define _atoi64 atoll
182#define sprintf_s snprintf
183#define _strdup strdup
184#define _strnicmp strnicmp
185
186#define vsnprintf_s vsnprintf
187#define strcat_s strcat
188#define strcpy_s(dst, n, src) strncpy(dst, src, n)
189#define _vscwprintf vwprintf
190#define vswprintf_s vswprintf
191#define swprintf_s swprintf
192
193#define StringCchCopyW(dst, n, src) wcsncpy(dst, src, n)
194
195#define OutputDebugStringW(msg) fputws(msg, stderr)
196
197#define OutputDebugStringA(msg) fputs(msg, stderr)
198#define OutputDebugFormatA(...) fprintf(stderr, __VA_ARGS__)
199
200// Event Tracing for Windows (ETW) provides application programmers the ability
201// to start and stop event tracing sessions, instrument an application to
202// provide trace events, and consume trace events.
203#define DxcEtw_DXCompilerCreateInstance_Start()
204#define DxcEtw_DXCompilerCreateInstance_Stop(hr)
205#define DxcEtw_DXCompilerCompile_Start()
206#define DxcEtw_DXCompilerCompile_Stop(hr)
207#define DxcEtw_DXCompilerDisassemble_Start()
208#define DxcEtw_DXCompilerDisassemble_Stop(hr)
209#define DxcEtw_DXCompilerPreprocess_Start()
210#define DxcEtw_DXCompilerPreprocess_Stop(hr)
211#define DxcEtw_DxcValidation_Start()
212#define DxcEtw_DxcValidation_Stop(hr)
213
214#define UInt32Add UIntAdd
215#define Int32ToUInt32 IntToUInt
216
217//===--------------------- HRESULT Related Macros -------------------------===//
218
219#define S_OK ((HRESULT)0L)
220#define S_FALSE ((HRESULT)1L)
221
222#define E_ABORT (HRESULT)0x80004004
223#define E_ACCESSDENIED (HRESULT)0x80070005
224#define E_BOUNDS (HRESULT)0x8000000B
225#define E_FAIL (HRESULT)0x80004005
226#define E_HANDLE (HRESULT)0x80070006
227#define E_INVALIDARG (HRESULT)0x80070057
228#define E_NOINTERFACE (HRESULT)0x80004002
229#define E_NOTIMPL (HRESULT)0x80004001
230#define E_NOT_VALID_STATE (HRESULT)0x8007139F
231#define E_OUTOFMEMORY (HRESULT)0x8007000E
232#define E_POINTER (HRESULT)0x80004003
233#define E_UNEXPECTED (HRESULT)0x8000FFFF
234
235#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
236#define FAILED(hr) (((HRESULT)(hr)) < 0)
237#define DXC_FAILED(hr) (((HRESULT)(hr)) < 0)
238
239#define HRESULT_FROM_WIN32(x)                                                  \
240  (HRESULT)(x) <= 0 ? (HRESULT)(x)                                             \
241                    : (HRESULT)(((x)&0x0000FFFF) | (7 << 16) | 0x80000000)
242
243//===----------------------------------------------------------------------===//
244//
245//                         Begin: Disable SAL Annotations
246//
247//===----------------------------------------------------------------------===//
248#define _In_
249#define _In_z_
250#define _In_opt_
251#define _In_opt_count_(size)
252#define _In_opt_z_
253#define _In_reads_(size)
254#define _In_reads_bytes_(size)
255#define _In_reads_bytes_opt_(size)
256#define _In_reads_opt_(size)
257#define _In_reads_to_ptr_(ptr)
258#define _In_count_(size)
259#define _In_range_(lb, ub)
260#define _In_bytecount_(size)
261#define _In_opt_bytecount_(size)
262#define _In_NLS_string_(size)
263#define __in_bcount(size)
264
265#define _Out_
266#define _Out_bytecap_(nbytes)
267#define _Out_writes_to_(a, b)
268#define _Out_writes_to_opt_(a, b)
269#define _Outptr_
270#define _Outptr_opt_
271#define _Outptr_opt_result_z_
272#define _Out_opt_
273#define _Out_writes_(size)
274#define _Out_write_bytes_(size)
275#define _Out_writes_z_(size)
276#define _Out_writes_all_(size)
277#define _Out_writes_bytes_(size)
278#define _Outref_result_buffer_(size)
279#define _Outptr_result_buffer_(size)
280#define _Out_cap_(size)
281#define _Out_cap_x_(size)
282#define _Out_range_(lb, ub)
283#define _Outptr_result_z_
284#define _Outptr_result_buffer_maybenull_(ptr)
285#define _Outptr_result_maybenull_
286#define _Outptr_result_nullonfailure_
287
288#define __out_ecount_part(a, b)
289
290#define _Inout_
291#define _Inout_z_
292#define _Inout_opt_
293#define _Inout_cap_(size)
294#define _Inout_count_(size)
295#define _Inout_count_c_(size)
296#define _Inout_opt_count_c_(size)
297#define _Inout_bytecount_c_(size)
298#define _Inout_opt_bytecount_c_(size)
299
300#define _Ret_maybenull_
301#define _Ret_notnull_
302#define _Ret_opt_
303
304#define _Use_decl_annotations_
305#define __analysis_assume(expr)
306#define _Analysis_assume_(expr)
307#define _Analysis_assume_nullterminated_(x)
308#define _Success_(expr)
309
310#define __inexpressible_readableTo(size)
311#define __inexpressible_writableTo(size)
312
313#define _Printf_format_string_
314#define _Null_terminated_
315
316#define _Field_size_(size)
317#define _Field_size_full_(size)
318#define _Field_size_opt_(size)
319#define _Post_writable_byte_size_(size)
320#define _Post_readable_byte_size_(size)
321#define __drv_allocatesMem(mem)
322
323#define _COM_Outptr_
324#define _COM_Outptr_opt_
325#define _COM_Outptr_result_maybenull_
326#define _COM_Outptr_opt_result_maybenull_
327
328#define _Null_
329#define _Notnull_
330#define _Maybenull_
331#define THIS_
332#define THIS
333#define PURE = 0
334
335#define _Outptr_result_bytebuffer_(size)
336
337#define __debugbreak()
338
339// GCC produces erros on calling convention attributes.
340#ifdef __GNUC__
341#define __cdecl
342#define __CRTDECL
343#define __stdcall
344#define __vectorcall
345#define __thiscall
346#define __fastcall
347#define __clrcall
348#endif // __GNUC__
349
350//===----------------------------------------------------------------------===//
351//
352//                             Begin: Type Definitions
353//
354//===----------------------------------------------------------------------===//
355
356#ifdef __cplusplus
357
358typedef unsigned char BYTE, UINT8;
359typedef unsigned char *LPBYTE;
360
361typedef BYTE BOOLEAN;
362typedef BOOLEAN *PBOOLEAN;
363
364typedef bool BOOL;
365typedef BOOL *LPBOOL;
366
367typedef int INT;
368typedef long LONG;
369typedef unsigned int UINT;
370typedef unsigned long ULONG;
371typedef long long LONGLONG;
372typedef long long LONG_PTR;
373typedef unsigned long long ULONG_PTR;
374typedef unsigned long long ULONGLONG;
375
376typedef uint16_t WORD;
377typedef uint32_t DWORD;
378typedef DWORD *LPDWORD;
379
380typedef uint32_t UINT32;
381typedef uint64_t UINT64;
382
383typedef signed char INT8, *PINT8;
384typedef signed int INT32, *PINT32;
385
386typedef size_t SIZE_T;
387typedef const char *LPCSTR;
388typedef const char *PCSTR;
389
390typedef int errno_t;
391
392typedef wchar_t WCHAR;
393typedef wchar_t *LPWSTR;
394typedef wchar_t *PWCHAR;
395typedef const wchar_t *LPCWSTR;
396typedef const wchar_t *PCWSTR;
397
398typedef WCHAR OLECHAR;
399typedef OLECHAR *BSTR;
400typedef OLECHAR *LPOLESTR;
401typedef char *LPSTR;
402
403typedef void *LPVOID;
404typedef const void *LPCVOID;
405
406typedef std::nullptr_t nullptr_t;
407
408typedef signed int HRESULT;
409
410//===--------------------- Handle Types -----------------------------------===//
411
412typedef void *HANDLE;
413typedef void *RPC_IF_HANDLE;
414
415#define DECLARE_HANDLE(name)                                                   \
416  struct name##__ {                                                            \
417    int unused;                                                                \
418  };                                                                           \
419  typedef struct name##__ *name
420DECLARE_HANDLE(HINSTANCE);
421
422typedef void *HMODULE;
423
424#define STD_INPUT_HANDLE ((DWORD)-10)
425#define STD_OUTPUT_HANDLE ((DWORD)-11)
426#define STD_ERROR_HANDLE ((DWORD)-12)
427
428//===--------------------- ID Types and Macros for COM --------------------===//
429
430#ifdef __EMULATE_UUID
431struct GUID
432#else  // __EMULATE_UUID
433// These specific definitions are required by clang -fms-extensions.
434typedef struct _GUID
435#endif // __EMULATE_UUID
436{
437  uint32_t Data1;
438  uint16_t Data2;
439  uint16_t Data3;
440  uint8_t Data4[8];
441}
442#ifdef __EMULATE_UUID
443;
444#else  // __EMULATE_UUID
445GUID;
446#endif // __EMULATE_UUID
447typedef GUID CLSID;
448typedef const GUID &REFGUID;
449typedef const GUID &REFCLSID;
450
451typedef GUID IID;
452typedef IID *LPIID;
453typedef const IID &REFIID;
454inline bool IsEqualGUID(REFGUID rguid1, REFGUID rguid2) {
455  // Optimization:
456  if (&rguid1 == &rguid2)
457    return true;
458
459  return !memcmp(&rguid1, &rguid2, sizeof(GUID));
460}
461
462inline bool operator==(REFGUID guidOne, REFGUID guidOther) {
463  return !!IsEqualGUID(guidOne, guidOther);
464}
465
466inline bool operator!=(REFGUID guidOne, REFGUID guidOther) {
467  return !(guidOne == guidOther);
468}
469
470inline bool IsEqualIID(REFIID riid1, REFIID riid2) {
471  return IsEqualGUID(riid1, riid2);
472}
473
474inline bool IsEqualCLSID(REFCLSID rclsid1, REFCLSID rclsid2) {
475  return IsEqualGUID(rclsid1, rclsid2);
476}
477
478//===--------------------- Struct Types -----------------------------------===//
479
480typedef struct _FILETIME {
481  DWORD dwLowDateTime;
482  DWORD dwHighDateTime;
483} FILETIME, *PFILETIME, *LPFILETIME;
484
485typedef struct _BY_HANDLE_FILE_INFORMATION {
486  DWORD dwFileAttributes;
487  FILETIME ftCreationTime;
488  FILETIME ftLastAccessTime;
489  FILETIME ftLastWriteTime;
490  DWORD dwVolumeSerialNumber;
491  DWORD nFileSizeHigh;
492  DWORD nFileSizeLow;
493  DWORD nNumberOfLinks;
494  DWORD nFileIndexHigh;
495  DWORD nFileIndexLow;
496} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION,
497    *LPBY_HANDLE_FILE_INFORMATION;
498
499typedef struct _WIN32_FIND_DATAW {
500  DWORD dwFileAttributes;
501  FILETIME ftCreationTime;
502  FILETIME ftLastAccessTime;
503  FILETIME ftLastWriteTime;
504  DWORD nFileSizeHigh;
505  DWORD nFileSizeLow;
506  DWORD dwReserved0;
507  DWORD dwReserved1;
508  WCHAR cFileName[260];
509  WCHAR cAlternateFileName[14];
510} WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
511
512typedef union _LARGE_INTEGER {
513  struct {
514    DWORD LowPart;
515    DWORD HighPart;
516  } u;
517  LONGLONG QuadPart;
518} LARGE_INTEGER;
519
520typedef LARGE_INTEGER *PLARGE_INTEGER;
521
522typedef union _ULARGE_INTEGER {
523  struct {
524    DWORD LowPart;
525    DWORD HighPart;
526  } u;
527  ULONGLONG QuadPart;
528} ULARGE_INTEGER;
529
530typedef ULARGE_INTEGER *PULARGE_INTEGER;
531
532typedef struct tagSTATSTG {
533  LPOLESTR pwcsName;
534  DWORD type;
535  ULARGE_INTEGER cbSize;
536  FILETIME mtime;
537  FILETIME ctime;
538  FILETIME atime;
539  DWORD grfMode;
540  DWORD grfLocksSupported;
541  CLSID clsid;
542  DWORD grfStateBits;
543  DWORD reserved;
544} STATSTG;
545
546enum tagSTATFLAG {
547  STATFLAG_DEFAULT = 0,
548  STATFLAG_NONAME = 1,
549  STATFLAG_NOOPEN = 2
550};
551
552//===--------------------- UUID Related Macros ----------------------------===//
553
554#ifdef __EMULATE_UUID
555
556// The following macros are defined to facilitate the lack of 'uuid' on Linux.
557
558constexpr uint8_t nybble_from_hex(char c) {
559  return ((c >= '0' && c <= '9')
560              ? (c - '0')
561              : ((c >= 'a' && c <= 'f')
562                     ? (c - 'a' + 10)
563                     : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10)
564                                               : /* Should be an error */ -1)));
565}
566
567constexpr uint8_t byte_from_hex(char c1, char c2) {
568  return nybble_from_hex(c1) << 4 | nybble_from_hex(c2);
569}
570
571constexpr uint8_t byte_from_hexstr(const char str[2]) {
572  return nybble_from_hex(str[0]) << 4 | nybble_from_hex(str[1]);
573}
574
575constexpr GUID guid_from_string(const char str[37]) {
576  return GUID{static_cast<uint32_t>(byte_from_hexstr(str)) << 24 |
577                  static_cast<uint32_t>(byte_from_hexstr(str + 2)) << 16 |
578                  static_cast<uint32_t>(byte_from_hexstr(str + 4)) << 8 |
579                  byte_from_hexstr(str + 6),
580              static_cast<uint16_t>(
581                  static_cast<uint16_t>(byte_from_hexstr(str + 9)) << 8 |
582                  byte_from_hexstr(str + 11)),
583              static_cast<uint16_t>(
584                  static_cast<uint16_t>(byte_from_hexstr(str + 14)) << 8 |
585                  byte_from_hexstr(str + 16)),
586              {byte_from_hexstr(str + 19), byte_from_hexstr(str + 21),
587               byte_from_hexstr(str + 24), byte_from_hexstr(str + 26),
588               byte_from_hexstr(str + 28), byte_from_hexstr(str + 30),
589               byte_from_hexstr(str + 32), byte_from_hexstr(str + 34)}};
590}
591
592template <typename interface> inline GUID __emulated_uuidof();
593
594#define CROSS_PLATFORM_UUIDOF(interface, spec)                                 \
595  struct interface;                                                            \
596  template <> inline GUID __emulated_uuidof<interface>() {                     \
597    static const IID _IID = guid_from_string(spec);                            \
598    return _IID;                                                               \
599  }
600
601#define __uuidof(T) __emulated_uuidof<typename std::decay<T>::type>()
602
603#define IID_PPV_ARGS(ppType)                                                   \
604  __uuidof(decltype(**(ppType))), reinterpret_cast<void **>(ppType)
605
606#else // __EMULATE_UUID
607
608#ifndef CROSS_PLATFORM_UUIDOF
609// Warning: This macro exists in dxcapi.h as well
610#define CROSS_PLATFORM_UUIDOF(interface, spec)                                 \
611  struct __declspec(uuid(spec)) interface;
612#endif
613
614template <typename T> inline void **IID_PPV_ARGS_Helper(T **pp) {
615  return reinterpret_cast<void **>(pp);
616}
617#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
618
619#endif // __EMULATE_UUID
620
621// Needed for d3d headers, but fail to create actual interfaces
622#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
623#define DECLSPEC_UUID(x)
624#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x)
625#define DECLARE_INTERFACE(iface)                struct iface
626#define DECLARE_INTERFACE_(iface, parent)       DECLARE_INTERFACE(iface) : parent
627
628//===--------------------- COM Interfaces ---------------------------------===//
629
630CROSS_PLATFORM_UUIDOF(IUnknown, "00000000-0000-0000-C000-000000000046")
631struct IUnknown {
632  IUnknown() {};
633  virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) = 0;
634  virtual ULONG AddRef() = 0;
635  virtual ULONG Release() = 0;
636  template <class Q> HRESULT QueryInterface(Q **pp) {
637    return QueryInterface(__uuidof(Q), (void **)pp);
638  }
639};
640
641CROSS_PLATFORM_UUIDOF(INoMarshal, "ECC8691B-C1DB-4DC0-855E-65F6C551AF49")
642struct INoMarshal : public IUnknown {};
643
644CROSS_PLATFORM_UUIDOF(IMalloc, "00000002-0000-0000-C000-000000000046")
645struct IMalloc : public IUnknown {
646  virtual void *Alloc(size_t size) = 0;
647  virtual void *Realloc(void *ptr, size_t size) = 0;
648  virtual void Free(void *ptr) = 0;
649  virtual size_t GetSize(void *pv) = 0;
650  virtual int DidAlloc(void *pv) = 0;
651  virtual void HeapMinimize(void) = 0;
652};
653
654CROSS_PLATFORM_UUIDOF(ISequentialStream, "0C733A30-2A1C-11CE-ADE5-00AA0044773D")
655struct ISequentialStream : public IUnknown {
656  virtual HRESULT Read(void *pv, ULONG cb, ULONG *pcbRead) = 0;
657  virtual HRESULT Write(const void *pv, ULONG cb, ULONG *pcbWritten) = 0;
658};
659
660CROSS_PLATFORM_UUIDOF(IStream, "0000000c-0000-0000-C000-000000000046")
661struct IStream : public ISequentialStream {
662  virtual HRESULT Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin,
663                       ULARGE_INTEGER *plibNewPosition) = 0;
664  virtual HRESULT SetSize(ULARGE_INTEGER libNewSize) = 0;
665  virtual HRESULT CopyTo(IStream *pstm, ULARGE_INTEGER cb,
666                         ULARGE_INTEGER *pcbRead,
667                         ULARGE_INTEGER *pcbWritten) = 0;
668
669  virtual HRESULT Commit(DWORD grfCommitFlags) = 0;
670
671  virtual HRESULT Revert(void) = 0;
672
673  virtual HRESULT LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
674                             DWORD dwLockType) = 0;
675
676  virtual HRESULT UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
677                               DWORD dwLockType) = 0;
678
679  virtual HRESULT Stat(STATSTG *pstatstg, DWORD grfStatFlag) = 0;
680
681  virtual HRESULT Clone(IStream **ppstm) = 0;
682};
683
684// These don't need stub implementations as they come from the DirectX Headers
685// They still need the __uuidof() though
686CROSS_PLATFORM_UUIDOF(ID3D12LibraryReflection, "8E349D19-54DB-4A56-9DC9-119D87BDB804")
687CROSS_PLATFORM_UUIDOF(ID3D12ShaderReflection, "5A58797D-A72C-478D-8BA2-EFC6B0EFE88E")
688
689//===--------------------- COM Pointer Types ------------------------------===//
690
691class CAllocator {
692public:
693  static void *Reallocate(void *p, size_t nBytes) throw();
694  static void *Allocate(size_t nBytes) throw();
695  static void Free(void *p) throw();
696};
697
698template <class T> class CComPtrBase {
699protected:
700  CComPtrBase() throw() { p = nullptr; }
701  CComPtrBase(T *lp) throw() {
702    p = lp;
703    if (p != nullptr)
704      p->AddRef();
705  }
706  void Swap(CComPtrBase &other) {
707    T *pTemp = p;
708    p = other.p;
709    other.p = pTemp;
710  }
711
712public:
713  ~CComPtrBase() throw() {
714    if (p) {
715      p->Release();
716      p = nullptr;
717    }
718  }
719  operator T *() const throw() { return p; }
720  T &operator*() const { return *p; }
721  T *operator->() const { return p; }
722  T **operator&() throw() {
723    assert(p == nullptr);
724    return &p;
725  }
726  bool operator!() const throw() { return (p == nullptr); }
727  bool operator<(T *pT) const throw() { return p < pT; }
728  bool operator!=(T *pT) const { return !operator==(pT); }
729  bool operator==(T *pT) const throw() { return p == pT; }
730
731  // Release the interface and set to nullptr
732  void Release() throw() {
733    T *pTemp = p;
734    if (pTemp) {
735      p = nullptr;
736      pTemp->Release();
737    }
738  }
739
740  // Attach to an existing interface (does not AddRef)
741  void Attach(T *p2) throw() {
742    if (p) {
743      ULONG ref = p->Release();
744      (void)(ref);
745      // Attaching to the same object only works if duplicate references are
746      // being coalesced.  Otherwise re-attaching will cause the pointer to be
747      // released and may cause a crash on a subsequent dereference.
748      assert(ref != 0 || p2 != p);
749    }
750    p = p2;
751  }
752
753  // Detach the interface (does not Release)
754  T *Detach() throw() {
755    T *pt = p;
756    p = nullptr;
757    return pt;
758  }
759
760  HRESULT CopyTo(T **ppT) throw() {
761    assert(ppT != nullptr);
762    if (ppT == nullptr)
763      return E_POINTER;
764    *ppT = p;
765    if (p)
766      p->AddRef();
767    return S_OK;
768  }
769
770  template <class Q> HRESULT QueryInterface(Q **pp) const throw() {
771    assert(pp != nullptr);
772    return p->QueryInterface(__uuidof(Q), (void **)pp);
773  }
774
775  T *p;
776};
777
778template <class T> class CComPtr : public CComPtrBase<T> {
779public:
780  CComPtr() throw() {}
781  CComPtr(T *lp) throw() : CComPtrBase<T>(lp) {}
782  CComPtr(const CComPtr<T> &lp) throw() : CComPtrBase<T>(lp.p) {}
783  T *operator=(T *lp) throw() {
784    if (*this != lp) {
785      CComPtr(lp).Swap(*this);
786    }
787    return *this;
788  }
789
790  inline bool IsEqualObject(IUnknown *pOther) throw() {
791    if (this->p == nullptr && pOther == nullptr)
792      return true; // They are both NULL objects
793
794    if (this->p == nullptr || pOther == nullptr)
795      return false; // One is NULL the other is not
796
797    CComPtr<IUnknown> punk1;
798    CComPtr<IUnknown> punk2;
799    this->p->QueryInterface(__uuidof(IUnknown), (void **)&punk1);
800    pOther->QueryInterface(__uuidof(IUnknown), (void **)&punk2);
801    return punk1 == punk2;
802  }
803
804  void ComPtrAssign(IUnknown **pp, IUnknown *lp, REFIID riid) {
805    IUnknown *pTemp = *pp; // takes ownership
806    if (lp == nullptr || FAILED(lp->QueryInterface(riid, (void **)pp)))
807      *pp = nullptr;
808    if (pTemp)
809      pTemp->Release();
810  }
811
812  template <typename Q> T *operator=(const CComPtr<Q> &lp) throw() {
813    if (!this->IsEqualObject(lp)) {
814      ComPtrAssign((IUnknown **)&this->p, lp, __uuidof(T));
815    }
816    return *this;
817  }
818
819  T *operator=(const CComPtr<T> &lp) throw() {
820    if (*this != lp) {
821      CComPtr(lp).Swap(*this);
822    }
823    return *this;
824  }
825
826  CComPtr(CComPtr<T> &&lp) throw() : CComPtrBase<T>() { lp.Swap(*this); }
827
828  T *operator=(CComPtr<T> &&lp) throw() {
829    if (*this != lp) {
830      CComPtr(static_cast<CComPtr &&>(lp)).Swap(*this);
831    }
832    return *this;
833  }
834};
835
836template <class T> class CSimpleArray : public std::vector<T> {
837public:
838  bool Add(const T &t) {
839    this->push_back(t);
840    return true;
841  }
842  int GetSize() { return this->size(); }
843  T *GetData() { return this->data(); }
844  void RemoveAll() { this->clear(); }
845};
846
847template <class T, class Allocator = CAllocator> class CHeapPtrBase {
848protected:
849  CHeapPtrBase() throw() : m_pData(NULL) {}
850  CHeapPtrBase(CHeapPtrBase<T, Allocator> &p) throw() {
851    m_pData = p.Detach(); // Transfer ownership
852  }
853  explicit CHeapPtrBase(T *pData) throw() : m_pData(pData) {}
854
855public:
856  ~CHeapPtrBase() throw() { Free(); }
857
858protected:
859  CHeapPtrBase<T, Allocator> &operator=(CHeapPtrBase<T, Allocator> &p) throw() {
860    if (m_pData != p.m_pData)
861      Attach(p.Detach()); // Transfer ownership
862    return *this;
863  }
864
865public:
866  operator T *() const throw() { return m_pData; }
867  T *operator->() const throw() {
868    assert(m_pData != NULL);
869    return m_pData;
870  }
871
872  T **operator&() throw() {
873    assert(m_pData == NULL);
874    return &m_pData;
875  }
876
877  // Allocate a buffer with the given number of bytes
878  bool AllocateBytes(size_t nBytes) throw() {
879    assert(m_pData == NULL);
880    m_pData = static_cast<T *>(Allocator::Allocate(nBytes * sizeof(char)));
881    if (m_pData == NULL)
882      return false;
883
884    return true;
885  }
886
887  // Attach to an existing pointer (takes ownership)
888  void Attach(T *pData) throw() {
889    Allocator::Free(m_pData);
890    m_pData = pData;
891  }
892
893  // Detach the pointer (releases ownership)
894  T *Detach() throw() {
895    T *pTemp = m_pData;
896    m_pData = NULL;
897    return pTemp;
898  }
899
900  // Free the memory pointed to, and set the pointer to NULL
901  void Free() throw() {
902    Allocator::Free(m_pData);
903    m_pData = NULL;
904  }
905
906  // Reallocate the buffer to hold a given number of bytes
907  bool ReallocateBytes(size_t nBytes) throw() {
908    T *pNew;
909    pNew =
910        static_cast<T *>(Allocator::Reallocate(m_pData, nBytes * sizeof(char)));
911    if (pNew == NULL)
912      return false;
913    m_pData = pNew;
914
915    return true;
916  }
917
918public:
919  T *m_pData;
920};
921
922template <typename T, class Allocator = CAllocator>
923class CHeapPtr : public CHeapPtrBase<T, Allocator> {
924public:
925  CHeapPtr() throw() {}
926  CHeapPtr(CHeapPtr<T, Allocator> &p) throw() : CHeapPtrBase<T, Allocator>(p) {}
927  explicit CHeapPtr(T *p) throw() : CHeapPtrBase<T, Allocator>(p) {}
928  CHeapPtr<T> &operator=(CHeapPtr<T, Allocator> &p) throw() {
929    CHeapPtrBase<T, Allocator>::operator=(p);
930    return *this;
931  }
932
933  // Allocate a buffer with the given number of elements
934  bool Allocate(size_t nElements = 1) throw() {
935    size_t nBytes = nElements * sizeof(T);
936    return this->AllocateBytes(nBytes);
937  }
938
939  // Reallocate the buffer to hold a given number of elements
940  bool Reallocate(size_t nElements) throw() {
941    size_t nBytes = nElements * sizeof(T);
942    return this->ReallocateBytes(nBytes);
943  }
944};
945
946#define CComHeapPtr CHeapPtr
947
948//===--------------------------- BSTR Allocation --------------------------===//
949
950void SysFreeString(BSTR bstrString);
951// Allocate string with length prefix
952BSTR SysAllocStringLen(const OLECHAR *strIn, UINT ui);
953
954//===--------------------- UTF-8 Related Types ----------------------------===//
955
956// Code Page
957#define CP_ACP 0
958#define CP_UTF8 65001 // UTF-8 translation.
959
960// Convert Windows codepage value to locale string
961const char *CPToLocale(uint32_t CodePage);
962
963// The t_nBufferLength parameter is part of the published interface, but not
964// used here.
965template <int t_nBufferLength = 128> class CW2AEX {
966public:
967  CW2AEX(LPCWSTR psz, UINT nCodePage = CP_UTF8) {
968    const char *locale = CPToLocale(nCodePage);
969    if (locale == nullptr) {
970      // Current Implementation only supports CP_UTF8, and CP_ACP
971      assert(false && "CW2AEX implementation for Linux only handles "
972                      "UTF8 and ACP code pages");
973      return;
974    }
975
976    if (!psz) {
977      m_psz = NULL;
978      return;
979    }
980
981    locale = setlocale(LC_ALL, locale);
982    int len = (wcslen(psz) + 1) * 4;
983    m_psz = new char[len];
984    std::wcstombs(m_psz, psz, len);
985    setlocale(LC_ALL, locale);
986  }
987
988  ~CW2AEX() { delete[] m_psz; }
989
990  operator LPSTR() const { return m_psz; }
991
992  char *m_psz;
993};
994typedef CW2AEX<> CW2A;
995
996// The t_nBufferLength parameter is part of the published interface, but not
997// used here.
998template <int t_nBufferLength = 128> class CA2WEX {
999public:
1000  CA2WEX(LPCSTR psz, UINT nCodePage = CP_UTF8) {
1001    const char *locale = CPToLocale(nCodePage);
1002    if (locale == nullptr) {
1003      // Current Implementation only supports CP_UTF8, and CP_ACP
1004      assert(false && "CA2WEX implementation for Linux only handles "
1005                      "UTF8 and ACP code pages");
1006      return;
1007    }
1008
1009    if (!psz) {
1010      m_psz = NULL;
1011      return;
1012    }
1013
1014    locale = setlocale(LC_ALL, locale);
1015    int len = strlen(psz) + 1;
1016    m_psz = new wchar_t[len];
1017    std::mbstowcs(m_psz, psz, len);
1018    setlocale(LC_ALL, locale);
1019  }
1020
1021  ~CA2WEX() { delete[] m_psz; }
1022
1023  operator LPWSTR() const { return m_psz; }
1024
1025  wchar_t *m_psz;
1026};
1027
1028typedef CA2WEX<> CA2W;
1029
1030//===--------- File IO Related Types ----------------===//
1031
1032class CHandle {
1033public:
1034  CHandle(HANDLE h);
1035  ~CHandle();
1036  operator HANDLE() const throw();
1037
1038private:
1039  HANDLE m_h;
1040};
1041
1042#endif // __cplusplus
1043
1044#endif // _WIN32
1045
1046#endif // LLVM_SUPPORT_WIN_ADAPTER_H