|
|
1.1 ! root 1: #include "cem.h" ! 2: #define STD_OBJ 1 ! 3: #include "stdobj.h" ! 4: #include "symbol.h" ! 5: #include "type.h" ! 6: ! 7: /* ! 8: * Type table routines. ! 9: */ ! 10: ! 11: extern char *strchr(); ! 12: ! 13: /* ! 14: * Comparison routines. "Identical type" equivalence. ! 15: * We believe file modtimes unless we are told to doubt. ! 16: */ ! 17: ! 18: static int ! 19: cmp_enum(p, q) ! 20: type *p; ! 21: type *q; ! 22: { ! 23: register e_data *e; ! 24: register e_data *f; ! 25: register e_elt *g; ! 26: register e_elt *h; ! 27: register int i; ! 28: ! 29: e = p->d.e; ! 30: f = q->d.e; ! 31: ! 32: if (modtimes && e->e_line == f->e_line && match_times(e->e_file, f->e_file)) ! 33: return 0; ! 34: ! 35: if (e->e_name != f->e_name) ! 36: { ! 37: if (e->e_name == NULL) ! 38: return -f->e_name->sy_index; ! 39: else if (f->e_name == NULL) ! 40: return e->e_name->sy_index; ! 41: else ! 42: return e->e_name->sy_index - f->e_name->sy_index; ! 43: } ! 44: ! 45: if ((i = e->e_low - f->e_low) != 0 || (i = e->e_high - f->e_high) != 0) ! 46: return i; ! 47: ! 48: g = e->e_list; ! 49: h = f->e_list; ! 50: ! 51: while (g != NULL) ! 52: { ! 53: if (h == NULL) ! 54: return -1; ! 55: ! 56: if (g->e_name != h->e_name) ! 57: return g->e_name->sy_index - h->e_name->sy_index; ! 58: ! 59: if ((i = g->e_value - h->e_value) != 0) ! 60: return i; ! 61: ! 62: g = g->e_next; ! 63: h = h->e_next; ! 64: } ! 65: ! 66: if (h != NULL) ! 67: return 1; ! 68: ! 69: return 0; ! 70: } ! 71: ! 72: static int ! 73: cmp_struct(p, q) ! 74: type *p; ! 75: type *q; ! 76: { ! 77: register s_data *e; ! 78: register s_data *f; ! 79: register s_elt *g; ! 80: register s_elt *h; ! 81: register int i; ! 82: ! 83: e = p->d.s; ! 84: f = q->d.s; ! 85: ! 86: if (modtimes && e->s_line == f->s_line && match_times(e->s_file, f->s_file)) ! 87: return 0; ! 88: ! 89: if (e->s_name != f->s_name) ! 90: { ! 91: if (e->s_name == NULL) ! 92: return -f->s_name->sy_index; ! 93: else if (f->s_name == NULL) ! 94: return e->s_name->sy_index; ! 95: else ! 96: return e->s_name->sy_index - f->s_name->sy_index; ! 97: } ! 98: ! 99: if ((i = e->s_size - f->s_size) != 0) ! 100: return i; ! 101: ! 102: g = e->s_list; ! 103: h = f->s_list; ! 104: ! 105: while (g != NULL) ! 106: { ! 107: if (h == NULL) ! 108: return -1; ! 109: ! 110: if (g->s_name != h->s_name) ! 111: return g->s_name->sy_index - h->s_name->sy_index; ! 112: ! 113: if (g->s_type != h->s_type) ! 114: return g->s_type->t_index - h->s_type->t_index; ! 115: ! 116: g = g->s_next; ! 117: h = h->s_next; ! 118: } ! 119: ! 120: if (h != NULL) ! 121: return 1; ! 122: ! 123: return 0; ! 124: } ! 125: ! 126: static int ! 127: cmp_union(p, q) ! 128: type *p; ! 129: type *q; ! 130: { ! 131: register u_data *e; ! 132: register u_data *f; ! 133: register u_elt *g; ! 134: register u_elt *h; ! 135: register int i; ! 136: ! 137: e = p->d.u; ! 138: f = q->d.u; ! 139: ! 140: if (modtimes && e->u_line == f->u_line && match_times(e->u_file, f->u_file)) ! 141: return 0; ! 142: ! 143: if (e->u_name != f->u_name) ! 144: { ! 145: if (e->u_name == NULL) ! 146: return -f->u_name->sy_index; ! 147: else if (f->u_name == NULL) ! 148: return e->u_name->sy_index; ! 149: else ! 150: return e->u_name->sy_index - f->u_name->sy_index; ! 151: } ! 152: ! 153: if ((i = e->u_size - f->u_size) != 0) ! 154: return i; ! 155: ! 156: g = e->u_list; ! 157: h = f->u_list; ! 158: ! 159: while (g != NULL) ! 160: { ! 161: if (h == NULL) ! 162: return -1; ! 163: ! 164: if (g->u_name != h->u_name) ! 165: return g->u_name->sy_index - h->u_name->sy_index; ! 166: ! 167: if (g->u_type != h->u_type) ! 168: return g->u_type->t_index - h->u_type->t_index; ! 169: ! 170: g = g->u_next; ! 171: h = h->u_next; ! 172: } ! 173: ! 174: if (h != NULL) ! 175: return 1; ! 176: ! 177: return 0; ! 178: } ! 179: ! 180: /* ! 181: * We win a lot by trusting the file/modtime linenumber ! 182: * of a struct/unions declaration. ! 183: */ ! 184: #define THASHSZ 37 ! 185: #define TPRIME0 7 ! 186: #define TPRIME1 31 ! 187: ! 188: /* ! 189: * Type hashing by filename/modtime and line number. ! 190: */ ! 191: static type * ! 192: type_hash(h0, h1, t) ! 193: long h0; ! 194: long h1; ! 195: type *t; ! 196: { ! 197: typedef struct thash thash; ! 198: ! 199: struct thash ! 200: { ! 201: long h0; ! 202: long h1; ! 203: type *t; ! 204: thash *next; ! 205: }; ! 206: ! 207: register long i; ! 208: register thash *p; ! 209: static thash *thasht[THASHSZ]; ! 210: ! 211: i = TPRIME0 * h0 + TPRIME1 * h1; ! 212: ! 213: if (i < 0) ! 214: i = -i; ! 215: ! 216: i %= THASHSZ; ! 217: ! 218: for (p = thasht[i]; p != NULL; p = p->next) ! 219: { ! 220: if (p->h0 == h0 && p->h1 == h1) ! 221: return p->t; ! 222: ! 223: } ! 224: ! 225: if (t == NULL) ! 226: return NULL; ! 227: ! 228: p = talloc(thash); ! 229: p->h0 = h0; ! 230: p->h1 = h1; ! 231: p->t = t; ! 232: p->next = thasht[i]; ! 233: thasht[i] = p; ! 234: return t; ! 235: } ! 236: ! 237: /* ! 238: * Lookup a type hashing by filename/modtime and line number. ! 239: */ ! 240: type * ! 241: lookup_hash(s, l) ! 242: symbol *s; ! 243: long l; ! 244: { ! 245: if (modtimes && strchr(s->sy_name, TIME_SEP) != NULL) ! 246: return type_hash(s->sy_index, l, (type *)NULL); ! 247: else ! 248: return NULL; ! 249: } ! 250: ! 251: /* ! 252: * Enter a type hashing by filename/modtime and line number. ! 253: */ ! 254: void ! 255: enter_hash(s, l, t) ! 256: symbol *s; ! 257: long l; ! 258: type *t; ! 259: { ! 260: if (modtimes && strchr(s->sy_name, TIME_SEP) != NULL) ! 261: type_hash(s->sy_index, l, t); ! 262: } ! 263: ! 264: /* ! 265: * Type table manager. Pass it a type and it will return you the ! 266: * (strongly) equivalent type that characterises it. i.e. it ! 267: * 'interns' a type. Type comparison is then pointer comparison. ! 268: */ ! 269: type * ! 270: find_type(t) ! 271: register type *t; ! 272: { ! 273: typedef struct ttnode ttnode; ! 274: ! 275: struct ttnode ! 276: { ! 277: type *tt_type; ! 278: ttnode *tt_left; ! 279: ttnode *tt_right; ! 280: }; ! 281: ! 282: register type *p; ! 283: register type *q; ! 284: register int i; ! 285: register ttnode **n; ! 286: register ttnode *tt; ! 287: ! 288: static ttnode *type_table[(int)t_types]; ! 289: ! 290: n = &type_table[(int)t->t_type]; ! 291: ! 292: while (*n != NULL) ! 293: { ! 294: p = t; ! 295: q = (*n)->tt_type; ! 296: ! 297: if ((i = ((int)p->t_type) - ((int)q->t_type)) == 0) ! 298: { ! 299: switch (p->t_type) ! 300: { ! 301: case t_arrayof: ! 302: if ((i = p->d.dim - q->d.dim) == 0) ! 303: i = p->t_subtype->t_index - q->t_subtype->t_index; ! 304: ! 305: break; ! 306: ! 307: case t_basetype: ! 308: i = p->d.mask - q->d.mask; ! 309: break; ! 310: ! 311: case t_bitfield: ! 312: if ((i = p->d.size - q->d.size) == 0) ! 313: i = p->t_subtype->t_index - q->t_subtype->t_index; ! 314: ! 315: break; ! 316: ! 317: case t_dimless: ! 318: case t_ftnreturning: ! 319: case t_ptrto: ! 320: i = p->t_subtype->t_index - q->t_subtype->t_index; ! 321: break; ! 322: ! 323: case t_enum: ! 324: i = cmp_enum(p, q); ! 325: break; ! 326: ! 327: case t_structof: ! 328: i = cmp_struct(p, q); ! 329: break; ! 330: ! 331: case t_unionof: ! 332: i = cmp_union(p, q); ! 333: break; ! 334: ! 335: default: ! 336: fprintf(stderr, "%s: find_type - bad type\n", my_name); ! 337: exit(1); ! 338: } ! 339: ! 340: if (i == 0) ! 341: { ! 342: delete_type(t); ! 343: return (*n)->tt_type; ! 344: } ! 345: } ! 346: ! 347: n = i < 0 ? &((*n)->tt_left) : &((*n)->tt_right); ! 348: } ! 349: ! 350: switch (t->t_type) ! 351: { ! 352: case t_structof: ! 353: enter_hash(t->d.s->s_file, t->d.s->s_line, t); ! 354: break; ! 355: ! 356: case t_unionof: ! 357: enter_hash(t->d.u->u_file, t->d.u->u_line, t); ! 358: } ! 359: ! 360: tt = talloc(ttnode); ! 361: *n = tt; ! 362: tt->tt_type = t; ! 363: tt->tt_left = NULL; ! 364: tt->tt_right = NULL; ! 365: t->t_index = new_type_index++; ! 366: return t; ! 367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.