|
|
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[] = 1.1.1.6 ! root 90: { ASSIGN, RANGE, OROR, ANDAND, MIN_MAX, EQCOMPARE, 1.1 root 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, 1.1.1.6 ! root 96: CATCH, THROW, ANSI_TRY, ANSI_THROW, DYNAMIC_CAST, TYPEID, ! 97: EXTERN_LANG_STRING, ALL, END_OF_SAVED_INPUT, -1 }; 1.1 root 98: static short toks_follow_types[] = 99: { IDENTIFIER, TYPENAME, SCOPED_TYPENAME, SCSPEC, TYPESPEC, TYPE_QUAL, 1.1.1.6 ! root 100: ELLIPSIS, THIS, OPERATOR, TEMPLATE, SCOPE, START_DECLARATOR, 1.1 root 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. */ 1.1.1.6 ! root 195: if (tmp->yychar == '{' || tmp->yychar == ':' || tmp->yychar == ';') 1.1 root 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; 1.1.1.6 ! root 701: tree t; ! 702: char *assume; 1.1 root 703: 704: scan_tokens (3); 705: ch = nth_token (1)->yychar; 706: 707: switch (ch) 708: { 709: case '(': 710: case LEFT_RIGHT: 711: /* If we guessed wrong here, `build_functional_cast' can fix it. */ 712: return type_decl; 713: 714: case '=': 715: if (global_bindings_p ()) 716: /* Probably a default parameter. */ 717: return type_decl; 718: /* Probably not an initialization. */ 719: return exp_decl; 720: 721: case '[': 722: /* This needs special help because an expression inside the 723: brackets means nothing. */ 724: { 725: int i; 726: 727: for (i = 0; i < 42; i++) 728: { 729: int ith_yychar; 730: 731: scan_tokens (3+i); 732: ith_yychar = nth_token (2+i)->yychar; 733: 734: /* If we hit an undefined identifier, assume 1.1.1.2 root 735: the decl in arbitration is its type specifier. */ 1.1 root 736: if (ith_yychar == IDENTIFIER 737: && lookup_name (nth_token (2+i)->yylval.ttype, 0) == 0) 738: return type_decl; 739: else if (ith_yychar == ']') 740: { 741: /* There are only a few things we expect after a ']' 742: in a declarator. */ 743: i += 1; 744: scan_tokens (4+i); 745: ith_yychar = nth_token (2+i)->yychar; 746: 747: /* These are inconclusive. */ 748: if (ith_yychar == LEFT_RIGHT 749: || ith_yychar == '(' 750: || ith_yychar == '[' 751: || ith_yychar == ',') 752: continue; 753: /* stmt or decl? We'll probably never know. */ 754: else if (ith_yychar == ';') 755: goto warn_ambiguous; 756: 757: if (ith_yychar == '=') 758: { 759: if (nth_token (3+i)->yychar == '{') 760: return type_decl; 761: continue; 762: } 763: 764: /* Whatever it is, it looks like we're processing an expr. */ 765: return exp_decl; 766: } 767: } 768: goto warn_ambiguous; 769: } 770: 771: case ',': 772: case ';': 773: case '&': 774: case '<': 775: case '*': 776: case ']': 777: case ')': 778: case '>': 779: /* see if the next token looks like it wants to be part 780: of a declaration list or an expression list. */ 781: { 782: int i; 783: 784: /* Some heuristics: if we are inside a function definition, 785: prefer the local declaration. */ 786: if (! global_bindings_p ()) 787: { 788: if (IDENTIFIER_LOCAL_VALUE (name) == exp_decl) 789: return exp_decl; 790: if (IDENTIFIER_LOCAL_VALUE (name) != type_decl 791: && IDENTIFIER_CLASS_VALUE (name) == exp_decl) 792: return exp_decl; 793: } 794: /* If these symbols follow in a list, we know it's a list of 795: expressions. */ 796: if (follows_identifier[nth_token (2)->yychar]) 797: return exp_decl; 798: 1.1.1.4 root 799: /* If we see a id&, or id&) the we are probably in an argument list. */ 800: if (ch=='&' 801: && (nth_token (2)->yychar == ',' || nth_token (2)->yychar == ')')) 802: return type_decl; 803: 1.1 root 804: /* Look for the first identifier or other distinguishing token 805: we find in the next several tokens. */ 806: for (i = 0; i < 42; i++) 807: { 808: int ith_yychar; 809: 810: scan_tokens (3+i); 811: ith_yychar = nth_token (2+i)->yychar; 812: 813: if (ith_yychar == IDENTIFIER) 814: { 815: tree as_type = lookup_name (nth_token (2+i)->yylval.ttype, 1); 816: if (as_type && TREE_CODE (as_type) != TYPE_DECL) 817: return exp_decl; 818: /* An undeclared identifier or a typename means we're 819: probably looking at a typename. */ 820: return type_decl; 821: } 822: else if (ith_yychar == EMPTY 823: || follows_identifier[ith_yychar]) 824: return exp_decl; 825: else if (follows_typename[ith_yychar]) 826: return type_decl; 827: /* stmt or decl? We'll probably never know. */ 828: else if (ith_yychar == ';') 829: goto warn_ambiguous; 830: } 831: goto warn_ambiguous; 832: } 833: 834: default: 835: if (follows_identifier[ch]) 836: return exp_decl; 837: if (follows_typename[ch]) 838: return type_decl; 839: 840: /* Fall through... */ 841: warn_ambiguous: 1.1.1.6 ! root 842: if (ch == '[') ! 843: { ! 844: assume = "expression"; ! 845: t = exp_decl; ! 846: } ! 847: else ! 848: { ! 849: assume = "type"; ! 850: t = type_decl; ! 851: } ! 852: ! 853: warning ("name `%s' could be type or expression; compiler assuming %s", ! 854: IDENTIFIER_POINTER (DECL_NAME (t)), assume); ! 855: return t; 1.1 root 856: } 857: } 858: 859: /* now returns decl_node */ 860: 861: #if 0 862: static tree 863: hack_ptype() 864: { 865: /* when we get here, we know that [0] is a ptype and [1] is '<'. 866: * now we loop over simple parameters. */ 867: struct token this_param; 868: int n = 2; 869: tree tplist = 0; 870: tree tc; 871: scan_tokens(n+1); 872: 873: while((this_param = *nth_token(n)).yychar != '>') 874: { 875: /* if it is a type, add it to the list */ 876: tree thistype; 877: 878: switch(this_param.yychar) 879: { 880: case IDENTIFIER: 881: case TYPENAME: 882: case TYPESPEC: 883: break; 884: default: 885: return 0; 886: } 887: 888: thistype = this_param.yylval.ttype; 889: thistype = lookup_name(thistype, 1); 890: thistype = TREE_TYPE (thistype); 891: 892: if (tplist) 893: tplist = chainon (tplist, build_tree_list (NULL_TREE, thistype)); 894: else 895: tplist = build_tree_list(NULL_TREE, thistype); 896: 897: 898: /* then suck up the comma */ 899: n++; 900: scan_tokens(n+1); 901: this_param = *nth_token(n); 902: if (this_param.yychar == ',') 903: { 904: n++; 905: scan_tokens(n+1); 906: continue; 907: } 908: if (this_param.yychar == '>') 909: break; 910: return 0; 911: } 912: 913: /* once we're done, lookup_template_class -> identifier */ 914: tc = lookup_template_class (nth_token(0)->yylval.ttype,tplist); 915: /* then lookup_name on that to get a type, if there is one */ 916: tc = lookup_name (tc, 1); 917: if (tc) 918: { 919: int i; 920: /* don't actually eat the trailing '>'... we can replace it! */ 921: for (i=0; i<n; i++) 922: consume_token(); 1.1.1.2 root 923: /* IDENTIFIER_TYPE_VALUE (DECL_NAME (tc)) = */ 1.1 root 924: return DECL_NAME (tc); 925: } 926: return NULL_TREE; 927: } 928: #endif 929: 1.1.1.3 root 930: #if 0 1.1 root 931: static tree 932: hack_more_ids (n) 933: int n; 934: { 935: /* 936: * The recursion should probably do consume_tokens(), since once we've started 937: * down an IDENTIFIER SCOPE ... chain, we don't need to back-track - we just 938: * get as much as we can, make SCOPE_REF's out of it, and return it. 939: */ 940: struct token this_iter, this2_iter; 941: int tmp_y; 942: 943: scan_tokens(n+1); 944: this_iter = *nth_token(n); 945: 946: tmp_y = nth_token(n)->yychar; 947: if (tmp_y == IDENTIFIER || tmp_y == TYPENAME) 948: { 949: scan_tokens(n+2+2); 950: if (nth_token(n+1)->yychar == SCOPE) 951: { 952: if (nth_token(n+1+2)->yychar == SCOPE) 953: { 954: tree hmi; 955: 956: consume_token(); /* last IDENTIFIER (this_iter) */ 957: consume_token(); /* last SCOPE */ 958: this2_iter = *nth_token(n); 959: 960: hmi = hack_more_ids (n); 961: 962: if (hmi) 963: return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, hmi); 964: consume_token(); /* last IDENTIFIER (this2_iter) */ 965: return build_parse_node (SCOPE_REF, this_iter.yylval.ttype, 966: this2_iter.yylval.ttype); 967: } 968: else 969: { 970: /* consume_token(); */ /* last IDENTIFIER */ 971: /* leave whatever else we got */ 972: /* return this_iter.yylval.ttype; */ 973: return NULL_TREE; 974: } 975: } 976: } 977: return NULL_TREE; /* @@ may need to backtrack */ 978: } 1.1.1.3 root 979: #else 980: /* [email protected] says: I didn't understand how the code above was intended 981: * to work, so I rewrote it (also changed the interface a bit). This code 982: * dives down an IDENTIFIER/TYPENAME SCOPE ... chain as long as the parsed 983: * type prefix constitutes recognizable (by resolve_scope_to_name) types. 984: * Interface changed like this: 985: * 1. Takes an extra argument containing the name of the the type recognized 986: * so far. 987: * 2. Now returns the name of the type instead of a SCOPE_REF. */ 988: static tree 989: hack_more_ids(n, outer) 990: int n; 991: tree outer; 992: { 993: int ch; 994: tree type, val; 995: 996: scan_tokens (n + 2); 997: if (nth_token (n + 1)->yychar != SCOPE 998: || ((ch = nth_token (n + 2)->yychar) != IDENTIFIER && ch != TYPENAME)) 999: return NULL_TREE; 1000: val = build_parse_node (SCOPE_REF, outer, nth_token (n + 2)->yylval.ttype); 1001: type = resolve_scope_to_name (NULL_TREE, val); 1.1.1.4 root 1002: if (type == NULL_TREE) 1.1.1.3 root 1003: return NULL_TREE; 1004: consume_token (); 1005: consume_token (); 1006: val = hack_more_ids (n, type); 1007: if (! val) 1008: consume_token (); 1009: return val ? val : type; 1010: } 1011: #endif 1.1 root 1012: 1013: #if 0 1014: static struct token 1015: hack_scope () 1016: { 1017: /* we've got a :: - what follows is either a global var or a type. */ 1018: /* hmm, template names can be in the global scope too... */ 1019: tree t1; 1020: struct token rt; 1021: 1022: scan_tokens(1); 1023: if (nth_token(1)->yychar == IDENTIFIER) 1024: { 1025: /* @@ this is probably not right, but doesn't get hit yet */ 1026: t1 = build_parse_node (SCOPE_REF, 1027: NULL_TREE, /* to get "global" scope */ 1028: hack_more_ids(0)); /* do some prefetching */ 1029: rt.yylval.ttype = t1; 1030: rt.yychar = /*SCOPED_*/TYPENAME; 1031: return rt; 1032: } 1033: else 1034: { 1035: rt = *nth_token(0); 1036: consume_token(); 1037: return rt; 1038: } 1039: } 1040: #endif 1041: 1042: /* 1043: * Generations: 1044: * 1045: * PINST: PTYPE { saved_arg_count = arg_count($1) } 1046: * '<' { arg_c = 0; } PARGS '>' 1047: * ; 1048: * PARG: TYPE 1049: * | VALUE 1050: * ; 1051: * (of course the arg counting doesn't work for recursion... Do it right.) 1052: * PARGS: PARG { assert(arg_c == saved_arg_count); } 1053: * | PARG ',' PARGS { arg_c++; } 1054: * ; 1055: * ATYPE: PINST 1056: * | TYPEID 1057: * ; 1058: * TYPE: ATYPE 1059: * | ATYPE { basetype = $1; } '::' TYPEKIDS 1060: * ; 1061: * TYPEKIDS: TYPE { assert ($1 is a member of basetype); } 1062: * | TYPEKIDS { basetype += $1} TYPE { assert( $3 is in basetype ); } 1063: * ; 1064: * 1065: * 1066: * state0: ; ATYPE 1067: * TYPE '<': ac = args($0), base = CALL state1, state3 1068: * TYPE '::': base=$0, state3 1069: * else return TYPE 1070: * state1: ; begin PARGS 1071: * if(ac < list length) punt 1072: * PARG ",": add to list, state1 1073: * PARG ">": add to list, return 1074: * else unravel 1075: * state3: ; begin TYPEKIDS 1076: * TYPE: 1077: */ 1078: 1079: 1080: #ifdef SPEW_DEBUG 1.1.1.4 root 1081: /* debug_yychar takes a yychar (token number) value and prints its name. */ 1.1 root 1082: static int 1083: debug_yychar (yy) 1084: int yy; 1085: { 1.1.1.4 root 1086: /* In cp-parse.y: */ 1.1 root 1087: extern char *debug_yytranslate (); 1088: 1089: int i; 1090: 1091: if(yy<256) { 1092: fprintf (stderr, "<%d: %c >\n", yy, yy); 1093: return 0; 1094: } 1095: fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy)); 1096: return 1; 1097: } 1098: 1099: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.