Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions compiler/test/compilable/importc_wchar_t.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// EXTRA_SOURCES: imports/importc_wchar_t_c.c

import importc_wchar_t_c;

version (Windows)
{
/+ On Windows, we expect C's `wchar_t` to be D's `wchar`. +/

static assert(is(typeof(wchar_t_aggregate.w) == wchar));

alias Func = extern(C) void function(const(wchar)* str);

Func wcharT()
{
wchar c = 0;
wchar_t_aggregate w = wchar_t_aggregate('W');
w.p = &c;

accept_wchar_t_string("Hello, World!");
accept_wchar_t_string("Hello, World!"w.ptr);
accept_wchar_t_string(&w.w);
accept_wchar_t_string(w.p);

static if (__traits(hasMember, importc_wchar_t_c, "accept_msvc___wchar_t_string"))
{
accept_msvc___wchar_t_string("Hello, World!");
accept_msvc___wchar_t_string("Hello, World!"w.ptr);
accept_msvc___wchar_t_string(&w.w);
}

return &accept_wchar_t_string;
}
}
else
{
/+ On non-Windows platforms, we expect C's `wchar_t` to be whatever `<stddef.h>` defined it as. +/

alias WCharT = typeof(wchar_t_aggregate.w);
static assert(__traits(isScalar, WCharT));

alias Func = extern(C) void function(const(WCharT)* str);

Func wcharT()
{
WCharT c = 0;
wchar_t_aggregate w = wchar_t_aggregate('W');
w.p = &c;

accept_wchar_t_string(&w.w);
accept_wchar_t_string(w.p);

static if (WCharT.sizeof == 4)
{
accept_wchar_t_string(cast(const(WCharT)*) "Hello, World!"d.ptr);
}
else static if (WCharT.sizeof == 2)
{
accept_wchar_t_string(cast(const(WCharT)*) "Hello, World!"w.ptr);
}
else static if (WCharT.sizeof == 1)
{
accept_wchar_t_string(cast(const(WCharT)*) "Hello, World!".ptr);
}

return &accept_wchar_t_string;
}
}
20 changes: 20 additions & 0 deletions compiler/test/compilable/imports/importc_wchar_t_c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

#include <stddef.h>

_Static_assert(sizeof(__importc_char) == 1, "sizeof(__importc_char) == 1");
_Static_assert(sizeof(__importc_wchar) == 2, "sizeof(__importc_wchar) == 2");
_Static_assert(sizeof(__importc_dchar) == 4, "sizeof(__importc_dchar) == 4");

typedef struct
{
wchar_t w;
wchar_t *p;
} wchar_t_aggregate;

void accept_wchar_t_string(const wchar_t *str)
{}

#ifdef _MSC_VER
void accept_msvc___wchar_t_string(const __wchar_t *str)
{}
#endif
6 changes: 6 additions & 0 deletions druntime/src/__importc_builtins.di
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ version (CRuntime_Microsoft)
alias __int64 = long;
}

/* Make D's character types available in ImportC.
*/
alias __importc_char = char;
alias __importc_wchar = wchar;
alias __importc_dchar = dchar;

/*********** floating point *************/

/* https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
Expand Down
15 changes: 15 additions & 0 deletions druntime/src/importc.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,21 @@ typedef unsigned short __uint16_t;
typedef unsigned int __uint32_t;
typedef unsigned long long __uint64_t;

/* wchar_t */
#if defined(_WIN32)
#ifndef _WCHAR_T_DEFINED
// On Windows, wchar_t is defined as an unsigned 16-bit integer: the same as D's wchar.
typedef __importc_wchar wchar_t;
#define _WCHAR_T_DEFINED 1
#define _NATIVE_WCHAR_T_DEFINED 1

#ifdef _MSC_VER
// Microsoft go a step further and have a proper built-in type.
typedef __importc_wchar __wchar_t;
#endif
#endif
#endif

/*********************
* Obsolete detritus
*/
Expand Down
11 changes: 11 additions & 0 deletions spec/importc.dd
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,12 @@ $(H2 $(LNAME2 implementation, Implementation))
C compiler) on the target platform.
)

$(H3 $(LNAME2 wchar_t, `wchar_t`))

$(P When targeting Windows, `wchar_t` is a `typedef` for $(RELATIVE_LINK2 d-character-types, `__importc_wchar`).
When targeting platforms other than Windows, `wchar_t` receives no special treatment
and thus is defined by the `<stddef.h>` header, as usual.)

$(H3 $(LNAME2 implicit-function-declaration, Implicit Function Declarations))

$(P Implicit function declarations:)
Expand Down Expand Up @@ -731,6 +737,11 @@ _Static_assert(sizeof(A) == 1, "A should be size 1");
)


$(H3 $(LNAME2 d-character-types, D Character Types))

$(P D's character types are available in ImportC via the
`__importc_char`, `__importc_wchar`, and `__importc_dchar` aliases.)

$(H3 $(LNAME2 register, Register Storage Class))

$(P Objects with `register` storage class are treated as `auto` declarations.)
Expand Down
Loading