Annotation of 3BSD/cmd/f77/proc.c, revision 1.1.1.1

1.1       root        1: #include "defs"
                      2: 
                      3: #ifdef SDB
                      4: #      include <a.out.h>
                      5: char *stabline();
                      6: #endif
                      7: 
                      8: /* start a new procedure */
                      9: 
                     10: newproc()
                     11: {
                     12: if(parstate != OUTSIDE)
                     13:        {
                     14:        execerr("missing end statement", 0);
                     15:        endproc();
                     16:        }
                     17: 
                     18: parstate = INSIDE;
                     19: procclass = CLMAIN;    /* default */
                     20: }
                     21: 
                     22: 
                     23: 
                     24: /* end of procedure. generate variables, epilogs, and prologs */
                     25: 
                     26: endproc()
                     27: {
                     28: struct Labelblock *lp;
                     29: 
                     30: if(parstate < INDATA)
                     31:        enddcl();
                     32: if(ctlstack >= ctls)
                     33:        err("DO loop or BLOCK IF not closed");
                     34: for(lp = labeltab ; lp < labtabend ; ++lp)
                     35:        if(lp->stateno!=0 && lp->labdefined==NO)
                     36:                errstr("missing statement number %s", convic(lp->stateno) );
                     37: 
                     38: epicode();
                     39: procode();
                     40: dobss();
                     41: prdbginfo();
                     42: 
                     43: #if FAMILY == PCC
                     44:        putbracket();
                     45: #endif
                     46: 
                     47: procinit();    /* clean up for next procedure */
                     48: }
                     49: 
                     50: 
                     51: 
                     52: /* End of declaration section of procedure.  Allocate storage. */
                     53: 
                     54: enddcl()
                     55: {
                     56: register struct Entrypoint *p;
                     57: 
                     58: parstate = INEXEC;
                     59: docommon();
                     60: doequiv();
                     61: docomleng();
                     62: for(p = entries ; p ; p = p->nextp)
                     63:        doentry(p);
                     64: }
                     65: 
                     66: /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
                     67: 
                     68: /* Main program or Block data */
                     69: 
                     70: startproc(progname, class)
                     71: struct Extsym * progname;
                     72: int class;
                     73: {
                     74: register struct Entrypoint *p;
                     75: char buff[10];
                     76: 
                     77: p = ALLOC(Entrypoint);
                     78: if(class == CLMAIN)
                     79:        puthead("MAIN__", CLMAIN);
                     80: else
                     81:        puthead(NULL, CLBLOCK);
                     82: if(class == CLMAIN)
                     83:        newentry( mkname(5, "MAIN_") );
                     84: p->entryname = progname;
                     85: p->entrylabel = newlabel();
                     86: entries = p;
                     87: 
                     88: procclass = class;
                     89: retlabel = newlabel();
                     90: fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
                     91: if(progname)
                     92:        fprintf(diagfile, " %s", nounder(XL, procname = progname->extname) );
                     93: fprintf(diagfile, ":\n");
                     94: #ifdef SDB
                     95: if(sdbflag && class==CLMAIN)
                     96:        {
                     97:        sprintf(buff, "L%d", p->entrylabel);
                     98:        prstab("MAIN_", N_FUN, lineno, buff);
                     99:        p2pass( stabline("MAIN_", N_FNAME, 0, 0) );
                    100:        if(progname)
                    101:                {
                    102:                prstab(nounder(XL,progname->extname), N_ENTRY, lineno,buff);
                    103: /*             p2pass(stabline(nounder(XL,progname->extname),N_FNAME,0,0));    */
                    104:                }
                    105:        }
                    106: #endif
                    107: }
                    108: 
                    109: /* subroutine or function statement */
                    110: 
                    111: struct Extsym *newentry(v)
                    112: register struct Nameblock *v;
                    113: {
                    114: register struct Extsym *p;
                    115: 
                    116: p = mkext( varunder(VL, v->varname) );
                    117: 
                    118: if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
                    119:        {
                    120:        if(p == 0)
                    121:                dclerr("invalid entry name", v);
                    122:        else    dclerr("external name already used", v);
                    123:        return(0);
                    124:        }
                    125: v->vstg = STGAUTO;
                    126: v->vprocclass = PTHISPROC;
                    127: v->vclass = CLPROC;
                    128: p->extstg = STGEXT;
                    129: p->extinit = YES;
                    130: return(p);
                    131: }
                    132: 
                    133: 
                    134: entrypt(class, type, length, entry, args)
                    135: int class, type;
                    136: ftnint length;
                    137: struct Extsym *entry;
                    138: chainp args;
                    139: {
                    140: register struct Nameblock *q;
                    141: register struct Entrypoint *p;
                    142: char buff[10];
                    143: 
                    144: if(class != CLENTRY)
                    145:        puthead( varstr(XL, procname = entry->extname), class);
                    146: if(class == CLENTRY)
                    147:        fprintf(diagfile, "       entry ");
                    148: fprintf(diagfile, "   %s:\n", nounder(XL, entry->extname));
                    149: q = mkname(VL, nounder(XL,entry->extname) );
                    150: 
                    151: if( (type = lengtype(type, (int) length)) != TYCHAR)
                    152:        length = 0;
                    153: if(class == CLPROC)
                    154:        {
                    155:        procclass = CLPROC;
                    156:        proctype = type;
                    157:        procleng = length;
                    158: 
                    159:        retlabel = newlabel();
                    160:        if(type == TYSUBR)
                    161:                ret0label = newlabel();
                    162:        }
                    163: 
                    164: p = ALLOC(Entrypoint);
                    165: entries = hookup(entries, p);
                    166: p->entryname = entry;
                    167: p->arglist = args;
                    168: p->entrylabel = newlabel();
                    169: p->enamep = q;
                    170: 
                    171: #ifdef SDB
                    172: if(sdbflag)
                    173:        {
                    174:        sprintf(buff, "L%d", p->entrylabel);
                    175:        prstab(nounder(XL, entry->extname),
                    176:                (class==CLENTRY ? N_ENTRY : N_FUN),
                    177:                lineno, buff);
                    178:        if(class != CLENTRY)
                    179:        p2pass( stabline( nounder(XL,entry->extname), N_FNAME, 0, 0) );
                    180:        }
                    181: #endif
                    182: 
                    183: if(class == CLENTRY)
                    184:        {
                    185:        class = CLPROC;
                    186:        if(proctype == TYSUBR)
                    187:                type = TYSUBR;
                    188:        }
                    189: 
                    190: q->vclass = class;
                    191: q->vprocclass = PTHISPROC;
                    192: settype(q, type, (int) length);
                    193: /* hold all initial entry points till end of declarations */
                    194: if(parstate >= INDATA)
                    195:        doentry(p);
                    196: }
                    197: 
                    198: /* generate epilogs */
                    199: 
                    200: LOCAL epicode()
                    201: {
                    202: register int i;
                    203: 
                    204: if(procclass==CLPROC)
                    205:        {
                    206:        if(proctype==TYSUBR)
                    207:                {
                    208:                putlabel(ret0label);
                    209:                if(substars)
                    210:                        putforce(TYINT, ICON(0) );
                    211:                putlabel(retlabel);
                    212:                goret(TYSUBR);
                    213:                }
                    214:        else    {
                    215:                putlabel(retlabel);
                    216:                if(multitypes)
                    217:                        {
                    218:                        typeaddr = autovar(1, TYADDR, NULL);
                    219:                        putbranch( cpexpr(typeaddr) );
                    220:                        for(i = 0; i < NTYPES ; ++i)
                    221:                                if(rtvlabel[i] != 0)
                    222:                                        {
                    223:                                        putlabel(rtvlabel[i]);
                    224:                                        retval(i);
                    225:                                        }
                    226:                        }
                    227:                else
                    228:                        retval(proctype);
                    229:                }
                    230:        }
                    231: 
                    232: else if(procclass != CLBLOCK)
                    233:        {
                    234:        putlabel(retlabel);
                    235:        goret(TYSUBR);
                    236:        }
                    237: }
                    238: 
                    239: 
                    240: /* generate code to return value of type  t */
                    241: 
                    242: LOCAL retval(t)
                    243: register int t;
                    244: {
                    245: register struct Addrblock *p;
                    246: 
                    247: switch(t)
                    248:        {
                    249:        case TYCHAR:
                    250:        case TYCOMPLEX:
                    251:        case TYDCOMPLEX:
                    252:                break;
                    253: 
                    254:        case TYLOGICAL:
                    255:                t = tylogical;
                    256:        case TYADDR:
                    257:        case TYSHORT:
                    258:        case TYLONG:
                    259:                p = cpexpr(retslot);
                    260:                p->vtype = t;
                    261:                putforce(t, p);
                    262:                break;
                    263: 
                    264:        case TYREAL:
                    265:        case TYDREAL:
                    266:                p = cpexpr(retslot);
                    267:                p->vtype = t;
                    268:                putforce(t, p);
                    269:                break;
                    270: 
                    271:        default:
                    272:                fatali("retval: impossible type %d", t);
                    273:        }
                    274: goret(t);
                    275: }
                    276: 
                    277: 
                    278: /* Allocate extra argument array if needed. Generate prologs. */
                    279: 
                    280: LOCAL procode()
                    281: {
                    282: register struct Entrypoint *p;
                    283: struct Addrblock *argvec;
                    284: 
                    285: #if TARGET==GCOS
                    286:        argvec = autovar(lastargslot/SZADDR, TYADDR, NULL);
                    287: #else
                    288:        if(lastargslot>0 && nentry>1)
                    289: #if TARGET == VAX
                    290:                argvec = autovar(1 + lastargslot/SZADDR, TYADDR, NULL);
                    291: #else
                    292:                argvec = autovar(lastargslot/SZADDR, TYADDR, NULL);
                    293: #endif
                    294:        else
                    295:                argvec = NULL;
                    296: #endif
                    297: 
                    298: 
                    299: #if TARGET == PDP11
                    300:        /* for the optimizer */
                    301:        if(fudgelabel)
                    302:                putlabel(fudgelabel);
                    303: #endif
                    304: 
                    305: for(p = entries ; p ; p = p->nextp)
                    306:        prolog(p, argvec);
                    307: 
                    308: #if FAMILY == PCC
                    309:        putrbrack(procno);
                    310: #endif
                    311: 
                    312: prendproc();
                    313: }
                    314: 
                    315: /*
                    316:    manipulate argument lists (allocate argument slot positions)
                    317:  * keep track of return types and labels
                    318:  */
                    319: 
                    320: LOCAL doentry(ep)
                    321: struct Entrypoint *ep;
                    322: {
                    323: register int type;
                    324: register struct Nameblock *np;
                    325: chainp p;
                    326: register struct Nameblock *q;
                    327: 
                    328: ++nentry;
                    329: if(procclass == CLMAIN)
                    330:        {
                    331:        putlabel(ep->entrylabel);
                    332:        return;
                    333:        }
                    334: else if(procclass == CLBLOCK)
                    335:        return;
                    336: 
                    337: impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
                    338: type = np->vtype;
                    339: if(proctype == TYUNKNOWN)
                    340:        if( (proctype = type) == TYCHAR)
                    341:                procleng = (np->vleng ? np->vleng->constblock.const.ci : (ftnint) 0);
                    342: 
                    343: if(proctype == TYCHAR)
                    344:        {
                    345:        if(type != TYCHAR)
                    346:                err("noncharacter entry of character function");
                    347:        else if( (np->vleng ? np->vleng->constblock.const.ci : (ftnint) 0) != procleng)
                    348:                err("mismatched character entry lengths");
                    349:        }
                    350: else if(type == TYCHAR)
                    351:        err("character entry of noncharacter function");
                    352: else if(type != proctype)
                    353:        multitype = YES;
                    354: if(rtvlabel[type] == 0)
                    355:        rtvlabel[type] = newlabel();
                    356: ep->typelabel = rtvlabel[type];
                    357: 
                    358: if(type == TYCHAR)
                    359:        {
                    360:        if(chslot < 0)
                    361:                {
                    362:                chslot = nextarg(TYADDR);
                    363:                chlgslot = nextarg(TYLENG);
                    364:                }
                    365:        np->vstg = STGARG;
                    366:        np->vardesc.varno = chslot;
                    367:        if(procleng == 0)
                    368:                np->vleng = mkarg(TYLENG, chlgslot);
                    369:        }
                    370: else if( ISCOMPLEX(type) )
                    371:        {
                    372:        np->vstg = STGARG;
                    373:        if(cxslot < 0)
                    374:                cxslot = nextarg(TYADDR);
                    375:        np->vardesc.varno = cxslot;
                    376:        }
                    377: else if(type != TYSUBR)
                    378:        {
                    379:        if(nentry == 1)
                    380:                retslot = autovar(1, TYDREAL, NULL);
                    381:        np->vstg = STGAUTO;
                    382:        np->voffset = retslot->memoffset->constblock.const.ci;
                    383:        }
                    384: 
                    385: for(p = ep->arglist ; p ; p = p->nextp)
                    386:        if(! ((q = p->datap)->vdcldone) )
                    387:                q->vardesc.varno = nextarg(TYADDR);
                    388: 
                    389: for(p = ep->arglist ; p ; p = p->nextp)
                    390:        if(! ((q = p->datap)->vdcldone) )
                    391:                {
                    392:                impldcl(q);
                    393:                q->vdcldone = YES;
                    394: #ifdef SDB
                    395:                if(sdbflag)
                    396:                        prstab(varstr(VL,q->varname), N_PSYM,
                    397:                                stabtype(q),
                    398:                                convic(q->vardesc.varno + ARGOFFSET) );
                    399: #endif
                    400:                if(q->vtype == TYCHAR)
                    401:                        {
                    402:                        if(q->vleng == NULL)    /* character*(*) */
                    403:                                q->vleng = mkarg(TYLENG, nextarg(TYLENG) );
                    404:                        else if(nentry == 1)
                    405:                                nextarg(TYLENG);
                    406:                        }
                    407:                else if(q->vclass==CLPROC && nentry==1)
                    408:                        nextarg(TYLENG) ;
                    409:                }
                    410: 
                    411: putlabel(ep->entrylabel);
                    412: }
                    413: 
                    414: 
                    415: 
                    416: LOCAL nextarg(type)
                    417: int type;
                    418: {
                    419: int k;
                    420: k = lastargslot;
                    421: lastargslot += typesize[type];
                    422: return(k);
                    423: }
                    424: 
                    425: /* generate variable references */
                    426: 
                    427: LOCAL dobss()
                    428: {
                    429: register struct Hashentry *p;
                    430: register struct Nameblock *q;
                    431: register int i;
                    432: int align;
                    433: ftnint leng, iarrl;
                    434: char *memname();
                    435: int qstg, qclass, qtype;
                    436: 
                    437: pruse(asmfile, USEBSS);
                    438: 
                    439: for(p = hashtab ; p<lasthash ; ++p)
                    440:     if(q = p->varp)
                    441:        {
                    442:        qstg = q->vstg;
                    443:        qtype = q->vtype;
                    444:        qclass = q->vclass;
                    445: 
                    446: #ifdef SDB
                    447:                if(sdbflag&&qclass==CLVAR&&(qstg==STGBSS||qstg==STGINIT))
                    448:                        {
                    449:                        prstab(varstr(VL,q->varname), N_LCSYM,
                    450:                                stabtype(q), memname(qstg,q->vardesc.varno) );
                    451:                        prstleng(q, iarrlen(q));
                    452:                        }
                    453: #endif
                    454: 
                    455:        if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
                    456:            (qclass==CLVAR && qstg==STGUNKNOWN) )
                    457:                warn1("local variable %s never used", varstr(VL,q->varname) );
                    458:        else if(qclass==CLVAR && qstg==STGBSS)
                    459:                {
                    460:                align = (qtype==TYCHAR ? ALILONG : typealign[qtype]);
                    461:                if(bssleng % align != 0)
                    462:                        {
                    463:                        bssleng = roundup(bssleng, align);
                    464:                        preven(align);
                    465:                        }
                    466:                prlocvar(memname(STGBSS,q->vardesc.varno), iarrl = iarrlen(q) );
                    467:                bssleng += iarrl;
                    468:                }
                    469:        else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG)
                    470:                mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
                    471: 
                    472:        if(qclass==CLVAR && qstg!=STGARG)
                    473:                {
                    474:                if(q->vdim && !ISICON(q->vdim->nelt) )
                    475:                        dclerr("adjustable dimension on non-argument", q);
                    476:                if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
                    477:                        dclerr("adjustable leng on nonargument", q);
                    478:                }
                    479:        }
                    480: 
                    481: for(i = 0 ; i < nequiv ; ++i)
                    482:        if(eqvclass[i].eqvinit==NO && (leng = eqvclass[i].eqvleng)!=0 )
                    483:                {
                    484:                bssleng = roundup(bssleng, ALIDOUBLE);
                    485:                preven(ALIDOUBLE);
                    486:                prlocvar( memname(STGEQUIV, i), leng);
                    487:                bssleng += leng;
                    488:                }
                    489: }
                    490: 
                    491: 
                    492: 
                    493: 
                    494: doext()
                    495: {
                    496: struct Extsym *p;
                    497: 
                    498: for(p = extsymtab ; p<nextext ; ++p)
                    499:        prext( varstr(XL, p->extname), p->maxleng, p->extinit);
                    500: }
                    501: 
                    502: 
                    503: 
                    504: 
                    505: ftnint iarrlen(q)
                    506: register struct Nameblock *q;
                    507: {
                    508: ftnint leng;
                    509: 
                    510: leng = typesize[q->vtype];
                    511: if(leng <= 0)
                    512:        return(-1);
                    513: if(q->vdim)
                    514:        if( ISICON(q->vdim->nelt) )
                    515:                leng *= q->vdim->nelt->constblock.const.ci;
                    516:        else    return(-1);
                    517: if(q->vleng)
                    518:        if( ISICON(q->vleng) )
                    519:                leng *= q->vleng->constblock.const.ci;
                    520:        else    return(-1);
                    521: return(leng);
                    522: }
                    523: 
                    524: LOCAL docommon()
                    525: {
                    526: register struct Extsym *p;
                    527: register chainp q;
                    528: struct Dimblock *t;
                    529: expptr neltp;
                    530: register struct Nameblock *v;
                    531: ftnint size;
                    532: int type;
                    533: 
                    534: for(p = extsymtab ; p<nextext ; ++p)
                    535:        if(p->extstg==STGCOMMON)
                    536:                {
                    537: #ifdef SDB
                    538:                if(sdbflag)
                    539:                        prstab(NULL, N_BCOMM, 0, 0);
                    540: #endif
                    541:                for(q = p->extp ; q ; q = q->nextp)
                    542:                        {
                    543:                        v = q->datap;
                    544:                        if(v->vdcldone == NO)
                    545:                                vardcl(v);
                    546:                        type = v->vtype;
                    547:                        if(p->extleng % typealign[type] != 0)
                    548:                                {
                    549:                                dclerr("common alignment", v);
                    550:                                p->extleng = roundup(p->extleng, typealign[type]);
                    551:                                }
                    552:                        v->voffset = p->extleng;
                    553:                        v->vardesc.varno = p - extsymtab;
                    554:                        if(type == TYCHAR)
                    555:                                size = v->vleng->constblock.const.ci;
                    556:                        else    size = typesize[type];
                    557:                        if(t = v->vdim)
                    558:                                if( (neltp = t->nelt) && ISCONST(neltp) )
                    559:                                        size *= neltp->constblock.const.ci;
                    560:                                else
                    561:                                        dclerr("adjustable array in common", v);
                    562:                        p->extleng += size;
                    563: #ifdef SDB
                    564:                        if(sdbflag)
                    565:                                {
                    566:                                prstssym(v);
                    567:                                prstleng(v, size);
                    568:                                }
                    569: #endif
                    570:                        }
                    571: 
                    572:                frchain( &(p->extp) );
                    573: #ifdef SDB
                    574:                if(sdbflag)
                    575:                        prstab(varstr(XL,p->extname), N_ECOMM, 0, 0);
                    576: #endif
                    577:                }
                    578: }
                    579: 
                    580: 
                    581: 
                    582: 
                    583: 
                    584: LOCAL docomleng()
                    585: {
                    586: register struct Extsym *p;
                    587: 
                    588: for(p = extsymtab ; p < nextext ; ++p)
                    589:        if(p->extstg == STGCOMMON)
                    590:                {
                    591:                if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
                    592:                    && !eqn(XL,"_BLNK__ ",p->extname) )
                    593:                        warn1("incompatible lengths for common block %s",
                    594:                                nounder(XL, p->extname) );
                    595:                if(p->maxleng < p->extleng)
                    596:                        p->maxleng = p->extleng;
                    597:                p->extleng = 0;
                    598:        }
                    599: }
                    600: 
                    601: 
                    602: 
                    603: 
                    604: /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
                    605: 
                    606: frtemp(p)
                    607: struct Addrblock *p;
                    608: {
                    609: holdtemps = mkchain(p, holdtemps);
                    610: }
                    611: 
                    612: 
                    613: 
                    614: 
                    615: /* allocate an automatic variable slot */
                    616: 
                    617: struct Addrblock *autovar(nelt, t, lengp)
                    618: register int nelt, t;
                    619: expptr lengp;
                    620: {
                    621: ftnint leng;
                    622: register struct Addrblock *q;
                    623: 
                    624: if(t == TYCHAR)
                    625:        if( ISICON(lengp) )
                    626:                leng = lengp->constblock.const.ci;
                    627:        else    {
                    628:                fatal("automatic variable of nonconstant length");
                    629:                }
                    630: else
                    631:        leng = typesize[t];
                    632: autoleng = roundup( autoleng, typealign[t]);
                    633: 
                    634: q = ALLOC(Addrblock);
                    635: q->tag = TADDR;
                    636: q->vtype = t;
                    637: if(t == TYCHAR)
                    638:        q->vleng = ICON(leng);
                    639: q->vstg = STGAUTO;
                    640: q->ntempelt = nelt;
                    641: #if TARGET==PDP11 || TARGET==VAX
                    642:        /* stack grows downward */
                    643:        autoleng += nelt*leng;
                    644:        q->memoffset = ICON( - autoleng );
                    645: #else
                    646:        q->memoffset = ICON( autoleng );
                    647:        autoleng += nelt*leng;
                    648: #endif
                    649: 
                    650: return(q);
                    651: }
                    652: 
                    653: 
                    654: struct Addrblock *mktmpn(nelt, type, lengp)
                    655: int nelt;
                    656: register int type;
                    657: expptr lengp;
                    658: {
                    659: ftnint leng;
                    660: chainp p, oldp;
                    661: register struct Addrblock *q;
                    662: 
                    663: if(type==TYUNKNOWN || type==TYERROR)
                    664:        fatali("mktmpn: invalid type %d", type);
                    665: 
                    666: if(type==TYCHAR)
                    667:        if( ISICON(lengp) )
                    668:                leng = lengp->constblock.const.ci;
                    669:        else    {
                    670:                err("adjustable length");
                    671:                return( errnode() );
                    672:                }
                    673: for(oldp = &templist ; p = oldp->nextp ; oldp = p)
                    674:        {
                    675:        q = p->datap;
                    676:        if(q->vtype==type && q->ntempelt==nelt &&
                    677:            (type!=TYCHAR || q->vleng->constblock.const.ci==leng) )
                    678:                {
                    679:                oldp->nextp = p->nextp;
                    680:                free(p);
                    681:                return(q);
                    682:                }
                    683:        }
                    684: q = autovar(nelt, type, lengp);
                    685: q->istemp = YES;
                    686: return(q);
                    687: }
                    688: 
                    689: 
                    690: 
                    691: 
                    692: struct Addrblock *mktemp(type, lengp)
                    693: int type;
                    694: expptr lengp;
                    695: {
                    696: return( mktmpn(1,type,lengp) );
                    697: }
                    698: 
                    699: /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
                    700: 
                    701: struct Extsym *comblock(len, s)
                    702: register int len;
                    703: register char *s;
                    704: {
                    705: struct Extsym *p;
                    706: 
                    707: if(len == 0)
                    708:        {
                    709:        s = BLANKCOMMON;
                    710:        len = strlen(s);
                    711:        }
                    712: p = mkext( varunder(len, s) );
                    713: if(p->extstg == STGUNKNOWN)
                    714:        p->extstg = STGCOMMON;
                    715: else if(p->extstg != STGCOMMON)
                    716:        {
                    717:        errstr("%s cannot be a common block name", s);
                    718:        return(0);
                    719:        }
                    720: 
                    721: return( p );
                    722: }
                    723: 
                    724: 
                    725: incomm(c, v)
                    726: struct Extsym *c;
                    727: struct Nameblock *v;
                    728: {
                    729: if(v->vstg != STGUNKNOWN)
                    730:        dclerr("incompatible common declaration", v);
                    731: else
                    732:        {
                    733:        v->vstg = STGCOMMON;
                    734:        c->extp = hookup(c->extp, mkchain(v,NULL) );
                    735:        }
                    736: }
                    737: 
                    738: 
                    739: 
                    740: 
                    741: settype(v, type, length)
                    742: register struct Nameblock * v;
                    743: register int type;
                    744: register int length;
                    745: {
                    746: if(type == TYUNKNOWN)
                    747:        return;
                    748: 
                    749: if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
                    750:        {
                    751:        v->vtype = TYSUBR;
                    752:        frexpr(v->vleng);
                    753:        }
                    754: else if(type < 0)      /* storage class set */
                    755:        {
                    756:        if(v->vstg == STGUNKNOWN)
                    757:                v->vstg = - type;
                    758:        else if(v->vstg != -type)
                    759:                dclerr("incompatible storage declarations", v);
                    760:        }
                    761: else if(v->vtype == TYUNKNOWN)
                    762:        {
                    763:        if( (v->vtype = lengtype(type, length))==TYCHAR && length!=0)
                    764:                v->vleng = ICON(length);
                    765:        }
                    766: else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.const.ci!=length) )
                    767:        dclerr("incompatible type declarations", v);
                    768: }
                    769: 
                    770: 
                    771: 
                    772: 
                    773: 
                    774: lengtype(type, length)
                    775: register int type;
                    776: register int length;
                    777: {
                    778: switch(type)
                    779:        {
                    780:        case TYREAL:
                    781:                if(length == 8)
                    782:                        return(TYDREAL);
                    783:                if(length == 4)
                    784:                        goto ret;
                    785:                break;
                    786: 
                    787:        case TYCOMPLEX:
                    788:                if(length == 16)
                    789:                        return(TYDCOMPLEX);
                    790:                if(length == 8)
                    791:                        goto ret;
                    792:                break;
                    793: 
                    794:        case TYSHORT:
                    795:        case TYDREAL:
                    796:        case TYDCOMPLEX:
                    797:        case TYCHAR:
                    798:        case TYUNKNOWN:
                    799:        case TYSUBR:
                    800:        case TYERROR:
                    801:                goto ret;
                    802: 
                    803:        case TYLOGICAL:
                    804:                if(length == typesize[TYLOGICAL])
                    805:                        goto ret;
                    806:                break;
                    807: 
                    808:        case TYLONG:
                    809:                if(length == 0)
                    810:                        return(tyint);
                    811:                if(length == 2)
                    812:                        return(TYSHORT);
                    813:                if(length == 4)
                    814:                        goto ret;
                    815:                break;
                    816:        default:
                    817:                fatali("lengtype: invalid type %d", type);
                    818:        }
                    819: 
                    820: if(length != 0)
                    821:        err("incompatible type-length combination");
                    822: 
                    823: ret:
                    824:        return(type);
                    825: }
                    826: 
                    827: 
                    828: 
                    829: 
                    830: 
                    831: setintr(v)
                    832: register struct Nameblock * v;
                    833: {
                    834: register int k;
                    835: 
                    836: if(v->vstg == STGUNKNOWN)
                    837:        v->vstg = STGINTR;
                    838: else if(v->vstg!=STGINTR)
                    839:        dclerr("incompatible use of intrinsic function", v);
                    840: if(v->vclass==CLUNKNOWN)
                    841:        v->vclass = CLPROC;
                    842: if(v->vprocclass == PUNKNOWN)
                    843:        v->vprocclass = PINTRINSIC;
                    844: else if(v->vprocclass != PINTRINSIC)
                    845:        dclerr("invalid intrinsic declaration", v);
                    846: if(k = intrfunct(v->varname))
                    847:        v->vardesc.varno = k;
                    848: else
                    849:        dclerr("unknown intrinsic function", v);
                    850: }
                    851: 
                    852: 
                    853: 
                    854: setext(v)
                    855: register struct Nameblock * v;
                    856: {
                    857: if(v->vclass == CLUNKNOWN)
                    858:        v->vclass = CLPROC;
                    859: else if(v->vclass != CLPROC)
                    860:        dclerr("invalid external declaration", v);
                    861: 
                    862: if(v->vprocclass == PUNKNOWN)
                    863:        v->vprocclass = PEXTERNAL;
                    864: else if(v->vprocclass != PEXTERNAL)
                    865:        dclerr("invalid external declaration", v);
                    866: }
                    867: 
                    868: 
                    869: 
                    870: 
                    871: /* create dimensions block for array variable */
                    872: 
                    873: setbound(v, nd, dims)
                    874: register struct Nameblock * v;
                    875: int nd;
                    876: struct { expptr lb, ub; } dims[ ];
                    877: {
                    878: register expptr q, t;
                    879: register struct Dimblock *p;
                    880: int i;
                    881: 
                    882: if(v->vclass == CLUNKNOWN)
                    883:        v->vclass = CLVAR;
                    884: else if(v->vclass != CLVAR)
                    885:        {
                    886:        dclerr("only variables may be arrays", v);
                    887:        return;
                    888:        }
                    889: 
                    890: v->vdim = p = (struct Dimblock *) ckalloc(sizeof(int) + (3+2*nd)*sizeof(expptr) );
                    891: p->ndim = nd;
                    892: p->nelt = ICON(1);
                    893: 
                    894: for(i=0 ; i<nd ; ++i)
                    895:        {
                    896:        if( (q = dims[i].ub) == NULL)
                    897:                {
                    898:                if(i == nd-1)
                    899:                        {
                    900:                        frexpr(p->nelt);
                    901:                        p->nelt = NULL;
                    902:                        }
                    903:                else
                    904:                        err("only last bound may be asterisk");
                    905:                p->dims[i].dimsize = ICON(1);;
                    906:                p->dims[i].dimexpr = NULL;
                    907:                }
                    908:        else
                    909:                {
                    910:                if(dims[i].lb)
                    911:                        {
                    912:                        q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
                    913:                        q = mkexpr(OPPLUS, q, ICON(1) );
                    914:                        }
                    915:                if( ISCONST(q) )
                    916:                        {
                    917:                        p->dims[i].dimsize = q;
                    918:                        p->dims[i].dimexpr = NULL;
                    919:                        }
                    920:                else    {
                    921:                        p->dims[i].dimsize = autovar(1, tyint, NULL);
                    922:                        p->dims[i].dimexpr = q;
                    923:                        }
                    924:                if(p->nelt)
                    925:                        p->nelt = mkexpr(OPSTAR, p->nelt,
                    926:                                        cpexpr(p->dims[i].dimsize) );
                    927:                }
                    928:        }
                    929: 
                    930: q = dims[nd-1].lb;
                    931: if(q == NULL)
                    932:        q = ICON(1);
                    933: 
                    934: for(i = nd-2 ; i>=0 ; --i)
                    935:        {
                    936:        t = dims[i].lb;
                    937:        if(t == NULL)
                    938:                t = ICON(1);
                    939:        if(p->dims[i].dimsize)
                    940:                q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
                    941:        }
                    942: 
                    943: if( ISCONST(q) )
                    944:        {
                    945:        p->baseoffset = q;
                    946:        p->basexpr = NULL;
                    947:        }
                    948: else
                    949:        {
                    950:        p->baseoffset = autovar(1, tyint, NULL);
                    951:        p->basexpr = q;
                    952:        }
                    953: }

unix.superglobalmegacorp.com

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