| // EXTRA_CPP_SOURCES: externmangle.cpp |
| // REQUIRED_ARGS: -extern-std=c++11 |
| |
| import core.stdc.config; |
| import core.stdc.stdint; |
| |
| extern(C++): |
| |
| struct Foo(X) |
| { |
| X* v; |
| } |
| |
| |
| struct Boo(X) |
| { |
| X* v; |
| } |
| |
| |
| void test1(Foo!int arg1); |
| void test2(int* arg2, Boo!(int*) arg1); |
| |
| |
| struct Test3(int X, int Y) |
| { |
| } |
| |
| void test3(Test3!(3,3) arg1); |
| |
| void test4(Foo!(int*) arg1, Boo!(int*) arg2, Boo!(int*) arg3, int*, Foo!(double)); |
| |
| void test5(Foo!(int*) arg1, Boo!(int*) arg2, Boo!(int*) arg3); |
| |
| |
| struct Goo |
| { |
| struct Foo(X) |
| { |
| X* v; |
| } |
| |
| struct Boo(X) |
| { |
| struct Xoo(Y) |
| { |
| Y* v; |
| }; |
| X* v; |
| } |
| |
| |
| void test6(Foo!(Boo!(Foo!(void))) arg1); |
| void test7(Boo!(void).Xoo!(int) arg1); |
| } |
| |
| struct P1 |
| { |
| struct Mem(T) |
| { |
| } |
| } |
| |
| struct P2 |
| { |
| struct Mem(T) |
| { |
| } |
| } |
| |
| void test8(P1.Mem!int, P2.Mem!int); |
| void test9(Foo!(int**), Foo!(int*), int**, int*); |
| |
| |
| interface Test10 |
| { |
| private final void test10(); |
| public final void test11(); |
| protected final void test12(); |
| public final void test13() const; |
| |
| private void test14(); |
| public void test15(); |
| protected void test16(); |
| |
| private static void test17(); |
| public static void test18(); |
| protected static void test19(); |
| }; |
| |
| Test10 Test10Ctor(); |
| void Test10Dtor(ref Test10 ptr); |
| |
| struct Test20 |
| { |
| __gshared: |
| private extern int test20; |
| protected extern int test21; |
| public extern int test22; |
| }; |
| |
| |
| int test23(Test10*, Test10, Test10**, const(Test10)); |
| int test23b(const Test10*, const Test10, Test10); |
| |
| void test24(int function(int,int)); |
| |
| void test25(int[291][6][5]* arr); |
| int test26(int[291][6]* arr); |
| |
| void test27(int, ...); |
| void test28(int); |
| |
| void test29(float); |
| void test30(const float); |
| |
| struct Array(T) |
| { |
| int dim; |
| } |
| |
| |
| interface Module |
| { |
| public static void imports(Module); |
| public static int dim(Array!Module*); |
| }; |
| |
| uint64_t testlongmangle(int a, uint b, int64_t c, uint64_t d); |
| cpp_ulong testCppLongMangle(cpp_long a, cpp_ulong b); |
| cpp_ulonglong testCppLongLongMangle(cpp_longlong a, cpp_ulonglong b); |
| |
| // direct size_t/ptrdiff_t interop is fine except on 32-bit OS X |
| version (OSX) { version (D_LP64) {} else version = OSX_32; } |
| version (OSX_32) |
| cpp_size_t testCppSizeTMangle(cpp_ptrdiff_t a, cpp_size_t b); |
| else |
| size_t testCppSizeTMangle(ptrdiff_t a, size_t b); |
| |
| __gshared extern int[2][2][2] test31; |
| __gshared extern int* test32; |
| |
| |
| alias int function(Expression , void* ) apply_fp_t; |
| |
| interface Expression |
| { |
| public final int apply(apply_fp_t fp, apply_fp_t fp2, void* param); |
| public final int getType(); |
| public static Expression create(int); |
| public static void dispose(ref Expression); |
| } |
| |
| //int test34(int[0][0]*); |
| version(CRuntime_Microsoft){} |
| else |
| { |
| int test35(real arg); |
| } |
| |
| const(char)* test36(const(char)*); |
| |
| final class Test37 |
| { |
| static Test37 create() |
| { |
| return new Test37; |
| } |
| |
| bool test() |
| { |
| return true; |
| } |
| } |
| |
| bool test37(); |
| |
| interface Test38 |
| { |
| final int test(int, ...); |
| public static Test38 create(); |
| public static void dispose(ref Test38); |
| } |
| |
| extern(C++) int test39cpp(C2!char, S2!(int)*); |
| |
| extern(C++, class) |
| struct S1 |
| { |
| private int val; |
| static S1* init(int); |
| int value(); |
| } |
| |
| extern(C++, class) |
| struct S2(T) |
| { |
| private T val; |
| static S2!T* init(int); |
| T value(); |
| } |
| |
| extern(C++, struct) |
| class C1 |
| { |
| const(char)* data; |
| |
| static C1 init(const(char)* p); |
| const(char)* getDataCPP(); |
| extern(C++) const(char)* getDataD() |
| { |
| return data; |
| } |
| } |
| |
| extern(C++, struct) |
| class C2(T) |
| { |
| const(T)* data; |
| |
| static C2!T init(const(T)* p); |
| const(T)* getData(); |
| } |
| |
| void test39() |
| { |
| S1* s1 = S1.init(42); |
| assert(s1.value == 42); |
| assert(S2!int.init(43).value == 43); |
| const(char)* ptr = "test".ptr; |
| C1 c1 = C1.init(ptr); |
| assert(c1.getDataCPP() == ptr); |
| assert(c1.getDataD() == ptr); |
| C2!char c2 = C2!char.init(ptr); |
| assert(c2.getData() == ptr); |
| auto result = test39cpp(c2, S2!int.init(43)); |
| assert(result == 0); |
| } |
| |
| extern(C++, "foo", "bar", "baz") int doStuff(int); |
| |
| version(CppRuntime_DigitalMars) // DMC doesn't support c++11 |
| { |
| void test40() {} |
| void test41() {} |
| } |
| else |
| { |
| void test40(); |
| |
| void foovargs(T...)(T args) |
| { |
| static if (is(T[0] == char*)) |
| { |
| assert(*args[0] == 'a'); |
| } |
| else |
| { |
| float ret = args[0] + args[1]; |
| assert(ret == 3.0f); |
| } |
| } |
| |
| alias FooVargs = foovargs!(int, float); |
| alias FooVargs2 = foovargs!(char*); |
| |
| void test41(); |
| void make_shared_poc(T, Args...)(ref Args args) |
| { |
| assert(args[0] + args[1] == 3); |
| } |
| alias Make_Shared_Poc = make_shared_poc!(int, int, int); |
| } |
| |
| void main() |
| { |
| test1(Foo!int()); |
| test2(null, Boo!(int*)()); |
| test3(Test3!(3,3)()); |
| test4(Foo!(int*)(), Boo!(int*)(), Boo!(int*)(), null, Foo!(double)()); |
| test5(Foo!(int*)(), Boo!(int*)(), Boo!(int*)()); |
| Goo goo; |
| goo.test6(Goo.Foo!(Goo.Boo!(Goo.Foo!(void)))()); |
| goo.test7(Goo.Boo!(void).Xoo!(int)()); |
| |
| test8(P1.Mem!int(), P2.Mem!int()); |
| test9(Foo!(int**)(), Foo!(int*)(), null, null); |
| |
| auto t10 = Test10Ctor(); |
| scope(exit) Test10Dtor(t10); |
| |
| t10.test10(); |
| t10.test11(); |
| t10.test12(); |
| t10.test13(); |
| t10.test14(); |
| t10.test15(); |
| t10.test16(); |
| t10.test17(); |
| t10.test18(); |
| t10.test19(); |
| |
| assert(Test20.test20 == 20); |
| assert(Test20.test21 == 21); |
| assert(Test20.test22 == 22); |
| |
| assert(test23(null, null, null, null) == 1); |
| assert(test23b(null, null, null) == 1); |
| |
| extern(C++) static int cb(int a, int b){return a+b;} |
| |
| test24(&cb); |
| int[291][6][5] arr; |
| arr[1][1][1] = 42; |
| test25(&arr); |
| assert(test26(&arr[0]) == 42); |
| |
| test27(3,4,5); |
| test28(3); |
| |
| test29(3.14f); |
| test30(3.14f); |
| |
| auto t32 = &Module.imports; |
| Array!Module arr2; |
| arr2.dim = 20; |
| assert(Module.dim(&arr2) == 20); |
| |
| assert(testlongmangle(1, 2, 3, 4) == 10); |
| assert(testCppLongMangle(1, 2) == 3); |
| assert(testCppLongLongMangle(3, 4) == 7); |
| assert(testCppSizeTMangle(3, 4) == 7); |
| assert(test31 == [[[1, 1], [1, 1]], [[1, 1], [1, 1]]]); |
| assert(test32 == null); |
| |
| auto ee = Expression.create(42); |
| extern(C++) static int efun(Expression e, void* p) |
| { |
| return cast(int)(cast(size_t)p ^ e.getType()); |
| } |
| |
| extern(C++) static int efun2(Expression e, void* p) |
| { |
| return cast(int)(cast(size_t)p * e.getType()); |
| } |
| |
| auto test33 = ee.apply(&efun, &efun2, cast(void*)&Expression.create); |
| assert(test33 == cast(int)(cast(size_t)cast(void*)&Expression.create ^ 42) * cast(int)(cast(size_t)cast(void*)&Expression.create * 42)); |
| Expression.dispose(ee); |
| assert(ee is null); |
| //assert(test34(null) == 0); |
| version(CRuntime_Microsoft){} |
| else |
| { |
| assert(test35(3.14L) == 3); |
| } |
| const char* hello = "hello"; |
| assert(test36(hello) == hello); |
| assert(test37()); |
| auto t38 = Test38.create(); |
| assert(t38.test(1, 2, 3) == 1); |
| Test38.dispose(t38); |
| test39(); |
| |
| assert(doStuff(2) == 4); |
| |
| test40(); |
| test41(); |
| } |