Annotation of researchv10no/cmd/cfront/ocfront/lalex.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.