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