1 /* Type Analyzer for GNU C++.
2 Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
3 Hacked... nay, bludgeoned... by Mark Eichin (eichin@cygnus.com)
5 This file is part of GNU CC.
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)
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.
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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 /* This file is the type analyzer for GNU C++. To debug it, define SPEW_DEBUG
24 when compiling parse.c and spew.c. */
36 /* This takes a token stream that hasn't decided much about types and
37 tries to figure out as much as it can, with excessive lookahead and
40 /* fifo of tokens recognized and available to parser. */
42 /* The values for YYCHAR will fit in a short. */
48 static int do_aggr
PROTO((void));
49 static int probe_obstack
PROTO((struct obstack
*, tree
, unsigned int));
50 static void scan_tokens
PROTO((int));
53 static int num_tokens
PROTO((void));
54 static struct token
*nth_token
PROTO((int));
55 static void add_token
PROTO((struct token
*));
56 static void consume_token
PROTO((void));
57 static int debug_yychar
PROTO((int));
61 /* the declaration found for the last IDENTIFIER token read in.
62 yylex must look this up to detect typedefs, which get token type TYPENAME,
63 so it is left around in case the identifier is not a typedef but is
64 used in a context which makes it a reference to a variable. */
65 extern tree lastiddecl
; /* let our brains leak out here too */
66 extern int yychar
; /* the lookahead symbol */
67 extern YYSTYPE yylval
; /* the semantic value of the */
68 /* lookahead symbol */
69 extern int end_of_file
;
71 struct obstack token_obstack
;
76 static unsigned int yylex_ctr
= 0;
77 static int debug_yychar ();
80 /* Initialize token_obstack. Called once, from init_parse. */
85 gcc_obstack_init (&token_obstack
);
89 /* Use functions for debugging... */
91 /* Return the number of tokens available on the fifo. */
96 return (obstack_object_size (&token_obstack
) / sizeof (struct token
))
100 /* Fetch the token N down the line from the head of the fifo. */
106 /* could just have this do slurp_ implicitly, but this way is easier
108 my_friendly_assert (n
< num_tokens (), 298);
109 return ((struct token
*)obstack_base (&token_obstack
)) + n
+ first_token
;
112 /* Add a token to the token fifo. */
118 obstack_grow (&token_obstack
, t
, sizeof (struct token
));
121 /* Consume the next token out of the fifo. */
126 if (num_tokens () == 1)
128 obstack_free (&token_obstack
, obstack_base (&token_obstack
));
136 /* ...otherwise use macros. */
138 #define num_tokens() \
139 ((obstack_object_size (&token_obstack) / sizeof (struct token)) - first_token)
141 #define nth_token(N) \
142 (((struct token*)obstack_base (&token_obstack))+(N)+first_token)
144 #define add_token(T) obstack_grow (&token_obstack, (T), sizeof (struct token))
146 #define consume_token() \
147 (num_tokens () == 1 \
148 ? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \
153 /* Pull in enough tokens from real_yylex that the queue is N long beyond
154 the current token. */
163 /* We cannot read past certain tokens, so make sure we don't. */
170 /* Never read past these characters: they might separate
171 the current input stream from one we save away later. */
172 if (tmp
->yychar
== '{' || tmp
->yychar
== ':' || tmp
->yychar
== ';')
176 while (num_tokens () <= n
)
178 obstack_blank (&token_obstack
, sizeof (struct token
));
179 tmp
= ((struct token
*)obstack_next_free (&token_obstack
))-1;
180 tmp
->yychar
= real_yylex ();
181 tmp
->end_of_file
= end_of_file
;
182 tmp
->yylval
= yylval
;
184 if (tmp
->yychar
== '{'
185 || tmp
->yychar
== ':'
186 || tmp
->yychar
== ';')
189 while (num_tokens () <= n
)
191 obstack_blank (&token_obstack
, sizeof (struct token
));
192 tmp
= ((struct token
*)obstack_next_free (&token_obstack
))-1;
194 tmp
->end_of_file
= 0;
200 /* Like _obstack_allocated_p, but stop after checking NLEVELS chunks. */
203 probe_obstack (h
, obj
, nlevels
)
206 unsigned int nlevels
;
208 register struct _obstack_chunk
* lp
; /* below addr of any objects in this chunk */
209 register struct _obstack_chunk
* plp
; /* point to previous chunk if any */
212 /* We use >= rather than > since the object cannot be exactly at
213 the beginning of the chunk but might be an empty object exactly
214 at the end of an adjacent chunk. */
215 for (; nlevels
!= 0 && lp
!= 0 && ((tree
)lp
>= obj
|| (tree
)lp
->limit
< obj
);
221 return nlevels
!= 0 && lp
!= 0;
225 /* Value is 1 (or 2) if we should try to make the next identifier look like
226 a typename (when it may be a local variable or a class variable).
227 Value is 0 if we treat this name in a default fashion. */
228 extern int looking_for_typename
;
229 int looking_for_template
;
230 extern int do_snarf_defarg
;
232 extern struct obstack
*current_obstack
, *saveable_obstack
;
240 return nth_token (0)->yychar
;
246 struct token tmp_token
;
248 int old_looking_for_typename
= 0;
255 fprintf (stderr
, "\t\t## %d ##", yylex_ctr
);
261 my_friendly_assert (num_tokens () == 0, 2837);
262 tmp_token
.yychar
= DEFARG
;
263 tmp_token
.yylval
.ttype
= snarf_defarg ();
264 tmp_token
.end_of_file
= 0;
266 add_token (&tmp_token
);
269 /* if we've got tokens, send them */
270 else if (num_tokens ())
272 tmp_token
= *nth_token (0);
274 /* TMP_TOKEN.YYLVAL.TTYPE may have been allocated on the wrong obstack.
275 If we don't find it in CURRENT_OBSTACK's current or immediately
276 previous chunk, assume it was and copy it to the current obstack. */
277 if ((tmp_token
.yychar
== CONSTANT
278 || tmp_token
.yychar
== STRING
)
279 && ! TREE_PERMANENT (tmp_token
.yylval
.ttype
)
280 && ! probe_obstack (current_obstack
, tmp_token
.yylval
.ttype
, 2)
281 && ! probe_obstack (saveable_obstack
, tmp_token
.yylval
.ttype
, 2))
282 tmp_token
.yylval
.ttype
= copy_node (tmp_token
.yylval
.ttype
);
286 /* if not, grab the next one and think about it */
287 tmp_token
.yychar
= real_yylex ();
288 tmp_token
.yylval
= yylval
;
289 tmp_token
.end_of_file
= end_of_file
;
290 add_token (&tmp_token
);
293 /* many tokens just need to be returned. At first glance, all we
294 have to do is send them back up, but some of them are needed to
295 figure out local context. */
296 switch (tmp_token
.yychar
)
299 /* This is a lexical no-op. */
303 debug_yychar (tmp_token
.yychar
);
309 if (nth_token (1)->yychar
== SCOPE
)
311 /* Don't interfere with the setting from an 'aggr' prefix. */
312 old_looking_for_typename
= looking_for_typename
;
313 looking_for_typename
= 1;
315 else if (nth_token (1)->yychar
== '<')
316 looking_for_template
= 1;
318 trrr
= lookup_name (tmp_token
.yylval
.ttype
, -2);
322 tmp_token
.yychar
= identifier_type (trrr
);
323 switch (tmp_token
.yychar
)
331 /* If this got special lookup, remember it. In these cases,
332 we don't have to worry about being a declarator-id. */
333 if (got_scope
|| got_object
)
334 tmp_token
.yylval
.ttype
= trrr
;
343 my_friendly_abort (101);
347 lastiddecl
= NULL_TREE
;
348 got_scope
= NULL_TREE
;
349 /* and fall through to... */
350 case IDENTIFIER_DEFN
:
356 /* If we see a SCOPE next, restore the old value.
357 Otherwise, we got what we want. */
358 looking_for_typename
= old_looking_for_typename
;
359 looking_for_template
= 0;
363 /* If export, warn that it's unimplemented and go on. */
364 if (tmp_token
.yylval
.ttype
== get_identifier("export"))
366 warning ("keyword 'export' not implemented and will be ignored");
377 /* do_aggr needs to check if the previous token was RID_NEW,
378 so just increment first_token instead of calling consume_token. */
387 *nth_token (0) = tmp_token
;
389 /* fall through to output... */
391 /* Set this again, in case we are rescanning. */
392 looking_for_typename
= 2;
393 /* fall through... */
398 /* class member lookup only applies to the first token after the object
399 expression, except for explicit destructor calls. */
400 if (tmp_token
.yychar
!= '~')
401 got_object
= NULL_TREE
;
403 yylval
= tmp_token
.yylval
;
404 yychar
= tmp_token
.yychar
;
405 end_of_file
= tmp_token
.end_of_file
;
408 debug_yychar (yychar
);
414 /* token[0] == AGGR (struct/union/enum)
415 Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN.
416 If token[2] == '{' or ':' then it's TYPENAME_DEFN.
417 It's also a definition if it's a forward declaration (as in 'struct Foo;')
418 which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW. */
426 yc1
= nth_token (1)->yychar
;
427 if (yc1
!= TYPENAME
&& yc1
!= IDENTIFIER
&& yc1
!= PTYPENAME
)
429 yc2
= nth_token (2)->yychar
;
432 /* It's a forward declaration iff we were not preceded by
433 'friend' or `new'. */
436 if (nth_token (-1)->yychar
== SCSPEC
437 && nth_token (-1)->yylval
.ttype
== ridpointers
[(int) RID_FRIEND
])
439 if (nth_token (-1)->yychar
== NEW
)
443 else if (yc2
!= '{' && yc2
!= ':')
449 nth_token (1)->yychar
= TYPENAME_DEFN
;
452 nth_token (1)->yychar
= PTYPENAME_DEFN
;
455 nth_token (1)->yychar
= IDENTIFIER_DEFN
;
458 my_friendly_abort (102);
464 /* debug_yychar takes a yychar (token number) value and prints its name. */
471 extern char *debug_yytranslate ();
476 fprintf (stderr
, "<%d: %c >\n", yy
, yy
);
479 fprintf (stderr
, "<%d:%s>\n", yy
, debug_yytranslate (yy
));