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