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(). 
 | 
 
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
 
 
 
 
       
	   
	   
	   
	  