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