|
|
1.1 root 1: /*ident "@(#)ctrans:src/lalex.c 1.6.3.37" */
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: lalex.c:
11:
12: lookahead
13:
14: *****************************************************************************/
15: #include <stdio.h>
16:
17: #ifdef c_plusplus
18: overload is_empty;
19: #endif
20:
21: #include "cfront.h"
22: #include "yystype.h"
23: #include "tqueue.h"
24:
25: #ifdef DBG
26: #define LDB(val,a) { if(Ldebug>=val) {a;} }
27: #else
28: #define LDB(val,a) /**/
29: #endif
30:
31: #ifdef DBG
32: static char*
33: image( int t )
34: {
35: if(keys[t]) return keys[t];
36: else { static char b[20];
37: sprintf(b,"token(%d)",t);
38: return b;
39: }
40: }
41: static void
42: showQ( char* where )
43: /*
44: display token Q
45: */
46: {
47: fprintf(stderr,"TOKEN Q (%s):\n",where);
48: for (register toknode* t = front; t; t = t->next) {
49: fprintf(stderr,"\t%s",image(t->tok));
50: switch(t->tok) {
51: case ID: case ICON: case CCON: case FCON: case STRING:
52: fprintf(stderr," '%s'",t->retval.s);
53: break;
54: case TNAME:
55: fprintf(stderr," '%s'",t->retval.pn->string);
56: break;
57: }
58: putc(' ',stderr);
59: t->place.put(stderr);
60: putc('\n',stderr);
61: }
62: putc('\n',stderr);
63: }
64: #endif
65:
66: int bl_level;
67:
68: static int laexpr( TOK );
69: static int latype( TOK );
70: static int la_decl();
71: static TOK lookahead();
72:
73: /* make this a toknode! */
74: static int lasttk = 0; // one token history
75: static YYSTYPE lastval; // yylval lasttk value
76:
77: int must_be_expr = 0; // handle redundant parentheses
78: int must_be_id = 0; // !0, TNAME => ID, i.e., int X
79:
80: loc curloc;
81: int curr_file;
82:
83: toknode* latok; // current lookahead token
84: toknode* front = 0;
85: toknode* rear = 0;
86:
87: static toknode* free_toks = 0;
88: const TQCHUNK = 16;
89:
90: toknode::toknode(TOK t, YYSTYPE r, loc tloc)
91: {
92: if (free_toks == 0) {
93: register toknode* q;
94: free_toks = q = (toknode*)malloc( TQCHUNK * sizeof(toknode) );
95: for (; q != &free_toks[TQCHUNK-1]; q->next = q+1, ++q);
96: q->next = 0;
97: }
98: this = free_toks; free_toks = free_toks->next;
99: tok = t;
100: used = 0;
101: retval = r;
102: place = tloc;
103: next = last = 0;
104: }
105:
106: toknode::~toknode()
107: {
108: next = free_toks;
109: free_toks = this;
110: this = 0;
111: }
112:
113: #define USE_TOKEN(T,W) \
114: LDB(2,error('d',&(T)->place,"use_token('%k','%s')",(T)->tok,W);); \
115: if ( !(T)->used ) use_token(T);
116:
117: Ptype
118: return_nstd_local_type( Pname n, TOK &sw )
119: {
120: Ptype tt;
121: switch ( n->tp->base ) {
122: case EOBJ:
123: case COBJ:
124: tt = Pbase(n->tp)->b_name->tp;
125: sw = n->tp->base;
126: break;
127: default:
128: tt = n->tpdef;
129: sw = NESTED; // in repr.c, prints ``typedef''
130: break;
131: }
132: return tt;
133: }
134:
135: static Pname
136: local_nested_kludge( Pname n, Pname tn )
137: /*
138: * for backward compatibility with 2.0
139: * in transitional model of nested class types
140: *
141: * struct T { ... };
142: * foobar() {
143: * class X {
144: * typedef int T;
145: * // ...
146: * };
147: * T t;
148: * }
149: *
150: * pure nested classes, choose global struct T{};
151: * no nested classes, choose typedef int T
152: * transitional model: choose typedef, and generate warning
153: * BUG: local typedefs and enums do not have lex_level set
154: */
155: {
156: // error( 'd', "local_nested_kludge: n: %n", n );
157: for ( Pname nn = n; nn; nn = nn->n_tbl_list )
158: {
159: Pname local_class;
160: TOK ntd;
161: if ( nn->n_key != NESTED ) continue;
162: Ptype tt = return_nstd_local_type(nn,ntd);
163: Pclass cl = tt->in_class;
164: while ( cl->in_class ) cl = cl->in_class;
165: if (cl->lex_level &&
166: (local_class = ktbl->look(cl->string,LOCAL)))
167: {
168: // same typedef at nested and non-nested scope
169: if (ntd == NESTED && tn && tn->tp == nn->tp )
170: ;
171: else
172: error('w',"%s occurs at outer and nested localC scope; using %k %t::%s", n->string,ntd,cl,n->string);
173:
174: /*
175: if ( ntd == NESTED && nn->n_dcl_printed != 2 ) {
176: nn->dcl_print(0);
177: nn->n_dcl_printed = 2;
178: }
179: */
180: return nn;
181: }
182: }
183: return 0;
184: }
185:
186: enum { one_back, two_back };
187:
188: static void
189: use_token( toknode* T )
190: /*
191: lookup TNAMEs here instead of in tlex()
192: maintain block level
193: */
194: {
195: static TOK last_tokens[2]; // TSCOPE not reduced at this point
196: static Pname last_tname; // tname :: id, where id is nested class
197: static Pname tdef_name; // typedef tname tdef_name
198:
199: T->used = 1;
200:
201: // error('d', &T->place, "use_token: %k, lasttk: %k",T->tok,lasttk );
202: // error('d', &T->place, "last_tokens: %k %k",last_tokens[two_back],last_tokens[one_back]);
203: // error('d', &T->place, "use_token: last_tname: %n", last_tname);
204:
205: switch ( T->tok ) {
206: case ID:
207: Pname n;
208: // error('d', &T->place, "use_token: %s", T->retval.s );
209: if ( last_tokens[one_back] == MEM &&
210: last_tokens[two_back] == TNAME &&
211: (n=ktbl->look(T->retval.s,NESTED)))
212: { // TYPEDEF :: ID, nested class ctor
213: if (tdef_name && tdef_name->n_key==NESTED &&
214: strcmp(tdef_name->string,n->string)==0)
215: {
216: T->tok = TNAME;
217: T->retval.pn = n;
218: break;
219: }
220: else { // TNAME :: ID, where ID may be nested class
221: for ( Pname nn = n; nn; nn = nn->n_tbl_list )
222: {
223: TOK sw;
224: if ( nn->n_key != NESTED ) continue;
225: Ptype tt = return_nstd_local_type(nn,sw);
226: Pclass cl = tt->in_class;
227: if (strcmp(last_tname->string,cl->string)==0)
228: {
229: T->tok = TNAME;
230: T->retval.pn = nn;
231: break;
232: }
233: }
234: }
235: }
236: else
237: if ( bl_level &&
238: // TNAME:: and :: cannot refer to ``local'' TNAME
239: last_tokens[one_back] != MEM &&
240: (n=ktbl->look(T->retval.s,LOCAL)) )
241: {
242: DB( if(Ldebug>=1)error( 'd', &T->place, "use_token: local class instance: %n", n ) );
243: T->tok = TNAME;
244: T->retval.pn = n;
245: }
246: else if ( n=ktbl->look(T->retval.s,0) ) {
247: DB( if(Ldebug>=1)error( 'd', &T->place, "use_token: global class instance: %n", n ) );
248: // error( 'd', &T->place, "use_token: global class instance: %n %t", n, n->tp );
249:
250: // X:: ?, then n cannot be a global TNAME
251: // except in the case of a constructor
252: if (last_tokens[one_back] == MEM &&
253: last_tokens[two_back] == TNAME &&
254: strcmp(T->retval.s,last_tname->string))
255: ; // do nothing; i.e., return ID
256: else
257: if ( bl_level && n->tp->base != COBJ &&
258: last_tokens[one_back] == MEM &&
259: last_tokens[two_back] != TNAME &&
260: gtbl->look(T->retval.s,0))
261: ; // do nothing: local typedefs & enums not implemented
262: else {
263: Pname nn = 0;
264: TOK ntd;
265: if (bl_level && (nn=ktbl->look(T->retval.s,NESTED)))
266: {
267: (void) return_nstd_local_type(n,ntd);
268: nn = local_nested_kludge(nn,ntd==NESTED?n:0);
269: }
270: T->tok = TNAME;
271: T->retval.pn = nn?nn:n;
272: }
273: }
274: #ifdef DBG
275: else if(Ldebug>=1)
276: error('d',&T->place,"use_token: id %s",T->retval.s);
277: #endif
278: break;
279: case LC: ++bl_level; break;
280: case RC: --bl_level; break;
281: }
282:
283: if (T->tok != COMPL || last_tokens[one_back] != MEM) {
284: last_tokens[two_back] = last_tokens[one_back];
285: last_tokens[one_back] = T->tok;
286: if (T->tok == TNAME) last_tname = T->retval.pn;
287: if ( last_tname &&
288: last_tname->tp->base == TYPE )
289: {
290: tdef_name = last_tname;
291: do
292: tdef_name = Pbase(tdef_name->tp)->b_name;
293: while ( tdef_name->tp->base == TYPE );
294: }
295: }
296: }
297:
298: void
299: addtok(TOK t, YYSTYPE r, loc tloc)
300: {
301: toknode* T = new toknode(t,r,tloc);
302: if (front == 0)
303: front = rear = T;
304: else {
305: rear->next = T;
306: T->last = rear;
307: rear = T;
308: }
309: //error('d',&tloc,"addtok: %k '%s'",t,t==ID?r.s:"");
310: //showQ("addtok");
311: }
312:
313: extern TOK
314: deltok( int noset = 0 )
315: {
316: register toknode* T = front;
317: USE_TOKEN(T,"deltok");
318: register TOK tk = T->tok;
319: if ( !noset ) { yylval = T->retval; curloc = T->place; }
320: curr_file = curloc.file;
321: if (front = front->next)
322: front->last = 0;
323: else
324: latok = rear = 0;
325: delete T;
326: return tk;
327: }
328:
329: static void
330: add_tokens()
331: /*
332: extend lookahead token queue when depleted
333: */
334: {
335: TOK tk = tlex();
336: if ( tk != ID )
337: return;
338:
339: while (tk == ID || tk == MEM || tk == DOT )
340: tk = tlex();
341: }
342:
343: extern TOK
344: la_look()
345: /*
346: peek at head of token queue
347: */
348: {
349: LDB(1,fprintf(stderr,"\n*** la_look()"));
350: if ( front == 0 )
351: add_tokens();
352:
353: latok = front;
354: USE_TOKEN(latok,"la_look");
355: LDB(1,fprintf(stderr," -- %s\n",image(latok->tok)));
356: return latok->tok;
357: }
358:
359: #define NEXTTOK() ( (yychar==-1) ? (yychar=lalex(),yychar) : yychar )
360: void
361: check_decl()
362: /*
363: Lookahead to direct parsing of local/arg type declarations
364: la_decl() returns 1 if lookahead sees a declaration.
365: */
366: {
367: TOK tk2;
368: switch( NEXTTOK() ) {
369: default:
370: break;
371: case TSCOPE: //XXX
372: tk2 = la_look();
373: while ( tk2 == TSCOPE ) tk2 = lookahead();
374: if ( tk2 == TNAME ) {
375: toknode* t = latok;
376: if(t->tok!=TNAME)
377: error('i',"check_decl() token scan");
378: tk2 = lookahead();
379: if ( tk2 == LP && la_decl() ) {
380: t->tok = DECL_MARKER; //TNAME
381: }
382: }
383: break;
384: case TYPE: case TNAME:
385: if ( la_look() == LP && la_decl() ) {
386: must_be_id = 0;
387: DECL_TYPE=yychar;
388: yychar = DECL_MARKER;
389: }
390: }
391: }
392:
393: void
394: check_cast()
395: /*
396: Lookahead to direct parsing of cast
397: la_cast() returns 1 if lookahead sees an ambiguous old-style C cast.
398: */
399: {
400: TOK tk2;
401: switch( NEXTTOK() ) {
402: case TSCOPE: //XXX
403: tk2 = la_look();
404: while ( tk2 == TSCOPE ) tk2 = lookahead();
405: if ( tk2 == TNAME ) {
406: toknode* t = latok;
407: if(t->tok!=TNAME)
408: error('i',"check_cast() token scan");
409: tk2 = lookahead();
410: if ( tk2 == LP && la_decl() ) {
411: t->tok = DECL_MARKER;//TNAME
412: }
413: }
414: break;
415: case TYPE: case TNAME:
416: if ( la_look() == LP && la_cast() ) {
417: must_be_id = 0;
418: DECL_TYPE = yychar;
419: yychar = DECL_MARKER;
420: }
421: }
422: }
423:
424:
425: static int
426: latype( TOK t )
427: {
428: switch ( t ) {
429: default: // includes friend, typedef, storage classes, etc.
430: return 0;
431: case CHAR: case SHORT: case INT: case LONG:
432: case FLOAT: case DOUBLE:
433: case UNSIGNED:
434: return 1;
435: }
436: }
437:
438: static int
439: laexpr( TOK t )
440: {
441: switch ( t ) {
442: default:
443: return 0;
444: case RETURN: case NEW: case AND: case ANDAND: case OR: case OROR:
445: case SIZEOF: case NOT: case COMPL: case MUL: case PLUS: case MINUS:
446: case ER: case ASSIGN: case ASOP: case RELOP: case EQUOP: case DIVOP:
447: case SHIFTOP: case ICOP:
448: return 1;
449: }
450: }
451:
452:
453: static TOK
454: lookahead()
455: /*
456: advance lookahead pointer, lexing at end of Q
457: handle occurrences of TNAME and TSCOPE
458: (should be kept up to date with lalex())
459: */
460: {
461: TOK tk;
462: TOK tk2;
463: TOK prev_tk = 0;
464: YYSTYPE lastval;
465:
466: if ( latok == rear ) {
467: add_tokens();
468: if ( latok )
469: latok = latok->next;
470: else
471: latok = front;
472: }
473: else
474: latok = latok->next;
475:
476: if ( latok->last ) {
477: prev_tk = latok->last->tok;
478: lastval = latok->last->retval;
479: }
480:
481: nexttok:
482: USE_TOKEN(latok,"lookahead1");
483: tk = latok->tok;
484: if ( tk == ID || tk == TNAME )
485: {
486: if (latok->next == 0) add_tokens();
487: USE_TOKEN(latok->next,"lookahead2");
488: /* TOK */ tk2 = latok->next->tok;
489: if ( tk == TNAME ) {
490: if ( tk2 == MEM || tk2 == DOT ) {
491: tscope: tk = TSCOPE;
492: // error('d',"lookahead: tk: %k tk2: %k", tk, tk2 );
493: //XXX -- should be modified to loop and do lookup
494: latok = latok->next;
495: if (latok->next == 0) add_tokens();
496: USE_TOKEN(latok->next,"lookahead3");
497: tk2 = latok->next->tok;
498: if ( tk2 == MUL ) {
499: tk = MEMPTR;
500: latok = latok->next;
501: }
502: }
503: else if (( prev_tk == MUL && tk2 != RP )
504: || prev_tk == AND )
505: {
506: tk = ID;
507: latok->retval.pn->hide();
508: latok->tok = ID;
509: latok->retval.s = latok->retval.pn->string;
510: }
511: }
512: else if ( tk2 == MEM ) {
513: // ID ::
514: //XXX latok = latok->next->next;
515: //XXX goto nexttok;
516: goto tscope; // treat as tscope
517: }
518:
519: if ( tk == ID &&
520: ( tk2 == ID ||
521: ( prev_tk == ID && ( tk2 == COLON || tk2 == LC )))) {
522: // ID ID
523: latok = latok->next;
524: goto nexttok;
525: }
526: }
527:
528: if ( tk == ID ) {
529: Pname nstd = ktbl->look(latok->retval.s,NESTED);
530: if (nstd && (must_be_id == 0 ||
531: must_be_id && prev_tk == LP)) {
532: extern Pname check_for_nested(Pname,TOK,YYSTYPE,TOK); // use this in lalex, too
533: Pname n = check_for_nested(nstd,prev_tk,lastval,tk2);
534: if ( n ) {
535: tk = latok->tok = TNAME;
536: latok->retval.pn = n;
537: }
538: }
539: }
540:
541: return tk;
542: }
543:
544: static Pname mem_sel = 0;
545: char *class_typedef = 0;
546:
547: static Pname
548: do_local_class( Pname n, int lex_level )
549: { /*
550: * modify to ``do_local_type:
551: * do local types: enums and typedefs
552: */
553: Pname nn = n;
554: if ( n->tp ) { // already a TNAME
555: Pclass cl = n->tp->base==COBJ ? Pclass(Pbase(n->tp)->b_name->tp) : 0;
556: if ( n->lex_level != lex_level || (cl && cl->lcl) ) {
557: local_hide( n );
558: nn = new name( n->string );
559: nn->lex_level = lex_level>=0?lex_level:0;
560: }
561: else
562: if ( lex_level == n->lex_level && cl->defined ) {
563: error( "localC %n redefined", n );
564: return n;
565: }
566: }
567:
568: nn = nn->tname( lastval.t );
569: modified_tn = modified_tn->l;
570: nn->n_key = LOCAL;
571: local_class = new name_list( nn, local_class );
572: local_blk = new name_list( nn, local_blk );
573:
574: // error('d', "do_local_class: nn %n tp %t", nn, Pclass(Pbase(nn->tp)->b_name->tp));
575: return nn;
576: }
577:
578: static char*
579: make_nested_name( char *s, Pclass cl )
580: { // Q<cnt>_<class_names><space><null>
581: const nested_depth = 9;
582: char *str_arr[nested_depth];
583: int size_arr[nested_depth];
584: int cnt = 2;
585: int size = 4; // Q,<cnt>,<_>,<null>
586:
587: str_arr[0] = s; str_arr[1] = cl->string;
588:
589: size += size_arr[0] = strlen(s);
590: size += size_arr[1] = cl->strlen?cl->strlen:strlen(cl->string);
591:
592: for (Pclass nc = cl->in_class; nc; nc = nc->in_class ) {
593: if (cnt > nested_depth-1) error('s',"nested depth class beyond %d unsupported",nested_depth);
594: size += size_arr[cnt] = nc->strlen?nc->strlen:strlen(nc->string);
595: str_arr[cnt++] = nc->string;
596: }
597:
598: for ( int i=0; i<cnt; i++ ) // <nnn><string>
599: size += size_arr[i]>99?3:size_arr[i]<10?1:2;
600:
601: //error('d', "make_nested_name( %s, %t ) cnt: %d size: %d", s, cl, cnt, size );
602: char *result = new char[size];
603: sprintf(result, "Q%d_", cnt );
604: size = 3;
605: for ( i=cnt; i; i-- ) {
606: sprintf(result+size,"%d%s", size_arr[i-1], str_arr[i-1]);
607: size += size_arr[i-1] + (size_arr[i-1]>99?3:size_arr[i-1]<10?1:2);
608: }
609:
610: //error('d', "size: %d ", size );
611: result[size] = '\0';
612: //error('d', "make_nested_name result: %s", result );
613: return result;
614: }
615:
616: int is_empty( Pclass cl, bit const_chk )
617: { /* for nested class check, empty means *no* members
618: * for const object check, means no *data* members
619: */
620:
621: // error('d',"%t->is_empty: max: %d real_size: %d", cl, cl->memtbl->max(),cl->real_size );
622:
623: int mbr_cnt = cl->memtbl->max();
624: if ( mbr_cnt == 0 ) return 1;
625:
626: if ( cl->baselist == 0 && cl->real_size!=1 )
627: return 0;
628:
629: // empty class to turn on transitional nested class scope
630: if ( const_chk == 0 &&
631: ( cl->baselist != 0 || mbr_cnt > 1 )) return 0;
632:
633: int i = 1;
634: for (Pname nn=cl->memtbl->get_mem(i); nn; nn=cl->memtbl->get_mem(++i)) {
635: if (nn->base==NAME &&
636: nn->n_union==0 &&
637: nn->tp->base!=FCT &&
638: nn->tp->base!=OVERLOAD &&
639: nn->tp->base!=CLASS &&
640: nn->tp->base!=ENUM &&
641: nn->tp->base!=EOBJ &&
642: nn->n_stclass != STATIC)
643: {
644: if ( nn->string[0]=='_' &&
645: nn->string[1]=='_' &&
646: nn->string[2]=='W' )
647: return 1;
648: else return 0;
649: }
650: }
651:
652: return 1; // if here, no data members encountered
653: }
654:
655: static int
656: is_empty( Penum en )
657: { // is this an empty enum ??
658:
659: // error('d', "%t no_of_enumerators: %d", en, en->no_of_enumerators);
660: if ( en->no_of_enumerators != 0 )
661: return 0;
662:
663: return 1;
664: }
665:
666: static Pname
667: check_nested_type( Pname nm )
668: {
669: // error('d', "check nested type: %n ccl: %t", nm, ccl );
670:
671: Pname nx, n = ktbl->look(nm->string, NESTED);
672: if ( n == 0 || n == nm ) return nm;
673:
674: int cnt = 1;
675: for (nx = n; n; n=n->n_tbl_list )
676: if (n->n_key == NESTED) ++cnt;
677:
678: if ( cnt > 1 ) {
679: error( "ambiguous nested type %s (%d instances), use x::y syntax", nm->string, cnt );
680: error( 'i', "cannot recover from previous errors" );
681: }
682: else {
683: TOK ntk;
684: Ptype tt = return_nstd_local_type(nx,ntk);
685: error('w', "use %t:: to access nested %k %s (anachronism)", tt->in_class, ntk, nx->string);
686: }
687: return nx;
688: }
689:
690: static int
691: in_local_class( Pclass cl )
692: {
693: if ( cl->lex_level )
694: return 1;
695: if ( cl->in_class )
696: return in_local_class( cl->in_class );
697: return 0;
698: }
699:
700: static Pname
701: do_nested_type( Pname n )
702: {
703: Pname nn = n;
704: char *str = 0;
705:
706: // error('d', "do_nested_type: %s in_typedef: %d ccl: %t", n->string, in_typedef, ccl );
707: // error('d', "lasttk: %k class_typedef: %s", lasttk, class_typedef);
708: if ( in_typedef && ccl->string[0]=='_'
709: && ccl->string[1]=='_'
710: && ccl->string[2]=='C') return n;
711:
712: if ( n->tp )
713: { // already a TNAME :
714: // hide existing instance, encode new instance
715: /*
716: * need handle the anomaly:
717: * class x;
718: * x *p;
719: * class y {
720: * class x{ ... }; // oops
721: * };
722: */
723: if (n->tp->base==COBJ) {
724: Pclass cl = Pclass(Pbase(n->tp)->b_name->tp);
725: if (cl->defined == 0 && lasttk == AGGR) {
726: error('w',"forward declaration ofC%n resolved to nested%t::%s",n,ccl,n->string);
727: cl->lcl = new char[9];
728: strcpy(cl->lcl,"FUDGE007"); // license to hack
729: n->lex_level=Pbase(n->tp)->b_name->lex_level=0;
730: return n;
731: }
732: }
733: else if (n->tp->base==EOBJ) { // watch out for enum x;
734: Penum en = Penum(Pbase(n->tp)->b_name->tp);
735: if (en->defined == 0 && lasttk == ENUM) return n;
736: }
737:
738: nested_hide( n );
739: nn = new name( n->string );
740: str = make_nested_name( n->string, ccl );
741: }
742: else
743: // make sure we haven't already seen a nested instance
744: // if so, for transition, this needs to be an error
745: if (ktbl->look( n->string, NESTED ))
746: error("multiple type %s nestings (to do this define an empty class/enum %s {};)",n->string,n->string);
747: if ( in_typedef &&
748: ( class_typedef == 0 ||
749: strcmp(nn->string,class_typedef)==0 ))
750: {
751: if (strcmp(ccl->string, nn->string)==0) { // class x { typedef T x;
752: error( "nested Tdef %s redefines immediately enclosing class", nn->string );
753: error( 'i', "cannot recover from previous errors" );
754: }
755:
756: // make sure there isn't an identifier at global scope being defined
757: // by a nested typedef -- previously an error; keep it so for transition
758: Pname tn;
759: if ( n->tp == 0 && in_local_class(ccl)==0 &&
760: (tn=gtbl->look(n->string,0))) {
761: error( "nested Tdef %s redefines global %n", n->string, tn );
762: error( 'i', "cannot recover from previous errors" );
763: }
764:
765: nn->tpdef = new type;
766: nn->tpdef->nested_sig = str;
767: nn->tpdef->in_class = ccl;
768: nn->tpdef->lex_level = NESTED;
769: PERM(nn->tpdef);
770: }
771: else {
772: nn = nn->tname( lastval.t );
773: Pname tn = Pbase(nn->tp)->b_name;
774: Ptype tt = tn->tp;
775: if ( tt->defined && tt->in_class == ccl) {
776: error( "nested %t redefines immediately enclosing class", nn->string );
777: error( 'i', "cannot recover from previous errors" );
778: }
779: tt->nested_sig = str;
780: modified_tn = modified_tn->l;
781: nn->lex_level = tn->lex_level = 0;
782: nested_type = new name_list( nn, nested_type );
783: }
784: nn->n_key = NESTED;
785: return nn;
786: }
787:
788: static Pname dtor_seen;
789: static int in_expr;
790: extern int in_sizeof;
791:
792: extern TOK
793: lalex()
794: /* return next token to grammar */
795: {
796: register TOK tk;
797: if ( front == 0 )
798: add_tokens(); // extend lookahead queue
799: LDB(1,fprintf(stderr,"\n*** lalex()\n");showQ("before"));
800:
801: gettok:
802: tk = deltok();
803: // error('d',&curloc,"lalex: just got %k '%s' in_typedef: %d",tk,tk==ID?yylval.s:tk==TNAME?yylval.pn->string:"", in_typedef);
804:
805: if ( tk == ID || tk == TNAME )
806: {
807: TOK tk2 = la_look();
808: int lex_level = bl_level - in_class_decl - (tk2 == LC );
809:
810: if ( tk == TNAME )
811: {
812: //error('d', "lalex tname %n; lasttk: %k tk2: %k", yylval.pn, lasttk, tk2);
813: //error('d', " must_be_id: %d must_be_expr %d decl_type %d",must_be_id,must_be_expr,DECL_TYPE);
814: //error('d', " bl_level: %d parsing_members %d",bl_level,parsing_class_members);
815: if ( tk2 == LP
816: && (bl_level == 0 || parsing_class_members)
817: && ( laexpr(lasttk) == 0 )
818: && must_be_expr == 0
819: && DECL_TYPE == 0 ) {
820: if (la_decl()) {
821: must_be_id = 0;
822: DECL_TYPE = tk;
823: tk = DECL_MARKER;
824: goto ret;
825: }
826: }
827:
828: // note: *** can handle local typedefs here, too!
829: if ( in_typedef &&
830: in_typedef->base != 0 &&
831: ccl && in_mem_fct == 0 &&
832: (tk2 == SM || tk2 == RP || tk2 == LB))
833: yylval.pn = do_nested_type(yylval.pn);
834:
835: if ( lasttk == AGGR || lasttk == ENUM ) {
836: if ( tk2 == LC || tk2 == COLON ) { // class definition
837: if ( in_typedef &&
838: in_typedef->base == 0 &&
839: class_typedef == 0 )
840: class_typedef = yylval.pn->string;
841: if ( lex_level
842: && (in_class_decl==0 || in_mem_fct)
843: && lasttk != ENUM ) // temporary
844: yylval.pn = do_local_class( yylval.pn, lex_level );
845: else
846: if ( in_class_decl && ccl )
847: yylval.pn = do_nested_type( yylval.pn );
848: }
849: }
850:
851: if ( tk2 == MEM || (tk2 == DOT && mem_sel == 0 )) {
852: if (tk2==DOT)
853: error(strict_opt?0:'w',"``.'' used for qualification; please use ``::'' (anachronism)");
854: crunch:
855: tk = TSCOPE;
856: {//XXX -- should be modified to do lookup and del at each ::
857: while ( (tk2 = lookahead()) == TSCOPE ) ;
858: if ( tk2 == TNAME ) {
859: tk2 = lookahead();
860: if ( tk2 == LP
861: && (bl_level == 0 || parsing_class_members)
862: && ( laexpr(lasttk) == 0 )
863: && must_be_expr == 0
864: && DECL_TYPE == 0 ) {
865: if (la_decl()) {
866: must_be_id = 0;
867: //DECL_TYPE = tk;//???
868: DECL_TYPE = TNAME;
869: //front should be ::
870: front->tok = TSCOPE;
871: front->retval.pn = yylval.pn;
872: yylval.pn = 0;
873: tk = DECL_MARKER;
874: goto ret;
875: }
876: }
877: }
878: }
879: tk2 = deltok(1);
880: tk2 = la_look();
881: if ( tk2 == MUL ) {
882: tk = MEMPTR;
883: tk2 = deltok(1);
884: }
885: }
886: // Have a TNAME. Check to be sure.
887: else if ( must_be_id ){
888: //error('d',"lalex: must_be_id: <tname %n> <%k>",yylval.pn,tk2);
889: if ( in_class_decl
890: && lasttk == TYPE
891: && tk2 == LP
892: && strcmp(yylval.pn->string,ccl->string) == 0 )
893: error("%nK with returnT", yylval.pn);
894:
895: else if ( lasttk == TYPE && lastval.t == OVERLOAD
896: && ( tk2 == SM || tk2 == LP ) )
897: {
898: tk = ID;
899: yylval.pn->hide();
900: yylval.pn = new name( yylval.pn->string );
901: yylval.pn->n_oper = TNAME;
902: }
903: else if ( lasttk == OPERATOR ||
904: in_typedef && yylval.pn->n_key == NESTED)
905: must_be_id = 0;
906: else if ( lasttk != TSCOPE // watch out for X::X
907: || lastval.pn != yylval.pn
908: || (in_typedef &&
909: in_typedef->check( yylval.pn->tp,0) == 0 ))
910: {
911: tk = ID;
912: if ( in_typedef && (lasttk == MUL || lasttk == REF)) {
913: defer_check = 1;
914: in_tag = yylval.pn;
915: }
916:
917: if ( lasttk == MEM && yylval.pn->lex_level ) {
918: Pname nn = gtbl->look( yylval.pn->string, 0 );
919: if (nn == 0 )
920: error( "%k%s undeclared", lasttk, yylval.pn->string);
921: else
922: yylval.pn = nn;
923: }
924: else {
925: // error('d',"lalex: else: lasttk: %k", lasttk );
926: if (lasttk!=DOT && lasttk!=REF
927: && lasttk!=TSCOPE && lasttk != GOTO
928: // handle typedefs in basetype::check
929: // when type is available
930: && !in_typedef) {
931: // error('d',"\"%s\" line %d: hiding%n",__FILE__,__LINE__,yylval.pn);
932: yylval.pn->hide();
933: }
934:
935: yylval.pn = new name (yylval.pn->string);
936: if (lasttk!=DOT && lasttk!=REF &&
937: lasttk!=TSCOPE && lasttk !=GOTO)
938: yylval.pn->n_oper = TNAME;
939: }
940: if ( defer_check ) defer_check = 0;
941: }
942: } // must_be_id
943:
944: if ( in_class_decl &&
945: ccl->lex_level &&
946: yylval.pn->lex_level != 0 &&
947: yylval.pn->tp &&
948: (yylval.pn->tp->base != COBJ && yylval.pn->tp->base != EOBJ))
949: {
950: Pname n = gtbl->look( yylval.pn->string,0);
951: if ( in_mem_fct ) {
952: if (n && n->base == TNAME ) {
953: error('w', "local typedef %n(%t) is not in scope of local class %s members; using global (%t)", yylval.pn, yylval.pn->tp, ccl->string, n->tp );
954: yylval.pn = n;
955: } else
956: error( "local typedef %sis not in scope of inline member function of local class %s", yylval.pn->string, ccl->string);
957: }
958: }
959:
960: // if we still have a TNAME, make sure have the right TNAME
961: // possibility of ananchronistic reference to nested type
962: Ptype nbt = yylval.pn->tp;
963: if (tk == TNAME && curr_scope == 0 && nbt && // Y y; not X::Y y;
964: (nbt->base == EOBJ || nbt->base == COBJ))
965: {
966: Ptype t = Pbase(nbt)->b_name->tp;
967: if ( ccl && t->in_class &&
968: strcmp(t->in_class->string, ccl->string))
969: {
970: switch( nbt->base ) {
971: case COBJ:
972: if (is_empty(Pclass(t)))
973: yylval.pn = check_nested_type( yylval.pn );
974: break;
975: case EOBJ:
976: if (is_empty(Penum(t)))
977: yylval.pn = check_nested_type( yylval.pn );
978: break;
979: };
980: }
981: }
982: }
983: else
984: { // tk == ID
985: char *s = yylval.s;
986: Pname n = ktbl->look( s, HIDDEN );
987: Pname nstd = ktbl->look( s, NESTED );
988:
989: // inside a class definition, ccl, that is nested
990: // s is a nested class name, and is the name of ccl
991: if (ccl && ccl->in_class && nstd &&
992: strcmp(s, ccl->string)==0)
993: {
994: for (Pname nn=nstd; nn; nn=nn->n_tbl_list) {
995: Ptype tt = (nn->tp->base==COBJ || nn->tp->base==EOBJ)
996: ? Pbase(nn->tp)->b_name->tp : nn->tpdef;
997: Pclass cl = tt->in_class;
998: if ( nn->n_key != NESTED ) continue;
999: if (strcmp(ccl->in_class->string,cl->string) == 0) {
1000: tk = TNAME;
1001: yylval.pn = nn;
1002: n = nstd = nn;
1003: }
1004: }
1005: }
1006:
1007: if (tk2 == MEM) {
1008: // ID ::
1009: if (n) {
1010: yylval.pn = n;
1011: /*XXX*/ goto crunch;
1012: }
1013: else
1014: if (nstd &&
1015: nstd->n_tbl_list==0)
1016: {
1017: yylval.pn = nstd;
1018: tk = TSCOPE;
1019: tk2 = deltok(1);
1020: tk2 = la_look();
1021: if (tk2 == MUL ) {
1022: tk = MEMPTR;
1023: tk2 = deltok(1);
1024: }
1025: }
1026: else {
1027: error( "%s:: %sis not aTN", s, s );
1028: tk2 = deltok(1);
1029: goto gettok;
1030: }
1031: }
1032: else // transitional kludge
1033: if ( n && nstd && n == nstd )
1034: ; // null statement
1035:
1036: // Have an ID. Check last token to be sure.
1037: else if (lasttk==ENUM || lasttk==AGGR) {
1038: int fd = tk2!=LC && tk2!=COLON;
1039: if ( in_typedef && fd == 0 &&
1040: in_typedef->base == 0 &&
1041: class_typedef == 0 )
1042: class_typedef = yylval.s;
1043: tk = TNAME;
1044: if ( nstd ) {
1045: // in transitional model, need flag this as error
1046: if ( fd == 0 ) { // real definition
1047: if ( ccl == 0 )
1048: error("nested and global%k %s(to do this place global%k %s {}; first)",lasttk==ENUM?lasttk:CLASS, s, lasttk==ENUM?lasttk:CLASS, s);
1049: else
1050: error("multiple nested%k %s(to do this place global%k %s {}; first)",lasttk==ENUM?lasttk:CLASS, s, lasttk==ENUM?lasttk:CLASS,s);
1051: error( 'i', "cannot recover from previous errors" );
1052: }
1053: }
1054: else
1055: if (n==0) { // new tag, define it
1056: // error('d', "ccl: %t fd: %d, in_mem_fct: %d, in_class_decl: %d", ccl, fd, in_mem_fct, in_class_decl);
1057: n = new name( s );
1058: if ( fd ) // struct X*, etc.
1059: n->lex_level=0;
1060: else
1061: n->lex_level=lex_level>=0?lex_level:0;
1062:
1063: if ( ccl && fd == 0 &&
1064: in_class_decl &&
1065: in_mem_fct == 0 )
1066: n = do_nested_type( n );
1067: else
1068: // note: ***** modify to handle local typedef
1069: // note: ***** add local enums
1070: if ( n->lex_level &&
1071: lasttk != ENUM ) // temporary
1072: n = do_local_class( n, n->lex_level );
1073: else {
1074: n = n->tname( lastval.t );
1075: modified_tn = modified_tn->l;
1076: if (fd && gtbl->look(n->string,0)) statStat = n;
1077: }
1078: }
1079: else {
1080: if (n->tp->base!=COBJ && n->tp->base!=EOBJ) {
1081: error( 'i', "hidden%n:%t",n,n->tp );
1082: goto gettok;
1083: }
1084:
1085: if ( tk2 == LC || tk2 == COLON ) {
1086: // class declared and hidden but not yet defined
1087: // may have ctor defined which invalidates hiding
1088: statStat = n;
1089: n->n_key = 0; // inside class definition it cannot be hidden
1090: }
1091: }
1092: yylval.pn = nstd?nstd:n;
1093: }
1094: else {
1095: tk = ID;
1096: yylval.pn = new name( s );
1097: }
1098:
1099: if ( tk == ID )
1100: {
1101: switch ( tk2 ) {
1102: case ID: case TNAME: case AGGR: case ENUM:
1103: {
1104: Pname n = 0;
1105:
1106: if ((curr_scope||ccl) && nstd) {
1107: // within class scope in which nested class is visible
1108: // curr_scope == set by TSCOPE, X::foo() { ... }
1109: // ccl == parsing class definition ``ccl''
1110:
1111: char *str = curr_scope?curr_scope->string:ccl->string;
1112: for (Pname nn=nstd; nn; nn=nn->n_tbl_list) {
1113: Ptype tt = (nn->tp->base==COBJ || nn->tp->base==EOBJ)
1114: ? Pbase(nn->tp)->b_name->tp : nn->tpdef;
1115: Pclass cl = tt->in_class;
1116: if ( nn->n_key != NESTED ) continue;
1117: if ( strcmp(str,cl->string) == 0){
1118: tk = TNAME;
1119: yylval.pn = nn;
1120: if (lasttk == TYPE &&
1121: lastval.t == TYPEDEF )
1122: in_typedef = yylval.pn->tp;
1123: break;
1124: }
1125: }
1126: }
1127: if (tk == TNAME) break; // found nested class
1128:
1129: n = ktbl->look( s, HIDDEN );
1130: if ( n ) {
1131: Pname nn = n;
1132: switch ( n->tp->base ) {
1133: default:
1134: error("typedef %sis not visible in this scope", s );
1135: break;
1136: case COBJ:
1137: if (is_empty(Pclass(Pbase(n->tp)->b_name->tp)))
1138: n = check_nested_type( nn );
1139: if (nn == n)
1140: error("%sis hidden: use struct %s%s", s,s,front->retval.s);
1141: break;
1142: case EOBJ:
1143: if (is_empty(Penum(Pbase(n->tp)->b_name->tp)))
1144: n = check_nested_type( nn );
1145: if (nn == n)
1146: error("%sis hidden: use enum %s%s", s,s,front->retval.s);
1147: break;
1148: };
1149: tk = TNAME;
1150: yylval.pn = n;
1151: }
1152: else
1153: if (n=ktbl->look(s,NESTED))
1154: {
1155: TOK ntk;
1156: bit ok = 0;
1157: Ptype tt = return_nstd_local_type(n,ntk);
1158: Pclass cl = tt->in_class;
1159: if (ccl) {
1160: // x::y unncessary with in_class,
1161: // a derived class of in_class
1162: // or classes enclosing in_class
1163: if (ccl==cl || ccl->has_base(cl))
1164: ok++;
1165: else {
1166: for (Pclass eccl=ccl->in_class;eccl; eccl=eccl->in_class)
1167: if ( eccl == cl ) { ok++; break; }
1168: }
1169: }
1170: if (!ok)
1171: error('w', "use %t:: to access nested %k %s (anachronism)", cl, ntk, n->string );
1172: tk = TNAME;
1173: yylval.pn = n;
1174: }
1175: else { // probably a typo
1176: if ( tk2 == ID )
1177: error("%s%s: %sis not aTN", s,front->retval.s,s);
1178: else if ( tk2 == TNAME )
1179: error("%s%s: %sis not aTN", s,front->retval.pn->string,s);
1180: else
1181: error("%s%k: %sis not aTN", s,front->retval.t,s);
1182: goto gettok;
1183: }
1184: break;
1185: }
1186: case DOT: case REF:
1187: mem_sel = yylval.pn;
1188: break;
1189: default:
1190: if ( lasttk == TNAME && tk2 == LC )
1191: {
1192: error("T%s %k: %s is unexpected", s, tk2, s );
1193: goto gettok;
1194: }
1195:
1196: // have an ID. lets just make sure it should not be a TNAME
1197: if (curr_scope||ccl||nstd) {
1198: if (ccl && in_typedef &&
1199: in_typedef->base != 0 &&
1200: in_mem_fct == 0 &&
1201: (tk2 == SM || tk2 == RP || tk2 == LB))
1202: {
1203: yylval.pn = do_nested_type( yylval.pn );
1204: tk = TNAME;
1205: }
1206: else
1207: if (nstd && must_be_id == 0 && in_expr == 0) {
1208: // error('d',"nstd: %n must_be_id 0 have id tk2: %k lasttk: %k",nstd,tk2,lasttk);
1209: // error('d',"nstd: in_expr %d lex_level %d",in_expr,lex_level);
1210: Pclass xcl = curr_scope?Pclass(Pbase(curr_scope->tp)->b_name->tp):(ccl?ccl:0);
1211: for (Pname nn=nstd; nn; nn=nn->n_tbl_list) {
1212: TOK ntk;
1213: bit ok = 0;
1214: Ptype tt = return_nstd_local_type(nn,ntk);
1215: Pclass cl = tt->in_class;
1216: // error('d',"xcl: %t ccl: %t", xcl, ccl );
1217: if ( xcl ) {
1218: if (xcl==cl || xcl->has_base(cl) || ccl == cl)
1219: ok++;
1220: else {
1221: for (Pclass eccl=xcl->in_class;eccl;eccl=eccl->in_class)
1222: if ( eccl == cl ) { ok++; break; }
1223: }
1224: }
1225:
1226: if (nn == nstd)
1227: {
1228: if (
1229: // special case: foo(X,
1230: // in_arg_list not set until **after** X is handled
1231: ((in_arg_list || lasttk==LP) && // foo(nestedX
1232: (tk2==CM || tk2==ASSIGN ||
1233: (tk2==RP && lasttk!=MUL && lasttk!=REF)))
1234: || // class x : public nestedX
1235: (tk2==LC && (lasttk==PR || lasttk==VIRTUAL))
1236: || // nestedX [*&]
1237: (tk2 == MUL || tk2==AND)
1238: || (lasttk==LP && tk2==RP)
1239: || (lasttk==TSCOPE && lastval.pn == nn)
1240: || (lasttk==COMPL && dtor_seen == nn)
1241: || (lasttk==TYPE && lastval.t == TYPEDEF)
1242: || lasttk == OPERATOR
1243: || lasttk == NEW || in_sizeof )
1244: { // must be type name, and it must be nested:
1245: if ( nstd->n_tbl_list == 0 ) { // only one: ok
1246: if (lasttk != TSCOPE && !ok )
1247: error('w', "use %t:: to access nested %k %s (anachronism)", cl, ntk, nn->string);
1248: break;
1249: }
1250: else {
1251: if (lasttk != TSCOPE && !ok){
1252: error("ambiguous nested type %s, use X::%s",nn->string,nn->string);
1253: error( 'i', "cannot recover from previous errors" );
1254: }
1255: }
1256: }
1257:
1258: }
1259: if ( nn->n_key != NESTED ) continue;
1260: if (xcl &&
1261: strcmp(xcl->string,cl->string) == 0) break;
1262: } // end: for nn = nstd
1263:
1264: if (nn) {
1265: tk = TNAME;
1266: yylval.pn = nn;
1267: if (lasttk == TYPE &&
1268: lastval.t == TYPEDEF )
1269: in_typedef = yylval.pn->tp;
1270: }
1271: } // end: if (nstd)
1272: } // end: if (curr_scope||ccl)
1273: break;
1274: } // end: switch tk2
1275: } // end: if (tk == ID)
1276: }
1277:
1278: // error('d',"testing for in_expr: in_expr: %d tk: %k", in_expr, tk );
1279: // error('d',"testing for in_expr: tk2: %k lasttk: %k", tk2, lasttk );
1280: if (lex_level && tk==ID && tk2==LP &&
1281: (lasttk==LC || lasttk==RC || lasttk==RP ||
1282: lasttk == ASSIGN || lasttk == SM))
1283: in_expr = 1;
1284: else in_expr = 0;
1285:
1286: }
1287: if ( tk == TNAME || ( tk == TYPE && latype(yylval.t) )
1288: // XXX || tk == TSCOPE || tk == MEM
1289: || tk == REF || tk == DOT || tk == GOTO
1290: || tk == MEMPTR )
1291: // TNAME cannot immediately follow a type name,
1292: // scope operator, right curly, selection, or goto
1293: must_be_id = 1;
1294: else
1295: must_be_id = 0;
1296:
1297: switch ( tk ) {
1298: case SM:
1299: mem_sel = 0; // no break
1300: in_expr = 0;
1301: case RP: case RC: must_be_expr = 0; break;
1302: case COLON:
1303: if (lasttk == RP ||
1304: (lasttk == TYPE && lastval.t == CONST))
1305: must_be_expr = 1;
1306: break;
1307: case SIZEOF:
1308: in_sizeof = 1;
1309: break;
1310: };
1311: ret:
1312: if ( tk == COMPL && lasttk == TSCOPE )
1313: dtor_seen = lastval.pn;
1314: else dtor_seen = 0;
1315: lasttk = tk;
1316: lastval = yylval;
1317: LDB(1,showQ("after");
1318: fprintf(stderr,"returning '%s'",image(tk));
1319: if ( tk==ID || tk==TNAME ) fprintf(stderr," -- '%s'",yylval.pn->string);
1320: fprintf(stderr,"\n");
1321: );
1322: // error('d',"returning tk: %k dtor_seen: %n", tk,dtor_seen );
1323: return tk;
1324: }
1325:
1326: extern void
1327: la_backup( TOK t, YYSTYPE r )
1328: /*
1329: called by parser to push token back on front of queue
1330: */
1331: {
1332: LDB(1,fprintf(stderr,"\n*** la_backup( '%s', ...)\n",image(t)));
1333: if ( t == ID ) { Pname n = r.pn; r.s = n->string; DEL(n); }
1334: register toknode* T = new toknode(t,r,curloc);
1335: if (front) {
1336: front->last = T;
1337: T->next = front;
1338: T->last = 0;
1339: front = T;
1340: } else
1341: front = rear = T;
1342: lasttk = 0;
1343: }
1344:
1345: extern int
1346: la_sctype( TOK t )
1347: {
1348: //error('d',&latok->place,"la_sctype(%k ) -- latok ==%k",t,latok->tok);
1349: if ( t != latok->tok && t != TSCOPE && t != MEMPTR )
1350: error( 'i', &latok->place, "la_sctype, lalex.c" );
1351:
1352: switch( latok->retval.t ) {
1353: case TYPEDEF:
1354: case EXTERN:
1355: case STATIC:
1356: case AUTO:
1357: case REGISTER:
1358: case OVERLOAD:
1359: case INLINE:
1360: case FRIEND:
1361: case CONST:
1362: case VOLATILE:
1363: return 1;
1364: default:
1365: return 0;
1366: }
1367: }
1368:
1369: extern int
1370: la_cast()
1371: /*
1372: called in reduction of term_lp to check for ambiguous prefix-style cast
1373: if result is 1, caller inserts DECL_MARKER to force reduction of cast
1374: */
1375: {
1376: // yychar already designates TYPE or TNAME
1377: // LP must start the lookahead queue!
1378: LDB(1,fprintf(stderr,"\n*** la_cast()\n"););
1379: int tk, tk2 = latok->tok;
1380:
1381: for ( ; ; ) {
1382: tk = tk2;
1383: tk2 = lookahead();
1384:
1385: switch( tk ) {
1386: case LP:
1387: if ( tk2 == MUL || tk2 == AND ||
1388: tk2 == TSCOPE || tk2 == MEMPTR )
1389: // T ( * ...
1390: // T ( C ::* ...
1391: continue;
1392: else
1393: // T ( exp )
1394: return 0;
1395: case MUL: case AND:
1396: //if ( tk2 == SCTYPE )
1397: if ( la_sctype( tk2 ) )
1398: // T ( * const ...
1399: // T ( * volatile ...
1400: tk2 = lookahead();
1401: continue;
1402: case TSCOPE:
1403: if ( tk2 == MUL )
1404: // T ( C :: * ...
1405: continue;
1406: else
1407: // T ( exp )
1408: return 0;
1409: case RP: case LB:
1410: // T (*)()
1411: // T (*[])()
1412: return 1;
1413: case MEMPTR:
1414: if ( tk2 == RP )
1415: continue;
1416: }
1417:
1418: return 0;
1419: }
1420: }
1421:
1422: static int
1423: la_decl()
1424: /*
1425: handles ambiguities
1426: type (*x) ()
1427: type (*x) []
1428: at start of arg list / statement
1429: return val == 1 if lookahead finds a declaration
1430: (used for error messages only)
1431: if declaration is "ambiguous" (i.e., can't be recognized with
1432: 1-symbol lookahead), insert DECL_MARKER to force reduction
1433: of "type"
1434: */
1435: {
1436:
1437: // LP must start the lookahead queue!
1438: LDB(1,fprintf(stderr,"\n*** la_decl()\n"););
1439: int tk, tk2 = latok->tok;
1440: int paren = 0;
1441: int ptr = 0;
1442:
1443: for ( ; ; ) {
1444:
1445: tk = tk2;
1446: tk2 = lookahead();
1447:
1448: // fprintf(stderr,"\nla_decl:tk:%d %s tk2: %d %s", tk, keys[tk], tk2, keys[tk2]);
1449: switch( tk ) {
1450: case LP:
1451: if ( tk2 == MUL || tk2 == AND || tk2 == TSCOPE ) {
1452: // T ( * ...
1453: ++paren;
1454: ptr = 1;
1455: continue;
1456: } else
1457: if ( tk2 == MEMPTR ) {
1458: // T ( C ::* ...
1459: return 1;
1460: } else
1461: // possible redundant parens
1462: if ( tk2 == ID && lookahead() == RP ) {
1463: TOK tp = lookahead();
1464: // error( 'd', "tp %k tk: %k tk2: %k", tp, tk, tk2 );
1465: // error( 'd', "bl_level: %d, in_class_decl: %d", bl_level,in_class_decl );
1466: if ( tp == SM || tp == CM || tp == ASSIGN )
1467: {
1468: // member initialization list
1469: if ( tp != SM && in_arg_list == 0 ) return 1;
1470: }
1471: else
1472: if ( tp == RP && (bl_level-in_class_decl==0))
1473: return 1;
1474: if ( tp != LP )
1475: return 0;
1476: latok=latok->last; // restore lookahead
1477: ++paren;
1478: continue;
1479: }
1480: else
1481: // T ( exp )
1482: return 0;
1483: case MUL: case AND:
1484: //if ( tk2 == SCTYPE )
1485: if ( la_sctype( tk2 ))
1486: // T ( * const ...
1487: // T ( * volatile ...
1488: return 1;
1489: else {
1490: ptr = 0;
1491: continue;
1492: }
1493: case MEMPTR:
1494: // T ( C :: * ...
1495: return 1;
1496: case TSCOPE:
1497: if ( tk2 == MUL ) //??tk SHOULD HAVE TRANSLATED TO MEMPTR!!
1498: // T ( C :: * ...
1499: return 1;
1500: else if ( ptr )
1501: // T ( exp )
1502: return 0;
1503: else if ( tk2 == ID || tk2 == OPERATOR )
1504: // T ( * C :: id ...
1505: continue;
1506: else
1507: // error
1508: return 0;
1509: }
1510:
1511: break;
1512: }
1513:
1514: if ( tk == RP || tk == LB )
1515: // T (*)()
1516: // T (*[])()
1517: return 1;
1518:
1519: if ( tk != ID && tk != OPERATOR )
1520: // T ( exp )
1521: return 0;
1522:
1523: if ( tk == OPERATOR )
1524: switch ( tk2 ) {
1525: case PLUS: case MINUS: case MUL: case REFMUL:
1526: case AND: case OR: case ER: case SHIFTOP: case EQUOP:
1527: case DIVOP: case RELOP: case ANDAND: case OROR:
1528: case NOT: case COMPL: case ICOP: case ASSIGN:
1529: case ASOP: case NEW: case GNEW: case DELETE:
1530: // OPERATOR oper
1531: tk2 = lookahead();
1532: break;
1533: case LP:
1534: // OPERATOR ()
1535: tk2 = lookahead();
1536: if ( tk2 == RP ) {
1537: tk2 = lookahead();
1538: break;
1539: } else
1540: return 0;
1541: case LB:
1542: // OPERATOR []
1543: tk2 = lookahead();
1544: if ( tk2 == LB ) {
1545: tk2 = lookahead();
1546: break;
1547: } else
1548: return 0;
1549: default: // illegal operator
1550: return 0;
1551: }
1552:
1553: int allow_lp = 1;
1554: int allow_rp = 1;
1555: for ( ; ; ) {
1556: tk = tk2;
1557: tk2 = lookahead();
1558:
1559: // fprintf(stderr,"\nla_decl2:tk:%d %s tk2: %d %s", tk, keys[tk], tk2, keys[tk2]);
1560: switch( tk ) {
1561: case LP:
1562: if ( !allow_lp )
1563: // T ( * id [ exp ] ( ...
1564: return 0;
1565:
1566: // Current lookahead will be a decl if
1567: // the next lookahead is an arg decl
1568: if ( tk2 == RP || tk2 == ENUM || tk2==AGGR
1569: || tk2==ELLIPSIS || la_sctype( tk2 ))
1570: // T ( * id ()
1571: // T ( * id ) ()
1572: return 1;
1573:
1574: if ( tk2 == TYPE || tk2 == TNAME ) {
1575: // T ( * id ) ( T2 ...
1576: if ( lookahead() == LP && !la_decl() )
1577: return 0;
1578: return 1;
1579: }
1580:
1581: return 0;
1582: case LB:
1583: if ( tk2 == RB || lookahead() == RB )
1584: // T ( * id [] ...
1585: return 1;
1586: else {
1587: // T ( * id [ exp ] ...
1588: allow_lp = 0;
1589: allow_rp = 1;
1590: while ( lookahead() != RB );
1591: tk2 = lookahead();
1592: continue;
1593: }
1594: case RP:
1595: // error ('d', "rp: allow_rp: %d paren: %d", allow_rp, paren );
1596: if ( !allow_rp || !paren )
1597: // T ( * id ) )
1598: return 0;
1599: // permit redundant parentheses
1600: else
1601: if ( tk2 == SM || tk2 == CM || tk2 == ASSIGN )
1602: return 1;
1603: else
1604: if ( tk2 == RP && (bl_level-in_class_decl == 0))
1605: return 1;
1606: else
1607: {
1608: // T ( * id ) ...
1609: allow_lp = 1;
1610: allow_rp = 0;
1611: --paren;
1612: continue;
1613: }
1614: default:
1615: return 0;
1616: }
1617: }
1618: }
1619:
1620:
1621:
1622: /*
1623: ** PROCESSING OF INLINE MEMBER FUNCTIONS
1624: */
1625: static int la_snarf();
1626:
1627: extern toknode*
1628: save_text()
1629: /*
1630: save text of inline def on q of class
1631: */
1632: {
1633: // Q should contain at least the tokens < FDEF, X ... >
1634: // where X is either LC or COLON (start of ftn)
1635: LDB(2,fprintf(stderr,"save_text()"));
1636: LDB(3,fprintf(stderr,"front: %s",image(front->tok)));
1637: LDB(3,fprintf(stderr,"front->next: %s",image(front->next->tok)));
1638: latok = front->next;
1639: if ( la_snarf() ) {
1640: // append this set of tokens to
1641: // inline tokenq for class
1642: toknode* t = front; // FDEF
1643: if ( ccl->c_funqf == 0 )
1644: ccl->c_funqf = front;
1645: else {
1646: ccl->c_funqr->next = front;
1647: front->last = ccl->c_funqr;
1648: }
1649: ccl->c_funqr = latok;
1650: front = latok->next;
1651: latok->next = 0;
1652: if (front) front->last = 0;
1653: return t;
1654: }
1655: return 0;
1656: }
1657:
1658:
1659: extern void
1660: restore_text()
1661: /*
1662: restore tokens for member inlines onto token q
1663: */
1664: {
1665: LDB(2,fprintf(stderr,"restore_text()"));
1666: if (ccl->c_funqf == 0) // no inlines on Q
1667: return;
1668: LDB(3,fprintf(stderr," Q present: %d,%d",ccl->c_funqf,ccl->c_funqr));
1669: LDB(3,fprintf(stderr," front==%s",image(ccl->c_funqf->tok)));
1670: LDB(3,fprintf(stderr," rear ==%s",image(ccl->c_funqr->tok)));
1671: ccl->c_funqr->next = front;
1672: if (front) front->last = ccl->c_funqr;
1673: front = ccl->c_funqf;
1674: ccl->c_funqf = ccl->c_funqr = 0;
1675: }
1676:
1677:
1678: static void
1679: del_tokens( toknode* marker )
1680: /*
1681: delete tokens from marker to latok, not inclusive
1682: */
1683: {
1684: if ( marker == 0 || marker == latok || marker->next == 0 )
1685: error('i', "bad token queue");
1686:
1687: LDB(2,fprintf(stderr,"del_tokens: %s..%s\n",image(marker->tok),image(latok->tok)));
1688:
1689: register toknode* tt = marker->next;
1690: if ( tt == latok ) return;
1691: marker->next = latok;
1692: latok->last->next = 0;
1693: latok->last = marker;
1694: register toknode* tx = tt;
1695: do {
1696: LDB(3,fprintf(stderr," deleting %s\n",image(tt->tok)));
1697: tx = tx->next;
1698: delete tt;
1699: tt = tx;
1700: } while ( tx );
1701: }
1702:
1703:
1704: static int
1705: la_snarf()
1706: /*
1707: scan function def without processing declarations
1708: */
1709: {
1710: LDB(2,fprintf(stderr,"la_snarf()"));
1711: loc *L = &latok->place;
1712: //DBPLACE(1,L.l,L.f);
1713: int parens = 0;
1714: int paren_error = 0;
1715: toknode* marker = latok;
1716: switch ( latok->tok ) {
1717: default:
1718: error('i', L, "bad token Q snarfing function: %d", latok->tok);
1719: case COLON:
1720: break;
1721: case LC:
1722: --bl_level;
1723: goto eatf;
1724: }
1725: LDB(2,fprintf(stderr,"\"eat\" member initializers"));
1726: for (;;) {
1727: if (latok->next == 0) add_tokens();
1728: switch ( (latok=latok->next)->tok ) {
1729: case LP:
1730: ++parens;
1731: default:
1732: LDB(3,fprintf(stderr,"...%s",image(latok->tok)));
1733: continue;
1734: case RP:
1735: if ( (--parens < 0) && (paren_error++ == 0) )
1736: error(0,&latok->place,"unbalanced ()");
1737: continue;
1738: case LC:
1739: case RC:
1740: if ( parens <= 0 )
1741: goto eatf;
1742: continue;
1743: case SM:
1744: if ( parens <= 0 ) {
1745: error(0, L, "illegal bit field");
1746: del_tokens( front );
1747: delete front;
1748: front = latok;
1749: front->last = 0;
1750: return 0;
1751: }
1752: continue;
1753: case EOFTOK:
1754: error('i',&latok->place,"unexpected end of file");
1755: } // switch
1756: } // for
1757:
1758: eatf:
1759: int level = 1;
1760: for (;;) {
1761: if (latok->next == 0) add_tokens();
1762: switch ( (latok=latok->next)->tok ) {
1763: case LC:
1764: ++level;
1765: default:
1766: LDB(3,fprintf(stderr,"...%s",image(latok->tok)));
1767: continue;
1768: case RC:
1769: LDB(3,fprintf(stderr,"...RC"));
1770: if (--level <= 0) {
1771: if (level < 0) {
1772: error(0,&latok->place,"unexpected '}'");
1773: goto bad;
1774: }
1775: return 1;
1776: }
1777: break;
1778: case EOFTOK:
1779: error('e', &latok->place, "unbalanced {}");
1780: goto bad;
1781: } // switch
1782: } // for
1783: bad:
1784: del_tokens( marker );
1785: marker->tok = SM;
1786: return 0;
1787: }
1788:
1789: Pname check_for_nested( Pname nstd, TOK lasttk, YYSTYPE lastval, TOK tk2)
1790: {
1791: // error('d',"nstd: %n must_be_id 0 tk2: %k lasttk: %d",nstd,tk2,lasttk);
1792: TOK tk = ID;
1793: Pclass xcl = curr_scope?Pclass(Pbase(curr_scope->tp)->b_name->tp):(ccl?ccl:0);
1794:
1795: for (Pname nn=nstd; nn; nn=nn->n_tbl_list) {
1796: TOK ntk;
1797: bit ok = 0;
1798: Ptype tt = return_nstd_local_type(nn,ntk);
1799: Pclass cl = tt->in_class;
1800: if ( xcl ) {
1801: if (xcl==cl || xcl->has_base(cl))
1802: ok++;
1803: else {
1804: for (Pclass eccl=xcl->in_class;eccl;eccl=eccl->in_class)
1805: if ( eccl == cl ) { ok++; break; }
1806: }
1807: }
1808:
1809: if (nn == nstd)
1810: {
1811: if ( ((in_arg_list || lasttk==LP) && // foo(nestedX
1812: (tk2==CM || tk2==ASSIGN || tk2==RP))
1813: || (tk2==LC && (lasttk==PR || lasttk==VIRTUAL))
1814: || (tk2 == MUL || tk2==AND)
1815: || (lasttk==LP && tk2==RP)
1816: || (lasttk==TSCOPE && lastval.pn == nn)
1817: || (lasttk==COMPL && dtor_seen == nn)
1818: || (lasttk==TYPE && lastval.t == TYPEDEF)
1819: || lasttk == NEW || in_sizeof )
1820: {
1821: if ( nstd->n_tbl_list == 0 ) { // only one: ok
1822: break;
1823: } else {
1824: if (lasttk != TSCOPE && !ok){
1825: error("ambiguous nested type %s, use X::%s",nn->string,nn->string);
1826: error( 'i', "cannot recover from previous errors" );
1827: }
1828: }
1829: }
1830: }
1831: if ( nn->n_key != NESTED ) continue;
1832: if (xcl && strcmp(xcl->string,cl->string) == 0) break;
1833: } // end: for nn = nstd
1834: return nn;
1835: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.