proc.c File Reference

#include "defs.h"
#include "names.h"
#include "output.h"
#include "p1defs.h"

Include dependency graph for proc.c:

Go to the source code of this file.

Defines

#define roundup(a, b)   ( b * ( (a+b-1)/b) )
#define EXNULL   (union Expression *)0

Functions

static void dobss Argdcl ((void))
static void doentry Argdcl ((struct Entrypoint *))
static int nextarg Argdcl ((int))
void changedtype (Namep q)
void unamstring (register Addrp q, register char *s)
static void fix_entry_returns (Void)
static void putentries (FILE *outfile)
static void entry_goto (FILE *outfile)
void newproc (Void)
static void zap_changes (Void)
void endproc (Void)
void enddcl (Void)
void startproc (Extsym *progname, int Class)
Extsymnewentry (register Namep v, int substmsg)
void entrypt (int Class, int type, ftnint length, Extsym *entry, chainp args)
LOCAL void epicode (Void)
LOCAL void retval (register int t)
void procode (FILE *outfile)
static void bad_dimtype (Namep q)
static void dim_finish (Namep v)
static void duparg (Namep q)
LOCAL void doentry (struct Entrypoint *ep)
LOCAL int nextarg (int type)
LOCAL void dim_check (Namep q)
LOCAL void dobss (Void)
void donmlist (Void)
ftnint iarrlen (register Namep q)
void namelist (Namep np)
LOCAL void docommon (Void)
void copy_data (chainp list)
LOCAL void docomleng (Void)
void frtemp (Addrp p)
void freetemps (Void)
Addrp autovar (register int nelt0, register int t, expptr lengp, char *name)
Addrp mktmpn (int nelt, register int type, expptr lengp)
Addrp mktmp (int type, expptr lengp)
Addrp mktmp0 (int type, expptr lengp)
Extsymcomblock (register char *s)
void incomm (Extsym *c, Namep v)
void settype (register Namep v, register int type, register ftnint length)
int lengtype (register int type, ftnint len)
void setintr (register Namep v)
void setext (register Namep v)
void setbound (Namep v, int nd, struct Dims *dims)
void wr_abbrevs (FILE *outfile, int function_head, chainp vars)

Variables

static char Blank [] = BLANKCOMMON
static char * postfix []
chainp new_procs
int prev_proc
int proc_argchanges
int proc_protochanges


Define Documentation

#define EXNULL   (union Expression *)0

Definition at line 36 of file proc.c.

Referenced by doentry().

#define roundup ( a,
b   )     ( b * ( (a+b-1)/b) )

Definition at line 34 of file proc.c.

Referenced by docommon().


Function Documentation

static int nextarg Argdcl ( (int  )  [static]

static void doentry Argdcl ( (struct Entrypoint *)   )  [static]

static void dobss Argdcl ( (void)   )  [static]

Addrp autovar ( register int  nelt0,
register int  t,
expptr  lengp,
char *  name 
)

Definition at line 1230 of file proc.c.

References ALLOC, autonum, av_pfix, declare_new_addr(), Fatal(), ICON, Addrblock::ident, Addrblock::isarray, ISICON, Addrblock::memoffset, Dimblock::nelt, Addrblock::ntempelt, STGAUTO, TADDR, Addrblock::tag, temp_name(), TYCHAR, typesize, UNAM_IDENT, Addrblock::uname_tag, unamstring(), Addrblock::user, Addrblock::varleng, Addrblock::vleng, Addrblock::vstg, and Addrblock::vtype.

Referenced by doentry(), endioctl(), settype(), and startrw().

01232 {
01233         ftnint leng;
01234         register Addrp q;
01235         register int nelt = nelt0 > 0 ? nelt0 : 1;
01236         extern char *av_pfix[];
01237 
01238         if(t == TYCHAR)
01239                 if( ISICON(lengp) )
01240                         leng = lengp->constblock.Const.ci;
01241                 else    {
01242                         Fatal("automatic variable of nonconstant length");
01243                 }
01244         else
01245                 leng = typesize[t];
01246 
01247         q = ALLOC(Addrblock);
01248         q->tag = TADDR;
01249         q->vtype = t;
01250         if(t == TYCHAR)
01251         {
01252                 q->vleng = ICON(leng);
01253                 q->varleng = leng;
01254         }
01255         q->vstg = STGAUTO;
01256         q->ntempelt = nelt;
01257         q->isarray = (nelt > 1);
01258         q->memoffset = ICON(0);
01259 
01260         /* kludge for nls so we can have ret_val rather than ret_val_4 */
01261         if (*name == ' ')
01262                 unamstring(q, name);
01263         else {
01264                 q->uname_tag = UNAM_IDENT;
01265                 temp_name(av_pfix[t], ++autonum[t], q->user.ident);
01266                 }
01267         if (nelt0 > 0)
01268                 declare_new_addr (q);
01269         return(q);
01270 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void bad_dimtype ( Namep  q  )  [static]

Definition at line 666 of file proc.c.

References errstr(), and Nameblock::fvarname.

Referenced by dim_check(), and dim_finish().

00668 {
00669         errstr("bad dimension type for %.70s", q->fvarname);
00670         }

Here is the call graph for this function:

Here is the caller graph for this function:

void changedtype ( Namep  q  ) 

Definition at line 62 of file proc.c.

References Extsym::arginfo, buf, Argtypes::changes, Argtypes::defined, extsymtab, Extsym::extype, Extsym::exused, ftn_types, Nameblock::fvarname, TYSUBR, TYUNKNOWN, Nameblock::vardesc, Nameblock::varno, Nameblock::vtype, Nameblock::vtypewarned, and warn().

Referenced by doentry(), fixexttype(), and settype().

00064 {
00065         char buf[200];
00066         int qtype, type1;
00067         register Extsym *e;
00068         Argtypes *at;
00069 
00070         if (q->vtypewarned)
00071                 return;
00072         q->vtypewarned = 1;
00073         qtype = q->vtype;
00074         e = &extsymtab[q->vardesc.varno];
00075         if (!(at = e->arginfo)) {
00076                 if (!e->exused)
00077                         return;
00078                 }
00079         else if (at->changes & 2 && qtype != TYUNKNOWN && !at->defined)
00080                 proc_protochanges++;
00081         type1 = e->extype;
00082         if (type1 == TYUNKNOWN)
00083                 return;
00084         if (qtype == TYUNKNOWN)
00085                 /* e.g.,
00086                         subroutine foo
00087                         end
00088                         external foo
00089                         call goo(foo)
00090                         end
00091                 */
00092                 return;
00093         sprintf(buf, "%.90s: inconsistent declarations:\n\
00094         here %s%s, previously %s%s.", q->fvarname, ftn_types[qtype],
00095                 qtype == TYSUBR ? "" : " function",
00096                 ftn_types[type1], type1 == TYSUBR ? "" : " function");
00097         warn(buf);
00098         }

Here is the call graph for this function:

Here is the caller graph for this function:

Extsym* comblock ( register char *  s  ) 

Definition at line 1380 of file proc.c.

References errstr(), i, mkext1(), p, STGCOMMON, and STGUNKNOWN.

Referenced by yyparse().

01382 {
01383         Extsym *p;
01384         register char *t;
01385         register int c, i;
01386         char cbuf[256], *s0;
01387 
01388 /* Give the unnamed common block a unique name */
01389 
01390         if(*s == 0)
01391                 p = mkext1(s0 = Blank, Blank);
01392         else {
01393                 s0 = s;
01394                 t = cbuf;
01395                 for(i = 0; c = *t = *s++; t++)
01396                         if (c == '_')
01397                                 i = 1;
01398                 if (i)
01399                         *t++ = '_';
01400                 t[0] = '_';
01401                 t[1] = 0;
01402                 p = mkext1(s0,cbuf);
01403                 }
01404         if(p->extstg == STGUNKNOWN)
01405                 p->extstg = STGCOMMON;
01406         else if(p->extstg != STGCOMMON)
01407         {
01408                 errstr("%.52s cannot be a common block: it is a subprogram.",
01409                         s0);
01410                 return(0);
01411         }
01412 
01413         return( p );
01414 }

Here is the call graph for this function:

Here is the caller graph for this function:

void copy_data ( chainp  list  ) 

Definition at line 1131 of file proc.c.

References ALLOC, ckalloc(), cpexpr(), cpn(), Chain::datap, dims, Dimblock::dimsize, gmem(), i, int, nd, ndim, and size.

Referenced by endproc().

01133 {
01134     for (; list; list = list -> nextp) {
01135         Namep namep = ALLOC (Nameblock);
01136         int size, nd, i;
01137         struct Dimblock *dp;
01138 
01139         cpn(sizeof(struct Nameblock), list->datap, (char *)namep);
01140         namep->fvarname = strcpy(gmem(strlen(namep->fvarname)+1,0),
01141                 namep->fvarname);
01142         namep->cvarname = strcmp(namep->fvarname, namep->cvarname)
01143                 ? strcpy(gmem(strlen(namep->cvarname)+1,0), namep->cvarname)
01144                 : namep->fvarname;
01145         if (namep -> vleng)
01146             namep -> vleng = (expptr) cpexpr (namep -> vleng);
01147         if (namep -> vdim) {
01148             nd = namep -> vdim -> ndim;
01149             size = sizeof(int) + (3 + 2 * nd) * sizeof (expptr);
01150             dp = (struct Dimblock *) ckalloc (size);
01151             cpn(size, (char *)namep->vdim, (char *)dp);
01152             namep -> vdim = dp;
01153             dp->nelt = (expptr)cpexpr(dp->nelt);
01154             for (i = 0; i < nd; i++) {
01155                 dp -> dims[i].dimsize = (expptr) cpexpr (dp -> dims[i].dimsize);
01156             } /* for */
01157         } /* if */
01158         list -> datap = (char *) namep;
01159     } /* for */
01160 } /* copy_data */

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL void dim_check ( Namep  q  ) 

Definition at line 909 of file proc.c.

References bad_dimtype(), Constant::cd, Constant::ci, Constblock::Const, Expression::constblock, dclerr(), Expression::headblock, ISCONST, ISINT, MSKINT, MSKREAL, Dimblock::nelt, ONEOF, Nameblock::vdim, and Headblock::vtype.

00911 {
00912         register struct Dimblock *vdim = q->vdim;
00913         register expptr nelt;
00914 
00915         if(!(nelt = vdim->nelt) || !ISCONST(nelt))
00916                 dclerr("adjustable dimension on non-argument", q);
00917         else if (!ONEOF(nelt->headblock.vtype, MSKINT|MSKREAL))
00918                 bad_dimtype(q);
00919         else if (ISINT(nelt->headblock.vtype)
00920                         ? nelt->constblock.Const.ci <= 0
00921                         : nelt->constblock.Const.cd[0] <= 0.)
00922                 dclerr("nonpositive dimension", q);
00923         }

Here is the call graph for this function:

static void dim_finish ( Namep  v  )  [static]

Definition at line 685 of file proc.c.

References bad_dimtype(), doin_setbound, fixtype(), Expression::headblock, i, make_int_expr(), MSKINT, MSKREAL, nd, ONEOF, p, putx(), v, and Headblock::vtype.

Referenced by doentry().

00687 {
00688         register struct Dimblock *p;
00689         register expptr q;
00690         register int i, nd;
00691 
00692         p = v->vdim;
00693         v->vdimfinish = 0;
00694         nd = p->ndim;
00695         doin_setbound = 1;
00696         for(i = 0; i < nd; i++)
00697                 if (q = p->dims[i].dimexpr) {
00698                         q = p->dims[i].dimexpr = make_int_expr(putx(fixtype(q)));
00699                         if (!ONEOF(q->headblock.vtype, MSKINT|MSKREAL))
00700                                 bad_dimtype(v);
00701                         }
00702         if (q = p->basexpr)
00703                 p->basexpr = make_int_expr(putx(fixtype(q)));
00704         doin_setbound = 0;
00705         }

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL void dobss ( Void   ) 

Definition at line 926 of file proc.c.

References CLUNKNOWN, CLVAR, Nameblock::fvarname, lasthash, p, STGARG, STGUNKNOWN, Nameblock::vclass, Nameblock::vimpldovar, Nameblock::vis_assigned, Nameblock::vstg, Nameblock::vtype, and warn1().

Referenced by endproc().

00927 {
00928         register struct Hashentry *p;
00929         register Namep q;
00930         int qstg, qclass, qtype;
00931         Extsym *e;
00932 
00933         for(p = hashtab ; p<lasthash ; ++p)
00934                 if(q = p->varp)
00935                 {
00936                         qstg = q->vstg;
00937                         qtype = q->vtype;
00938                         qclass = q->vclass;
00939 
00940                         if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
00941                             (qclass==CLVAR && qstg==STGUNKNOWN) ) {
00942                                 if (!(q->vis_assigned | q->vimpldovar))
00943                                         warn1("local variable %s never used",
00944                                                 q->fvarname);
00945                                 }
00946                         else if(qclass==CLVAR && qstg==STGBSS)
00947                         { ; }
00948 
00949 /* Give external procedures the proper storage class */
00950 
00951                         else if(qclass==CLPROC && q->vprocclass==PEXTERNAL
00952                                         && qstg!=STGARG) {
00953                                 e = mkext(q->fvarname,addunder(q->cvarname));
00954                                 e->extstg = STGEXT;
00955                                 q->vardesc.varno = e - extsymtab;
00956                                 if (e->extype != qtype)
00957                                         changedtype(q);
00958                                 }
00959                         if(qclass==CLVAR) {
00960                             if (qstg != STGARG && q->vdim)
00961                                 dim_check(q);
00962                         } /* if qclass == CLVAR */
00963                 }
00964 
00965 }

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL void docomleng ( Void   ) 

Definition at line 1165 of file proc.c.

References extsymtab, nextext, p, STGCOMMON, and warn1().

Referenced by enddcl().

01166 {
01167         register Extsym *p;
01168 
01169         for(p = extsymtab ; p < nextext ; ++p)
01170                 if(p->extstg == STGCOMMON)
01171                 {
01172                         if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
01173                             && strcmp(Blank, p->cextname) )
01174                                 warn1("incompatible lengths for common block %.60s",
01175                                     p->fextname);
01176                         if(p->maxleng < p->extleng)
01177                                 p->maxleng = p->extleng;
01178                         p->extleng = 0;
01179                 }
01180 }

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL void docommon ( Void   ) 

