1 /* Type Analyzer for GNU C++.
2 Copyright (C) 1987, 89, 92-97, 1998 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. */
37 /* This takes a token stream that hasn't decided much about types and
38 tries to figure out as much as it can, with excessive lookahead and
41 /* fifo of tokens recognized and available to parser. */
43 /* The values for YYCHAR will fit in a short. */
49 static int do_aggr PROTO((void));
50 static int probe_obstack PROTO((struct obstack *, tree, unsigned int));
51 static void scan_tokens PROTO((unsigned int));
54 static int num_tokens PROTO((void));
55 static struct token *nth_token PROTO((int));
56 static void add_token PROTO((struct token *));
57 static void consume_token PROTO((void));
58 static int debug_yychar PROTO((int));
62 /* the declaration found for the last IDENTIFIER token read in.
63 yylex must look this up to detect typedefs, which get token type TYPENAME,
64 so it is left around in case the identifier is not a typedef but is
65 used in a context which makes it a reference to a variable. */
66 extern tree lastiddecl; /* let our brains leak out here too */
67 extern int yychar; /* the lookahead symbol */
68 extern YYSTYPE yylval; /* the semantic value of the */
69 /* lookahead symbol */
70 extern int end_of_file;
72 struct obstack token_obstack;
77 static unsigned int yylex_ctr = 0;
78 static int debug_yychar ();
81 /* Initialize token_obstack. Called once, from init_parse. */
86 gcc_obstack_init (&token_obstack);
90 /* Use functions for debugging... */
92 /* Return the number of tokens available on the fifo. */
97 return (obstack_object_size (&token_obstack) / sizeof (struct token))
101 /* Fetch the token N down the line from the head of the fifo. */
107 /* could just have this do slurp_ implicitly, but this way is easier
109 my_friendly_assert (n < num_tokens (), 298);
110 return ((struct token*)obstack_base (&token_obstack)) + n + first_token;
113 /* Add a token to the token fifo. */
119 obstack_grow (&token_obstack, t, sizeof (struct token));
122 /* Consume the next token out of the fifo. */
127 if (num_tokens () == 1)
129 obstack_free (&token_obstack, obstack_base (&token_obstack));
137 /* ...otherwise use macros. */
139 #define num_tokens() \
140 ((obstack_object_size (&token_obstack) / sizeof (struct token)) - first_token)
142 #define nth_token(N) \
143 (((struct token*)obstack_base (&token_obstack))+(N)+first_token)
145 #define add_token(T) obstack_grow (&token_obstack, (T), sizeof (struct token))
147 #define consume_token() \
148 (num_tokens () == 1 \
149 ? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \
154 /* Pull in enough tokens from real_yylex that the queue is N long beyond
155 the current token. */
164 /* We cannot read past certain tokens, so make sure we don't. */
171 /* Never read past these characters: they might separate
172 the current input stream from one we save away later. */
173 if (tmp->yychar == '{' || tmp->yychar == ':' || tmp->yychar == ';')
177 while (num_tokens () <= n)
179 obstack_blank (&token_obstack, sizeof (struct token));
180 tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
181 tmp->yychar = real_yylex ();
182 tmp->end_of_file = end_of_file;
183 tmp->yylval = yylval;
185 if (tmp->yychar == '{'
186 || tmp->yychar == ':'
187 || tmp->yychar == ';')
190 while (num_tokens () <= n)
192 obstack_blank (&token_obstack, sizeof (struct token));
193 tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
195 tmp->end_of_file = 0;
201 /* Like _obstack_allocated_p, but stop after checking NLEVELS chunks. */
204 probe_obstack (h, obj, nlevels)
207 unsigned int nlevels;
209 register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
210 register struct _obstack_chunk* plp; /* point to previous chunk if any */
213 /* We use >= rather than > since the object cannot be exactly at
214 the beginning of the chunk but might be an empty object exactly
215 at the end of an adjacent chunk. */
216 for (; nlevels != 0 && lp != 0 && ((tree)lp >= obj || (tree)lp->limit < obj);
222 return nlevels != 0 && lp != 0;
226 /* Value is 1 (or 2) if we should try to make the next identifier look like
227 a typename (when it may be a local variable or a class variable).
228 Value is 0 if we treat this name in a default fashion. */
229 extern int looking_for_typename;
230 int looking_for_template;
231 extern int do_snarf_defarg;
233 extern struct obstack *current_obstack, *saveable_obstack;
241 return nth_token (0)->yychar;
247 struct token tmp_token;
248 tree trrr = NULL_TREE;
249 int old_looking_for_typename = 0;
256 fprintf (stderr, "\t\t## %d ##", yylex_ctr);
262 my_friendly_assert (num_tokens () == 0, 2837);
263 tmp_token.yychar = DEFARG;
264 tmp_token.yylval.ttype = snarf_defarg ();
265 tmp_token.end_of_file = 0;
267 add_token (&tmp_token);
270 /* if we've got tokens, send them */
271 else if (num_tokens ())
273 tmp_token= *nth_token (0);
275 /* TMP_TOKEN.YYLVAL.TTYPE may have been allocated on the wrong obstack.
276 If we don't find it in CURRENT_OBSTACK's current or immediately
277 previous chunk, assume it was and copy it to the current obstack. */
278 if ((tmp_token.yychar == CONSTANT
279 || tmp_token.yychar == STRING)
280 && ! TREE_PERMANENT (tmp_token.yylval.ttype)
281 && ! probe_obstack (current_obstack, tmp_token.yylval.ttype, 2)
282 && ! probe_obstack (saveable_obstack, tmp_token.yylval.ttype, 2))
283 tmp_token.yylval.ttype = copy_node (tmp_token.yylval.ttype);
287 /* if not, grab the next one and think about it */
288 tmp_token.yychar = real_yylex ();
289 tmp_token.yylval = yylval;
290 tmp_token.end_of_file = end_of_file;
291 add_token (&tmp_token);
294 /* many tokens just need to be returned. At first glance, all we
295 have to do is send them back up, but some of them are needed to
296 figure out local context. */
297 switch (tmp_token.yychar)
300 /* This is a lexical no-op. */
304 debug_yychar (tmp_token.yychar);
310 if (nth_token (1)->yychar == SCOPE)
312 /* Don't interfere with the setting from an 'aggr' prefix. */
313 old_looking_for_typename = looking_for_typename;
314 looking_for_typename = 1;
316 else if (nth_token (1)->yychar == '<')
317 looking_for_template = 1;
319 trrr = lookup_name (tmp_token.yylval.ttype, -2);
323 tmp_token.yychar = identifier_type (trrr);
324 switch (tmp_token.yychar)
332 /* If this got special lookup, remember it. In these cases,
333 we don't have to worry about being a declarator-id. */
334 if (got_scope || got_object)
335 tmp_token.yylval.ttype = trrr;
344 my_friendly_abort (101);
348 lastiddecl = NULL_TREE;
349 got_scope = NULL_TREE;
350 /* and fall through to... */
351 case IDENTIFIER_DEFN:
357 /* If we see a SCOPE next, restore the old value.
358 Otherwise, we got what we want. */
359 looking_for_typename = old_looking_for_typename;
360 looking_for_template = 0;
364 /* If export, warn that it's unimplemented and go on. */
365 if (tmp_token.yylval.ttype == get_identifier("export"))
367 warning ("keyword 'export' not implemented and will be ignored");
378 /* do_aggr needs to check if the previous token was RID_NEW,
379 so just increment first_token instead of calling consume_token. */
388 *nth_token (0) = tmp_token;
390 /* fall through to output... */
392 /* Set this again, in case we are rescanning. */
393 looking_for_typename = 2;
394 /* fall through... */
399 /* class member lookup only applies to the first token after the object
400 expression, except for explicit destructor calls. */
401 if (tmp_token.yychar != '~')
402 got_object = NULL_TREE;
404 /* Clear looking_for_typename if we got 'enum { ... };'. */
405 if (tmp_token.yychar == '{' || tmp_token.yychar == ':'
406 || tmp_token.yychar == ';')
407 looking_for_typename = 0;
409 yylval = tmp_token.yylval;
410 yychar = tmp_token.yychar;
411 end_of_file = tmp_token.end_of_file;
414 debug_yychar (yychar);
420 /* token[0] == AGGR (struct/union/enum)
421 Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN.
422 If token[2] == '{' or ':' then it's TYPENAME_DEFN.
423 It's also a definition if it's a forward declaration (as in 'struct Foo;')
424 which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW. */
432 yc1 = nth_token (1)->yychar;
433 if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
435 yc2 = nth_token (2)->yychar;
438 /* It's a forward declaration iff we were not preceded by
439 'friend' or `new'. */
442 if (nth_token (-1)->yychar == SCSPEC
443 && nth_token (-1)->yylval.ttype == ridpointers[(int) RID_FRIEND])
445 if (nth_token (-1)->yychar == NEW)
449 else if (yc2 != '{' && yc2 != ':')
455 nth_token (1)->yychar = TYPENAME_DEFN;
458 nth_token (1)->yychar = PTYPENAME_DEFN;
461 nth_token (1)->yychar = IDENTIFIER_DEFN;
464 my_friendly_abort (102);
470 /* debug_yychar takes a yychar (token number) value and prints its name. */
477 extern char *debug_yytranslate ();
482 fprintf (stderr, "<%d: %c >\n", yy, yy);
485 fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy));