Annotation of gcc/cp-spew.c, revision 1.1.1.2

1.1       root        1: /* Type Analyzer for GNU C++.
                      2:    Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
                      3:    Hacked... nay, bludgeoned... by Mark Eichin ([email protected])
                      4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU General Public License as published by
                      9: the Free Software Foundation; either version 2, or (at your option)
                     10: any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful,
                     13: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: GNU General Public License for more details.
                     16: 
                     17: You should have received a copy of the GNU General Public License
                     18: along with GNU CC; see the file COPYING.  If not, write to
                     19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: 
                     22: /* This file is the type analyzer for GNU C++.  */
                     23: 
                     24: #include "config.h"
                     25: #include <stdio.h>
                     26: #include "input.h"
                     27: #include "tree.h"
                     28: #include "cp-lex.h"
                     29: #include "cp-parse.h"
                     30: #include "cp-tree.h"
                     31: #include "flags.h"
                     32: #include "obstack.h"
                     33: #include <assert.h>
                     34: 
                     35: /* This takes a token stream that hasn't decided much about types and
                     36:    tries to figure out as much as it can, with excessive lookahead and
                     37:    backtracking. */
                     38: 
                     39: /* fifo of tokens recognized and available to parser. */
                     40: struct token  {
                     41:   /* The values for YYCHAR will fit in a short.  */
                     42:   short                yychar;
                     43:   short                end_of_file;
                     44:   YYSTYPE      yylval;
                     45: };
                     46: 
                     47: static int do_aggr ();
                     48: static struct token frob_identifier ();
                     49: static struct token hack_scope ();
                     50: static tree hack_ptype ();
                     51: static tree hack_more_ids ();
                     52: 
                     53: /* From cp-lex.c: */
                     54: /* the declaration found for the last IDENTIFIER token read in.
                     55:    yylex must look this up to detect typedefs, which get token type TYPENAME,
                     56:    so it is left around in case the identifier is not a typedef but is
                     57:    used in a context which makes it a reference to a variable.  */
                     58: extern tree lastiddecl;                /* let our brains leak out here too */
                     59: extern int     yychar;         /*  the lookahead symbol                */
                     60: extern YYSTYPE yylval;         /*  the semantic value of the           */
                     61:                                /*  lookahead symbol                    */
                     62: extern int end_of_file;
                     63: 
                     64: struct obstack token_obstack;
                     65: int first_token;
                     66:   
                     67: /* #define SPEW_DEBUG */
                     68: #ifdef SPEW_DEBUG
                     69: static int spew_debug = 0;
                     70: static int yylex_ctr = 0;
                     71: #endif
                     72: 
1.1.1.2 ! root       73: static char follows_typename[END_OF_SAVED_INPUT+1];
        !            74: static char follows_identifier[END_OF_SAVED_INPUT+1];