Definition at line 1041 of file proc.c.

References Constant::ci, Constblock::Const, Expression::constblock, Chain::datap, dclerr(), Extsym::extleng, Extsym::extp, Extsym::extstg, extsymtab, i, ISCONST, nerr, nextext, Chain::nextp, NO, revchain(), roundup, size, STGCOMMON, t, TYCHAR, type_pref, typealign, typesize, vardcl(), Nameblock::vardesc, Nameblock::varno, Nameblock::vdcldone, Nameblock::vdim, Nameblock::vleng, and Nameblock::voffset.

Referenced by enddcl().

01042 {
01043     register Extsym *extptr;
01044     register chainp q, q1;
01045     struct Dimblock *t;
01046     expptr neltp;
01047     register Namep comvar;
01048     ftnint size;
01049     int i, k, pref, type;
01050     extern int type_pref[];
01051 
01052     for(extptr = extsymtab ; extptr<nextext ; ++extptr)
01053         if (extptr->extstg == STGCOMMON && (q = extptr->extp)) {
01054 
01055 /* If a common declaration also had a list of variables ... */
01056 
01057             q = extptr->extp = revchain(q);
01058             pref = 1;
01059             for(k = TYCHAR; q ; q = q->nextp)
01060             {
01061                 comvar = (Namep) (q->datap);
01062 
01063                 if(comvar->vdcldone == NO)
01064                     vardcl(comvar);
01065                 type = comvar->vtype;
01066                 if (pref < type_pref[type])
01067                         pref = type_pref[k = type];
01068                 if(extptr->extleng % typealign[type] != 0) {
01069                     dclerr("common alignment", comvar);
01070                     --nerr; /* don't give bad return code for this */
01071 #if 0
01072                     extptr->extleng = roundup(extptr->extleng, typealign[type]);
01073 #endif
01074                 } /* if extptr -> extleng % */
01075 
01076 /* Set the offset into the common block */
01077 
01078                 comvar->voffset = extptr->extleng;
01079                 comvar->vardesc.varno = extptr - extsymtab;
01080                 if(type == TYCHAR)
01081                         if (comvar->vleng)
01082                                 size = comvar->vleng->constblock.Const.ci;
01083                         else  {
01084                                 dclerr("character*(*) in common", comvar);
01085                                 size = 1;
01086                                 }
01087                 else
01088                         size = typesize[type];
01089                 if(t = comvar->vdim)
01090                     if( (neltp = t->nelt) && ISCONST(neltp) )
01091                         size *= neltp->constblock.Const.ci;
01092                     else
01093                         dclerr("adjustable array in common", comvar);
01094 
01095 /* Adjust the length of the common block so far */
01096 
01097                 extptr->extleng += size;
01098             } /* for */
01099 
01100             extptr->extype = k;
01101 
01102 /* Determine curno and, if new, save this identifier chain */
01103 
01104             q1 = extptr->extp;
01105             for (q = extptr->allextp, i = 0; q; i++, q = q->nextp)
01106                 if (struct_eq((chainp)q->datap, q1))
01107                         break;
01108             if (q)
01109                 extptr->curno = extptr->maxno - i;
01110             else {
01111                 extptr->curno = ++extptr->maxno;
01112                 extptr->allextp = mkchain((char *)extptr->extp,
01113                                                 extptr->allextp);
01114                 }
01115         } /* if extptr -> extstg == STGCOMMON */
01116 
01117 /* Now the hash table entries have STGCOMMON, vdcldone, voffset, and
01118    varno.  And the common block itself has its full size in extleng. */
01119 
01120 } /* docommon */

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL void doentry ( struct Entrypoint ep  ) 

