1: /*
   2:  * C compiler, phase 1
   3:  * Handles processing of declarations,
   4:  * except for top-level processing of
   5:  * externals.
   6:  */
   7: 
   8: #include "c0.h"
   9: 
  10: /*
  11:  * Process a sequence of declaration statements
  12:  */
  13: declist(sclass)
  14: {
  15:     register sc, offset;
  16:     struct nmlist typer;
  17: 
  18:     offset = 0;
  19:     sc = sclass;
  20:     while (getkeywords(&sclass, &typer)) {
  21:         offset = declare(sclass, &typer, offset);
  22:         sclass = sc;
  23:     }
  24:     return(offset+align(INT, offset, 0));
  25: }
  26: 
  27: /*
  28:  * Read the keywords introducing a declaration statement
  29:  * Store back the storage class, and fill in the type
  30:  * entry, which looks like a hash table entry.
  31:  */
  32: getkeywords(scptr, tptr)
  33: int *scptr;
  34: struct nmlist *tptr;
  35: {
  36:     register skw, tkw, longf;
  37:     int o, isadecl, ismos, unsignf;
  38: 
  39:     isadecl = 0;
  40:     longf = 0;
  41:     unsignf = 0;
  42:     tptr->htype = INT;
  43:     tptr->hstrp = NULL;
  44:     tptr->hsubsp = NULL;
  45:     tkw = -1;
  46:     skw = *scptr;
  47:     ismos = skw==MOS||skw==MOU? FMOS: 0;
  48:     for (;;) {
  49:         mosflg = isadecl? ismos: 0;
  50:         o = symbol();
  51:         if (o==NAME && csym->hclass==TYPEDEF) {
  52:             if (tkw >= 0)
  53:                 error("type clash");
  54:             tkw = csym->htype;
  55:             tptr->hsubsp = csym->hsubsp;
  56:             tptr->hstrp = csym->hstrp;
  57:             isadecl++;
  58:             continue;
  59:         }
  60:         switch (o==KEYW? cval: -1) {
  61:         case AUTO:
  62:         case STATIC:
  63:         case EXTERN:
  64:         case REG:
  65:         case TYPEDEF:
  66:             if (skw && skw!=cval) {
  67:                 if (skw==ARG && cval==REG)
  68:                     cval = AREG;
  69:                 else
  70:                     error("Conflict in storage class");
  71:             }
  72:             skw = cval;
  73:             break;
  74: 
  75:         case UNSIGN:
  76:             unsignf++;
  77:             break;
  78: 
  79:         case LONG:
  80:             longf++;
  81:             break;
  82: 
  83:         case ENUM:
  84:             if (longf || unsignf)
  85:                 error("Perverse modifier on 'enum'");
  86:             strdec(ismos, cval);
  87:             cval = INT;
  88:             goto types;
  89: 
  90:         case UNION:
  91:         case STRUCT:
  92:             tptr->hstrp = strdec(ismos, cval);
  93:             cval = STRUCT;
  94:         case INT:
  95:         case CHAR:
  96:         case FLOAT:
  97:         case DOUBLE:
  98:         case VOID:
  99:         types:
 100:             if (tkw>=0 && (tkw!=INT || cval!=INT))
 101:                 error("Type clash");
 102:             tkw = cval;
 103:             if (unscflg && cval==CHAR)
 104:                 unsignf++;
 105:             break;
 106: 
 107:         default:
 108:             peeksym = o;
 109:             if (isadecl==0)
 110:                 return(0);
 111:             if (tkw<0)
 112:                 tkw = INT;
 113:             if (skw==0)
 114:                 skw = blklev==0? DEFXTRN: AUTO;
 115:             if (unsignf) {
 116:                 if (tkw==INT)
 117:                     tkw = UNSIGN;
 118:                 else if (tkw==CHAR)
 119:                     tkw = UNCHAR;
 120:                 else if (tkw==LONG)
 121:                     tkw = UNLONG;
 122:                 else
 123:                     error("Misplaced 'unsigned'");
 124:             }
 125:             if (longf) {
 126:                 if (tkw==FLOAT)
 127:                     tkw = DOUBLE;
 128:                 else if (tkw==INT)
 129:                     tkw = LONG;
 130:                 else if (tkw==UNSIGN)
 131:                     tkw = UNLONG;
 132:                 else
 133:                     error("Misplaced 'long'");
 134:             }
 135:             *scptr = skw;
 136:             tptr->htype = tkw;
 137:             return(1);
 138:         }
 139:         isadecl++;
 140:     }
 141: }
 142: 
 143: /*
 144:  * Process a structure, union, or enum declaration; a subroutine
 145:  * of getkeywords.
 146:  */
 147: union str *
 148: strdec(mosf, kind)
 149: {
 150:     register elsize, o;
 151:     register struct nmlist *ssym;
 152:     int savebits;
 153:     struct nmlist **savememlist;
 154:     union str *savesparent;
 155:     int savenmems;
 156:     union str *strp;
 157:     struct nmlist *ds;
 158:     struct nmlist *mems[NMEMS];
 159:     struct nmlist typer;
 160:     int tagkind;
 161: 
 162:     if (kind!=ENUM) {
 163:         tagkind = STRTAG;
 164:         mosflg = FTAG;
 165:         if (kind==UNION)
 166:             mosflg = FUNION;
 167:     } else {
 168:         tagkind = ENUMTAG;
 169:         mosflg = FENUM;
 170:     }
 171:     ssym = 0;
 172:     if ((o=symbol())==NAME) {
 173:         ssym = csym;
 174:         mosflg = mosf;
 175:         o = symbol();
 176:         if (o==LBRACE && ssym->hblklev<blklev)
 177:             ssym = pushdecl(ssym);
 178:         if (ssym->hclass && ssym->hclass!=tagkind) {
 179:             defsym = ssym;
 180:             redec();
 181:             ssym = pushdecl(ssym);
 182:         }
 183:         if (ssym->hclass==0) {
 184:             ssym->hclass = tagkind;
 185:             ssym->hstrp = (union str *)Dblock(sizeof(struct SS));
 186:             ssym->hstrp->S.ssize = 0;
 187:             ssym->hstrp->S.memlist = NULL;
 188:         }
 189:         strp = ssym->hstrp;
 190:     } else {
 191:         strp = (union str *)Dblock(sizeof(struct SS));
 192:         strp->S.ssize = 0;
 193:         strp->S.memlist = NULL;
 194:     }
 195:     mosflg = 0;
 196:     if (o != LBRACE) {
 197:         if (ssym==0)
 198:             goto syntax;
 199:         if (ssym->hclass!=tagkind)
 200:             error("Bad structure/union/enum name");
 201:         peeksym = o;
 202:     } else {
 203:         ds = defsym;
 204:         mosflg = 0;
 205:         savebits = bitoffs;
 206:         savememlist = memlist;
 207:         savesparent = sparent;
 208:         savenmems = nmems;
 209:         memlist = mems;
 210:         sparent = strp;
 211:         nmems = 2;
 212:         bitoffs = 0;
 213:         if (kind==ENUM) {
 214:             typer.htype = INT;
 215:             typer.hstrp = strp;
 216:             declare(ENUM, &typer, 0);
 217:         } else
 218:             elsize = declist(kind==UNION?MOU:MOS);
 219:         bitoffs = savebits;
 220:         defsym = ds;
 221:         if (strp->S.ssize)
 222:             error("%s redeclared", ssym->name);
 223:         strp->S.ssize = elsize;
 224:         *memlist++ = NULL;
 225:         strp->S.memlist = (struct nmlist **)Dblock((memlist-mems)*sizeof(*memlist));
 226:         for (o=0; &mems[o] != memlist; o++)
 227:             strp->S.memlist[o] = mems[o];
 228:         memlist = savememlist;
 229:         sparent = savesparent;
 230:         nmems = savenmems;
 231:         if ((o = symbol()) != RBRACE)
 232:             goto syntax;
 233:     }
 234:     return(strp);
 235:    syntax:
 236:     decsyn(o);
 237:     return(0);
 238: }
 239: 
 240: /*
 241:  * Process a comma-separated list of declarators
 242:  */
 243: declare(askw, tptr, offset)
 244: struct nmlist *tptr;
 245: {
 246:     register unsigned o;
 247:     register int skw, isunion;
 248:     struct nmlist abs, *aptr;
 249: 
 250:     skw = askw;
 251:     isunion = 0;
 252:     if (skw==MOU) {
 253:         skw = MOS;
 254:         isunion++;
 255:         mosflg = FMOS;
 256:         if ((peeksym=symbol()) == SEMI) {
 257:             o = length((union tree *)tptr);
 258:             if (o>offset)
 259:                 offset = o;
 260:         }
 261:     }
 262:     do {
 263:         if (skw==ENUM && (peeksym=symbol())==RBRACE) {
 264:             o = peeksym;
 265:             peeksym = -1;
 266:             break;
 267:         }
 268:         if (skw == MOS) {
 269:             abs.hclass = 0;
 270:             abs.hflag = 0;
 271:             abs.htype = 0;
 272:             abs.hsubsp = 0;
 273:             abs.hstrp = 0;
 274:             abs.nextnm = 0;
 275:             abs.sparent = 0;
 276:             abs.hblklev = blklev;
 277:             abs.name = "<none>";
 278:             aptr = &abs;
 279:         } else
 280:             aptr = NULL;
 281:         o = decl1(skw, tptr, isunion?0:offset, aptr);
 282:         if (isunion) {
 283:             o += align(CHAR, o, 0);
 284:             if (o>offset)
 285:                 offset = o;
 286:         } else
 287:             offset += o;
 288:     } while ((o=symbol()) == COMMA);
 289:     if (o==RBRACE) {
 290:         peeksym = o;
 291:         o = SEMI;
 292:     }
 293:     if (o!=SEMI && (o!=RPARN || skw!=ARG1))
 294:         decsyn(o);
 295:     return(offset);
 296: }
 297: 
 298: /*
 299:  * Process a single declarator
 300:  */
 301: decl1(askw, atptr, offset, absname)
 302: struct nmlist *atptr, *absname;
 303: {
 304:     int t1, a, elsize;
 305:     register int skw;
 306:     int type;
 307:     register struct nmlist *dsym;
 308:     register struct nmlist *tptr;
 309:     struct tdim dim;
 310:     int *dp;
 311:     int isinit;
 312: 
 313:     skw = askw;
 314:     tptr = atptr;
 315:     mosflg = skw==MOS? FMOS: 0;
 316:     dim.rank = 0;
 317:     if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)
 318:         return(0);
 319:     /*
 320: 	 * Filler field
 321: 	 */
 322:     if (peeksym==COLON && skw==MOS) {
 323:         peeksym = -1;
 324:         t1 = conexp();
 325:         if (t1<0) {
 326:             error("Negative field width");
 327:             t1 = 0;
 328:         }
 329:         elsize = align(tptr->htype, offset, t1);
 330:         bitoffs += t1;
 331:         return(elsize);
 332:     }
 333:     t1 = getype(&dim, absname);
 334:     if (t1 == -1)
 335:         return(0);
 336:     if (defsym)
 337:         absname = NULL;
 338:     if (tptr->hsubsp) {
 339:         type = tptr->htype;
 340:         for (a=0; type&XTYPE;) {
 341:             if ((type&XTYPE)==ARRAY)
 342:                 dim.dimens[dim.rank++] = tptr->hsubsp[a++];
 343:             type >>= TYLEN;
 344:         }
 345:     }
 346:     type = tptr->htype & ~TYPE;
 347:     while (t1&XTYPE) {
 348:         if (type&BIGTYPE) {
 349:             typov();
 350:             type = t1 = 0;
 351:         }
 352:         type = type<<TYLEN | (t1 & XTYPE);
 353:         t1 >>= TYLEN;
 354:     }
 355:     type |= tptr->htype&TYPE;
 356:     if ((type&XTYPE) == FUNC) {
 357:         if (skw==AUTO)
 358:             skw = EXTERN;
 359:         if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)
 360:             error("Bad func. storage class");
 361:     }
 362:     if (defsym)
 363:         dsym = defsym;
 364:     else if (absname)
 365:         dsym = absname;
 366:     else {
 367:         error("Name required in declaration");
 368:         return(0);
 369:     }
 370:     if (defsym)
 371:     if (dsym->hblklev<blklev || dsym->hclass==MOS && skw==MOS) {
 372:         if (skw==MOS && dsym->sparent==sparent)
 373:             redec();
 374:         defsym = dsym;
 375:         if (skw==EXTERN) {
 376:             for (; dsym!=NULL; dsym = dsym->nextnm) {
 377:                 if (dsym->hclass==EXTERN
 378:                  && strcmp(dsym->name, defsym->name)==0) {
 379:                     defsym = dsym;
 380:                     break;
 381:                 }
 382:             }
 383:             dsym = defsym;
 384:         } else
 385:             defsym = dsym = pushdecl(dsym);
 386:     }
 387:     if (dim.rank == 0)
 388:         dsym->hsubsp = NULL;
 389:     else {
 390:         /*
 391: 		 * If an array is declared twice, make sure the declarations
 392: 		 * agree in dimension.  This happens typically when a .h
 393: 		 * and .c file both declare a variable.
 394: 		 */
 395:         if (dsym->hsubsp) {
 396:             for (a=0, t1 = dsym->htype;
 397:                 a<dim.rank && (t1&XTYPE)==ARRAY;
 398:                 a++, t1 >>= TYLEN)
 399:                 /*
 400: 				 * If we haven't seen a declaration for this
 401: 				 * dimension yet, take what's been given now.
 402: 				 */
 403:                 if (!dsym->hsubsp[a])
 404:                     dsym->hsubsp[a] = dim.dimens[a];
 405:                 else if (dim.dimens[a]
 406:                     && dim.dimens[a] != dsym->hsubsp[a])
 407:                     redec();
 408:             if (a<dim.rank || (t1&XTYPE)==ARRAY)
 409:                 redec();
 410:         } else {
 411:             dp = (int *)Dblock(dim.rank*sizeof(dim.rank));
 412:             for (a=0; a<dim.rank; a++)
 413:                 dp[a] = dim.dimens[a];
 414:             dsym->hsubsp = dp;
 415:         }
 416:     }
 417:     if (!(dsym->hclass==0
 418:        || ((skw==ARG||skw==AREG) && dsym->hclass==ARG1)
 419:        || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type))) {
 420:         redec();
 421:         goto syntax;
 422:     }
 423:     if (dsym->hclass && (dsym->htype&TYPE)==STRUCT && (type&TYPE)==STRUCT)
 424:         if (dsym->hstrp != tptr->hstrp) {
 425:             error("structure redeclaration");
 426:         }
 427:     dsym->htype = type;
 428:     if (tptr->hstrp)
 429:         dsym->hstrp = tptr->hstrp;
 430:     if (skw==TYPEDEF) {
 431:         dsym->hclass = TYPEDEF;
 432:         return(0);
 433:     }
 434:     if (skw==ARG1) {
 435:         if (paraml==NULL)
 436:             paraml = dsym;
 437:         else
 438:             parame->sparent = (union str *)dsym;
 439:         parame = dsym;
 440:         dsym->hclass = skw;
 441:         return(0);
 442:     }
 443:     elsize = 0;
 444:     if (skw==MOS) {
 445:         elsize = length((union tree *)dsym);
 446:         if ((peeksym = symbol())==COLON) {
 447:             elsize = 0;
 448:             peeksym = -1;
 449:             t1 = conexp();
 450:             a = align(type, offset, t1);
 451:             if (dsym->hflag&FFIELD) {
 452:                 if (dsym->hstrp->F.bitoffs!=bitoffs
 453:                  || dsym->hstrp->F.flen!=t1)
 454:                     redec();
 455:             } else {
 456:                 dsym->hstrp = (union str *)Dblock(sizeof(struct FS));
 457:             }
 458:             dsym->hflag |= FFIELD;
 459:             dsym->hstrp->F.bitoffs = bitoffs;
 460:             dsym->hstrp->F.flen = t1;
 461:             bitoffs += t1;
 462:         } else
 463:             a = align(type, offset, 0);
 464:         elsize += a;
 465:         offset += a;
 466:         if (++nmems >= NMEMS) {
 467:             error("Too many structure members");
 468:             nmems -= NMEMS/2;
 469:             memlist -= NMEMS/2;
 470:         }
 471:         if (a)
 472:             *memlist++ = &structhole;
 473:         dsym->hoffset = offset;
 474:         *memlist++ = dsym;
 475:         dsym->sparent = sparent;
 476:     }
 477:     if (skw==REG)
 478:         if ((dsym->hoffset = goodreg(dsym)) < 0)
 479:             skw = AUTO;
 480:     dsym->hclass = skw;
 481:     isinit = 0;
 482:     if ((a=symbol()) == ASSIGN)
 483:         isinit++;
 484:     else
 485:         peeksym = a;
 486:     if (skw==AUTO) {
 487:     /*	if (STAUTO < 0) {	*/
 488:             autolen -= rlength((union tree *)dsym);
 489:             dsym->hoffset = autolen;
 490:             if (autolen < maxauto)
 491:                 maxauto = autolen;
 492:     /*	} else { 			*/
 493:     /*		dsym->hoffset = autolen;	*/
 494:     /*		autolen += rlength(dsym);	*/
 495:     /*		if (autolen > maxauto)		*/
 496:     /*			maxauto = autolen;	*/
 497:     /*	}			*/
 498:         if (isinit)
 499:             cinit(dsym, 0, AUTO);
 500:         isinit = 0;
 501:     } else if (skw==STATIC) {
 502:         dsym->hoffset = isn;
 503:         if (isinit) {
 504:             outcode("BBN", DATA, LABEL, isn++);
 505:             if (cinit(dsym, 1, STATIC) & ALIGN)
 506:                 outcode("B", EVEN);
 507:         } else
 508:             outcode("BBNBN", BSS, LABEL, isn++, SSPACE,
 509:               rlength((union tree *)dsym));
 510:         outcode("B", PROG);
 511:         isinit = 0;
 512:     } else if (skw==REG && isinit) {
 513:         cinit(dsym, 0, REG);
 514:         isinit = 0;
 515:     } else if (skw==ENUM) {
 516:         if (type!=INT)
 517:             error("Illegal enumeration %s", dsym->name);
 518:         dsym->hclass = ENUMCON;
 519:         dsym->hoffset = offset;
 520:         if (isinit)
 521:             cinit(dsym, 0, ENUMCON);
 522:         elsize = dsym->hoffset-offset+1;
 523:         isinit = 0;
 524:     }
 525:     if (absname==0)
 526:         prste(dsym);
 527:     if (isinit)
 528:         peeksym = ASSIGN;
 529: syntax:
 530:     return(elsize);
 531: }
 532: 
 533: /*
 534:  * Push down an outer-block declaration
 535:  * after redeclaration in an inner block.
 536:  */
 537: struct nmlist *
 538: pushdecl(sp)
 539: register struct nmlist *sp;
 540: {
 541:     register struct nmlist *nsp, **hsp;
 542: 
 543:     nsp = (struct nmlist *)Dblock(sizeof(struct nmlist));
 544:     *nsp = *sp;
 545:     nsp->hclass = 0;
 546:     nsp->hflag &= FKIND;
 547:     nsp->htype = 0;
 548:     nsp->hoffset = 0;
 549:     nsp->hblklev = blklev;
 550:     nsp->hstrp = NULL;
 551:     nsp->hsubsp = NULL;
 552:     nsp->sparent = NULL;
 553:     hsp = &hshtab[hash(sp->name)];
 554:     nsp->nextnm = *hsp;
 555:     *hsp = nsp;
 556:     return(nsp);
 557: }
 558: 
 559: /*
 560:  * Read a declarator and get the implied type
 561:  */
 562: getype(dimp, absname)
 563: register struct tdim *dimp;
 564: struct nmlist *absname;
 565: {
 566:     static struct nmlist argtype;
 567:     int type;
 568:     register int o;
 569:     register struct nmlist *ds;
 570: 
 571:     defsym = 0;
 572:     type = 0;
 573:     switch(o=symbol()) {
 574: 
 575:     case TIMES:
 576:         type = getype(dimp, absname);
 577:         if (type==-1)
 578:             return(type);
 579:         if (type&BIGTYPE) {
 580:             typov();
 581:             type = 0;
 582:         }
 583:         return(type<<TYLEN | PTR);
 584: 
 585:     case LPARN:
 586:         if (absname==NULL || nextchar()!=')') {
 587:             type = getype(dimp, absname);
 588:             if (type==-1)
 589:                 return(type);
 590:             if ((o=symbol()) != RPARN)
 591:                 goto syntax;
 592:             goto getf;
 593:         }
 594: 
 595:     default:
 596:         peeksym = o;
 597:         if (absname)
 598:             goto getf;
 599:         break;
 600: 
 601:     case NAME:
 602:         defsym = ds = csym;
 603:     getf:
 604:         switch(o=symbol()) {
 605: 
 606:         case LPARN:
 607:             if (blklev==0) {
 608:                 blklev++;
 609:                 ds = defsym;
 610:                 declare(ARG1, &argtype, 0);
 611:                 defsym = ds;
 612:                 blklev--;
 613:             } else
 614:                 if ((o=symbol()) != RPARN)
 615:                     goto syntax;
 616:             if (type&BIGTYPE) {
 617:                 typov();
 618:                 type = 0;
 619:             }
 620:             type = type<<TYLEN | FUNC;
 621:             goto getf;
 622: 
 623:         case LBRACK:
 624:             if (dimp->rank>=5) {
 625:                 error("Rank too large");
 626:                 dimp->rank = 4;
 627:             }
 628:             if ((o=symbol()) != RBRACK) {
 629:                 peeksym = o;
 630:                 ds = defsym;
 631:                 cval = conexp();
 632:                 defsym = ds;
 633:                 if ((o=symbol())!=RBRACK)
 634:                     goto syntax;
 635:             } else {
 636:                 if (dimp->rank!=0)
 637:                     error("Null dimension");
 638:                 cval = 0;
 639:             }
 640:             dimp->dimens[dimp->rank++] = cval;
 641:             if (type&BIGTYPE) {
 642:                 typov();
 643:                 type = 0;
 644:             }
 645:             type = type<<TYLEN | ARRAY;
 646:             goto getf;
 647:         }
 648:         peeksym = o;
 649:         return(type);
 650:     }
 651: syntax:
 652:     decsyn(o);
 653:     return(-1);
 654: }
 655: 
 656: /*
 657:  * More bits required for type than allowed.
 658:  */
 659: typov()
 660: {
 661:     error("Type is too complicated");
 662: }
 663: 
 664: /*
 665:  * Enforce alignment restrictions in structures,
 666:  * including bit-field considerations.
 667:  */
 668: align(type, offset, aflen)
 669: {
 670:     register a, t, flen;
 671:     char *ftl;
 672: 
 673:     flen = aflen;
 674:     a = offset;
 675:     t = type;
 676:     ftl = "Field too long";
 677:     if (flen==0) {
 678:         a += (NBPC+bitoffs-1) / NBPC;
 679:         bitoffs = 0;
 680:     }
 681:     while ((t&XTYPE)==ARRAY)
 682:         t = decref(t);
 683:     if (t!=CHAR && t!=UNCHAR) {
 684:         a = (a+ALIGN) & ~ALIGN;
 685:         if (a>offset)
 686:             bitoffs = 0;
 687:     }
 688:     if (flen) {
 689:         if (type==INT || type==UNSIGN) {
 690:             if (flen > NBPW)
 691:                 error(ftl);
 692:             if (flen+bitoffs > NBPW) {
 693:                 bitoffs = 0;
 694:                 a += NCPW;
 695:             }
 696:         } else if (type==CHAR || type==UNCHAR) {
 697:             if (flen > NBPC)
 698:                 error(ftl);
 699:             if (flen+bitoffs > NBPC) {
 700:                 bitoffs = 0;
 701:                 a += 1;
 702:             }
 703:         } else
 704:             error("Bad type for field");
 705:     }
 706:     return(a-offset);
 707: }
 708: 
 709: /*
 710:  * Complain about syntax error in declaration
 711:  */
 712: decsyn(o)
 713: {
 714:     error("Declaration syntax");
 715:     errflush(o);
 716: }
 717: 
 718: /*
 719:  * Complain about a redeclaration
 720:  */
 721: redec()
 722: {
 723:     error("%s redeclared", defsym->name);
 724: }
 725: 
 726: /*
 727:  * Determine if a variable is suitable for storage in
 728:  * a register; if so return the register number
 729:  */
 730: goodreg(hp)
 731: struct nmlist *hp;
 732: {
 733:     int type;
 734: 
 735:     type = hp->htype;
 736:     if ((type!=INT && type!=UNSIGN && (type&XTYPE)==0)
 737:      || (type&XTYPE)>PTR || regvar<3)
 738:         return(-1);
 739:     return(--regvar);
 740: }

Defined functions

align defined in line 668; used 5 times
decl1 defined in line 301; used 4 times
declare defined in line 243; used 3 times
declist defined in line 13; used 3 times
decsyn defined in line 712; used 3 times
getkeywords defined in line 32; used 3 times
getype defined in line 562; used 3 times
goodreg defined in line 730; used 2 times
pushdecl defined in line 537; used 6 times
redec defined in line 721; used 7 times
strdec defined in line 147; used 3 times
typov defined in line 659; used 4 times
Last modified: 1993-07-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3889
Valid CSS Valid XHTML 1.0 Strict