Annotation of researchv10no/cmd/f2c/proc.c, revision 1.1.1.1

1.1       root        1: /****************************************************************
                      2: Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore.
                      3: 
                      4: Permission to use, copy, modify, and distribute this software
                      5: and its documentation for any purpose and without fee is hereby
                      6: granted, provided that the above copyright notice appear in all
                      7: copies and that both that the copyright notice and this
                      8: permission notice and warranty disclaimer appear in supporting
                      9: documentation, and that the names of AT&T Bell Laboratories or
                     10: Bellcore or any of their entities not be used in advertising or
                     11: publicity pertaining to distribution of the software without
                     12: specific, written prior permission.
                     13: 
                     14: AT&T and Bellcore disclaim all warranties with regard to this
                     15: software, including all implied warranties of merchantability
                     16: and fitness.  In no event shall AT&T or Bellcore be liable for
                     17: any special, indirect or consequential damages or any damages
                     18: whatsoever resulting from loss of use, data or profits, whether
                     19: in an action of contract, negligence or other tortious action,
                     20: arising out of or in connection with the use or performance of
                     21: this software.
                     22: ****************************************************************/
                     23: 
                     24: #include "defs.h"
                     25: #include "names.h"
                     26: #include "output.h"
                     27: #include "p1defs.h"
                     28: 
                     29: #define EXNULL (union Expression *)0
                     30: 
                     31: LOCAL dobss(), docomleng(), docommon(), doentry(),
                     32:        epicode(), nextarg(), retval();
                     33: 
                     34: static char Blank[] = BLANKCOMMON;
                     35: 
                     36:  static char *postfix[] = { "g", "h", "i",
                     37: #ifdef TYQUAD
                     38:                                        "j",
                     39: #endif
                     40:                                        "r", "d", "c", "z", "g", "h", "i" };
                     41: 
                     42:  chainp new_procs;
                     43:  int prev_proc, proc_argchanges, proc_protochanges;
                     44: 
                     45:  void
                     46: changedtype(q)
                     47:  Namep q;
                     48: {
                     49:        char buf[200];
                     50:        int qtype, type1;
                     51:        register Extsym *e;
                     52:        Argtypes *at;
                     53: 
                     54:        if (q->vtypewarned)
                     55:                return;
                     56:        q->vtypewarned = 1;
                     57:        qtype = q->vtype;
                     58:        e = &extsymtab[q->vardesc.varno];
                     59:        if (!(at = e->arginfo)) {
                     60:                if (!e->exused)
                     61:                        return;
                     62:                }
                     63:        else if (at->changes & 2 && qtype != TYUNKNOWN && !at->defined)
                     64:                proc_protochanges++;
                     65:        type1 = e->extype;
                     66:        if (type1 == TYUNKNOWN)
                     67:                return;
                     68:        if (qtype == TYUNKNOWN)
                     69:                /* e.g.,
                     70:                        subroutine foo
                     71:                        end
                     72:                        external foo
                     73:                        call goo(foo)
                     74:                        end
                     75:                */
                     76:                return;
                     77:        sprintf(buf, "%.90s: inconsistent declarations:\n\
                     78:        here %s%s, previously %s%s.", q->fvarname, ftn_types[qtype],
                     79:                qtype == TYSUBR ? "" : " function",
                     80:                ftn_types[type1], type1 == TYSUBR ? "" : " function");
                     81:        warn(buf);
                     82:        }
                     83: 
                     84:  void
                     85: unamstring(q, s)
                     86:  register Addrp q;
                     87:  register char *s;
                     88: {
                     89:        register int k;
                     90:        register char *t;
                     91: 
                     92:        k = strlen(s);
                     93:        if (k < IDENT_LEN) {
                     94:                q->uname_tag = UNAM_IDENT;
                     95:                t = q->user.ident;
                     96:                }
                     97:        else {
                     98:                q->uname_tag = UNAM_CHARP;
                     99:                q->user.Charp = t = mem(k+1, 0);
                    100:                }
                    101:        strcpy(t, s);
                    102:        }
                    103: 
                    104:  static void
                    105: fix_entry_returns()    /* for multiple entry points */
                    106: {
                    107:        Addrp a;
                    108:        int i;
                    109:        struct Entrypoint *e;
                    110:        Namep np;
                    111: 
                    112:        e = entries = (struct Entrypoint *)revchain((chainp)entries);
                    113:        allargs = revchain(allargs);
                    114:        if (!multitype)
                    115:                return;
                    116: 
                    117:        /* TYLOGICAL should have been turned into TYLONG or TYSHORT by now */
                    118: 
                    119:        for(i = TYINT1; i <= TYLOGICAL; i++)
                    120:                if (a = xretslot[i])
                    121:                        sprintf(a->user.ident, "(*ret_val).%s",
                    122:                                postfix[i-TYINT1]);
                    123: 
                    124:        do {
                    125:                np = e->enamep;
                    126:                switch(np->vtype) {
                    127:                        case TYINT1:
                    128:                        case TYSHORT:
                    129:                        case TYLONG:
                    130: #ifdef TYQUAD
                    131:                        case TYQUAD:
                    132: #endif
                    133:                        case TYREAL:
                    134:                        case TYDREAL:
                    135:                        case TYCOMPLEX:
                    136:                        case TYDCOMPLEX:
                    137:                        case TYLOGICAL1:
                    138:                        case TYLOGICAL2:
                    139:                        case TYLOGICAL:
                    140:                                np->vstg = STGARG;
                    141:                        }
                    142:                }
                    143:                while(e = e->entnextp);
                    144:        }
                    145: 
                    146:  static void
                    147: putentries(outfile)    /* put out wrappers for multiple entries */
                    148:  FILE *outfile;
                    149: {
                    150:        char base[IDENT_LEN];
                    151:        struct Entrypoint *e;
                    152:        Namep *A, *Ae, *Ae1, **Alp, *a, **a1, np;
                    153:        chainp args, lengths, length_comp();
                    154:        void listargs(), list_arg_types();
                    155:        int i, k, mt, nL, type;
                    156:        extern char *dfltarg[], **dfltproc;
                    157: 
                    158:        e = entries;
                    159:        if (!e->enamep) /* only possible with erroneous input */
                    160:                return;
                    161:        nL = (nallargs + nallchargs) * sizeof(Namep *);
                    162:        A = (Namep *)ckalloc(nL + nallargs*sizeof(Namep **));
                    163:        Ae = A + nallargs;
                    164:        Alp = (Namep **)(Ae1 = Ae + nallchargs);
                    165:        i = k = 0;
                    166:        for(a1 = Alp, args = allargs; args; a1++, args = args->nextp) {
                    167:                np = (Namep)args->datap;
                    168:                if (np->vtype == TYCHAR && np->vclass != CLPROC)
                    169:                        *a1 = &Ae[i++];
                    170:                }
                    171: 
                    172:        mt = multitype;
                    173:        multitype = 0;
                    174:        sprintf(base, "%s0_", e->enamep->cvarname);
                    175:        do {
                    176:                np = e->enamep;
                    177:                lengths = length_comp(e, 0);
                    178:                proctype = type = np->vtype;
                    179:                if (protofile)
                    180:                        protowrite(protofile, type, np->cvarname, e, lengths);
                    181:                nice_printf(outfile, "\n%s ", c_type_decl(type, 1));
                    182:                nice_printf(outfile, "%s", np->cvarname);
                    183:                if (!Ansi) {
                    184:                        listargs(outfile, e, 0, lengths);
                    185:                        nice_printf(outfile, "\n");
                    186:                        }
                    187:                list_arg_types(outfile, e, lengths, 0, "\n");
                    188:                nice_printf(outfile, "{\n");
                    189:                frchain(&lengths);
                    190:                next_tab(outfile);
                    191:                if (mt)
                    192:                        nice_printf(outfile,
                    193:                                "Multitype ret_val;\n%s(%d, &ret_val",
                    194:                                base, k); /*)*/
                    195:                else if (ISCOMPLEX(type))
                    196:                        nice_printf(outfile, "%s(%d,%s", base, k,
                    197:                                xretslot[type]->user.ident); /*)*/
                    198:                else if (type == TYCHAR)
                    199:                        nice_printf(outfile,
                    200:                                "%s(%d, ret_val, ret_val_len", base, k); /*)*/
                    201:                else
                    202:                        nice_printf(outfile, "return %s(%d", base, k); /*)*/
                    203:                k++;
                    204:                memset((char *)A, 0, nL);
                    205:                for(args = e->arglist; args; args = args->nextp) {
                    206:                        np = (Namep)args->datap;
                    207:                        A[np->argno] = np;
                    208:                        if (np->vtype == TYCHAR && np->vclass != CLPROC)
                    209:                                *Alp[np->argno] = np;
                    210:                        }
                    211:                args = allargs;
                    212:                for(a = A; a < Ae; a++, args = args->nextp)
                    213:                        nice_printf(outfile, ", %s", (np = *a)
                    214:                                ? np->cvarname
                    215:                                : ((Namep)args->datap)->vclass == CLPROC
                    216:                                ? dfltproc[((Namep)args->datap)->vtype]
                    217:                                : dfltarg[((Namep)args->datap)->vtype]);
                    218:                for(; a < Ae1; a++)
                    219:                        if (np = *a)
                    220:                                nice_printf(outfile, ", %s_len", np->fvarname);
                    221:                        else
                    222:                                nice_printf(outfile, ", (ftnint)0");
                    223:                nice_printf(outfile, /*(*/ ");\n");
                    224:                if (mt) {
                    225:                        if (type == TYCOMPLEX)
                    226:                                nice_printf(outfile,
                    227:                    "r_v->r = ret_val.c.r; r_v->i = ret_val.c.i;\nreturn 0;\n");
                    228:                        else if (type == TYDCOMPLEX)
                    229:                                nice_printf(outfile,
                    230:                    "r_v->r = ret_val.z.r; r_v->i = ret_val.z.i;\nreturn 0;\n");
                    231:                        else nice_printf(outfile, "return ret_val.%s;\n",
                    232:                                postfix[type-TYINT1]);
                    233:                        }
                    234:                nice_printf(outfile, "}\n");
                    235:                prev_tab(outfile);
                    236:                }
                    237:                while(e = e->entnextp);
                    238:        free((char *)A);
                    239:        }
                    240: 
                    241:  static void
                    242: entry_goto(outfile)
                    243:  FILEP outfile;
                    244: {
                    245:        struct Entrypoint *e = entries;
                    246:        int k = 0;
                    247: 
                    248:        nice_printf(outfile, "switch(n__) {\n");
                    249:        next_tab(outfile);
                    250:        while(e = e->entnextp)
                    251:                nice_printf(outfile, "case %d: goto %s;\n", ++k,
                    252:                        user_label((long)(extsymtab - e->entryname - 1)));
                    253:        nice_printf(outfile, "}\n\n");
                    254:        prev_tab(outfile);
                    255:        }
                    256: 
                    257: /* start a new procedure */
                    258: 
                    259: newproc()
                    260: {
                    261:        if(parstate != OUTSIDE)
                    262:        {
                    263:                execerr("missing end statement", CNULL);
                    264:                endproc();
                    265:        }
                    266: 
                    267:        parstate = INSIDE;
                    268:        procclass = CLMAIN;     /* default */
                    269: }
                    270: 
                    271:  static void
                    272: zap_changes()
                    273: {
                    274:        register chainp cp;
                    275:        register Argtypes *at;
                    276: 
                    277:        /* arrange to get correct count of prototypes that would
                    278:           change by running f2c again */
                    279: 
                    280:        if (prev_proc && proc_argchanges)
                    281:                proc_protochanges++;
                    282:        prev_proc = proc_argchanges = 0;
                    283:        for(cp = new_procs; cp; cp = cp->nextp)
                    284:                if (at = ((Namep)cp->datap)->arginfo)
                    285:                        at->changes &= ~1;
                    286:        frchain(&new_procs);
                    287:        }
                    288: 
                    289: /* end of procedure. generate variables, epilogs, and prologs */
                    290: 
                    291: endproc()
                    292: {
                    293:        struct Labelblock *lp;
                    294:        Extsym *ext;
                    295: 
                    296:        if(parstate < INDATA)
                    297:                enddcl();
                    298:        if(ctlstack >= ctls)
                    299:                err("DO loop or BLOCK IF not closed");
                    300:        for(lp = labeltab ; lp < labtabend ; ++lp)
                    301:                if(lp->stateno!=0 && lp->labdefined==NO)
                    302:                        errstr("missing statement label %s",
                    303:                                convic(lp->stateno) );
                    304: 
                    305: /* Save copies of the common variables in extptr -> allextp */
                    306: 
                    307:        for (ext = extsymtab; ext < nextext; ext++)
                    308:                if (ext -> extstg == STGCOMMON && ext -> extp) {
                    309:                        extern int usedefsforcommon;
                    310: 
                    311: /* Write out the abbreviations for common block reference */
                    312: 
                    313:                        copy_data (ext -> extp);
                    314:                        if (usedefsforcommon) {
                    315:                                wr_abbrevs (c_file, 1, ext -> extp);
                    316:                                ext -> used_here = 1;
                    317:                                }
                    318:                        else
                    319:                                ext -> extp = CHNULL;
                    320: 
                    321:                        }
                    322: 
                    323:        if (nentry > 1)
                    324:                fix_entry_returns();
                    325:        epicode();
                    326:        donmlist();
                    327:        dobss();
                    328:        start_formatting ();
                    329:        if (nentry > 1)
                    330:                putentries(c_file);
                    331: 
                    332:        zap_changes();
                    333:        procinit();     /* clean up for next procedure */
                    334: }
                    335: 
                    336: 
                    337: 
                    338: /* End of declaration section of procedure.  Allocate storage. */
                    339: 
                    340: enddcl()
                    341: {
                    342:        register struct Entrypoint *ep;
                    343:        struct Entrypoint *ep0;
                    344:        extern void freetemps();
                    345:        chainp cp;
                    346:        extern char *err_proc;
                    347:        static char comblks[] = "common blocks";
                    348: 
                    349:        err_proc = comblks;
                    350:        docommon();
                    351: 
                    352: /* Now the hash table entries for fields of common blocks have STGCOMMON,
                    353:    vdcldone, voffset, and varno.  And the common blocks themselves have
                    354:    their full sizes in extleng. */
                    355: 
                    356:        err_proc = "equivalences";
                    357:        doequiv();
                    358: 
                    359:        err_proc = comblks;
                    360:        docomleng();
                    361: 
                    362: /* This implies that entry points in the declarations are buffered in
                    363:    entries   but not written out */
                    364: 
                    365:        err_proc = "entries";
                    366:        if (ep = ep0 = (struct Entrypoint *)revchain((chainp)entries)) {
                    367:                /* entries could be 0 in case of an error */
                    368:                do doentry(ep);
                    369:                        while(ep = ep->entnextp);
                    370:                entries = (struct Entrypoint *)revchain((chainp)ep0);
                    371:                }
                    372: 
                    373:        err_proc = 0;
                    374:        parstate = INEXEC;
                    375:        p1put(P1_PROCODE);
                    376:        freetemps();
                    377:        if (earlylabs) {
                    378:                for(cp = earlylabs = revchain(earlylabs); cp; cp = cp->nextp)
                    379:                        p1_label((long)cp->datap);
                    380:                frchain(&earlylabs);
                    381:                }
                    382: }
                    383: 
                    384: /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
                    385: 
                    386: /* Main program or Block data */
                    387: 
                    388: startproc(progname, class)
                    389: Extsym * progname;
                    390: int class;
                    391: {
                    392:        register struct Entrypoint *p;
                    393: 
                    394:        p = ALLOC(Entrypoint);
                    395:        if(class == CLMAIN) {
                    396:                puthead(CNULL, CLMAIN);
                    397:                if (progname)
                    398:                    strcpy (main_alias, progname->cextname);
                    399:        } else
                    400:                puthead(CNULL, CLBLOCK);
                    401:        if(class == CLMAIN)
                    402:                newentry( mkname(" MAIN"), 0 )->extinit = 1;
                    403:        p->entryname = progname;
                    404:        entries = p;
                    405: 
                    406:        procclass = class;
                    407:        fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
                    408:        if(progname) {
                    409:                fprintf(diagfile, " %s", progname->fextname);
                    410:                procname = progname->cextname;
                    411:                }
                    412:        fprintf(diagfile, ":\n");
                    413:        fflush(diagfile);
                    414: }
                    415: 
                    416: /* subroutine or function statement */
                    417: 
                    418: Extsym *newentry(v, substmsg)
                    419:  register Namep v;
                    420:  int substmsg;
                    421: {
                    422:        register Extsym *p;
                    423:        char buf[128], badname[64];
                    424:        static int nbad = 0;
                    425:        static char already[] = "external name already used";
                    426: 
                    427:        p = mkext(v->fvarname, addunder(v->cvarname));
                    428: 
                    429:        if(p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
                    430:        {
                    431:                sprintf(badname, "%s_bad%d", v->fvarname, ++nbad);
                    432:                if (substmsg) {
                    433:                        sprintf(buf,"%s\n\tsubstituting \"%s\"",
                    434:                                already, badname);
                    435:                        dclerr(buf, v);
                    436:                        }
                    437:                else
                    438:                        dclerr(already, v);
                    439:                p = mkext(v->fvarname, badname);
                    440:        }
                    441:        v->vstg = STGAUTO;
                    442:        v->vprocclass = PTHISPROC;
                    443:        v->vclass = CLPROC;
                    444:        if (p->extstg == STGEXT)
                    445:                prev_proc = 1;
                    446:        else
                    447:                p->extstg = STGEXT;
                    448:        p->extinit = YES;
                    449:        v->vardesc.varno = p - extsymtab;
                    450:        return(p);
                    451: }
                    452: 
                    453: 
                    454: entrypt(class, type, length, entry, args)
                    455: int class, type;
                    456: ftnint length;
                    457: Extsym *entry;
                    458: chainp args;
                    459: {
                    460:        register Namep q;
                    461:        register struct Entrypoint *p;
                    462: 
                    463:        if(class != CLENTRY)
                    464:                puthead( procname = entry->cextname, class);
                    465:        else
                    466:                fprintf(diagfile, "       entry ");
                    467:        fprintf(diagfile, "   %s:\n", entry->fextname);
                    468:        fflush(diagfile);
                    469:        q = mkname(entry->fextname);
                    470:        if (type == TYSUBR)
                    471:                q->vstg = STGEXT;
                    472: 
                    473:        type = lengtype(type, length);
                    474:        if(class == CLPROC)
                    475:        {
                    476:                procclass = CLPROC;
                    477:                proctype = type;
                    478:                procleng = type == TYCHAR ? length : 0;
                    479:        }
                    480: 
                    481:        p = ALLOC(Entrypoint);
                    482: 
                    483:        p->entnextp = entries;
                    484:        entries = p;
                    485: 
                    486:        p->entryname = entry;
                    487:        p->arglist = revchain(args);
                    488:        p->enamep = q;
                    489: 
                    490:        if(class == CLENTRY)
                    491:        {
                    492:                class = CLPROC;
                    493:                if(proctype == TYSUBR)
                    494:                        type = TYSUBR;
                    495:        }
                    496: 
                    497:        q->vclass = class;
                    498:        q->vprocclass = 0;
                    499:        settype(q, type, length);
                    500:        q->vprocclass = PTHISPROC;
                    501:        /* hold all initial entry points till end of declarations */
                    502:        if(parstate >= INDATA)
                    503:                doentry(p);
                    504: }
                    505: 
                    506: /* generate epilogs */
                    507: 
                    508: /* epicode -- write out the proper function return mechanism at the end of
                    509:    the procedure declaration.  Handles multiple return value types, as
                    510:    well as cooercion into the proper value */
                    511: 
                    512: LOCAL epicode()
                    513: {
                    514:        extern int lastwasbranch;
                    515: 
                    516:        if(procclass==CLPROC)
                    517:        {
                    518:                if(proctype==TYSUBR)
                    519:                {
                    520: 
                    521: /* Return a zero only when the alternate return mechanism has been
                    522:    specified in the function header */
                    523: 
                    524:                        if ((substars || Ansi) && lastwasbranch != YES)
                    525:                            p1_subr_ret (ICON(0));
                    526:                }
                    527:                else if (!multitype && lastwasbranch != YES)
                    528:                        retval(proctype);
                    529:        }
                    530:        else if (procclass == CLMAIN && Ansi && lastwasbranch != YES)
                    531:                p1_subr_ret (ICON(0));
                    532:        lastwasbranch = NO;
                    533: }
                    534: 
                    535: 
                    536: /* generate code to return value of type  t */
                    537: 
                    538: LOCAL retval(t)
                    539: register int t;
                    540: {
                    541:        register Addrp p;
                    542: 
                    543:        switch(t)
                    544:        {
                    545:        case TYCHAR:
                    546:        case TYCOMPLEX:
                    547:        case TYDCOMPLEX:
                    548:                break;
                    549: 
                    550:        case TYLOGICAL:
                    551:                t = tylogical;
                    552:        case TYINT1:
                    553:        case TYADDR:
                    554:        case TYSHORT:
                    555:        case TYLONG:
                    556: #ifdef TYQUAD
                    557:        case TYQUAD:
                    558: #endif
                    559:        case TYREAL:
                    560:        case TYDREAL:
                    561:        case TYLOGICAL1:
                    562:        case TYLOGICAL2:
                    563:                p = (Addrp) cpexpr((expptr)retslot);
                    564:                p->vtype = t;
                    565:                p1_subr_ret (mkconv (t, fixtype((expptr)p)));
                    566:                break;
                    567: 
                    568:        default:
                    569:                badtype("retval", t);
                    570:        }
                    571: }
                    572: 
                    573: 
                    574: /* Do parameter adjustments */
                    575: 
                    576: procode(outfile)
                    577: FILE *outfile;
                    578: {
                    579:        prolog(outfile, allargs);
                    580: 
                    581:        if (nentry > 1)
                    582:                entry_goto(outfile);
                    583:        }
                    584: 
                    585: /* Finish bound computations now that all variables are declared.
                    586:  * This used to be in setbound(), but under -u the following incurred
                    587:  * an erroneous error message:
                    588:  *     subroutine foo(x,n)
                    589:  *     real x(n)
                    590:  *     integer n
                    591:  */
                    592: 
                    593:  static void
                    594: dim_finish(v)
                    595:  Namep v;
                    596: {
                    597:        register struct Dimblock *p;
                    598:        register expptr q;
                    599:        register int i, nd;
                    600:        extern expptr make_int_expr();
                    601: 
                    602:        p = v->vdim;
                    603:        v->vdimfinish = 0;
                    604:        nd = p->ndim;
                    605:        doin_setbound = 1;
                    606:        for(i = 0; i < nd; i++)
                    607:                if (q = p->dims[i].dimexpr) {
                    608:                        q = p->dims[i].dimexpr = make_int_expr(putx(fixtype(q)));
                    609:                        if (!ONEOF(q->headblock.vtype, MSKINT|MSKREAL))
                    610:                                errstr("bad dimension type for %.70s",
                    611:                                        v->fvarname);
                    612:                        }
                    613:        if (q = p->basexpr)
                    614:                p->basexpr = make_int_expr(putx(fixtype(q)));
                    615:        doin_setbound = 0;
                    616:        }
                    617: 
                    618:  static void
                    619: duparg(q)
                    620:  Namep q;
                    621: { errstr("duplicate argument %.80s", q->fvarname); }
                    622: 
                    623: /*
                    624:    manipulate argument lists (allocate argument slot positions)
                    625:  * keep track of return types and labels
                    626:  */
                    627: 
                    628: LOCAL doentry(ep)
                    629: struct Entrypoint *ep;
                    630: {
                    631:        register int type;
                    632:        register Namep np;
                    633:        chainp p, p1;
                    634:        register Namep q;
                    635:        Addrp mkarg(), rs;
                    636:        int it, k;
                    637:        extern char dflttype[26];
                    638:        Extsym *entryname = ep->entryname;
                    639: 
                    640:        if (++nentry > 1)
                    641:                p1_label((long)(extsymtab - entryname - 1));
                    642: 
                    643: /* The main program isn't allowed to have parameters, so any given
                    644:    parameters are ignored */
                    645: 
                    646:        if(procclass == CLMAIN || procclass == CLBLOCK)
                    647:                return;
                    648: 
                    649: /* So now we're working with something other than CLMAIN or CLBLOCK.
                    650:    Determine the type of its return value. */
                    651: 
                    652:        impldcl( np = mkname(entryname->fextname) );
                    653:        type = np->vtype;
                    654:        proc_argchanges = prev_proc && type != entryname->extype;
                    655:        entryname->extseen = 1;
                    656:        if(proctype == TYUNKNOWN)
                    657:                if( (proctype = type) == TYCHAR)
                    658:                        procleng = np->vleng ? np->vleng->constblock.Const.ci
                    659:                                             : (ftnint) (-1);
                    660: 
                    661:        if(proctype == TYCHAR)
                    662:        {
                    663:                if(type != TYCHAR)
                    664:                        err("noncharacter entry of character function");
                    665: 
                    666: /* Functions returning type   char   can only have multiple entries if all
                    667:    entries return the same length */
                    668: 
                    669:                else if( (np->vleng ? np->vleng->constblock.Const.ci :
                    670:                    (ftnint) (-1)) != procleng)
                    671:                        err("mismatched character entry lengths");
                    672:        }
                    673:        else if(type == TYCHAR)
                    674:                err("character entry of noncharacter function");
                    675:        else if(type != proctype)
                    676:                multitype = YES;
                    677:        if(rtvlabel[type] == 0)
                    678:                rtvlabel[type] = newlabel();
                    679:        ep->typelabel = rtvlabel[type];
                    680: 
                    681:        if(type == TYCHAR)
                    682:        {
                    683:                if(chslot < 0)
                    684:                {
                    685:                        chslot = nextarg(TYADDR);
                    686:                        chlgslot = nextarg(TYLENG);
                    687:                }
                    688:                np->vstg = STGARG;
                    689: 
                    690: /* Put a new argument in the function, one which will hold the result of
                    691:    a character function.  This will have to be named sometime, probably in
                    692:    mkarg(). */
                    693: 
                    694:                if(procleng < 0) {
                    695:                        np->vleng = (expptr) mkarg(TYLENG, chlgslot);
                    696:                        np->vleng->addrblock.uname_tag = UNAM_IDENT;
                    697:                        strcpy (np -> vleng -> addrblock.user.ident,
                    698:                                new_func_length());
                    699:                        }
                    700:                if (!xretslot[TYCHAR]) {
                    701:                        xretslot[TYCHAR] = rs =
                    702:                                autovar(0, type, ISCONST(np->vleng)
                    703:                                        ? np->vleng : ICON(0), "");
                    704:                        strcpy(rs->user.ident, "ret_val");
                    705:                        }
                    706:        }
                    707: 
                    708: /* Handle a   complex   return type -- declare a new parameter (pointer to
                    709:    a complex value) */
                    710: 
                    711:        else if( ISCOMPLEX(type) ) {
                    712:                if (!xretslot[type])
                    713:                        xretslot[type] =
                    714:                                autovar(0, type, EXNULL, " ret_val");
                    715:                                /* the blank is for use in out_addr */
                    716:                np->vstg = STGARG;
                    717:                if(cxslot < 0)
                    718:                        cxslot = nextarg(TYADDR);
                    719:                }
                    720:        else if (type != TYSUBR) {
                    721:                if (type == TYUNKNOWN) {
                    722:                        dclerr("untyped function", np);
                    723:                        proctype = type = np->vtype =
                    724:                                dflttype[letter(np->fvarname[0])];
                    725:                        }
                    726:                if (!xretslot[type])
                    727:                        xretslot[type] = retslot =
                    728:                                autovar(1, type, EXNULL, " ret_val");
                    729:                                /* the blank is for use in out_addr */
                    730:                np->vstg = STGAUTO;
                    731:                }
                    732: 
                    733:        for(p = ep->arglist ; p ; p = p->nextp)
                    734:                if(! (( q = (Namep) (p->datap) )->vknownarg) ) {
                    735:                        q->vknownarg = 1;
                    736:                        q->vardesc.varno = nextarg(TYADDR);
                    737:                        allargs = mkchain((char *)q, allargs);
                    738:                        q->argno = nallargs++;
                    739:                        }
                    740:                else if (nentry == 1)
                    741:                        duparg(q);
                    742:                else for(p1 = ep->arglist ; p1 != p; p1 = p1->nextp)
                    743:                        if ((Namep)p1->datap == q)
                    744:                                duparg(q);
                    745: 
                    746:        k = 0;
                    747:        for(p = ep->arglist ; p ; p = p->nextp) {
                    748:                if(! (( q = (Namep) (p->datap) )->vdcldone) )
                    749:                        {
                    750:                        impldcl(q);
                    751:                        q->vdcldone = YES;
                    752:                        if(q->vtype == TYCHAR)
                    753:                                {
                    754: 
                    755: /* If we don't know the length of a char*(*) (i.e. a string), we must add
                    756:    in this additional length argument. */
                    757: 
                    758:                                ++nallchargs;
                    759:                                if (q->vclass == CLPROC)
                    760:                                        nallchargs--;
                    761:                                else if (q->vleng == NULL) {
                    762:                                        /* character*(*) */
                    763:                                        q->vleng = (expptr)
                    764:                                            mkarg(TYLENG, nextarg(TYLENG) );
                    765:                                        unamstring((Addrp)q->vleng,
                    766:                                                new_arg_length(q));
                    767:                                        }
                    768:                                }
                    769:                        }
                    770:                if (q->vdimfinish)
                    771:                        dim_finish(q);
                    772:                if (q->vtype == TYCHAR && q->vclass != CLPROC)
                    773:                        k++;
                    774:                }
                    775: 
                    776:        if (entryname->extype != type)
                    777:                changedtype(np);
                    778: 
                    779:        /* save information for checking consistency of arg lists */
                    780: 
                    781:        it = infertypes;
                    782:        if (entryname->exproto)
                    783:                infertypes = 1;
                    784:        save_argtypes(ep->arglist, &entryname->arginfo, &np->arginfo,
                    785:                        0, np->fvarname, STGEXT, k, np->vtype, 2);
                    786:        infertypes = it;
                    787: }
                    788: 
                    789: 
                    790: 
                    791: LOCAL nextarg(type)
                    792: int type;
                    793: {
                    794:        int k;
                    795:        k = lastargslot;
                    796:        lastargslot += typesize[type];
                    797:        return(k);
                    798: }
                    799: 
                    800:  LOCAL
                    801: dim_check(q)
                    802:  Namep q;
                    803: {
                    804:        register struct Dimblock *vdim = q->vdim;
                    805: 
                    806:        if(!vdim->nelt || !ISICON(vdim->nelt))
                    807:                dclerr("adjustable dimension on non-argument", q);
                    808:        else if (vdim->nelt->constblock.Const.ci <= 0)
                    809:                dclerr("nonpositive dimension", q);
                    810:        }
                    811: 
                    812: LOCAL dobss()
                    813: {
                    814:        register struct Hashentry *p;
                    815:        register Namep q;
                    816:        int qstg, qclass, qtype;
                    817:        Extsym *e;
                    818: 
                    819:        for(p = hashtab ; p<lasthash ; ++p)
                    820:                if(q = p->varp)
                    821:                {
                    822:                        qstg = q->vstg;
                    823:                        qtype = q->vtype;
                    824:                        qclass = q->vclass;
                    825: 
                    826:                        if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
                    827:                            (qclass==CLVAR && qstg==STGUNKNOWN) ) {
                    828:                                if (!(q->vis_assigned | q->vimpldovar))
                    829:                                        warn1("local variable %s never used",
                    830:                                                q->fvarname);
                    831:                                }
                    832:                        else if(qclass==CLVAR && qstg==STGBSS)
                    833:                        { ; }
                    834: 
                    835: /* Give external procedures the proper storage class */
                    836: 
                    837:                        else if(qclass==CLPROC && q->vprocclass==PEXTERNAL
                    838:                                        && qstg!=STGARG) {
                    839:                                e = mkext(q->fvarname,addunder(q->cvarname));
                    840:                                e->extstg = STGEXT;
                    841:                                q->vardesc.varno = e - extsymtab;
                    842:                                if (e->extype != qtype)
                    843:                                        changedtype(q);
                    844:                                }
                    845:                        if(qclass==CLVAR) {
                    846:                            if (qstg != STGARG && q->vdim)
                    847:                                dim_check(q);
                    848:                        } /* if qclass == CLVAR */
                    849:                }
                    850: 
                    851: }
                    852: 
                    853: 
                    854: 
                    855: donmlist()
                    856: {
                    857:        register struct Hashentry *p;
                    858:        register Namep q;
                    859: 
                    860:        for(p=hashtab; p<lasthash; ++p)
                    861:                if( (q = p->varp) && q->vclass==CLNAMELIST)
                    862:                        namelist(q);
                    863: }
                    864: 
                    865: 
                    866: /* iarrlen -- Returns the size of the array in bytes, or -1 */
                    867: 
                    868: ftnint iarrlen(q)
                    869: register Namep q;
                    870: {
                    871:        ftnint leng;
                    872: 
                    873:        leng = typesize[q->vtype];
                    874:        if(leng <= 0)
                    875:                return(-1);
                    876:        if(q->vdim)
                    877:                if( ISICON(q->vdim->nelt) )
                    878:                        leng *= q->vdim->nelt->constblock.Const.ci;
                    879:                else    return(-1);
                    880:        if(q->vleng)
                    881:                if( ISICON(q->vleng) )
                    882:                        leng *= q->vleng->constblock.Const.ci;
                    883:                else return(-1);
                    884:        return(leng);
                    885: }
                    886: 
                    887: namelist(np)
                    888: Namep np;
                    889: {
                    890:        register chainp q;
                    891:        register Namep v;
                    892:        int y;
                    893: 
                    894:        if (!np->visused)
                    895:                return;
                    896:        y = 0;
                    897: 
                    898:        for(q = np->varxptr.namelist ; q ; q = q->nextp)
                    899:        {
                    900:                vardcl( v = (Namep) (q->datap) );
                    901:                if( !ONEOF(v->vstg, MSKSTATIC) )
                    902:                        dclerr("may not appear in namelist", v);
                    903:                else {
                    904:                        v->vnamelist = 1;
                    905:                        v->visused = 1;
                    906:                        v->vsave = 1;
                    907:                        y = 1;
                    908:                        }
                    909:        np->visused = y;
                    910:        }
                    911: }
                    912: 
                    913: /* docommon -- called at the end of procedure declarations, before
                    914:    equivalences and the procedure body */
                    915: 
                    916: LOCAL docommon()
                    917: {
                    918:     register Extsym *extptr;
                    919:     register chainp q, q1;
                    920:     struct Dimblock *t;
                    921:     expptr neltp;
                    922:     register Namep comvar;
                    923:     ftnint size;
                    924:     int i, k, pref, type;
                    925:     extern int type_pref[];
                    926: 
                    927:     for(extptr = extsymtab ; extptr<nextext ; ++extptr)
                    928:        if (extptr->extstg == STGCOMMON && (q = extptr->extp)) {
                    929: 
                    930: /* If a common declaration also had a list of variables ... */
                    931: 
                    932:            q = extptr->extp = revchain(q);
                    933:            pref = 1;
                    934:            for(k = TYCHAR; q ; q = q->nextp)
                    935:            {
                    936:                comvar = (Namep) (q->datap);
                    937: 
                    938:                if(comvar->vdcldone == NO)
                    939:                    vardcl(comvar);
                    940:                type = comvar->vtype;
                    941:                if (pref < type_pref[type])
                    942:                        pref = type_pref[k = type];
                    943:                if(extptr->extleng % typealign[type] != 0) {
                    944:                    dclerr("common alignment", comvar);
                    945:                    --nerr; /* don't give bad return code for this */
                    946: #if 0
                    947:                    extptr->extleng = roundup(extptr->extleng, typealign[type]);
                    948: #endif
                    949:                } /* if extptr -> extleng % */
                    950: 
                    951: /* Set the offset into the common block */
                    952: 
                    953:                comvar->voffset = extptr->extleng;
                    954:                comvar->vardesc.varno = extptr - extsymtab;
                    955:                if(type == TYCHAR)
                    956:                    size = comvar->vleng->constblock.Const.ci;
                    957:                else
                    958:                    size = typesize[type];
                    959:                if(t = comvar->vdim)
                    960:                    if( (neltp = t->nelt) && ISCONST(neltp) )
                    961:                        size *= neltp->constblock.Const.ci;
                    962:                    else
                    963:                        dclerr("adjustable array in common", comvar);
                    964: 
                    965: /* Adjust the length of the common block so far */
                    966: 
                    967:                extptr->extleng += size;
                    968:            } /* for */
                    969: 
                    970:            extptr->extype = k;
                    971: 
                    972: /* Determine curno and, if new, save this identifier chain */
                    973: 
                    974:            q1 = extptr->extp;
                    975:            for (q = extptr->allextp, i = 0; q; i++, q = q->nextp)
                    976:                if (struct_eq((chainp)q->datap, q1))
                    977:                        break;
                    978:            if (q)
                    979:                extptr->curno = extptr->maxno - i;
                    980:            else {
                    981:                extptr->curno = ++extptr->maxno;
                    982:                extptr->allextp = mkchain((char *)extptr->extp,
                    983:                                                extptr->allextp);
                    984:                }
                    985:        } /* if extptr -> extstg == STGCOMMON */
                    986: 
                    987: /* Now the hash table entries have STGCOMMON, vdcldone, voffset, and
                    988:    varno.  And the common block itself has its full size in extleng. */
                    989: 
                    990: } /* docommon */
                    991: 
                    992: 
                    993: /* copy_data -- copy the Namep entries so they are available even after
                    994:    the hash table is empty */
                    995: 
                    996: copy_data (list)
                    997: chainp list;
                    998: {
                    999:     for (; list; list = list -> nextp) {
                   1000:        Namep namep = ALLOC (Nameblock);
                   1001:        int size, nd, i;
                   1002:        struct Dimblock *dp;
                   1003: 
                   1004:        cpn(sizeof(struct Nameblock), list->datap, (char *)namep);
                   1005:        namep->fvarname = strcpy(gmem(strlen(namep->fvarname)+1,0),
                   1006:                namep->fvarname);
                   1007:        namep->cvarname = strcmp(namep->fvarname, namep->cvarname)
                   1008:                ? strcpy(gmem(strlen(namep->cvarname)+1,0), namep->cvarname)
                   1009:                : namep->fvarname;
                   1010:        if (namep -> vleng)
                   1011:            namep -> vleng = (expptr) cpexpr (namep -> vleng);
                   1012:        if (namep -> vdim) {
                   1013:            nd = namep -> vdim -> ndim;
                   1014:            size = sizeof(int) + (3 + 2 * nd) * sizeof (expptr);
                   1015:            dp = (struct Dimblock *) ckalloc (size);
                   1016:            cpn(size, (char *)namep->vdim, (char *)dp);
                   1017:            namep -> vdim = dp;
                   1018:            dp->nelt = (expptr)cpexpr(dp->nelt);
                   1019:            for (i = 0; i < nd; i++) {
                   1020:                dp -> dims[i].dimsize = (expptr) cpexpr (dp -> dims[i].dimsize);
                   1021:            } /* for */
                   1022:        } /* if */
                   1023:        list -> datap = (char *) namep;
                   1024:     } /* for */
                   1025: } /* copy_data */
                   1026: 
                   1027: 
                   1028: 
                   1029: LOCAL docomleng()
                   1030: {
                   1031:        register Extsym *p;
                   1032: 
                   1033:        for(p = extsymtab ; p < nextext ; ++p)
                   1034:                if(p->extstg == STGCOMMON)
                   1035:                {
                   1036:                        if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
                   1037:                            && strcmp(Blank, p->cextname) )
                   1038:                                warn1("incompatible lengths for common block %.60s",
                   1039:                                    p->fextname);
                   1040:                        if(p->maxleng < p->extleng)
                   1041:                                p->maxleng = p->extleng;
                   1042:                        p->extleng = 0;
                   1043:                }
                   1044: }
                   1045: 
                   1046: 
                   1047: /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
                   1048: 
                   1049: frtemp(p)
                   1050: Addrp p;
                   1051: {
                   1052:        /* put block on chain of temps to be reclaimed */
                   1053:        holdtemps = mkchain((char *)p, holdtemps);
                   1054: }
                   1055: 
                   1056:  void
                   1057: freetemps()
                   1058: {
                   1059:        register chainp p, p1;
                   1060:        register Addrp q;
                   1061:        register int t;
                   1062: 
                   1063:        p1 = holdtemps;
                   1064:        while(p = p1) {
                   1065:                q = (Addrp)p->datap;
                   1066:                t = q->vtype;
                   1067:                if (t == TYCHAR && q->varleng != 0) {
                   1068:                        /* restore clobbered character string lengths */
                   1069:                        frexpr(q->vleng);
                   1070:                        q->vleng = ICON(q->varleng);
                   1071:                        }
                   1072:                p1 = p->nextp;
                   1073:                p->nextp = templist[t];
                   1074:                templist[t] = p;
                   1075:                }
                   1076:        holdtemps = 0;
                   1077:        }
                   1078: 
                   1079: /* allocate an automatic variable slot for each of   nelt   variables */
                   1080: 
                   1081: Addrp autovar(nelt0, t, lengp, name)
                   1082: register int nelt0, t;
                   1083: expptr lengp;
                   1084: char *name;
                   1085: {
                   1086:        ftnint leng;
                   1087:        register Addrp q;
                   1088:        char *temp_name ();
                   1089:        register int nelt = nelt0 > 0 ? nelt0 : 1;
                   1090:        extern char *av_pfix[];
                   1091: 
                   1092:        if(t == TYCHAR)
                   1093:                if( ISICON(lengp) )
                   1094:                        leng = lengp->constblock.Const.ci;
                   1095:                else    {
                   1096:                        Fatal("automatic variable of nonconstant length");
                   1097:                }
                   1098:        else
                   1099:                leng = typesize[t];
                   1100: 
                   1101:        q = ALLOC(Addrblock);
                   1102:        q->tag = TADDR;
                   1103:        q->vtype = t;
                   1104:        if(t == TYCHAR)
                   1105:        {
                   1106:                q->vleng = ICON(leng);
                   1107:                q->varleng = leng;
                   1108:        }
                   1109:        q->vstg = STGAUTO;
                   1110:        q->ntempelt = nelt;
                   1111:        q->isarray = (nelt > 1);
                   1112:        q->memoffset = ICON(0);
                   1113: 
                   1114:        /* kludge for nls so we can have ret_val rather than ret_val_4 */
                   1115:        if (*name == ' ')
                   1116:                unamstring(q, name);
                   1117:        else {
                   1118:                q->uname_tag = UNAM_IDENT;
                   1119:                temp_name(av_pfix[t], ++autonum[t], q->user.ident);
                   1120:                }
                   1121:        if (nelt0 > 0)
                   1122:                declare_new_addr (q);
                   1123:        return(q);
                   1124: }
                   1125: 
                   1126: 
                   1127: /* Returns a temporary of the appropriate type.  Will reuse existing
                   1128:    temporaries when possible */
                   1129: 
                   1130: Addrp mktmpn(nelt, type, lengp)
                   1131: int nelt;
                   1132: register int type;
                   1133: expptr lengp;
                   1134: {
                   1135:        ftnint leng;
                   1136:        chainp p, oldp;
                   1137:        register Addrp q;
                   1138: 
                   1139:        if(type==TYUNKNOWN || type==TYERROR)
                   1140:                badtype("mktmpn", type);
                   1141: 
                   1142:        if(type==TYCHAR)
                   1143:                if(lengp && ISICON(lengp) )
                   1144:                        leng = lengp->constblock.Const.ci;
                   1145:                else    {
                   1146:                        err("adjustable length");
                   1147:                        return( (Addrp) errnode() );
                   1148:                }
                   1149:        else if (type > TYCHAR || type < TYADDR) {
                   1150:                erri("mktmpn: unexpected type %d", type);
                   1151:                exit(1);
                   1152:                }
                   1153: /*
                   1154:  * if a temporary of appropriate shape is on the templist,
                   1155:  * remove it from the list and return it
                   1156:  */
                   1157:        for(oldp=CHNULL, p=templist[type];  p  ;  oldp=p, p=p->nextp)
                   1158:        {
                   1159:                q = (Addrp) (p->datap);
                   1160:                if(q->ntempelt==nelt &&
                   1161:                    (type!=TYCHAR || q->vleng->constblock.Const.ci==leng) )
                   1162:                {
                   1163:                        if(oldp)
                   1164:                                oldp->nextp = p->nextp;
                   1165:                        else
                   1166:                                templist[type] = p->nextp;
                   1167:                        free( (charptr) p);
                   1168:                        return(q);
                   1169:                }
                   1170:        }
                   1171:        q = autovar(nelt, type, lengp, "");
                   1172:        return(q);
                   1173: }
                   1174: 
                   1175: 
                   1176: 
                   1177: 
                   1178: /* mktmp -- create new local variable; call it something like   name
                   1179:    lengp   is taken directly, not copied */
                   1180: 
                   1181: Addrp mktmp(type, lengp)
                   1182: int type;
                   1183: expptr lengp;
                   1184: {
                   1185:        Addrp rv;
                   1186:        /* arrange for temporaries to be recycled */
                   1187:        /* at the end of this statement... */
                   1188:        rv = mktmpn(1,type,lengp);
                   1189:        frtemp((Addrp)cpexpr((expptr)rv));
                   1190:        return rv;
                   1191: }
                   1192: 
                   1193: /* mktmp0 omits frtemp() */
                   1194: Addrp mktmp0(type, lengp)
                   1195: int type;
                   1196: expptr lengp;
                   1197: {
                   1198:        Addrp rv;
                   1199:        /* arrange for temporaries to be recycled */
                   1200:        /* when this Addrp is freed */
                   1201:        rv = mktmpn(1,type,lengp);
                   1202:        rv->istemp = YES;
                   1203:        return rv;
                   1204: }
                   1205: 
                   1206: /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
                   1207: 
                   1208: /* comblock -- Declare a new common block.  Input parameters name the block;
                   1209:    s   will be NULL if the block is unnamed */
                   1210: 
                   1211: Extsym *comblock(s)
                   1212:  register char *s;
                   1213: {
                   1214:        Extsym *p;
                   1215:        register char *t;
                   1216:        register int c, i;
                   1217:        char cbuf[256], *s0;
                   1218: 
                   1219: /* Give the unnamed common block a unique name */
                   1220: 
                   1221:        if(*s == 0)
                   1222:                p = mkext(Blank,Blank);
                   1223:        else {
                   1224:                s0 = s;
                   1225:                t = cbuf;
                   1226:                for(i = 0; c = *t = *s++; t++)
                   1227:                        if (c == '_')
                   1228:                                i = 1;
                   1229:                if (i)
                   1230:                        *t++ = '_';
                   1231:                t[0] = '_';
                   1232:                t[1] = 0;
                   1233:                p = mkext(s0,cbuf);
                   1234:                }
                   1235:        if(p->extstg == STGUNKNOWN)
                   1236:                p->extstg = STGCOMMON;
                   1237:        else if(p->extstg != STGCOMMON)
                   1238:        {
                   1239:                errstr("%.68s cannot be a common block name", s);
                   1240:                return(0);
                   1241:        }
                   1242: 
                   1243:        return( p );
                   1244: }
                   1245: 
                   1246: 
                   1247: /* incomm -- add a new variable to a common declaration */
                   1248: 
                   1249: incomm(c, v)
                   1250: Extsym *c;
                   1251: Namep v;
                   1252: {
                   1253:        if (!c)
                   1254:                return;
                   1255:        if(v->vstg != STGUNKNOWN && !v->vimplstg)
                   1256:                dclerr(v->vstg == STGARG
                   1257:                        ? "dummy arguments cannot be in common"
                   1258:                        : "incompatible common declaration", v);
                   1259:        else
                   1260:        {
                   1261:                v->vstg = STGCOMMON;
                   1262:                c->extp = mkchain((char *)v, c->extp);
                   1263:        }
                   1264: }
                   1265: 
                   1266: 
                   1267: 
                   1268: 
                   1269: /* settype -- set the type or storage class of a Namep object.  If
                   1270:    v -> vstg == STGUNKNOWN && type < 0,   attempt to reset vstg to be
                   1271:    -type.  This function will not change any earlier definitions in   v,
                   1272:    in will only attempt to fill out more information give the other params */
                   1273: 
                   1274: settype(v, type, length)
                   1275: register Namep  v;
                   1276: register int type;
                   1277: register ftnint length;
                   1278: {
                   1279:        int type1;
                   1280: 
                   1281:        if(type == TYUNKNOWN)
                   1282:                return;
                   1283: 
                   1284:        if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
                   1285:        {
                   1286:                v->vtype = TYSUBR;
                   1287:                frexpr(v->vleng);
                   1288:                v->vleng = 0;
                   1289:                v->vimpltype = 0;
                   1290:        }
                   1291:        else if(type < 0)       /* storage class set */
                   1292:        {
                   1293:                if(v->vstg == STGUNKNOWN)
                   1294:                        v->vstg = - type;
                   1295:                else if(v->vstg != -type)
                   1296:                        dclerr("incompatible storage declarations", v);
                   1297:        }
                   1298:        else if(v->vtype == TYUNKNOWN || v->vimpltype && v->vtype != type)
                   1299:        {
                   1300:                if( (v->vtype = lengtype(type, length))==TYCHAR )
                   1301:                        if (length>=0)
                   1302:                                v->vleng = ICON(length);
                   1303:                        else if (parstate >= INDATA)
                   1304:                                v->vleng = ICON(1);     /* avoid a memory fault */
                   1305:                v->vimpltype = 0;
                   1306: 
                   1307:                if (v->vclass == CLPROC) {
                   1308:                        if (v->vstg == STGEXT
                   1309:                         && (type1 = extsymtab[v->vardesc.varno].extype)
                   1310:                         &&  type1 != v->vtype)
                   1311:                                changedtype(v);
                   1312:                        else if (v->vprocclass == PTHISPROC
                   1313:                                        && (parstate >= INDATA
                   1314:                                                || procclass == CLMAIN)
                   1315:                                        && !xretslot[type]) {
                   1316:                                xretslot[type] = autovar(ONEOF(type,
                   1317:                                        MSKCOMPLEX|MSKCHAR) ? 0 : 1, type,
                   1318:                                        v->vleng, " ret_val");
                   1319:                                if (procclass == CLMAIN)
                   1320:                                        errstr(
                   1321:                                "illegal use of %.60s (main program name)",
                   1322:                                        v->fvarname);
                   1323:                                /* not completely right, but enough to */
                   1324:                                /* avoid memory faults; we won't */
                   1325:                                /* emit any C as we have illegal Fortran */
                   1326:                                }
                   1327:                        }
                   1328:        }
                   1329:        else if(v->vtype!=type) {
                   1330:  incompat:
                   1331:                dclerr("incompatible type declarations", v);
                   1332:                }
                   1333:        else if (type==TYCHAR)
                   1334:                if (v->vleng && v->vleng->constblock.Const.ci != length)
                   1335:                        goto incompat;
                   1336:                else if (parstate >= INDATA)
                   1337:                        v->vleng = ICON(1);     /* avoid a memory fault */
                   1338: }
                   1339: 
                   1340: 
                   1341: 
                   1342: 
                   1343: 
                   1344: /* lengtype -- returns the proper compiler type, given input of Fortran
                   1345:    type and length specifier */
                   1346: 
                   1347: lengtype(type, len)
                   1348: register int type;
                   1349: ftnint len;
                   1350: {
                   1351:        register int length = (int)len;
                   1352:        switch(type)
                   1353:        {
                   1354:        case TYREAL:
                   1355:                if(length == typesize[TYDREAL])
                   1356:                        return(TYDREAL);
                   1357:                if(length == typesize[TYREAL])
                   1358:                        goto ret;
                   1359:                break;
                   1360: 
                   1361:        case TYCOMPLEX:
                   1362:                if(length == typesize[TYDCOMPLEX])
                   1363:                        return(TYDCOMPLEX);
                   1364:                if(length == typesize[TYCOMPLEX])
                   1365:                        goto ret;
                   1366:                break;
                   1367: 
                   1368:        case TYINT1:
                   1369:        case TYSHORT:
                   1370:        case TYDREAL:
                   1371:        case TYDCOMPLEX:
                   1372:        case TYCHAR:
                   1373:        case TYLOGICAL1:
                   1374:        case TYLOGICAL2:
                   1375:        case TYUNKNOWN:
                   1376:        case TYSUBR:
                   1377:        case TYERROR:
                   1378: #ifdef TYQUAD
                   1379:        case TYQUAD:
                   1380: #endif
                   1381:                goto ret;
                   1382: 
                   1383:        case TYLOGICAL:
                   1384:                switch(length) {
                   1385:                        case 0: return tylog;
                   1386:                        case 1: return TYLOGICAL1;
                   1387:                        case 2: return TYLOGICAL2;
                   1388:                        case 4: goto ret;
                   1389:                        }
                   1390: #if 0 /*!!??!!*/
                   1391:                if(length == typesize[TYLOGICAL])
                   1392:                        goto ret;
                   1393: #endif
                   1394:                break;
                   1395: 
                   1396:        case TYLONG:
                   1397:                if(length == 0)
                   1398:                        return(tyint);
                   1399:                if (length == 1)
                   1400:                        return TYINT1;
                   1401:                if(length == typesize[TYSHORT])
                   1402:                        return(TYSHORT);
                   1403: #ifdef TYQUAD
                   1404:                if(length == typesize[TYQUAD] && use_tyquad)
                   1405:                        return(TYQUAD);
                   1406: #endif
                   1407:                if(length == typesize[TYLONG])
                   1408:                        goto ret;
                   1409:                break;
                   1410:        default:
                   1411:                badtype("lengtype", type);
                   1412:        }
                   1413: 
                   1414:        if(len != 0)
                   1415:                err("incompatible type-length combination");
                   1416: 
                   1417: ret:
                   1418:        return(type);
                   1419: }
                   1420: 
                   1421: 
                   1422: 
                   1423: 
                   1424: 
                   1425: /* setintr -- Set Intrinsic function */
                   1426: 
                   1427: setintr(v)
                   1428: register Namep  v;
                   1429: {
                   1430:        int k;
                   1431: 
                   1432:        if(v->vstg == STGUNKNOWN)
                   1433:                v->vstg = STGINTR;
                   1434:        else if(v->vstg!=STGINTR)
                   1435:                dclerr("incompatible use of intrinsic function", v);
                   1436:        if(v->vclass==CLUNKNOWN)
                   1437:                v->vclass = CLPROC;
                   1438:        if(v->vprocclass == PUNKNOWN)
                   1439:                v->vprocclass = PINTRINSIC;
                   1440:        else if(v->vprocclass != PINTRINSIC)
                   1441:                dclerr("invalid intrinsic declaration", v);
                   1442:        if(k = intrfunct(v->fvarname)) {
                   1443:                if ((*(struct Intrpacked *)&k).f4)
                   1444:                        if (noextflag)
                   1445:                                goto unknown;
                   1446:                        else
                   1447:                                dcomplex_seen++;
                   1448:                v->vardesc.varno = k;
                   1449:                }
                   1450:        else {
                   1451:  unknown:
                   1452:                dclerr("unknown intrinsic function", v);
                   1453:                }
                   1454: }
                   1455: 
                   1456: 
                   1457: 
                   1458: /* setext -- Set External declaration -- assume that unknowns will become
                   1459:    procedures */
                   1460: 
                   1461: setext(v)
                   1462: register Namep  v;
                   1463: {
                   1464:        if(v->vclass == CLUNKNOWN)
                   1465:                v->vclass = CLPROC;
                   1466:        else if(v->vclass != CLPROC)
                   1467:                dclerr("invalid external declaration", v);
                   1468: 
                   1469:        if(v->vprocclass == PUNKNOWN)
                   1470:                v->vprocclass = PEXTERNAL;
                   1471:        else if(v->vprocclass != PEXTERNAL)
                   1472:                dclerr("invalid external declaration", v);
                   1473: } /* setext */
                   1474: 
                   1475: 
                   1476: 
                   1477: 
                   1478: /* create dimensions block for array variable */
                   1479: 
                   1480: setbound(v, nd, dims)
                   1481: register Namep  v;
                   1482: int nd;
                   1483: struct Dims dims[ ];
                   1484: {
                   1485:        register expptr q, t;
                   1486:        register struct Dimblock *p;
                   1487:        int i;
                   1488:        extern chainp new_vars;
                   1489:        char buf[256];
                   1490: 
                   1491:        if(v->vclass == CLUNKNOWN)
                   1492:                v->vclass = CLVAR;
                   1493:        else if(v->vclass != CLVAR)
                   1494:        {
                   1495:                dclerr("only variables may be arrays", v);
                   1496:                return;
                   1497:        }
                   1498: 
                   1499:        v->vdim = p = (struct Dimblock *)
                   1500:            ckalloc( sizeof(int) + (3+2*nd)*sizeof(expptr) );
                   1501:        p->ndim = nd--;
                   1502:        p->nelt = ICON(1);
                   1503:        doin_setbound = 1;
                   1504: 
                   1505:        for(i = 0; i <= nd; ++i)
                   1506:        {
                   1507:                if( (q = dims[i].ub) == NULL)
                   1508:                {
                   1509:                        if(i == nd)
                   1510:                        {
                   1511:                                frexpr(p->nelt);
                   1512:                                p->nelt = NULL;
                   1513:                        }
                   1514:                        else
                   1515:                                err("only last bound may be asterisk");
                   1516:                        p->dims[i].dimsize = ICON(1);
                   1517:                        ;
                   1518:                        p->dims[i].dimexpr = NULL;
                   1519:                }
                   1520:                else
                   1521:                {
                   1522: 
                   1523:                        if(dims[i].lb)
                   1524:                        {
                   1525:                                q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
                   1526:                                q = mkexpr(OPPLUS, q, ICON(1) );
                   1527:                        }
                   1528:                        if( ISCONST(q) )
                   1529:                        {
                   1530:                                p->dims[i].dimsize = q;
                   1531:                                p->dims[i].dimexpr = (expptr) PNULL;
                   1532:                        }
                   1533:                        else {
                   1534:                                sprintf(buf, " %s_dim%d", v->fvarname, i+1);
                   1535:                                p->dims[i].dimsize = (expptr)
                   1536:                                        autovar(1, tyint, EXNULL, buf);
                   1537:                                p->dims[i].dimexpr = q;
                   1538:                                if (i == nd)
                   1539:                                        v->vlastdim = new_vars;
                   1540:                                v->vdimfinish = 1;
                   1541:                        }
                   1542:                        if(p->nelt)
                   1543:                                p->nelt = mkexpr(OPSTAR, p->nelt,
                   1544:                                    cpexpr(p->dims[i].dimsize) );
                   1545:                }
                   1546:        }
                   1547: 
                   1548:        q = dims[nd].lb;
                   1549:        if(q == NULL)
                   1550:                q = ICON(1);
                   1551: 
                   1552:        for(i = nd-1 ; i>=0 ; --i)
                   1553:        {
                   1554:                t = dims[i].lb;
                   1555:                if(t == NULL)
                   1556:                        t = ICON(1);
                   1557:                if(p->dims[i].dimsize)
                   1558:                        q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
                   1559:        }
                   1560: 
                   1561:        if( ISCONST(q) )
                   1562:        {
                   1563:                p->baseoffset = q;
                   1564:                p->basexpr = NULL;
                   1565:        }
                   1566:        else
                   1567:        {
                   1568:                sprintf(buf, " %s_offset", v->fvarname);
                   1569:                p->baseoffset = (expptr) autovar(1, tyint, EXNULL, buf);
                   1570:                p->basexpr = q;
                   1571:                v->vdimfinish = 1;
                   1572:        }
                   1573:        doin_setbound = 0;
                   1574: }
                   1575: 
                   1576: 
                   1577: 
                   1578: wr_abbrevs (outfile, function_head, vars)
                   1579: FILE *outfile;
                   1580: int function_head;
                   1581: chainp vars;
                   1582: {
                   1583:     for (; vars; vars = vars -> nextp) {
                   1584:        Namep name = (Namep) vars -> datap;
                   1585:        if (!name->visused)
                   1586:                continue;
                   1587: 
                   1588:        if (function_head)
                   1589:            nice_printf (outfile, "#define ");
                   1590:        else
                   1591:            nice_printf (outfile, "#undef ");
                   1592:        out_name (outfile, name);
                   1593: 
                   1594:        if (function_head) {
                   1595:            Extsym *comm = &extsymtab[name -> vardesc.varno];
                   1596: 
                   1597:            nice_printf (outfile, " (");
                   1598:            extern_out (outfile, comm);
                   1599:            nice_printf (outfile, "%d.", comm->curno);
                   1600:            nice_printf (outfile, "%s)", name->cvarname);
                   1601:        } /* if function_head */
                   1602:        nice_printf (outfile, "\n");
                   1603:     } /* for */
                   1604: } /* wr_abbrevs */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.