|
|
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.