1 // EXTRA_FILES: cppmangle2.d
2 // Test C++ name mangling.
3 // https://issues.dlang.org/show_bug.cgi?id=4059
4 // https://issues.dlang.org/show_bug.cgi?id=5148
5 // https://issues.dlang.org/show_bug.cgi?id=7024
6 // https://issues.dlang.org/show_bug.cgi?id=10058
7 
8 import core.stdc.stdio;
9 
10 extern (C++) int foob(int i, int j, int k);
11 
12 class C
13 {
bar(int i,int j,int k)14     extern (C++) int bar(int i, int j, int k)
15     {
16         printf("this = %p\n", this);
17         printf("i = %d\n", i);
18         printf("j = %d\n", j);
19         printf("k = %d\n", k);
20         return 1;
21     }
22 }
23 
24 
25 extern (C++)
foo(int i,int j,int k)26 int foo(int i, int j, int k)
27 {
28     printf("i = %d\n", i);
29     printf("j = %d\n", j);
30     printf("k = %d\n", k);
31     assert(i == 1);
32     assert(j == 2);
33     assert(k == 3);
34     return 1;
35 }
36 
test1()37 void test1()
38 {
39     foo(1, 2, 3);
40 
41     auto i = foob(1, 2, 3);
42     assert(i == 7);
43 
44     C c = new C();
45     c.bar(4, 5, 6);
46 }
47 
version(Posix)48 version (Posix)
49 {
50     static assert(foo.mangleof == "_Z3fooiii");
51     static assert(foob.mangleof == "_Z4foobiii");
52     static assert(C.bar.mangleof == "_ZN1C3barEiii");
53 }
version(Win32)54 version (Win32)
55 {
56     static assert(foo.mangleof == "?foo@@YAHHHH@Z");
57     static assert(foob.mangleof == "?foob@@YAHHHH@Z");
58     static assert(C.bar.mangleof == "?bar@C@@UAEHHHH@Z");
59 }
version(Win64)60 version (Win64)
61 {
62     static assert(foo.mangleof == "?foo@@YAHHHH@Z");
63     static assert(foob.mangleof == "?foob@@YAHHHH@Z");
64     static assert(C.bar.mangleof == "?bar@C@@UEAAHHHH@Z");
65 }
66 
67 /****************************************/
68 
69 extern (C++)
70 interface D
71 {
72     int bar(int i, int j, int k);
73 }
74 
75 extern (C++) D getD();
76 
test2()77 void test2()
78 {
79     D d = getD();
80     int i = d.bar(9,10,11);
81     assert(i == 8);
82 }
83 
version(Posix)84 version (Posix)
85 {
86     static assert (getD.mangleof == "_Z4getDv");
87     static assert (D.bar.mangleof == "_ZN1D3barEiii");
88 }
89 
90 /****************************************/
91 
92 extern (C++) int callE(E);
93 
94 extern (C++)
95 interface E
96 {
97     int bar(int i, int j, int k);
98 }
99 
100 class F : E
101 {
bar(int i,int j,int k)102     extern (C++) int bar(int i, int j, int k)
103     {
104         printf("F.bar: i = %d\n", i);
105         printf("F.bar: j = %d\n", j);
106         printf("F.bar: k = %d\n", k);
107         assert(i == 11);
108         assert(j == 12);
109         assert(k == 13);
110         return 8;
111     }
112 }
113 
test3()114 void test3()
115 {
116     F f = new F();
117     int i = callE(f);
118     assert(i == 8);
119 }
120 
version(Posix)121 version (Posix)
122 {
123     static assert (callE.mangleof == "_Z5callEP1E");
124     static assert (E.bar.mangleof == "_ZN1E3barEiii");
125     static assert (F.bar.mangleof == "_ZN1F3barEiii");
126 }
127 
128 /****************************************/
129 
130 extern (C++) void foo4(char* p);
131 
test4()132 void test4()
133 {
134     foo4(null);
135 }
136 
version(Posix)137 version (Posix)
138 {
139     static assert(foo4.mangleof == "_Z4foo4Pc");
140 }
141 
142 /****************************************/
143 
144 extern(C++)
145 {
146   struct foo5 { int i; int j; void* p; }
147 
148   interface bar5{
149     foo5 getFoo(int i);
150   }
151 
152   bar5 newBar();
153 }
154 
test5()155 void test5()
156 {
157   bar5 b = newBar();
158   foo5 f = b.getFoo(4);
159   printf("f.p = %p, b = %p\n", f.p, cast(void*)b);
160   assert(f.p == cast(void*)b);
161 }
162 
version(Posix)163 version (Posix)
164 {
165     static assert(bar5.getFoo.mangleof == "_ZN4bar56getFooEi");
166     static assert (newBar.mangleof == "_Z6newBarv");
167 }
168 
169 /****************************************/
170 
171 extern(C++)
172 {
173     struct S6
174     {
175         int i;
176         double d;
177     }
178     S6 foo6();
179 }
180 
181 extern (C) int foosize6();
182 
test6()183 void test6()
184 {
185     S6 f = foo6();
186     printf("%d %d\n", foosize6(), cast(int)S6.sizeof);
187     assert(foosize6() == S6.sizeof);
188     assert(f.i == 42);
189     printf("f.d = %g\n", f.d);
190     assert(f.d == 2.5);
191 }
192 
version(Posix)193 version (Posix)
194 {
195     static assert (foo6.mangleof == "_Z4foo6v");
196 }
197 
198 /****************************************/
199 
200 extern (C) int foo7();
201 
202 struct S
203 {
204     int i;
205     long l;
206 }
207 
test7()208 void test7()
209 {
210     printf("%d %d\n", foo7(), cast(int)S.sizeof);
211     assert(foo7() == S.sizeof);
212 }
213 
214 /****************************************/
215 
216 extern (C++) void foo8(const char *);
217 
test8()218 void test8()
219 {
220     char c;
221     foo8(&c);
222 }
223 
version(Posix)224 version (Posix)
225 {
226     static assert(foo8.mangleof == "_Z4foo8PKc");
227 }
228 
229 /****************************************/
230 // https://issues.dlang.org/show_bug.cgi?id=4059
231 
232 struct elem9 { }
233 
234 extern(C++) void foobar9(elem9*, elem9*);
235 
test9()236 void test9()
237 {
238     elem9 *a;
239     foobar9(a, a);
240 }
241 
version(Posix)242 version (Posix)
243 {
244     static assert(foobar9.mangleof == "_Z7foobar9P5elem9S0_");
245 }
246 
247 /****************************************/
248 // https://issues.dlang.org/show_bug.cgi?id=5148
249 
250 extern (C++)
251 {
252     void foo10(const char*, const char*);
253     void foo10(const int, const int);
254     void foo10(const char, const char);
255 
256     struct MyStructType { }
257     void foo10(const MyStructType s, const MyStructType t);
258 
259     enum MyEnumType { onemember }
260     void foo10(const MyEnumType s, const MyEnumType t);
261 }
262 
test10()263 void test10()
264 {
265     char* p;
266     foo10(p, p);
267     foo10(1,2);
268     foo10('c','d');
269     MyStructType s;
270     foo10(s,s);
271     MyEnumType e;
272     foo10(e,e);
273 }
274 
275 // https://issues.dlang.org/show_bug.cgi?id=19504
276 extern(C++) struct Class19504 {
277     pragma(mangle, "HOHOHO")
278     ~this();
279 }
280 static assert(Class19504.__xdtor.mangleof == "HOHOHO");
281 
282 /**************************************/
283 // https://issues.dlang.org/show_bug.cgi?id=10058
284 
285 extern (C++)
286 {
test10058a(void *)287     void test10058a(void*) { }
test10058b(void function (void *))288     void test10058b(void function(void*)) { }
test10058c(void * function (void *))289     void test10058c(void* function(void*)) { }
test10058d(void function (void *),void *)290     void test10058d(void function(void*), void*) { }
test10058e(void * function (void *),void *)291     void test10058e(void* function(void*), void*) { }
test10058f(void * function (void *),void * function (void *))292     void test10058f(void* function(void*), void* function(void*)) { }
test10058g(void function (void *),void *,void *)293     void test10058g(void function(void*), void*, void*) { }
test10058h(void * function (void *),void *,void *)294     void test10058h(void* function(void*), void*, void*) { }
test10058i(void * function (void *),void * function (void *),void *)295     void test10058i(void* function(void*), void* function(void*), void*) { }
test10058j(void * function (void *),void * function (void *),void * function (void *))296     void test10058j(void* function(void*), void* function(void*), void* function(void*)) { }
test10058k(void * function (void *),void * function (const (void)*))297     void test10058k(void* function(void*), void* function(const (void)*)) { }
test10058l(void * function (void *),void * function (const (void)*),const (void)* function (void *))298     void test10058l(void* function(void*), void* function(const (void)*), const(void)* function(void*)) { }
299 }
300 
version(Posix)301 version (Posix)
302 {
303     static assert(test10058a.mangleof == "_Z10test10058aPv");
304     static assert(test10058b.mangleof == "_Z10test10058bPFvPvE");
305     static assert(test10058c.mangleof == "_Z10test10058cPFPvS_E");
306     static assert(test10058d.mangleof == "_Z10test10058dPFvPvES_");
307     static assert(test10058e.mangleof == "_Z10test10058ePFPvS_ES_");
308     static assert(test10058f.mangleof == "_Z10test10058fPFPvS_ES1_");
309     static assert(test10058g.mangleof == "_Z10test10058gPFvPvES_S_");
310     static assert(test10058h.mangleof == "_Z10test10058hPFPvS_ES_S_");
311     static assert(test10058i.mangleof == "_Z10test10058iPFPvS_ES1_S_");
312     static assert(test10058j.mangleof == "_Z10test10058jPFPvS_ES1_S1_");
313     static assert(test10058k.mangleof == "_Z10test10058kPFPvS_EPFS_PKvE");
314     static assert(test10058l.mangleof == "_Z10test10058lPFPvS_EPFS_PKvEPFS3_S_E");
315 }
316 
317 /**************************************/
318 // https://issues.dlang.org/show_bug.cgi?id=11696
319 
320 class Expression;
321 struct Loc {}
322 
323 extern(C++)
324 class CallExp
325 {
326     static void test11696a(Loc, Expression, Expression);
327     static void test11696b(Loc, Expression, Expression*);
328     static void test11696c(Loc, Expression*, Expression);
329     static void test11696d(Loc, Expression*, Expression*);
330 }
331 
version(Posix)332 version (Posix)
333 {
334     static assert(CallExp.test11696a.mangleof == "_ZN7CallExp10test11696aE3LocP10ExpressionS2_");
335     static assert(CallExp.test11696b.mangleof == "_ZN7CallExp10test11696bE3LocP10ExpressionPS2_");
336     static assert(CallExp.test11696c.mangleof == "_ZN7CallExp10test11696cE3LocPP10ExpressionS2_");
337     static assert(CallExp.test11696d.mangleof == "_ZN7CallExp10test11696dE3LocPP10ExpressionS3_");
338 }
339 
340 /**************************************/
341 // https://issues.dlang.org/show_bug.cgi?id=13337
342 
343 extern(C++, N13337a.N13337b.N13337c)
344 {
345   struct S13337{}
346   void foo13337(S13337 s);
347 }
348 
349 extern(C++, `N13337a`, `N13337b`, `N13337c`)
350 {
351     struct S13337_2{}
352     void foo13337_2(S13337 s);
353     void foo13337_3(S13337_2 s);
354 }
355 
version(Posix)356 version (Posix)
357 {
358     static assert(foo13337.mangleof == "_ZN7N13337a7N13337b7N13337c8foo13337ENS1_6S13337E");
359     static assert(foo13337_2.mangleof == "_ZN7N13337a7N13337b7N13337c10foo13337_2ENS1_6S13337E");
360     static assert(foo13337_3.mangleof == "_ZN7N13337a7N13337b7N13337c10foo13337_3ENS1_8S13337_2E");
361 }
362 
363 /**************************************/
364 // https://issues.dlang.org/show_bug.cgi?id=15789
365 
366 extern (C++) void test15789a(T...)(T args);
367 
test15789()368 void test15789()
369 {
370     test15789a(0);
371 }
372 
373 /**************************************/
374 // https://issues.dlang.org/show_bug.cgi?id=7030
375 
376 extern(C++)
377 {
378     struct Struct7030
379     {
380         void foo(int) const;
381         void bar(int);
382         static __gshared int boo;
383     }
384 }
385 
386 version (Posix)
387 {
388     static assert(Struct7030.foo.mangleof == "_ZNK10Struct70303fooEi");
389     static assert(Struct7030.bar.mangleof == "_ZN10Struct70303barEi");
390     static assert(Struct7030.boo.mangleof == "_ZN10Struct70303booE");
391 }
392 
393 /****************************************/
394 
395 // Special cases of Itanium mangling
396 
397 extern (C++, std)
398 {
399     struct pair(T1, T2)
400     {
401         void swap(ref pair other);
402     }
403 
404     struct allocator(T)
405     {
406         uint fooa() const;
407         uint foob();
408     }
409 
410     struct basic_string(T1, T2, T3)
411     {
412         uint fooa();
413     }
414 
415     struct basic_istream(T1, T2)
416     {
417         uint fooc();
418     }
419 
420     struct basic_ostream(T1, T2)
421     {
422         uint food();
423     }
424 
425     struct basic_iostream(T1, T2)
426     {
427         uint fooe();
428     }
429 
430     struct char_traits(T)
431     {
432         uint foof();
433     }
434 
435     struct vector (T);
436 
437     struct test18957 {}
438 }
439 
440 extern (C++, `std`)
441 {
442     struct pair(T1, T2)
443     {
444         void swap(ref pair other);
445     }
446 
447     struct allocator(T)
448     {
449         uint fooa() const;
450         uint foob();
451     }
452 
453     struct basic_string(T1, T2, T3)
454     {
455         uint fooa();
456     }
457 
458     struct basic_istream(T1, T2)
459     {
460         uint fooc();
461     }
462 
463     struct basic_ostream(T1, T2)
464     {
465         uint food();
466     }
467 
468     struct basic_iostream(T1, T2)
469     {
470         uint fooe();
471     }
472 
473     struct char_traits(T)
474     {
475         uint foof();
476     }
477 
478     struct vector (T);
479 
480     struct Struct18957 {}
481 }
482 
483 extern(C++)
484 {
485     // Nspace
486     std.allocator!int func_18957_1(std.allocator!(int)* v);
487     // CPPNamespaceAttribute
488     allocator!int func_18957_2(allocator!(int)* v);
489     X func_18957_2(X)(X* v);
490 }
491 
492 extern (C++)
493 {
494     void func_20413(pair!(int, float), pair!(float, int));
495 }
496 
497 version (Posix)
498 {
499     // https://issues.dlang.org/show_bug.cgi?id=17947
500     static assert(std.pair!(void*, void*).swap.mangleof == "_ZNSt4pairIPvS0_E4swapERS1_");
501     static assert(std.allocator!int.fooa.mangleof == "_ZNKSaIiE4fooaEv");
502     static assert(std.allocator!int.foob.mangleof == "_ZNSaIiE4foobEv");
503     static assert(std.basic_string!(char,int,uint).fooa.mangleof == "_ZNSbIcijE4fooaEv");
504     static assert(std.basic_string!(char, std.char_traits!char, std.allocator!char).fooa.mangleof == "_ZNSs4fooaEv");
505     static assert(std.basic_istream!(char, std.char_traits!char).fooc.mangleof == "_ZNSi4foocEv");
506     static assert(std.basic_ostream!(char, std.char_traits!char).food.mangleof == "_ZNSo4foodEv");
507     static assert(std.basic_iostream!(char, std.char_traits!char).fooe.mangleof == "_ZNSd4fooeEv");
508 
509     static assert(func_18957_1.mangleof == `_Z12func_18957_1PSaIiE`);
510     static assert(func_18957_2!(std.allocator!int).mangleof == `_Z12func_18957_2ISaIiEET_PS1_`);
511 
512 
513     static assert(pair!(void*, void*).swap.mangleof == "_ZNSt4pairIPvS0_E4swapERS1_");
514     static assert(allocator!int.fooa.mangleof == "_ZNKSaIiE4fooaEv");
515     static assert(allocator!int.foob.mangleof == "_ZNSaIiE4foobEv");
516     static assert(basic_string!(char,int,uint).fooa.mangleof == "_ZNSbIcijE4fooaEv");
517     static assert(basic_string!(char, char_traits!char, allocator!char).fooa.mangleof == "_ZNSs4fooaEv");
518     static assert(basic_istream!(char, char_traits!char).fooc.mangleof == "_ZNSi4foocEv");
519     static assert(basic_ostream!(char, char_traits!char).food.mangleof == "_ZNSo4foodEv");
520     static assert(basic_iostream!(char, char_traits!char).fooe.mangleof == "_ZNSd4fooeEv");
521 
522     static assert(func_18957_2.mangleof == `_Z12func_18957_2PSaIiE`);
523     static assert(func_18957_2!(allocator!int).mangleof == `_Z12func_18957_2ISaIiEET_PS1_`);
524 
525     static assert(func_20413.mangleof == `_Z10func_20413St4pairIifES_IfiE`);
526 }
527 
528 /**************************************/
529 
530 alias T36 = int ********** ********** ********** **********;
531 
532 extern (C++) void test36(T36, T36*) { }
533 
534 version (Posix)
535 {
536     static assert(test36.mangleof == "_Z6test36PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPiPS12_");
537 }
538 
539 /*****************************************/
540 // https://issues.dlang.org/show_bug.cgi?id=17772
541 
542 extern(C++, SPACE)
543 int test37(T)(){ return 0;}
544 
545 extern(C++, `SPACE`)
546 int test37(T)(){ return 0;}
547 
548 version (Posix) // all non-Windows machines
549 {
550     static assert(SPACE.test37!int.mangleof == "_ZN5SPACE6test37IiEEiv");
551     static assert(test37!int.mangleof == "_ZN5SPACE6test37IiEEiv");
552 }
553 
554 /**************************************/
555 // https://issues.dlang.org/show_bug.cgi?id=15388
556 
557 extern (C++) void test15388(typeof(null));
558 
559 version (Posix)
560 {
561     static assert(test15388.mangleof == "_Z9test15388Dn");
562 }
563 version (Windows)
564 {
565     static assert(test15388.mangleof == "?test15388@@YAX$$T@Z");
566 }
567 
568 /**************************************/
569 // https://issues.dlang.org/show_bug.cgi?id=14086
570 
571 extern (C++) class Test14086
572 {
573     this();
574     ~this();
575 }
576 extern (C++) class Test14086_2
577 {
578     final ~this();
579 }
580 extern (C++) struct Test14086_S
581 {
582     this(int);
583     ~this();
584 }
585 
586 version(Posix)
587 {
588     static assert(Test14086.__ctor.mangleof == "_ZN9Test14086C1Ev");
589     static assert(Test14086.__dtor.mangleof == "_ZN9Test14086D1Ev");
590     static assert(Test14086_2.__dtor.mangleof == "_ZN11Test14086_2D1Ev");
591     static assert(Test14086_S.__ctor.mangleof == "_ZN11Test14086_SC1Ei");
592     static assert(Test14086_S.__dtor.mangleof == "_ZN11Test14086_SD1Ev");
593 }
594 version(Win32)
595 {
596     static assert(Test14086.__ctor.mangleof == "??0Test14086@@QAE@XZ");
597     static assert(Test14086.__dtor.mangleof == "??1Test14086@@UAE@XZ");
598     static assert(Test14086_2.__dtor.mangleof == "??1Test14086_2@@QAE@XZ");
599     static assert(Test14086_S.__ctor.mangleof == "??0Test14086_S@@QAE@H@Z");
600     static assert(Test14086_S.__dtor.mangleof == "??1Test14086_S@@QAE@XZ");
601 }
602 version(Win64)
603 {
604     static assert(Test14086.__ctor.mangleof == "??0Test14086@@QEAA@XZ");
605     static assert(Test14086.__dtor.mangleof == "??1Test14086@@UEAA@XZ");
606     static assert(Test14086_2.__dtor.mangleof == "??1Test14086_2@@QEAA@XZ");
607     static assert(Test14086_S.__ctor.mangleof == "??0Test14086_S@@QEAA@H@Z");
608     static assert(Test14086_S.__dtor.mangleof == "??1Test14086_S@@QEAA@XZ");
609 }
610 
611 /**************************************/
612 // https://issues.dlang.org/show_bug.cgi?id=18888
613 
614 extern (C++)
615 struct T18888(T)
616 {
617     void fun();
618 }
619 
620 extern (C++)
621 struct S18888(alias arg = T18888)
622 {
623     alias I = T18888!(arg!int);
624 }
625 
626 version(Posix)
627 {
628     static assert(S18888!().I.fun.mangleof == "_ZN6T18888IS_IiEE3funEv");
629 }
630 version(Win32)
631 {
632     static assert(S18888!().I.fun.mangleof == "?fun@?$T18888@U?$T18888@H@@@@QAEXXZ");
633 }
634 version(Win64)
635 {
636     static assert(S18888!().I.fun.mangleof == "?fun@?$T18888@U?$T18888@H@@@@QEAAXXZ");
637 }
638 
639 /**************************************/
640 // https://issues.dlang.org/show_bug.cgi?id=18890
641 
642 extern (C++) class C18890
643 {
644     ~this() {}
645 }
646 extern (C++) class C18890_2
647 {
648     ~this() {}
649     extern (C++) struct Agg
650     {
651         ~this() {}
652     }
653     Agg s;
654 }
655 
656 version (Posix)
657 {
658     static assert(C18890.__dtor.mangleof == "_ZN6C18890D1Ev");
659     static assert(C18890.__xdtor.mangleof == "_ZN6C18890D1Ev");
660     static assert(C18890_2.__dtor.mangleof == "_ZN8C18890_26__dtorEv");
661     static assert(C18890_2.__xdtor.mangleof == "_ZN8C18890_2D1Ev");
662 }
663 version (Win32)
664 {
665     static assert(C18890.__dtor.mangleof == "??1C18890@@UAE@XZ");
666     static assert(C18890.__xdtor.mangleof == "??_GC18890@@UAEPAXI@Z");
667     static assert(C18890_2.__dtor.mangleof == "?__dtor@C18890_2@@UAEXXZ");
668     static assert(C18890_2.__xdtor.mangleof == "??_GC18890_2@@UAEPAXI@Z");
669 }
670 version (Win64)
671 {
672     static assert(C18890.__dtor.mangleof == "??1C18890@@UEAA@XZ");
673     static assert(C18890.__xdtor.mangleof == "??_GC18890@@UEAAPEAXI@Z");
674     static assert(C18890_2.__dtor.mangleof == "?__dtor@C18890_2@@UEAAXXZ");
675     static assert(C18890_2.__xdtor.mangleof == "??_GC18890_2@@UEAAPEAXI@Z");
676 }
677 
678 /**************************************/
679 // https://issues.dlang.org/show_bug.cgi?id=18891
680 
681 extern (C++) class C18891
682 {
683     ~this();
684     extern (C++) struct Agg
685     {
686         ~this() {}
687     }
688     Agg s;
689 }
690 
691 version (Posix)
692 {
693     static assert(C18891.__dtor.mangleof == "_ZN6C18891D1Ev");
694     static assert(C18891.__xdtor.mangleof == "_ZN6C18891D1Ev");
695 }
696 version (Win32)
697 {
698     static assert(C18891.__dtor.mangleof == "??1C18891@@UAE@XZ");
699     static assert(C18891.__xdtor.mangleof == "??_GC18891@@UAEPAXI@Z");
700 }
701 version (Win64)
702 {
703     static assert(C18891.__dtor.mangleof == "??1C18891@@UEAA@XZ");
704     static assert(C18891.__xdtor.mangleof == "??_GC18891@@UEAAPEAXI@Z");
705 }
706 
707 /**************************************/
708 // Test C++ operator mangling
709 
710 extern (C++) struct TestOperators
711 {
712     int opCast(T)();
713     int opBinary(string op)(int x);
714     int opUnary(string op)();
715     int opOpAssign(string op)(int x);
716     int opIndex(int x);
717     bool opEquals(int x);
718     int opCall(int, float);
719     int opAssign(int);
720 }
721 
722 version (Posix)
723 {
724     static assert(TestOperators.opUnary!"*".mangleof     == "_ZN13TestOperatorsdeEv");
725     static assert(TestOperators.opUnary!"++".mangleof    == "_ZN13TestOperatorsppEv");
726     static assert(TestOperators.opUnary!"--".mangleof    == "_ZN13TestOperatorsmmEv");
727     static assert(TestOperators.opUnary!"-".mangleof     == "_ZN13TestOperatorsngEv");
728     static assert(TestOperators.opUnary!"+".mangleof     == "_ZN13TestOperatorspsEv");
729     static assert(TestOperators.opUnary!"~".mangleof     == "_ZN13TestOperatorscoEv");
730     static assert(TestOperators.opBinary!">>".mangleof   == "_ZN13TestOperatorsrsEi");
731     static assert(TestOperators.opBinary!"<<".mangleof   == "_ZN13TestOperatorslsEi");
732     static assert(TestOperators.opBinary!"*".mangleof    == "_ZN13TestOperatorsmlEi");
733     static assert(TestOperators.opBinary!"-".mangleof    == "_ZN13TestOperatorsmiEi");
734     static assert(TestOperators.opBinary!"+".mangleof    == "_ZN13TestOperatorsplEi");
735     static assert(TestOperators.opBinary!"&".mangleof    == "_ZN13TestOperatorsanEi");
736     static assert(TestOperators.opBinary!"/".mangleof    == "_ZN13TestOperatorsdvEi");
737     static assert(TestOperators.opBinary!"%".mangleof    == "_ZN13TestOperatorsrmEi");
738     static assert(TestOperators.opBinary!"^".mangleof    == "_ZN13TestOperatorseoEi");
739     static assert(TestOperators.opBinary!"|".mangleof    == "_ZN13TestOperatorsorEi");
740     static assert(TestOperators.opOpAssign!"*".mangleof  == "_ZN13TestOperatorsmLEi");
741     static assert(TestOperators.opOpAssign!"+".mangleof  == "_ZN13TestOperatorspLEi");
742     static assert(TestOperators.opOpAssign!"-".mangleof  == "_ZN13TestOperatorsmIEi");
743     static assert(TestOperators.opOpAssign!"/".mangleof  == "_ZN13TestOperatorsdVEi");
744     static assert(TestOperators.opOpAssign!"%".mangleof  == "_ZN13TestOperatorsrMEi");
745     static assert(TestOperators.opOpAssign!">>".mangleof == "_ZN13TestOperatorsrSEi");
746     static assert(TestOperators.opOpAssign!"<<".mangleof == "_ZN13TestOperatorslSEi");
747     static assert(TestOperators.opOpAssign!"&".mangleof  == "_ZN13TestOperatorsaNEi");
748     static assert(TestOperators.opOpAssign!"|".mangleof  == "_ZN13TestOperatorsoREi");
749     static assert(TestOperators.opOpAssign!"^".mangleof  == "_ZN13TestOperatorseOEi");
750     static assert(TestOperators.opCast!int.mangleof      == "_ZN13TestOperatorscviEv");
751     static assert(TestOperators.opAssign.mangleof        == "_ZN13TestOperatorsaSEi");
752     static assert(TestOperators.opEquals.mangleof        == "_ZN13TestOperatorseqEi");
753     static assert(TestOperators.opIndex.mangleof         == "_ZN13TestOperatorsixEi");
754     static assert(TestOperators.opCall.mangleof          == "_ZN13TestOperatorsclEif");
755 }
756 version (Win32)
757 {
758     static assert(TestOperators.opUnary!"*".mangleof     == "??DTestOperators@@QAEHXZ");
759     static assert(TestOperators.opUnary!"++".mangleof    == "??ETestOperators@@QAEHXZ");
760     static assert(TestOperators.opUnary!"--".mangleof    == "??FTestOperators@@QAEHXZ");
761     static assert(TestOperators.opUnary!"-".mangleof     == "??GTestOperators@@QAEHXZ");
762     static assert(TestOperators.opUnary!"+".mangleof     == "??HTestOperators@@QAEHXZ");
763     static assert(TestOperators.opUnary!"~".mangleof     == "??STestOperators@@QAEHXZ");
764     static assert(TestOperators.opBinary!">>".mangleof   == "??5TestOperators@@QAEHH@Z");
765     static assert(TestOperators.opBinary!"<<".mangleof   == "??6TestOperators@@QAEHH@Z");
766     static assert(TestOperators.opBinary!"*".mangleof    == "??DTestOperators@@QAEHH@Z");
767     static assert(TestOperators.opBinary!"-".mangleof    == "??GTestOperators@@QAEHH@Z");
768     static assert(TestOperators.opBinary!"+".mangleof    == "??HTestOperators@@QAEHH@Z");
769     static assert(TestOperators.opBinary!"&".mangleof    == "??ITestOperators@@QAEHH@Z");
770     static assert(TestOperators.opBinary!"/".mangleof    == "??KTestOperators@@QAEHH@Z");
771     static assert(TestOperators.opBinary!"%".mangleof    == "??LTestOperators@@QAEHH@Z");
772     static assert(TestOperators.opBinary!"^".mangleof    == "??TTestOperators@@QAEHH@Z");
773     static assert(TestOperators.opBinary!"|".mangleof    == "??UTestOperators@@QAEHH@Z");
774     static assert(TestOperators.opOpAssign!"*".mangleof  == "??XTestOperators@@QAEHH@Z");
775     static assert(TestOperators.opOpAssign!"+".mangleof  == "??YTestOperators@@QAEHH@Z");
776     static assert(TestOperators.opOpAssign!"-".mangleof  == "??ZTestOperators@@QAEHH@Z");
777     static assert(TestOperators.opOpAssign!"/".mangleof  == "??_0TestOperators@@QAEHH@Z");
778     static assert(TestOperators.opOpAssign!"%".mangleof  == "??_1TestOperators@@QAEHH@Z");
779     static assert(TestOperators.opOpAssign!">>".mangleof == "??_2TestOperators@@QAEHH@Z");
780     static assert(TestOperators.opOpAssign!"<<".mangleof == "??_3TestOperators@@QAEHH@Z");
781     static assert(TestOperators.opOpAssign!"&".mangleof  == "??_4TestOperators@@QAEHH@Z");
782     static assert(TestOperators.opOpAssign!"|".mangleof  == "??_5TestOperators@@QAEHH@Z");
783     static assert(TestOperators.opOpAssign!"^".mangleof  == "??_6TestOperators@@QAEHH@Z");
784     static assert(TestOperators.opCast!int.mangleof      == "??BTestOperators@@QAEHXZ");
785     static assert(TestOperators.opAssign.mangleof        == "??4TestOperators@@QAEHH@Z");
786     static assert(TestOperators.opEquals.mangleof        == "??8TestOperators@@QAE_NH@Z");
787     static assert(TestOperators.opIndex.mangleof         == "??ATestOperators@@QAEHH@Z");
788     static assert(TestOperators.opCall.mangleof          == "??RTestOperators@@QAEHHM@Z");
789 }
790 version (Win64)
791 {
792     static assert(TestOperators.opUnary!"*".mangleof     == "??DTestOperators@@QEAAHXZ");
793     static assert(TestOperators.opUnary!"++".mangleof    == "??ETestOperators@@QEAAHXZ");
794     static assert(TestOperators.opUnary!"--".mangleof    == "??FTestOperators@@QEAAHXZ");
795     static assert(TestOperators.opUnary!"-".mangleof     == "??GTestOperators@@QEAAHXZ");
796     static assert(TestOperators.opUnary!"+".mangleof     == "??HTestOperators@@QEAAHXZ");
797     static assert(TestOperators.opUnary!"~".mangleof     == "??STestOperators@@QEAAHXZ");
798     static assert(TestOperators.opBinary!">>".mangleof   == "??5TestOperators@@QEAAHH@Z");
799     static assert(TestOperators.opBinary!"<<".mangleof   == "??6TestOperators@@QEAAHH@Z");
800     static assert(TestOperators.opBinary!"*".mangleof    == "??DTestOperators@@QEAAHH@Z");
801     static assert(TestOperators.opBinary!"-".mangleof    == "??GTestOperators@@QEAAHH@Z");
802     static assert(TestOperators.opBinary!"+".mangleof    == "??HTestOperators@@QEAAHH@Z");
803     static assert(TestOperators.opBinary!"&".mangleof    == "??ITestOperators@@QEAAHH@Z");
804     static assert(TestOperators.opBinary!"/".mangleof    == "??KTestOperators@@QEAAHH@Z");
805     static assert(TestOperators.opBinary!"%".mangleof    == "??LTestOperators@@QEAAHH@Z");
806     static assert(TestOperators.opBinary!"^".mangleof    == "??TTestOperators@@QEAAHH@Z");
807     static assert(TestOperators.opBinary!"|".mangleof    == "??UTestOperators@@QEAAHH@Z");
808     static assert(TestOperators.opOpAssign!"*".mangleof  == "??XTestOperators@@QEAAHH@Z");
809     static assert(TestOperators.opOpAssign!"+".mangleof  == "??YTestOperators@@QEAAHH@Z");
810     static assert(TestOperators.opOpAssign!"-".mangleof  == "??ZTestOperators@@QEAAHH@Z");
811     static assert(TestOperators.opOpAssign!"/".mangleof  == "??_0TestOperators@@QEAAHH@Z");
812     static assert(TestOperators.opOpAssign!"%".mangleof  == "??_1TestOperators@@QEAAHH@Z");
813     static assert(TestOperators.opOpAssign!">>".mangleof == "??_2TestOperators@@QEAAHH@Z");
814     static assert(TestOperators.opOpAssign!"<<".mangleof == "??_3TestOperators@@QEAAHH@Z");
815     static assert(TestOperators.opOpAssign!"&".mangleof  == "??_4TestOperators@@QEAAHH@Z");
816     static assert(TestOperators.opOpAssign!"|".mangleof  == "??_5TestOperators@@QEAAHH@Z");
817     static assert(TestOperators.opOpAssign!"^".mangleof  == "??_6TestOperators@@QEAAHH@Z");
818     static assert(TestOperators.opCast!int.mangleof      == "??BTestOperators@@QEAAHXZ");
819     static assert(TestOperators.opAssign.mangleof        == "??4TestOperators@@QEAAHH@Z");
820     static assert(TestOperators.opEquals.mangleof        == "??8TestOperators@@QEAA_NH@Z");
821     static assert(TestOperators.opIndex.mangleof         == "??ATestOperators@@QEAAHH@Z");
822     static assert(TestOperators.opCall.mangleof          == "??RTestOperators@@QEAAHHM@Z");
823 }
824 
825 import cppmangle2;
826 extern(C++, Namespace18922)
827 {
828     // Nspace
829     void func18922(cppmangle2.Namespace18922.Struct18922) {}
830     // CPPNamespaceAttribute
831     void func18922_1(Struct18922) {}
832 }
833 
834 extern(C++, `Namespace18922`)
835 {
836     // Nspace
837     void func18922_2(cppmangle2.Namespace18922.Struct18922) {}
838     // CPPNamespaceAttribute
839     void func18922_3(Struct18922) {}
840 }
841 
842 version (Posix)
843 {
844     static assert(func18922.mangleof == "_ZN14Namespace189229func18922ENS_11Struct18922E");
845     static assert(func18922_1.mangleof == "_ZN14Namespace1892211func18922_1ENS_11Struct18922E");
846     static assert(func18922_2.mangleof == "_ZN14Namespace1892211func18922_2ENS_11Struct18922E");
847     static assert(func18922_3.mangleof == "_ZN14Namespace1892211func18922_3ENS_11Struct18922E");
848 }
849 else version(Windows)
850 {
851     static assert(func18922.mangleof == "?func18922@Namespace18922@@YAXUStruct18922@1@@Z");
852     static assert(func18922_1.mangleof == "?func18922_1@Namespace18922@@YAXUStruct18922@1@@Z");
853     static assert(func18922_2.mangleof == "?func18922_2@Namespace18922@@YAXUStruct18922@1@@Z");
854     static assert(func18922_3.mangleof == "?func18922_3@Namespace18922@@YAXUStruct18922@1@@Z");
855 }
856 
857 /**************************************/
858 // https://issues.dlang.org/show_bug.cgi?id=18957
859 // extern(C++) doesn't mangle 'std' correctly on posix systems
860 
861 version (Posix)
862 {
863     // https://godbolt.org/z/C5T2LQ
864     /+
865     namespace std
866     {
867     struct test18957 {};
868     }
869     void test18957(const std::test18957& t) {}
870     +/
871     extern (C++) void test18957(ref const(Struct18957) t) {}
872 
873     static assert(test18957.mangleof == "_Z9test18957RKSt11Struct18957");
874 }
875 
876 /**************************************/
877 // https://issues.dlang.org/show_bug.cgi?id=19043
878 // Incorrect mangling for extern(C++) const template parameter on windows
879 
880 extern(C++) struct test19043(T) {}
881 
882 extern(C++) void test19043a(test19043!(const(char)) a) {}
883 extern(C++) void test19043b(T)(T a) {}
884 version(Windows)
885 {
886     static assert(test19043a.mangleof == "?test19043a@@YAXU?$test19043@$$CBD@@@Z");
887     static assert(test19043b!(test19043!(const(char))).mangleof ==
888       "??$test19043b@U?$test19043@$$CBD@@@@YAXU?$test19043@$$CBD@@@Z");
889 }
890 
891 // https://issues.dlang.org/show_bug.cgi?id=16479
892 //  Missing substitution while mangling C++ template parameter for functions
893 version (Posix) extern (C++)
894 {
895     // Make sure aliases are still resolved
896     alias Alias16479 = int;
897     Alias16479 func16479_0 (FuncT1) (FuncT1, Alias16479);
898     static assert(func16479_0!(int).mangleof == `_Z11func16479_0IiEiT_i`);
899 
900     // Simple substitution on return type
901     FuncT1* func16479_1 (FuncT1) ();
902     static assert(func16479_1!(int).mangleof == `_Z11func16479_1IiEPT_v`);
903 
904     // Simple substitution on parameter
905     void    func16479_2 (FuncT1) (FuncT1);
906     static assert(func16479_2!(int).mangleof == `_Z11func16479_2IiEvT_`);
907 
908     // Make sure component substition is prefered over template parameter
909     FuncT1* func16479_3 (FuncT1) (FuncT1);
910     static assert(func16479_3!(int).mangleof == `_Z11func16479_3IiEPT_S0_`);
911 
912     struct Array16479 (Arg) { Arg* data; }
913     struct Array16479_2 (Arg, int Size) { Arg[Size] data; }
914     struct Value16479 (int Value1, int Value2) { int data; }
915 
916     // Make sure template parameter substitution happens on templated return
917     Array16479!(FuncT2) func16479_4 (FuncT1, FuncT2) (FuncT1);
918     static assert(func16479_4!(int, float).mangleof
919                   == `_Z11func16479_4IifE10Array16479IT0_ET_`);
920 
921     // Make sure template parameter substitution happens with values
922     Value16479!(Value2, Value1)* func16479_5 (int Value1, int Value2) ();
923     static assert(func16479_5!(1, 1).mangleof
924                   == `_Z11func16479_5ILi1ELi1EEP10Value16479IXT0_EXT_EEv`);
925 
926     // But make sure it's not substituting *too many* values
927     Value16479!(1, 1)* func16479_6 (int Value1, int Value2) ();
928     static assert(func16479_6!(1, 1).mangleof
929                   == `_Z11func16479_6ILi1ELi1EEP10Value16479ILi1ELi1EEv`);
930 
931     // Or too many types
932     Array16479!(int) func16479_7 (FuncT1, FuncT2) (FuncT1);
933     static assert(func16479_7!(int, int).mangleof
934                   == `_Z11func16479_7IiiE10Array16479IiET_`);
935 
936     // Also must check the parameters for template param substitution
937     void func16479_8 (FuncT1) (Array16479!(FuncT1));
938     static assert(func16479_8!(int).mangleof
939                   == `_Z11func16479_8IiEv10Array16479IT_E`);
940 
941     // And non-substitution
942     void func16479_9 (FuncT1) (Array16479!(int));
943     static assert(func16479_9!(int).mangleof
944                   == `_Z11func16479_9IiEv10Array16479IiE`);
945 
946     // Now let's have a bit of fun with alias parameters,
947     // starting with C functions
948     // TODO: Why is this mangled by g++:
949     /*
950       extern "C"
951       {
952         void externC16479 (int);
953       }
954 
955       template<void (*Print)(int)>
956       void func16479_10 ();
957 
958       void foo () { func16479_10<externC16479>(); }
959      */
960     extern (C) void externC16479 (int);
961     void func16479_10 (alias Print) ();
962     static assert(func16479_10!(externC16479).mangleof
963                   == `_Z12func16479_10IXadL_Z12externC16479EEEvv`);
964 
965     /**
966      * Let's not exclude C++ functions
967      * Note:
968      *   Passing a function as template parameter has an implicit
969      *   `&` operator prepended to it, so the following code:
970      * ---
971      * void CPPPrinter16479(const char*);
972      * template<void (*Print)(const char*)> void func16479_11 ();
973      * void foo () { func16479_11<CPPPrinter16479>(); }
974      * ---
975      * Gets mangled as `func16479_11<&CPPPrinter16479>()` would,
976      * which means the expression part of the template argument is
977      * mangled as `XadL_Z[...]E` not `XL_Z[...]E`
978      * (expressions always begin with a code anyway).
979      */
980     extern(C++) void CPPPrinter16479(const(char)*);
981     extern(C++, Namespace16479) void CPPPrinterNS16479(const(char)*);
982     extern(C++, `Namespace16479`) void CPPPrinterNS16479_1(const(char)*);
983     void func16479_11 (alias Print) ();
984     static assert(func16479_11!(CPPPrinter16479).mangleof
985                   == `_Z12func16479_11IXadL_Z15CPPPrinter16479PKcEEEvv`);
986     static assert(func16479_11!(CPPPrinterNS16479).mangleof
987                   == `_Z12func16479_11IXadL_ZN14Namespace1647917CPPPrinterNS16479EPKcEEEvv`);
988     static assert(func16479_11!(CPPPrinterNS16479_1).mangleof
989                   == `_Z12func16479_11IXadL_ZN14Namespace1647919CPPPrinterNS16479_1EPKcEEEvv`);
990 
991     // Functions are fine, but templates are finer
992     // ---
993     // template<template<typename, int> class Container, typename T, int Val>
994     // Container<T, Val> func16479_12 ();
995     // ---
996     Container!(T, Val) func16479_12 (alias Container, T, int Val) ();
997     static assert(func16479_12!(Array16479_2, int, 42).mangleof
998                   == `_Z12func16479_12I12Array16479_2iLi42EET_IT0_XT1_EEv`);
999 
1000     // Substitution needs to happen on the most specialized type
1001     // Iow, `ref T identity (T) (ref T v);` should be mangled as
1002     // `_Z8identityIiET_*S1_*`, not as `_Z8identityIiET_*RS0_*`
1003     ref FuncT1 func16479_13_1 (FuncT1) (ref FuncT1);
1004     FuncT1*    func16479_13_2 (FuncT1) (FuncT1*);
1005     void       func16479_13_3 (FuncT1) (FuncT1*, FuncT1*);
1006     FuncT1**   func16479_13_4 (FuncT1) (FuncT1*, FuncT1);
1007     FuncT1     func16479_13_5 (FuncT1) (FuncT1*, FuncT1**);
1008     static assert(func16479_13_1!(int).mangleof == `_Z14func16479_13_1IiERT_S1_`);
1009     static assert(func16479_13_2!(float).mangleof == `_Z14func16479_13_2IfEPT_S1_`);
1010     static assert(func16479_13_3!(int).mangleof == `_Z14func16479_13_3IiEvPT_S1_`);
1011     static assert(func16479_13_4!(int).mangleof == `_Z14func16479_13_4IiEPPT_S1_S0_`);
1012     static assert(func16479_13_5!(int).mangleof == `_Z14func16479_13_5IiET_PS0_PS1_`);
1013 
1014     // Opaque types result in a slightly different AST
1015     vector!T* func16479_14 (T) (T v);
1016     static assert(func16479_14!(int).mangleof == `_Z12func16479_14IiEPSt6vectorIT_ES1_`);
1017 
1018     struct Foo16479_15 (T);
1019     struct Baguette16479_15 (T);
1020     struct Bar16479_15 (T);
1021     struct FooBar16479_15 (A, B);
1022     void inst16479_15_2 (A, B) ();
1023     void inst16479_15_3 (A, B, C) ();
1024 
1025     static assert(inst16479_15_2!(Bar16479_15!int, int).mangleof
1026                   == `_Z14inst16479_15_2I11Bar16479_15IiEiEvv`);
1027     static assert(inst16479_15_2!(int, Bar16479_15!int).mangleof
1028                   == `_Z14inst16479_15_2Ii11Bar16479_15IiEEvv`);
1029     static assert(inst16479_15_2!(Bar16479_15!int, FooBar16479_15!(Bar16479_15!int, Foo16479_15!(Bar16479_15!(Foo16479_15!int)))).mangleof
1030                   == `_Z14inst16479_15_2I11Bar16479_15IiE14FooBar16479_15IS1_11Foo16479_15IS0_IS3_IiEEEEEvv`);
1031     static assert(inst16479_15_3!(int, Bar16479_15!int, FooBar16479_15!(Bar16479_15!int, Foo16479_15!(Bar16479_15!(Foo16479_15!int)))).mangleof
1032                   == `_Z14inst16479_15_3Ii11Bar16479_15IiE14FooBar16479_15IS1_11Foo16479_15IS0_IS3_IiEEEEEvv`);
1033 
1034     static import cppmangle2;
1035     cppmangle2.Struct18922* func16479_16_1 (T) (T*);
1036     static assert(func16479_16_1!int.mangleof == `_Z14func16479_16_1IiEPN14Namespace1892211Struct18922EPT_`);
1037     T* func16479_16_2 (T) (T*);
1038     static assert(func16479_16_2!int.mangleof == `_Z14func16479_16_2IiEPT_S1_`);
1039     static assert(func16479_16_2!(cppmangle2.vector!int).mangleof == `_Z14func16479_16_2ISt6vectorIiEEPT_S3_`);
1040     static assert(func16479_16_2!(cppmangle2.vector!int).mangleof
1041                   == func16479_16_2!(cppmangle2.vector!int).mangleof);
1042     cppmangle2.vector!T* func16479_16_3 (T) (T*);
1043     static assert(func16479_16_3!int.mangleof == `_Z14func16479_16_3IiEPSt6vectorIiEPT_`);
1044 
1045     extern(C++, `fakestd`) {
1046         extern (C++, `__1`) {
1047             struct allocator16479 (T);
1048             struct vector16479(T, alloc = allocator16479!T);
1049         }
1050     }
1051     vector16479!(T, allocator16479!T)* func16479_17_1(T)();
1052     vector16479!(T)* func16479_17_2(T)();
1053     static assert(func16479_17_1!int.mangleof == `_Z14func16479_17_1IiEPN7fakestd3__111vector16479IT_NS1_14allocator16479IS3_EEEEv`);
1054     static assert(func16479_17_2!int.mangleof == `_Z14func16479_17_2IiEPN7fakestd3__111vector16479IT_NS1_14allocator16479IS3_EEEEv`);
1055 
1056     // Make sure substitution takes place everywhere in template arg list
1057     extern(C++, "ns") void func16479_18_1(T, X)(int, X, T, float);
1058     extern(C++, "ns") void func16479_18_2(T, X)(X, int, T, float);
1059     static assert(func16479_18_1!(double, char).mangleof == `_ZN2ns14func16479_18_1IdcEEviT0_T_f`);
1060     static assert(func16479_18_2!(double, char).mangleof == `_ZN2ns14func16479_18_2IdcEEvT0_iT_f`);
1061 }
1062 
1063 /**************************************/
1064 // https://issues.dlang.org/show_bug.cgi?id=19278
1065 // extern(C++, "name") doesn't accept expressions
1066 
1067 extern(C++, "hello" ~ "world")
1068 {
1069     void test19278();
1070 }
1071 enum NS = "lookup";
1072 extern(C++, (NS))
1073 {
1074     void test19278_2();
1075 }
1076 alias AliasSeq(Args...) = Args;
1077 alias Tup = AliasSeq!("hello", "world");
1078 extern(C++, (Tup))
1079 {
1080     void test19278_3();
1081     __gshared size_t test19278_var;
1082 }
1083 extern(C++, (AliasSeq!(Tup, "yay")))
1084 {
1085     void test19278_4();
1086 }
1087 version(Win64)
1088 {
1089     static assert(test19278.mangleof == "?test19278@helloworld@@YAXXZ");
1090     static assert(test19278_2.mangleof == "?test19278_2@lookup@@YAXXZ");
1091     static assert(test19278_3.mangleof == "?test19278_3@world@hello@@YAXXZ");
1092     static assert(test19278_4.mangleof == "?test19278_4@yay@world@hello@@YAXXZ");
1093     static assert(test19278_var.mangleof == "?test19278_var@world@hello@@3_KA");
1094 }
1095 else version(Posix)
1096 {
1097     static assert(test19278.mangleof == "_ZN10helloworld9test19278Ev");
1098     static assert(test19278_2.mangleof == "_ZN6lookup11test19278_2Ev");
1099     static assert(test19278_3.mangleof == "_ZN5hello5world11test19278_3Ev");
1100     static assert(test19278_4.mangleof == "_ZN5hello5world3yay11test19278_4Ev");
1101     static assert(test19278_var.mangleof == "_ZN5hello5world13test19278_varE");
1102 }
1103 
1104 /**************************************/
1105 // https://issues.dlang.org/show_bug.cgi?id=18958
1106 // Issue 18958 - extern(C++) wchar, dchar mangling not correct
1107 
1108 version(Posix)
1109     enum __c_wchar_t : dchar;
1110 else version(Windows)
1111     enum __c_wchar_t : wchar;
1112 alias wchar_t = __c_wchar_t;
1113 extern (C++) void test_char_mangling(char, wchar, dchar, wchar_t);
1114 version (Posix)
1115 {
1116     static assert(test_char_mangling.mangleof == "_Z18test_char_manglingcDsDiw");
1117 }
1118 version (Win64)
1119 {
1120     static assert(test_char_mangling.mangleof == "?test_char_mangling@@YAXD_S_U_W@Z");
1121 }
1122 
1123 // https://github.com/dlang/dmd/pull/10021/files#r294055424
1124 version (Posix)
1125 {
1126     extern(C++, PR10021_NS) struct PR10021_Struct(T){}
1127     extern(C++) void PR10021_fun(int i)(PR10021_Struct!int);
1128     static assert(PR10021_fun!0.mangleof == `_Z11PR10021_funILi0EEvN10PR10021_NS14PR10021_StructIiEE`);
1129 }
1130 
1131 // https://github.com/dlang/dmd/pull/10021#discussion_r294095749
1132 version (Posix)
1133 {
1134     extern(C++, "a", "b")
1135     struct PR10021_Struct2
1136     {
1137         void func();
1138         void func2(PR10021_Struct2*);
1139     }
1140     static assert(PR10021_Struct2.func.mangleof == `_ZN1a1b15PR10021_Struct24funcEv`);
1141     static assert(PR10021_Struct2.func2.mangleof == `_ZN1a1b15PR10021_Struct25func2EPS1_`);
1142 }
1143 
1144 /// https://issues.dlang.org/show_bug.cgi?id=20022
1145 version (Posix)
1146 {
1147     extern(C++, `ns20022`) enum Enum20022_1 { A = 1, }
1148     extern(C++) void fun20022_1(Enum20022_1);
1149     extern(C++, `ns20022`) void fun20022_2(Enum20022_1);
1150 
1151     extern(C++, ns20022)
1152     {
1153         enum Enum20022_2 { A = 1, }
1154         void fun20022_5(Enum20022_1);
1155         void fun20022_6(Enum20022_2);
1156     }
1157     extern(C++) void fun20022_3(Enum20022_2);
1158     extern(C++, `ns20022`) void fun20022_4(Enum20022_2);
1159 
1160     static assert(fun20022_1.mangleof == `_Z10fun20022_1N7ns2002211Enum20022_1E`);
1161     static assert(fun20022_2.mangleof == `_ZN7ns2002210fun20022_2ENS_11Enum20022_1E`);
1162 
1163     static assert(fun20022_3.mangleof == `_Z10fun20022_3N7ns2002211Enum20022_2E`);
1164     static assert(fun20022_4.mangleof == `_ZN7ns2002210fun20022_4ENS_11Enum20022_2E`);
1165     static assert(fun20022_5.mangleof == `_ZN7ns2002210fun20022_5ENS_11Enum20022_1E`);
1166     static assert(fun20022_6.mangleof == `_ZN7ns2002210fun20022_6ENS_11Enum20022_2E`);
1167 }
1168 
1169 // https://issues.dlang.org/show_bug.cgi?id=20094
1170 version (Posix)
1171 {
1172     extern(C++, "ns20094")
1173     {
1174         struct xvector20094 (T) {}
1175         alias V20094 = xvector20094!(ubyte);
1176     }
1177 
1178     extern(C++) void test20094(xvector20094!(V20094)* v);
1179     static assert(test20094.mangleof == `_Z9test20094PN7ns2009412xvector20094INS0_IhEEEE`);
1180 }
1181 
1182 // https://issues.dlang.org/show_bug.cgi?id=20223
1183 version (Posix)
1184 {
1185     extern(C++)
1186     {
1187         int test20223_1(T)(int function(const(T)* value));
1188         int test20223_2(T)(int function(ref const(T) value));
1189 
1190         struct Struct20223_1 {}
1191         struct Struct20223_2 {}
1192         int test20223_3(ref const Struct20223_1, Struct20223_2*, Struct20223_2*);
1193         int test20223_4(ref const Struct20223_1, const ref Struct20223_2, Struct20223_2*);
1194 
1195         struct Struct20223_3 (T) {}
1196         void test20223_5(ref Struct20223_1, ref Struct20223_3!(const(char)*),
1197                          ref Struct20223_3!(const(char)*));
1198     }
1199     static assert(test20223_1!int.mangleof == `_Z11test20223_1IiEiPFiPKT_E`);
1200     static assert(test20223_2!int.mangleof == `_Z11test20223_2IiEiPFiRKT_E`);
1201     static assert(test20223_1!(int*).mangleof == `_Z11test20223_1IPiEiPFiPKT_E`);
1202     static assert(test20223_2!(int*).mangleof == `_Z11test20223_2IPiEiPFiRKT_E`);
1203     static assert(test20223_3.mangleof == `_Z11test20223_3RK13Struct20223_1P13Struct20223_2S3_`);
1204     static assert(test20223_4.mangleof == `_Z11test20223_4RK13Struct20223_1RK13Struct20223_2PS2_`);
1205     static assert(test20223_5.mangleof == `_Z11test20223_5R13Struct20223_1R13Struct20223_3IPKcES5_`);
1206 }
1207 
1208 // https://issues.dlang.org/show_bug.cgi?id=20224
1209 version (Posix)
1210 {
1211     extern(C++) public int test20224_1(T)(set20224!T set);  // ok
1212     extern(C++) public int test20224_2(T)(ref set20224!T set);  // segfault
1213 
1214     extern(C++) struct set20224 (T)
1215     {
1216         void test ()
1217         {
1218             test20224_1!T(this);
1219             test20224_2!T(this);  // segfaults
1220         }
1221     }
1222 
1223     extern(D) void func20224 ()
1224     {
1225         set20224!int x;
1226     }
1227 }
1228 
1229 /**************************************/
1230 
1231 version (Posix)
1232 {
1233     extern (C++) struct Loc2 {};
1234     extern (C++) class FuncDeclaration
1235     {
1236         static FuncDeclaration create(ref const Loc2, ref const Loc2);
1237     };
1238     extern (C++) FuncDeclaration FuncDeclaration_create(ref const Loc2, ref const Loc2);
1239 
1240     static assert(FuncDeclaration_create.mangleof == `_Z22FuncDeclaration_createRK4Loc2S1_`);
1241     static assert(FuncDeclaration.create.mangleof == `_ZN15FuncDeclaration6createERK4Loc2S2_`);
1242 }
1243 
1244 enum Enum19542 = func19542!(int).mangleof;
1245 
1246 extern(C++, `bar`)
1247 {
1248     void func19542(T)();
1249 }
1250 
1251 // https://issues.dlang.org/show_bug.cgi?id=20700
1252 // Only testing on WIn64 because the mangling includes 'E',
1253 // and the bug can be tested on either platform
1254 version (Win64) extern(C++)
1255 {
1256     void test20700_1(Struct20700);
1257     extern(C++, class) struct Struct20700 {}
1258     void test20700_2(Struct20700);
1259 
1260     // Note: Needs to be `V` (`class`), not `U` (`struct`)
1261     static assert(test20700_1.mangleof == `?test20700_1@@YAXVStruct20700@@@Z`);
1262     static assert(test20700_2.mangleof == `?test20700_2@@YAXVStruct20700@@@Z`);
1263 
1264     // Test that the scope is not "sticky" on the arguments
1265     void test20700_3(TStruct20700_1!DefaultClass20700_1);
1266     extern(C++, class) struct TStruct20700_1 (T1, T2 = DefaultStruct20700_1) {}
1267     extern(C++, class) struct DefaultStruct20700_1 {}
1268     extern(C++, struct) class DefaultClass20700_1 {}
1269     static assert(test20700_3.mangleof == `?test20700_3@@YAXV?$TStruct20700_1@PEAUDefaultClass20700_1@@VDefaultStruct20700_1@@@@@Z`);
1270 
1271     // Each test needs to be independent symbol to trigger a new semantic pass
1272     void test20700_4(TStruct20700_2!(DefaultClass20700_2, DefaultStruct20700_2));
1273     extern(C++, struct) class TStruct20700_2 (T1, T2 = DefaultClass20700_2) {}
1274     extern(C++, class) struct DefaultStruct20700_2 {}
1275     extern(C++, struct) class DefaultClass20700_2 {}
1276     static assert(test20700_4.mangleof == `?test20700_4@@YAXPEAU?$TStruct20700_2@PEAUDefaultClass20700_2@@VDefaultStruct20700_2@@@@@Z`);
1277 }
1278 
1279 /*****************************************/
1280 
1281 alias noreturn = typeof(*null);
1282 
1283 extern (C++)
1284 {
1285     alias fpcpp = noreturn function();
1286     int funccpp(fpcpp);
1287 
1288     version (Posix)
1289         static assert(funccpp.mangleof == "_Z7funccppPFvvE");
1290 
1291     version (Win32)
1292         static assert(funccpp.mangleof == "?funccpp@@YAHP6AXXZ@Z");
1293 
1294     version (Win64)
1295         static assert(funccpp.mangleof == "?funccpp@@YAHP6AXXZ@Z");
1296 }
1297