|
|
1.1 ! root 1: /**************************************************************** ! 2: Copyright 1990, 1993 by AT&T Bell Laboratories and Bellcore. ! 3: ! 4: Permission to use, copy, modify, and distribute this software ! 5: and its documentation for any purpose and without fee is hereby ! 6: granted, provided that the above copyright notice appear in all ! 7: copies and that both that the copyright notice and this ! 8: permission notice and warranty disclaimer appear in supporting ! 9: documentation, and that the names of AT&T Bell Laboratories or ! 10: Bellcore or any of their entities not be used in advertising or ! 11: publicity pertaining to distribution of the software without ! 12: specific, written prior permission. ! 13: ! 14: AT&T and Bellcore disclaim all warranties with regard to this ! 15: software, including all implied warranties of merchantability ! 16: and fitness. In no event shall AT&T or Bellcore be liable for ! 17: any special, indirect or consequential damages or any damages ! 18: whatsoever resulting from loss of use, data or profits, whether ! 19: in an action of contract, negligence or other tortious action, ! 20: arising out of or in connection with the use or performance of ! 21: this software. ! 22: ****************************************************************/ ! 23: ! 24: #include "defs.h" ! 25: ! 26: LOCAL eqvcommon(), eqveqv(), nsubs(); ! 27: ! 28: /* ROUTINES RELATED TO EQUIVALENCE CLASS PROCESSING */ ! 29: ! 30: /* called at end of declarations section to process chains ! 31: created by EQUIVALENCE statements ! 32: */ ! 33: doequiv() ! 34: { ! 35: register int i; ! 36: int inequiv; /* True if one namep occurs in ! 37: several EQUIV declarations */ ! 38: int comno; /* Index into Extsym table of the last ! 39: COMMON block seen (implicitly assuming ! 40: that only one will be given) */ ! 41: int ovarno; ! 42: ftnint comoffset; /* Index into the COMMON block */ ! 43: ftnint offset; /* Offset from array base */ ! 44: ftnint leng; ! 45: register struct Equivblock *equivdecl; ! 46: register struct Eqvchain *q; ! 47: struct Primblock *primp; ! 48: register Namep np; ! 49: int k, k1, ns, pref, t; ! 50: chainp cp; ! 51: extern int type_pref[]; ! 52: char *s; ! 53: ! 54: for(i = 0 ; i < nequiv ; ++i) ! 55: { ! 56: ! 57: /* Handle each equivalence declaration */ ! 58: ! 59: equivdecl = &eqvclass[i]; ! 60: equivdecl->eqvbottom = equivdecl->eqvtop = 0; ! 61: comno = -1; ! 62: ! 63: ! 64: ! 65: for(q = equivdecl->equivs ; q ; q = q->eqvnextp) ! 66: { ! 67: offset = 0; ! 68: primp = q->eqvitem.eqvlhs; ! 69: vardcl(np = primp->namep); ! 70: if(primp->argsp || primp->fcharp) ! 71: { ! 72: expptr offp, suboffset(); ! 73: ! 74: /* Pad ones onto the end of an array declaration when needed */ ! 75: ! 76: if(np->vdim!=NULL && np->vdim->ndim>1 && ! 77: nsubs(primp->argsp)==1 ) ! 78: { ! 79: if(! ftn66flag) ! 80: warni ! 81: ("1-dim subscript in EQUIVALENCE, %d-dim declared", ! 82: np -> vdim -> ndim); ! 83: cp = NULL; ! 84: ns = np->vdim->ndim; ! 85: while(--ns > 0) ! 86: cp = mkchain((char *)ICON(1), cp); ! 87: primp->argsp->listp->nextp = cp; ! 88: } ! 89: ! 90: offp = suboffset(primp); ! 91: if(ISICON(offp)) ! 92: offset = offp->constblock.Const.ci; ! 93: else { ! 94: dclerr ! 95: ("nonconstant subscript in equivalence ", ! 96: np); ! 97: np = NULL; ! 98: } ! 99: frexpr(offp); ! 100: } ! 101: ! 102: /* Free up the primblock, since we now have a hash table (Namep) entry */ ! 103: ! 104: frexpr((expptr)primp); ! 105: ! 106: if(np && (leng = iarrlen(np))<0) ! 107: { ! 108: dclerr("adjustable in equivalence", np); ! 109: np = NULL; ! 110: } ! 111: ! 112: if(np) switch(np->vstg) ! 113: { ! 114: case STGUNKNOWN: ! 115: case STGBSS: ! 116: case STGEQUIV: ! 117: if (in_vector(np->cvarname, st_fields, ! 118: n_st_fields) >= 0) { ! 119: k = strlen(np->cvarname); ! 120: strcpy(s = mem(k+2,0), np->cvarname); ! 121: s[k] = '_'; ! 122: s[k+1] = 0; ! 123: np->cvarname = s; ! 124: } ! 125: break; ! 126: ! 127: case STGCOMMON: ! 128: ! 129: /* The code assumes that all COMMON references in a given EQUIVALENCE will ! 130: be to the same COMMON block, and will all be consistent */ ! 131: ! 132: comno = np->vardesc.varno; ! 133: comoffset = np->voffset + offset; ! 134: break; ! 135: ! 136: default: ! 137: dclerr("bad storage class in equivalence", np); ! 138: np = NULL; ! 139: break; ! 140: } ! 141: ! 142: if(np) ! 143: { ! 144: q->eqvoffset = offset; ! 145: ! 146: /* eqvbottom gets the largest difference between the array base address ! 147: and the address specified in the EQUIV declaration */ ! 148: ! 149: equivdecl->eqvbottom = ! 150: lmin(equivdecl->eqvbottom, -offset); ! 151: ! 152: /* eqvtop gets the largest difference between the end of the array and ! 153: the address given in the EQUIVALENCE */ ! 154: ! 155: equivdecl->eqvtop = ! 156: lmax(equivdecl->eqvtop, leng-offset); ! 157: } ! 158: q->eqvitem.eqvname = np; ! 159: } ! 160: ! 161: /* Now all equivalenced variables are in the hash table with the proper ! 162: offset, and eqvtop and eqvbottom are set. */ ! 163: ! 164: if(comno >= 0) ! 165: ! 166: /* Get rid of all STGEQUIVS, they will be mapped onto STGCOMMON variables ! 167: */ ! 168: ! 169: eqvcommon(equivdecl, comno, comoffset); ! 170: else for(q = equivdecl->equivs ; q ; q = q->eqvnextp) ! 171: { ! 172: if(np = q->eqvitem.eqvname) ! 173: { ! 174: inequiv = NO; ! 175: if(np->vstg==STGEQUIV) ! 176: if( (ovarno = np->vardesc.varno) == i) ! 177: { ! 178: ! 179: /* Can't EQUIV different elements of the same array */ ! 180: ! 181: if(np->voffset + q->eqvoffset != 0) ! 182: dclerr ! 183: ("inconsistent equivalence", np); ! 184: } ! 185: else { ! 186: offset = np->voffset; ! 187: inequiv = YES; ! 188: } ! 189: ! 190: np->vstg = STGEQUIV; ! 191: np->vardesc.varno = i; ! 192: np->voffset = - q->eqvoffset; ! 193: ! 194: if(inequiv) ! 195: ! 196: /* Combine 2 equivalence declarations */ ! 197: ! 198: eqveqv(i, ovarno, q->eqvoffset + offset); ! 199: } ! 200: } ! 201: } ! 202: ! 203: /* Now each equivalence declaration is distinct (all connections have been ! 204: merged in eqveqv()), and some may be empty. */ ! 205: ! 206: for(i = 0 ; i < nequiv ; ++i) ! 207: { ! 208: equivdecl = & eqvclass[i]; ! 209: if(equivdecl->eqvbottom!=0 || equivdecl->eqvtop!=0) { ! 210: ! 211: /* a live chain */ ! 212: ! 213: k = TYCHAR; ! 214: pref = 1; ! 215: for(q = equivdecl->equivs ; q; q = q->eqvnextp) ! 216: if (np = q->eqvitem.eqvname){ ! 217: np->voffset -= equivdecl->eqvbottom; ! 218: t = typealign[k1 = np->vtype]; ! 219: if (pref < type_pref[k1]) { ! 220: k = k1; ! 221: pref = type_pref[k1]; ! 222: } ! 223: if(np->voffset % t != 0) { ! 224: dclerr("bad alignment forced by equivalence", np); ! 225: --nerr; /* don't give bad return code for this */ ! 226: } ! 227: } ! 228: equivdecl->eqvtype = k; ! 229: } ! 230: freqchain(equivdecl); ! 231: } ! 232: } ! 233: ! 234: ! 235: ! 236: ! 237: ! 238: /* put equivalence chain p at common block comno + comoffset */ ! 239: ! 240: LOCAL eqvcommon(p, comno, comoffset) ! 241: struct Equivblock *p; ! 242: int comno; ! 243: ftnint comoffset; ! 244: { ! 245: int ovarno; ! 246: ftnint k, offq; ! 247: register Namep np; ! 248: register struct Eqvchain *q; ! 249: ! 250: if(comoffset + p->eqvbottom < 0) ! 251: { ! 252: errstr("attempt to extend common %s backward", ! 253: extsymtab[comno].fextname); ! 254: freqchain(p); ! 255: return; ! 256: } ! 257: ! 258: if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng) ! 259: extsymtab[comno].extleng = k; ! 260: ! 261: ! 262: for(q = p->equivs ; q ; q = q->eqvnextp) ! 263: if(np = q->eqvitem.eqvname) ! 264: { ! 265: switch(np->vstg) ! 266: { ! 267: case STGUNKNOWN: ! 268: case STGBSS: ! 269: np->vstg = STGCOMMON; ! 270: np->vcommequiv = 1; ! 271: np->vardesc.varno = comno; ! 272: ! 273: /* np -> voffset will point to the base of the array */ ! 274: ! 275: np->voffset = comoffset - q->eqvoffset; ! 276: break; ! 277: ! 278: case STGEQUIV: ! 279: ovarno = np->vardesc.varno; ! 280: ! 281: /* offq will point to the current element, even if it's in an array */ ! 282: ! 283: offq = comoffset - q->eqvoffset - np->voffset; ! 284: np->vstg = STGCOMMON; ! 285: np->vcommequiv = 1; ! 286: np->vardesc.varno = comno; ! 287: ! 288: /* np -> voffset will point to the base of the array */ ! 289: ! 290: np->voffset += offq; ! 291: if(ovarno != (p - eqvclass)) ! 292: eqvcommon(&eqvclass[ovarno], comno, offq); ! 293: break; ! 294: ! 295: case STGCOMMON: ! 296: if(comno != np->vardesc.varno || ! 297: comoffset != np->voffset+q->eqvoffset) ! 298: dclerr("inconsistent common usage", np); ! 299: break; ! 300: ! 301: ! 302: default: ! 303: badstg("eqvcommon", np->vstg); ! 304: } ! 305: } ! 306: ! 307: freqchain(p); ! 308: p->eqvbottom = p->eqvtop = 0; ! 309: } ! 310: ! 311: ! 312: /* Move all items on ovarno chain to the front of nvarno chain. ! 313: * adjust offsets of ovarno elements and top and bottom of nvarno chain ! 314: */ ! 315: ! 316: LOCAL eqveqv(nvarno, ovarno, delta) ! 317: int ovarno, nvarno; ! 318: ftnint delta; ! 319: { ! 320: register struct Equivblock *neweqv, *oldeqv; ! 321: register Namep np; ! 322: struct Eqvchain *q, *q1; ! 323: ! 324: neweqv = eqvclass + nvarno; ! 325: oldeqv = eqvclass + ovarno; ! 326: neweqv->eqvbottom = lmin(neweqv->eqvbottom, oldeqv->eqvbottom - delta); ! 327: neweqv->eqvtop = lmax(neweqv->eqvtop, oldeqv->eqvtop - delta); ! 328: oldeqv->eqvbottom = oldeqv->eqvtop = 0; ! 329: ! 330: for(q = oldeqv->equivs ; q ; q = q1) ! 331: { ! 332: q1 = q->eqvnextp; ! 333: if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno) ! 334: { ! 335: q->eqvnextp = neweqv->equivs; ! 336: neweqv->equivs = q; ! 337: q->eqvoffset += delta; ! 338: np->vardesc.varno = nvarno; ! 339: np->voffset -= delta; ! 340: } ! 341: else free( (charptr) q); ! 342: } ! 343: oldeqv->equivs = NULL; ! 344: } ! 345: ! 346: ! 347: ! 348: ! 349: freqchain(p) ! 350: register struct Equivblock *p; ! 351: { ! 352: register struct Eqvchain *q, *oq; ! 353: ! 354: for(q = p->equivs ; q ; q = oq) ! 355: { ! 356: oq = q->eqvnextp; ! 357: free( (charptr) q); ! 358: } ! 359: p->equivs = NULL; ! 360: } ! 361: ! 362: ! 363: ! 364: ! 365: ! 366: /* nsubs -- number of subscripts in this arglist (just the length of the ! 367: list) */ ! 368: ! 369: LOCAL nsubs(p) ! 370: register struct Listblock *p; ! 371: { ! 372: register int n; ! 373: register chainp q; ! 374: ! 375: n = 0; ! 376: if(p) ! 377: for(q = p->listp ; q ; q = q->nextp) ! 378: ++n; ! 379: ! 380: return(n); ! 381: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.