Annotation of researchv10no/cmd/f2c/proc.c, revision 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.