|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char *sccsid[] = "@(#)equiv.c 5.1 (Berkeley) 6/7/85";
9: #endif not lint
10:
11: /*
12: * equiv.c
13: *
14: * Routines related to equivalence class processing, f77 compiler, 4.2 BSD.
15: *
16: * University of Utah CS Dept modification history:
17: *
18: * Revision 3.2 85/01/14 00:14:12 donn
19: * Fixed bug in eqvcommon that was causing the calculations of multilevel
20: * equivalences to be screwed up.
21: *
22: * Revision 3.1 84/10/13 01:16:08 donn
23: * Installed Jerry Berkman's version; added UofU comment header.
24: *
25: */
26:
27:
28: #include "defs.h"
29:
30: #ifdef SDB
31: # include <a.out.h>
32: # ifndef N_SO
33: # include <stab.h>
34: # endif
35: #endif
36:
37: /* called at end of declarations section to process chains
38: created by EQUIVALENCE statements
39: */
40:
41: doequiv()
42: {
43: register int i;
44: int inequiv, comno, ovarno;
45: ftnint comoffset, offset, leng;
46: register struct Equivblock *p;
47: register struct Eqvchain *q;
48: struct Primblock *itemp;
49: register Namep np;
50: expptr offp, suboffset();
51: int ns, nsubs();
52: chainp cp;
53: char *memname();
54: int doeqverr = 0;
55:
56: for(i = 0 ; i < nequiv ; ++i)
57: {
58: p = &eqvclass[i];
59: p->eqvbottom = p->eqvtop = 0;
60: comno = -1;
61:
62: for(q = p->equivs ; q ; q = q->eqvnextp)
63: {
64: offset = 0;
65: itemp = q->eqvitem.eqvlhs;
66: if( itemp == NULL ) fatal("error processing equivalence");
67: equivdcl = YES;
68: vardcl(np = itemp->namep);
69: equivdcl = NO;
70: if(itemp->argsp || itemp->fcharp)
71: {
72: if(np->vdim!=NULL && np->vdim->ndim>1 &&
73: nsubs(itemp->argsp)==1 )
74: {
75: if(! ftn66flag)
76: warn("1-dim subscript in EQUIVALENCE");
77: cp = NULL;
78: ns = np->vdim->ndim;
79: while(--ns > 0)
80: cp = mkchain( ICON(1), cp);
81: itemp->argsp->listp->nextp = cp;
82: }
83:
84: offp = suboffset(itemp);
85: if(ISICON(offp))
86: offset = offp->constblock.const.ci;
87: else {
88: dclerr("illegal subscript in equivalence ",
89: np);
90: np = NULL;
91: doeqverr = 1;
92: }
93: frexpr(offp);
94: }
95: frexpr(itemp);
96:
97: if(np && (leng = iarrlen(np))<0)
98: {
99: dclerr("argument in equivalence", np);
100: np = NULL;
101: doeqverr =1;
102: }
103:
104: if(np) switch(np->vstg)
105: {
106: case STGUNKNOWN:
107: case STGBSS:
108: case STGEQUIV:
109: break;
110:
111: case STGCOMMON:
112: comno = np->vardesc.varno;
113: comoffset = np->voffset + offset;
114: break;
115:
116: default:
117: dclerr("bad storage class in equivalence", np);
118: np = NULL;
119: doeqverr = 1;
120: break;
121: }
122:
123: if(np)
124: {
125: q->eqvoffset = offset;
126: p->eqvbottom = lmin(p->eqvbottom, -offset);
127: p->eqvtop = lmax(p->eqvtop, leng-offset);
128: }
129: q->eqvitem.eqvname = np;
130: }
131:
132: if(comno >= 0)
133: eqvcommon(p, comno, comoffset);
134: else for(q = p->equivs ; q ; q = q->eqvnextp)
135: {
136: if(np = q->eqvitem.eqvname)
137: {
138: inequiv = NO;
139: if(np->vstg==STGEQUIV)
140: if( (ovarno = np->vardesc.varno) == i)
141: {
142: if(np->voffset + q->eqvoffset != 0)
143: dclerr("inconsistent equivalence", np);
144: doeqverr = 1;
145: }
146: else {
147: offset = np->voffset;
148: inequiv = YES;
149: }
150:
151: np->vstg = STGEQUIV;
152: np->vardesc.varno = i;
153: np->voffset = - q->eqvoffset;
154:
155: if(inequiv)
156: eqveqv(i, ovarno, q->eqvoffset + offset);
157: }
158: }
159: }
160:
161: if( !doeqverr )
162: for(i = 0 ; i < nequiv ; ++i)
163: {
164: p = & eqvclass[i];
165: if(p->eqvbottom!=0 || p->eqvtop!=0) /* a live chain */
166: {
167: for(q = p->equivs ; q; q = q->eqvnextp)
168: {
169: np = q->eqvitem.eqvname;
170: np->voffset -= p->eqvbottom;
171: if(np->voffset % typealign[np->vtype] != 0)
172: dclerr("bad alignment forced by equivalence", np);
173: }
174: p->eqvtop -= p->eqvbottom;
175: p->eqvbottom = 0;
176: }
177: freqchain(p);
178: }
179: }
180:
181:
182:
183:
184:
185: /* put equivalence chain p at common block comno + comoffset */
186:
187: LOCAL eqvcommon(p, comno, comoffset)
188: struct Equivblock *p;
189: int comno;
190: ftnint comoffset;
191: {
192: int ovarno;
193: ftnint k, offq;
194: register Namep np;
195: register struct Eqvchain *q;
196:
197: if(comoffset + p->eqvbottom < 0)
198: {
199: errstr("attempt to extend common %s backward",
200: nounder(XL, extsymtab[comno].extname) );
201: freqchain(p);
202: return;
203: }
204:
205: if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
206: extsymtab[comno].extleng = k;
207:
208: #ifdef SDB
209: if(sdbflag)
210: prstab( varstr(XL,extsymtab[comno].extname), N_BCOMM,0,0);
211: #endif
212:
213: for(q = p->equivs ; q ; q = q->eqvnextp)
214: if(np = q->eqvitem.eqvname)
215: {
216: switch(np->vstg)
217: {
218: case STGUNKNOWN:
219: case STGBSS:
220: np->vstg = STGCOMMON;
221: np->vardesc.varno = comno;
222: np->voffset = comoffset - q->eqvoffset;
223: #ifdef SDB
224: if(sdbflag)
225: {
226: namestab(np);
227: }
228: #endif
229: break;
230:
231: case STGEQUIV:
232: ovarno = np->vardesc.varno;
233: offq = comoffset - q->eqvoffset - np->voffset;
234: np->vstg = STGCOMMON;
235: np->vardesc.varno = comno;
236: np->voffset = comoffset + q->eqvoffset;
237: if(ovarno != (p - eqvclass))
238: eqvcommon(&eqvclass[ovarno], comno, offq);
239: #ifdef SDB
240: if(sdbflag)
241: {
242: namestab(np);
243: }
244: #endif
245: break;
246:
247: case STGCOMMON:
248: if(comno != np->vardesc.varno ||
249: comoffset != np->voffset+q->eqvoffset)
250: dclerr("inconsistent common usage", np);
251: break;
252:
253:
254: default:
255: badstg("eqvcommon", np->vstg);
256: }
257: }
258:
259: #ifdef SDB
260: if(sdbflag)
261: prstab( varstr(XL,extsymtab[comno].extname), N_ECOMM,0,0);
262: #endif
263:
264: freqchain(p);
265: p->eqvbottom = p->eqvtop = 0;
266: }
267:
268:
269: /* put all items on ovarno chain on front of nvarno chain
270: * adjust offsets of ovarno elements and top and bottom of nvarno chain
271: */
272:
273: LOCAL eqveqv(nvarno, ovarno, delta)
274: int ovarno, nvarno;
275: ftnint delta;
276: {
277: register struct Equivblock *p0, *p;
278: register Namep np;
279: struct Eqvchain *q, *q1;
280:
281: p0 = eqvclass + nvarno;
282: p = eqvclass + ovarno;
283: p0->eqvbottom = lmin(p0->eqvbottom, p->eqvbottom - delta);
284: p0->eqvtop = lmax(p0->eqvtop, p->eqvtop - delta);
285: p->eqvbottom = p->eqvtop = 0;
286:
287: for(q = p->equivs ; q ; q = q1)
288: {
289: q1 = q->eqvnextp;
290: if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno)
291: {
292: q->eqvnextp = p0->equivs;
293: p0->equivs = q;
294: q->eqvoffset -= delta;
295: np->vardesc.varno = nvarno;
296: np->voffset -= delta;
297: }
298: else free( (charptr) q);
299: }
300: p->equivs = NULL;
301: }
302:
303:
304:
305:
306: LOCAL freqchain(p)
307: register struct Equivblock *p;
308: {
309: register struct Eqvchain *q, *oq;
310:
311: for(q = p->equivs ; q ; q = oq)
312: {
313: oq = q->eqvnextp;
314: free( (charptr) q);
315: }
316: p->equivs = NULL;
317: }
318:
319:
320:
321:
322:
323: LOCAL nsubs(p)
324: register struct Listblock *p;
325: {
326: register int n;
327: register chainp q;
328:
329: n = 0;
330: if(p)
331: for(q = p->listp ; q ; q = q->nextp)
332: ++n;
333:
334: return(n);
335: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.