Annotation of researchv10no/cmd/f77/proc.c, revision 1.1

1.1     ! root        1: #include "defs"
        !             2: 
        !             3: #ifdef SDB
        !             4: #      include <a.out.h>
        !             5: char *stabline();
        !             6: #      ifndef N_SO
        !             7: #              include <stab.h>
        !             8: #      endif
        !             9: char *stabdline();
        !            10: #endif
        !            11: char *memname();
        !            12: #define ESNULL (struct Extsym *)0
        !            13: #define EXNULL (union Expression *)0
        !            14: 
        !            15: LOCAL dobss(), docomleng(), docommon(), doentry(), dolblfudge(),
        !            16: epicode(), nextarg(), procode(), retval();
        !            17: 
        !            18: /* start a new procedure */
        !            19: 
        !            20: newproc()
        !            21: {
        !            22:        if(parstate != OUTSIDE)
        !            23:        {
        !            24:                execerr("missing end statement", CNULL);
        !            25:                endproc();
        !            26:        }
        !            27: 
        !            28:        parstate = INSIDE;
        !            29:        procclass = CLMAIN;     /* default */
        !            30: }
        !            31: 
        !            32: 
        !            33: 
        !            34: /* end of procedure. generate variables, epilogs, and prologs */
        !            35: 
        !            36: endproc()
        !            37: {
        !            38:        struct Labelblock *lp;
        !            39: #if SDB
        !            40:        char elab[10];
        !            41:        int elnum;
        !            42: #endif
        !            43: 
        !            44:        if(parstate < INDATA)
        !            45:                enddcl();
        !            46:        if(ctlstack >= ctls)
        !            47:                err("DO loop or BLOCK IF not closed");
        !            48:        for(lp = labeltab ; lp < labtabend ; ++lp)
        !            49:                if(lp->stateno!=0 && lp->labdefined==NO)
        !            50:                        errstr("missing statement number %s", convic(lp->stateno) );
        !            51: 
        !            52:        dolblfudge();
        !            53:        epicode();
        !            54:        procode();
        !            55:        donmlist();
        !            56:        dobss();
        !            57:        prdbginfo();
        !            58: #if SDB
        !            59:        if (sdbflag && procclass != CLBLOCK) {
        !            60:                sprintf(elab, "L%d", elnum = newlabel());
        !            61:                putlabel(elnum);
        !            62:                prstab(procclass == CLMAIN ? "MAIN_" : nounder(XL, procname),
        !            63:                    N_EFUN, lineno, elab);
        !            64:        }
        !            65: #endif
        !            66: #if FAMILY == PCC
        !            67:        putbracket();
        !            68: #endif
        !            69:        fixlwm();
        !            70:        procinit();     /* clean up for next procedure */
        !            71: }
        !            72: 
        !            73: 
        !            74: 
        !            75: /* End of declaration section of procedure.  Allocate storage. */
        !            76: 
        !            77: enddcl()
        !            78: {
        !            79:        register struct Entrypoint *ep;
        !            80: 
        !            81: #ifdef SDB
        !            82:        if( sdbflag )
        !            83:        {
        !            84: #      ifdef UCBVAXASM
        !            85:                p2pass( stabdline(N_SLINE, lineno) );
        !            86: #      else
        !            87:                char buff[10];
        !            88:                sprintf(buff,"LL%d", ++dbglabel);
        !            89:                p2pass( stabline(0, N_SLINE, lineno, buff) );
        !            90:                p2pi("LL%d:\n", dbglabel);
        !            91: #      endif
        !            92:        }
        !            93: #endif
        !            94:        parstate = INEXEC;
        !            95:        docommon();
        !            96:        doequiv();
        !            97:        docomleng();
        !            98:        for(ep = entries ; ep ; ep = ep->entnextp)
        !            99:                doentry(ep);
        !           100: }
        !           101: 
        !           102: /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
        !           103: 
        !           104: /* Main program or Block data */
        !           105: 
        !           106: startproc(progname, class)
        !           107: struct Extsym * progname;
        !           108: int class;
        !           109: {
        !           110:        register struct Entrypoint *p;
        !           111:        char *ftnname();
        !           112: 
        !           113:        p = ALLOC(Entrypoint);
        !           114:        if(class == CLMAIN)
        !           115:                puthead("MAIN__", CLMAIN);
        !           116:        else
        !           117:                puthead(CNULL, CLBLOCK);
        !           118:        if(class == CLMAIN)
        !           119:                newentry( mkname(5, "MAIN_") );
        !           120:        p->entryname = progname;
        !           121:        p->entrylabel = newlabel();
        !           122:        entries = p;
        !           123: 
        !           124:        procclass = class;
        !           125:        retlabel = newlabel();
        !           126:        fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
        !           127:        if(progname)
        !           128:                fprintf(diagfile, " %s", nounder(XL, procname = progname->extname) );
        !           129:        fprintf(diagfile, ":\n");
        !           130: #ifdef SDB
        !           131:        if(sdbflag && class==CLMAIN)
        !           132:        {
        !           133:                prstab("MAIN__", N_BFUN, lineno, ftnname(STGEXT, "MAIN__"));
        !           134: #if NOTDEF
        !           135:                p2pass( stabline("MAIN_", N_FNAME, 0, 0) );
        !           136: #endif
        !           137:                if(progname)
        !           138:                {
        !           139:                        prstab(nounder(XL,progname->extname), N_ENTRY, lineno,
        !           140:                            ftnname(STGEXT, progname->extname));
        !           141:                        /*              p2pass(stabline(nounder(XL,progname->extname),N_FNAME,0,0));    */
        !           142:                }
        !           143:        }
        !           144: #endif
        !           145: }
        !           146: 
        !           147: /* subroutine or function statement */
        !           148: 
        !           149: struct Extsym *newentry(v)
        !           150: register Namep v;
        !           151: {
        !           152:        register struct Extsym *p;
        !           153: 
        !           154:        p = mkext( varunder(VL, v->varname) );
        !           155: 
        !           156:        if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
        !           157:        {
        !           158:                if(p == 0)
        !           159:                        dclerr("invalid entry name", v);
        !           160:                else    dclerr("external name already used", v);
        !           161:                return(0);
        !           162:        }
        !           163:        v->vstg = STGAUTO;
        !           164:        v->vprocclass = PTHISPROC;
        !           165:        v->vclass = CLPROC;
        !           166:        p->extstg = STGEXT;
        !           167:        p->extinit = YES;
        !           168:        return(p);
        !           169: }
        !           170: 
        !           171: 
        !           172: entrypt(class, type, length, entry, args)
        !           173: int class, type;
        !           174: ftnint length;
        !           175: struct Extsym *entry;
        !           176: chainp args;
        !           177: {
        !           178:        register Namep q;
        !           179:        register struct Entrypoint *p, *ep;
        !           180:        extern int types3[];
        !           181: 
        !           182:        if(class != CLENTRY)
        !           183:                puthead( varstr(XL, procname = entry->extname), class);
        !           184:        if(class == CLENTRY)
        !           185:                fprintf(diagfile, "       entry ");
        !           186:        fprintf(diagfile, "   %s:\n", nounder(XL, entry->extname));
        !           187:        q = mkname(VL, nounder(XL,entry->extname) );
        !           188: 
        !           189:        if( (type = lengtype(type, (int) length)) != TYCHAR)
        !           190:                length = 0;
        !           191:        if(class == CLPROC)
        !           192:        {
        !           193:                procclass = CLPROC;
        !           194:                proctype = type;
        !           195:                procleng = length;
        !           196: 
        !           197:                retlabel = newlabel();
        !           198:                if(type == TYSUBR)
        !           199:                        ret0label = newlabel();
        !           200:        }
        !           201: 
        !           202:        p = ALLOC(Entrypoint);
        !           203: 
        !           204:        if(entries)     /* put new block at end of entries list */
        !           205:        {
        !           206:                for(ep = entries; ep->entnextp; ep = ep->entnextp)
        !           207:                        ;
        !           208:                ep->entnextp = p;
        !           209:        }
        !           210:        else
        !           211:                entries = p;
        !           212: 
        !           213:        p->entryname = entry;
        !           214:        p->arglist = args;
        !           215:        p->entrylabel = newlabel();
        !           216:        p->enamep = q;
        !           217: 
        !           218: #ifdef SDB
        !           219:        if(sdbflag)
        !           220:        {
        !           221:                /*      prstab(nounder(XL, entry->extname),
        !           222:  *             (class==CLENTRY ? N_ENTRY : N_BFUN),
        !           223:  *             lineno, ftnname(STGEXT, entry->extname));
        !           224:  */
        !           225:                prstab(entry->extname,
        !           226:                    (class==CLENTRY ? N_ENTRY : N_BFUN),
        !           227:                    lineno, ftnname(STGEXT, entry->extname));
        !           228:                if (class != CLENTRY)
        !           229:                        prstab(entry->extname, N_GSYM, types3[type], CNULL);
        !           230:                if(class != CLENTRY) {
        !           231: #if NOTDEF
        !           232:                        /*              p2pass( stabline( nounder(XL,entry->extname), N_FNAME, 0, 0) );
        !           233:  */
        !           234:                        p2pass( stabline( entry->extname, N_FNAME, 0, 0) );
        !           235: #endif
        !           236:                }
        !           237:        }
        !           238: #endif
        !           239: 
        !           240:        if(class == CLENTRY)
        !           241:        {
        !           242:                class = CLPROC;
        !           243:                if(proctype == TYSUBR)
        !           244:                        type = TYSUBR;
        !           245:        }
        !           246: 
        !           247:        q->vclass = class;
        !           248:        q->vprocclass = PTHISPROC;
        !           249:        settype(q, type, (int) length);
        !           250:        /* hold all initial entry points till end of declarations */
        !           251:        if(parstate >= INDATA)
        !           252:                doentry(p);
        !           253: }
        !           254: 
        !           255: /* fudge labels (for ASSIGN stmts that reference yet undefined labels) */
        !           256: 
        !           257: LOCAL dolblfudge()
        !           258: {
        !           259:        extern chainp Lblfudgelist;
        !           260:        register chainp cp;
        !           261:        register Addrp A;
        !           262: 
        !           263:        for(cp = Lblfudgelist; cp; cp = cp->nextp->nextp) {
        !           264:                A = (Addrp)cp->nextp->datap;
        !           265:                fprintf(asmfile, "v.%d:\t.long\tL%d\n", A->memno,
        !           266:                        (int)cp->datap);
        !           267:                free((char *)A);
        !           268:                }
        !           269:        frchain(&Lblfudgelist);
        !           270:        }
        !           271: 
        !           272: /* generate epilogs */
        !           273: 
        !           274: LOCAL epicode()
        !           275: {
        !           276:        register int i;
        !           277: 
        !           278:        if(procclass==CLPROC)
        !           279:        {
        !           280:                if(proctype==TYSUBR)
        !           281:                {
        !           282:                        putlabel(ret0label);
        !           283:                        if(substars)
        !           284:                                putforce(TYINT, ICON(0) );
        !           285:                        putlabel(retlabel);
        !           286:                        goret(TYSUBR);
        !           287:                }
        !           288:                else    {
        !           289:                        putlabel(retlabel);
        !           290:                        if(multitype)
        !           291:                        {
        !           292:                                typeaddr = autovar(1, TYADDR, EXNULL);
        !           293:                                putbranch( cpexpr(typeaddr) );
        !           294:                                for(i = 0; i < NTYPES ; ++i)
        !           295:                                        if(rtvlabel[i] != 0)
        !           296:                                        {
        !           297:                                                putlabel(rtvlabel[i]);
        !           298:                                                retval(i);
        !           299:                                        }
        !           300:                        }
        !           301:                        else
        !           302:                                retval(proctype);
        !           303:                }
        !           304:        }
        !           305: 
        !           306:        else if(procclass != CLBLOCK)
        !           307:        {
        !           308:                putlabel(retlabel);
        !           309:                goret(TYSUBR);
        !           310:        }
        !           311: }
        !           312: 
        !           313: 
        !           314: /* generate code to return value of type  t */
        !           315: 
        !           316: LOCAL retval(t)
        !           317: register int t;
        !           318: {
        !           319:        register Addrp p;
        !           320: 
        !           321:        switch(t)
        !           322:        {
        !           323:        case TYCHAR:
        !           324:        case TYCOMPLEX:
        !           325:        case TYDCOMPLEX:
        !           326:                break;
        !           327: 
        !           328:        case TYLOGICAL:
        !           329:                t = tylogical;
        !           330:        case TYADDR:
        !           331:        case TYSHORT:
        !           332:        case TYLONG:
        !           333:                p = (Addrp) cpexpr(retslot);
        !           334:                p->vtype = t;
        !           335:                putforce(t, p);
        !           336:                break;
        !           337: 
        !           338:        case TYREAL:
        !           339:        case TYDREAL:
        !           340:                p = (Addrp) cpexpr(retslot);
        !           341:                p->vtype = t;
        !           342:                putforce(t, p);
        !           343:                break;
        !           344: 
        !           345:        default:
        !           346:                badtype("retval", t);
        !           347:        }
        !           348:        goret(t);
        !           349: }
        !           350: 
        !           351: 
        !           352: /* Allocate extra argument array if needed. Generate prologs. */
        !           353: 
        !           354: LOCAL procode()
        !           355: {
        !           356:        register struct Entrypoint *p;
        !           357:        Addrp argvec;
        !           358: 
        !           359: #if TARGET==GCOS
        !           360:        argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
        !           361: #else
        !           362:        if(lastargslot>0 && nentry>1)
        !           363: #if TARGET == VAX
        !           364:                argvec = autovar(1 + lastargslot/SZADDR, TYADDR, EXNULL);
        !           365: #else
        !           366:        argvec = autovar(lastargslot/SZADDR, TYADDR, EXNULL);
        !           367: #endif
        !           368: else
        !           369:        argvec = NULL;
        !           370: #endif
        !           371: 
        !           372: 
        !           373: #if TARGET == PDP11
        !           374: /* for the optimizer */
        !           375: if(fudgelabel)
        !           376: putlabel(fudgelabel);
        !           377: #endif
        !           378: 
        !           379: for(p = entries ; p ; p = p->entnextp)
        !           380: prolog(p, argvec);
        !           381: 
        !           382: #if FAMILY == PCC
        !           383: putrbrack(procno);
        !           384: #endif
        !           385: 
        !           386: prendproc();
        !           387: }
        !           388: 
        !           389: /*
        !           390:    manipulate argument lists (allocate argument slot positions)
        !           391:  * keep track of return types and labels
        !           392:  */
        !           393: 
        !           394: LOCAL doentry(ep)
        !           395: struct Entrypoint *ep;
        !           396: {
        !           397:        register int type;
        !           398:        register Namep np;
        !           399:        chainp p;
        !           400:        register Namep q;
        !           401:        Addrp mkarg();
        !           402:        int botched_procs;
        !           403: 
        !           404:        ++nentry;
        !           405:        if(procclass == CLMAIN)
        !           406:        {
        !           407: #ifdef SDB
        !           408:                if (sdbflag)
        !           409:                        prstab(CNULL, N_LBRAC, 0, "2");
        !           410: #endif
        !           411:                putlabel(ep->entrylabel);
        !           412:                return;
        !           413:        }
        !           414:        else if(procclass == CLBLOCK) {
        !           415: #ifdef SDB
        !           416:                if (sdbflag)
        !           417:                        prstab(CNULL, N_LBRAC, 0, "2");
        !           418: #endif
        !           419:                return;
        !           420:        }
        !           421: 
        !           422:        impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
        !           423:        type = np->vtype;
        !           424:        if(proctype == TYUNKNOWN)
        !           425:                if( (proctype = type) == TYCHAR)
        !           426:                        procleng = (np->vleng ? np->vleng->constblock.Const.ci : (ftnint) (-1));
        !           427: 
        !           428:        if(proctype == TYCHAR)
        !           429:        {
        !           430:                if(type != TYCHAR)
        !           431:                        err("noncharacter entry of character function");
        !           432:                else if( (np->vleng ? np->vleng->constblock.Const.ci : (ftnint) (-1)) != procleng)
        !           433:                        err("mismatched character entry lengths");
        !           434:        }
        !           435:        else if(type == TYCHAR)
        !           436:                err("character entry of noncharacter function");
        !           437:        else if(type != proctype)
        !           438:                multitype = YES;
        !           439:        if(rtvlabel[type] == 0)
        !           440:                rtvlabel[type] = newlabel();
        !           441:        ep->typelabel = rtvlabel[type];
        !           442: 
        !           443:        if(type == TYCHAR)
        !           444:        {
        !           445:                if(chslot < 0)
        !           446:                {
        !           447:                        chslot = nextarg(TYADDR);
        !           448:                        chlgslot = nextarg(TYLENG);
        !           449:                }
        !           450:                np->vstg = STGARG;
        !           451:                np->vardesc.varno = chslot;
        !           452:                if(procleng < 0)
        !           453:                        np->vleng = (expptr) mkarg(TYLENG, chlgslot);
        !           454: #ifdef SDB
        !           455:                if (sdbflag) {
        !           456:                        prstab("ret_val", N_PSYM, 34, "4");
        !           457:                        prstab("ret_val_len", N_PSYM, 5, "8");
        !           458:                }
        !           459: #endif
        !           460:        }
        !           461:        else if( ISCOMPLEX(type) )
        !           462:        {
        !           463:                np->vstg = STGARG;
        !           464:                if(cxslot < 0)
        !           465:                        cxslot = nextarg(TYADDR);
        !           466:                np->vardesc.varno = cxslot;
        !           467: #ifdef SDB
        !           468:                if (sdbflag) {
        !           469:                        prstab("ret_val", N_PSYM, 40, "4");
        !           470:                        prstab(type == TYCOMPLEX ? "complex" : "dcomplex",
        !           471:                            N_TYID, 0, CNULL);
        !           472:                }
        !           473: #endif
        !           474:        }
        !           475:        else if(type != TYSUBR)
        !           476:        {
        !           477:                if(nentry == 1)
        !           478:                        retslot = autovar(1, TYDREAL, EXNULL);
        !           479:                np->vstg = STGAUTO;
        !           480:                np->voffset = retslot->memoffset->constblock.Const.ci;
        !           481:        }
        !           482: 
        !           483:        for(p = ep->arglist ; p ; p = p->nextp)
        !           484:                if(! (( q = (Namep) (p->datap) )->vdcldone) )
        !           485:                        q->vardesc.varno = nextarg(TYADDR);
        !           486: 
        !           487:        botched_procs = 0;
        !           488:        for(p = ep->arglist ; p ; p = p->nextp)
        !           489:                if(! (( q = (Namep) (p->datap) )->vdcldone) )
        !           490:                {
        !           491:                        impldcl(q);
        !           492:                        q->vdcldone = YES;
        !           493: #ifdef SDB
        !           494:                        if(sdbflag)
        !           495:                                prstabtype(ESNULL, q, N_PSYM,
        !           496:                                    convic(q->vardesc.varno + ARGOFFSET));
        !           497: #endif
        !           498:                        if(q->vtype == TYCHAR)
        !           499:                        {
        !           500:                                if (q->vclass == CLPROC)
        !           501:                                        botched_procs++;
        !           502:                                else if (q->vleng == NULL) {
        !           503:                                        /* character*(*) */
        !           504:                                        if (botched_procs && bugwarn & 1)
        !           505:                                                warnb1(
        !           506:                                        "old f77 botched references to %s",
        !           507:                                                        varstr(VL,q->varname));
        !           508:                                        q->vleng = (expptr)
        !           509:                                            mkarg(TYLENG, nextarg(TYLENG) );
        !           510:                                        }
        !           511:                                else if(nentry == 1)
        !           512:                                        nextarg(TYLENG);
        !           513:                        }
        !           514:                        /* Once upon a time, external args caused extra
        !           515:                         * length args to be passed, in case they were
        !           516:                         * character-valued functions.
        !           517:                         */
        !           518:                        else if(q->vclass==CLPROC && nentry==1) {
        !           519:                                botched_procs++;
        !           520:                                if (bugwarn & 2)
        !           521:                                        nextarg(TYLENG) ;
        !           522:                                }
        !           523:                }
        !           524: #ifdef SDB
        !           525:        if (sdbflag)
        !           526:                prstab(CNULL, N_LBRAC, 0, "2");
        !           527: #endif
        !           528: 
        !           529:        putlabel(ep->entrylabel);
        !           530: }
        !           531: 
        !           532: 
        !           533: 
        !           534: LOCAL nextarg(type)
        !           535: int type;
        !           536: {
        !           537:        int k;
        !           538:        k = lastargslot;
        !           539:        lastargslot += typesize[type];
        !           540:        return(k);
        !           541: }
        !           542: 
        !           543: /* generate variable references */
        !           544: 
        !           545: /* the following computes an expression that would address an equivalenced
        !           546:  * variable -- if only one could have expressions in stab addrs...
        !           547:  *
        !           548:  * LOCAL char *memplusoff(q)
        !           549:  * register Namep q;
        !           550:  * {   static char buf[32];
        !           551:  *     char *s;
        !           552:  *     ftnint offset;
        !           553:  *     s = memname(STGEQUIV, q->vardesc.varno);
        !           554:  *     if (!(offset = q->voffset))
        !           555:  *             return s;
        !           556:  *     sprintf(buf, offset > 0 ? "%s+%ld" : "%s%ld", s, offset);
        !           557:  *     return buf;
        !           558:  *     }
        !           559:  */
        !           560: 
        !           561: LOCAL dobss()
        !           562: {
        !           563:        register struct Hashentry *p;
        !           564:        register Namep q;
        !           565:        register int i;
        !           566:        int align;
        !           567:        ftnint leng, iarrl, i1arrlen();
        !           568:        int qstg, qclass, qtype;
        !           569: 
        !           570:        pruse(asmfile, USEBSS);
        !           571: 
        !           572:        for(p = hashtab ; p<lasthash ; ++p)
        !           573:                if(q = p->varp)
        !           574:                {
        !           575:                        qstg = q->vstg;
        !           576:                        qtype = q->vtype;
        !           577:                        qclass = q->vclass;
        !           578: 
        !           579: #ifdef SDB
        !           580:                        if(sdbflag && qclass==CLVAR) switch(qstg)
        !           581:                        {
        !           582:                        case STGAUTO:
        !           583:                                prstabtype(ESNULL, q, N_LSYM,
        !           584:                                    convic(-q->voffset));
        !           585:                                break;
        !           586: 
        !           587:                        case STGBSS:
        !           588:                                prstabtype(ESNULL, q, N_LCSYM,
        !           589:                                    memname(qstg,q->vardesc.varno));
        !           590:                                break;
        !           591: 
        !           592:                        case STGINIT:
        !           593:                                prstabtype(ESNULL, q, N_STSYM,
        !           594:                                    memname(qstg,q->vardesc.varno));
        !           595:                                break;
        !           596: 
        !           597:                        case STGEQUIV:
        !           598:                                i = eqvclass[q->vardesc.varno].eqvinit
        !           599:                                    ? N_STSYM : N_LCSYM;
        !           600:                                /* prstabtype(ESNULL, q, i, memplusoff(q)); */
        !           601:                                if (!q->voffset)
        !           602:                                        prstabtype(ESNULL, q, i,
        !           603:                                            memname(qstg,q->vardesc.varno));
        !           604:                                break;
        !           605:                        }
        !           606: #endif
        !           607: 
        !           608:                        if( (qclass==CLUNKNOWN && qstg!=STGARG
        !           609:                                && !q->vimpldovar) ||
        !           610:                            (qclass==CLVAR && qstg==STGUNKNOWN) )
        !           611:                                warn1("local variable %s never used", varstr(VL,q->varname) );
        !           612:                        else if(qclass==CLVAR && qstg==STGBSS)
        !           613:                        {
        !           614:                                align = (qtype==TYCHAR ? ALILONG : typealign[qtype]);
        !           615:                                if(bssleng % align != 0)
        !           616:                                {
        !           617:                                        bssleng = roundup(bssleng, align);
        !           618:                                        preven(align);
        !           619:                                }
        !           620:                                prlocvar(memname(STGBSS,q->vardesc.varno), iarrl = iarrlen(q) );
        !           621:                                bssleng += iarrl;
        !           622:                        }
        !           623:                        else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG)
        !           624:                                mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
        !           625: 
        !           626:                        if(qclass==CLVAR && qstg!=STGARG)
        !           627:                        {
        !           628:                                if(q->vdim && !ISICON(q->vdim->nelt) )
        !           629:                                        dclerr("adjustable dimension on non-argument", q);
        !           630:                                if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
        !           631:                                        dclerr("adjustable leng on nonargument", q);
        !           632:                        }
        !           633:                }
        !           634: #ifdef SDB
        !           635:        if (sdbflag) {
        !           636:                struct Equivblock *p1;
        !           637:                struct Eqvchain *q1;
        !           638:                Namep np1;
        !           639: 
        !           640:                for(i = 0, p1 = eqvclass; i < nequiv ; ++i, ++p1) {
        !           641:                        if (p1->eqvtop && (q1 = p1->equivs)) {
        !           642: 
        !           643:                                /* put out null-named common block describing   */
        !           644:                                /* EQUIVALENCED variables with nonzero offsets  */
        !           645: 
        !           646:                                do 
        !           647:                                        if ((np1 = q1->eqvitem.eqvname)
        !           648:                                            && np1->voffset) {
        !           649:                                                prstab(CNULL, N_BCOMM, 0, CNULL);
        !           650:                                                prstab(CNULL, p1->eqvinit ? N_STSYM : N_LCSYM,
        !           651:                                                    0, memname(STGEQUIV,
        !           652:                                                    np1->vardesc.varno));
        !           653:                                                do 
        !           654:                                                        if ((np1 = q1->eqvitem.eqvname)
        !           655:                                                            && np1->voffset)
        !           656:                                                                prstabtype(ESNULL, np1, N_SSYM,
        !           657:                                                                    convic(np1->voffset));
        !           658:                                                while(q1 = q1->eqvnextp);
        !           659:                                                prstab(CNULL, N_ECOML, 0, CNULL);
        !           660:                                                break;
        !           661:                                        }
        !           662:                                while(q1 = q1->eqvnextp);
        !           663:                        }
        !           664:                        freqchain(p1);
        !           665:                }
        !           666:        }
        !           667: #endif
        !           668: 
        !           669:        for(i = 0 ; i < nequiv ; ++i)
        !           670:                if(eqvclass[i].eqvinit==NO && (leng = eqvclass[i].eqvleng)!=0 )
        !           671:                {
        !           672:                        bssleng = roundup(bssleng, ALIDOUBLE);
        !           673:                        preven(ALIDOUBLE);
        !           674:                        prlocvar( memname(STGEQUIV, i), leng);
        !           675:                        bssleng += leng;
        !           676:                }
        !           677: #ifdef SDB
        !           678:        if (sdbflag)
        !           679:                prstab(CNULL, N_RBRAC, 0, "2");
        !           680: #endif
        !           681: }
        !           682: 
        !           683: 
        !           684: 
        !           685: donmlist()
        !           686: {
        !           687:        register struct Hashentry *p;
        !           688:        register Namep q;
        !           689: 
        !           690:        pruse(asmfile, USEINIT);
        !           691: 
        !           692:        for(p=hashtab; p<lasthash; ++p)
        !           693:                if( (q = p->varp) && q->vclass==CLNAMELIST)
        !           694:                        namelist(q);
        !           695: }
        !           696: 
        !           697: 
        !           698: doext()
        !           699: {
        !           700:        struct Extsym *p;
        !           701: 
        !           702:        for(p = extsymtab ; p<nextext ; ++p)
        !           703:                prext( varstr(XL, p->extname), p->maxleng, p->extinit);
        !           704: }
        !           705: 
        !           706: 
        !           707: 
        !           708: 
        !           709: ftnint iarrlen(q)
        !           710: register Namep q;
        !           711: {
        !           712:        ftnint leng;
        !           713: 
        !           714:        leng = typesize[q->vtype];
        !           715:        if(leng <= 0)
        !           716:                return(-1);
        !           717:        if(q->vdim)
        !           718:                if( ISICON(q->vdim->nelt) )
        !           719:                        leng *= q->vdim->nelt->constblock.Const.ci;
        !           720:                else    return(-1);
        !           721:        if(q->vleng)
        !           722:                if( ISICON(q->vleng) )
        !           723:                        leng *= q->vleng->constblock.Const.ci;
        !           724:                else return(-1);
        !           725:        return(leng);
        !           726: }
        !           727: 
        !           728: 
        !           729: ftnint i1arrlen(q)
        !           730: register Namep q;
        !           731: {
        !           732:        ftnint leng;
        !           733: 
        !           734:        leng = 1;
        !           735:        if(q->vdim)
        !           736:                if( ISICON(q->vdim->nelt) )
        !           737:                        leng = q->vdim->nelt->constblock.Const.ci;
        !           738:                else    return(-1);
        !           739:        if(q->vleng)
        !           740:                if( ISICON(q->vleng) )
        !           741:                        leng *= q->vleng->constblock.Const.ci;
        !           742:                else return(-1);
        !           743:        return(leng);
        !           744: }
        !           745: 
        !           746: 
        !           747: /* This routine creates static structures representing a namelist.
        !           748:    Declarations of the namelist and related structures are:
        !           749: 
        !           750:        struct Vardesc {
        !           751:                char *name;
        !           752:                char *addr;
        !           753:                Long *dims;     /* laid out as struct dimensions below *//*
        !           754:                int  type;
        !           755:                };
        !           756:        typedef struct Vardesc Vardesc;
        !           757: 
        !           758:        struct Namelist {
        !           759:                char *name;
        !           760:                Vardesc **vars;
        !           761:                int nvars;
        !           762:                };
        !           763: 
        !           764:        struct dimensions
        !           765:                {
        !           766:                long numberofdimensions;
        !           767:                long numberofelements
        !           768:                long baseoffset;
        !           769:                long span[numberofdimensions-1];
        !           770:                };
        !           771: 
        !           772:    If dims is not null, then the corner element of the array is at
        !           773:    addr.  However,  the element with subscripts (i1,...,in) is at
        !           774:    addr + sizeoftype * (i1+span[0]*(i2+span[1]*...) - dimp->baseoffset)
        !           775: */
        !           776: 
        !           777:  static char *
        !           778: ucvarstr(n, s, len)
        !           779:  register int n, *len;
        !           780:  register char *s;
        !           781: {
        !           782:        register int c, i;
        !           783:        static char name[XL+1];
        !           784: 
        !           785:        for(i=0;  i < n && (c = *s++) && c != ' '; ++i)
        !           786:                name[i] = c >= 'a' && c <= 'z' ? c + 'A' - 'a' : c;
        !           787: 
        !           788:        name[i] = '\0';
        !           789: 
        !           790:        *len = i;
        !           791:        return( name );
        !           792:        }
        !           793: 
        !           794:  static void
        !           795: make_desc(v)
        !           796:  register Namep v;
        !           797: {
        !           798:        register char *s;
        !           799:        register struct Dimblock *d;
        !           800:        register expptr e;
        !           801:        int i, n;
        !           802:        ftnint type;
        !           803: 
        !           804:        v->nlmemno = ++lastvarno;
        !           805:        fprintf(asmfile, LABELFMT, memname(STGINIT, ++lastvarno));
        !           806:        s = ucvarstr(VL, v->varname, &n);
        !           807:        putstr(asmfile, s, n);
        !           808:        preven(ALILONG);
        !           809:        if ((d = v->vdim) && d->nelt && ISCONST(d->nelt)) {
        !           810:                fprintf(asmfile, LABELFMT, memname(STGINIT, ++lastvarno));
        !           811:                prconi(asmfile, TYINT, (ftnint)d->ndim);
        !           812:                prconi(asmfile, TYINT,
        !           813:                        (ftnint)d->nelt->constblock.Const.ci);
        !           814:                prconi(asmfile, TYINT,
        !           815:                        (ftnint)d->baseoffset->constblock.Const.ci);
        !           816:                for(i = 0, n = d->ndim - 1; i < n; i++)
        !           817:                        prconi(asmfile, TYINT, (e = d->dims[i].dimsize)
        !           818:                                ? (ftnint)e->constblock.Const.ci : 0L);
        !           819:                }
        !           820:        fprintf(asmfile, LABELFMT, memname(STGINIT, v->nlmemno));
        !           821:        praddr(asmfile, STGINIT, v->nlmemno+1, 0L);
        !           822:        praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset);
        !           823:        praddr(asmfile, d ? STGINIT : STGNULL, lastvarno, 0L);
        !           824:        if ((type = v->vtype) == TYCHAR)
        !           825:                type = -v->vleng->constblock.Const.ci;
        !           826:        prconi(asmfile, TYINT, type);
        !           827:        }
        !           828: 
        !           829: namelist(np)
        !           830: Namep np;
        !           831: {
        !           832: 
        !           833:        register chainp q;
        !           834:        register Namep v;
        !           835:        register struct Dimblock *dp;
        !           836:        int dimno, len;
        !           837:        flag bad;
        !           838:        char *s;
        !           839:        ftnint n = 0;
        !           840: 
        !           841:        bad = NO;
        !           842: 
        !           843:        for(q = np->varxptr.namelist ; q ; q = q->nextp) {
        !           844:                vardcl( v = (Namep) (q->datap) );
        !           845:                if( ONEOF(v->vstg, MSKSTATIC) ) {
        !           846:                        if (!v->nlmemno)
        !           847:                                make_desc(v);
        !           848:                        ++n;
        !           849:                        }
        !           850:                else {
        !           851:                        dclerr("may not appear in namelist", v);
        !           852:                        bad = YES;
        !           853:                        }
        !           854:                }
        !           855: 
        !           856:        if(bad)
        !           857:                return;
        !           858: 
        !           859:        dimno = ++lastvarno;
        !           860:        fprintf(asmfile, LABELFMT, memname(STGINIT, dimno));
        !           861:        for(q = np->varxptr.namelist ; q ; q = q->nextp) {
        !           862:                v = (Namep)q->datap;
        !           863:                praddr(asmfile, STGINIT, v->nlmemno, 0L);
        !           864:                }
        !           865:        fprintf(asmfile, LABELFMT, memname(STGINIT, ++lastvarno));
        !           866:        s = ucvarstr(VL, np->varname, &len);
        !           867:        putstr(asmfile, s, len);
        !           868:        preven(ALILONG);
        !           869:        fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno));
        !           870:        praddr(asmfile, STGINIT, dimno+1, 0L);
        !           871:        praddr(asmfile, STGINIT, dimno, 0L);
        !           872:        prconi(asmfile, TYINT, n);
        !           873:        }
        !           874: 
        !           875: LOCAL docommon()
        !           876: {
        !           877:        register struct Extsym *p;
        !           878:        register chainp q;
        !           879:        struct Dimblock *t;
        !           880:        expptr neltp;
        !           881:        register Namep v;
        !           882:        ftnint size;
        !           883:        int type;
        !           884: 
        !           885:        for(p = extsymtab ; p<nextext ; ++p)
        !           886:                if (p->extstg == STGCOMMON && (q = p->extp))
        !           887:                {
        !           888: #ifdef SDB
        !           889:                        if(sdbflag)
        !           890:                                prstab(varstr(XL, p->extname), N_BCOMM, 0,
        !           891:                                    ftnname(STGCOMMON, p->extname));
        !           892: #endif
        !           893:                        for(; q ; q = q->nextp)
        !           894:                        {
        !           895:                                v = (Namep) (q->datap);
        !           896:                                if(v->vdcldone == NO)
        !           897:                                        vardcl(v);
        !           898:                                type = v->vtype;
        !           899:                                if(p->extleng % typealign[type] != 0)
        !           900:                                {
        !           901:                                        dclerr("common alignment", v);
        !           902:                                        p->extleng = roundup(p->extleng, typealign[type]);
        !           903:                                }
        !           904:                                v->voffset = p->extleng;
        !           905:                                v->vardesc.varno = p - extsymtab;
        !           906:                                if(type == TYCHAR)
        !           907:                                        size = v->vleng->constblock.Const.ci;
        !           908:                                else    size = typesize[type];
        !           909:                                if(t = v->vdim)
        !           910:                                        if( (neltp = t->nelt) && ISCONST(neltp) )
        !           911:                                                size *= neltp->constblock.Const.ci;
        !           912:                                        else
        !           913:                                                dclerr("adjustable array in common", v);
        !           914: #ifdef SDB
        !           915:                                if(sdbflag)
        !           916:                                        prcomssym(v, p);
        !           917: #endif
        !           918:                                p->extleng += size;
        !           919:                        }
        !           920:                        frchain( &(p->extp) );
        !           921: #ifdef SDB
        !           922:                        if(sdbflag)
        !           923:                                prstab(varstr(XL,p->extname), N_ECOMM, 0, ftnname(STGCOMMON, p->extname));
        !           924: #endif
        !           925:                }
        !           926: }
        !           927: 
        !           928: #ifdef SDB
        !           929: #define todata() if(first){p2pass(USEDATA);first=0;}
        !           930: 
        !           931: commstruct()   /* put common blocks into pi's GLOBAL menu */
        !           932: /* also emit complex and dcomplex struct defs if needed */
        !           933: {
        !           934:        register struct Extsym *p;
        !           935:        register struct Comvar *cv;
        !           936:        int first = 1;
        !           937:        char cstbuf[XL+10], lenbuf[16], *s;
        !           938: 
        !           939:        for(p = extsymtab ; p<nextext ; ++p)
        !           940:                if (p->extstg == STGCOMMON && (cv = p->cv))
        !           941:                {
        !           942:                        todata();
        !           943:                        s = varstr(XL, p->extname);
        !           944:                        strcpy(cstbuf, s);
        !           945:                        strcat(cstbuf, "COMMON_");
        !           946:                        prstab(s, N_GSYM, 8, CNULL);
        !           947:                        prstab(cstbuf, N_TYID, 0, CNULL);
        !           948:                        prstab(cstbuf, N_BSTR, 8, CNULL);
        !           949:                        do {
        !           950:                                sprintf(lenbuf, "%ld", cv->offset);
        !           951:                                prstab(cv->name, N_SSYM, cv->type, lenbuf);
        !           952:                                if (cv->tyid)
        !           953:                                        prstab(cv->tyid, N_TYID, 0, CNULL);
        !           954:                                if (cv->nelt)
        !           955:                                        p2pass(stabdline(N_DIM, cv->nelt));
        !           956:                        } while(cv = cv->next);
        !           957:                        sprintf(lenbuf, "%ld", p->maxleng);
        !           958:                        prstab(cstbuf, N_ESTR, 8, lenbuf);
        !           959:                }
        !           960:        if (complex_seen) {
        !           961:                todata();
        !           962:                prstab("complex", N_BSTR, 8, CNULL);
        !           963:                prstab("real", N_SSYM, 6, CNULL);
        !           964:                prstab("imag", N_SSYM, 6, "4");
        !           965:                prstab("complex", N_ESTR, 8, "8");
        !           966:        }
        !           967:        if (dcomplex_seen) {
        !           968:                todata();
        !           969:                prstab("dcomplex", N_BSTR, 8, CNULL);
        !           970:                prstab("real", N_SSYM, 7, CNULL);
        !           971:                prstab("imag", N_SSYM, 7, "8");
        !           972:                prstab("dcomplex", N_ESTR, 8, "16");
        !           973:        }
        !           974:        if (!first)
        !           975:                p2pass(USETEXT);
        !           976: }
        !           977: #endif
        !           978: 
        !           979: 
        !           980: 
        !           981: LOCAL docomleng()
        !           982: {
        !           983:        register struct Extsym *p;
        !           984: 
        !           985:        for(p = extsymtab ; p < nextext ; ++p)
        !           986:                if(p->extstg == STGCOMMON)
        !           987:                {
        !           988:                        if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
        !           989:                            && !eqn(XL,"_BLNK__ ",p->extname) )
        !           990:                                warn1("incompatible lengths for common block %s",
        !           991:                                    nounder(XL, p->extname) );
        !           992:                        if(p->maxleng < p->extleng)
        !           993:                                p->maxleng = p->extleng;
        !           994:                        p->extleng = 0;
        !           995:                }
        !           996: }
        !           997: 
        !           998: 
        !           999: 
        !          1000: 
        !          1001: /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
        !          1002: 
        !          1003: frtemp(p)
        !          1004: Addrp p;
        !          1005: {
        !          1006:        /* restore clobbered character string lengths */
        !          1007:        if(p->vtype==TYCHAR && p->varleng!=0)
        !          1008:        {
        !          1009:                frexpr(p->vleng);
        !          1010:                p->vleng = ICON(p->varleng);
        !          1011:        }
        !          1012: 
        !          1013:        /* put block on chain of temps to be reclaimed */
        !          1014:        holdtemps = mkchain(p, holdtemps);
        !          1015: }
        !          1016: 
        !          1017: 
        !          1018: 
        !          1019: 
        !          1020: /* allocate an automatic variable slot */
        !          1021: 
        !          1022: Addrp autovar(nelt, t, lengp)
        !          1023: register int nelt, t;
        !          1024: expptr lengp;
        !          1025: {
        !          1026:        ftnint leng;
        !          1027:        register Addrp q;
        !          1028: 
        !          1029:        if(t == TYCHAR)
        !          1030:                if( ISICON(lengp) )
        !          1031:                        leng = lengp->constblock.Const.ci;
        !          1032:                else    {
        !          1033:                        fatal("automatic variable of nonconstant length");
        !          1034:                }
        !          1035:        else
        !          1036:                leng = typesize[t];
        !          1037:        autoleng = roundup( autoleng, typealign[t]);
        !          1038: 
        !          1039:        q = ALLOC(Addrblock);
        !          1040:        q->tag = TADDR;
        !          1041:        q->vtype = t;
        !          1042:        if(t == TYCHAR)
        !          1043:        {
        !          1044:                q->vleng = ICON(leng);
        !          1045:                q->varleng = leng;
        !          1046:        }
        !          1047:        q->vstg = STGAUTO;
        !          1048:        q->ntempelt = nelt;
        !          1049: #if TARGET==PDP11 || TARGET==VAX
        !          1050:        /* stack grows downward */
        !          1051:        autoleng += nelt*leng;
        !          1052:        q->memoffset = ICON( - autoleng );
        !          1053: #else
        !          1054:        q->memoffset = ICON( autoleng );
        !          1055:        autoleng += nelt*leng;
        !          1056: #endif
        !          1057: 
        !          1058:        return(q);
        !          1059: }
        !          1060: 
        !          1061: 
        !          1062: Addrp mktmpn(nelt, type, lengp)
        !          1063: int nelt;
        !          1064: register int type;
        !          1065: expptr lengp;
        !          1066: {
        !          1067:        ftnint leng;
        !          1068:        chainp p, oldp;
        !          1069:        register Addrp q;
        !          1070: 
        !          1071:        if(type==TYUNKNOWN || type==TYERROR)
        !          1072:                badtype("mktmpn", type);
        !          1073: 
        !          1074:        if(type==TYCHAR)
        !          1075:                if( ISICON(lengp) )
        !          1076:                        leng = lengp->constblock.Const.ci;
        !          1077:                else    {
        !          1078:                        err("adjustable length");
        !          1079:                        return( (Addrp) errnode() );
        !          1080:                }
        !          1081:        /*
        !          1082:  * if an temporary of appropriate shape is on the templist,
        !          1083:  * remove it from the list and return it
        !          1084:  */
        !          1085: 
        !          1086:        for(oldp=CHNULL, p=templist  ;  p  ;  oldp=p, p=p->nextp)
        !          1087:        {
        !          1088:                q = (Addrp) (p->datap);
        !          1089:                if(q->vtype==type && q->ntempelt==nelt &&
        !          1090:                    (type!=TYCHAR || q->vleng->constblock.Const.ci==leng) )
        !          1091:                {
        !          1092:                        if(oldp)
        !          1093:                                oldp->nextp = p->nextp;
        !          1094:                        else
        !          1095:                                templist = p->nextp;
        !          1096:                        free( (charptr) p);
        !          1097:                        return(q);
        !          1098:                }
        !          1099:        }
        !          1100:        q = autovar(nelt, type, lengp);
        !          1101:        q->istemp = YES;
        !          1102:        return(q);
        !          1103: }
        !          1104: 
        !          1105: 
        !          1106: 
        !          1107: 
        !          1108: Addrp mktemp(type, lengp)
        !          1109: int type;
        !          1110: expptr lengp;
        !          1111: {
        !          1112:        return( mktmpn(1,type,lengp) );
        !          1113: }
        !          1114: 
        !          1115: /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
        !          1116: 
        !          1117: struct Extsym *comblock(len, s)
        !          1118: register int len;
        !          1119: register char *s;
        !          1120: {
        !          1121:        struct Extsym *p;
        !          1122: 
        !          1123:        if(len == 0)
        !          1124:        {
        !          1125:                s = BLANKCOMMON;
        !          1126:                len = strlen(s);
        !          1127:        }
        !          1128:        p = mkext( varunder(len, s) );
        !          1129:        if(p->extstg == STGUNKNOWN)
        !          1130:                p->extstg = STGCOMMON;
        !          1131:        else if(p->extstg != STGCOMMON)
        !          1132:        {
        !          1133:                errstr("%s cannot be a common block name", s);
        !          1134:                return(0);
        !          1135:        }
        !          1136: 
        !          1137:        return( p );
        !          1138: }
        !          1139: 
        !          1140: 
        !          1141: incomm(c, v)
        !          1142: struct Extsym *c;
        !          1143: Namep v;
        !          1144: {
        !          1145:        if(v->vstg != STGUNKNOWN)
        !          1146:                dclerr("incompatible common declaration", v);
        !          1147:        else
        !          1148:        {
        !          1149:                v->vstg = STGCOMMON;
        !          1150:                c->extp = hookup(c->extp, mkchain(v,CHNULL) );
        !          1151:        }
        !          1152: }
        !          1153: 
        !          1154: 
        !          1155: 
        !          1156: 
        !          1157: settype(v, type, length)
        !          1158: register Namep  v;
        !          1159: register int type;
        !          1160: register int length;
        !          1161: {
        !          1162:        if(type == TYUNKNOWN)
        !          1163:                return;
        !          1164: 
        !          1165:        if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
        !          1166:        {
        !          1167:                v->vtype = TYSUBR;
        !          1168:                frexpr(v->vleng);
        !          1169:                v->vleng = 0;
        !          1170:        }
        !          1171:        else if(type < 0)       /* storage class set */
        !          1172:        {
        !          1173:                if(v->vstg == STGUNKNOWN)
        !          1174:                        v->vstg = - type;
        !          1175:                else if(v->vstg != -type)
        !          1176:                        dclerr("incompatible storage declarations", v);
        !          1177:        }
        !          1178:        else if(v->vtype == TYUNKNOWN)
        !          1179:        {
        !          1180:                if( (v->vtype = lengtype(type, length))==TYCHAR && length>=0)
        !          1181:                        v->vleng = ICON(length);
        !          1182:        }
        !          1183:        else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.Const.ci!=length) )
        !          1184:                dclerr("incompatible type declarations", v);
        !          1185: }
        !          1186: 
        !          1187: 
        !          1188: 
        !          1189: 
        !          1190: 
        !          1191: lengtype(type, length)
        !          1192: register int type;
        !          1193: register int length;
        !          1194: {
        !          1195:        switch(type)
        !          1196:        {
        !          1197:        case TYREAL:
        !          1198:                if(length == 8)
        !          1199:                        return(TYDREAL);
        !          1200:                if(length == 4)
        !          1201:                        goto ret;
        !          1202:                break;
        !          1203: 
        !          1204:        case TYCOMPLEX:
        !          1205:                if(length == 16)
        !          1206:                        return(TYDCOMPLEX);
        !          1207:                if(length == 8)
        !          1208:                        goto ret;
        !          1209:                break;
        !          1210: 
        !          1211:        case TYSHORT:
        !          1212:        case TYDREAL:
        !          1213:        case TYDCOMPLEX:
        !          1214:        case TYCHAR:
        !          1215:        case TYUNKNOWN:
        !          1216:        case TYSUBR:
        !          1217:        case TYERROR:
        !          1218:                goto ret;
        !          1219: 
        !          1220:        case TYLOGICAL:
        !          1221:                if(length == typesize[TYLOGICAL])
        !          1222:                        goto ret;
        !          1223:                break;
        !          1224: 
        !          1225:        case TYLONG:
        !          1226:                if(length == 0)
        !          1227:                        return(tyint);
        !          1228:                if(length == 2)
        !          1229:                        return(TYSHORT);
        !          1230:                if(length == 4)
        !          1231:                        goto ret;
        !          1232:                break;
        !          1233:        default:
        !          1234:                badtype("lengtype", type);
        !          1235:        }
        !          1236: 
        !          1237:        if(length != 0)
        !          1238:                err("incompatible type-length combination");
        !          1239: 
        !          1240: ret:
        !          1241:        return(type);
        !          1242: }
        !          1243: 
        !          1244: 
        !          1245: 
        !          1246: 
        !          1247: 
        !          1248: setintr(v)
        !          1249: register Namep  v;
        !          1250: {
        !          1251:        register int k;
        !          1252: 
        !          1253:        if(v->vstg == STGUNKNOWN)
        !          1254:                v->vstg = STGINTR;
        !          1255:        else if(v->vstg!=STGINTR)
        !          1256:                dclerr("incompatible use of intrinsic function", v);
        !          1257:        if(v->vclass==CLUNKNOWN)
        !          1258:                v->vclass = CLPROC;
        !          1259:        if(v->vprocclass == PUNKNOWN)
        !          1260:                v->vprocclass = PINTRINSIC;
        !          1261:        else if(v->vprocclass != PINTRINSIC)
        !          1262:                dclerr("invalid intrinsic declaration", v);
        !          1263:        if(k = intrfunct(v->varname))
        !          1264:                v->vardesc.varno = k;
        !          1265:        else
        !          1266:                dclerr("unknown intrinsic function", v);
        !          1267: }
        !          1268: 
        !          1269: 
        !          1270: 
        !          1271: setext(v)
        !          1272: register Namep  v;
        !          1273: {
        !          1274:        if(v->vclass == CLUNKNOWN)
        !          1275:                v->vclass = CLPROC;
        !          1276:        else if(v->vclass != CLPROC)
        !          1277:                dclerr("invalid external declaration", v);
        !          1278: 
        !          1279:        if(v->vprocclass == PUNKNOWN)
        !          1280:                v->vprocclass = PEXTERNAL;
        !          1281:        else if(v->vprocclass != PEXTERNAL)
        !          1282:                dclerr("invalid external declaration", v);
        !          1283: }
        !          1284: 
        !          1285: 
        !          1286: 
        !          1287: 
        !          1288: /* create dimensions block for array variable */
        !          1289: 
        !          1290: setbound(v, nd, dims)
        !          1291: register Namep  v;
        !          1292: int nd;
        !          1293: struct { 
        !          1294:        expptr lb, ub; 
        !          1295: } dims[ ];
        !          1296: {
        !          1297:        register expptr q, t;
        !          1298:        register struct Dimblock *p;
        !          1299:        int i;
        !          1300: 
        !          1301:        if(v->vclass == CLUNKNOWN)
        !          1302:                v->vclass = CLVAR;
        !          1303:        else if(v->vclass != CLVAR)
        !          1304:        {
        !          1305:                dclerr("only variables may be arrays", v);
        !          1306:                return;
        !          1307:        }
        !          1308: 
        !          1309:        v->vdim = p = (struct Dimblock *)
        !          1310:            ckalloc( sizeof(int) + (3+2*nd)*sizeof(expptr) );
        !          1311:        p->ndim = nd;
        !          1312:        p->nelt = ICON(1);
        !          1313: 
        !          1314:        for(i=0 ; i<nd ; ++i)
        !          1315:        {
        !          1316:                if( (q = dims[i].ub) == NULL)
        !          1317:                {
        !          1318:                        if(i == nd-1)
        !          1319:                        {
        !          1320:                                frexpr(p->nelt);
        !          1321:                                p->nelt = NULL;
        !          1322:                        }
        !          1323:                        else
        !          1324:                                err("only last bound may be asterisk");
        !          1325:                        p->dims[i].dimsize = ICON(1);
        !          1326:                        ;
        !          1327:                        p->dims[i].dimexpr = NULL;
        !          1328:                }
        !          1329:                else
        !          1330:                {
        !          1331:                        if(dims[i].lb)
        !          1332:                        {
        !          1333:                                q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
        !          1334:                                q = mkexpr(OPPLUS, q, ICON(1) );
        !          1335:                        }
        !          1336:                        if( ISCONST(q) )
        !          1337:                        {
        !          1338:                                p->dims[i].dimsize = q;
        !          1339:                                p->dims[i].dimexpr = (expptr) PNULL;
        !          1340:                        }
        !          1341:                        else    {
        !          1342:                                p->dims[i].dimsize = (expptr) autovar(1, tyint, EXNULL);
        !          1343:                                p->dims[i].dimexpr = q;
        !          1344:                        }
        !          1345:                        if(p->nelt)
        !          1346:                                p->nelt = mkexpr(OPSTAR, p->nelt,
        !          1347:                                    cpexpr(p->dims[i].dimsize) );
        !          1348:                }
        !          1349:        }
        !          1350: 
        !          1351:        q = dims[nd-1].lb;
        !          1352:        if(q == NULL)
        !          1353:                q = ICON(1);
        !          1354: 
        !          1355:        for(i = nd-2 ; i>=0 ; --i)
        !          1356:        {
        !          1357:                t = dims[i].lb;
        !          1358:                if(t == NULL)
        !          1359:                        t = ICON(1);
        !          1360:                if(p->dims[i].dimsize)
        !          1361:                        q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
        !          1362:        }
        !          1363: 
        !          1364:        if( ISCONST(q) )
        !          1365:        {
        !          1366:                p->baseoffset = q;
        !          1367:                p->basexpr = NULL;
        !          1368:        }
        !          1369:        else
        !          1370:        {
        !          1371:                p->baseoffset = (expptr) autovar(1, tyint, EXNULL);
        !          1372:                p->basexpr = q;
        !          1373:        }
        !          1374: }

unix.superglobalmegacorp.com

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