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