1*770Speter /* Copyright (c) 1979 Regents of the University of California */ 2*770Speter 3*770Speter static char sccsid[] = "@(#)rec.c 1.1 08/27/80"; 4*770Speter 5*770Speter #include "whoami.h" 6*770Speter #include "0.h" 7*770Speter #include "tree.h" 8*770Speter #include "opcode.h" 9*770Speter 10*770Speter /* 11*770Speter * Build a record namelist entry. 12*770Speter * Some of the processing here is somewhat involved. 13*770Speter * The basic structure we are building is as follows. 14*770Speter * 15*770Speter * Each record has a main RECORD entry, with an attached 16*770Speter * chain of fields as ->chain; these include all the fields in all 17*770Speter * the variants of this record. 18*770Speter * 19*770Speter * Attached to NL_VARNT is a chain of VARNT structures 20*770Speter * describing each of the variants. These are further linked 21*770Speter * through ->chain. Each VARNT has, in ->range[0] the value of 22*770Speter * the associated constant, and each points at a RECORD describing 23*770Speter * the subrecord through NL_VTOREC. These pointers are not unique, 24*770Speter * more than one VARNT may reference the same RECORD. 25*770Speter * 26*770Speter * The involved processing here is in computing the NL_OFFS entry 27*770Speter * by maxing over the variants. This works as follows. 28*770Speter * 29*770Speter * Each RECORD has two size counters. NL_OFFS is the maximum size 30*770Speter * so far of any variant of this record; NL_FLDSZ gives the size 31*770Speter * of just the FIELDs to this point as a base for further variants. 32*770Speter * 33*770Speter * As we process each variant record, we start its size with the 34*770Speter * NL_FLDSZ we have so far. After processing it, if its NL_OFFS 35*770Speter * is the largest so far, we update the NL_OFFS of this subrecord. 36*770Speter * This will eventually propagate back and update the NL_OFFS of the 37*770Speter * entire record. 38*770Speter */ 39*770Speter 40*770Speter /* 41*770Speter * P0 points to the outermost RECORD for name searches. 42*770Speter */ 43*770Speter struct nl *P0; 44*770Speter 45*770Speter tyrec(r, off) 46*770Speter int *r, off; 47*770Speter { 48*770Speter 49*770Speter return tyrec1(r, off, 1); 50*770Speter } 51*770Speter 52*770Speter /* 53*770Speter * Define a record namelist entry. 54*770Speter * R is the tree for the record to be built. 55*770Speter * Off is the offset for the first item in this (sub)record. 56*770Speter */ 57*770Speter struct nl * 58*770Speter tyrec1(r, off, first) 59*770Speter register int *r; 60*770Speter int off; 61*770Speter char first; 62*770Speter { 63*770Speter register struct nl *p, *P0was; 64*770Speter 65*770Speter p = defnl(0, RECORD, 0, 0); 66*770Speter P0was = P0; 67*770Speter if (first) 68*770Speter P0 = p; 69*770Speter #ifndef PI0 70*770Speter p->value[NL_FLDSZ] = p->value[NL_OFFS] = off; 71*770Speter #endif 72*770Speter if (r != NIL) { 73*770Speter fields(p, r[2]); 74*770Speter variants(p, r[3]); 75*770Speter } 76*770Speter /* 77*770Speter * round the lengths of records up to their alignments 78*770Speter */ 79*770Speter p -> value[ NL_OFFS ] = roundup( p -> value[ NL_OFFS ] , align( p ) ); 80*770Speter P0 = P0was; 81*770Speter return (p); 82*770Speter } 83*770Speter 84*770Speter /* 85*770Speter * Define the fixed part fields for p. 86*770Speter */ 87*770Speter struct nl * 88*770Speter fields(p, r) 89*770Speter struct nl *p; 90*770Speter int *r; 91*770Speter { 92*770Speter register int *fp, *tp, *ip; 93*770Speter struct nl *jp; 94*770Speter 95*770Speter for (fp = r; fp != NIL; fp = fp[2]) { 96*770Speter tp = fp[1]; 97*770Speter if (tp == NIL) 98*770Speter continue; 99*770Speter jp = gtype(tp[3]); 100*770Speter line = tp[1]; 101*770Speter for (ip = tp[2]; ip != NIL; ip = ip[2]) 102*770Speter deffld(p, ip[1], jp); 103*770Speter } 104*770Speter } 105*770Speter 106*770Speter /* 107*770Speter * Define the variants for RECORD p. 108*770Speter */ 109*770Speter struct nl * 110*770Speter variants(p, r) 111*770Speter struct nl *p; 112*770Speter register int *r; 113*770Speter { 114*770Speter register int *vc, *v; 115*770Speter int *vr; 116*770Speter struct nl *ct; 117*770Speter 118*770Speter if (r == NIL) 119*770Speter return; 120*770Speter ct = gtype(r[3]); 121*770Speter if ( isnta( ct , "bcsi" ) ) { 122*770Speter error("Tag fields cannot be %ss" , nameof( ct ) ); 123*770Speter } 124*770Speter line = r[1]; 125*770Speter /* 126*770Speter * Want it even if r[2] is NIL so 127*770Speter * we check its type in "new" and "dispose" 128*770Speter * calls -- link it to NL_TAG. 129*770Speter */ 130*770Speter p->ptr[NL_TAG] = deffld(p, r[2], ct); 131*770Speter for (vc = r[4]; vc != NIL; vc = vc[2]) { 132*770Speter v = vc[1]; 133*770Speter if (v == NIL) 134*770Speter continue; 135*770Speter vr = tyrec1(v[3], p->value[NL_FLDSZ], 0); 136*770Speter #ifndef PI0 137*770Speter if (vr->value[NL_OFFS] > p->value[NL_OFFS]) 138*770Speter p->value[NL_OFFS] = vr->value[NL_OFFS]; 139*770Speter #endif 140*770Speter line = v[1]; 141*770Speter for (v = v[2]; v != NIL; v = v[2]) 142*770Speter defvnt(p, v[1], vr, ct); 143*770Speter } 144*770Speter } 145*770Speter 146*770Speter /* 147*770Speter * Define a field in subrecord p of record P0 148*770Speter * with name s and type t. 149*770Speter */ 150*770Speter struct nl * 151*770Speter deffld(p, s, t) 152*770Speter struct nl *p; 153*770Speter register char *s; 154*770Speter register struct nl *t; 155*770Speter { 156*770Speter register struct nl *fp; 157*770Speter 158*770Speter if (reclook(P0, s) != NIL) { 159*770Speter #ifndef PI1 160*770Speter error("%s is a duplicate field name in this record", s); 161*770Speter #endif 162*770Speter s = NIL; 163*770Speter } 164*770Speter #ifndef PI0 165*770Speter /* 166*770Speter * it used to be easy to keep track of offsets of fields 167*770Speter * and total sizes of records. 168*770Speter * but now, the offset of the field is aligned 169*770Speter * so only it knows it's offset, and calculating 170*770Speter * the total size of the record is based on it, 171*770Speter * rather than just the width of the field. 172*770Speter */ 173*770Speter fp = enter( defnl( s , FIELD , t , roundup( p -> value[ NL_OFFS ] 174*770Speter , align( t ) ) ) ); 175*770Speter #else 176*770Speter fp = enter(defnl(s, FIELD, t, 0)); 177*770Speter #endif 178*770Speter if (s != NIL) { 179*770Speter fp->chain = P0->chain; 180*770Speter P0->chain = fp; 181*770Speter #ifndef PI0 182*770Speter /* 183*770Speter * and the size of the record is incremented. 184*770Speter */ 185*770Speter p -> value[ NL_OFFS ] = fp -> value[ NL_OFFS ] 186*770Speter + even( width( t ) ); 187*770Speter p -> value[ NL_FLDSZ ] = p -> value[ NL_OFFS ]; 188*770Speter #endif 189*770Speter if (t != NIL) { 190*770Speter P0->nl_flags |= t->nl_flags & NFILES; 191*770Speter p->nl_flags |= t->nl_flags & NFILES; 192*770Speter } 193*770Speter # ifdef PC 194*770Speter stabfield( s , p2type( t ) , fp -> value[ NL_OFFS ] 195*770Speter , lwidth( t ) ); 196*770Speter # endif PC 197*770Speter } 198*770Speter return (fp); 199*770Speter } 200*770Speter 201*770Speter /* 202*770Speter * Define a variant from the constant tree of t 203*770Speter * in subrecord p of record P0 where the casetype 204*770Speter * is ct and the variant record to be associated is vr. 205*770Speter */ 206*770Speter struct nl * 207*770Speter defvnt(p, t, vr, ct) 208*770Speter struct nl *p, *vr; 209*770Speter int *t; 210*770Speter register struct nl *ct; 211*770Speter { 212*770Speter register struct nl *av; 213*770Speter 214*770Speter gconst(t); 215*770Speter if (ct != NIL && incompat(con.ctype, ct , t )) { 216*770Speter #ifndef PI1 217*770Speter cerror("Variant label type incompatible with selector type"); 218*770Speter #endif 219*770Speter ct = NIL; 220*770Speter } 221*770Speter av = defnl(0, VARNT, ct, 0); 222*770Speter #ifndef PI1 223*770Speter if (ct != NIL) 224*770Speter uniqv(p); 225*770Speter #endif 226*770Speter av->chain = p->ptr[NL_VARNT]; 227*770Speter p->ptr[NL_VARNT] = av; 228*770Speter av->ptr[NL_VTOREC] = vr; 229*770Speter av->range[0] = con.crval; 230*770Speter return (av); 231*770Speter } 232*770Speter 233*770Speter #ifndef PI1 234*770Speter /* 235*770Speter * Check that the constant label value 236*770Speter * is unique among the labels in this variant. 237*770Speter */ 238*770Speter uniqv(p) 239*770Speter struct nl *p; 240*770Speter { 241*770Speter register struct nl *vt; 242*770Speter 243*770Speter for (vt = p->ptr[NL_VARNT]; vt != NIL; vt = vt->chain) 244*770Speter if (vt->range[0] == con.crval) { 245*770Speter error("Duplicate variant case label in record"); 246*770Speter return; 247*770Speter } 248*770Speter } 249*770Speter #endif 250*770Speter 251*770Speter /* 252*770Speter * See if the field name s is defined 253*770Speter * in the record p, returning a pointer 254*770Speter * to it namelist entry if it is. 255*770Speter */ 256*770Speter struct nl * 257*770Speter reclook(p, s) 258*770Speter register struct nl *p; 259*770Speter char *s; 260*770Speter { 261*770Speter 262*770Speter if (p == NIL || s == NIL) 263*770Speter return (NIL); 264*770Speter for (p = p->chain; p != NIL; p = p->chain) 265*770Speter if (p->symbol == s) 266*770Speter return (p); 267*770Speter return (NIL); 268*770Speter } 269