1.1       root       75: 
                     76: /* Initialize token_obstack. Called once, from init_lex.  */
                     77: void
                     78: init_spew ()
                     79: {
                     80:   static char *chars_following_identifier = ".+-|/%^!?:";
                     81:   short *ps;
                     82:   char *pc;
                     83:   static short toks_follow_ids[] =
                     84:     { POINTSAT_LEFT_RIGHT, ASSIGN, RANGE, OROR, ANDAND, MIN_MAX, EQCOMPARE,
                     85:       ARITHCOMPARE, LSHIFT, RSHIFT, UNARY, PLUSPLUS, MINUSMINUS, POINTSAT,
                     86:       POINTSAT_STAR, DOT_STAR, CONSTANT, STRING, SIZEOF, ENUM, IF,
                     87:       ELSE, WHILE, DO, FOR, SWITCH, CASE, DEFAULT, BREAK, CONTINUE,
1.1.1.2 ! root       88:       RETURN, GOTO, ASM_KEYWORD, TYPEOF, ALIGNOF, HEADOF, CLASSOF, ATTRIBUTE,
1.1       root       89:       AGGR, VISSPEC, DELETE, RAISE, RERAISE, TRY, EXCEPT, CATCH,
                     90:       THROW, ANSI_TRY, ANSI_THROW, EXTERN_LANG_STRING, ALL,
                     91:       END_OF_SAVED_INPUT, -1 };
                     92:   static char *chars_following_typename = "(";
                     93:   static short toks_follow_types[] =
                     94:     { IDENTIFIER, TYPENAME, SCOPED_TYPENAME, SCSPEC, TYPESPEC, TYPE_QUAL,
                     95:       ELLIPSIS, THIS, OPERATOR, DYNAMIC, TEMPLATE, SCOPE, START_DECLARATOR,
                     96:       TYPENAME_COLON, PAREN_STAR_PAREN, TYPENAME_ELLIPSIS, PTYPENAME,
                     97:       PRE_PARSED_FUNCTION_DECL, PRE_PARSED_CLASS_DECL, -1 };
                     98: 
                     99:   gcc_obstack_init(&token_obstack);
                    100: 
                    101:   /* Initialize the arrays saying what tokens are definitely
                    102:      (or possibly) valid following typenames and identifiers.  */
                    103:   while (*chars_following_identifier)
                    104:     follows_identifier[*chars_following_identifier++] = 1;
                    105:   for (ps = toks_follow_ids; *ps != -1; ps++)
                    106:     follows_identifier[*ps] = 1;
                    107:   for (ps = toks_follow_types; *ps != -1; ps++)
                    108:     follows_typename[*ps] = 1;
                    109: }
                    110: 
                    111: #ifdef SPEW_DEBUG
                    112: /* Use functions for debugging...  */
                    113: 
                    114: /* Return the number of tokens available on the fifo. */
                    115: static int
                    116: num_tokens ()
                    117: {
                    118:   return (obstack_object_size(&token_obstack)/sizeof(struct token))
                    119:     - first_token;
                    120: }
                    121: 
                    122: /* Fetch the token N down the line from the head of the fifo. */
                    123: static struct token*
                    124: nth_token (n)
                    125:      int n;
                    126: {
                    127:   /* could just have this do slurp_ implicitly, but this way is easier
                    128:    * to debug... */
                    129:   assert (n < num_tokens());
                    130:   return ((struct token*)obstack_base(&token_obstack))+n+first_token;
                    131: }
                    132: 
                    133: /* Add a token to the token fifo. */
                    134: static void
                    135: add_token (t)
                    136:      struct token* t;
                    137: {
                    138:   obstack_grow(&token_obstack,t,sizeof (struct token));
                    139: }
                    140: 
                    141: /* Consume the next token out of the fifo.  */
                    142: static void
                    143: consume_token()
                    144: {
                    145:   if (num_tokens() == 1)
                    146:     {
                    147:       obstack_free(&token_obstack, obstack_base (&token_obstack));
                    148:       first_token = 0;
                    149:     }
                    150:   else
                    151:     first_token++;
                    152: }
                    153: 
                    154: #else
                    155: /* ...otherwise use macros.  */
                    156: 
                    157: #define num_tokens() \
                    158:   ((obstack_object_size(&token_obstack)/sizeof(struct token)) - first_token)
                    159: 
                    160: #define nth_token(N) \
                    161:   (((struct token*)obstack_base(&token_obstack))+(N)+first_token)
                    162: 
                    163: #define add_token(T) obstack_grow(&token_obstack, (T), sizeof (struct token))
                    164: 
                    165: #define consume_token() \
                    166:   (num_tokens() == 1                                                   \
                    167:    ? (obstack_free (&token_obstack, obstack_base (&token_obstack)),    \
                    168:       (first_token = 0))                                               \
                    169:    : first_token++)
                    170: #endif
                    171: 
                    172: /* Pull in enough tokens from real_yylex that the queue is N long.  */
                    173: 
                    174: static void
                    175: scan_tokens (n)
                    176:      int n;
                    177: {
                    178:   int i;
                    179:   struct token *tmp;
                    180: 
                    181:   /* We cannot read past certain tokens, so make sure we don't.  */
                    182:   i = num_tokens ();
                    183:   if (i > n)
                    184:     return;
                    185:   while (i-- > 0)
                    186:     {
                    187:       tmp = nth_token (i);
                    188:       /* Never read past these characters: they might separate
                    189:         the current input stream from one we save away later.  */
                    190:       if (tmp->yychar == '{' || tmp->yychar == ':')
                    191:        goto pad_tokens;
                    192:     }
                    193: 
                    194:   while (num_tokens() <= n)
                    195:     {
                    196:       obstack_blank(&token_obstack,sizeof (struct token));
                    197:       tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
                    198:       tmp->yychar = real_yylex();
                    199:       tmp->end_of_file = end_of_file;
                    200:       tmp->yylval = yylval;
                    201:       end_of_file = 0;
                    202:       if (tmp->yychar == '{'
                    203:          || tmp->yychar == ':'
                    204:          || tmp->yychar == ';')
                    205:        {
                    206:        pad_tokens:
                    207:          while (num_tokens () <= n)
                    208:            {
                    209:              obstack_blank(&token_obstack,sizeof (struct token));
                    210:              tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
                    211:              tmp->yychar = EMPTY;
                    212:              tmp->end_of_file = 0;
                    213:            }
                    214:        }
                    215:     }
                    216: }
                    217: 
                    218: /* Create room for N tokens at the front of the fifo.  This is used
                    219:    to insert new tokens into the stream ahead of the current token.  */
                    220: 
                    221: static void
                    222: shift_tokens (n)
                    223:      int n;
                    224: {
                    225:   if (first_token >= n)
                    226:     first_token -= n;
                    227:   else
                    228:     {
                    229:       int old_token_count = num_tokens ();
                    230:       char *tmp;
                    231: 
                    232:       obstack_blank (&token_obstack, (n-first_token) * sizeof (struct token));
                    233:       tmp = (char *)alloca ((num_tokens () + (n-first_token))
                    234:                            * sizeof (struct token));
                    235:       /* This move does not rely on the system being able to handle
                    236:         overlapping moves.  */
                    237:       bcopy (nth_token (0), tmp, old_token_count * sizeof (struct token));
                    238:       bcopy (tmp, nth_token (n), old_token_count * sizeof (struct token));
                    239:       first_token = 0;
                    240:     }
                    241: }
                    242: 
                    243: int
                    244: probe_obstack (h, obj, nlevels)
                    245:      struct obstack *h;
                    246:      tree obj;
                    247:      unsigned int nlevels;
                    248: {
                    249:   register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
                    250:   register struct _obstack_chunk*  plp;        /* point to previous chunk if any */
                    251: 
                    252:   lp = (h)->chunk;
                    253:   /* We use >= rather than > since the object cannot be exactly at
                    254:      the beginning of the chunk but might be an empty object exactly
                    255:      at the end of an adjacent chunk. */
                    256:   for (; nlevels > 0 && lp != 0 && ((tree)lp >= obj || (tree)lp->limit < obj);
                    257:        nlevels -= 1)
                    258:     {
                    259:       plp = lp->prev;
                    260:       lp = plp;      
                    261:     }
                    262:   return nlevels > 0 && lp != 0;
                    263: }
                    264: 
                    265: /* from cp-lex.c: */
                    266: /* Value is 1 if we should try to make the next identifier look like a
                    267:    typename (when it may be a local variable or a class variable).
                    268:    Value is 0 if we treat this name in a default fashion.
                    269:    Value is -1 if we must not see a type name.  */
                    270: extern int looking_for_typename;
                    271: 
                    272: extern struct obstack *current_obstack, *saveable_obstack;
                    273: 
                    274: int
                    275: yylex()
                    276: {
                    277:   struct token tmp_token;
                    278:   tree t2;
                    279:   tree dk, trrr;
                    280: 
                    281:  retry:
                    282: #ifdef SPEW_DEBUG
                    283:   if (spew_debug)
                    284:   {
                    285:     yylex_ctr ++;
                    286:     fprintf(stderr, "\t\t## %d ##",yylex_ctr);
                    287:   }
                    288: #endif
                    289:   
                    290:   /* if we've got tokens, send them */
                    291:   if (num_tokens())
                    292:     {
                    293:       tree tmp;
                    294:       tmp_token= *nth_token(0);
                    295: 
                    296:       /* TMP_TOKEN.YYLVAL.TTYPE may have been allocated on the wrong obstack.
                    297:         If we don't find it in CURRENT_OBSTACK's current or immediately
                    298:         previous chunk, assume it was and copy it to the current obstack.  */
                    299:       if ((tmp_token.yychar == CONSTANT
                    300:           || tmp_token.yychar == STRING)
                    301:          && ! TREE_PERMANENT (tmp_token.yylval.ttype)
                    302:          && ! probe_obstack (current_obstack, tmp_token.yylval.ttype, 2)
                    303:          && ! probe_obstack (saveable_obstack, tmp_token.yylval.ttype, 2))
                    304:        tmp_token.yylval.ttype = copy_node (tmp_token.yylval.ttype);
                    305:     }
                    306:   else
                    307:     {
                    308:       /* if not, grab the next one and think about it */
1.1.1.2 ! root      309:       tmp_token.yychar = real_yylex ();
1.1       root      310:       tmp_token.yylval = yylval;
1.1.1.2 ! root      311:       tmp_token.end_of_file = end_of_file;
1.1       root      312:       add_token(&tmp_token);
                    313:     }
                    314: 
                    315:   /* many tokens just need to be returned. At first glance, all we
                    316:    * have to do is send them back up, but some of them are needed to
                    317:    * figure out local context. */
                    318:   switch(tmp_token.yychar)
                    319:     {
                    320:     case EMPTY:
                    321:       /* This is a lexical no-op.  */
                    322:       consume_token ();
                    323: #ifdef SPEW_DEBUG    
                    324:       if (spew_debug)
                    325:        debug_yychar (tmp_token.yychar);
                    326: #endif
                    327:       goto retry;
                    328: 
                    329:     case IDENTIFIER:
                    330:       /* Note: this calls arbitrate_lookup.  */
                    331:       trrr = lookup_name (tmp_token.yylval.ttype, -1);
                    332:       if (trrr)
                    333:        {
                    334:          tmp_token.yychar = identifier_type (trrr);
                    335:          switch (tmp_token.yychar)
                    336:            {
                    337:            case TYPENAME:
                    338:              lastiddecl = IDENTIFIER_TYPEDECL_VALUE (tmp_token.yylval.ttype);
                    339:              break;
                    340:            case IDENTIFIER:
                    341:              lastiddecl = trrr;
                    342:              break;
                    343:            case PTYPENAME:
                    344:              /* This is for cases like
                    345:                    template<class A> X<A>::operator[] ...
                    346:                 since "X" is (presumably) a PTYPENAME; we might want to
                    347:                 avoid seeing the entire thing as a type name, but X<A>
                    348:                 must be one.
                    349: 
                    350:                 It might not work right if the thing after the ::
                    351:                 can be a typename nested in X<A>, but I don't think the
                    352:                 PT code would be up to dealing with that anyways.  --KR  */
                    353:              if (looking_for_typename == -1)
                    354:                {
                    355:                  scan_tokens (2);
                    356:                  if (nth_token(1)->yychar == '<')
                    357:                    looking_for_typename = 0;
                    358:                }
                    359:              break;
                    360:            default:
                    361:              abort ();
                    362:            }
                    363:        }
                    364:       else
                    365:        lastiddecl = trrr;
                    366:       /* and fall through to... */
                    367:     case TYPENAME:
                    368:     case PTYPENAME:
                    369:       /* if (new_token) add_token (&tmp_token); */
                    370:       *nth_token(0) = tmp_token;
                    371:       tmp_token = frob_identifier ();
                    372:       if (looking_for_typename < 0)
                    373:        {
                    374:          tmp_token.yychar = IDENTIFIER;
                    375:          lastiddecl = 0;
                    376:          looking_for_typename = 0;
                    377:        }
                    378:       else if (lastiddecl && TREE_CODE (lastiddecl) == TYPE_DECL)
                    379:        {
                    380:          scan_tokens (2);
                    381:          if (nth_token(0)->yychar == IDENTIFIER
                    382:              && nth_token (1)->yychar != SCOPE)
                    383:            looking_for_typename = -1;
                    384:          else
                    385:            looking_for_typename = 0;
                    386:          goto finish_typename_processing;
                    387:        }
                    388:       else
                    389:        looking_for_typename = 0;
                    390:       break;
                    391: 
                    392:     case TYPESPEC:
                    393:     case SCSPEC:
                    394:       consume_token ();
                    395:     finish_typename_processing:
                    396:       /* Now see if we should insert a START_DECLARATOR token.
                    397:          Here are the cases caught:
                    398: 
                    399:         typespec ( * ID ) (    // ptr to function
                    400:         typespec ( & ID ) (    // ref to function
                    401:         typespec ( * ID ) [    // array of pointers
                    402:         typespec ( & ID ) [    // array of references
                    403: 
                    404:         This is a terrible kludge.  */
                    405: 
                    406:       scan_tokens (2);
                    407:       if (nth_token (0)->yychar == '('
                    408:          && (nth_token (1)->yychar == '*'
                    409:              || nth_token (1)->yychar == '&'))
                    410:        {
                    411:          scan_tokens (5);
                    412:          if (nth_token (3)->yychar == ')'
                    413:              && (nth_token (4)->yychar == '('
                    414:                  || nth_token (4)->yychar == '['
                    415:                  || nth_token (4)->yychar == LEFT_RIGHT)
                    416:              && (nth_token (2)->yychar == IDENTIFIER
                    417:                  || nth_token (2)->yychar == TYPENAME))
                    418:            {
                    419:              shift_tokens (1);
                    420:              nth_token (0)->yychar = START_DECLARATOR;
                    421:            }
                    422:        }
                    423:       break;
                    424: 
                    425: #if 0
                    426:     case '(':
                    427:       /* Handle casts.  We are looking for one of:
                    428:          `( TYPENAME' followed by `)', or
                    429:         `( TYPENAME *' followed by one of `[,*,&,)', or
                    430:         `( TYPENAME &' followed by one of `[,*,&,)', or
                    431:         `( TYPENAME [' followed by `]'.  We are punting
                    432:         generality on scanning casts to array types.  */
                    433:       scan_tokens (4);
                    434:       if (nth_token (1)->yychar == IDENTIFIER)
                    435:        {
                    436:          tree type = identifier_typedecl_value (nth_token (1)->yylval.ttype);
                    437:          if (type)
                    438:            switch (nth_token (2)->yychar)
                    439:              {
                    440:              default:
                    441:                break;
                    442:              }
                    443:        }
                    444:       break;
                    445: 
                    446:     case SCOPE:
                    447:       /* if (new_token) add_token (&tmp_token); */
                    448:       *nth_token(0) = tmp_token;
                    449:       tmp_token = hack_scope ();
                    450:       break;
                    451: #endif
                    452: 
                    453:     case AGGR:
                    454:       *nth_token(0) = tmp_token;
                    455:       do_aggr ();
                    456:       /* fall through to output... */
                    457:     case ENUM:
                    458:       /* Set this again, in case we are rescanning.  */
                    459:       looking_for_typename = 1;
                    460:       /* fall through... */
                    461:     default:
                    462: #ifdef SPEW_DEBUG    
                    463:       if (spew_debug)
                    464:        debug_yychar(tmp_token.yychar);
                    465: #endif
                    466:       consume_token();
                    467:       yylval = tmp_token.yylval;
                    468:       yychar = tmp_token.yychar;
                    469:       end_of_file = tmp_token.end_of_file;
                    470:       return tmp_token.yychar;
                    471:     }
                    472: 
                    473:   if (tmp_token.yychar == SCOPED_TYPENAME)
                    474:     {
                    475: #if 0
                    476:       t2 = resolve_scope_to_name (NULL_TREE, tmp_token.yylval.ttype);
                    477:       if (t2)
                    478:        {
                    479:          tmp_token.yylval.ttype = t2;
                    480:          tmp_token.yychar = TYPENAME;
                    481:        }
                    482:       else
                    483:        {
                    484:          /* unwind? */
                    485:        }
                    486:     }
                    487:   else
                    488:     {
                    489:       /* couldn't get here, as is... */
                    490: #endif
                    491:       tmp_token.yychar = TYPENAME;
                    492:     }
                    493: 
                    494:   yylval = tmp_token.yylval;
                    495:   yychar = tmp_token.yychar;
                    496:   end_of_file = tmp_token.end_of_file;
                    497: #ifdef SPEW_DEBUG    
                    498:   if (spew_debug)
                    499:     debug_yychar(yychar);
                    500: #endif
                    501: /*  consume_token(); */ /* already eaten by frob_identifier?... */
                    502:   return yychar;
                    503: }
                    504: 
                    505: /* token[0] == AGGR (struct/union/enum)
                    506:  * thus, token[1] is either a TYPENAME or a TYPENAME_DEFN
                    507:  * if token[2] == '{' or ':' then it's TYPENAME_DEFN
                    508:  */
                    509: static int
                    510: do_aggr ()
                    511: {
                    512:   int yc1, yc2;
                    513:   
                    514:   scan_tokens (2);
                    515:   yc1 = nth_token (1)->yychar;
                    516:   if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
                    517:     return 0;
                    518:   yc2 = nth_token (2)->yychar;
                    519:   if (yc2 == '{' || yc2 == ':')
                    520:     {
                    521:       switch (yc1)
                    522:        {
                    523:        case TYPENAME:
                    524:          nth_token (1)->yychar = TYPENAME_DEFN;
                    525:          break;
                    526:        case PTYPENAME:
                    527:          nth_token (1)->yychar = PTYPENAME_DEFN;
                    528:          break;
                    529:        case IDENTIFIER:
                    530:          nth_token (1)->yychar = IDENTIFIER_DEFN;
                    531:          break;
                    532:        default:
                    533:          abort ();
                    534:        }
                    535:     }
                    536:   return 0;
                    537: }  
                    538: 
                    539: static struct token
                    540: frob_identifier ()
                    541: {
                    542:   /* we could have a type, if it is followed by :: (if so, suck it all up); */
                    543:   /* we could have a ptypename; */
                    544:   /* we could have a normal identifier. */
                    545:   tree t1;
                    546:   struct token rt;
                    547:   
                    548:   scan_tokens(1);
                    549:   rt = *nth_token(0);
                    550: 
                    551: #if 0
                    552:   if (nth_token(1)->yychar == '<')
                    553:     {
                    554:       t1 = hack_ptype();       /* suck up the whole thing */
                    555:       if (t1)
                    556:        {
                    557:          rt.yylval.ttype = t1;
                    558:          rt.yychar = TYPENAME;
                    559:          *nth_token(0) = rt;
                    560:        }
                    561:       /* else fall out bottom */
                    562:     }  
                    563: #endif
                    564: 
                    565:   if (nth_token(1)->yychar == SCOPE)
                    566:     {
                    567:       t1 = hack_more_ids(0);
                    568:       if (t1 && TREE_CODE(t1) == SCOPE_REF)
                    569:        {
                    570:          rt.yylval.ttype = t1;
                    571:          rt.yychar = SCOPED_TYPENAME ;
                    572:          return rt;
                    573:        }
                    574:       else
                    575:        {
                    576:          /* deal with types (enums?) in classes... */
                    577:          struct token *tok;
                    578:          tree ta, tb;
                    579:          scan_tokens(3);
                    580: 
                    581:          /* Have to check for a type conversion operator
                    582:             to a nested type.  */
                    583:          if (nth_token (2)->yychar == OPERATOR)
                    584:            tok = nth_token (3);
                    585:          else
                    586:            tok = nth_token(2);
                    587: 
                    588:          if (tok->yychar == IDENTIFIER || tok->yychar == TYPENAME)
                    589:            {
                    590:              ta = build_parse_node (SCOPE_REF,
                    591:                                     nth_token(0)->yylval.ttype,
                    592:                                     tok->yylval.ttype);
                    593:              tb = resolve_scope_to_name (NULL_TREE, ta);
                    594: 
                    595:              if (tb)
                    596:                {
                    597:                  if (nth_token (2)->yychar == OPERATOR)
                    598:                    {
                    599:                      /* Have to keep these tokens around
                    600:                         so we can finish parsing the declaration.
                    601:                         What do we do for
                    602: 
                    603:                         int foo::operator bar::baz (); 
                    604: 
                    605:                         where bar is a nested class in foo?  */
                    606:                      nth_token (3)->yychar = TYPENAME;
                    607:                      nth_token (3)->yylval.ttype = tb;
                    608:                    }
                    609:                  else
                    610:                    {
                    611:                      consume_token (); /* base type */
                    612:                      consume_token (); /* SCOPE */
                    613:                      consume_token (); /* member type */
                    614:                      rt.yychar = TYPENAME;
                    615:                      rt.yylval.ttype = tb;
                    616:                      rt.end_of_file = tok->end_of_file;
                    617:                      return rt;
                    618:                    }
                    619:                  
                    620:                }
                    621:            }      
                    622:          /* else fall out bottom */
                    623:        }
                    624:     }
                    625:             
                    626:   consume_token();
                    627:   return rt;
                    628: }
                    629: 
                    630: /* When this function is called, nth_token(0) is the current
                    631:    token we are scanning.  This means that the next token we'll
                    632:    scan is nth_token (1).  Usually the next token we'll scan
                    633:    is nth_token (0) (and the current token is in [yylval,yychar]).  */
                    634: tree
                    635: arbitrate_lookup (name, exp_decl, type_decl)
                    636:      tree name, exp_decl, type_decl;
                    637: {
                    638:   int ch;
                    639: 
                    640:   scan_tokens (3);
                    641:   ch = nth_token (1)->yychar;
                    642: 
                    643:   switch (ch)
                    644:     {
                    645:     case '(':
                    646:     case LEFT_RIGHT:
                    647:       /* If we guessed wrong here, `build_functional_cast' can fix it.  */
                    648:       return type_decl;
                    649: 
                    650:     case '=':
                    651:       if (global_bindings_p ())
                    652:        /* Probably a default parameter.  */
                    653:        return type_decl;
                    654:       /* Probably not an initialization.  */
                    655:       return exp_decl;
                    656: 
                    657:     case '[':
                    658:       /* This needs special help because an expression inside the
                    659:         brackets means nothing.  */
                    660:       {
                    661:        int i;
                    662: 
                    663:        for (i = 0; i < 42; i++)
                    664:          {
                    665:            int ith_yychar;
                    666: 
                    667:            scan_tokens (3+i);
                    668:            ith_yychar = nth_token (2+i)->yychar;
                    669: 
                    670:            /* If we hit an undefined identifier, assume
1.1.1.2 ! root      671:               the decl in arbitration is its type specifier.  */
1.1       root      672:            if (ith_yychar == IDENTIFIER
                    673:                && lookup_name (nth_token (2+i)->yylval.ttype, 0) == 0)
                    674:              return type_decl;
                    675:            else if (ith_yychar == ']')
                    676:              {
                    677:                /* There are only a few things we expect after a ']'
                    678:                   in a declarator.  */
                    679:                i += 1;
                    680:                scan_tokens (4+i);
                    681:                ith_yychar = nth_token (2+i)->yychar;
                    682: 
                    683:                /* These are inconclusive.  */
                    684:                if (ith_yychar == LEFT_RIGHT
                    685:                    || ith_yychar == '('
                    686:                    || ith_yychar == '['
                    687:                    || ith_yychar == ',')
                    688:                  continue;
                    689:                /* stmt or decl?  We'll probably never know.  */
                    690:                else if (ith_yychar == ';')
                    691:                  goto warn_ambiguous;
                    692: 
                    693:                if (ith_yychar == '=')
                    694:                  {
                    695:                    if (nth_token (3+i)->yychar == '{')
                    696:                      return type_decl;
                    697:                    continue;
                    698:                  }
                    699: 
                    700:                /* Whatever it is, it looks like we're processing an expr.  */
                    701:                return exp_decl;
                    702:              }
                    703:          }
                    704:        goto warn_ambiguous;
                    705:       }
                    706: 
                    707:     case ',':
                    708:     case ';':
                    709:     case '&':
                    710:     case '<':
                    711:     case '*':
                    712:     case ']':
                    713:     case ')':
                    714:     case '>':
                    715:       /* see if the next token looks like it wants to be part
                    716:         of a declaration list or an expression list.  */
                    717:       {
                    718:        int i;
                    719: 
                    720:        /* Some heuristics: if we are inside a function definition,
                    721:           prefer the local declaration.  */
                    722:        if (! global_bindings_p ())
                    723:          {
                    724:            if (IDENTIFIER_LOCAL_VALUE (name) == exp_decl)
                    725:              return exp_decl;
                    726:            if (IDENTIFIER_LOCAL_VALUE (name) != type_decl
                    727:                && IDENTIFIER_CLASS_VALUE (name) == exp_decl)
                    728:              return exp_decl;
                    729:          }
                    730:        /* If these symbols follow in a list, we know it's a list of
                    731:           expressions.  */
                    732:        if (follows_identifier[nth_token (2)->yychar])
                    733:          return exp_decl;
                    734: 
                    735:        /* Look for the first identifier or other distinguishing token
                    736:           we find in the next several tokens.  */
                    737:        for (i = 0; i < 42; i++)
                    738:          {
                    739:            int ith_yychar;
                    740: 
                    741:            scan_tokens (3+i);
                    742:            ith_yychar = nth_token (2+i)->yychar;
                    743: 
                    744:            if (ith_yychar == IDENTIFIER)
                    745:              {
                    746:                tree as_type = lookup_name (nth_token (2+i)->yylval.ttype, 1);
                    747:                if (as_type && TREE_CODE (as_type) != TYPE_DECL)
                    748:                  return exp_decl;
                    749:                /* An undeclared identifier or a typename means we're
                    750:                   probably looking at a typename.  */
                    751:                return type_decl;
                    752:              }
                    753:            else if (ith_yychar == EMPTY
                    754:                     || follows_identifier[ith_yychar])
                    755:              return exp_decl;
                    756:            else if (follows_typename[ith_yychar])
                    757:              return type_decl;
                    758:            /* stmt or decl?  We'll probably never know.  */
                    759:            else if (ith_yychar == ';')
                    760:              goto warn_ambiguous;
                    761:          }
                    762:        goto warn_ambiguous;
                    763:       }
                    764: 
                    765:     default:
                    766:       if (follows_identifier[ch])
                    767:        return exp_decl;
                    768:       if (follows_typename[ch])
                    769:        return type_decl;
                    770: 
                    771:       /* Fall through...  */
                    772:     warn_ambiguous:
                    773:       warning ("name `%s' could be type or expression; compiler assuming type",
                    774:               IDENTIFIER_POINTER (DECL_NAME (type_decl)));
                    775:       return type_decl;
                    776:     }
                    777: }
                    778: 
                    779: /* now returns decl_node */
                    780: 
                    781: #if 0
                    782: static tree
                    783: hack_ptype()
                    784: {
                    785:   /* when we get here, we know that [0] is a ptype and [1] is '<'.
                    786:    * now we loop over simple parameters. */
                    787:   struct token this_param;
                    788:   int n = 2;
                    789:   tree tplist = 0;
                    790:   tree tc;
                    791:   scan_tokens(n+1);
                    792:   
                    793:   while((this_param = *nth_token(n)).yychar != '>')
                    794:     {
                    795:       /* if it is a type, add it to the list */
                    796:       tree thistype;
                    797:     
                    798:       switch(this_param.yychar)
                    799:        {
                    800:        case IDENTIFIER:
                    801:        case TYPENAME:
                    802:        case TYPESPEC:
                    803:          break;
                    804:        default:
                    805:          return 0;
                    806:        }
                    807: 
                    808:       thistype = this_param.yylval.ttype;
                    809:       thistype = lookup_name(thistype, 1);
                    810:       thistype = TREE_TYPE (thistype);
                    811:         
                    812:       if (tplist)
                    813:        tplist = chainon (tplist, build_tree_list (NULL_TREE, thistype));
                    814:       else
                    815:        tplist = build_tree_list(NULL_TREE, thistype);
                    816:     
                    817:     
                    818:       /* then suck up the comma */
                    819:       n++;
                    820:       scan_tokens(n+1);
                    821:       this_param = *nth_token(n);
                    822:       if (this_param.yychar == ',')
                    823:        {
                    824:          n++;
                    825:          scan_tokens(n+1);
                    826:          continue;
                    827:        }
                    828:       if (this_param.yychar == '>')
                    829:        break;
                    830:       return 0;
                    831:     }
                    832: 
                    833:   /* once we're done, lookup_template_class -> identifier */
                    834:   tc = lookup_template_class (nth_token(0)->yylval.ttype,tplist);
                    835:   /* then lookup_name on that to get a type, if there is one */
                    836:   tc = lookup_name (tc, 1);
                    837:   if (tc)
                    838:     {
                    839:       int i;
                    840:       /* don't actually eat the trailing '>'... we can replace it! */
                    841:       for (i=0; i<n; i++)
                    842:        consume_token();
1.1.1.2 ! root      843:       /*    IDENTIFIER_TYPE_VALUE (DECL_NAME (tc)) = */
1.1       root      844:       return DECL_NAME (tc);
                    845:     }
                    846:   return NULL_TREE;
                    847: }
                    848: #endif
                    849: 
                    850: static tree
                    851: hack_more_ids (n)
                    852:      int n;
                    853: {
                    854:   /*
                    855:    * The recursion should probably do consume_tokens(), since once we've started
                    856:    * down an IDENTIFIER SCOPE ... chain, we don't need to back-track - we just
                    857:    * get as much as we can, make SCOPE_REF's out of it, and return it.
                    858:    */
                    859:   struct token this_iter, this2_iter;
                    860:   int tmp_y;
                    861:   
                    862:   scan_tokens(n+1);
                    863:   this_iter = *nth_token(n);
                    864: 
                    865:   tmp_y = nth_token(n)->yychar;
                    866:   if (tmp_y == IDENTIFIER || tmp_y == TYPENAME)
                    867:     {
                    868:       scan_tokens(n+2+2);
                    869:       if (nth_token(n+1)->yychar == SCOPE)
                    870:        {
                    871:          if (nth_token(n+1+2)->yychar == SCOPE)
                    872:            {
                    873:              tree hmi;
                    874:        
                    875:              consume_token();  /* last IDENTIFIER (this_iter) */
                    876:              consume_token();  /* last SCOPE */
                    877:              this2_iter = *nth_token(n);
                    878:        
                    879:              hmi = hack_more_ids (n);
                    880:        
                    881:              if (hmi)
                    882:                return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, hmi);
                    883:              consume_token(); /* last IDENTIFIER (this2_iter) */
                    884:              return build_parse_node (SCOPE_REF, this_iter.yylval.ttype,
                    885:                                       this2_iter.yylval.ttype);
                    886:            }
                    887:          else
                    888:            {
                    889:              /* consume_token();       */      /* last IDENTIFIER */
                    890:              /* leave whatever else we got */
                    891:              /* return this_iter.yylval.ttype; */
                    892:              return NULL_TREE;
                    893:            }
                    894:        }
                    895:     }
                    896:   return NULL_TREE;            /* @@ may need to backtrack */
                    897: }
                    898: 
                    899: #if 0
                    900: static struct token
                    901: hack_scope ()
                    902: {
                    903:   /* we've got a :: - what follows is either a global var or a type. */
                    904:   /* hmm, template names can be in the global scope too... */
                    905:   tree t1;
                    906:   struct token rt;
                    907:   
                    908:   scan_tokens(1);
                    909:   if (nth_token(1)->yychar == IDENTIFIER)
                    910:     {
                    911:       /* @@ this is probably not right, but doesn't get hit yet */
                    912:       t1 = build_parse_node (SCOPE_REF,
                    913:                             NULL_TREE, /* to get "global" scope */
                    914:                             hack_more_ids(0)); /* do some prefetching */
                    915:       rt.yylval.ttype = t1;
                    916:       rt.yychar =              /*SCOPED_*/TYPENAME;
                    917:       return rt;
                    918:     }
                    919:   else
                    920:     {
                    921:       rt = *nth_token(0);
                    922:       consume_token();
                    923:       return rt;
                    924:     }
                    925: }
                    926: #endif
                    927:   
                    928: /*
                    929:  * Generations:
                    930:  *     
                    931:  * PINST: PTYPE { saved_arg_count = arg_count($1) }
                    932:  *        '<' { arg_c = 0; } PARGS '>'
                    933:  *        ;
                    934:  * PARG: TYPE
                    935:  *       | VALUE
                    936:  *       ;
                    937:  * (of course the arg counting doesn't work for recursion... Do it right.)
                    938:  * PARGS: PARG { assert(arg_c == saved_arg_count); }
                    939:  *        | PARG ',' PARGS     { arg_c++; }
                    940:  *        ;
                    941:  * ATYPE: PINST
                    942:  *        | TYPEID
                    943:  *        ;
                    944:  * TYPE: ATYPE
                    945:  *       | ATYPE { basetype = $1; } '::' TYPEKIDS
                    946:  *       ;
                    947:  * TYPEKIDS: TYPE { assert ($1 is a member of basetype); }
                    948:  *       | TYPEKIDS { basetype += $1} TYPE { assert( $3 is in basetype ); }
                    949:  *       ;
                    950:  *
                    951:  *
                    952:  * state0: ; ATYPE
                    953:  *     TYPE '<': ac = args($0), base = CALL state1, state3     
                    954:  *     TYPE '::': base=$0, state3
                    955:  *     else return TYPE
                    956:  * state1: ; begin PARGS
                    957:  *     if(ac < list length) punt
                    958:  *     PARG ",": add to list, state1
                    959:  *     PARG ">": add to list, return
                    960:  *     else unravel
                    961:  * state3: ; begin TYPEKIDS
                    962:  *     TYPE: 
                    963:  */
                    964:   
                    965:   
                    966: #ifdef SPEW_DEBUG    
                    967: 
                    968: /*
                    969:  * debug_yychar takes a yychar (token number) value and prints its
                    970:  * name. This only works if cp-tab.c is compiled with YYDEBUG != 0.
                    971:  */
                    972: static int
                    973: debug_yychar (yy)
                    974:      int yy;
                    975: {
                    976:   extern char *debug_yytranslate ();
                    977:   
                    978:   int i;
                    979:   
                    980:   if(yy<256) {
                    981:     fprintf (stderr, "<%d: %c >\n", yy, yy);
                    982:     return 0;
                    983:   }
                    984:   fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy));
                    985:   return 1;
                    986: }
                    987: 
                    988: #endif

unix.superglobalmegacorp.com

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