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