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