|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/norm.c 1.6.4.41" */ ! 2: /************************************************************************ ! 3: ! 4: C++ source for cfront, the C++ compiler front-end ! 5: written in the computer science research center of Bell Labs ! 6: ! 7: Copyright (c) 1984 AT&T, Inc. All Rights Reserved ! 8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC. ! 9: ! 10: norm.c: ! 11: ! 12: "normalization" handles problems which could have been handled ! 13: by the syntax analyser; but has not been done. The idea is ! 14: to simplify the grammar and the actions accociated with it, ! 15: and to get a more robust error handling ! 16: ! 17: ****************************************************************************/ ! 18: #ifdef c_plusplus ! 19: overload nested_hide; ! 20: #endif ! 21: ! 22: #include "cfront.h" ! 23: #include "size.h" ! 24: ! 25: Pname sta_name = 0; ! 26: ! 27: void syn_init() ! 28: { ! 29: any_type = new basetype(ANY,0); ! 30: PERM(any_type); ! 31: dummy = new expr(DUMMY,0,0); ! 32: PERM(dummy); ! 33: dummy->tp = any_type; ! 34: zero = new expr(ZERO,0,0); ! 35: PERM(zero); ! 36: sta_name = new name; ! 37: PERM(sta_name); ! 38: } ! 39: ! 40: int stcount; ! 41: ! 42: char* make_name(TOK c) ! 43: { ! 44: char* s = new char[8]; // as it happens: fits in two words ! 45: ! 46: if (10000 <= ++stcount) error('i',"too many generatedNs"); ! 47: ! 48: sprintf(s,"__%c%d",c,stcount); ! 49: return s; ! 50: } ! 51: ! 52: Pbase basetype::type_adj(TOK t) ! 53: { ! 54: //error('d',"bastype::type_adj(%k)",t); ! 55: switch (base) { ! 56: case COBJ: ! 57: case EOBJ: ! 58: { Pbase bt = new basetype(0,0); ! 59: *bt = *this; ! 60: DEL(this); ! 61: this = bt; ! 62: } ! 63: } ! 64: ! 65: if (b_xname) { ! 66: if (base) ! 67: error("badBT:%n%k",b_xname,t); ! 68: else { ! 69: base = TYPE; ! 70: b_name = b_xname; ! 71: } ! 72: b_xname = 0; ! 73: } ! 74: ! 75: switch (t) { ! 76: case TYPEDEF: b_typedef = 1; break; ! 77: case INLINE: b_inline = 1; break; ! 78: case VIRTUAL: b_virtual = 1; break; ! 79: case CONST: if (b_const) error('w',"two const declarators"); ! 80: b_const = 1; break; ! 81: case UNSIGNED: b_unsigned = 1; break; ! 82: case SHORT: b_short = 1; break; ! 83: case LONG: if (b_long) error('w',"two long declarators"); ! 84: if (base == DOUBLE) ! 85: base = LDOUBLE; ! 86: else ! 87: b_long = 1; ! 88: break; ! 89: case FRIEND: ! 90: case OVERLOAD: ! 91: case EXTERN: ! 92: case STATIC: ! 93: case AUTO: ! 94: case REGISTER: ! 95: if (b_sto) ! 96: error("badBT:%k%k",b_sto,t); ! 97: else ! 98: b_sto = t; ! 99: break; ! 100: case DOUBLE: ! 101: if (b_long) { ! 102: t = LDOUBLE; ! 103: b_long = 0; ! 104: } ! 105: // no break ! 106: case VOID: ! 107: case CHAR: ! 108: case INT: ! 109: case FLOAT: ! 110: if (base) ! 111: error("badBT:%k%k",base,t); ! 112: else ! 113: base = t; ! 114: break; ! 115: case SIGNED: ! 116: case VOLATILE: ! 117: error('w',"\"%k\" not implemented (ignored)",t); ! 118: break; ! 119: default: ! 120: error('i',"BT::type_adj(%k)",t); ! 121: } ! 122: return this; ! 123: } ! 124: ! 125: Pbase basetype::name_adj(Pname n) ! 126: { ! 127: //error('d',"name_adj(%n)",n); ! 128: if (b_xname) { ! 129: if (base) ! 130: error("badBT:%n%n",b_xname,n); ! 131: else { ! 132: base = TYPE; ! 133: b_name = b_xname; ! 134: } ! 135: b_xname = 0; ! 136: } ! 137: ! 138: if ( base==0 ! 139: && n->base == TNAME ! 140: && ( n->tp->base!=COBJ || in_arg_list )) { ! 141: base = TYPE; ! 142: b_name = n; ! 143: } ! 144: else ! 145: b_xname = n; ! 146: ! 147: return this; ! 148: } ! 149: ! 150: static TOK type_set( Pbase b ) ! 151: { ! 152: TOK t = 0; ! 153: ! 154: if ( b->b_long ) t = LONG; ! 155: else if ( b->b_short ) t = SHORT; ! 156: else if ( b->b_unsigned ) t = UNSIGNED; ! 157: else if ( b->b_inline ) t = INLINE; ! 158: else if ( b->b_virtual ) t = VIRTUAL; ! 159: else if ( b->b_sto == OVERLOAD ) t = OVERLOAD; ! 160: return t; ! 161: } ! 162: ! 163: int declTag = 1; ! 164: ! 165: Pbase basetype::base_adj(Pbase b) ! 166: { ! 167: // error('d', "basetype::base_adj: %t %k", b, b->base ); ! 168: Pname bn = b->b_name; ! 169: ! 170: switch (base) { ! 171: case COBJ: ! 172: case EOBJ: ! 173: error("NX after%k%n",base,b_name); ! 174: return this; ! 175: } ! 176: ! 177: TOK t; ! 178: if (base) { ! 179: if (b_name) ! 180: error("badBT:%k%n%k%n",base,b_name,b->base,bn); ! 181: else ! 182: error("badBT:%k%k%n",base,b->base,bn); ! 183: } ! 184: else if ( t = type_set(this)) { ! 185: if (b_name) ! 186: error("badBT:%k%n%k%n",t,b_name,b->base,bn); ! 187: else { ! 188: if ( declTag++ ) error("badBT:%k%k%n",t,b->base,bn); ! 189: base=b->base; b_name = bn; ! 190: // error('d',"base_adj: t: %k", t ); ! 191: } ! 192: } ! 193: else { ! 194: base = b->base; ! 195: b_name = bn; ! 196: b_table = b->b_table; ! 197: } ! 198: ! 199: if ( b->base == COBJ ) { ! 200: Pclass cl = Pclass(bn->tp); ! 201: if ( cl->in_class && ! 202: bn->tpdef && ! 203: bn->tpdef->lex_level == NESTED ) ! 204: { // peculiar case: class x { typedef class bn {} _bn; ... ! 205: // bn has been half dealt with in do_nested_type ... ! 206: Pname n = new name(bn->string); ! 207: n->tp = b; ! 208: Pname nn = ktbl->insert(n, NESTED); ! 209: nn->tpdef = bn->tpdef; ! 210: nn->tpdef->lex_level = nn->lex_level = 0; ! 211: bn->tpdef = 0; ! 212: } ! 213: } ! 214: ! 215: return this; ! 216: } ! 217: ! 218: Pbase basetype::check(Pname n) ! 219: /* ! 220: "n" is the first name to be declared using "this" ! 221: check the consistency of "this" ! 222: and use "b_xname" for "n->string" if possible and needed ! 223: */ ! 224: { ! 225: b_inline = 0; ! 226: b_virtual = 0; ! 227: // error('d',"basetype::check(%n) base %k b_xname %n",n,base,b_xname); ! 228: ! 229: if (b_xname && (n->tp || n->string)) { ! 230: if (base) ! 231: error("badBT:%k%n",base,b_xname); ! 232: else { ! 233: base = TYPE; ! 234: b_name = b_xname; ! 235: } ! 236: b_xname = 0; ! 237: } ! 238: ! 239: if (b_xname) { ! 240: if (n->string) ! 241: error("twoNs inD:%n%n",b_xname,n); ! 242: else { ! 243: n->string = b_xname->string; ! 244: b_xname->hide(); ! 245: } ! 246: b_xname = 0; ! 247: } ! 248: ! 249: if (ccl==0 ! 250: && n ! 251: && n->n_oper==TNAME ! 252: && n->n_qualifier==0 ! 253: && n->string) { // hide type name ! 254: Pname nx = ktbl->look(n->string,0); ! 255: if (nx) nx->hide(); ! 256: } ! 257: ! 258: int defa = 0; ! 259: switch (base) { ! 260: case 0: ! 261: defa = 1; ! 262: base = INT; ! 263: break; ! 264: case EOBJ: ! 265: case COBJ: ! 266: if (b_name->base == TNAME) error('i',"TN%n inCO %p",b_name,this); ! 267: } ! 268: ! 269: if (b_long || b_short) { ! 270: TOK sl = (b_short) ? SHORT : LONG; ! 271: if (b_long && b_short) error("badBT:long short%k%n",base,n); ! 272: if (base != INT) ! 273: error("badBT:%k%k%n",sl,base,n); ! 274: else ! 275: base = sl; ! 276: b_short = b_long = 0; ! 277: } ! 278: ! 279: if (b_typedef && b_sto) error("badBT:Tdef%k%n",b_sto,n); ! 280: b_typedef = b_sto = 0; ! 281: ! 282: if (b_linkage) { ! 283: if (1 <= bl_level) error("local linkage directive"); ! 284: } ! 285: ! 286: if (Pfctvec_type == 0) return this; ! 287: ! 288: if (b_const) { ! 289: if (b_unsigned) { ! 290: switch (base) { ! 291: default: ! 292: error("badBT: unsigned const %k%n",base,n); ! 293: b_unsigned = 0; ! 294: case LONG: ! 295: case SHORT: ! 296: case INT: ! 297: case CHAR: ! 298: return this; ! 299: } ! 300: } ! 301: return this; ! 302: } ! 303: else if (b_unsigned) { ! 304: switch (base) { ! 305: case LONG: ! 306: delete this; ! 307: return ulong_type; ! 308: case SHORT: ! 309: delete this; ! 310: return ushort_type; ! 311: case INT: ! 312: delete this; ! 313: return uint_type; ! 314: case CHAR: ! 315: delete this; ! 316: return uchar_type; ! 317: default: ! 318: error("badBT: unsigned%k%n",base,n); ! 319: b_unsigned = 0; ! 320: return this; ! 321: } ! 322: } ! 323: else { ! 324: switch (base) { ! 325: case LONG: ! 326: delete this; ! 327: return long_type; ! 328: case SHORT: ! 329: delete this; ! 330: return short_type; ! 331: case INT: ! 332: if (this==int_type || this==defa_type) return this; ! 333: // if (this != int_type) ! 334: delete this; ! 335: if (defa) return defa_type; ! 336: return int_type; ! 337: case CHAR: ! 338: delete this; ! 339: return char_type; ! 340: case VOID: ! 341: delete this; ! 342: return void_type; ! 343: case TYPE: ! 344: /* use a single base saved in the keyword */ ! 345: if (b_name->n_qualifier) { ! 346: Pbase rv = Pbase(b_name->n_qualifier); ! 347: delete this; ! 348: return rv; ! 349: } ! 350: else { ! 351: PERM(this); ! 352: b_name->n_qualifier = (Pname)this; ! 353: return this; ! 354: } ! 355: default: ! 356: return this; ! 357: } ! 358: } ! 359: } ! 360: ! 361: Pname basetype::aggr() ! 362: /* ! 363: "type SM" seen e.g. struct s {}; ! 364: class x; ! 365: enum e; ! 366: int tname; ! 367: friend cname; ! 368: friend class x; ! 369: int; ! 370: ! 371: typedef int i; // where i is tname ! 372: ! 373: convert ! 374: union { ... }; ! 375: into ! 376: union name { ... } name ; ! 377: */ ! 378: { ! 379: if (b_xname) { ! 380: if (base) { ! 381: Pname n = new name(b_xname->string); ! 382: // error('d',"basetype::aggr: bxname: %n tpdef: %d ccl: %t", b_xname, b_xname->tpdef, ccl ); ! 383: if (ccl && b_xname->tpdef) ! 384: n->tpdef = b_xname->tpdef; ! 385: b_xname->hide(); ! 386: b_xname = 0; ! 387: return n->normalize(this,0,0); ! 388: } ! 389: else { ! 390: base = TYPE; ! 391: b_name = b_xname; ! 392: b_xname = 0; ! 393: } ! 394: } ! 395: ! 396: switch (base) { ! 397: case COBJ: ! 398: { Pclass cl = Pclass(b_name->tp); ! 399: char* s = cl->string; ! 400: if (b_name->base == TNAME) error('i',"TN%n inCO",b_name); ! 401: if (b_const) error("const%k%n",cl->csu,b_name); ! 402: ! 403: if (cl->c_body == 2) { /* body seen */ ! 404: if (s[0]=='_' ! 405: && s[1]=='_' ! 406: && s[2]=='C') { ! 407: char* ss = new char[8]; // max size of generated name is 7 chars, see make_name() ! 408: Pname obj = new name(ss); ! 409: strcpy(ss,s); ! 410: if (cl->csu == UNION) { ! 411: ss[2] = 'O'; ! 412: cl->csu = ANON; ! 413: return obj->normalize(this,0,0); ! 414: } ! 415: error('w',"unusable%k ignored",cl->csu); ! 416: } ! 417: if ( b_sto == FRIEND ) ! 418: error("friend%k%n{...}",cl->csu,b_name); ! 419: cl->c_body = 1; ! 420: return b_name; ! 421: } ! 422: else { /* really a typedef for cfront only: class x; */ ! 423: if (b_sto == FRIEND) goto frr; ! 424: if (ansi_opt) printf("struct %s;\n",s); ! 425: return 0; ! 426: } ! 427: } ! 428: ! 429: case EOBJ: ! 430: { Penum en = Penum(b_name->tp); ! 431: if (b_name->base == TNAME) error('i',"TN%n in enumO",b_name); ! 432: if (b_const) error("const enum%n",b_name); ! 433: if (en->e_body == 2) { ! 434: en->e_body = 1; ! 435: return b_name; ! 436: } ! 437: else { ! 438: error("forward declaration of enum%n", b_name); ! 439: en->e_type = int_type; ! 440: } ! 441: //if (b_sto == FRIEND) goto frr; ! 442: return 0; ! 443: } ! 444: ! 445: case 0: ! 446: { Pname n = new name(make_name('D')); ! 447: n->tp = defa_type; ! 448: error("NX inDL"); ! 449: return n; ! 450: } ! 451: default: ! 452: if (b_typedef) error('w',"illegalTdef ignored"); ! 453: ! 454: if (b_sto == FRIEND && b_name ) { ! 455: frr: ! 456: Pname fr = ktbl->look(b_name->string,0); ! 457: if (fr == 0) error('i',"cannot find friend%n",b_name); ! 458: Pname n = new name(b_name->string); ! 459: n->n_sto = FRIEND; ! 460: n->tp = fr->tp; ! 461: return n; ! 462: } ! 463: else { ! 464: Pname n = new name(make_name('D')); ! 465: n->tp = defa_type; ! 466: error('w',"NX inDL"); ! 467: return n; ! 468: } ! 469: } ! 470: } ! 471: ! 472: void local_name() ! 473: { /* need to provide an additional temporary name ! 474: * to handle case of ! 475: * f() { ! 476: * { class x{...}; } ! 477: * { class x{...}; } ! 478: * } ! 479: * generate name after closing } of block ! 480: * to distinquish between separate blocks at same lexical level ! 481: */ ! 482: for (Plist l=local_blk; l; l=l->l) { ! 483: Pname n = l->f; ! 484: if ( n->tp == 0 ) error( 'i', "no tp yet: #0 local_name" ); ! 485: if ( Pbase(n->tp)->b_name == 0 ) error( 'i', "no tp yet: #1 local_name" ); ! 486: Pname bn = Pbase(n->tp)->b_name; ! 487: if ( bn->tp == 0 ) error( 'i', "no tp yet#2: local_name" ); ! 488: Pclass cl = Pclass(bn->tp); ! 489: cl->lcl = make_name( 'L' ); ! 490: // error( 'd', "local_name(): %n bn: %n: cl : %s nof: %d", n, bn, cl->string, cc->nof ); ! 491: } ! 492: } ! 493: ! 494: void local_restore() ! 495: { ! 496: for (Plist l=local_tn; l; l=l->l) { ! 497: Pname n = l->f; ! 498: // error('d',"local_restore: n %n %t %d bl_level: %d", n, n->tp, n->lex_level, bl_level ); ! 499: //fprintf(stderr," -- n_key %d\n",n->n_key); ! 500: ! 501: n->n_key = (n->lex_level==0)?0:(n->lex_level && n->lex_level<=bl_level) ? LOCAL : HIDDEN; ! 502: //fprintf(stderr," -- n_key %d\n",n->n_key); ! 503: } ! 504: } ! 505: ! 506: void local_hide( Pname n ) ! 507: { ! 508: // error('d',"local_hide(%n )",n); ! 509: ! 510: if ( n->base != TNAME ) return; ! 511: if ( n->n_key == 0 ) { ! 512: local_tn = new name_list( n, local_tn ); ! 513: n->n_key = HIDDEN; ! 514: // error( 'd', "local_hide(): %n n_key: %d", n, n->n_key ); ! 515: } ! 516: } ! 517: ! 518: void ! 519: nested_restore() ! 520: { ! 521: for (Plist l = nested_type; l; l=l->l) ! 522: { ! 523: Pname n = l->f; ! 524: n->n_key = NESTED; ! 525: } ! 526: ! 527: for (l=nested_tn; l; l=l->l) { ! 528: Pname n = l->f; ! 529: Ptype tp = n->tp; ! 530: // error('d',"nested_restore: n %n %t %d bl_level: %d", n, n->tp, n->lex_level, bl_level ); ! 531: // error('d'," --- n_key %k", n->n_key ); ! 532: ! 533: if ( tp->in_class ) ! 534: n->n_key = NESTED; ! 535: else ! 536: if ( tp->lex_level ) ! 537: n->n_key = LOCAL; ! 538: else ! 539: n->n_key = 0; ! 540: // error('d'," --- n_key %k", n->n_key ); ! 541: } ! 542: } ! 543: ! 544: void ! 545: nested_hide( Pname n ) ! 546: { ! 547: // error('d',"nested_hide(%n )",n); ! 548: ! 549: if ( n->base != TNAME ) return; ! 550: if ( n->n_key == 0 ) { ! 551: nested_tn = new name_list( n, nested_tn ); ! 552: n->n_key = HIDDEN; ! 553: // error( 'd', "nested_hide(): %n n_key: %d", n, n->n_key ); ! 554: } ! 555: } ! 556: ! 557: static void ! 558: nested_hide( Plist l ) ! 559: { ! 560: // error('d',"nested_hide( list )"); ! 561: ! 562: for (; l; l=l->l) { ! 563: Pname nn = l->f; ! 564: Pname n = ktbl->look(nn->string,0); ! 565: // error('d',"nested_hide %n %t", n, n->tp, n->n_key); ! 566: if (n==0) continue; ! 567: ! 568: if ( n->base != TNAME ) ! 569: error('i', "nested_hide: %n not a type name (%t)", n, n->tp ); ! 570: if ( n->n_key == 0 ) { ! 571: nested_tn = new name_list( n, nested_tn ); ! 572: n->n_key = HIDDEN; ! 573: // error( 'd', "nested_hide(list): %n n_key: %d", n, n->n_key ); ! 574: // nn->n_key = 0; ! 575: } ! 576: } ! 577: } ! 578: ! 579: int defer_check = 0; ! 580: Pname statStat = 0; ! 581: ! 582: void name::hide() ! 583: /* ! 584: hide "this": that is, "this" should not be a keyword in this scope ! 585: */ ! 586: { ! 587: if (base != TNAME) return; ! 588: // error('d',"'%n '->hide() -- %t lex_level %d bl_level %d",this,tp,lex_level,::bl_level); ! 589: if (n_key == 0) { ! 590: if (lex_level == bl_level && in_arg_list == 0) { ! 591: if (tp->base != COBJ) { ! 592: if ( !in_typedef ) ! 593: error("%n redefined: typedef and identifier", this); ! 594: else if ( in_typedef->base ! 595: && tp->base != type_set(Pbase(in_typedef)) ! 596: && in_typedef->check(tp,0) ) { ! 597: if ( defer_check == 0 ) ! 598: error("%n redefined: previous: %t now: %t", this, tp, in_typedef); ! 599: } ! 600: } ! 601: else { ! 602: //error('d',"in_typedef%t %d tp%t %d",in_typedef,in_typedef,tp,tp); ! 603: //error('d',"in_typedef%k tp%k",in_typedef->base,tp->base); ! 604: if ( in_typedef && in_typedef->base ! 605: && in_typedef->check(tp, 0) ) { ! 606: if ( defer_check == 0 ) ! 607: error( "%n redefined: previous: %t now: %t", this, tp, in_typedef); ! 608: } ! 609: else { ! 610: Pname nn = Pbase(tp)->b_name; ! 611: Pclass cl = Pclass( nn->tp ); ! 612: // check for 'typedef class X X;' ! 613: // and 'typedef X X;' ! 614: if ( in_typedef ) ! 615: while ( in_typedef->base == TYPE ) ! 616: in_typedef = Pbase(in_typedef)->b_name->tp; ! 617: if ( in_typedef ! 618: && in_typedef->base==COBJ ! 619: && Pbase(in_typedef)->b_name->tp==cl ) ! 620: in_typedef = tp; ! 621: else if ( cl->has_ctor() ) ! 622: error( "%n redefined: both aCNWK and %s", this, in_typedef?"a type name":"an identifier" ); ! 623: } ! 624: } ! 625: ! 626: } ! 627: // error( 'd', "%n::hide", this ); ! 628: modified_tn = new name_list(this,modified_tn); ! 629: n_key = HIDDEN; ! 630: } ! 631: } ! 632: ! 633: static Pname Ntncheck; // ensure TNAMES hidden within class scopes ! 634: static int notReally = 0; ! 635: ! 636: void set_scope(Pname tn) ! 637: /* enter the scope of class tn after seeing "tn::f" */ ! 638: { ! 639: // error( 'd', "set_scope: %n %t %d", tn, tn->tp, tn->tp->base ); ! 640: // error( 'd', "set_scope: %d", notReally ); ! 641: ! 642: Pbase b = Pbase(tn->tp); ! 643: while ( b->base == TYPE ) b=Pbase(b->b_name->tp); // typedef class X T ! 644: if (b->base != COBJ) return; // error caught elsewhere ! 645: ! 646: Pclass cl = Pclass(b->b_name->tp); ! 647: char *str = cl->string; ! 648: ! 649: if ( cl->nest_list && notReally == 0 ) { ! 650: nested_type = cl->nest_list; ! 651: nested_hide(cl->nest_list); ! 652: } ! 653: ! 654: Pname ntn = Ntncheck; ! 655: if( notReally == 0 ) ! 656: while ( ntn && ntn->tp->base == TYPE ) ntn = Pbase(ntn->tp)->b_name; ! 657: ! 658: if ( notReally || ntn == 0 || strcmp( str,ntn->string )) { ! 659: if ( cl->baselist ) { ! 660: Pname nb = new name, nbc = new name; ! 661: nb->tp = new basetype(COBJ,0); ! 662: Pbase(nb->tp)->b_name = nbc; ! 663: for (Pbcl bx, bb=cl->baselist; bb; bb = bb->next) { ! 664: bx = bb->next; ! 665: if ( bb->bclass != 0 ) { ! 666: nbc->tp = bb->bclass; ! 667: notReally++; set_scope(nb); notReally--; ! 668: } ! 669: } ! 670: DEL(nbc); DEL(nb->tp); DEL(nb); ! 671: } ! 672: ! 673: int i = 1; ! 674: Plist ll = 0; ! 675: for (Pname nn=cl->memtbl->get_mem(i); nn; nn=cl->memtbl->get_mem(++i) ) { ! 676: if (nn->base == TNAME || nn->base == PUBLIC) continue; ! 677: if (nn->tp->base == CLASS) continue; ! 678: if (nn->tp->base == ENUM) continue; ! 679: Pname n = ktbl->look( nn->string, 0 ); ! 680: if (n) ll = new name_list( n, ll ); ! 681: } ! 682: ! 683: if ( ll ) cl->tn_list = ll; ! 684: if (notReally == 0) Ntncheck = tn; ! 685: } ! 686: ! 687: for (Plist l=cl->tn_list; l; l=l->l) { ! 688: Pname n = l->f; ! 689: n->n_key = (n->lex_level) ? 0 : HIDDEN; ! 690: modified_tn = new name_list(n,modified_tn); ! 691: } ! 692: } ! 693: ! 694: void restore() ! 695: { ! 696: for (Plist l=modified_tn; l; l=l->l) { ! 697: Pname n = l->f; ! 698: // error('d',"restore: n %n %t %d bl_level: %d", n, n->tp, n->lex_level, bl_level ); ! 699: //fprintf(stderr," -- n_key %d\n",n->n_key); ! 700: n->n_key = (n->lex_level==0 || (n->lex_level && n->lex_level<=bl_level)) ? 0 : HIDDEN; ! 701: //fprintf(stderr," -- n_key %d\n",n->n_key); ! 702: if ( n->lex_level == 0 ! 703: && (n->tp->base == COBJ || n->tp->base == EOBJ)) { ! 704: Pname nn = gtbl->look( n->string, 0 ); ! 705: if ( nn ) n->n_key = HIDDEN; ! 706: } ! 707: //fprintf(stderr," -- n_key %d\n",n->n_key); ! 708: } ! 709: } ! 710: ! 711: Pbase start_cl(TOK t, Pname c, Pbcl b) ! 712: { ! 713: int mk_local = 0; ! 714: if (c == 0) { ! 715: c = new name(make_name('C')); ! 716: c->lex_level -= in_class_decl + 1; ! 717: if ( in_typedef && c->lex_level ) ! 718: mk_local = 1; ! 719: else c->lex_level = 0; ! 720: } ! 721: ! 722: for ( Pclass tc = ccl; tc; tc = tc->in_class ) { ! 723: if ( tc->lex_level == c->lex_level ! 724: && strcmp( tc->string, c->string) == 0) { ! 725: error( "C %s redefined", c->string ); ! 726: error('i', "can't recover from previous errors"); ! 727: } ! 728: } ! 729: ! 730: // error('d',&c->where,"%n (%k) %t",c,c->base,c->tp); ! 731: Pname n = c->tname(t); /* t ignored */ ! 732: ! 733: // typedef struct {} x; ! 734: if ( mk_local ) { ! 735: n->n_key = LOCAL; ! 736: extern Plist local_blk, local_class; // place in cfront.h ! 737: local_class = new name_list( n, local_class ); ! 738: local_blk = new name_list( n, local_blk ); ! 739: modified_tn = modified_tn->l; ! 740: } ! 741: ! 742: n->where = curloc; ! 743: Pbase bt = Pbase(n->tp); /* COBJ */ ! 744: if (bt->base != COBJ) { ! 745: error("twoDs of%n:%t andC",n,bt); ! 746: error('i', "can't recover from previous errors"); ! 747: } ! 748: ! 749: Pclass occl = ccl; ! 750: ccl = Pclass(bt->b_name->tp); /* CLASS */ ! 751: if (ccl->defined) ccl->defined |= IN_ERROR; ! 752: ccl->defined |= DEF_SEEN; ! 753: ! 754: // error('d', "start_cl: %n ccl->in_class: %t lex_level: %d", n, ccl->in_class, n->lex_level ); ! 755: ! 756: if (ccl->in_class = occl) { ! 757: occl->tn_list = modified_tn; // save mod-list ! 758: modified_tn = 0; ! 759: } ! 760: ! 761: Ntncheck = 0; // zero it out with each new class declaration ! 762: ccl->string = n->string; ! 763: ccl->csu = t; ! 764: ! 765: if (b) { // list of base classes ! 766: for (Pbcl bx, bb=b, l=0; bb; bb = bx) { ! 767: bx = bb->next; ! 768: bb->next = 0; ! 769: ! 770: if ( bb->bclass ! 771: && strcmp(ccl->string,bb->bclass->string)==0 ) ! 772: error(&n->where,"%nderived from itself",n); ! 773: else if (l == 0) ! 774: l = bb; ! 775: else { // append and check for duplicates ! 776: for (Pbcl ll = l;;) { ! 777: if (bb->bclass && ll->bclass==bb->bclass) { ! 778: error("%s has %s asB twice",ccl->string,bb->bclass->string); ! 779: break; ! 780: } ! 781: ! 782: if (ll->next) ! 783: ll = ll->next; ! 784: else { ! 785: bb->next = l; ! 786: l = bb; ! 787: break; ! 788: } ! 789: } ! 790: } ! 791: } ! 792: ! 793: ccl->baselist = l; ! 794: notReally++; set_scope(n); notReally--; ! 795: } ! 796: return bt; ! 797: } ! 798: ! 799: void end_cl() ! 800: { ! 801: Pclass occl = ccl->in_class; ! 802: Plist ol = occl ? occl->tn_list : 0; // saved modified name list ! 803: ccl->c_body = 2; ! 804: ! 805: if (modified_tn) { // export nested class names to outer scope: ! 806: Plist local = 0; ! 807: for (Plist l=modified_tn, nl=0; l; l=nl) { ! 808: nl = l->l; ! 809: Pname n = l->f; ! 810: ! 811: // in a pure implementation, no longer do this ! 812: if (ktbl->look(n->string,0)) { ! 813: // add it to enclosing class's modified name list ! 814: l->l = ol; ! 815: ol = l; ! 816: } ! 817: else { // retain it in this class's modified name list ! 818: l->l = local; ! 819: local = l; ! 820: } ! 821: } ! 822: if (ccl->tn_list = modified_tn = local) restore(); ! 823: } ! 824: modified_tn = ol; // restore mod-list (possibly modified) ! 825: /* ! 826: if ( occl ) { ! 827: Pname n = ktbl->look(ccl->string,NESTED); ! 828: for (;n; n=n->n_tbl_list) { ! 829: Ptype tt = Pbase(n->tp)->b_name->tp; ! 830: // error('d',"end_cl: ccl: %t occl: %t in_class: %t", ccl, occl, tt->in_class); ! 831: if (strcmp(tt->in_class->string, occl->string) == 0) { ! 832: n->n_key = 0; ! 833: } ! 834: } ! 835: } ! 836: */ ! 837: ccl = occl; ! 838: } ! 839: ! 840: Pbase end_enum(Pname n, Pname b) ! 841: { ! 842: // error( 'd', "end_enum: %n ccl: %t", n , ccl ); ! 843: if (n == 0) n = new name(make_name('E')); ! 844: n = n->tname(ENUM); ! 845: Pbase bt = (Pbase)n->tp; ! 846: if (bt->base != EOBJ) { ! 847: error("twoDs of%n:%t and enum",n,bt); ! 848: error('i', "can't recover from previous errors"); ! 849: } ! 850: Penum en = (Penum)bt->b_name->tp; ! 851: en->e_body = 2; ! 852: en->mem = name_unlist((class nlist *)b); ! 853: if (en->defined) { ! 854: // shouldn't be necessary anymore with nested types ! 855: // if ( in_class_decl ) ! 856: // error("%n redefined, enum tag not local to class", n); ! 857: en->defined |= IN_ERROR; ! 858: } ! 859: en->defined |= DEF_SEEN; ! 860: en->in_class = ccl; ! 861: return bt; ! 862: } ! 863: ! 864: extern Ptype return_nstd_local_type(Pname,TOK&); ! 865: Pname name::tdef() ! 866: /* ! 867: typedef "this" ! 868: */ ! 869: { ! 870: // error('d', "%n->tdef() %t in_typedef: %d", this, tp, in_typedef ); ! 871: ! 872: int anon_cl = 0; ! 873: if (n_qualifier) { ! 874: error("QdN in typedef",this); ! 875: n_qualifier = 0; ! 876: } ! 877: ! 878: Pname n; ! 879: if ( tpdef && tpdef->in_class ) { // nested typedef ! 880: // error('d', "*****%s->tdef: %d ccl: %t", string, tpdef, ccl ); ! 881: n = ktbl->insert(this,NESTED); ! 882: n->tpdef = tpdef; ! 883: n->tpdef->lex_level = n->lex_level = 0; ! 884: nested_type = new name_list( n, nested_type ); ! 885: } ! 886: else { ! 887: Pname nn = ktbl->look(string,NESTED); ! 888: if ( nn ) { ! 889: TOK ntk = 0; // set by return_nstd... ! 890: Ptype tt = return_nstd_local_type(nn,ntk); ! 891: error("nested %k %t::%s seen before globalTdef %s (to do this place global definition first)",ntk, tt->in_class, string, string); ! 892: error( 'i', "cannot recover from previous errors" ); ! 893: } ! 894: lex_level = bl_level - in_class_decl; ! 895: n = ktbl->insert(this,0); ! 896: } ! 897: ! 898: if (tp == 0) error('i',"Tdef%n tp==0",this); ! 899: n->base = base = TNAME; ! 900: PERM(n); ! 901: PERM(tp); ! 902: ! 903: if (tp->base == COBJ || tp->base == EOBJ ) ! 904: { // typedef struct/enum { } s; => struct/enum s {}; ! 905: Pname b = Pbase(tp)->b_name; ! 906: if (b->string[0] == '_' && b->string[1] == '_' ) ! 907: switch ( tp->base ) { ! 908: case COBJ: { ! 909: if (b->string[2] == 'C') { ! 910: Pclass cl = Pclass(b->tp); ! 911: b->string = n->string; ! 912: cl->string = n->string; ! 913: cl->strlen = strlen(cl->string); ! 914: if ( lex_level ) { ! 915: anon_cl = 1; ! 916: n->n_key = LOCAL; ! 917: } ! 918: } ! 919: break; ! 920: } ! 921: case EOBJ: { ! 922: if (b->string[2] == 'E') { ! 923: Penum en = Penum(b->tp); ! 924: b->string = n->string; ! 925: en->string = n->string; ! 926: en->strlen = strlen(en->string); ! 927: } ! 928: } ! 929: } ! 930: } ! 931: ! 932: if ( anon_cl == 0 ) ! 933: modified_tn = new name_list(n,modified_tn); ! 934: return n; ! 935: } ! 936: ! 937: Pname name::tname(TOK csu) ! 938: /* ! 939: "csu" "this" seen, return typedef'd name for "this" ! 940: return (TNAME,x) ! 941: x: (COBJ,y) ! 942: y: (NAME,z) ! 943: z: (CLASS,ae); ! 944: */ ! 945: { ! 946: switch (base) { ! 947: case TNAME: ! 948: return this; ! 949: case NAME: ! 950: { Pname tn = ktbl->insert(this,0); ! 951: // error('d',"tname %n",this); ! 952: Pname on = new name; ! 953: tn->base = TNAME; ! 954: tn->lex_level = lex_level; ! 955: modified_tn = new name_list(tn,modified_tn); ! 956: tn->n_list = n_list = 0; ! 957: string = tn->string; ! 958: *on = *this; ! 959: switch (csu) { ! 960: case ENUM: ! 961: tn->tp = new basetype(EOBJ,on); ! 962: on->tp = new enumdef(0); ! 963: Penum(on->tp)->string = tn->string; ! 964: break; ! 965: default: ! 966: on->tp = new classdef(csu); ! 967: Pclass(on->tp)->string = tn->string; ! 968: Pclass(on->tp)->lex_level = lex_level; ! 969: tn->tp = new basetype(COBJ,on); ! 970: Pbase(tn->tp)->b_table = Pclass(on->tp)->memtbl; ! 971: } ! 972: PERM(tn); ! 973: PERM(tn->tp); ! 974: PERM(on); ! 975: PERM(on->tp); ! 976: return tn; ! 977: } ! 978: default: ! 979: error('i',"tname(%s %d %k)",string,this,base); ! 980: } ! 981: } ! 982: ! 983: int co_hack; ! 984: Pname name::normalize(Pbase b, Pblock bl, bit Cast) ! 985: /* ! 986: if (bl) : a function definition (check that it really is a type ! 987: ! 988: if (Cast) : no name string ! 989: ! 990: for each name on the name list ! 991: invert the declarator list(s) and attatch basetype ! 992: watch out for class object initializers ! 993: ! 994: convert ! 995: struct s { int a; } a; ! 996: into ! 997: struct s { int a; }; struct s a; ! 998: */ ! 999: { ! 1000: Pname n; ! 1001: Pname nn; ! 1002: TOK stc; ! 1003: bit tpdf; ! 1004: bit inli; ! 1005: bit virt; ! 1006: char * lnkg; ! 1007: // error('d',"%n::normalize b %k",this,b->base); ! 1008: if (b) { ! 1009: stc = b->b_sto; ! 1010: tpdf = b->b_typedef; ! 1011: inli = b->b_inline; ! 1012: virt = b->b_virtual; ! 1013: lnkg = b->b_linkage; ! 1014: } ! 1015: else { ! 1016: stc = 0; ! 1017: tpdf = 0; ! 1018: inli = 0; ! 1019: virt = 0; ! 1020: lnkg = 0; ! 1021: } ! 1022: ! 1023: if (inli && stc==EXTERN) { ! 1024: error("both extern and inline"); ! 1025: inli = 0; ! 1026: } ! 1027: ! 1028: if ( stc==STATIC && tp && ! 1029: tp->base == FCT ! 1030: && Pfct(tp)->f_const ) ! 1031: error( "%n staticMF cannot be const", this ); ! 1032: ! 1033: if (stc==FRIEND && tp==0) { ! 1034: /* friend x; ! 1035: must be handled during syntax analysis to cope with ! 1036: class x { friend y; y* p; }; ! 1037: "y" is not local to "x": ! 1038: class x { friend y; ... }; y* p; ! 1039: is legal ! 1040: ! 1041: examples: ! 1042: ! 1043: typedef void SIG_TYP(int); ! 1044: class x { ! 1045: friend class y; ! 1046: friend z; ! 1047: friend x; // dumb ! 1048: friend int i; // error ! 1049: friend SIG_TYP sigFunc; // subtle ! 1050: friend int f(); ! 1051: friend g(int); ! 1052: }; ! 1053: */ ! 1054: if (b && (b->base || b->b_name || b->b_xname)) goto ccc; ! 1055: ! 1056: if (n_list) { ! 1057: error("L of friends"); ! 1058: n_list = 0; ! 1059: } ! 1060: ! 1061: if (!Cast) { ! 1062: Pname nn = gtbl->look( string, 0 ); ! 1063: if ( nn ) { ! 1064: if (nn->tp->base == FCT) ! 1065: error("friendF must include signature:%n", this ); ! 1066: else ! 1067: error("illegal friend declaration:%n", this ); ! 1068: } ! 1069: } ! 1070: ! 1071: //error( 'd', "%n ll: %d", ccl, ccl->lex_level ); ! 1072: lex_level = ccl->lex_level; ! 1073: Pname nx = tname(CLASS); ! 1074: modified_tn = modified_tn->l; /* global */ ! 1075: n_sto = FRIEND; ! 1076: tp = nx->tp; ! 1077: return this; ! 1078: } ! 1079: ccc: ! 1080: if (tp // FUDGE: fix the bad grammar ! 1081: && tp->base==FCT ! 1082: && (n_oper==TNAME || Pfct(tp)->returns)) { ! 1083: Pfct f = Pfct(tp); ! 1084: Pfct f2 = Pfct(f->returns); ! 1085: ! 1086: if (f2) { ! 1087: Ptype pt; ! 1088: Ptype t = f2; ! 1089: lxlx: ! 1090: switch (t->base) { ! 1091: case PTR: // x(* p)(args) ? ! 1092: case VEC: // x(* p[10])(args) ? ! 1093: if (pt = Pptr(t)->typ) { ! 1094: if (pt->base == TYPE) { ! 1095: Pptr(t)->typ = 0; ! 1096: b = Pbase(pt); ! 1097: // stc = b->b_sto; ! 1098: // tpdf = b->b_typedef; ! 1099: // inli = b->b_inline; ! 1100: // virt = b->b_virtual; ! 1101: } ! 1102: else { ! 1103: t = pt; ! 1104: goto lxlx; ! 1105: } ! 1106: } ! 1107: goto zse1; ! 1108: case FCT: ! 1109: {// Pexpr e = f2->argtype; ! 1110: Pexpr e = Pfct(f)->argtype; ! 1111: if (e && e->base==ELIST) { // get the real name; fix its type ! 1112: if (e->e2 || e->e1->base!=DEREF) goto zse1; ! 1113: Pexpr ee = e->e1; ! 1114: Ptype t = 0; ! 1115: Ptype tpx; ! 1116: ldld: ! 1117: switch (ee->base) { ! 1118: case DEREF: ! 1119: { Ptype tt = (ee->e2) ? Ptype(new vec(0,ee->e2)) : Ptype (new ptr(PTR,0)); ! 1120: if (t) ! 1121: Pptr(t)->typ = tt; ! 1122: else ! 1123: tpx = tt; ! 1124: t = tt; ! 1125: ee = ee->e1; ! 1126: goto ldld; ! 1127: } ! 1128: case NAME: ! 1129: { Pname rn = Pname(ee); ! 1130: b = new basetype(TYPE,ktbl->look(string,0)); ! 1131: f->returns = tpx; ! 1132: n_oper = 0; ! 1133: string = rn->string; ! 1134: base = NAME; ! 1135: } ! 1136: } ! 1137: } ! 1138: } ! 1139: } ! 1140: } ! 1141: } ! 1142: ! 1143: zse1: ! 1144: if (b == 0) { ! 1145: error("BTX for %s",string); ! 1146: b = Pbase(defa_type); ! 1147: } ! 1148: ! 1149: if (Cast) string = ""; ! 1150: b = b->check(this); ! 1151: ! 1152: switch (b->base) { // separate class definitions ! 1153: // from object and function type declarations ! 1154: case COBJ: ! 1155: nn = b->b_name; ! 1156: ! 1157: if (Pclass(nn->tp)->c_body==2) { /* first occurrence */ ! 1158: if ( stc == FRIEND ) { ! 1159: Pclass cl = Pclass(nn->tp); ! 1160: if ( cl->csu == ANON ) ! 1161: error( &nn->where, "friend anonymous union"); ! 1162: else ! 1163: error( &nn->where, "%k%n defined in friendD",cl->csu,nn); ! 1164: } ! 1165: if (tp && tp->base==FCT && co_hack == 0) { ! 1166: error(&this->where,"%k%n defined as returnT for%n (did you forget a ';' after '}' ?)",Pclass(nn->tp)->csu,nn,this); ! 1167: nn = this; ! 1168: break; ! 1169: } ! 1170: nn->n_list = this; ! 1171: Pclass(nn->tp)->c_body = 1; /* other occurences */ ! 1172: } ! 1173: else ! 1174: nn = this; ! 1175: break; ! 1176: case EOBJ: ! 1177: nn = b->b_name; ! 1178: if (Penum(nn->tp)->e_body==2) { ! 1179: if (tp && tp->base==FCT) { ! 1180: error(&this->where,"enum%n defined as returnT for%n (did you forget a ';'?)",nn,this); ! 1181: nn = this; ! 1182: break; ! 1183: } ! 1184: nn->n_list = this; ! 1185: Penum(nn->tp)->e_body = 1; ! 1186: } ! 1187: else { ! 1188: Penum en = Penum(nn->tp); ! 1189: if ( en->defined == 0 ) ! 1190: error( "forward declaration of enum%n", nn ); ! 1191: en->e_type = int_type; ! 1192: nn = this; ! 1193: } ! 1194: break; ! 1195: default: ! 1196: nn = this; ! 1197: } ! 1198: ! 1199: Pname nx; ! 1200: for (n=this; n; n=nx) { ! 1201: Ptype t = n->tp; ! 1202: nx = n->n_list; ! 1203: n->n_sto = stc; ! 1204: ! 1205: if (n->base == TNAME) error('i',"redefinition ofTN%n",n); ! 1206: ! 1207: if (t == 0) { ! 1208: if (bl == 0) ! 1209: n->tp = t = b; ! 1210: else { ! 1211: if ( n->base == NAME && n->n_oper ) ! 1212: error(&n->where,"illegal declaration of %n",n); ! 1213: else ! 1214: error(&n->where,"body of nonF%n",n); ! 1215: t = new fct(0,0,0); ! 1216: } ! 1217: } ! 1218: ! 1219: switch (t->base) { ! 1220: case PTR: ! 1221: case RPTR: ! 1222: n->tp = Pptr(t)->normalize(b); ! 1223: break; ! 1224: case VEC: ! 1225: n->tp = Pvec(t)->normalize(b); ! 1226: break; ! 1227: case FCT: ! 1228: n->tp = Pfct(t)->normalize(b); ! 1229: break; ! 1230: case FIELD: ! 1231: if (n->string == 0) n->string = make_name('F'); ! 1232: n->tp = t; ! 1233: Pbase tb = b; ! 1234: // error('d', "field t %k tb %k", t->base, tb->base ); ! 1235: flatten: ! 1236: switch (tb->base) { ! 1237: case TYPE: /* chase typedefs */ ! 1238: tb = (Pbase)tb->b_name->tp; ! 1239: goto flatten; ! 1240: case CHAR: ! 1241: case SHORT: ! 1242: case EOBJ: ! 1243: case INT: ! 1244: // typedef const unsigned cu_int; ! 1245: // struct x { x(); cu_int b1: 2; } ! 1246: ! 1247: Pbase(t)->b_fieldtype = (b->b_unsigned||tb->b_unsigned) ? uint_type : int_type; ! 1248: // goto iii; ! 1249: // case CHAR: ! 1250: // Pbase(t)->b_fieldtype = (b->b_unsigned) ? uchar_type : char_type; ! 1251: // goto iii; ! 1252: // case SHORT: ! 1253: // Pbase(t)->b_fieldtype = (b->b_unsigned) ? ushort_type : short_type; ! 1254: // goto iii; ! 1255: // iii: ! 1256: Pbase(t)->b_unsigned = b->b_unsigned?b->b_unsigned:tb->b_unsigned; ! 1257: Pbase(t)->b_const = b->b_const?b->b_const:tb->b_const; ! 1258: break; ! 1259: default: ! 1260: error("non-int field"); ! 1261: n->tp = defa_type; ! 1262: } ! 1263: break; ! 1264: } ! 1265: ! 1266: Pfct f = Pfct(n->tp); ! 1267: ! 1268: if (f->base != FCT) { ! 1269: if (bl) { ! 1270: error("body for nonF%n",n); ! 1271: n->tp = f = new fct(defa_type,0,0); ! 1272: continue; ! 1273: } ! 1274: if (inli) error("inline nonF%n",n); ! 1275: if (virt) error("virtual nonF%n",n); ! 1276: ! 1277: if (tpdf) { ! 1278: // error('d', "%n->normalize: ccl: %t", this, ccl ); ! 1279: if (ccl && n->tpdef && ! 1280: (n->tpdef->lex_level == NESTED || ! 1281: n->tpdef->lex_level == LOCAL)) ! 1282: ; // using this field for nested/local type info ! 1283: else ! 1284: if (n->n_initializer) { ! 1285: error("Ir forTdefN%n",n); ! 1286: n->n_initializer = 0; ! 1287: } ! 1288: n->tdef(); ! 1289: // because do_nested_type can't call tdef() ! 1290: if ( n->n_key == NESTED ) ! 1291: modified_tn = modified_tn->l; ! 1292: } ! 1293: continue; ! 1294: } ! 1295: ! 1296: if ( lnkg ) set_linkage(lnkg); ! 1297: f->f_linkage = linkage; ! 1298: if ( lnkg ) set_linkage(0); ! 1299: // wait and call f->sign() after args are checked ! 1300: ! 1301: f->f_inline = inli; ! 1302: extern int vcounter; ! 1303: f->f_virtual = virt?(vcounter++,VTOK):0; ! 1304: ! 1305: if (tpdf) { ! 1306: if (f->body = bl) error("Tdef%n { ... }",n); ! 1307: if (n->n_qualifier) { ! 1308: // typedef T x::f(args); ! 1309: // a pointer to member fucntion: ! 1310: // equivalent to typedef T x::(f)(args); ! 1311: f->memof = Pclass(Pbase(n->n_qualifier->tp)->b_name->tp); ! 1312: n->n_qualifier = 0; ! 1313: } ! 1314: n->tdef(); ! 1315: // because do_nested_type can't call tdef() ! 1316: if ( n->n_key == NESTED ) ! 1317: modified_tn = modified_tn->l; ! 1318: continue; ! 1319: } ! 1320: ! 1321: if (f->body = bl) continue; ! 1322: ! 1323: /* ! 1324: Check function declarations. ! 1325: Look for class object instansiations ! 1326: The real ambiguity: ; class x fo(); ! 1327: is interpreted as an extern function ! 1328: declaration NOT a class object with an ! 1329: empty initializer ! 1330: */ ! 1331: { Pname cn = f->returns->is_cl_obj(); ! 1332: bit clob = (cn || cl_obj_vec); ! 1333: ! 1334: if (f->argtype) { /* check argument/initializer list */ ! 1335: Pname nn; ! 1336: ! 1337: for (nn=f->argtype; nn; nn=nn->n_list) { ! 1338: if (nn->base != NAME) { ! 1339: if (!clob) { ! 1340: error(&n->where,"ATX for%n",n); ! 1341: goto zzz; ! 1342: } ! 1343: goto is_obj; ! 1344: } ! 1345: //if (nn->string) { ! 1346: // error("AN%n inD of%n",nn,n); ! 1347: // nn->string = 0; ! 1348: //} ! 1349: if (nn->tp) goto ok; ! 1350: } ! 1351: if (!clob) { ! 1352: error("FALX"); ! 1353: goto zzz; ! 1354: } ! 1355: is_obj: ! 1356: /* it was an initializer: expand to constructor */ ! 1357: n->tp = f->returns; ! 1358: if (f->argtype->base != ELIST) f->f_args = f->argtype = (Pname)new expr(ELIST,(Pexpr)f->argtype,0); ! 1359: if ( n->n_initializer ) { ! 1360: error(&n->where,"twoIrs for%n",n); ! 1361: DEL( ((Pexpr)f->argtype) ); ! 1362: f->argtype = 0; ! 1363: } else ! 1364: n->n_initializer = new texpr(VALUE,cn->tp,(Pexpr)f->argtype); ! 1365: goto ok; ! 1366: zzz: ! 1367: if (f->argtype) { ! 1368: DEL(Pexpr(f->argtype)); ! 1369: f->argtype = 0; ! 1370: f->nargs = 0; ! 1371: f->nargs_known = 1; ! 1372: } ! 1373: } ! 1374: else { /* T a(); => function declaration */ ! 1375: /* ! 1376: if (clob) { ! 1377: DEL(n->tp); ! 1378: n->tp = f->returns; ! 1379: } ! 1380: */ ! 1381: } ! 1382: ok: ! 1383: ; ! 1384: } ! 1385: } ! 1386: return nn; ! 1387: } ! 1388: ! 1389: Ptype vec::normalize(Ptype vecof) ! 1390: { ! 1391: Ptype t = typ; ! 1392: typ = vecof; ! 1393: ! 1394: while(vecof->base == TYPE) ! 1395: vecof = Pbase(vecof)->b_name->tp; ! 1396: ! 1397: switch (vecof->base) { ! 1398: case RPTR: ! 1399: error("array ofRs"); ! 1400: break; ! 1401: case FCT: ! 1402: error("array ofFs"); ! 1403: break; ! 1404: default: ! 1405: break; ! 1406: } ! 1407: ! 1408: if (t == 0) return this; ! 1409: ! 1410: switch (t->base) { ! 1411: case PTR: ! 1412: case RPTR: return Pptr(t)->normalize(this); ! 1413: case VEC: return Pvec(t)->normalize(this); ! 1414: case FCT: return Pfct(t)->normalize(this); ! 1415: default: error('i',"bad arrayT(%d)",t->base); ! 1416: } ! 1417: ! 1418: } ! 1419: ! 1420: Ptype ptr::normalize(Ptype ptrto) ! 1421: { ! 1422: // if (this == 0) error('i',"0->ptr.normalize()"); ! 1423: Ptype t = typ; ! 1424: typ = ptrto; ! 1425: ! 1426: int bc = 0; ! 1427: while (ptrto->base == TYPE) { ! 1428: bc += Pbase(ptrto)->b_const; ! 1429: ptrto = Pbase(ptrto)->b_name->tp; ! 1430: } ! 1431: ! 1432: switch (ptrto->base) { ! 1433: case FCT: ! 1434: if (memof) ! 1435: if (Pfct(ptrto)->memof) { ! 1436: if (memof != Pfct(ptrto)->memof) error("P toMF mismatch: %s and %s",memof->string, Pfct(ptrto)->memof->string); ! 1437: } ! 1438: else ! 1439: Pfct(ptrto)->memof = memof; ! 1440: else ! 1441: memof = Pfct(ptrto)->memof; ! 1442: break; ! 1443: case RPTR: ! 1444: switch (base) { ! 1445: case PTR: error("P toR"); break; ! 1446: case RPTR: error("R toR"); break; ! 1447: } ! 1448: } ! 1449: ! 1450: if (t == 0) { ! 1451: Pbase b = Pbase(ptrto); ! 1452: if (Pfctvec_type ! 1453: && rdo==0 ! 1454: && b->b_unsigned==0 ! 1455: && b->b_const==0 ! 1456: && bc == 0 ! 1457: && memof==0 ! 1458: && base==PTR) { ! 1459: switch (b->base) { ! 1460: case INT: delete this; return Pint_type; ! 1461: case CHAR: delete this; return Pchar_type; ! 1462: case VOID: delete this; return Pvoid_type; ! 1463: } ! 1464: } ! 1465: if (base==RPTR && b->base==VOID) error("void& is not a validT"); ! 1466: return this; ! 1467: } ! 1468: ! 1469: switch (t->base) { ! 1470: case PTR: ! 1471: case RPTR: return Pptr(t)->normalize(this); ! 1472: case VEC: return Pvec(t)->normalize(this); ! 1473: case FCT: return Pfct(t)->normalize(this); ! 1474: default: error('i',"badPT(%k)",t->base); ! 1475: } ! 1476: } ! 1477: ! 1478: Ptype fct::normalize(Ptype ret) ! 1479: /* ! 1480: normalize return type ! 1481: */ ! 1482: { ! 1483: register Ptype t = returns; ! 1484: returns = ret; ! 1485: ! 1486: if (argtype && argtype->base==NAME && argtype->n_qualifier) { ! 1487: error("syntax: ANX"); ! 1488: argtype = 0; ! 1489: nargs = 0; ! 1490: nargs_known = 0; ! 1491: } ! 1492: ! 1493: while(ret->base == TYPE) ! 1494: ret = Pbase(ret)->b_name->tp; ! 1495: ! 1496: switch(ret->base) { ! 1497: case VEC: ! 1498: error("F returning array"); ! 1499: break; ! 1500: case FCT: ! 1501: error("F returningF"); ! 1502: break; ! 1503: default: ! 1504: break; ! 1505: } ! 1506: ! 1507: if (t == 0) return this; ! 1508: ! 1509: switch (t->base) { ! 1510: case PTR: ! 1511: case RPTR: return Pptr(t)->normalize(this); ! 1512: case VEC: return Pvec(t)->normalize(this); ! 1513: case FCT: return Pfct(t)->normalize(this); ! 1514: default: error('i',"badFT:%k",t->base); ! 1515: } ! 1516: } ! 1517: ! 1518: void fct::argdcl(Pname dcl, Pname fn) ! 1519: /* ! 1520: sort out the argument types for old syntax: ! 1521: f(a,b) int a; char b; { ... } ! 1522: beware of ! 1523: f(a) struct s { int a; }; struct s a; ! 1524: */ ! 1525: { ! 1526: Pname n; ! 1527: /*fprintf(stderr,"%d argtype %d %d dcl %d %d\n",this, argtype, argtype?argtype->base:0, dcl, dcl?dcl->base:0); fflush(stderr);*/ ! 1528: switch (base) { ! 1529: case FCT: break; ! 1530: case ANY: return; ! 1531: default: error('i',"fct::argdcl(%d)",base); ! 1532: } ! 1533: ! 1534: if (argtype) { ! 1535: switch (argtype->base) { ! 1536: case NAME: ! 1537: if (dcl) error("badF definition syntax"); ! 1538: for (n=argtype; n; n=n->n_list) { ! 1539: if (n->string == 0) n->string = make_name('A'); ! 1540: } ! 1541: return; ! 1542: case ELIST: // expression list: f(a,b,c) int a; ... { ... } ! 1543: // scan the elist and build a NAME list ! 1544: { ! 1545: Pname tail = 0; ! 1546: n = 0; ! 1547: ! 1548: error(strict_opt?0:'w',&fn->where,"old style definition of%n (anachronism)",fn); ! 1549: ! 1550: for (Pexpr e=Pexpr(argtype); e; e=e->e2) { ! 1551: Pexpr id = e->e1; ! 1552: if (id->base != NAME) { ! 1553: error("NX inAL"); ! 1554: argtype = 0; ! 1555: dcl = 0; ! 1556: break; ! 1557: } ! 1558: Pname nn = new name(id->string); ! 1559: if (n) ! 1560: tail = tail->n_list = nn; ! 1561: else ! 1562: tail = n = nn; ! 1563: } ! 1564: f_args = argtype = n; ! 1565: break; ! 1566: } ! 1567: default: ! 1568: error("ALX(%d)",argtype->base); ! 1569: argtype = 0; ! 1570: dcl = 0; ! 1571: } ! 1572: } ! 1573: else if(nargs_known == ELLIPSIS) { ! 1574: return; ! 1575: } ! 1576: else { ! 1577: nargs_known = 1; ! 1578: nargs = 0; ! 1579: if (dcl) error("ADL forFWoutAs"); ! 1580: return; ! 1581: } ! 1582: ! 1583: // nargs_known = 0; ! 1584: ! 1585: if (dcl) { ! 1586: Pname d; ! 1587: Pname dx; ! 1588: /* for each argument name see if its type is specified ! 1589: in the declaration list otherwise give it the default type ! 1590: */ ! 1591: ! 1592: for (n=argtype; n; n=n->n_list) { ! 1593: char* s = n->string; ! 1594: if (s == 0) { ! 1595: error("AN missing inF definition"); ! 1596: n->string = s = make_name('A'); ! 1597: } ! 1598: else if (n->tp) error("twoTs forA %s",n->string); ! 1599: ! 1600: for (d=dcl; d; d=d->n_list) { ! 1601: if (strcmp(s,d->string) == 0) { ! 1602: if (d->tp->base == VOID) { ! 1603: error("voidA%n",d); ! 1604: d->tp = any_type; ! 1605: } ! 1606: n->tp = d->tp; ! 1607: n->n_sto = d->n_sto; ! 1608: d->tp = 0; // now merged into argtype ! 1609: goto xx; ! 1610: } ! 1611: } ! 1612: n->tp = defa_type; ! 1613: xx:; ! 1614: if (n->tp == 0) error('i',"noT for %s",n->string); ! 1615: } ! 1616: ! 1617: /* now scan the declaration list for "unused declarations" ! 1618: and delete it ! 1619: */ ! 1620: for (d=dcl; d; d=dx) { ! 1621: dx = d->n_list; ! 1622: if (d->tp) { /* not merged with argtype list */ ! 1623: /*if (d->base == TNAME) ??? */ ! 1624: switch (d->tp->base) { ! 1625: case CLASS: ! 1626: case ENUM: ! 1627: /* WARNING: this will reverse the order of ! 1628: class and enum declarations ! 1629: */ ! 1630: d->n_list = argtype; ! 1631: f_args = argtype = d; ! 1632: break; ! 1633: default: ! 1634: error("%n inADL not inAL",d); ! 1635: } ! 1636: } ! 1637: } ! 1638: } ! 1639: ! 1640: /* add default argument types if necessary */ ! 1641: for (n=argtype; n; n=n->n_list) { ! 1642: if (n->tp == 0) n->tp = defa_type; ! 1643: nargs++; ! 1644: } ! 1645: } ! 1646: ! 1647: Pname cl_obj_vec; /* set if is_cl_obj() found a array of class objects */ ! 1648: Pname eobj; /* set if is_cl_obj() found an enum */ ! 1649: ! 1650: Pname type::is_cl_obj() ! 1651: /* ! 1652: returns this->b_name if this is a class object ! 1653: returns 0 and sets cl_obj_vec to this->b_name ! 1654: if this is a array of class objects ! 1655: returns 0 and sets eobj to this->b_name ! 1656: if this is an enum object ! 1657: else returns 0 ! 1658: */ ! 1659: { ! 1660: bit v = 0; ! 1661: register Ptype t = this; ! 1662: ! 1663: if (t == 0) return 0; ! 1664: eobj = 0; ! 1665: cl_obj_vec = 0; ! 1666: xx: ! 1667: switch (t->base) { ! 1668: case TYPE: ! 1669: t = Pbase(t)->b_name->tp; ! 1670: goto xx; ! 1671: ! 1672: case COBJ: ! 1673: if (v) { ! 1674: cl_obj_vec = Pbase(t)->b_name; ! 1675: return 0; ! 1676: } ! 1677: else ! 1678: return Pbase(t)->b_name; ! 1679: ! 1680: case VEC: ! 1681: t = Pvec(t)->typ; ! 1682: v=1; ! 1683: goto xx; ! 1684: ! 1685: case EOBJ: ! 1686: eobj = Pbase(t)->b_name; ! 1687: default: ! 1688: return 0; ! 1689: } ! 1690: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.