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