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