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