1 /**
2    Github issues.
3  */
4 module it.issues;
5 
6 import it;
7 
8 @Tags("issue")
9 @("3")
10 @safe unittest {
11     shouldCompile(
12         C(
13             `
14                 #include <signal.h>
15             `
16         ),
17         D(
18             q{
19                 siginfo_t si;
20                 si._sifields._timer.si_tid = 2;
21                 static assert(is(typeof(si.si_signo) == int));
22                 static assert(is(typeof(si._sifields._timer.si_tid) == int),
23                               typeof(si._sifields._timer.si_tid).stringof);
24             }
25         ),
26     );
27 }
28 
29 
30 @Tags("issue")
31 @("4")
32 @safe unittest {
33     with(immutable IncludeSandbox()) {
34         writeFile("issue4.h",
35                   q{
36                       extern char *arr[9];
37                   });
38         writeFile("issue4.dpp",
39                   `
40                    #include "issue4.h"
41                   `);
42         runPreprocessOnly("issue4.dpp");
43         fileShouldContain("issue4.d", q{extern __gshared char*[9] arr;});
44     }
45 }
46 
47 @Tags("issue")
48 @("5")
49 @safe unittest {
50     shouldCompile(
51         C(
52             q{
53                 typedef enum zfs_error {
54                     EZFS_SUCCESS = 0,
55                     EZFS_NOMEM = 2000,
56                 };
57 
58                 typedef struct zfs_perm_node {
59                     char z_pname[4096];
60                 } zfs_perm_node_t;
61 
62                 typedef struct libzfs_handle libzfs_handle_t;
63             }
64         ),
65         D(
66             q{
67                 zfs_error e1 = EZFS_SUCCESS;
68                 zfs_error e2 = zfs_error.EZFS_SUCCESS;
69                 zfs_perm_node_t node;
70                 static assert(node.z_pname.sizeof == 4096);
71                 static assert(is(typeof(node.z_pname[0]) == char), (typeof(node.z_pname[0]).stringof));
72                 libzfs_handle_t* ptr;
73             }
74         ),
75     );
76 }
77 
78 @Tags("issue")
79 @("6")
80 @safe unittest {
81     with(immutable IncludeSandbox()) {
82         writeFile("issue6.h",
83                   q{
84                       char *getMessage();
85                   });
86         writeFile("issue6.dpp",
87                   `
88                    #include "issue6.h"
89                   `);
90         runPreprocessOnly("issue6.dpp");
91         fileShouldContain("issue6.d", q{char* getMessage() @nogc nothrow;});
92     }
93 }
94 
95 
96 @Tags("issue", "bitfield")
97 @("7")
98 @safe unittest {
99     shouldCompile(
100         C(
101             q{
102                 struct splitflags {
103                     int dryrun : 1;
104                     int import : 2;
105                     int name_flags;
106                     int foo: 3;
107                     int bar: 4;
108                     int suffix;
109                 };
110 
111                 struct other {
112                     int quux: 2;
113                     int toto: 3;
114                 };
115             }
116         ),
117         D(
118             q{
119                 static assert(splitflags.sizeof == 16);
120                 static assert(other.sizeof == 4);
121             }
122         ),
123     );
124 }
125 
126 @Tags("issue")
127 @("10")
128 @safe unittest {
129     shouldCompile(
130         C(
131             q{
132                 enum silly_name {
133                     FOO,
134                     BAR,
135                     BAZ,
136                 };
137 
138                 extern void silly_name(enum silly_name thingie);
139             }
140         ),
141         D(
142             q{
143                 silly_name_(silly_name.FOO);
144             }
145         ),
146     );
147 }
148 
149 @Tags("issue")
150 @("11")
151 @safe unittest {
152     shouldCompile(
153         C(
154             q{
155                 struct Foo;
156                 typedef struct Foo* FooPtr;
157             }
158         ),
159         D(
160             q{
161                 FooPtr f = null;
162                 static assert(!__traits(compiles, Foo()));
163             }
164         ),
165     );
166 }
167 
168 @Tags("issue")
169 @("14")
170 @safe unittest {
171     import dpp.runtime.options: Options;
172     with(immutable IncludeSandbox()) {
173 
174         writeFile("foo.h",
175                   q{
176                       typedef int foo;
177                   });
178 
179         runPreprocessOnly("foo.h").shouldThrowWithMessage(
180             "No .dpp input file specified\n" ~ Options.usage);
181     }
182 }
183 
184 @Tags("issue", "preprocessor")
185 @("22.0")
186 @safe unittest {
187     shouldCompile(
188         C(
189             `
190                 typedef struct {
191                     #ifdef __USE_XOPEN
192                         int fds_bits[42];
193                         #define __FDS_BITS(set) ((set)->fds_bits)
194                     #else
195                         int __fds_bits[42];
196                         #define __FDS_BITS(set) ((set)->__fds_bits)
197                     #endif
198                 } fd_set;
199             `
200         ),
201         D(
202             q{
203                 fd_set set;
204                 __FDS_BITS(set)[0] = 42;
205             }
206         ),
207     );
208 }
209 
210 @Tags("issue", "preprocessor")
211 @("22.1")
212 @safe unittest {
213     shouldCompile(
214         C(
215             `
216                 #define SIZEOF(x) (sizeof(x))
217             `
218         ),
219         D(
220             q{
221                 int i;
222                 static assert(SIZEOF(i) == 4);
223             }
224         ),
225     );
226 }
227 
228 @ShouldFail
229 @Tags("issue", "preprocessor")
230 @("22.3")
231 @safe unittest {
232     shouldCompile(
233         C(
234             `
235                 typedef long int __fd_mask;
236                 #define __NFDBITS (8 * (int) sizeof (__fd_mask))
237             `
238         ),
239         D(
240             q{
241                 import std.conv;
242                 static assert(__NFDBITS == 8 * c_long.sizeof,
243                               text("expected ", 8 * c_long.sizeof, ", got: ", __NFDBITS));
244             }
245         ),
246     );
247 }
248 
249 @Tags("issue", "preprocessor")
250 @("22.4")
251 @safe unittest {
252     shouldCompile(
253         C(
254             `
255                 typedef struct clist { struct list* next; };
256                 #define clist_next(iter) (iter ? (iter)->next : NULL)
257             `
258         ),
259         D(
260             q{
261                 clist l;
262                 auto next = clist_next(&l);
263             }
264         ),
265     );
266 }
267 
268 
269 
270 @Tags("issue", "collision", "issue24")
271 @("24.0")
272 @safe unittest {
273     shouldCompile(
274         C(
275             q{
276                 struct Bar {
277                     void (*Foo)(void); // this should get renamed as Foo_
278                     struct Foo* (*whatever)(void);
279                 };
280             }
281         ),
282         D(
283             q{
284             }
285         ),
286     );
287 }
288 
289 @Tags("issue", "collision", "issue24")
290 @("24.1")
291 @safe unittest {
292     shouldCompile(
293         C(
294             q{
295                 int foo(int, struct foo_data**);
296                 struct foo { int dummy; };
297                 struct foo_data { int dummy; };
298             }
299         ),
300         D(
301             q{
302                 foo_data** data;
303                 int ret = foo_(42, data);
304                 foo s;
305                 s.dummy = 33;
306                 foo_data fd;
307                 fd.dummy = 77;
308             }
309         ),
310     );
311 }
312 
313 
314 @Tags("issue")
315 @("29.0")
316 @safe unittest {
317     shouldCompile(
318         C(
319             q{
320                 typedef struct {
321                     union {
322                         struct {
323                             double x;
324                             double y;
325                             double z;
326                         };
327                         double raw[3];
328                     };
329                 } vec3d_t;
330             }
331         ),
332         D(
333             q{
334                 vec3d_t v;
335                 static assert(v.sizeof == 24);
336                 v.raw[1] = 3.0;
337                 v.y = 4.0;
338             }
339         ),
340     );
341 }
342 
343 @Tags("issue")
344 @("29.1")
345 @safe unittest {
346     shouldCompile(
347         C(
348             q{
349                 typedef struct {
350                     struct {
351                         int x;
352                         int y;
353                     };
354 
355                     struct {
356                         int z;
357                     };
358                 } Struct;
359             }
360         ),
361         D(
362             q{
363                 Struct s;
364                 s.x = 2;
365                 s.y = 3;
366                 s.z = 4;
367             }
368         ),
369     );
370 }
371 
372 @Tags("issue")
373 @("29.2")
374 @safe unittest {
375     shouldCompile(
376         C(
377             q{
378                 struct Struct {
379                     union {
380                         unsigned long long int foo;
381                         struct {
382                             unsigned int low;
383                             unsigned int high;
384                         } foo32;
385                     };
386                 };
387             }
388         ),
389         D(
390             q{
391                 Struct s;
392                 s.foo = 42;
393                 s.foo32.low = 33;
394                 s.foo32.high = 77;
395             }
396         ),
397     );
398 }
399 
400 
401 @Tags("issue")
402 @("29.3")
403 @safe unittest {
404     shouldCompile(
405         C(
406             q{
407                 struct Struct {
408                     union {
409                         unsigned long long int foo;
410                         void *bar;
411                     };
412                 };
413             }
414         ),
415         D(
416             q{
417                 Struct s;
418                 s.foo = 42;
419                 s.bar = null;
420             }
421         ),
422     );
423 }
424 
425 
426 @Tags("issue")
427 @("33.0")
428 @safe unittest {
429     shouldCompile(
430         C(
431             q{
432                 void (*f)();
433             }
434         ),
435         D(
436             q{
437                 static extern(C) void printHello() { }
438                 f = &printHello;
439                 f();
440             }
441         ),
442     );
443 }
444 
445 @Tags("issue")
446 @("33.1")
447 @safe unittest {
448     shouldCompile(
449         C(
450             q{
451                 int (*f)();
452             }
453         ),
454         D(
455             q{
456                 static extern(C) int func() { return 42; }
457                 f = &func;
458                 int i = f();
459             }
460         ),
461     );
462 }
463 
464 
465 @Tags("issue", "bitfield")
466 @("35")
467 @safe unittest {
468     shouldCompile(
469         C(
470             q{
471                 struct Struct {
472                     int foo;
473                     int bar;
474                     int :32;
475                     int :31;
476                     int :3;
477                     int :27;
478                 };
479             }
480         ),
481         D(
482             q{
483                 Struct s;
484                 static assert(s.sizeof == 20);
485             }
486         ),
487     );
488 }
489 
490 @Tags("issue")
491 @("37")
492 @safe unittest {
493     shouldCompile(
494         C(
495             `
496                 #include "mmintrin.h"
497             `
498         ),
499         D(
500             q{
501             }
502         ),
503     );
504 }
505 
506 
507 @Tags("issue", "preprocessor")
508 @("39.0")
509 @safe unittest {
510     shouldCompile(
511         C(
512             `
513                 typedef long value;
514                 typedef long intnat;
515                 typedef unsigned long uintnat;
516                 #define Val_long(x) ((intnat) (((uintnat)(x) << 1)) + 1)
517                 #define Long_val(x)     ((x) >> 1)
518                 #define Val_int(x) Val_long(x)
519                 #define Int_val(x) ((int) Long_val(x))
520                 #define Bp_val(v) ((char *) (v))
521                 #define String_val(x) ((const char *) Bp_val(x))
522                 value caml_callback(value, value);
523                 char* strdup(const char* val);
524             `
525         ),
526         D(
527             q{
528                 static value* fib_closure = null;
529                 int n;
530                 auto val = Int_val(caml_callback(*fib_closure, Val_int(n)));
531                 char* str = strdup(String_val(caml_callback(*fib_closure, Val_int(n))));
532             }
533         ),
534     );
535 }
536 
537 @Tags("issue", "preprocessor")
538 @("39.1")
539 @safe unittest {
540     shouldCompile(
541         C(
542             `
543                 #define VOID_PTR(x) ( void* )(x)
544             `
545         ),
546         D(
547             q{
548                 auto val = VOID_PTR(42);
549                 static assert(is(typeof(val) == void*));
550             }
551         ),
552     );
553 }
554 
555 @Tags("issue", "preprocessor")
556 @("39.2")
557 @safe unittest {
558     shouldCompile(
559         C(
560             `
561                 typedef int myint;
562                 #define CAST(x) ( myint* )(x)
563             `
564         ),
565         D(
566             q{
567                 auto val = CAST(42);
568                 static assert(is(typeof(val) == int*));
569             }
570         ),
571     );
572 }
573 
574 @Tags("issue", "preprocessor")
575 @("40")
576 @safe unittest {
577     with(immutable IncludeSandbox()) {
578         writeFile("hdr1.h",
579                   q{
580                       typedef int myint;
581                   });
582         writeFile("hdr2.h",
583                   q{
584                       myint myfunc(void);
585                   });
586         writeFile("src.dpp",
587                   `
588                       #include "hdr1.h"
589                       #include "hdr2.h"
590                       void func() {
591                           myint _ = myfunc();
592                       }
593                   `);
594         runPreprocessOnly("src.dpp");
595         shouldCompile("src.d");
596     }
597 }
598 
599 @Tags("issue")
600 @("43")
601 @safe unittest {
602     shouldCompile(
603         C(
604             q{
605                 // The declaration `int (f)(int x, int y)` is of a function
606                 // parameter that has the type of a binary function that
607                 // returns int. Because C is C, this is similar to writing
608                 // `int f[16]` in a parameter list but actually declaring
609                 // `int*`. The result is a parameter that's a function pointer
610                 // instead. To make things worse, if you put parens around the
611                 // parameter name as is done here, the cursor's type according
612                 // to libclang (in older versions) goes from FunctionProto to
613                 // Unexposed because "reasons".
614                 int binOp(int (f)(int x, int y), int a, int b);
615                 int thef(int x, int y);
616             }
617         ),
618         D(
619             q{
620                 binOp(&thef, 2, 3);
621             }
622         ),
623     );
624 }
625 
626 
627 @Tags("issue")
628 @("44.1")
629 @safe unittest {
630     shouldCompile(
631         C(
632             `
633                 #define macro(x) (x) + 42
634             `
635         ),
636         D(
637             q{
638                 static assert(macro_(0) == 42);
639                 static assert(macro_(1) == 43);
640             }
641         ),
642     );
643 }
644 
645 @Tags("issue")
646 @("44.2")
647 @safe unittest {
648     shouldCompile(
649         C(
650             `
651                 struct macro { int i };
652             `
653         ),
654         D(
655             q{
656             }
657         ),
658     );
659 }
660 
661 
662 @Tags("issue")
663 @("48")
664 @safe unittest {
665     shouldCompile(
666         C(
667             `
668                 #include <stddef.h>
669                 struct Struct {
670                     volatile int x;
671                     volatile size_t y;
672                 };
673             `
674         ),
675         D(
676             q{
677 
678             }
679         ),
680     );
681 }
682 
683 @Tags("issue", "preprocessor")
684 @("49")
685 @safe unittest {
686     shouldCompile(
687         C(
688             `
689                 #define func() ((void)0)
690                 void (func)(void);
691             `
692         ),
693         D(
694             q{
695                 // it gets renamed
696                 func_();
697             }
698         ),
699     );
700 }
701 
702 @Tags("issue")
703 @("53")
704 @safe unittest {
705     shouldCompile(
706         C(
707             q{
708                 typedef int bool;
709             }
710         ),
711         D(
712             q{
713 
714             }
715         ),
716     );
717 }
718 
719 @Tags("issue", "enum")
720 @("54")
721 @safe unittest {
722     shouldCompile(
723         C(
724             q{
725                 enum {
726                     SUCCESS,
727                 };
728                 typedef int boolean;
729             }
730         ),
731         D(
732             q{
733                 static assert(SUCCESS == 0);
734             }
735         ),
736     );
737 }
738 
739 
740 @Tags("issue")
741 @("66")
742 @safe unittest {
743     shouldCompile(
744         C(
745             `
746                 #include <linux/ethtool.h>
747             `
748         ),
749         D(
750             q{
751             }
752         ),
753     );
754 }
755 
756 
757 @Tags("issue")
758 @("76")
759 @safe unittest {
760     shouldCompile(
761         Cpp(
762             q{
763                 template <typename T>
764                 struct Template {
765                     T payload;
766                 };
767             }
768         ),
769         D(
770             q{
771                 static assert(__traits(getProtection, Template!int.payload) == "public",
772                               __traits(getProtection, Template!int.payload));
773             }
774         ),
775     );
776 }
777 
778 
779 
780 @Tags("issue")
781 @("77")
782 @safe unittest {
783     with(immutable IncludeSandbox()) {
784         writeFile("hdr.h", "");
785         writeFile("app.dpp",
786                   `
787                       module mymodule;
788                       #include "hdr.h"
789                       void main() {
790                           static assert(__MODULE__ == "mymodule");
791                       }
792                   `);
793         runPreprocessOnly("app.dpp");
794         shouldCompile("app.d");
795     }
796 }
797 
798 @Tags("issue")
799 @("79")
800 unittest {
801     with(const IncludeSandbox()) {
802         writeHeaderAndApp("1st.h",
803                           `
804                               #include "2nd.h"
805                               #define BAR 33
806                           `,
807                           D(""), // no need for .dpp source code
808         );
809         writeFile("2nd.h",
810                   `
811                       // these empty lines are important, since they push the enum
812                       // declaration down to have a higher line number than the BAR macro.
813                       enum TheEnum { BAR = 42 };
814                   `);
815         run("-c", inSandboxPath("app.dpp"));
816     }
817 }
818 
819 
820 @Tags("issue")
821 @("90.0")
822 @safe unittest {
823     shouldCompile(
824         C(
825             `
826                 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
827             `
828         ),
829         D(
830             q{
831             }
832         ),
833     );
834 }
835 
836 @Tags("issue")
837 @("90.1")
838 @safe unittest {
839     shouldCompile(
840         C(
841             `
842                 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(_ARR[0])))
843             `
844         ),
845         D(
846             q{
847                 int[8] ints;
848                 static assert(TEST(ints) == 8);
849             }
850         ),
851     );
852 }
853 
854 @Tags("issue")
855 @("91.0")
856 @safe unittest {
857     shouldCompile(
858         Cpp(
859             q{
860                 template <typename T, typename U> class Test {};
861                 void test(Test<unsigned short, unsigned int> a);
862             }
863         ),
864         D(
865             q{
866                 test(Test!(ushort, uint)());
867             }
868         ),
869     );
870 }
871 
872 @Tags("issue")
873 @("91.1")
874 @safe unittest {
875     shouldCompile(
876         Cpp(
877             q{
878                 template <typename T, int> class Test {};
879                 void test(Test<unsigned short, 42> a);
880             }
881         ),
882         D(
883             q{
884                 test(Test!(ushort, 42)());
885             }
886         ),
887     );
888 }
889 
890 
891 @Tags("issue")
892 @("93")
893 @safe unittest {
894     shouldCompile(
895         Cpp(
896             q{
897                 constexpr int x = sizeof(int) + (1) + sizeof(int);
898             }
899         ),
900         D(
901             q{
902                 static assert(x == 9);
903             }
904         ),
905     );
906 }
907 
908 
909 @Tags("issue")
910 @("95")
911 @safe unittest {
912     shouldCompile(
913         Cpp(
914             q{
915                 constexpr int x = sizeof(int) + alignof(int) + sizeof(int);
916             }
917         ),
918         D(
919             q{
920                 static assert(x == 12);
921             }
922         ),
923     );
924 }
925 
926 
927 @Tags("issue")
928 @("96")
929 @safe unittest {
930     shouldCompile(
931         Cpp(
932             q{
933                 template<unsigned long A, int B> class C{
934                     enum { value = 0 };
935                 };
936                 template<> class C<3,4> {
937                     enum { value = 1 };
938                 };
939             }
940         ),
941         D(
942             q{
943                 static assert(C!(0, 0).value == 0);
944                 static assert(C!(0, 1).value == 0);
945                 static assert(C!(1, 0).value == 0);
946 
947                 static assert(C!(3, 4).value == 1);
948             }
949         ),
950     );
951 }
952 
953 
954 @Tags("issue")
955 @("97")
956 @safe unittest {
957     shouldCompile(
958         Cpp(
959             q{
960                 class T1 {
961                 public:
962                     int i;
963                 };
964 
965                 template<int I>
966                 class T2 {
967                 public:
968                     double d;
969                 };
970 
971                 extern T1 a;
972                 extern T2<3> b;
973             }
974         ),
975         D(
976             q{
977                 a.i = 33;
978                 b.d = 33.3;
979             }
980         ),
981     );
982 }
983 
984 
985 @Tags("issue")
986 @("99")
987 @safe unittest {
988     shouldCompile(
989         Cpp(
990             q{
991                 class A {
992                 public:
993                     constexpr static int i = 0;
994                     constexpr static int j = A::i;
995                 };
996             }
997         ),
998         D(
999             q{
1000                 static assert(A.i == 0);
1001                 static assert(A.j == 0);
1002             }
1003         ),
1004     );
1005 }
1006 
1007 
1008 @ShouldFail("cursor.enumConstantValue returning 0 for `value = I`")
1009 @Tags("issue")
1010 @("100")
1011 @safe unittest {
1012     shouldCompile(
1013         Cpp(
1014             q{
1015                 class T1 {
1016                     enum { value = 42 };
1017                 };
1018 
1019                 template<int I>
1020                 class T2 {
1021                     enum { value = I };
1022                 };
1023             }
1024         ),
1025         D(
1026             q{
1027                 static assert(T1.value == 42);
1028                 static assert(T2!2.value == 2);
1029                 static assert(T2!3.value == 3);
1030             }
1031         ),
1032     );
1033 }
1034 
1035 
1036 @Tags("issue")
1037 @("101")
1038 @safe unittest {
1039     shouldCompile(
1040         Cpp(
1041             q{
1042                 // normally without the underscore
1043                 int operator "" _s(const wchar_t* __str, unsigned long __len);
1044             }
1045         ),
1046         D(
1047             q{
1048             }
1049         ),
1050     );
1051 }
1052 
1053 
1054 @Tags("issue")
1055 @("103.0")
1056 @safe unittest {
1057     with(immutable IncludeSandbox()) {
1058         writeFile("hdr.h",
1059                   "#define CONSTANT 42\n");
1060         writeFile("hdr.dpp",
1061                   `
1062                       #include "hdr.h"
1063                   `);
1064         writeFile("app.d",
1065                   q{
1066                       import hdr;
1067                       static assert(DPP_ENUM_CONSTANT == 42);
1068                   });
1069 
1070         runPreprocessOnly("hdr.dpp");
1071         shouldCompile("app.d");
1072     }
1073 }
1074 
1075 
1076 @Tags("issue")
1077 @("103.1")
1078 @safe unittest {
1079     with(immutable IncludeSandbox()) {
1080         writeFile("hdr.h",
1081                   "#define OCTAL 00177\n");
1082         writeFile("hdr.dpp",
1083                   `
1084                       #include "hdr.h"
1085                   `);
1086         writeFile("app.d",
1087                   q{
1088                       import hdr;
1089                       import std.conv: text;
1090                       static assert(DPP_ENUM_OCTAL == 127);
1091                   });
1092 
1093         runPreprocessOnly("hdr.dpp");
1094         shouldCompile("app.d");
1095     }
1096 }
1097 
1098 
1099 @ShouldFail
1100 @Tags("issue")
1101 @("104")
1102 @safe unittest {
1103     shouldCompile(
1104         Cpp(
1105             q{
1106                 template <int> struct Struct{};
1107                 template<>
1108                 struct Struct<1 + 1> {
1109                     static constexpr auto value = 42;
1110                 };
1111             }
1112         ),
1113         D(
1114             q{
1115                 static assert(Struct!2.value == 42);
1116             }
1117         ),
1118    );
1119 }
1120 
1121 
1122 @Tags("issue")
1123 @("108")
1124 @safe unittest {
1125     shouldCompile(
1126         Cpp(
1127             q{
1128                 template<class T1, class T2, int I>
1129                 class A {};
1130 
1131                 template <typename CC> class C {};
1132 
1133                 template<>
1134                 class A<C<int>, double, 42> {};
1135             }
1136         ),
1137         D(
1138             q{
1139 
1140             }
1141         ),
1142     );
1143 }
1144 
1145 
1146 @Tags("issue")
1147 @("109")
1148 @safe unittest {
1149     shouldCompile(
1150         Cpp(
1151             q{
1152                 template<typename C> class Test
1153                 {
1154                     bool operator==(const Test<C>& x) const { return 0; }
1155                     bool operator<(const Test<C>& x)  const { return 0; }
1156                     bool operator>(const Test<C>& x)  const { return 0; }
1157                 };
1158             }
1159         ),
1160         D(
1161             q{
1162                 const t = Test!int();
1163                 const eq = t == t;
1164                 const lt = t < t;
1165                 const gt = t > t;
1166             }
1167         ),
1168     );
1169 }
1170 
1171 
1172 @Tags("issue")
1173 @("110")
1174 @safe unittest {
1175     shouldCompile(
1176         Cpp(
1177             q{
1178                 class A {
1179                     bool operator_a() const;
1180                 };
1181             }
1182         ),
1183         D(
1184             q{
1185                 auto a = new const A;
1186                 bool ret = a.operator_a();
1187             }
1188         ),
1189     );
1190 }
1191 
1192 
1193 
1194 @Tags("issue", "namespace")
1195 @("113")
1196 @safe unittest {
1197     shouldCompile(
1198         Cpp(
1199             q{
1200                 // the issue here was nested namespaces
1201                 namespace ns1 {
1202                     namespace ns2 {
1203                         struct Struct;
1204 
1205                         template<typename T>
1206                             struct Template {
1207                         };
1208 
1209                         class Class;  // should be ignored but isn't
1210                         class Class: public Template<Struct> {
1211                             int i;
1212                         };
1213                     }
1214                 }
1215             }
1216         ),
1217         D(
1218             q{
1219             }
1220         ),
1221     );
1222 }
1223 
1224 
1225 @Tags("issue")
1226 @("114")
1227 @safe unittest {
1228     shouldCompile(
1229         Cpp(
1230             q{
1231                 template<class T>
1232                 struct Foo {
1233                     template<class U>
1234                     Foo& operator=(U& other) {
1235                         return *this;
1236                     }
1237                 };
1238             }
1239         ),
1240         D(
1241             q{
1242                 Foo!int foo;
1243                 int i;
1244                 foo = i;
1245                 double d;
1246                 foo = d;
1247             }
1248         ),
1249     );
1250 }
1251 
1252 
1253 @Tags("issue")
1254 @("115")
1255 @safe unittest {
1256     shouldCompile(
1257         Cpp(
1258             q{
1259                 template<class T>
1260                 class Foo {
1261                     T value;
1262                 public:
1263                     Foo(T value);
1264                 };
1265 
1266                 template<class T>
1267                 Foo<T>::Foo(T val) {
1268                     value = val;
1269                 }
1270             }
1271         ),
1272         D(
1273             q{
1274                 auto fooI = Foo!int(42);
1275                 auto fooD = Foo!double(33.3);
1276             }
1277         ),
1278     );
1279 }
1280 
1281 
1282 @Tags("issue")
1283 @("116")
1284 @safe unittest {
1285     shouldCompile(
1286         Cpp(
1287             q{
1288                 struct Foo;
1289                 struct Foo { int i; };
1290             }
1291         ),
1292         D(
1293             q{
1294                 static assert(is(typeof(Foo.i) == int));
1295             }
1296         ),
1297     );
1298 }
1299 
1300 
1301 @Tags("issue")
1302 @("119.0")
1303 @safe unittest {
1304     shouldCompile(
1305         Cpp(
1306             q{
1307                 struct Struct {
1308                     enum Enum { foo, bar, baz };
1309                 };
1310 
1311                 void fun(Struct::Enum);
1312             }
1313         ),
1314         D(
1315             q{
1316             }
1317         ),
1318     );
1319 }
1320 
1321 
1322 @Tags("issue")
1323 @("119.1")
1324 @safe unittest {
1325     shouldCompile(
1326         Cpp(
1327             q{
1328                 struct Struct {
1329                     enum class Enum { foo, bar, baz };
1330                 };
1331             }
1332         ),
1333         D(
1334             q{
1335                 auto f = Struct.Enum.foo;
1336                 static assert(!__traits(compiles, Struct.foo));
1337             }
1338         ),
1339     );
1340 }
1341 
1342 
1343 @ShouldFail("libclang fails to tokenise this for some reason")
1344 @Tags("issue", "libclang")
1345 @("119.2")
1346 @safe unittest {
1347     with(immutable IncludeSandbox()) {
1348 
1349         writeFile("util.hpp",
1350                   `
1351                       #define MAKE_ENUM_CLASS(type, values) enum class type { values };
1352                   `);
1353 
1354         writeFile("hdr.hpp",
1355                   `
1356                       #include "util.hpp"
1357                       #define VALUES X(foo) X(bar) X(baz)
1358                       #define X(n) n,
1359                           MAKE_ENUM_CLASS(Enum, VALUES)
1360                       #undef X
1361                   `);
1362 
1363         writeFile("app.dpp",
1364                   `
1365                   #include "hdr.hpp"
1366                   void main() {
1367                       auto f = Enum.foo;
1368                       static assert(!__traits(compiles, foo));
1369                   }
1370                   `);
1371 
1372         runPreprocessOnly(["app.dpp"]);
1373         shouldCompile("app.d");
1374     }
1375 }
1376 
1377 
1378 @Tags("issue")
1379 @("134")
1380 @safe unittest {
1381     shouldCompile(
1382         Cpp(
1383             q{
1384                 struct Foo {
1385                     double fun(int i) const;
1386                 };
1387 
1388                 double Foo::fun(int i) const {
1389                     return i * 2;
1390                 }
1391             }
1392         ),
1393         D(
1394             q{
1395                 auto foo = Foo();
1396                 double d = foo.fun(42);
1397             }
1398         ),
1399     );
1400 }
1401 
1402 
1403 @Tags("namespace", "issue")
1404 @("149")
1405 @safe unittest {
1406     shouldCompile(
1407         Cpp(
1408             q{
1409                 namespace ns {
1410                     struct Struct;
1411 
1412                     template<typename T>
1413                     struct Template { };
1414 
1415                     // The `Struct` template parameter must be translated properly
1416                     // and was showing up as ns.Struct
1417                     class Class: public Template<Struct> {
1418                         int i;
1419                     };
1420                 }
1421             }
1422         ),
1423         D(
1424             q{
1425             }
1426         ),
1427     );
1428 }
1429 
1430 
1431 @Tags("issue")
1432 @("150")
1433 @safe unittest {
1434     shouldCompile(
1435         Cpp(
1436             q{
1437                 struct Foo {
1438                     int a, b, c;
1439                 };
1440 
1441                 struct Bar {
1442                     Foo& foo;
1443                 };
1444             }
1445         ),
1446         D(
1447             q{
1448                 import std.conv: text;
1449                 static assert(Foo.sizeof == 12, Foo.sizeof.text);
1450                 static assert(Foo.alignof == 4, Foo.alignof.text);
1451                 static assert(Bar.sizeof == 8, Bar.sizeof.text);
1452                 static assert(Bar.alignof == 8, Bar.alignof.text);
1453             }
1454         ),
1455     );
1456 }
1457 
1458 
1459 @Tags("issue")
1460 @("151")
1461 @safe unittest {
1462     shouldRun(
1463         Cpp(
1464             q{
1465                 struct Foo {
1466                     long data;
1467                 };
1468 
1469                 struct Bar {
1470                     static long numDtors;
1471                     long data;
1472                     ~Bar();
1473                 };
1474 
1475                 Foo makeFoo();
1476                 Bar makeBar();
1477             }
1478         ),
1479         Cpp(
1480             q{
1481                 Foo makeFoo() { return {}; }
1482                 Bar makeBar() { return {}; }
1483                 Bar::~Bar() { ++numDtors; }
1484                 long Bar::numDtors;
1485             }
1486         ),
1487         D(
1488             q{
1489                 import std.conv: text;
1490 
1491                 auto foo = makeFoo;
1492                 assert(foo.data == 0, foo.data.text);
1493 
1494                 {
1495                     auto bar = makeBar;
1496                     assert(bar.data == 0, bar.data.text);
1497                     bar.data = 42;
1498                     assert(bar.numDtors == 0, bar.numDtors.text);
1499                 }
1500 
1501                 assert(Bar.numDtors == 1, Bar.numDtors.text);
1502             }
1503         ),
1504     );
1505 }
1506 
1507 
1508 @("missing.template.parameter")
1509 @safe unittest {
1510     shouldCompile(
1511         Cpp(
1512             q{
1513                 namespace myns {
1514                     template<typename T>
1515                     struct vector {
1516                         T* elements;
1517                         long size;
1518                     };
1519                 }
1520 
1521                 struct Problem {
1522                     // In the issue this gets emitted as `vector values`
1523                     // instead of `vector!double values`
1524                     myns::vector<double> values;
1525                 };
1526 
1527                 Problem createProblem();
1528             }
1529         ),
1530         D(
1531             q{
1532             }
1533         ),
1534    );
1535 }