Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.

Commit 9250b1c

Browse files
committed
MSVC: Enable compilation of C files with clang
For that to work, I had to drop pre-VS2015 support in `rt/msvc.c`. LDC requires VS2015+ in `ldc.eh_msvc` anyway. The nullfunc trick led to problems in 2 scenarios: * Linking with LLD. I had to make sure the MS lib containing the __acrt_iob_func preceeded druntime in the linker command line, as it apparently happily chose nullfunc otherwise. * Compiling the C source with clang. Even when linking with the MS linker, I couldn't get it to use the real __acrt_iob_func. The `/alternatename` directive is totally undocumented, so I'm not too surprised.
1 parent b2c58c7 commit 9250b1c

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

src/ldc/msvc.c

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ typedef BOOL WINAPI _TLSCB(HINSTANCE, DWORD, LPVOID);
9999
#pragma section(".CRT$XLB", long, read)
100100

101101
#pragma data_seg(".CRT$XLB")
102+
#ifdef __clang__
103+
__attribute__((unused))
104+
#endif
102105
__declspec(allocate(".CRT$XLB")) static _TLSCB* _pfix_tls = &fix_tlsAlignment;
103106

104107
#pragma data_seg(pop)

src/rt/msvc.c

+29-9
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ FILE* __iob_func(); // VS2013-
3434
int _set_output_format(int format); // VS2013-
3535

3636
//extern const char* __acrt_iob_func;
37+
#ifndef LDC
3738
extern const char* _nullfunc = 0;
39+
#endif
3840

3941
#if defined _M_IX86
4042
#define C_PREFIX "_"
@@ -47,12 +49,19 @@ extern const char* _nullfunc = 0;
4749
#define DECLARE_ALTERNATE_NAME(name, alternate_name) \
4850
__pragma(comment(linker, "/alternatename:" C_PREFIX #name "=" C_PREFIX #alternate_name))
4951

52+
#ifndef LDC
5053
DECLARE_ALTERNATE_NAME (__acrt_iob_func, _nullfunc);
5154
DECLARE_ALTERNATE_NAME (__iob_func, _nullfunc);
5255
DECLARE_ALTERNATE_NAME (_set_output_format, _nullfunc);
56+
#endif
5357

5458
void init_msvc()
5559
{
60+
#ifdef LDC
61+
stdin = __acrt_iob_func(0);
62+
stdout = __acrt_iob_func(1);
63+
stderr = __acrt_iob_func(2);
64+
#else
5665
if (&__acrt_iob_func != (void*) &_nullfunc)
5766
{
5867
stdin = __acrt_iob_func(0);
@@ -71,22 +80,33 @@ void init_msvc()
7180
const int _TWO_DIGIT_EXPONENT = 1;
7281
_set_output_format(_TWO_DIGIT_EXPONENT);
7382
}
83+
#endif // !LDC
7484
}
7585

86+
#ifdef LDC
87+
88+
// needed for POSIX names
89+
#pragma comment(lib, "oldnames.lib")
90+
// VS2015+: printf/scanf family defined inline in C headers
91+
#pragma comment(lib, "legacy_stdio_definitions.lib")
92+
93+
#else // !LDC
94+
7695
// VS2015+ provides C99-conformant (v)snprintf functions, so weakly
7796
// link to legacy _(v)snprintf (not C99-conformant!) for VS2013- only
97+
7898
DECLARE_ALTERNATE_NAME (snprintf, _snprintf);
7999
DECLARE_ALTERNATE_NAME (vsnprintf, _vsnprintf);
80100

81-
DECLARE_ALTERNATE_NAME (fileno, _fileno);
82-
83101
// VS2013- implements these functions as macros, VS2015+ provides symbols
102+
84103
DECLARE_ALTERNATE_NAME (_fputc_nolock, _msvc_fputc_nolock);
85104
DECLARE_ALTERNATE_NAME (_fgetc_nolock, _msvc_fgetc_nolock);
86105
DECLARE_ALTERNATE_NAME (rewind, _msvc_rewind);
87106
DECLARE_ALTERNATE_NAME (clearerr, _msvc_clearerr);
88107
DECLARE_ALTERNATE_NAME (feof, _msvc_feof);
89108
DECLARE_ALTERNATE_NAME (ferror, _msvc_ferror);
109+
DECLARE_ALTERNATE_NAME (fileno, _msvc_fileno);
90110

91111
// VS2013- helper functions
92112
int _filbuf(FILE* fp);
@@ -151,6 +171,13 @@ int _msvc_ferror(FILE* stream)
151171
return stream->_flag & _IOERR;
152172
}
153173

174+
int _msvc_fileno(FILE* stream)
175+
{
176+
return stream->_file;
177+
}
178+
179+
#endif // !LDC
180+
154181

155182

156183
/**
@@ -180,10 +207,3 @@ DECLARE_ALTERNATE_NAME (fmodf, _msvc_fmodf);
180207
DECLARE_ALTERNATE_NAME (modff, _msvc_modff);
181208

182209
#endif // _M_IX86
183-
184-
// LDC
185-
#pragma comment(lib, "oldnames.lib") // needed for POSIX names
186-
#if _MSC_VER >= 1900 // VS2015+
187-
// needed for some symbols that are inline functions in the C headers
188-
#pragma comment(lib, "legacy_stdio_definitions.lib")
189-
#endif

0 commit comments

Comments
 (0)