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

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

unix.superglobalmegacorp.com

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