Definition at line 726 of file proc.c.

References Expression::addrblock, allargs, Extsym::arginfo, Entrypoint::arglist, autovar(), changedtype(), chlgslot, chslot, Constant::ci, CLBLOCK, CLMAIN, CLPROC, Constblock::Const, Expression::constblock, cxslot, Chain::datap, dclerr(), dflttype, dim_finish(), duparg(), Entrypoint::entryname, err, EXNULL, Extsym::exproto, Extsym::extseen, extsymtab, Extsym::extype, Extsym::fextname, Nameblock::fvarname, ICON, Addrblock::ident, impldcl(), infertypes, int, ISCOMPLEX, ISCONST, it, letter, mkarg(), mkchain(), mkname(), multitype, nallargs, nallchargs, nentry, new_arg_length(), new_func_length(), newlabel(), nextarg(), Chain::nextp, NULL, p, p1_label(), procclass, procleng, proctype, retslot, rtvlabel, save_argtypes(), STGARG, STGAUTO, STGEXT, TYADDR, TYCHAR, TYLENG, Entrypoint::typelabel, TYSUBR, TYUNKNOWN, UNAM_IDENT, Addrblock::uname_tag, unamstring(), Addrblock::user, Nameblock::vardesc, Nameblock::varno, Nameblock::vclass, Nameblock::vdcldone, Nameblock::vknownarg, Nameblock::vleng, Nameblock::vstg, Nameblock::vtype, xretslot, and YES.

Referenced by enddcl(), and entrypt().

00728 {
00729         register int type;
00730         register Namep np;
00731         chainp p, p1;
00732         register Namep q;
00733         Addrp rs;
00734         int it, k;
00735         extern char dflttype[26];
00736         Extsym *entryname = ep->entryname;
00737 
00738         if (++nentry > 1)
00739                 p1_label((long)(extsymtab - entryname - 1));
00740 
00741 /* The main program isn't allowed to have parameters, so any given
00742    parameters are ignored */
00743 
00744         if(procclass == CLMAIN && !ep->arglist || procclass == CLBLOCK)
00745                 return;
00746 
00747         /* Entry points in MAIN are an error, but we process them here */
00748         /* to prevent faults elsewhere. */
00749 
00750 /* So now we're working with something other than CLMAIN or CLBLOCK.
00751    Determine the type of its return value. */
00752 
00753         impldcl( np = mkname(entryname->fextname) );
00754         type = np->vtype;
00755         proc_argchanges = prev_proc && type != entryname->extype;
00756         entryname->extseen = 1;
00757         if(proctype == TYUNKNOWN)
00758                 if( (proctype = type) == TYCHAR)
00759                         procleng = np->vleng ? np->vleng->constblock.Const.ci
00760                                              : (ftnint) (-1);
00761 
00762         if(proctype == TYCHAR)
00763         {
00764                 if(type != TYCHAR)
00765                         err("noncharacter entry of character function");
00766 
00767 /* Functions returning type   char   can only have multiple entries if all
00768    entries return the same length */
00769 
00770                 else if( (np->vleng ? np->vleng->constblock.Const.ci :
00771                     (ftnint) (-1)) != procleng)
00772                         err("mismatched character entry lengths");
00773         }
00774         else if(type == TYCHAR)
00775                 err("character entry of noncharacter function");
00776         else if(type != proctype)
00777                 multitype = YES;
00778         if(rtvlabel[type] == 0)
00779                 rtvlabel[type] = (int)newlabel();
00780         ep->typelabel = rtvlabel[type];
00781 
00782         if(type == TYCHAR)
00783         {
00784                 if(chslot < 0)
00785                 {
00786                         chslot = nextarg(TYADDR);
00787                         chlgslot = nextarg(TYLENG);
00788                 }
00789                 np->vstg = STGARG;
00790 
00791 /* Put a new argument in the function, one which will hold the result of
00792    a character function.  This will have to be named sometime, probably in
00793    mkarg(). */
00794 
00795                 if(procleng < 0) {
00796                         np->vleng = (expptr) mkarg(TYLENG, chlgslot);
00797                         np->vleng->addrblock.uname_tag = UNAM_IDENT;
00798                         strcpy (np -> vleng -> addrblock.user.ident,
00799                                 new_func_length());
00800                         }
00801                 if (!xretslot[TYCHAR]) {
00802                         xretslot[TYCHAR] = rs =
00803                                 autovar(0, type, ISCONST(np->vleng)
00804                                         ? np->vleng : ICON(0), "");
00805                         strcpy(rs->user.ident, "ret_val");
00806                         }
00807         }
00808 
00809 /* Handle a   complex   return type -- declare a new parameter (pointer to
00810    a complex value) */
00811 
00812         else if( ISCOMPLEX(type) ) {
00813                 if (!xretslot[type])
00814                         xretslot[type] =
00815                                 autovar(0, type, EXNULL, " ret_val");
00816                                 /* the blank is for use in out_addr */
00817                 np->vstg = STGARG;
00818                 if(cxslot < 0)
00819                         cxslot = nextarg(TYADDR);
00820                 }
00821         else if (type != TYSUBR) {
00822                 if (type == TYUNKNOWN) {
00823                         dclerr("untyped function", np);
00824                         proctype = type = np->vtype =
00825                                 dflttype[letter(np->fvarname[0])];
00826                         }
00827                 if (!xretslot[type])
00828                         xretslot[type] = retslot =
00829                                 autovar(1, type, EXNULL, " ret_val");
00830                                 /* the blank is for use in out_addr */
00831                 np->vstg = STGAUTO;
00832                 }
00833 
00834         for(p = ep->arglist ; p ; p = p->nextp)
00835                 if(! (( q = (Namep) (p->datap) )->vknownarg) ) {
00836                         q->vknownarg = 1;
00837                         q->vardesc.varno = nextarg(TYADDR);
00838                         allargs = mkchain((char *)q, allargs);
00839                         q->argno = nallargs++;
00840                         }
00841                 else if (nentry == 1)
00842                         duparg(q);
00843                 else for(p1 = ep->arglist ; p1 != p; p1 = p1->nextp)
00844                         if ((Namep)p1->datap == q)
00845                                 duparg(q);
00846 
00847         k = 0;
00848         for(p = ep->arglist ; p ; p = p->nextp) {
00849                 if(! (( q = (Namep) (p->datap) )->vdcldone) )
00850                         {
00851                         impldcl(q);
00852                         q->vdcldone = YES;
00853                         if(q->vtype == TYCHAR)
00854                                 {
00855 
00856 /* If we don't know the length of a char*(*) (i.e. a string), we must add
00857    in this additional length argument. */
00858 
00859                                 ++nallchargs;
00860                                 if (q->vclass == CLPROC)
00861                                         nallchargs--;
00862                                 else if (q->vleng == NULL) {
00863                                         /* character*(*) */
00864                                         q->vleng = (expptr)
00865                                             mkarg(TYLENG, nextarg(TYLENG) );
00866                                         unamstring((Addrp)q->vleng,
00867                                                 new_arg_length(q));
00868                                         }
00869                                 }
00870                         }
00871                 if (q->vdimfinish)
00872                         dim_finish(q);
00873                 if (q->vtype == TYCHAR && q->vclass != CLPROC)
00874                         k++;
00875                 }
00876 
00877         if (entryname->extype != type)
00878                 changedtype(np);
00879 
00880         /* save information for checking consistency of arg lists */
00881 
00882         it = infertypes;
00883         if (entryname->exproto)
00884                 infertypes = 1;
00885         save_argtypes(ep->arglist, &entryname->arginfo, &np->arginfo,
00886                         0, np->fvarname, STGEXT, k, np->vtype, 2);
00887         infertypes = it;
00888 }

Here is the call graph for this function:

Here is the caller graph for this function:

void donmlist ( Void   ) 

Definition at line 969 of file proc.c.

References CLNAMELIST, lasthash, namelist(), p, and Nameblock::vclass.

Referenced by endproc().

