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