Skip to content

Commit

Permalink
Add C++ ABI tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gchatelet committed Sep 14, 2015
1 parent 0742596 commit ed84fe6
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 14 deletions.
157 changes: 157 additions & 0 deletions test/runnable/cpp_abi_tests.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// EXTRA_CPP_SOURCES: cpp_abi_tests.cpp

extern(C++) {

struct S
{
float a = 1;
}

bool passthrough(bool value);
byte passthrough(byte value);
ubyte passthrough(ubyte value);
char passthrough(char value);
dchar passthrough(dchar value);
short passthrough(short value);
ushort passthrough(ushort value);
int passthrough(int value);
uint passthrough(uint value);
long passthrough(long value);
ulong passthrough(ulong value);
float passthrough(float value);
double passthrough(double value);
S passthrough(S value);

bool passthrough_ptr(bool *value);
byte passthrough_ptr(byte *value);
ubyte passthrough_ptr(ubyte *value);
char passthrough_ptr(char *value);
dchar passthrough_ptr(dchar *value);
short passthrough_ptr(short *value);
ushort passthrough_ptr(ushort *value);
int passthrough_ptr(int *value);
uint passthrough_ptr(uint *value);
long passthrough_ptr(long *value);
ulong passthrough_ptr(ulong *value);
float passthrough_ptr(float *value);
double passthrough_ptr(double *value);
S passthrough_ptr(S *value);

bool passthrough_ref(ref bool value);
byte passthrough_ref(ref byte value);
ubyte passthrough_ref(ref ubyte value);
char passthrough_ref(ref char value);
dchar passthrough_ref(ref dchar value);
short passthrough_ref(ref short value);
ushort passthrough_ref(ref ushort value);
int passthrough_ref(ref int value);
uint passthrough_ref(ref uint value);
long passthrough_ref(ref long value);
ulong passthrough_ref(ref ulong value);
float passthrough_ref(ref float value);
double passthrough_ref(ref double value);
S passthrough_ref(ref S value);
}

template IsSigned(T)
{
enum IsSigned = is(T==byte) ||
is(T==short) ||
is(T==int) ||
is(T==long);
}

template IsUnsigned(T)
{
enum IsUnsigned = is(T==ubyte) ||
is(T==ushort) ||
is(T==uint) ||
is(T==ulong);
}

template IsIntegral(T)
{
enum IsIntegral = IsSigned!T || IsUnsigned!T;
}

template IsFloatingPoint(T)
{
enum IsFloatingPoint = is(T==float) || is(T==double) || is(T==real);
}

template IsBoolean(T)
{
enum IsBoolean = is(T==bool);
}

template IsSomeChar(T)
{
enum IsSomeChar = is(T==char) || is(T==dchar);
}

void check(T)(T actual, T expected)
{
assert(actual is expected);
}

void check(T)(T value)
{
check(passthrough(value), value);
check(passthrough_ptr(&value), value);
check(passthrough_ref(value), value);
}

T[] values(T)()
{
T[] values;
static if(IsBoolean!T)
{
values ~= true;
values ~= false;
}
else static if(IsSomeChar!T)
{
values ~= T.init;
values ~= T('a');
values ~= T('z');
}
else
{
values ~= T(0);
values ~= T(1);
static if(IsIntegral!T)
{
static if(IsSigned!T) values ~= T.min;
values ~= T.max;
}
else static if(IsFloatingPoint!T)
{
values ~= T.nan;
values ~= T.min_normal;
values ~= T.max;
}
else
{
assert(0);
}
}
return values;
}

void main()
{
foreach(bool val; values!bool()) check(val);
foreach(byte val; values!byte()) check(val);
foreach(ubyte val; values!ubyte()) check(val);
foreach(char val; values!char()) check(val);
foreach(dchar val; values!dchar()) check(val);
foreach(short val; values!short()) check(val);
foreach(ushort val; values!ushort()) check(val);
foreach(int val; values!int()) check(val);
foreach(uint val; values!uint()) check(val);
foreach(long val; values!long()) check(val);
foreach(ulong val; values!ulong()) check(val);
foreach(float val; values!float()) check(val);
foreach(double val; values!double()) check(val);
check(S());
}
10 changes: 0 additions & 10 deletions test/runnable/cppmangle1.d

This file was deleted.

60 changes: 60 additions & 0 deletions test/runnable/extra-files/cpp_abi_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
struct S{
float a;
};

bool passthrough(bool value) { return value; }
signed char passthrough(signed char value) { return value; }
unsigned char passthrough(unsigned char value) { return value; }
char passthrough(char value) { return value; }
wchar_t passthrough(wchar_t value) { return value; }
short passthrough(short value) { return value; }
unsigned short passthrough(unsigned short value) { return value; }
int passthrough(int value) { return value; }
unsigned int passthrough(unsigned int value) { return value; }
long passthrough(long value) { return value; }
unsigned long passthrough(unsigned long value) { return value; }
long long passthrough(long long value) { return value; }
unsigned long long passthrough(unsigned long long value) { return value; }
float passthrough(float value) { return value; }
double passthrough(double value) { return value; }
S passthrough(S value) { return value; }

bool passthrough_ptr(bool *value) { return *value; }
signed char passthrough_ptr(signed char *value) { return *value; }
unsigned char passthrough_ptr(unsigned char *value) { return *value; }
char passthrough_ptr(char *value) { return *value; }
wchar_t passthrough_ptr(wchar_t *value) { return *value; }
short passthrough_ptr(short *value) { return *value; }
unsigned short passthrough_ptr(unsigned short *value) { return *value; }
int passthrough_ptr(int *value) { return *value; }
unsigned int passthrough_ptr(unsigned int *value) { return *value; }
long passthrough_ptr(long *value) { return *value; }
unsigned long passthrough_ptr(unsigned long *value) { return *value; }
long long passthrough_ptr(long long *value) { return *value; }
unsigned long long passthrough_ptr(unsigned long long *value) { return *value; }
float passthrough_ptr(float *value) { return *value; }
double passthrough_ptr(double *value) { return *value; }
S passthrough_ptr(S *value) { return *value; }

bool passthrough_ref(bool &value) { return value; }
signed char passthrough_ref(signed char &value) { return value; }
unsigned char passthrough_ref(unsigned char &value) { return value; }
char passthrough_ref(char &value) { return value; }
wchar_t passthrough_ref(wchar_t &value) { return value; }
short passthrough_ref(short &value) { return value; }
unsigned short passthrough_ref(unsigned short &value) { return value; }
int passthrough_ref(int &value) { return value; }
unsigned int passthrough_ref(unsigned int &value) { return value; }
long passthrough_ref(long &value) { return value; }
unsigned long passthrough_ref(unsigned long &value) { return value; }
long long passthrough_ref(long long &value) { return value; }
unsigned long long passthrough_ref(unsigned long long &value) { return value; }
float passthrough_ref(float &value) { return value; }
double passthrough_ref(double &value) { return value; }
S passthrough_ref(S &value) { return value; }

// Uncomment when mangling is fixed
// typedef void(*fn0)();
// fn0 passthrough_fn0 (fn0 value) { return value; }
// typedef int (*fn1)(int);
// fn1 passthrough_fn1 (fn1 value) { return value; }
4 changes: 0 additions & 4 deletions test/runnable/extra-files/cppmangle1.cpp

This file was deleted.

0 comments on commit ed84fe6

Please sign in to comment.