* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / f77 / fcom / equiv.c
blob7e83d153a1161c9c80a7d72729d095c157852fd1
1 /* $Id: equiv.c,v 1.11 2008/05/11 15:28:03 ragge Exp $ */
2 /*
3 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * Redistributions of source code and documentation must retain the above
10 * copyright notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditionsand the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed or owned by Caldera
17 * International, Inc.
18 * Neither the name of Caldera International, Inc. nor the names of other
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
22 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
36 #include "defines.h"
37 #include "defs.h"
40 /* ROUTINES RELATED TO EQUIVALENCE CLASS PROCESSING */
41 LOCAL void eqvcommon(struct equivblock *, int, ftnint);
42 LOCAL void eqveqv(int, int, ftnint);
43 LOCAL void freqchain(struct equivblock *p);
44 LOCAL int nsubs(struct bigblock *p);
46 /* called at end of declarations section to process chains
47 created by EQUIVALENCE statements
49 void
50 doequiv()
52 register int i;
53 int inequiv, comno, ovarno;
54 ftnint comoffset, offset, leng;
55 register struct equivblock *p;
56 register chainp q;
57 struct bigblock *itemp;
58 register struct bigblock *np;
59 bigptr offp;
60 int ns;
61 chainp cp;
63 ovarno = comoffset = offset = 0; /* XXX gcc */
64 for(i = 0 ; i < nequiv ; ++i)
66 p = &eqvclass[i];
67 p->eqvbottom = p->eqvtop = 0;
68 comno = -1;
70 for(q = p->equivs ; q ; q = q->eqvchain.nextp)
72 itemp = q->eqvchain.eqvitem;
73 vardcl(np = itemp->b_prim.namep);
74 if(itemp->b_prim.argsp || itemp->b_prim.fcharp)
76 if(np->b_name.vdim!=NULL && np->b_name.vdim->ndim>1 &&
77 nsubs(itemp->b_prim.argsp)==1 )
79 if(! ftn66flag)
80 warn("1-dim subscript in EQUIVALENCE");
81 cp = NULL;
82 ns = np->b_name.vdim->ndim;
83 while(--ns > 0)
84 cp = mkchain( MKICON(1), cp);
85 itemp->b_prim.argsp->b_list.listp->chain.nextp = cp;
87 offp = suboffset(itemp);
89 else offp = MKICON(0);
90 if(ISICON(offp))
91 offset = q->eqvchain.eqvoffset = offp->b_const.fconst.ci;
92 else {
93 dclerr("nonconstant subscript in equivalence ", np);
94 np = NULL;
95 goto endit;
97 if( (leng = iarrlen(np)) < 0)
99 dclerr("adjustable in equivalence", np);
100 np = NULL;
101 goto endit;
103 p->eqvbottom = lmin(p->eqvbottom, -offset);
104 p->eqvtop = lmax(p->eqvtop, leng-offset);
106 switch(np->vstg)
108 case STGUNKNOWN:
109 case STGBSS:
110 case STGEQUIV:
111 break;
113 case STGCOMMON:
114 comno = np->b_name.vardesc.varno;
115 comoffset = np->b_name.voffset + offset;
116 break;
118 default:
119 dclerr("bad storage class in equivalence", np);
120 np = NULL;
121 goto endit;
123 endit:
124 frexpr(offp);
125 q->eqvchain.eqvitem = np;
128 if(comno >= 0)
129 eqvcommon(p, comno, comoffset);
130 else for(q = p->equivs ; q ; q = q->eqvchain.nextp)
132 if((np = q->eqvchain.eqvitem))
134 inequiv = NO;
135 if(np->vstg==STGEQUIV) {
136 if( (ovarno = np->b_name.vardesc.varno) == i)
138 if(np->b_name.voffset + q->eqvchain.eqvoffset != 0)
139 dclerr("inconsistent equivalence", np);
141 else {
142 offset = np->b_name.voffset;
143 inequiv = YES;
146 np->vstg = STGEQUIV;
147 np->b_name.vardesc.varno = i;
148 np->b_name.voffset = - q->eqvchain.eqvoffset;
150 if(inequiv)
151 eqveqv(i, ovarno, q->eqvchain.eqvoffset + offset);
156 for(i = 0 ; i < nequiv ; ++i)
158 p = & eqvclass[i];
159 if(p->eqvbottom!=0 || p->eqvtop!=0)
161 for(q = p->equivs ; q; q = q->eqvchain.nextp)
163 np = q->eqvchain.eqvitem;
164 np->b_name.voffset -= p->eqvbottom;
165 if(np->b_name.voffset % typealign[np->vtype] != 0)
166 dclerr("bad alignment forced by equivalence", np);
168 p->eqvtop -= p->eqvbottom;
169 p->eqvbottom = 0;
171 freqchain(p);
179 /* put equivalence chain p at common block comno + comoffset */
181 LOCAL void eqvcommon(p, comno, comoffset)
182 struct equivblock *p;
183 int comno;
184 ftnint comoffset;
186 int ovarno;
187 ftnint k, offq;
188 register struct bigblock *np;
189 register chainp q;
191 if(comoffset + p->eqvbottom < 0)
193 err1("attempt to extend common %s backward",
194 nounder(XL, extsymtab[comno].extname) );
195 freqchain(p);
196 return;
199 if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
200 extsymtab[comno].extleng = k;
202 for(q = p->equivs ; q ; q = q->eqvchain.nextp)
203 if((np = q->eqvchain.eqvitem))
205 switch(np->vstg)
207 case STGUNKNOWN:
208 case STGBSS:
209 np->vstg = STGCOMMON;
210 np->b_name.vardesc.varno = comno;
211 np->b_name.voffset = comoffset - q->eqvchain.eqvoffset;
212 break;
214 case STGEQUIV:
215 ovarno = np->b_name.vardesc.varno;
216 offq = comoffset - q->eqvchain.eqvoffset - np->b_name.voffset;
217 np->vstg = STGCOMMON;
218 np->b_name.vardesc.varno = comno;
219 np->b_name.voffset = comoffset - q->eqvchain.eqvoffset;
220 if(ovarno != (p - eqvclass))
221 eqvcommon(&eqvclass[ovarno], comno, offq);
222 break;
224 case STGCOMMON:
225 if(comno != np->b_name.vardesc.varno ||
226 comoffset != np->b_name.voffset+q->eqvchain.eqvoffset)
227 dclerr("inconsistent common usage", np);
228 break;
231 default:
232 fatal1("eqvcommon: impossible vstg %d", np->vstg);
236 freqchain(p);
237 p->eqvbottom = p->eqvtop = 0;
241 /* put all items on ovarno chain on front of nvarno chain
242 * adjust offsets of ovarno elements and top and bottom of nvarno chain
245 LOCAL void eqveqv(nvarno, ovarno, delta)
246 int ovarno, nvarno;
247 ftnint delta;
249 register struct equivblock *p0, *p;
250 register struct nameblock *np;
251 chainp q, q1;
253 p0 = eqvclass + nvarno;
254 p = eqvclass + ovarno;
255 p0->eqvbottom = lmin(p0->eqvbottom, p->eqvbottom - delta);
256 p0->eqvtop = lmax(p0->eqvtop, p->eqvtop - delta);
257 p->eqvbottom = p->eqvtop = 0;
259 for(q = p->equivs ; q ; q = q1)
261 q1 = q->eqvchain.nextp;
262 if( (np = q->eqvchain.eqvitem) && np->vardesc.varno==ovarno)
264 q->eqvchain.nextp = p0->equivs;
265 p0->equivs = q;
266 q->eqvchain.eqvoffset -= delta;
267 np->vardesc.varno = nvarno;
268 np->voffset -= delta;
270 else ckfree(q);
272 p->equivs = NULL;
278 LOCAL void
279 freqchain(p)
280 register struct equivblock *p;
282 register chainp q, oq;
284 for(q = p->equivs ; q ; q = oq)
286 oq = q->eqvchain.nextp;
287 ckfree(q);
289 p->equivs = NULL;
296 LOCAL int
297 nsubs(p)
298 register struct bigblock *p;
300 register int n;
301 register chainp q;
303 n = 0;
304 if(p)
305 for(q = p->b_list.listp ; q ; q = q->chain.nextp)
306 ++n;
308 return(n);