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