1ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#include <stdio.h> 2ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#include <stdlib.h> 3ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 4ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#define N_FIELDS 7 5ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#define N_FUNCS 128 6ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#define FUNCSPACING 20 7ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#define N_STRUCTS 180 /* 1280 */ 8ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#define N_BASES 6 9ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao#define COVARIANT 0 10ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 11ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoconst char *simple_types[] = { "bool", "char", "short", "int", "float", 12ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao "double", "long double", "wchar_t", "void *", 13ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao "char *" 14ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao}; 15ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 16ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaovoid gl(const char *c) { 17ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf("%s\n", c); 18ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao} 19ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 20ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaovoid g(const char *c) { 21ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf("%s", c); 22ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao} 23ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 24ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaovoid g(int i) { 25ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf("%d", i); 26ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao} 27ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 28ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoint uuid = 0; 29ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaochar base_present[N_STRUCTS][N_STRUCTS]; 30ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 31ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// The return type for each function when doing covariant testcase generation. 32ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoshort ret_types[N_STRUCTS][N_FUNCS*FUNCSPACING]; 33ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 34ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaobool is_ambiguous(int s, int base) { 35ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < N_STRUCTS; ++i) { 36ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if ((base_present[base][i] & base_present[s][i]) == 1) 37ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao return true; 38ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 39ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao return false; 40ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao} 41ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 42ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaovoid add_bases(int s, int base) { 43ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < N_STRUCTS; ++i) 44ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao base_present[s][i] |= base_present[base][i]; 45ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (!COVARIANT) 46ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao return; 47ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < N_FUNCS*FUNCSPACING; ++i) { 48ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (!ret_types[base][i]) 49ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 50ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (!ret_types[s][i]) { 51ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_types[s][i] = ret_types[base][i]; 52ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 53ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 54ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (base_present[ret_types[base][i]][ret_types[s][i]]) 55ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // If the return type of the function from this base dominates 56ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_types[s][i] = ret_types[base][i]; 57ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (base_present[ret_types[s][i]][ret_types[base][i]]) 58ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // If a previous base dominates 59ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 60ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // If neither dominates, we'll use this class. 61ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_types[s][i] = s; 62ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 63ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao} 64ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 65ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// This contains the class that has the final override for 66ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao// each class, for each function. 67ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaoshort final_override[N_STRUCTS][N_FUNCS*FUNCSPACING]; 68ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 69ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaovoid gs(int s) { 70ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao bool polymorphic = false; 71ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 72ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao static int bases[N_BASES]; 73ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int i_bases = random() % (N_BASES*2); 74ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (i_bases >= N_BASES) 75ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // PARAM: 1/2 of all clases should have no bases 76ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao i_bases = 0; 77ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int n_bases = 0; 78ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao bool first_base = true; 79ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 80ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // PARAM: 3/4 of all should be class, the rest are structs 81ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (random() % 4 == 0) 82ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("struct s"); 83ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao else 84ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("class s"); 85ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(s); 86ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int old_base = -1; 87ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (s == 0 || s == 1) 88ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao i_bases = 0; 89ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao while (i_bases) { 90ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao --i_bases; 91ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int base = random() % (s-1) + 1; 92ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (!base_present[s][base]) { 93ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (is_ambiguous(s, base)) 94ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 95ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (first_base) { 96ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao first_base = false; 97ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(": "); 98ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } else 99ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(", "); 100ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int base_type = 1; 101ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (random()%8 == 0) { 102ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // PARAM: 1/8th the bases are virtual 103ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("virtual "); 104ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // We have a vtable and rtti, but technically we're not polymorphic 105ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // polymorphic = true; 106ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao base_type = 3; 107ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 108ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // PARAM: 1/4 are public, 1/8 are privare, 1/8 are protected, the reset, default 109ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int base_protection = 0; 110ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (!COVARIANT) 111ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao base_protection = random()%8; 112ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao switch (base_protection) { 113ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 0: 114ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 1: 115ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("public "); break; 116ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 2: 117ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 3: 118ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 4: 119ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 5: 120ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao break; 121ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 6: 122ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("private "); break; 123ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao case 7: 124ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("protected "); break; 125ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 126ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("s"); 127ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao add_bases(s, base); 128ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao bases[n_bases] = base; 129ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao base_present[s][base] = base_type; 130ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ++n_bases; 131ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(base); 132ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao old_base = base; 133ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 134ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 135ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" {"); 136ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 137ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao /* Fields */ 138ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int n_fields = N_FIELDS == 0 ? 0 : random() % (N_FIELDS*4); 139ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // PARAM: 3/4 of all structs should have no members 140ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (n_fields >= N_FIELDS) 141ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao n_fields = 0; 142ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_fields; ++i) { 143ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int t = random() % (sizeof(simple_types) / sizeof(simple_types[0])); 144ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" "); g(simple_types[t]); g(" field"); g(i); gl(";"); 145ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 146ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 147ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao /* Virtual functions */ 148ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao static int funcs[N_FUNCS*FUNCSPACING]; 149ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // PARAM: 1/2 of all structs should have no virtual functions 150ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int n_funcs = random() % (N_FUNCS*2); 151ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (n_funcs > N_FUNCS) 152ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao n_funcs = 0; 153ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int old_func = -1; 154ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_funcs; ++i) { 155ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int fn = old_func + random() % FUNCSPACING + 1; 156ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao funcs[i] = fn; 157ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int ret_type = 0; 158ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (COVARIANT) { 159ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_type = random() % s + 1; 160ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (!base_present[s][ret_type] 161ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao || !base_present[ret_type][ret_types[s][fn]]) 162ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (ret_types[s][fn]) { 163ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf(" // Found one for s%d for s%d* fun%d.\n", s, 164ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_types[s][fn], fn); 165ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_type = ret_types[s][fn]; 166ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } else 167ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_type = s; 168ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao else 169ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf(" // Wow found one for s%d for fun%d.\n", s, fn); 170ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_types[s][fn] = ret_type; 171ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 172ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (ret_type) { 173ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" virtual s"); g(ret_type); g("* fun"); 174ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } else 175ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" virtual void fun"); 176ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); 177ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (ret_type) 178ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("); return 0; }"); 179ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao else 180ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("); }"); 181ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao final_override[s][fn] = s; 182ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao old_func = fn; 183ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 184ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 185ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // Add required overriders for correctness 186ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_bases; ++i) { 187ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // For each base 188ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int base = bases[i]; 189ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int fn = 0; fn < N_FUNCS*FUNCSPACING; ++fn) { 190ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // For each possible function 191ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int new_base = final_override[base][fn]; 192ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (new_base == 0) 193ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // If the base didn't have a final overrider, skip 194ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 195ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 196ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int prev_base = final_override[s][fn]; 197ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (prev_base == s) 198ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // Skip functions defined in this class 199ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 200ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 201ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // If we don't want to change the info, skip 202ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (prev_base == new_base) 203ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 204ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 205ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (prev_base == 0) { 206ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // record the final override 207ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao final_override[s][fn] = new_base; 208ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 209ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 210ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 211ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (base_present[prev_base][new_base]) { 212ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // The previous base dominates the new base, no update necessary 213ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", 214ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao fn, s, prev_base, new_base); 215ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 216ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 217ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 218ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (base_present[new_base][prev_base]) { 219ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // The new base dominates the old base, no override necessary 220ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf(" // No override for fun%d in s%d as s%d dominates s%d.\n", 221ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao fn, s, new_base, prev_base); 222ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // record the final override 223ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao final_override[s][fn] = new_base; 224ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao continue; 225ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 226ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 227ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf(" // Found we needed override for fun%d in s%d.\n", fn, s); 228ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 229ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // record the final override 230ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao funcs[n_funcs++] = fn; 231ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (n_funcs == (N_FUNCS*FUNCSPACING-1)) 232ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao abort(); 233ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int ret_type = 0; 234ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (COVARIANT) { 235ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (!ret_types[s][fn]) { 236ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_types[s][fn] = ret_type = s; 237ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } else { 238ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao ret_type = ret_types[s][fn]; 239ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (ret_type != s) 240ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao printf(" // Calculated return type in s%d as s%d* fun%d.\n", 241ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao s, ret_type, fn); 242ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 243ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 244ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (ret_type) { 245ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" virtual s"); g(ret_type); g("* fun"); 246ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } else 247ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" virtual void fun"); 248ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(fn); g("(char *t) { mix(\"vfn this offset\", (char *)this - t); mix(\"vfn uuid\", "); g(++uuid); 249ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (ret_type) 250ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("); return 0; }"); 251ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao else 252ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("); }"); 253ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao final_override[s][fn] = s; 254ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 255ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 256ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 257ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("public:"); 258ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" void calc(char *t) {"); 259ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 260ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // mix in the type number 261ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" mix(\"type num\", "); g(s); gl(");"); 262ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // mix in the size 263ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" mix(\"type size\", sizeof (s"); g(s); gl("));"); 264ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // mix in the this offset 265ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" mix(\"subobject offset\", (char *)this - t);"); 266ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (n_funcs) 267ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao polymorphic = true; 268ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (polymorphic) { 269ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // mix in offset to the complete object under construction 270ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" mix(\"real top v current top\", t - (char *)dynamic_cast<void*>(this));"); 271ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 272ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 273ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao /* check base layout and overrides */ 274ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_bases; ++i) { 275ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" calc_s"); g(bases[i]); gl("(t);"); 276ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 277ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 278ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (polymorphic) { 279ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao /* check dynamic_cast to each direct base */ 280ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_bases; ++i) { 281ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" if ((char *)dynamic_cast<s"); g(bases[i]); gl("*>(this))"); 282ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" mix(\"base dyn cast\", t - (char *)dynamic_cast<s"); g(bases[i]); gl("*>(this));"); 283ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" else mix(\"no dyncast\", "); g(++uuid); gl(");"); 284ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 285ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 286ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 287ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao /* check field layout */ 288ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_fields; ++i) { 289ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" mix(\"field offset\", (char *)&field"); g(i); gl(" - (char *)this);"); 290ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 291ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (n_fields == 0) { 292ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" mix(\"no fields\", "); g(++uuid); gl(");"); 293ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 294ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 295ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao /* check functions */ 296ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_funcs; ++i) { 297ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" fun"); g(funcs[i]); gl("(t);"); 298ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 299ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (n_funcs == 0) { 300ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" mix(\"no funcs\", "); g(++uuid); gl(");"); 301ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 302ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 303ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" }"); 304ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 305ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // default ctor 306ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" s"); g(s); g("() "); 307ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao first_base = true; 308ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 0; i < n_bases; ++i) { 309ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (first_base) { 310ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(": "); 311ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao first_base = false; 312ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } else 313ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(", "); 314ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("s"); g(bases[i]); g("((char *)this)"); 315ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao } 316ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" { calc((char *)this); }"); 317ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" ~s"); g(s); gl("() { calc((char *)this); }"); 318ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 319ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // ctor with this to the complete object 320ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" s"); g(s); gl("(char *t) { calc(t); }"); 321ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g(" void calc_s"); g(s); gl("(char *t) { calc(t); }"); 322ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao g("} a"); g(s); gl(";"); 323ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao} 324ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 325ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liaomain(int argc, char **argv) { 326ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao unsigned seed = 0; 327ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao char state[16]; 328ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao if (argc > 1) 329ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao seed = atol(argv[1]); 330ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao 331ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao initstate(seed, state, sizeof(state)); 332ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("extern \"C\" int printf(const char *...);"); 333ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(""); 334ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("long long sum;"); 335ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("void mix(const char *desc, long long i) {"); 336ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // If this ever becomes too slow, we can remove this after we improve the 337ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // mixing function 338ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" printf(\"%s: %lld\\n\", desc, i);"); 339ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" sum += ((sum ^ i) << 3) + (sum<<1) - i;"); 340ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("}"); 341ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(""); 342ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao // PARAM: Randomly size testcases or large testcases? 343ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao int n_structs = /* random() % */ N_STRUCTS; 344ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao for (int i = 1; i < n_structs; ++i) 345ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gs(i); 346ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("int main() {"); 347ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl(" printf(\"%llx\\n\", sum);"); 348ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao gl("}"); 349ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao return 0; 350ea285162342df160e7860e26528bc7110bc6c0cdShih-wei Liao} 351