blob: f11886582eb2f45aaeb15b200f22084df2b7f113 [file] [log] [blame]
Mike Stump46ae64f2010-01-07 18:58:28 +00001#include <stdio.h>
2#include <stdlib.h>
3
4#define N_FIELDS 7
5#define N_FUNCS 128
6#define FUNCSPACING 10
7#define N_STRUCTS 300 /* 1280 */
8// FIXME: Need final overrider logic for 3 or more if we turn on virtual base
9// class dups
10#define N_BASES 30 /* 30 */
11
12const char *simple_types[] = { "bool", "char", "short", "int", "float",
13 "double", "long double", "wchar_t", "void *",
14 "char *"
15};
16
17void gl(const char *c) {
18 printf("%s\n", c);
19}
20
21void g(const char *c) {
22 printf("%s", c);
23}
24
25void g(int i) {
26 printf("%d", i);
27}
28
29int vfn = 0;
30char base_present[N_STRUCTS][N_STRUCTS];
31
32bool is_ambiguous(int s, int base) {
33 for (int i = 0; i < N_STRUCTS; ++i) {
34 if ((base_present[base][i] & base_present[s][i])
35 // FIXME: todo this, we need final overrider additions
36 /*== 1 */)
37 return true;
38 }
39 return false;
40}
41
42void add_bases(int s, int base) {
43 for (int i = 0; i < N_STRUCTS; ++i)
44 base_present[s][i] |= base_present[base][i];
45}
46
47void gs(int s) {
48 bool polymorphic = false;
49
50 static int bases[N_BASES];
51 int i_bases = random() % (N_BASES*2);
52 if (i_bases >= N_BASES)
53 // PARAM: 1/2 of all clases should have no bases
54 i_bases = 0;
55 int n_bases = 0;
56 bool first_base = true;
57
58 // PARAM: 3/4 of all should be class, the rest are structs
59 if (random() % 4 == 0)
60 g("struct s");
61 else
62 g("class s");
63 g(s);
64 int old_base = -1;
65 if (s == 0)
66 i_bases = 0;
67 while (i_bases) {
68 --i_bases;
69 int base = random() % s;
70 if (!base_present[s][base]) {
71 if (is_ambiguous(s, base))
72 continue;
73 if (first_base) {
74 first_base = false;
75 g(": ");
76 } else
77 g(", ");
78 int base_type = 1;
79 if (random()%8 == 0) {
80 // PARAM: 1/8th the bases are virtual
81 g("virtual ");
82 polymorphic = true;
83 base_type = 3;
84 }
85 switch (random()%8) {
86 case 0:
87 case 1:
88 case 2:
89 case 3:
90 break;
91 case 4:
92 case 5:
93 g("public "); break;
94 case 6:
95 g("private "); break;
96 case 7:
97 g("protected "); break;
98 }
99 g("s");
100 add_bases(s, base);
101 bases[n_bases] = base;
102 base_present[s][base] = base_type;
103 ++n_bases;
104 g(base);
105 old_base = base;
106 }
107 }
108 gl(" {");
109
110 /* Fields */
111 int n_fields = random() % (N_FIELDS*4);
112 // PARAM: 3/4 of all structs should have no members
113 if (n_fields >= N_FIELDS)
114 n_fields = 0;
115 for (int i = 0; i < n_fields; ++i) {
116 int t = random() % (sizeof(simple_types) / sizeof(simple_types[0]));
117 g(" "); g(simple_types[t]); g(" field"); g(i); gl(";");
118 }
119
120 /* Virtual functions */
121 static int funcs[N_FUNCS];
122 int n_funcs = random() % N_FUNCS;
123 int old_func = -1;
124 for (int i = 0; i < n_funcs; ++i) {
125 int fn = old_func + random() % FUNCSPACING + 1;
126 funcs[i] = fn;
127 g(" virtual void fun"); g(fn); g("(char *t) { mix((char *)this - t, "); g(++vfn); gl("); }");
128 old_func = fn;
129 }
130
131 gl("public:");
132 gl(" void calc(char *t) {");
133
134 // mix in the type number
135 g(" mix("); g(s); gl(");");
136 // mix in the size
137 g(" mix(sizeof (s"); g(s); gl("));");
138 // mix in the this offset
139 gl(" mix((char *)this - t);");
140 if (n_funcs)
141 polymorphic = true;
142 if (polymorphic) {
143 // mix in offset to the complete object under construction
144 gl(" mix(t - (char *)dynamic_cast<void*>(this));");
145 }
146
147 /* check base layout and overrides */
148 for (int i = 0; i < n_bases; ++i) {
149 g(" calc_s"); g(bases[i]); gl("(t);");
150 }
151
152 if (polymorphic) {
153 /* check dynamic_cast to each direct base */
154 for (int i = 0; i < n_bases; ++i) {
155 g(" if ((char *)dynamic_cast<s"); g(bases[i]); gl("*>(this))");
156 g(" mix(t - (char *)dynamic_cast<s"); g(bases[i]); gl("*>(this));");
157 gl(" else mix(666);");
158 }
159 }
160
161 /* check field layout */
162 for (int i = 0; i < n_fields; ++i) {
163 g(" mix((char *)&field"); g(i); gl(" - (char *)this);");
164 }
165 if (n_fields == 0)
166 gl(" mix(42);");
167
168 /* check functions */
169 for (int i = 0; i < n_funcs; ++i) {
170 g(" fun"); g(funcs[i]); gl("(t);");
171 }
172 if (n_funcs == 0)
173 gl(" mix(13);");
174
175 gl(" }");
176
177 // default ctor
178 g(" s"); g(s); g("() ");
179 first_base = true;
180 for (int i = 0; i < n_bases; ++i) {
181 if (first_base) {
182 g(": ");
183 first_base = false;
184 } else
185 g(", ");
186 g("s"); g(bases[i]); g("((char *)this)");
187 }
188 gl(" { calc((char *)this); }");
189 g(" ~s"); g(s); gl("() { calc((char *)this); }");
190
191 // ctor with this to the complete object
192 g(" s"); g(s); gl("(char *t) { calc(t); }");
193 g(" void calc_s"); g(s); gl("(char *t) { calc(t); }");
194 g("} a"); g(s); gl(";");
195}
196
197main(int argc, char **argv) {
198 unsigned seed = 0;
199 char state[16];
200 if (argc > 1)
201 seed = atol(argv[1]);
202
203 initstate(seed, state, sizeof(state));
204 gl("extern \"C\" int printf(const char *...);");
205 gl("");
206 gl("long long sum;");
207 gl("void mix(long long i) {");
208 // If this ever becomes too slow, we can remove this after we improve the
209 // mixing function
210 gl(" printf(\"%llx\\n\", i);");
211 gl(" sum += ((sum ^ i) << 3) + (sum<<1) - i;");
212 gl("}");
213 gl("void mix(long long i1, long long i2) { mix(i1); mix(i2); }");
214 gl("");
215 // PARAM: Randomly size testcases or large testcases?
216 int n_structs = /* random() % */ N_STRUCTS;
217 for (int i = 0; i < n_structs; ++i)
218 gs(i);
219 gl("int main() {");
220 gl(" printf(\"%llx\\n\", sum);");
221 gl("}");
222 return 0;
223}