|
|
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: ! 73: static char follows_typename[END_OF_SAVED_INPUT]; ! 74: static char follows_identifier[END_OF_SAVED_INPUT]; ! 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, ! 88: RETURN, GOTO, ASM, TYPEOF, ALIGNOF, HEADOF, CLASSOF, ATTRIBUTE, ! 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 */ ! 309: tmp_token.yychar = real_yylex(); ! 310: tmp_token.yylval = yylval; ! 311: add_token(&tmp_token); ! 312: } ! 313: ! 314: /* many tokens just need to be returned. At first glance, all we ! 315: * have to do is send them back up, but some of them are needed to ! 316: * figure out local context. */ ! 317: switch(tmp_token.yychar) ! 318: { ! 319: case EMPTY: ! 320: /* This is a lexical no-op. */ ! 321: consume_token (); ! 322: #ifdef SPEW_DEBUG ! 323: if (spew_debug) ! 324: debug_yychar (tmp_token.yychar); ! 325: #endif ! 326: goto retry; ! 327: ! 328: case IDENTIFIER: ! 329: /* Note: this calls arbitrate_lookup. */ ! 330: trrr = lookup_name (tmp_token.yylval.ttype, -1); ! 331: if (trrr) ! 332: { ! 333: tmp_token.yychar = identifier_type (trrr); ! 334: switch (tmp_token.yychar) ! 335: { ! 336: case TYPENAME: ! 337: lastiddecl = IDENTIFIER_TYPEDECL_VALUE (tmp_token.yylval.ttype); ! 338: break; ! 339: case IDENTIFIER: ! 340: lastiddecl = trrr; ! 341: break; ! 342: case PTYPENAME: ! 343: /* This is for cases like ! 344: template<class A> X<A>::operator[] ... ! 345: since "X" is (presumably) a PTYPENAME; we might want to ! 346: avoid seeing the entire thing as a type name, but X<A> ! 347: must be one. ! 348: ! 349: It might not work right if the thing after the :: ! 350: can be a typename nested in X<A>, but I don't think the ! 351: PT code would be up to dealing with that anyways. --KR */ ! 352: if (looking_for_typename == -1) ! 353: { ! 354: scan_tokens (2); ! 355: if (nth_token(1)->yychar == '<') ! 356: looking_for_typename = 0; ! 357: } ! 358: break; ! 359: default: ! 360: abort (); ! 361: } ! 362: } ! 363: else ! 364: lastiddecl = trrr; ! 365: /* and fall through to... */ ! 366: case TYPENAME: ! 367: case PTYPENAME: ! 368: /* if (new_token) add_token (&tmp_token); */ ! 369: *nth_token(0) = tmp_token; ! 370: tmp_token = frob_identifier (); ! 371: if (looking_for_typename < 0) ! 372: { ! 373: tmp_token.yychar = IDENTIFIER; ! 374: lastiddecl = 0; ! 375: looking_for_typename = 0; ! 376: } ! 377: else if (lastiddecl && TREE_CODE (lastiddecl) == TYPE_DECL) ! 378: { ! 379: scan_tokens (2); ! 380: if (nth_token(0)->yychar == IDENTIFIER ! 381: && nth_token (1)->yychar != SCOPE) ! 382: looking_for_typename = -1; ! 383: else ! 384: looking_for_typename = 0; ! 385: goto finish_typename_processing; ! 386: } ! 387: else ! 388: looking_for_typename = 0; ! 389: break; ! 390: ! 391: case TYPESPEC: ! 392: case SCSPEC: ! 393: consume_token (); ! 394: finish_typename_processing: ! 395: /* Now see if we should insert a START_DECLARATOR token. ! 396: Here are the cases caught: ! 397: ! 398: typespec ( * ID ) ( // ptr to function ! 399: typespec ( & ID ) ( // ref to function ! 400: typespec ( * ID ) [ // array of pointers ! 401: typespec ( & ID ) [ // array of references ! 402: ! 403: This is a terrible kludge. */ ! 404: ! 405: scan_tokens (2); ! 406: if (nth_token (0)->yychar == '(' ! 407: && (nth_token (1)->yychar == '*' ! 408: || nth_token (1)->yychar == '&')) ! 409: { ! 410: scan_tokens (5); ! 411: if (nth_token (3)->yychar == ')' ! 412: && (nth_token (4)->yychar == '(' ! 413: || nth_token (4)->yychar == '[' ! 414: || nth_token (4)->yychar == LEFT_RIGHT) ! 415: && (nth_token (2)->yychar == IDENTIFIER ! 416: || nth_token (2)->yychar == TYPENAME)) ! 417: { ! 418: shift_tokens (1); ! 419: nth_token (0)->yychar = START_DECLARATOR; ! 420: } ! 421: } ! 422: break; ! 423: ! 424: #if 0 ! 425: case '(': ! 426: /* Handle casts. We are looking for one of: ! 427: `( TYPENAME' followed by `)', or ! 428: `( TYPENAME *' followed by one of `[,*,&,)', or ! 429: `( TYPENAME &' followed by one of `[,*,&,)', or ! 430: `( TYPENAME [' followed by `]'. We are punting ! 431: generality on scanning casts to array types. */ ! 432: scan_tokens (4); ! 433: if (nth_token (1)->yychar == IDENTIFIER) ! 434: { ! 435: tree type = identifier_typedecl_value (nth_token (1)->yylval.ttype); ! 436: if (type) ! 437: switch (nth_token (2)->yychar) ! 438: { ! 439: default: ! 440: break; ! 441: } ! 442: } ! 443: break; ! 444: ! 445: case SCOPE: ! 446: /* if (new_token) add_token (&tmp_token); */ ! 447: *nth_token(0) = tmp_token; ! 448: tmp_token = hack_scope (); ! 449: break; ! 450: #endif ! 451: ! 452: case AGGR: ! 453: *nth_token(0) = tmp_token; ! 454: do_aggr (); ! 455: /* fall through to output... */ ! 456: case ENUM: ! 457: /* Set this again, in case we are rescanning. */ ! 458: looking_for_typename = 1; ! 459: /* fall through... */ ! 460: default: ! 461: #ifdef SPEW_DEBUG ! 462: if (spew_debug) ! 463: debug_yychar(tmp_token.yychar); ! 464: #endif ! 465: consume_token(); ! 466: yylval = tmp_token.yylval; ! 467: yychar = tmp_token.yychar; ! 468: end_of_file = tmp_token.end_of_file; ! 469: return tmp_token.yychar; ! 470: } ! 471: ! 472: if (tmp_token.yychar == SCOPED_TYPENAME) ! 473: { ! 474: #if 0 ! 475: t2 = resolve_scope_to_name (NULL_TREE, tmp_token.yylval.ttype); ! 476: if (t2) ! 477: { ! 478: tmp_token.yylval.ttype = t2; ! 479: tmp_token.yychar = TYPENAME; ! 480: } ! 481: else ! 482: { ! 483: /* unwind? */ ! 484: } ! 485: } ! 486: else ! 487: { ! 488: /* couldn't get here, as is... */ ! 489: #endif ! 490: tmp_token.yychar = TYPENAME; ! 491: } ! 492: ! 493: yylval = tmp_token.yylval; ! 494: yychar = tmp_token.yychar; ! 495: end_of_file = tmp_token.end_of_file; ! 496: #ifdef SPEW_DEBUG ! 497: if (spew_debug) ! 498: debug_yychar(yychar); ! 499: #endif ! 500: /* consume_token(); */ /* already eaten by frob_identifier?... */ ! 501: return yychar; ! 502: } ! 503: ! 504: /* token[0] == AGGR (struct/union/enum) ! 505: * thus, token[1] is either a TYPENAME or a TYPENAME_DEFN ! 506: * if token[2] == '{' or ':' then it's TYPENAME_DEFN ! 507: */ ! 508: static int ! 509: do_aggr () ! 510: { ! 511: int yc1, yc2; ! 512: ! 513: scan_tokens (2); ! 514: yc1 = nth_token (1)->yychar; ! 515: if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME) ! 516: return 0; ! 517: yc2 = nth_token (2)->yychar; ! 518: if (yc2 == '{' || yc2 == ':') ! 519: { ! 520: switch (yc1) ! 521: { ! 522: case TYPENAME: ! 523: nth_token (1)->yychar = TYPENAME_DEFN; ! 524: break; ! 525: case PTYPENAME: ! 526: nth_token (1)->yychar = PTYPENAME_DEFN; ! 527: break; ! 528: case IDENTIFIER: ! 529: nth_token (1)->yychar = IDENTIFIER_DEFN; ! 530: break; ! 531: default: ! 532: abort (); ! 533: } ! 534: } ! 535: return 0; ! 536: } ! 537: ! 538: static struct token ! 539: frob_identifier () ! 540: { ! 541: /* we could have a type, if it is followed by :: (if so, suck it all up); */ ! 542: /* we could have a ptypename; */ ! 543: /* we could have a normal identifier. */ ! 544: tree t1; ! 545: struct token rt; ! 546: ! 547: scan_tokens(1); ! 548: rt = *nth_token(0); ! 549: ! 550: #if 0 ! 551: if (nth_token(1)->yychar == '<') ! 552: { ! 553: t1 = hack_ptype(); /* suck up the whole thing */ ! 554: if (t1) ! 555: { ! 556: rt.yylval.ttype = t1; ! 557: rt.yychar = TYPENAME; ! 558: *nth_token(0) = rt; ! 559: } ! 560: /* else fall out bottom */ ! 561: } ! 562: #endif ! 563: ! 564: if (nth_token(1)->yychar == SCOPE) ! 565: { ! 566: t1 = hack_more_ids(0); ! 567: if (t1 && TREE_CODE(t1) == SCOPE_REF) ! 568: { ! 569: rt.yylval.ttype = t1; ! 570: rt.yychar = SCOPED_TYPENAME ; ! 571: return rt; ! 572: } ! 573: else ! 574: { ! 575: /* deal with types (enums?) in classes... */ ! 576: struct token *tok; ! 577: tree ta, tb; ! 578: scan_tokens(3); ! 579: ! 580: /* Have to check for a type conversion operator ! 581: to a nested type. */ ! 582: if (nth_token (2)->yychar == OPERATOR) ! 583: tok = nth_token (3); ! 584: else ! 585: tok = nth_token(2); ! 586: ! 587: if (tok->yychar == IDENTIFIER || tok->yychar == TYPENAME) ! 588: { ! 589: ta = build_parse_node (SCOPE_REF, ! 590: nth_token(0)->yylval.ttype, ! 591: tok->yylval.ttype); ! 592: tb = resolve_scope_to_name (NULL_TREE, ta); ! 593: ! 594: if (tb) ! 595: { ! 596: if (nth_token (2)->yychar == OPERATOR) ! 597: { ! 598: /* Have to keep these tokens around ! 599: so we can finish parsing the declaration. ! 600: What do we do for ! 601: ! 602: int foo::operator bar::baz (); ! 603: ! 604: where bar is a nested class in foo? */ ! 605: nth_token (3)->yychar = TYPENAME; ! 606: nth_token (3)->yylval.ttype = tb; ! 607: } ! 608: else ! 609: { ! 610: consume_token (); /* base type */ ! 611: consume_token (); /* SCOPE */ ! 612: consume_token (); /* member type */ ! 613: rt.yychar = TYPENAME; ! 614: rt.yylval.ttype = tb; ! 615: rt.end_of_file = tok->end_of_file; ! 616: return rt; ! 617: } ! 618: ! 619: } ! 620: } ! 621: /* else fall out bottom */ ! 622: } ! 623: } ! 624: ! 625: consume_token(); ! 626: return rt; ! 627: } ! 628: ! 629: /* When this function is called, nth_token(0) is the current ! 630: token we are scanning. This means that the next token we'll ! 631: scan is nth_token (1). Usually the next token we'll scan ! 632: is nth_token (0) (and the current token is in [yylval,yychar]). */ ! 633: tree ! 634: arbitrate_lookup (name, exp_decl, type_decl) ! 635: tree name, exp_decl, type_decl; ! 636: { ! 637: int ch; ! 638: ! 639: scan_tokens (3); ! 640: ch = nth_token (1)->yychar; ! 641: ! 642: switch (ch) ! 643: { ! 644: case '(': ! 645: case LEFT_RIGHT: ! 646: /* If we guessed wrong here, `build_functional_cast' can fix it. */ ! 647: return type_decl; ! 648: ! 649: case '=': ! 650: if (global_bindings_p ()) ! 651: /* Probably a default parameter. */ ! 652: return type_decl; ! 653: /* Probably not an initialization. */ ! 654: return exp_decl; ! 655: ! 656: case '[': ! 657: /* This needs special help because an expression inside the ! 658: brackets means nothing. */ ! 659: { ! 660: int i; ! 661: ! 662: for (i = 0; i < 42; i++) ! 663: { ! 664: int ith_yychar; ! 665: ! 666: scan_tokens (3+i); ! 667: ith_yychar = nth_token (2+i)->yychar; ! 668: ! 669: /* If we hit an undefined identifier, assume ! 670: the decl in aribtration is its type specifier. */ ! 671: if (ith_yychar == IDENTIFIER ! 672: && lookup_name (nth_token (2+i)->yylval.ttype, 0) == 0) ! 673: return type_decl; ! 674: else if (ith_yychar == ']') ! 675: { ! 676: /* There are only a few things we expect after a ']' ! 677: in a declarator. */ ! 678: i += 1; ! 679: scan_tokens (4+i); ! 680: ith_yychar = nth_token (2+i)->yychar; ! 681: ! 682: /* These are inconclusive. */ ! 683: if (ith_yychar == LEFT_RIGHT ! 684: || ith_yychar == '(' ! 685: || ith_yychar == '[' ! 686: || ith_yychar == ',') ! 687: continue; ! 688: /* stmt or decl? We'll probably never know. */ ! 689: else if (ith_yychar == ';') ! 690: goto warn_ambiguous; ! 691: ! 692: if (ith_yychar == '=') ! 693: { ! 694: if (nth_token (3+i)->yychar == '{') ! 695: return type_decl; ! 696: continue; ! 697: } ! 698: ! 699: /* Whatever it is, it looks like we're processing an expr. */ ! 700: return exp_decl; ! 701: } ! 702: } ! 703: goto warn_ambiguous; ! 704: } ! 705: ! 706: case ',': ! 707: case ';': ! 708: case '&': ! 709: case '<': ! 710: case '*': ! 711: case ']': ! 712: case ')': ! 713: case '>': ! 714: /* see if the next token looks like it wants to be part ! 715: of a declaration list or an expression list. */ ! 716: { ! 717: int i; ! 718: ! 719: /* Some heuristics: if we are inside a function definition, ! 720: prefer the local declaration. */ ! 721: if (! global_bindings_p ()) ! 722: { ! 723: if (IDENTIFIER_LOCAL_VALUE (name) == exp_decl) ! 724: return exp_decl; ! 725: if (IDENTIFIER_LOCAL_VALUE (name) != type_decl ! 726: && IDENTIFIER_CLASS_VALUE (name) == exp_decl) ! 727: return exp_decl; ! 728: } ! 729: /* If these symbols follow in a list, we know it's a list of ! 730: expressions. */ ! 731: if (follows_identifier[nth_token (2)->yychar]) ! 732: return exp_decl; ! 733: ! 734: /* Look for the first identifier or other distinguishing token ! 735: we find in the next several tokens. */ ! 736: for (i = 0; i < 42; i++) ! 737: { ! 738: int ith_yychar; ! 739: ! 740: scan_tokens (3+i); ! 741: ith_yychar = nth_token (2+i)->yychar; ! 742: ! 743: if (ith_yychar == IDENTIFIER) ! 744: { ! 745: tree as_type = lookup_name (nth_token (2+i)->yylval.ttype, 1); ! 746: if (as_type && TREE_CODE (as_type) != TYPE_DECL) ! 747: return exp_decl; ! 748: /* An undeclared identifier or a typename means we're ! 749: probably looking at a typename. */ ! 750: return type_decl; ! 751: } ! 752: else if (ith_yychar == EMPTY ! 753: || follows_identifier[ith_yychar]) ! 754: return exp_decl; ! 755: else if (follows_typename[ith_yychar]) ! 756: return type_decl; ! 757: /* stmt or decl? We'll probably never know. */ ! 758: else if (ith_yychar == ';') ! 759: goto warn_ambiguous; ! 760: } ! 761: goto warn_ambiguous; ! 762: } ! 763: ! 764: default: ! 765: if (follows_identifier[ch]) ! 766: return exp_decl; ! 767: if (follows_typename[ch]) ! 768: return type_decl; ! 769: ! 770: /* Fall through... */ ! 771: warn_ambiguous: ! 772: warning ("name `%s' could be type or expression; compiler assuming type", ! 773: IDENTIFIER_POINTER (DECL_NAME (type_decl))); ! 774: return type_decl; ! 775: } ! 776: } ! 777: ! 778: /* now returns decl_node */ ! 779: ! 780: #if 0 ! 781: static tree ! 782: hack_ptype() ! 783: { ! 784: /* when we get here, we know that [0] is a ptype and [1] is '<'. ! 785: * now we loop over simple parameters. */ ! 786: struct token this_param; ! 787: int n = 2; ! 788: tree tplist = 0; ! 789: tree tc; ! 790: scan_tokens(n+1); ! 791: ! 792: while((this_param = *nth_token(n)).yychar != '>') ! 793: { ! 794: /* if it is a type, add it to the list */ ! 795: tree thistype; ! 796: ! 797: switch(this_param.yychar) ! 798: { ! 799: case IDENTIFIER: ! 800: case TYPENAME: ! 801: case TYPESPEC: ! 802: break; ! 803: default: ! 804: return 0; ! 805: } ! 806: ! 807: thistype = this_param.yylval.ttype; ! 808: thistype = lookup_name(thistype, 1); ! 809: thistype = TREE_TYPE (thistype); ! 810: ! 811: if (tplist) ! 812: tplist = chainon (tplist, build_tree_list (NULL_TREE, thistype)); ! 813: else ! 814: tplist = build_tree_list(NULL_TREE, thistype); ! 815: ! 816: ! 817: /* then suck up the comma */ ! 818: n++; ! 819: scan_tokens(n+1); ! 820: this_param = *nth_token(n); ! 821: if (this_param.yychar == ',') ! 822: { ! 823: n++; ! 824: scan_tokens(n+1); ! 825: continue; ! 826: } ! 827: if (this_param.yychar == '>') ! 828: break; ! 829: return 0; ! 830: } ! 831: ! 832: /* once we're done, lookup_template_class -> identifier */ ! 833: tc = lookup_template_class (nth_token(0)->yylval.ttype,tplist); ! 834: /* then lookup_name on that to get a type, if there is one */ ! 835: tc = lookup_name (tc, 1); ! 836: if (tc) ! 837: { ! 838: int i; ! 839: /* don't actually eat the trailing '>'... we can replace it! */ ! 840: for (i=0; i<n; i++) ! 841: consume_token(); ! 842: /* IDENTIFER_TYPE_VALUE (DECL_NAME (tc)) = */ ! 843: return DECL_NAME (tc); ! 844: } ! 845: return NULL_TREE; ! 846: } ! 847: #endif ! 848: ! 849: static tree ! 850: hack_more_ids (n) ! 851: int n; ! 852: { ! 853: /* ! 854: * The recursion should probably do consume_tokens(), since once we've started ! 855: * down an IDENTIFIER SCOPE ... chain, we don't need to back-track - we just ! 856: * get as much as we can, make SCOPE_REF's out of it, and return it. ! 857: */ ! 858: struct token this_iter, this2_iter; ! 859: int tmp_y; ! 860: ! 861: scan_tokens(n+1); ! 862: this_iter = *nth_token(n); ! 863: ! 864: tmp_y = nth_token(n)->yychar; ! 865: if (tmp_y == IDENTIFIER || tmp_y == TYPENAME) ! 866: { ! 867: scan_tokens(n+2+2); ! 868: if (nth_token(n+1)->yychar == SCOPE) ! 869: { ! 870: if (nth_token(n+1+2)->yychar == SCOPE) ! 871: { ! 872: tree hmi; ! 873: ! 874: consume_token(); /* last IDENTIFIER (this_iter) */ ! 875: consume_token(); /* last SCOPE */ ! 876: this2_iter = *nth_token(n); ! 877: ! 878: hmi = hack_more_ids (n); ! 879: ! 880: if (hmi) ! 881: return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, hmi); ! 882: consume_token(); /* last IDENTIFIER (this2_iter) */ ! 883: return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, ! 884: this2_iter.yylval.ttype); ! 885: } ! 886: else ! 887: { ! 888: /* consume_token(); */ /* last IDENTIFIER */ ! 889: /* leave whatever else we got */ ! 890: /* return this_iter.yylval.ttype; */ ! 891: return NULL_TREE; ! 892: } ! 893: } ! 894: } ! 895: return NULL_TREE; /* @@ may need to backtrack */ ! 896: } ! 897: ! 898: #if 0 ! 899: static struct token ! 900: hack_scope () ! 901: { ! 902: /* we've got a :: - what follows is either a global var or a type. */ ! 903: /* hmm, template names can be in the global scope too... */ ! 904: tree t1; ! 905: struct token rt; ! 906: ! 907: scan_tokens(1); ! 908: if (nth_token(1)->yychar == IDENTIFIER) ! 909: { ! 910: /* @@ this is probably not right, but doesn't get hit yet */ ! 911: t1 = build_parse_node (SCOPE_REF, ! 912: NULL_TREE, /* to get "global" scope */ ! 913: hack_more_ids(0)); /* do some prefetching */ ! 914: rt.yylval.ttype = t1; ! 915: rt.yychar = /*SCOPED_*/TYPENAME; ! 916: return rt; ! 917: } ! 918: else ! 919: { ! 920: rt = *nth_token(0); ! 921: consume_token(); ! 922: return rt; ! 923: } ! 924: } ! 925: #endif ! 926: ! 927: /* ! 928: * Generations: ! 929: * ! 930: * PINST: PTYPE { saved_arg_count = arg_count($1) } ! 931: * '<' { arg_c = 0; } PARGS '>' ! 932: * ; ! 933: * PARG: TYPE ! 934: * | VALUE ! 935: * ; ! 936: * (of course the arg counting doesn't work for recursion... Do it right.) ! 937: * PARGS: PARG { assert(arg_c == saved_arg_count); } ! 938: * | PARG ',' PARGS { arg_c++; } ! 939: * ; ! 940: * ATYPE: PINST ! 941: * | TYPEID ! 942: * ; ! 943: * TYPE: ATYPE ! 944: * | ATYPE { basetype = $1; } '::' TYPEKIDS ! 945: * ; ! 946: * TYPEKIDS: TYPE { assert ($1 is a member of basetype); } ! 947: * | TYPEKIDS { basetype += $1} TYPE { assert( $3 is in basetype ); } ! 948: * ; ! 949: * ! 950: * ! 951: * state0: ; ATYPE ! 952: * TYPE '<': ac = args($0), base = CALL state1, state3 ! 953: * TYPE '::': base=$0, state3 ! 954: * else return TYPE ! 955: * state1: ; begin PARGS ! 956: * if(ac < list length) punt ! 957: * PARG ",": add to list, state1 ! 958: * PARG ">": add to list, return ! 959: * else unravel ! 960: * state3: ; begin TYPEKIDS ! 961: * TYPE: ! 962: */ ! 963: ! 964: ! 965: #ifdef SPEW_DEBUG ! 966: ! 967: /* ! 968: * debug_yychar takes a yychar (token number) value and prints its ! 969: * name. This only works if cp-tab.c is compiled with YYDEBUG != 0. ! 970: */ ! 971: static int ! 972: debug_yychar (yy) ! 973: int yy; ! 974: { ! 975: extern char *debug_yytranslate (); ! 976: ! 977: int i; ! 978: ! 979: if(yy<256) { ! 980: fprintf (stderr, "<%d: %c >\n", yy, yy); ! 981: return 0; ! 982: } ! 983: fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy)); ! 984: return 1; ! 985: } ! 986: ! 987: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.