1 /* $Id: equiv.c,v 1.11 2008/05/11 15:28:03 ragge Exp $ */
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
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
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.
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
53 int inequiv
, comno
, ovarno
;
54 ftnint comoffset
, offset
, leng
;
55 register struct equivblock
*p
;
57 struct bigblock
*itemp
;
58 register struct bigblock
*np
;
63 ovarno
= comoffset
= offset
= 0; /* XXX gcc */
64 for(i
= 0 ; i
< nequiv
; ++i
)
67 p
->eqvbottom
= p
->eqvtop
= 0;
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 )
80 warn("1-dim subscript in EQUIVALENCE");
82 ns
= np
->b_name
.vdim
->ndim
;
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);
91 offset
= q
->eqvchain
.eqvoffset
= offp
->b_const
.fconst
.ci
;
93 dclerr("nonconstant subscript in equivalence ", np
);
97 if( (leng
= iarrlen(np
)) < 0)
99 dclerr("adjustable in equivalence", np
);
103 p
->eqvbottom
= lmin(p
->eqvbottom
, -offset
);
104 p
->eqvtop
= lmax(p
->eqvtop
, leng
-offset
);
114 comno
= np
->b_name
.vardesc
.varno
;
115 comoffset
= np
->b_name
.voffset
+ offset
;
119 dclerr("bad storage class in equivalence", np
);
125 q
->eqvchain
.eqvitem
= np
;
129 eqvcommon(p
, comno
, comoffset
);
130 else for(q
= p
->equivs
; q
; q
= q
->eqvchain
.nextp
)
132 if((np
= q
->eqvchain
.eqvitem
))
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
);
142 offset
= np
->b_name
.voffset
;
147 np
->b_name
.vardesc
.varno
= i
;
148 np
->b_name
.voffset
= - q
->eqvchain
.eqvoffset
;
151 eqveqv(i
, ovarno
, q
->eqvchain
.eqvoffset
+ offset
);
156 for(i
= 0 ; i
< nequiv
; ++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
;
179 /* put equivalence chain p at common block comno + comoffset */
181 LOCAL
void eqvcommon(p
, comno
, comoffset
)
182 struct equivblock
*p
;
188 register struct bigblock
*np
;
191 if(comoffset
+ p
->eqvbottom
< 0)
193 err1("attempt to extend common %s backward",
194 nounder(XL
, extsymtab
[comno
].extname
) );
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
))
209 np
->vstg
= STGCOMMON
;
210 np
->b_name
.vardesc
.varno
= comno
;
211 np
->b_name
.voffset
= comoffset
- q
->eqvchain
.eqvoffset
;
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
);
225 if(comno
!= np
->b_name
.vardesc
.varno
||
226 comoffset
!= np
->b_name
.voffset
+q
->eqvchain
.eqvoffset
)
227 dclerr("inconsistent common usage", np
);
232 fatal1("eqvcommon: impossible vstg %d", np
->vstg
);
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
)
249 register struct equivblock
*p0
, *p
;
250 register struct nameblock
*np
;
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
;
266 q
->eqvchain
.eqvoffset
-= delta
;
267 np
->vardesc
.varno
= nvarno
;
268 np
->voffset
-= delta
;
280 register struct equivblock
*p
;
282 register chainp q
, oq
;
284 for(q
= p
->equivs
; q
; q
= oq
)
286 oq
= q
->eqvchain
.nextp
;
298 register struct bigblock
*p
;
305 for(q
= p
->b_list
.listp
; q
; q
= q
->chain
.nextp
)