00970 {
00971         register struct Hashentry *p;
00972         register Namep q;
00973 
00974         for(p=hashtab; p<lasthash; ++p)
00975                 if( (q = p->varp) && q->vclass==CLNAMELIST)
00976                         namelist(q);
00977 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void duparg ( Namep  q  )  [static]

Definition at line 712 of file proc.c.

References errstr(), and Nameblock::fvarname.

Referenced by doentry().

00714 { errstr("duplicate argument %.80s", q->fvarname); }

Here is the call graph for this function:

Here is the caller graph for this function:

void enddcl ( Void   ) 

Definition at line 380 of file proc.c.

References Chain::datap, docomleng(), docommon(), doentry(), doequiv(), earlylabs, entries, err_proc, frchain(), freetemps(), INEXEC, lineno, Chain::nextp, p1_label(), p1_line_number(), P1_PROCODE, p1put(), parstate, and revchain().

Referenced by endproc(), exequals(), and yyparse().

00381 {
00382         register struct Entrypoint *ep;
00383         struct Entrypoint *ep0;
00384         chainp cp;
00385         extern char *err_proc;
00386         static char comblks[] = "common blocks";
00387 
00388         err_proc = comblks;
00389         docommon();
00390 
00391 /* Now the hash table entries for fields of common blocks have STGCOMMON,
00392    vdcldone, voffset, and varno.  And the common blocks themselves have
00393    their full sizes in extleng. */
00394 
00395         err_proc = "equivalences";
00396         doequiv();
00397 
00398         err_proc = comblks;
00399         docomleng();
00400 
00401 /* This implies that entry points in the declarations are buffered in
00402    entries   but not written out */
00403 
00404         err_proc = "entries";
00405         if (ep = ep0 = (struct Entrypoint *)revchain((chainp)entries)) {
00406                 /* entries could be 0 in case of an error */
00407                 do doentry(ep);
00408                         while(ep = ep->entnextp);
00409                 entries = (struct Entrypoint *)revchain((chainp)ep0);
00410                 }
00411 
00412         err_proc = 0;
00413         parstate = INEXEC;
00414         p1put(P1_PROCODE);
00415         freetemps();
00416         if (earlylabs) {
00417                 for(cp = earlylabs = revchain(earlylabs); cp; cp = cp->nextp)
00418                         p1_label((long)cp->datap);
00419                 frchain(&earlylabs);
00420                 }
00421         p1_line_number(lineno); /* for files that start with a MAIN program */
00422                                 /* that starts with an executable statement */
00423 }

Here is the call graph for this function:

Here is the caller graph for this function:

void endproc ( Void   ) 

Definition at line 330 of file proc.c.

References c_file, CHNULL, convic(), copy_data(), ctls, ctlstack, dobss(), donmlist(), enddcl(), epicode(), err, errstr(), extsymtab, fix_entry_returns(), INDATA, labeltab, labtabend, lp, nentry, nextext, NO, parstate, procinit(), putentries(), start_formatting(), STGCOMMON, usedefsforcommon, wr_abbrevs(), and zap_changes().

Referenced by main(), newproc(), startproc(), and yyparse().

00331 {
00332         struct Labelblock *lp;
00333         Extsym *ext;
00334 
00335         if(parstate < INDATA)
00336                 enddcl();
00337         if(ctlstack >= ctls)
00338                 err("DO loop or BLOCK IF not closed");
00339         for(lp = labeltab ; lp < labtabend ; ++lp)
00340                 if(lp->stateno!=0 && lp->labdefined==NO)
00341                         errstr("missing statement label %s",
00342                                 convic(lp->stateno) );
00343 
00344 /* Save copies of the common variables in extptr -> allextp */
00345 
00346         for (ext = extsymtab; ext < nextext; ext++)
00347                 if (ext -> extstg == STGCOMMON && ext -> extp) {
00348                         extern int usedefsforcommon;
00349 
00350 /* Write out the abbreviations for common block reference */
00351 
00352                         copy_data (ext -> extp);
00353                         if (usedefsforcommon) {
00354                                 wr_abbrevs (c_file, 1, ext -> extp);
00355                                 ext -> used_here = 1;
00356                                 }
00357                         else
00358                                 ext -> extp = CHNULL;
00359 
00360                         }
00361 
00362         if (nentry > 1)
00363                 fix_entry_returns();
00364         epicode();
00365         donmlist();
00366         dobss();
00367         start_formatting ();
00368         if (nentry > 1)
00369                 putentries(c_file);
00370 
00371         zap_changes();
00372         procinit();     /* clean up for next procedure */
00373 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void entry_goto ( FILE *  outfile  )  [static]

Definition at line 279 of file proc.c.

References Entrypoint::entnextp, entries, Entrypoint::entryname, extsymtab, next_tab, nice_printf(), prev_tab, and user_label().

Referenced by procode().

00281 {
00282         struct Entrypoint *e = entries;
00283         int k = 0;
00284 
00285         nice_printf(outfile, "switch(n__) {\n");
00286         next_tab(outfile);
00287         while(e = e->entnextp)
00288                 nice_printf(outfile, "case %d: goto %s;\n", ++k,
00289                         user_label((long)(extsymtab - e->entryname - 1)));
00290         nice_printf(outfile, "}\n\n");
00291         prev_tab(outfile);
00292         }

Here is the call graph for this function:

Here is the caller graph for this function:

void entrypt ( int  Class,
int  type,
ftnint  length,
Extsym entry,
chainp  args 
)

Definition at line 523 of file proc.c.

References ALLOC, args, Extsym::cextname, CLENTRY, CLPROC, diagfile, doentry(), entries, Extsym::fextname, INDATA, lengtype(), mkname(), p, parstate, procclass, procleng, procname, proctype, PTHISPROC, puthead(), revchain(), settype(), STGEXT, TYCHAR, TYSUBR, Nameblock::vclass, Nameblock::vprocclass, and Nameblock::vstg.

Referenced by startproc(), and yyparse().

00525 {
00526         register Namep q;
00527         register struct Entrypoint *p;
00528 
00529         if(Class != CLENTRY)
00530                 puthead( procname = entry->cextname, Class);
00531         else
00532                 fprintf(diagfile, "       entry ");
00533         fprintf(diagfile, "   %s:\n", entry->fextname);
00534         fflush(diagfile);
00535         q = mkname(entry->fextname);
00536         if (type == TYSUBR)
00537                 q->vstg = STGEXT;
00538 
00539         type = lengtype(type, length);
00540         if(Class == CLPROC)
00541         {
00542                 procclass = CLPROC;
00543                 proctype = type;
00544                 procleng = type == TYCHAR ? length : 0;
00545         }
00546 
00547         p = ALLOC(Entrypoint);
00548 
00549         p->entnextp = entries;
00550         entries = p;
00551 
00552         p->entryname = entry;
00553         p->arglist = revchain(args);
00554         p->enamep = q;
00555 
00556         if(Class == CLENTRY)
00557         {
00558                 Class = CLPROC;
00559                 if(proctype == TYSUBR)
00560                         type = TYSUBR;
00561         }
00562 
00563         q->vclass = Class;
00564         q->vprocclass = 0;
00565         settype(q, type, length);
00566         q->vprocclass = PTHISPROC;
00567         /* hold all initial entry points till end of declarations */
00568         if(parstate >= INDATA)
00569                 doentry(p);
00570 }

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL void epicode ( Void   ) 

Definition at line 579 of file proc.c.

References Ansi, CLMAIN, CLPROC, ICON, lastwasbranch, multitype, NO, p1_subr_ret(), procclass, proctype, retval(), substars, TYSUBR, and YES.

Referenced by endproc().

00580 {
00581         extern int lastwasbranch;
00582 
00583         if(procclass==CLPROC)
00584         {
00585                 if(proctype==TYSUBR)
00586                 {
00587 
00588 /* Return a zero only when the alternate return mechanism has been
00589    specified in the function header */
00590 
00591                         if ((substars || Ansi) && lastwasbranch != YES)
00592                             p1_subr_ret (ICON(0));
00593                 }
00594                 else if (!multitype && lastwasbranch != YES)
00595                         retval(proctype);
00596         }
00597         else if (procclass == CLMAIN && Ansi && lastwasbranch != YES)
00598                 p1_subr_ret (ICON(0));
00599         lastwasbranch = NO;
00600 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void fix_entry_returns ( Void   )  [static]

Definition at line 125 of file proc.c.

References a, allargs, Entrypoint::enamep, entries, i, multitype, revchain(), STGARG, TYCOMPLEX, TYDCOMPLEX, TYDREAL, TYINT1, TYLOGICAL, TYLOGICAL1, TYLOGICAL2, TYLONG, TYQUAD, TYREAL, TYSHORT, Nameblock::vstg, Nameblock::vtype, and xretslot.

Referenced by endproc().

00126 {
00127         Addrp a;
00128         int i;
00129         struct Entrypoint *e;
00130         Namep np;
00131 
00132         e = entries = (struct Entrypoint *)revchain((chainp)entries);
00133         allargs = revchain(allargs);
00134         if (!multitype)
00135                 return;
00136 
00137         /* TYLOGICAL should have been turned into TYLONG or TYSHORT by now */
00138 
00139         for(i = TYINT1; i <= TYLOGICAL; i++)
00140                 if (a = xretslot[i])
00141                         sprintf(a->user.ident, "(*ret_val).%s",
00142                                 postfix[i-TYINT1]);
00143 
00144         do {
00145                 np = e->enamep;
00146                 switch(np->vtype) {
00147                         case TYINT1:
00148                         case TYSHORT:
00149                         case TYLONG:
00150 #ifdef TYQUAD
00151                         case TYQUAD:
00152 #endif
00153                         case TYREAL:
00154                         case TYDREAL:
00155                         case TYCOMPLEX:
00156                         case TYDCOMPLEX:
00157                         case TYLOGICAL1:
00158                         case TYLOGICAL2:
00159                         case TYLOGICAL:
00160                                 np->vstg = STGARG;
00161                         }
00162                 }
00163                 while(e = e->entnextp);
00164         }

Here is the call graph for this function:

Here is the caller graph for this function:

void freetemps ( Void   ) 

Definition at line 1198 of file proc.c.

References frexpr(), holdtemps, ICON, p, templist, TYCHAR, Addrblock::varleng, Addrblock::vleng, and Addrblock::vtype.

Referenced by enddcl(), and yyparse().

01199 {
01200         register chainp p, p1;
01201         register Addrp q;
01202         register int t;
01203 
01204         p1 = holdtemps;
01205         while(p = p1) {
01206                 q = (Addrp)p->datap;
01207                 t = q->vtype;
01208                 if (t == TYCHAR && q->varleng != 0) {
01209                         /* restore clobbered character string lengths */
01210                         frexpr(q->vleng);
01211                         q->vleng = ICON(q->varleng);
01212                         }
01213                 p1 = p->nextp;
01214                 p->nextp = templist[t];
01215                 templist[t] = p;
01216                 }
01217         holdtemps = 0;
01218         }

Here is the call graph for this function:

Here is the caller graph for this function:

void frtemp ( Addrp  p  ) 

Definition at line 1190 of file proc.c.

References holdtemps, mkchain(), and p.

Referenced by enddo(), mktmp(), and putcat().

01192 {
01193         /* put block on chain of temps to be reclaimed */
01194         holdtemps = mkchain((char *)p, holdtemps);
01195 }

Here is the call graph for this function:

Here is the caller graph for this function:

ftnint iarrlen ( register Namep  q  ) 

Definition at line 987 of file proc.c.

References ISICON, and typesize.

00989 {
00990         ftnint leng;
00991 
00992         leng = typesize[q->vtype];
00993         if(leng <= 0)
00994                 return(-1);
00995         if(q->vdim)
00996                 if( ISICON(q->vdim->nelt) )
00997                         leng *= q->vdim->nelt->constblock.Const.ci;
00998                 else    return(-1);
00999         if(q->vleng)
01000                 if( ISICON(q->vleng) )
01001                         leng *= q->vleng->constblock.Const.ci;
01002                 else return(-1);
01003         return(leng);
01004 }

void incomm ( Extsym c,
Namep  v 
)

Definition at line 1425 of file proc.c.

References dclerr(), Extsym::extp, mkchain(), STGARG, STGCOMMON, STGUNKNOWN, and v.

Referenced by yyparse().

01427 {
01428         if (!c)
01429                 return;
01430         if(v->vstg != STGUNKNOWN && !v->vimplstg)
01431                 dclerr(v->vstg == STGARG
01432                         ? "dummy arguments cannot be in common"
01433                         : "incompatible common declaration", v);
01434         else
01435         {
01436                 v->vstg = STGCOMMON;
01437                 c->extp = mkchain((char *)v, c->extp);
01438         }
01439 }

Here is the call graph for this function:

Here is the caller graph for this function:

int lengtype ( register int  type,
ftnint  len 
)

Definition at line 1537 of file proc.c.

References badtype(), err, int, TYCHAR, TYCOMPLEX, TYDCOMPLEX, TYDREAL, TYERROR, tyint, TYINT1, tylog, TYLOGICAL, TYLOGICAL1, TYLOGICAL2, TYLONG, typesize, TYQUAD, TYREAL, TYSHORT, TYSUBR, TYUNKNOWN, and use_tyquad.

Referenced by entrypt(), setimpl(), and settype().

01539 {
01540         register int length = (int)len;
01541         switch(type)
01542         {
01543         case TYREAL:
01544                 if(length == typesize[TYDREAL])
01545                         return(TYDREAL);
01546                 if(length == typesize[TYREAL])
01547                         goto ret;
01548                 break;
01549 
01550         case TYCOMPLEX:
01551                 if(length == typesize[TYDCOMPLEX])
01552                         return(TYDCOMPLEX);
01553                 if(length == typesize[TYCOMPLEX])
01554                         goto ret;
01555                 break;
01556 
01557         case TYINT1:
01558         case TYSHORT:
01559         case TYDREAL:
01560         case TYDCOMPLEX:
01561         case TYCHAR:
01562         case TYLOGICAL1:
01563         case TYLOGICAL2:
01564         case TYUNKNOWN:
01565         case TYSUBR:
01566         case TYERROR:
01567 #ifdef TYQUAD
01568         case TYQUAD:
01569 #endif
01570                 goto ret;
01571 
01572         case TYLOGICAL:
01573                 switch(length) {
01574                         case 0: return tylog;
01575                         case 1: return TYLOGICAL1;
01576                         case 2: return TYLOGICAL2;
01577                         case 4: goto ret;
01578                         }
01579                 break;
01580 
01581         case TYLONG:
01582                 if(length == 0)
01583                         return(tyint);
01584                 if (length == 1)
01585                         return TYINT1;
01586                 if(length == typesize[TYSHORT])
01587                         return(TYSHORT);
01588 #ifdef TYQUAD
01589                 if(length == typesize[TYQUAD] && use_tyquad)
01590                         return(TYQUAD);
01591 #endif
01592                 if(length == typesize[TYLONG])
01593                         goto ret;
01594                 break;
01595         default:
01596                 badtype("lengtype", type);
01597         }
01598 
01599         if(len != 0)
01600                 err("incompatible type-length combination");
01601 
01602 ret:
01603         return(type);
01604 }

Here is the call graph for this function:

Here is the caller graph for this function:

Addrp mktmp ( int  type,
expptr  lengp 
)

Definition at line 1341 of file proc.c.

References cpexpr(), frtemp(), and mktmpn().

Referenced by cast_args(), doiolist(), endioctl(), exarif(), exdo(), Inline(), intdouble(), krput(), putch1(), putcx1(), putmnmx(), putop(), putpower(), stfcall(), subcheck(), and suboffset().

01343 {
01344         Addrp rv;
01345         /* arrange for temporaries to be recycled */
01346         /* at the end of this statement... */
01347         rv = mktmpn(1,type,lengp);
01348         frtemp((Addrp)cpexpr((expptr)rv));
01349         return rv;
01350 }

Here is the call graph for this function:

Here is the caller graph for this function:

Addrp mktmp0 ( int  type,
expptr  lengp 
)

Definition at line 1359 of file proc.c.

References Addrblock::istemp, mktmpn(), and YES.

Referenced by exdo().

01361 {
01362         Addrp rv;
01363         /* arrange for temporaries to be recycled */
01364         /* when this Addrp is freed */
01365         rv = mktmpn(1,type,lengp);
01366         rv->istemp = YES;
01367         return rv;
01368 }

Here is the call graph for this function:

Here is the caller graph for this function:

Addrp mktmpn ( int  nelt,
register int  type,
expptr  lengp 
)

Definition at line 1283 of file proc.c.

References badtype(), CHNULL, Constant::ci, Constblock::Const, Expression::constblock, err, erri(), errnode, free(), ISICON, krparens, M, Chain::nextp, Addrblock::ntempelt, ONEOF, p, templist, TYADDR, TYCHAR, TYCOMPLEX, TYERROR, TYREAL, TYUNKNOWN, and Addrblock::vleng.

Referenced by mktmp(), mktmp0(), and putcat().

01285 {
01286         ftnint leng;
01287         chainp p, oldp;
01288         register Addrp q;
01289         extern int krparens;
01290 
01291         if(type==TYUNKNOWN || type==TYERROR)
01292                 badtype("mktmpn", type);
01293 
01294         if(type==TYCHAR)
01295                 if(lengp && ISICON(lengp) )
01296                         leng = lengp->constblock.Const.ci;
01297                 else    {
01298                         err("adjustable length");
01299                         return( (Addrp) errnode() );
01300                 }
01301         else if (type > TYCHAR || type < TYADDR) {
01302                 erri("mktmpn: unexpected type %d", type);
01303                 exit(1);
01304                 }
01305 /*
01306  * if a temporary of appropriate shape is on the templist,
01307  * remove it from the list and return it
01308  */
01309         if (krparens == 2 && ONEOF(type,M(TYREAL)|M(TYCOMPLEX)))
01310                 type++;
01311         for(oldp=CHNULL, p=templist[type];  p  ;  oldp=p, p=p->nextp)
01312         {
01313                 q = (Addrp) (p->datap);
01314                 if(q->ntempelt==nelt &&
01315                     (type!=TYCHAR || q->vleng->constblock.Const.ci==leng) )
01316                 {
01317                         if(oldp)
01318                                 oldp->nextp = p->nextp;
01319                         else
01320                                 templist[type] = p->nextp;
01321                         free( (charptr) p);
01322                         return(q);
01323                 }
01324         }
01325         q = autovar(nelt, type, lengp, "");
01326         return(q);
01327 }

Here is the call graph for this function:

Here is the caller graph for this function:

void namelist ( Namep  np  ) 

Definition at line 1011 of file proc.c.

References Chain::datap, dclerr(), MSKSTATIC, Nameblock::namelist, Chain::nextp, ONEOF, v, vardcl(), Nameblock::varxptr, Nameblock::visused, and y.

Referenced by donmlist().

01013 {
01014         register chainp q;
01015         register Namep v;
01016         int y;
01017 
01018         if (!np->visused)
01019                 return;
01020         y = 0;
01021 
01022         for(q = np->varxptr.namelist ; q ; q = q->nextp)
01023         {
01024                 vardcl( v = (Namep) (q->datap) );
01025                 if( !ONEOF(v->vstg, MSKSTATIC) )
01026                         dclerr("may not appear in namelist", v);
01027                 else {
01028                         v->vnamelist = 1;
01029                         v->visused = 1;
01030                         v->vsave = 1;
01031                         y = 1;
01032                         }
01033         np->visused = y;
01034         }
01035 }

Here is the call graph for this function:

Here is the caller graph for this function:

Extsym* newentry ( register Namep  v,
int  substmsg 
)

Definition at line 480 of file proc.c.

References addunder(), buf, CLPROC, dclerr(), extsymtab, M, mkext(), ONEOF, p, PTHISPROC, STGAUTO, STGEXT, STGUNKNOWN, and YES.

Referenced by startproc(), and yyparse().

00482 {
00483         register Extsym *p;
00484         char buf[128], badname[64];
00485         static int nbad = 0;
00486         static char already[] = "external name already used";
00487 
00488         p = mkext(v->fvarname, addunder(v->cvarname));
00489 
00490         if(p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
00491         {
00492                 sprintf(badname, "%s_bad%d", v->fvarname, ++nbad);
00493                 if (substmsg) {
00494                         sprintf(buf,"%s\n\tsubstituting \"%s\"",
00495                                 already, badname);
00496                         dclerr(buf, v);
00497                         }
00498                 else
00499                         dclerr(already, v);
00500                 p = mkext(v->fvarname, badname);
00501         }
00502         v->vstg = STGAUTO;
00503         v->vprocclass = PTHISPROC;
00504         v->vclass = CLPROC;
00505         if (p->extstg == STGEXT)
00506                 prev_proc = 1;
00507         else
00508                 p->extstg = STGEXT;
00509         p->extinit = YES;
00510         v->vardesc.varno = p - extsymtab;
00511         return(p);
00512 }

Here is the call graph for this function:

Here is the caller graph for this function:

void newproc ( Void   ) 

Definition at line 297 of file proc.c.

References CLMAIN, CNULL, endproc(), execerr(), INSIDE, OUTSIDE, parstate, and procclass.

Referenced by startproc(), and yyparse().

00298 {
00299         if(parstate != OUTSIDE)
00300         {
00301                 execerr("missing end statement", CNULL);
00302                 endproc();
00303         }
00304 
00305         parstate = INSIDE;
00306         procclass = CLMAIN;     /* default */
00307 }

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL int nextarg ( int  type  ) 

Definition at line 897 of file proc.c.

References lastargslot.

Referenced by doentry().

00899 {
00900         type = type;    /* shut up warning */
00901         return(lastargslot++);
00902         }

Here is the caller graph for this function:

void procode ( FILE *  outfile  ) 

Definition at line 653 of file proc.c.

References allargs, entry_goto(), nentry, and prolog().

Referenced by do_format().

00655 {
00656         prolog(outfile, allargs);
00657 
00658         if (nentry > 1)
00659                 entry_goto(outfile);
00660         }

Here is the call graph for this function:

Here is the caller graph for this function:

static void putentries ( FILE *  outfile  )  [static]

Definition at line 171 of file proc.c.

References a, A, allargs, Ansi, Entrypoint::arglist, Nameblock::argno, args, base, c_type_decl(), Castargs, ckalloc(), CLPROC, Nameblock::cvarname, dfltarg, dfltproc, Entrypoint::enamep, Entrypoint::entnextp, entries, forcedouble, frchain(), free(), i, Addrblock::ident, ISCOMPLEX, length_comp(), list_arg_types(), listargs(), MAXNAMELEN, memset(), mt, multitype, nallargs, nallchargs, new_arg_length(), next_tab, Chain::nextp, nice_printf(), prev_tab, proctype, protofile, protowrite(), t, TYCHAR, TYCOMPLEX, TYDCOMPLEX, TYDREAL, TYINT1, TYLOGICAL, type, TYREAL, TYSUBR, TYUNKNOWN, Nameblock::vclass, Nameblock::vtype, and xretslot.

Referenced by endproc().

00174 {
00175         char base[MAXNAMELEN+4];
00176         struct Entrypoint *e;
00177         Namep *A, *Ae, *Ae1, **Alp, *a, **a1, np;
00178         chainp args, lengths;
00179         int i, k, mt, nL, t, type;
00180         extern char *dfltarg[], **dfltproc;
00181 
00182         e = entries;
00183         if (!e->enamep) /* only possible with erroneous input */
00184                 return;
00185         nL = (nallargs + nallchargs) * sizeof(Namep *);
00186         if (!nL)
00187                 nL = 8;
00188         A = (Namep *)ckalloc(nL + nallargs*sizeof(Namep **));
00189         Ae = A + nallargs;
00190         Alp = (Namep **)(Ae1 = Ae + nallchargs);
00191         i = k = 0;
00192         for(a1 = Alp, args = allargs; args; a1++, args = args->nextp) {
00193                 np = (Namep)args->datap;
00194                 if (np->vtype == TYCHAR && np->vclass != CLPROC)
00195                         *a1 = &Ae[i++];
00196                 }
00197 
00198         mt = multitype;
00199         multitype = 0;
00200         sprintf(base, "%s0_", e->enamep->cvarname);
00201         do {
00202                 np = e->enamep;
00203                 lengths = length_comp(e, 0);
00204                 proctype = type = np->vtype;
00205                 if (protofile)
00206                         protowrite(protofile, type, np->cvarname, e, lengths);
00207                 nice_printf(outfile, "\n%s ", c_type_decl(type, 1));
00208                 nice_printf(outfile, "%s", np->cvarname);
00209                 if (!Ansi) {
00210                         listargs(outfile, e, 0, lengths);
00211                         nice_printf(outfile, "\n");
00212                         }
00213                 list_arg_types(outfile, e, lengths, 0, "\n");
00214                 nice_printf(outfile, "{\n");
00215                 frchain(&lengths);
00216                 next_tab(outfile);
00217                 if (mt)
00218                         nice_printf(outfile,
00219                                 "Multitype ret_val;\n%s(%d, &ret_val",
00220                                 base, k); /*)*/
00221                 else if (ISCOMPLEX(type))
00222                         nice_printf(outfile, "%s(%d,%s", base, k,
00223                                 xretslot[type]->user.ident); /*)*/
00224                 else if (type == TYCHAR)
00225                         nice_printf(outfile,
00226                                 "%s(%d, ret_val, ret_val_len", base, k); /*)*/
00227                 else
00228                         nice_printf(outfile, "return %s(%d", base, k); /*)*/
00229                 k++;
00230                 memset((char *)A, 0, nL);
00231                 for(args = e->arglist; args; args = args->nextp) {
00232                         np = (Namep)args->datap;
00233                         A[np->argno] = np;
00234                         if (np->vtype == TYCHAR && np->vclass != CLPROC)
00235                                 *Alp[np->argno] = np;
00236                         }
00237                 args = allargs;
00238                 for(a = A; a < Ae; a++, args = args->nextp) {
00239                         t = ((Namep)args->datap)->vtype;
00240                         nice_printf(outfile, ", %s", (np = *a)
00241                                 ? np->cvarname
00242                                 : ((Namep)args->datap)->vclass == CLPROC
00243                                 ? dfltproc[((Namep)args->datap)->vimpltype
00244                                         ? (Castargs ? TYUNKNOWN : TYSUBR)
00245                                         : t == TYREAL && forcedouble && !Castargs
00246                                         ? TYDREAL : t]
00247                                 : dfltarg[((Namep)args->datap)->vtype]);
00248                         }
00249                 for(; a < Ae1; a++)
00250                         if (np = *a)
00251                                 nice_printf(outfile, ", %s",
00252                                         new_arg_length(np));
00253                         else
00254                                 nice_printf(outfile, ", (ftnint)0");
00255                 nice_printf(outfile, /*(*/ ");\n");
00256                 if (mt) {
00257                         if (type == TYCOMPLEX)
00258                                 nice_printf(outfile,
00259                     "r_v->r = ret_val.c.r; r_v->i = ret_val.c.i;\n");
00260                         else if (type == TYDCOMPLEX)
00261                                 nice_printf(outfile,
00262                     "r_v->r = ret_val.z.r; r_v->i = ret_val.z.i;\n");
00263                         else if (type <= TYLOGICAL)
00264                                 nice_printf(outfile, "return ret_val.%s;\n",
00265                                         postfix[type-TYINT1]);
00266                         }
00267                 nice_printf(outfile, "}\n");
00268                 prev_tab(outfile);
00269                 }
00270                 while(e = e->entnextp);
00271         free((char *)A);
00272         }

Here is the call graph for this function:

Here is the caller graph for this function:

LOCAL void retval ( register int  t  ) 

Definition at line 610 of file proc.c.

References badtype(), cpexpr(), fixtype(), mkconv(), p, p1_subr_ret(), retslot, TYADDR, TYCHAR, TYCOMPLEX, TYDCOMPLEX, TYDREAL, TYINT1, tylogical, TYLOGICAL, TYLOGICAL1, TYLOGICAL2, TYLONG, TYQUAD, TYREAL, and TYSHORT.

Referenced by __PARAMS(), C2F(), call_printf(), do_format(), do_p1_subr_ret(), do_xxprintf(), epicode(), fakecresmat2(), getversionmodule(), int_objfscanf(), is_negatable(), isnegative_const(), Load_primitives_from_file(), MlistGetFieldNumber(), op_assign(), sciprint2(), stcreate(), XmuSnprintf(), and yylex().

00612 {
00613         register Addrp p;
00614 
00615         switch(t)
00616         {
00617         case TYCHAR:
00618         case TYCOMPLEX:
00619         case TYDCOMPLEX:
00620                 break;
00621 
00622         case TYLOGICAL:
00623                 t = tylogical;
00624         case TYINT1:
00625         case TYADDR:
00626         case TYSHORT:
00627         case TYLONG:
00628 #ifdef TYQUAD
00629         case TYQUAD:
00630 #endif
00631         case TYREAL:
00632         case TYDREAL:
00633         case TYLOGICAL1:
00634         case TYLOGICAL2:
00635                 p = (Addrp) cpexpr((expptr)retslot);
00636                 p->vtype = t;
00637                 p1_subr_ret (mkconv (t, fixtype((expptr)p)));
00638                 break;
00639 
00640         default:
00641                 badtype("retval", t);
00642         }
00643 }

Here is the call graph for this function:

Here is the caller graph for this function:

void setbound ( Namep  v,
int  nd,
struct Dims dims 
)

Definition at line 1683 of file proc.c.

References buf, ckalloc(), CLUNKNOWN, CLVAR, dclerr(), dims, doin_setbound, errext(), Expression::headblock, i, ICON, ISINT, new_vars, noextflag, p, Dims::ub, v, and Headblock::vtype.

Referenced by yyparse().

01685 {
01686         expptr q, q0, t;
01687         struct Dimblock *p;
01688         int i;
01689         extern chainp new_vars;
01690         char buf[256];
01691 
01692         if(v->vclass == CLUNKNOWN)
01693                 v->vclass = CLVAR;
01694         else if(v->vclass != CLVAR)
01695         {
01696                 dclerr("only variables may be arrays", v);
01697                 return;
01698         }
01699 
01700         v->vdim = p = (struct Dimblock *)
01701             ckalloc( sizeof(int) + (3+2*nd)*sizeof(expptr) );
01702         p->ndim = nd--;
01703         p->nelt = ICON(1);
01704         doin_setbound = 1;
01705 
01706         if (noextflag)
01707                 for(i = 0; i <= nd; i++)
01708                         if (((q = dims[i].lb) && !ISINT(q->headblock.vtype))
01709                          || ((q = dims[i].ub) && !ISINT(q->headblock.vtype))) {
01710                                 sprintf(buf, "dimension %d of %s is not an integer.",
01711                                         i+1, v->fvarname);
01712                                 errext(buf);
01713                                 break;
01714                                 }
01715 
01716         for(i = 0; i <= nd; i++) {
01717                 if (((q = dims[i].lb) && !ISINT(q->headblock.vtype)))
01718                         dims[i].lb = mkconv(TYINT, q);
01719                 if (((q = dims[i].ub) && !ISINT(q->headblock.vtype)))
01720                         dims[i].ub = mkconv(TYINT, q);
01721                 }
01722 
01723         for(i = 0; i <= nd; ++i)
01724         {
01725                 if( (q = dims[i].ub) == NULL)
01726                 {
01727                         if(i == nd)
01728                         {
01729                                 frexpr(p->nelt);
01730                                 p->nelt = NULL;
01731                         }
01732                         else
01733                                 err("only last bound may be asterisk");
01734                         p->dims[i].dimsize = ICON(1);
01735                         p->dims[i].dimexpr = NULL;
01736                 }
01737                 else
01738                 {
01739 
01740                         if(dims[i].lb)
01741                         {
01742                                 q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
01743                                 q = mkexpr(OPPLUS, q, ICON(1) );
01744                         }
01745                         if( ISCONST(q) )
01746                         {
01747                                 p->dims[i].dimsize = q;
01748                                 p->dims[i].dimexpr = (expptr) PNULL;
01749                         }
01750                         else {
01751                                 sprintf(buf, " %s_dim%d", v->fvarname, i+1);
01752                                 p->dims[i].dimsize = (expptr)
01753                                         autovar(1, tyint, EXNULL, buf);
01754                                 p->dims[i].dimexpr = q;
01755                                 if (i == nd)
01756                                         v->vlastdim = new_vars;
01757                                 v->vdimfinish = 1;
01758                         }
01759                         if(p->nelt)
01760                                 p->nelt = mkexpr(OPSTAR, p->nelt,
01761                                     cpexpr(p->dims[i].dimsize) );
01762                 }
01763         }
01764 
01765         q = dims[nd].lb;
01766         q0 = 0;
01767         if(q == NULL)
01768                 q = q0 = ICON(1);
01769 
01770         for(i = nd-1 ; i>=0 ; --i)
01771         {
01772                 t = dims[i].lb;
01773                 if(t == NULL)
01774                         t = ICON(1);
01775                 if(p->dims[i].dimsize) {
01776                         if (q == q0) {
01777                                 q0 = 0;
01778                                 frexpr(q);
01779                                 q = cpexpr(p->dims[i].dimsize);
01780                                 }
01781                         else
01782                                 q = mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q);
01783                         q = mkexpr(OPPLUS, t, q);
01784                         }
01785         }
01786 
01787         if( ISCONST(q) )
01788         {
01789                 p->baseoffset = q;
01790                 p->basexpr = NULL;
01791         }
01792         else
01793         {
01794                 sprintf(buf, " %s_offset", v->fvarname);
01795                 p->baseoffset = (expptr) autovar(1, tyint, EXNULL, buf);
01796                 p->basexpr = q;
01797                 v->vdimfinish = 1;
01798         }
01799         doin_setbound = 0;
01800 }

Here is the call graph for this function:

Here is the caller graph for this function:

void setext ( register Namep  v  ) 

Definition at line 1657 of file proc.c.

References CLPROC, CLUNKNOWN, dclerr(), PEXTERNAL, and PUNKNOWN.

Referenced by yyparse().

01659 {
01660         if(v->vclass == CLUNKNOWN)
01661                 v->vclass = CLPROC;
01662         else if(v->vclass != CLPROC)
01663                 dclerr("invalid external declaration", v);
01664 
01665         if(v->vprocclass == PUNKNOWN)
01666                 v->vprocclass = PEXTERNAL;
01667         else if(v->vprocclass != PEXTERNAL)
01668                 dclerr("invalid external declaration", v);
01669 } /* setext */

Here is the call graph for this function:

Here is the caller graph for this function:

void setintr ( register Namep  v  ) 

Definition at line 1617 of file proc.c.

References CLPROC, CLUNKNOWN, dclerr(), dcomplex_seen, intrfunct(), noextflag, PINTRINSIC, PUNKNOWN, STGINTR, STGUNKNOWN, and unknown.

Referenced by yyparse().

01619 {
01620         int k;
01621 
01622         if(k = intrfunct(v->fvarname)) {
01623                 if ((*(struct Intrpacked *)&k).f4)
01624                         if (noextflag)
01625                                 goto unknown;
01626                         else
01627                                 dcomplex_seen++;
01628                 v->vardesc.varno = k;
01629                 }
01630         else {
01631  unknown:
01632                 dclerr("unknown intrinsic function", v);
01633                 return;
01634                 }
01635         if(v->vstg == STGUNKNOWN)
01636                 v->vstg = STGINTR;
01637         else if(v->vstg!=STGINTR)
01638                 dclerr("incompatible use of intrinsic function", v);
01639         if(v->vclass==CLUNKNOWN)
01640                 v->vclass = CLPROC;
01641         if(v->vprocclass == PUNKNOWN)
01642                 v->vprocclass = PINTRINSIC;
01643         else if(v->vprocclass != PINTRINSIC)
01644                 dclerr("invalid intrinsic declaration", v);
01645 }

Here is the call graph for this function:

Here is the caller graph for this function:

void settype ( register Namep  v,
register int  type,
register ftnint  length 
)

Definition at line 1456 of file proc.c.

References autovar(), changedtype(), CLMAIN, CLPROC, dclerr(), errstr(), extsymtab, Extsym::extype, frexpr(), ICON, INDATA, lengtype(), MSKCHAR, MSKCOMPLEX, ONEOF, parstate, procclass, PTHISPROC, STGARG, STGEXT, STGUNKNOWN, TYCHAR, TYSUBR, TYUNKNOWN, and xretslot.

Referenced by entrypt(), excall(), impldcl(), and yyparse().

01458 {
01459         int type1;
01460 
01461         if(type == TYUNKNOWN)
01462                 return;
01463 
01464         if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
01465         {
01466                 v->vtype = TYSUBR;
01467                 frexpr(v->vleng);
01468                 v->vleng = 0;
01469                 v->vimpltype = 0;
01470         }
01471         else if(type < 0)       /* storage class set */
01472         {
01473                 if(v->vstg == STGUNKNOWN)
01474                         v->vstg = - type;
01475                 else if(v->vstg != -type)
01476                         dclerr("incompatible storage declarations", v);
01477         }
01478         else if(v->vtype == TYUNKNOWN
01479                 || v->vtype != type
01480                         && (v->vimpltype || v->vinftype || v->vinfproc))
01481         {
01482                 if( (v->vtype = lengtype(type, length))==TYCHAR )
01483                         if (length>=0)
01484                                 v->vleng = ICON(length);
01485                         else if (parstate >= INDATA)
01486                                 v->vleng = ICON(1);     /* avoid a memory fault */
01487                 v->vimpltype = 0;
01488                 v->vinftype = 0; /* 19960709 */
01489                 v->vinfproc = 0; /* 19960709 */
01490 
01491                 if (v->vclass == CLPROC) {
01492                         if (v->vstg == STGEXT
01493                          && (type1 = extsymtab[v->vardesc.varno].extype)
01494                          &&  type1 != v->vtype)
01495                                 changedtype(v);
01496                         else if (v->vprocclass == PTHISPROC
01497                                         && (parstate >= INDATA
01498                                                 || procclass == CLMAIN)
01499                                         && !xretslot[type]) {
01500                                 xretslot[type] = autovar(ONEOF(type,
01501                                         MSKCOMPLEX|MSKCHAR) ? 0 : 1, type,
01502                                         v->vleng, " ret_val");
01503                                 if (procclass == CLMAIN)
01504                                         errstr(
01505                                 "illegal use of %.60s (main program name)",
01506                                         v->fvarname);
01507                                 /* not completely right, but enough to */
01508                                 /* avoid memory faults; we won't */
01509                                 /* emit any C as we have illegal Fortran */
01510                                 }
01511                         }
01512         }
01513         else if(v->vtype != type && v->vtype != lengtype(type, length)) {
01514  incompat:
01515                 dclerr("incompatible type declarations", v);
01516                 }
01517         else if (type==TYCHAR)
01518                 if (v->vleng && v->vleng->constblock.Const.ci != length)
01519                         goto incompat;
01520                 else if (parstate >= INDATA)
01521                         v->vleng = ICON(1);     /* avoid a memory fault */
01522 }

Here is the call graph for this function:

Here is the caller graph for this function:

void startproc ( Extsym progname,
int  Class 
)

Definition at line 435 of file proc.c.

References ALLOC, CLBLOCK, CLMAIN, CLPROC, CNULL, diagfile, endproc(), entries, entrypt(), Extsym::extinit, main_alias, mkname(), newentry(), newproc(), p, procclass, procname, progname, puthead(), and TYSUBR.

Referenced by yyparse().

00437 {
00438         register struct Entrypoint *p;
00439 
00440         p = ALLOC(Entrypoint);
00441         if(Class == CLMAIN) {
00442                 puthead(CNULL, CLMAIN);
00443                 if (progname)
00444                     strcpy (main_alias, progname->cextname);
00445         } else {
00446                 if (progname) {
00447                         /* Construct an empty subroutine with this name */
00448                         /* in case the name is needed to force loading */
00449                         /* of this block-data subprogram: the name can */
00450                         /* appear elsewhere in an external statement. */
00451                         entrypt(CLPROC, TYSUBR, (ftnint)0, progname, (chainp)0);
00452                         endproc();
00453                         newproc();
00454                         }
00455                 puthead(CNULL, CLBLOCK);
00456                 }
00457         if(Class == CLMAIN)
00458                 newentry( mkname(" MAIN"), 0 )->extinit = 1;
00459         p->entryname = progname;
00460         entries = p;
00461 
00462         procclass = Class;
00463         fprintf(diagfile, "   %s", (Class==CLMAIN ? "MAIN" : "BLOCK DATA") );
00464         if(progname) {
00465                 fprintf(diagfile, " %s", progname->fextname);
00466                 procname = progname->cextname;
00467                 }
00468         fprintf(diagfile, ":\n");
00469         fflush(diagfile);
00470 }

Here is the call graph for this function:

Here is the caller graph for this function:

void unamstring ( register Addrp  q,
register char *  s 
)

Definition at line 106 of file proc.c.

References IDENT_LEN, mem(), t, UNAM_CHARP, and UNAM_IDENT.

Referenced by autovar(), and doentry().

00108 {
00109         register int k;
00110         register char *t;
00111 
00112         k = strlen(s);
00113         if (k < IDENT_LEN) {
00114                 q->uname_tag = UNAM_IDENT;
00115                 t = q->user.ident;
00116                 }
00117         else {
00118                 q->uname_tag = UNAM_CHARP;
00119                 q->user.Charp = t = mem(k+1, 0);
00120                 }
00121         strcpy(t, s);
00122         }

Here is the call graph for this function:

Here is the caller graph for this function:

void wr_abbrevs ( FILE *  outfile,
int  function_head,
chainp  vars 
)

Definition at line 1810 of file proc.c.

References Extsym::curno, extern_out(), extsymtab, nice_printf(), and out_name().

Referenced by endproc(), and start_formatting().

01812 {
01813     for (; vars; vars = vars -> nextp) {
01814         Namep name = (Namep) vars -> datap;
01815         if (!name->visused)
01816                 continue;
01817 
01818         if (function_head)
01819             nice_printf (outfile, "#define ");
01820         else
01821             nice_printf (outfile, "#undef ");
01822         out_name (outfile, name);
01823 
01824         if (function_head) {
01825             Extsym *comm = &extsymtab[name -> vardesc.varno];
01826 
01827             nice_printf (outfile, " (");
01828             extern_out (outfile, comm);
01829             nice_printf (outfile, "%d.", comm->curno);
01830             nice_printf (outfile, "%s)", name->cvarname);
01831         } /* if function_head */
01832         nice_printf (outfile, "\n");
01833     } /* for */
01834 } /* wr_abbrevs */

Here is the call graph for this function:

Here is the caller graph for this function:

static void zap_changes ( Void   )  [static]

Definition at line 310 of file proc.c.

References Argtypes::changes, Chain::datap, frchain(), new_procs, and Chain::nextp.

Referenced by endproc().

00311 {
00312         register chainp cp;
00313         register Argtypes *at;
00314 
00315         /* arrange to get correct count of prototypes that would
00316            change by running f2c again */
00317 
00318         if (prev_proc && proc_argchanges)
00319                 proc_protochanges++;
00320         prev_proc = proc_argchanges = 0;
00321         for(cp = new_procs; cp; cp = cp->nextp)
00322                 if (at = ((Namep)cp->datap)->arginfo)
00323                         at->changes &= ~1;
00324         frchain(&new_procs);
00325         }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char Blank[] = BLANKCOMMON [static]

Definition at line 46 of file proc.c.

Referenced by wr_equiv_init().

chainp new_procs

Definition at line 54 of file proc.c.

Referenced by mkfunct(), and zap_changes().

char* postfix[] [static]

Initial value:

 { "g", "h", "i",

                                        "j",

                                        "r", "d", "c", "z", "g", "h", "i" }

Definition at line 48 of file proc.c.

int prev_proc

Definition at line 55 of file proc.c.

int proc_argchanges

Definition at line 55 of file proc.c.

int proc_protochanges

Definition at line 55 of file proc.c.

Referenced by commonprotos().


Generated on Sun Mar 4 15:10:51 2007 for Scilab [trunk] by  doxygen 1.5.1