Doxygen Source Code Documentation
equiv.c File Reference
#include "defs.h"Go to the source code of this file.
Functions | |
| void eqvcommon | Argdcl ((struct Equivblock *, int, long int)) |
| void eqveqv | Argdcl ((int, int, long int)) |
| int nsubs | Argdcl ((struct Listblock *)) |
| void | doequiv (Void) |
| LOCAL void | eqvcommon (struct Equivblock *p, int comno, ftnint comoffset) |
| LOCAL void | eqveqv (int nvarno, int ovarno, ftnint delta) |
| void | freqchain (register struct Equivblock *p) |
| LOCAL int | nsubs (register struct Listblock *p) |
| Primblock * | primchk (expptr e) |
Function Documentation
|
|
|
|
|
|
|
|
|
|
|
Definition at line 36 of file equiv.c. References Primblock::argsp, Constant::ci, Constblock::Const, Expression::constblock, dclerr(), Equivblock::equivs, Equivblock::eqvbottom, eqvcommon(), eqveqv(), Eqvchain::eqvitem, Eqvchain::eqvnextp, Eqvchain::eqvoffset, Equivblock::eqvtop, Equivblock::eqvtype, Primblock::fcharp, freqchain(), frexpr(), i, iarrlen(), ICON, ISICON, Listblock::listp, lmax(), lmin(), mkchain(), Primblock::namep, Chain::nextp, NO, nsubs(), offset, STGBSS, STGCOMMON, STGEQUIV, STGUNKNOWN, suboffset(), type_pref, vardcl(), warni(), and YES. Referenced by enddcl().
00037 {
00038 register int i;
00039 int inequiv; /* True if one namep occurs in
00040 several EQUIV declarations */
00041 int comno; /* Index into Extsym table of the last
00042 COMMON block seen (implicitly assuming
00043 that only one will be given) */
00044 int ovarno;
00045 ftnint comoffset; /* Index into the COMMON block */
00046 ftnint offset; /* Offset from array base */
00047 ftnint leng;
00048 register struct Equivblock *equivdecl;
00049 register struct Eqvchain *q;
00050 struct Primblock *primp;
00051 register Namep np;
00052 int k, k1, ns, pref, t;
00053 chainp cp;
00054 extern int type_pref[];
00055 char *s;
00056
00057 for(i = 0 ; i < nequiv ; ++i)
00058 {
00059
00060 /* Handle each equivalence declaration */
00061
00062 equivdecl = &eqvclass[i];
00063 equivdecl->eqvbottom = equivdecl->eqvtop = 0;
00064 comno = -1;
00065
00066
00067
00068 for(q = equivdecl->equivs ; q ; q = q->eqvnextp)
00069 {
00070 offset = 0;
00071 if (!(primp = q->eqvitem.eqvlhs))
00072 continue;
00073 vardcl(np = primp->namep);
00074 if(primp->argsp || primp->fcharp)
00075 {
00076 expptr offp;
00077
00078 /* Pad ones onto the end of an array declaration when needed */
00079
00080 if(np->vdim!=NULL && np->vdim->ndim>1 &&
00081 nsubs(primp->argsp)==1 )
00082 {
00083 if(! ftn66flag)
00084 warni
00085 ("1-dim subscript in EQUIVALENCE, %d-dim declared",
00086 np -> vdim -> ndim);
00087 cp = NULL;
00088 ns = np->vdim->ndim;
00089 while(--ns > 0)
00090 cp = mkchain((char *)ICON(1), cp);
00091 primp->argsp->listp->nextp = cp;
00092 }
00093
00094 offp = suboffset(primp);
00095 if(ISICON(offp))
00096 offset = offp->constblock.Const.ci;
00097 else {
00098 dclerr
00099 ("nonconstant subscript in equivalence ",
00100 np);
00101 np = NULL;
00102 }
00103 frexpr(offp);
00104 }
00105
00106 /* Free up the primblock, since we now have a hash table (Namep) entry */
00107
00108 frexpr((expptr)primp);
00109
00110 if(np && (leng = iarrlen(np))<0)
00111 {
00112 dclerr("adjustable in equivalence", np);
00113 np = NULL;
00114 }
00115
00116 if(np) switch(np->vstg)
00117 {
00118 case STGUNKNOWN:
00119 case STGBSS:
00120 case STGEQUIV:
00121 break;
00122
00123 case STGCOMMON:
00124
00125 /* The code assumes that all COMMON references in a given EQUIVALENCE will
00126 be to the same COMMON block, and will all be consistent */
00127
00128 comno = np->vardesc.varno;
00129 comoffset = np->voffset + offset;
00130 break;
00131
00132 default:
00133 dclerr("bad storage class in equivalence", np);
00134 np = NULL;
00135 break;
00136 }
00137
00138 if(np)
00139 {
00140 q->eqvoffset = offset;
00141
00142 /* eqvbottom gets the largest difference between the array base address
00143 and the address specified in the EQUIV declaration */
00144
00145 equivdecl->eqvbottom =
00146 lmin(equivdecl->eqvbottom, -offset);
00147
00148 /* eqvtop gets the largest difference between the end of the array and
00149 the address given in the EQUIVALENCE */
00150
00151 equivdecl->eqvtop =
00152 lmax(equivdecl->eqvtop, leng-offset);
00153 }
00154 q->eqvitem.eqvname = np;
00155 }
00156
00157 /* Now all equivalenced variables are in the hash table with the proper
00158 offset, and eqvtop and eqvbottom are set. */
00159
00160 if(comno >= 0)
00161
00162 /* Get rid of all STGEQUIVS, they will be mapped onto STGCOMMON variables
00163 */
00164
00165 eqvcommon(equivdecl, comno, comoffset);
00166 else for(q = equivdecl->equivs ; q ; q = q->eqvnextp)
00167 {
00168 if(np = q->eqvitem.eqvname)
00169 {
00170 inequiv = NO;
00171 if(np->vstg==STGEQUIV)
00172 if( (ovarno = np->vardesc.varno) == i)
00173 {
00174
00175 /* Can't EQUIV different elements of the same array */
00176
00177 if(np->voffset + q->eqvoffset != 0)
00178 dclerr
00179 ("inconsistent equivalence", np);
00180 }
00181 else {
00182 offset = np->voffset;
00183 inequiv = YES;
00184 }
00185
00186 np->vstg = STGEQUIV;
00187 np->vardesc.varno = i;
00188 np->voffset = - q->eqvoffset;
00189
00190 if(inequiv)
00191
00192 /* Combine 2 equivalence declarations */
00193
00194 eqveqv(i, ovarno, q->eqvoffset + offset);
00195 }
00196 }
00197 }
00198
00199 /* Now each equivalence declaration is distinct (all connections have been
00200 merged in eqveqv()), and some may be empty. */
00201
00202 for(i = 0 ; i < nequiv ; ++i)
00203 {
00204 equivdecl = & eqvclass[i];
00205 if(equivdecl->eqvbottom!=0 || equivdecl->eqvtop!=0) {
00206
00207 /* a live chain */
00208
00209 k = TYCHAR;
00210 pref = 1;
00211 for(q = equivdecl->equivs ; q; q = q->eqvnextp)
00212 if ((np = q->eqvitem.eqvname)
00213 && !np->veqvadjust) {
00214 np->veqvadjust = 1;
00215 np->voffset -= equivdecl->eqvbottom;
00216 t = typealign[k1 = np->vtype];
00217 if (pref < type_pref[k1]) {
00218 k = k1;
00219 pref = type_pref[k1];
00220 }
00221 if(np->voffset % t != 0) {
00222 dclerr("bad alignment forced by equivalence", np);
00223 --nerr; /* don't give bad return code for this */
00224 }
00225 }
00226 equivdecl->eqvtype = k;
00227 }
00228 freqchain(equivdecl);
00229 }
00230 }
|
|
||||||||||||||||
|
Definition at line 245 of file equiv.c. References badstg(), dclerr(), Equivblock::equivs, Equivblock::eqvbottom, Eqvchain::eqvitem, Eqvchain::eqvnextp, Eqvchain::eqvoffset, Equivblock::eqvtop, errstr(), freqchain(), STGBSS, STGCOMMON, STGEQUIV, STGUNKNOWN, Nameblock::vardesc, Nameblock::vcommequiv, Nameblock::voffset, and Nameblock::vstg. Referenced by doequiv().
00247 {
00248 int ovarno;
00249 ftnint k, offq;
00250 register Namep np;
00251 register struct Eqvchain *q;
00252
00253 if(comoffset + p->eqvbottom < 0)
00254 {
00255 errstr("attempt to extend common %s backward",
00256 extsymtab[comno].fextname);
00257 freqchain(p);
00258 return;
00259 }
00260
00261 if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
00262 extsymtab[comno].extleng = k;
00263
00264
00265 for(q = p->equivs ; q ; q = q->eqvnextp)
00266 if(np = q->eqvitem.eqvname)
00267 {
00268 switch(np->vstg)
00269 {
00270 case STGUNKNOWN:
00271 case STGBSS:
00272 np->vstg = STGCOMMON;
00273 np->vcommequiv = 1;
00274 np->vardesc.varno = comno;
00275
00276 /* np -> voffset will point to the base of the array */
00277
00278 np->voffset = comoffset - q->eqvoffset;
00279 break;
00280
00281 case STGEQUIV:
00282 ovarno = np->vardesc.varno;
00283
00284 /* offq will point to the current element, even if it's in an array */
00285
00286 offq = comoffset - q->eqvoffset - np->voffset;
00287 np->vstg = STGCOMMON;
00288 np->vcommequiv = 1;
00289 np->vardesc.varno = comno;
00290
00291 /* np -> voffset will point to the base of the array */
00292
00293 np->voffset += offq;
00294 if(ovarno != (p - eqvclass))
00295 eqvcommon(&eqvclass[ovarno], comno, offq);
00296 break;
00297
00298 case STGCOMMON:
00299 if(comno != np->vardesc.varno ||
00300 comoffset != np->voffset+q->eqvoffset)
00301 dclerr("inconsistent common usage", np);
00302 break;
00303
00304
00305 default:
00306 badstg("eqvcommon", np->vstg);
00307 }
00308 }
00309
00310 freqchain(p);
00311 p->eqvbottom = p->eqvtop = 0;
00312 }
|
|
||||||||||||||||
|
Definition at line 326 of file equiv.c. References charptr, Equivblock::equivs, Equivblock::eqvbottom, Eqvchain::eqvitem, Eqvchain::eqvnextp, Eqvchain::eqvoffset, Equivblock::eqvtop, free, lmax(), and lmin(). Referenced by doequiv().
00328 {
00329 register struct Equivblock *neweqv, *oldeqv;
00330 register Namep np;
00331 struct Eqvchain *q, *q1;
00332
00333 neweqv = eqvclass + nvarno;
00334 oldeqv = eqvclass + ovarno;
00335 neweqv->eqvbottom = lmin(neweqv->eqvbottom, oldeqv->eqvbottom - delta);
00336 neweqv->eqvtop = lmax(neweqv->eqvtop, oldeqv->eqvtop - delta);
00337 oldeqv->eqvbottom = oldeqv->eqvtop = 0;
00338
00339 for(q = oldeqv->equivs ; q ; q = q1)
00340 {
00341 q1 = q->eqvnextp;
00342 if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno)
00343 {
00344 q->eqvnextp = neweqv->equivs;
00345 neweqv->equivs = q;
00346 q->eqvoffset += delta;
00347 np->vardesc.varno = nvarno;
00348 np->voffset -= delta;
00349 }
00350 else free( (charptr) q);
00351 }
00352 oldeqv->equivs = NULL;
00353 }
|
|
|
Definition at line 362 of file equiv.c. References charptr, Equivblock::equivs, Eqvchain::eqvnextp, and free. Referenced by doequiv(), and eqvcommon().
|
|
|
Definition at line 387 of file equiv.c. References Listblock::listp, Chain::nextp, and q. Referenced by doequiv().
|
|
|
Definition at line 405 of file equiv.c. References err, Primblock::tag, and TPRIM. Referenced by yyparse().
|