1 // REQUIRED_ARGS: -extern-std=c++98
2 
3 // This file is intended to contain all compilable traits-related tests in an
4 // effort to keep the number of files in the `compilable` folder to a minimum.
5 
6 // https://issues.dlang.org/show_bug.cgi?id=19152
7 module traits;
8 
9 class C19152
10 {
11     int OnExecute()
12     {
13         auto name = __traits(getOverloads, this, "OnExecute").stringof;
14         return 0;
15     }
16 }
17 
18 static assert(is(typeof(__traits(getTargetInfo, "cppRuntimeLibrary")) == string));
19 version (CppRuntime_Microsoft)
20 {
21     static assert(__traits(getTargetInfo, "cppRuntimeLibrary") == "libcmt" ||
22                   __traits(getTargetInfo, "cppRuntimeLibrary")[0..6] == "msvcrt"); // includes mingw import libs
23 }
24 
25 version (D_HardFloat)
26     static assert(__traits(getTargetInfo, "floatAbi") == "hard");
27 
28 version (Win64)
29     static assert(__traits(getTargetInfo, "objectFormat") == "coff");
30 version (OSX)
31     static assert(__traits(getTargetInfo, "objectFormat") == "macho");
32 version (linux)
33     static assert(__traits(getTargetInfo, "objectFormat") == "elf");
34 
35 static assert(__traits(getTargetInfo, "cppStd") == 199711);
36 
37 import imports.plainpackage.plainmodule;
38 import imports.pkgmodule.plainmodule;
39 
40 struct MyStruct;
41 
42 alias a = imports.plainpackage;
43 alias b = imports.pkgmodule.plainmodule;
44 
45 static assert(__traits(isPackage, imports.plainpackage));
46 static assert(__traits(isPackage, a));
47 static assert(!__traits(isPackage, imports.plainpackage.plainmodule));
48 static assert(!__traits(isPackage, b));
49 static assert(__traits(isPackage, imports.pkgmodule));
50 static assert(!__traits(isPackage, MyStruct));
51 
52 static assert(!__traits(isModule, imports.plainpackage));
53 static assert(!__traits(isModule, a));
54 static assert(__traits(isModule, imports.plainpackage.plainmodule));
55 static assert(__traits(isModule, b));
56 // This is supposed to work even though we haven't directly imported imports.pkgmodule.
57 static assert(__traits(isModule, imports.pkgmodule));
58 static assert(!__traits(isModule, MyStruct));
59 
60 /******************************************/
61 // https://issues.dlang.org/show_bug.cgi?id=19942
62 
63 static assert(!__traits(compiles, { a.init; }));
64 static assert(!__traits(compiles, { import m : a; a.init; }));
65 
66 version(Windows)
67     static assert(__traits(getLocation, MyStruct)[0] == `compilable\traits.d`);
68 else
69     static assert(__traits(getLocation, MyStruct)[0] == "compilable/traits.d");
70 static assert(__traits(getLocation, MyStruct)[1] == 40);
71 static assert(__traits(getLocation, MyStruct)[2] == 1);
72 
73 int foo();
74 int foo(int);
75 
76 static assert(__traits(getLocation, __traits(getOverloads, traits, "foo")[1])[1] == 74);
77 
78 mixin("int bar;");
79 static assert(__traits(getLocation, bar)[1] == 78);
80 
81 struct Outer
82 {
83     struct Nested{}
84 
85     void method() {}
86 }
87 static assert(__traits(getLocation, Outer.Nested)[1] == 83);
88 static assert(__traits(getLocation, Outer.method)[1] == 85);
89 
90 /******************************************/
91 // https://issues.dlang.org/show_bug.cgi?id=19902
92 // Define hasElaborateCopyConstructor trait
93 // but done as two independent traits per conversation
94 // in https://github.com/dlang/dmd/pull/10265
95 
96 struct S
97 {
98     this (ref S rhs) {}
99 }
100 
101 struct OuterS
102 {
103     struct S
104     {
105         this (ref S rhs) {}
106     }
107 
108     S s;
109 }
110 
111 void foo(T)()
112 {
113     struct S(U)
114     {
115         this (ref S rhs) {}
116     }
117     static assert (__traits(hasCopyConstructor, S!int));
118 }
119 
120 struct U(T)
121 {
122     this (ref U rhs) {}
123 }
124 
125 struct SPostblit
126 {
127     this(this) {}
128 }
129 
130 struct NoCpCtor { }
131 class C19902 { }
132 
133 static assert(__traits(hasCopyConstructor, S));
134 static assert(__traits(hasCopyConstructor, OuterS.S));
135 static assert(__traits(hasCopyConstructor, OuterS));
136 static assert(__traits(compiles, foo!int));
137 static assert(__traits(compiles, foo!S));
138 static assert(__traits(hasCopyConstructor, U!int));
139 static assert(__traits(hasCopyConstructor, U!S));
140 static assert(!__traits(hasPostblit, U!S));
141 static assert(__traits(hasPostblit, SPostblit));
142 static assert(!__traits(hasCopyConstructor, SPostblit));
143 
144 static assert(!__traits(hasCopyConstructor, NoCpCtor));
145 static assert(!__traits(hasCopyConstructor, C19902));
146 static assert(!__traits(hasCopyConstructor, int));
147 static assert(!__traits(hasPostblit, NoCpCtor));
148 static assert(!__traits(hasPostblit, C19902));
149 static assert(!__traits(hasPostblit, int));
150 
151 // Check that invalid use cases don't compile
152 static assert(!__traits(compiles, __traits(hasCopyConstructor)));
153 static assert(!__traits(compiles, __traits(hasCopyConstructor, S())));
154 static assert(!__traits(compiles, __traits(hasPostblit)));
155 static assert(!__traits(compiles, __traits(hasPostblit, S())));