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