|
|
1.1 ! root 1: /* ! 2: * n0/gdecl.c ! 3: * Read in declarators and build up the DIM and INFO structures. ! 4: */ ! 5: ! 6: #ifdef vax ! 7: #include "INC$LIB:cc0.h" ! 8: #else ! 9: #include "cc0.h" ! 10: #endif ! 11: ! 12: /* ! 13: * Read declarator. ! 14: * The arg "tdp" is the dimensions from a typedef. ! 15: * The storage class is passed since ! 16: * it determines the lexic level of the lookup. ! 17: */ ! 18: gdecl(asp, adp, tdp, c, ls) ! 19: SYM **asp; ! 20: DIM **adp, *tdp; ! 21: int c, ls; ! 22: { ! 23: register SYM *sp; ! 24: DIM *dp; ! 25: int ll; /* Lexical level */ ! 26: int aok; /* Args are OK flag */ ! 27: sizeof_t bound; /* Array bound */ ! 28: ! 29: aok = (llex==LL_EXT && (c==C_GDEF || c==C_GREF || c==C_SEX) && nargs==0); ! 30: while (s == CONST || s == VOLATILE) { ! 31: /* Ignore these for now. They should be treated as MUL */ ! 32: /* They can appear before the type-name as well */ ! 33: lex(); ! 34: } ! 35: if (s == MUL) { ! 36: lex(); ! 37: if (gdecl(asp, adp, NULL, c, ls) == 0) ! 38: return 0; ! 39: *adp = tackdim(*adp, D_PTR, (sizeof_t)0); ! 40: while (tdp != NULL) { ! 41: *adp = tackdim(*adp, tdp->d_type, tdp->d_bound); ! 42: tdp = tdp->d_dp; ! 43: } ! 44: return 1; ! 45: } ! 46: if (s == LPAREN) { ! 47: lex(); ! 48: if (gdecl(asp, adp, NULL, c, ls) == 0) ! 49: return 0; ! 50: mustbe(RPAREN); ! 51: sp = *asp; ! 52: dp = *adp; ! 53: if (nargs != 0) ! 54: aok = 0; ! 55: } else if (s == ID) { ! 56: if (c==C_ARG || c==C_PAUTO || c==C_PREG) ! 57: ll = LL_ARG; ! 58: else if (c==C_GDEF || c==C_GREF) ! 59: ll = LL_EXT; ! 60: else ! 61: ll = llex; ! 62: sp = deflookup(ls, ll); ! 63: dp = NULL; ! 64: lex(); ! 65: } else { ! 66: cerror("declarator syntax"); ! 67: while (s!=EOF && s!=COMMA && s!=SEMI) ! 68: skip(); ! 69: return 0; ! 70: } ! 71: again: ! 72: if (s == LPAREN) { ! 73: lex(); ! 74: garglist(&aok, &dp); ! 75: mustbe(RPAREN); ! 76: goto again; ! 77: } ! 78: if (s == LBRACK) { ! 79: lex(); ! 80: bound = 0; ! 81: if (s != RBRACK) ! 82: bound = getbound(); ! 83: mustbe(RBRACK); ! 84: dp = tackdim(dp, D_ARRAY, bound); ! 85: goto again; ! 86: } ! 87: while (tdp != NULL) { ! 88: dp = tackdim(dp, tdp->d_type, tdp->d_bound); ! 89: tdp = tdp->d_dp; ! 90: } ! 91: *asp = sp; ! 92: *adp = dp; ! 93: return 1; ! 94: } ! 95: ! 96: /* ! 97: * This routine generates tags for tagless struct/union/enum ! 98: * declarations. This makes life easier for csd. ! 99: */ ! 100: SYM *newtag(ll) int ll; ! 101: { ! 102: sprintf(id, ".%d", newlab()); ! 103: setid(id); ! 104: return deflookup(SL_TAG, ll); ! 105: } ! 106: ! 107: /* ! 108: * This routine processes structure and union declarations. ! 109: * The type and INFO data gets passed back indirectly through the ! 110: * "call by reference" parameters. ! 111: * The storage class is passed so that local extern structure ! 112: * definitions get entered at the correct (global) lexical level. ! 113: */ ! 114: gstruct(sc, at, aip) ! 115: int sc, *at; ! 116: INFO **aip; ! 117: { ! 118: int c, dt, i, j, mc, t, tc, w, rf, ls, ll, nbpstrg; ! 119: SYM *tsp, *msp, *mp; ! 120: DIM *dp, **mdp; ! 121: INFO *ip, *nip; ! 122: TOK *oidp; ! 123: unsigned long ofs, max, bitsize; ! 124: ! 125: ll = (sc == C_GREF) ? LL_EXT : llex; ! 126: ls = lsym; ! 127: if (notvariant(VSINU)) ! 128: lsym += 1; ! 129: dt = T_STRUCT; ! 130: tc = C_STAG; ! 131: mc = C_MOS; ! 132: if (s == UNION) { ! 133: dt = T_UNION; ! 134: tc = C_UTAG; ! 135: mc = C_MOU; ! 136: } ! 137: tsp = NULL; ! 138: lex(); ! 139: if (s == ID) { ! 140: tsp = reflookup(SL_TAG); ! 141: if (tsp == NULL) ! 142: tsp = deflookup(SL_TAG, ll); ! 143: oidp = idp; /* save idp, lex() may clobber it */ ! 144: lex(); ! 145: if (s != LBRACE) { ! 146: c = tsp->s_class; ! 147: if (c == C_NONE) { ! 148: *at = dt+1; /* Forward */ ! 149: *aip = tsp; ! 150: return; ! 151: } ! 152: if (c==C_STAG || c==C_UTAG) { ! 153: if (c != tc) ! 154: tagmismatch(tsp); ! 155: *at = dt; ! 156: *aip = tsp->s_ip; ! 157: ++tsp->s_ip->i_refc; ! 158: return; ! 159: } ! 160: cerror("\"%s\" is not a tag", tsp->s_id); ! 161: *at = T_INT; ! 162: *aip = NULL; ! 163: return; ! 164: } ! 165: idp = oidp; /* restore idp for deflookup() */ ! 166: tsp = deflookup(SL_TAG, ll); ! 167: } else ! 168: tsp = newtag(ll); ! 169: mustbe(LBRACE); ! 170: nip = (INFO *) new(sizeof(INFO)); ! 171: nip->i_refc = 1; ! 172: nip->i_nsp = 0; ! 173: ofs = 0; ! 174: max = 0; ! 175: while (s!=EOF && s!=RBRACE) { ! 176: gcandt(&c, &t, &dp, &ip, &rf); ! 177: if (t == T_NONE) { ! 178: if (s == ID) ! 179: cerror("\"%s\" is not a typedef name", id); ! 180: else ! 181: cerror("missing type in structure body"); ! 182: while (s!=EOF && s!=RBRACE && s!=SEMI) ! 183: lex(); ! 184: if (s == SEMI) ! 185: lex(); ! 186: continue; ! 187: } ! 188: if (rf != 0 || c != C_NONE) ! 189: cerror("class not allowed in structure body"); ! 190: if (isvariant(VSINU)) { ! 191: /* ! 192: * Handle the "struct" in "union" rule. ! 193: * A series of unnamed structures within a union are united ! 194: * into a set of named/typed offsets within the union. ! 195: * Basically, we add the unique members of the ! 196: * new structure to the members of the current union. ! 197: * Not strictly part of C, and only works if all MOS in ! 198: * same level of symbol table. ! 199: */ ! 200: if (dt==T_UNION && t==T_STRUCT && s==SEMI) { ! 201: notbook(); ! 202: lex(); ! 203: bitsize = (unsigned long)ip->i_size*NBPBYTE; ! 204: if (bitsize > max) ! 205: max = bitsize; ! 206: for (i=0; i<ip->i_nsp; ++i) { ! 207: mp = ip->i_sp[i]; ! 208: j = nip->i_nsp; ! 209: while (--j >= 0) ! 210: if (nip->i_sp[j] == mp) ! 211: break; ! 212: if (j < 0) { ! 213: nip = newinfo(nip, mp); ! 214: if (tsp != NULL) ! 215: mp->s_flag |= S_TAG; ! 216: } ! 217: } ! 218: continue; ! 219: } ! 220: } ! 221: for (;;) { ! 222: if (s == COLON) { ! 223: lex(); ! 224: newtree(sizeof(TREE)); ! 225: ++ininit; ! 226: w = iconexpr(); ! 227: --ininit; ! 228: if (w < 0) ! 229: cerror("bad filler field width"); ! 230: ofs = fieldalign(t, NULL, ip, w, ofs) + w; ! 231: } else if (gdecl(&msp, &mdp, dp, mc, ls)) { ! 232: if (sc == C_GREF) ! 233: msp->s_level = LL_EXT; ! 234: w = 0; ! 235: if (s == COLON) { ! 236: lex(); ! 237: newtree(sizeof(TREE)); ! 238: ++ininit; ! 239: w = iconexpr(); ! 240: --ininit; ! 241: if (w <= 0) ! 242: cerror("bad field width"); ! 243: } ! 244: ofs = fieldalign(t, mdp, ip, w, ofs); ! 245: msp = declare(msp, mc, t, mdp, ip, rf, w, ofs); ! 246: nip = newinfo(nip, msp); ! 247: if (tsp != NULL) ! 248: msp->s_flag |= S_TAG; ! 249: if (w == 0) ! 250: ofs += (unsigned long)ssize(msp)*NBPBYTE; ! 251: else ! 252: ofs += w; ! 253: } ! 254: if (dt == T_UNION) { ! 255: if (ofs > max) ! 256: max = ofs; ! 257: ofs = 0; ! 258: } ! 259: if (s != COMMA) ! 260: break; ! 261: lex(); ! 262: } ! 263: xdropinfo(t, ip); ! 264: mustbe(SEMI); ! 265: } ! 266: mustbe(RBRACE); ! 267: if (dt == T_STRUCT) ! 268: max = ofs; ! 269: nbpstrg = saligntype(nip) * NBPBYTE; ! 270: if (nbpstrg == 0) ! 271: nbpstrg = NBPBYTE; ! 272: max = (max + nbpstrg - 1) / nbpstrg; ! 273: max = max * nbpstrg / NBPBYTE; ! 274: if (max > MAXESIZE) { ! 275: cerror("size of %s too large", ! 276: (dt==T_STRUCT) ? "struct" : "union"); ! 277: max = 0; ! 278: } ! 279: nip->i_size = max; ! 280: if (tsp != NULL) ! 281: tsp = declare(tsp, tc, 0, NULL, nip, 0); ! 282: *at = dt; ! 283: *aip = nip; ! 284: } ! 285: ! 286: /* ! 287: * Read an enumeration. ! 288: */ ! 289: genum(sc, at, aip) ! 290: int sc, *at; ! 291: INFO **aip; ! 292: { ! 293: register SYM *sp, *tsp; ! 294: INFO *ip; ! 295: TOK *oidp; ! 296: int c, emv, emvmax, emvmin, ll; ! 297: ! 298: ll = (sc == C_GREF) ? LL_EXT : llex; ! 299: tsp = NULL; ! 300: lex(); ! 301: if (s == ID) { ! 302: tsp = reflookup(SL_TAG); ! 303: oidp = idp; /* save idp, lex() may clobber it */ ! 304: lex(); ! 305: if (s != LBRACE) { ! 306: if (tsp == NULL) ! 307: tsp = deflookup(SL_TAG, ll); ! 308: c = tsp->s_class; ! 309: if (c == C_NONE) { ! 310: *at = T_FENUM; ! 311: *aip = tsp; ! 312: return; ! 313: } ! 314: if (c == C_ETAG) { ! 315: *at = T_ENUM; ! 316: *aip = tsp->s_ip; ! 317: ++tsp->s_ip->i_refc; ! 318: return; ! 319: } ! 320: cerror("\"%s\" is not an \"enum\" tag", ! 321: tsp->s_id); ! 322: *at = T_INT; ! 323: *aip = NULL; ! 324: return; ! 325: } ! 326: idp = oidp; /* restore idp for deflookup() */ ! 327: tsp = deflookup(SL_TAG, ll); ! 328: } else ! 329: tsp = newtag(ll); ! 330: mustbe(LBRACE); ! 331: ip = (INFO *) new(sizeof(INFO)); ! 332: ip->i_refc = 1; ! 333: ip->i_nsp = 0; ! 334: emvmax = emvmin = emv = 0; ! 335: for (;;) { ! 336: if (s==EOF || (s==RBRACE && ip->i_nsp == 0)) { ! 337: cerror("unexpected end of enumeration list"); ! 338: break; ! 339: } else if (s==RBRACE) { ! 340: cwarn("trailing ',' in enumeration list"); ! 341: break; ! 342: } else if (s != ID) { ! 343: cerror("error in enumeration list syntax"); ! 344: skip(); ! 345: continue; ! 346: } ! 347: sp = deflookup(SL_VAR, ll); ! 348: lex(); ! 349: if (s == ASSIGN) { ! 350: lex(); ! 351: newtree(sizeof(TREE)); ! 352: ++ininit; ! 353: emv = iconexpr(); ! 354: --ininit; ! 355: } ! 356: if (emv > emvmax) ! 357: emvmax = emv; ! 358: if (emv < emvmin) ! 359: emvmin = emv; ! 360: ip = newinfo(ip, sp); ! 361: sp = declare(sp, C_MOE, 0, NULL, NULL, 0, emv); ! 362: ++emv; ! 363: if (s == RBRACE) ! 364: break; ! 365: mustbe(COMMA); ! 366: } ! 367: if (s == RBRACE) ! 368: lex(); ! 369: ip->i_type = (emvmax>MAXUCE || emvmin<0) ? T_INT : T_UCHAR; ! 370: if (tsp != NULL) ! 371: tsp = declare(tsp, C_ETAG, 0, NULL, ip, 0); ! 372: *at = T_ENUM; ! 373: *aip = ip; ! 374: } ! 375: ! 376: /* ! 377: * Read an old-style K&R function argument list. ! 378: * '*aokp' indicates whether the storage class of the parent declarator ! 379: * and the position of the parenthesized list is appropriate for the ! 380: * formal parameter list of an actual function definition. ! 381: * '*adp' is where the function prototype DIM should be stored. ! 382: */ ! 383: garglist(aokp, adp) register int *aokp; register DIM **adp; ! 384: { ! 385: register SYM *ap; ! 386: ! 387: if (*aokp==1) { ! 388: nargs = 0; ! 389: if (s != RPAREN) ! 390: for (;;) { ! 391: if (s != ID) { ! 392: cerror("argument list has incorrect syntax"); ! 393: break; ! 394: } ! 395: if (nargs >= NARGS) ! 396: cfatal("too many arguments"); ! 397: ap = deflookup(SL_VAR, LL_ARG); ! 398: ap = declare(ap, C_ARG, T_INT, ! 399: NULL, NULL, 0); ! 400: args[nargs++] = ap; ! 401: lex(); ! 402: if (s != COMMA) ! 403: break; ! 404: lex(); ! 405: } ! 406: *aokp = 0; ! 407: } ! 408: *adp = tackdim(*adp, D_FUNC, (sizeof_t)0); ! 409: } ! 410: ! 411: /* ! 412: * Tack a DIM structure onto the end ! 413: * of the dimension list associated with "dp". ! 414: */ ! 415: DIM * ! 416: tackdim(dp, t, b) ! 417: DIM *dp; ! 418: int t; ! 419: sizeof_t b; ! 420: { ! 421: register DIM *dp1, *dp2; ! 422: ! 423: dp1 = (struct dim *) new(sizeof(struct dim)); ! 424: dp1->d_dp = NULL; ! 425: dp1->d_type = t; ! 426: dp1->d_bound = b; ! 427: if ((dp2 = dp) == NULL) ! 428: return dp1; ! 429: while (dp2->d_dp != NULL) ! 430: dp2 = dp2->d_dp; ! 431: dp2->d_dp = dp1; ! 432: return dp; ! 433: } ! 434: ! 435: /* ! 436: * Release a DIM chain. ! 437: */ ! 438: dropdim(dp) ! 439: register DIM *dp; ! 440: { ! 441: if (dp != NULL) { ! 442: dropdim(dp->d_dp); ! 443: free((char *) dp); ! 444: } ! 445: } ! 446: ! 447: /* ! 448: * Duplicate a DIM chain. ! 449: */ ! 450: DIM * ! 451: dupldim(dp) ! 452: register DIM *dp; ! 453: { ! 454: register DIM *np; ! 455: ! 456: if (dp == NULL) ! 457: return NULL; ! 458: np = (struct dim *) new(sizeof(struct dim)); ! 459: np->d_dp = dupldim(dp->d_dp); ! 460: np->d_type = dp->d_type; ! 461: np->d_bound = dp->d_bound; ! 462: return np; ! 463: } ! 464: ! 465: /* ! 466: * Append a symbol to a struct/union/enum information array. ! 467: * Grow the array if necessary and possible. ! 468: */ ! 469: INFO * ! 470: newinfo(ip, sp) ! 471: register INFO *ip; ! 472: SYM *sp; ! 473: { ! 474: register INFO *tip; ! 475: register int i; ! 476: ! 477: i = ip->i_nsp; ! 478: if ((i % 16) == 0) { ! 479: tip = ip; ! 480: ip = (INFO *) new(sizeof(INFO) + (i+16) * sizeof(SYM *)); ! 481: ip->i_refc = tip->i_refc; ! 482: ip->i_data = tip->i_data; ! 483: ip->i_nsp = i; ! 484: while (--i >= 0) ! 485: ip->i_sp[i] = tip->i_sp[i]; ! 486: free((char *) tip); ! 487: i = ip->i_nsp; ! 488: } ! 489: ip->i_sp[i] = sp; ! 490: ip->i_nsp += 1; ! 491: return ip; ! 492: } ! 493: ! 494: /* ! 495: * Read an array bound. ! 496: * An array bound is a constant expression. ! 497: * It may be inside a cast, so save and restore the tree allocate pointer. ! 498: * If signed, give an error if the bound is less than 0. ! 499: * Call the machine dependent size check routine for upper bound check. ! 500: */ ! 501: sizeof_t getbound() ! 502: { ! 503: register TREE *tp; ! 504: extern TREE *expr(); ! 505: register int t; ! 506: register long bound; ! 507: TREE *tmp; ! 508: ! 509: tmp = talloc(); ! 510: tp = expr(); ! 511: treset(tmp); ! 512: if (tp->t_op == ICON) ! 513: bound = tp->t_ival; ! 514: else if (tp->t_op == LCON) ! 515: bound = tp->t_lval; ! 516: else if (tp->t_op == ZCON) ! 517: bound = tp->t_zval; ! 518: else { ! 519: cerror("array bound must be a constant"); ! 520: return 0; ! 521: } ! 522: t = tltype(tp); ! 523: if ((t==T_CHAR || t==T_SHORT || t==T_INT || t==T_LONG) ! 524: && bound < 0) { ! 525: cerror("array bound must be positive"); ! 526: return 0; ! 527: } ! 528: return szcheck(bound, 1, "array bound"); ! 529: } ! 530: ! 531: /* ! 532: * The SYM 'sp' has storage class C_STAG or C_UTAG. ! 533: * A new declaration has been encountered which is of the wrong class. ! 534: * Print a diagnostic giving the name of the tag and its previous class. ! 535: */ ! 536: tagmismatch(sp) ! 537: register SYM *sp; ! 538: { ! 539: register char *p; ! 540: ! 541: p = (sp->s_class == C_UTAG) ? "union" : "structure"; ! 542: cerror("\"%s\" is a %s tag", sp->s_id, p); ! 543: } ! 544: ! 545: /* ! 546: * Read a cast. ! 547: * Return a pointer to a CAST tree node, ! 548: * or NULL if not a legal cast. ! 549: */ ! 550: TREE * ! 551: cast() ! 552: { ! 553: register TREE *tp; ! 554: DIM *dp; ! 555: INFO *ip; ! 556: DIM *cast1(); ! 557: int rf; ! 558: int c, t; ! 559: ! 560: gcandt(&c, &t, &dp, &ip, &rf); ! 561: if (c==C_NONE && t==T_NONE && rf==0) ! 562: return NULL; ! 563: if (rf != 0 || c != C_NONE) ! 564: cerror("storage class not allowed in cast"); ! 565: if (t == T_NONE) { ! 566: cerror("type required in cast"); ! 567: t = T_INT; ! 568: } ! 569: dp = cast1(dp); ! 570: if (t==T_VOID && dp!=NULL && !isfunction(dp)) { ! 571: cerror("illegal use of void type in cast"); ! 572: t = T_INT; ! 573: } ! 574: mustbe(RPAREN); ! 575: tp = talloc(); ! 576: tp->t_op = CAST; ! 577: tp->t_type = t; ! 578: tp->t_dp = dp; ! 579: tp->t_ip = ip; ! 580: xdropinfo(t, ip); ! 581: return tp; ! 582: } ! 583: ! 584: /* this is the cast version of gdecl() */ ! 585: DIM * ! 586: cast1(tdp) ! 587: DIM *tdp; ! 588: { ! 589: register DIM *dp; ! 590: register sizeof_t b; ! 591: DIM *cast2(); ! 592: ! 593: while (s == CONST || s == VOLATILE) { ! 594: lex(); ! 595: } ! 596: if (s == MUL) { ! 597: lex(); ! 598: dp = cast2(cast1(NULL), D_PTR, (sizeof_t)0); ! 599: } else { ! 600: dp = NULL; ! 601: if (s == LPAREN) { ! 602: lex(); ! 603: if (s != RPAREN) { ! 604: dp = cast1(NULL); ! 605: mustbe(RPAREN); ! 606: } else { ! 607: lex(); ! 608: dp = cast2(dp, D_FUNC, (sizeof_t)0); ! 609: } ! 610: } ! 611: again: ! 612: if (s == LPAREN) { ! 613: DIM *tdp; ! 614: lex(); ! 615: tdp = dp; ! 616: cproto(&tdp); ! 617: dp = tdp; ! 618: mustbe(RPAREN); ! 619: goto again; ! 620: } ! 621: if (s == LBRACK) { ! 622: lex(); ! 623: b = 0; ! 624: if (s != RBRACK) ! 625: b = getbound(); ! 626: mustbe(RBRACK); ! 627: dp = cast2(dp, D_ARRAY, b); ! 628: goto again; ! 629: } ! 630: } ! 631: while (tdp != NULL) { ! 632: dp = cast2(dp, tdp->d_type, tdp->d_bound); ! 633: tdp = tdp->d_dp; ! 634: } ! 635: return dp; ! 636: } ! 637: ! 638: /* this is the cast version of tackdim() */ ! 639: DIM * ! 640: cast2(dp, t, b) ! 641: DIM *dp; ! 642: int t; ! 643: sizeof_t b; ! 644: { ! 645: register DIM *dp1, *dp2; ! 646: ! 647: dp1 = (struct dim *) talloc(); ! 648: dp1->d_dp = NULL; ! 649: dp1->d_type = t; ! 650: dp1->d_bound = b; ! 651: if ((dp2 = dp) == NULL) ! 652: return dp1; ! 653: while (dp2->d_dp != NULL) ! 654: dp2 = dp2->d_dp; ! 655: dp2->d_dp = dp1; ! 656: return dp; ! 657: } ! 658: ! 659: cproto(adp) DIM **adp; ! 660: { ! 661: *adp = cast2(*adp, D_FUNC, (sizeof_t)0); ! 662: } ! 663: ! 664: /* end of n0/gdecl.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.