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