(distribute_notes, case REG_DEAD): If a call uses a
[official-gcc.git] / gcc / cp / spew.c
blobea00ba273b373cb9dfc0b2bbbb89318e2a601459
1 /* Type Analyzer for GNU C++.
2 Copyright (C) 1987, 1989, 1992, 1993 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)
10 any later version.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 /* This file is the type analyzer for GNU C++. To debug it, define SPEW_DEBUG
23 when compiling parse.c and spew.c. */
25 #include "config.h"
26 #include <stdio.h>
27 #include "input.h"
28 #include "tree.h"
29 #include "lex.h"
30 #include "parse.h"
31 #include "cp-tree.h"
32 #include "flags.h"
33 #include "obstack.h"
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. */
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;
47 static int do_aggr ();
49 /* From lex.c: */
50 /* the declaration found for the last IDENTIFIER token read in.
51 yylex must look this up to detect typedefs, which get token type TYPENAME,
52 so it is left around in case the identifier is not a typedef but is
53 used in a context which makes it a reference to a variable. */
54 extern tree lastiddecl; /* let our brains leak out here too */
55 extern int yychar; /* the lookahead symbol */
56 extern YYSTYPE yylval; /* the semantic value of the */
57 /* lookahead symbol */
58 extern int end_of_file;
60 struct obstack token_obstack;
61 int first_token;
63 #ifdef SPEW_DEBUG
64 int spew_debug = 0;
65 static unsigned int yylex_ctr = 0;
66 static int debug_yychar ();
67 #endif
69 /* Initialize token_obstack. Called once, from init_lex. */
70 void
71 init_spew ()
73 gcc_obstack_init(&token_obstack);
76 #ifdef SPEW_DEBUG
77 /* Use functions for debugging... */
79 /* Return the number of tokens available on the fifo. */
80 static int
81 num_tokens ()
83 return (obstack_object_size(&token_obstack)/sizeof(struct token))
84 - first_token;
87 /* Fetch the token N down the line from the head of the fifo. */
88 static struct token*
89 nth_token (n)
90 int n;
92 /* could just have this do slurp_ implicitly, but this way is easier
93 * to debug... */
94 my_friendly_assert (n < num_tokens(), 298);
95 return ((struct token*)obstack_base(&token_obstack))+n+first_token;
98 /* Add a token to the token fifo. */
99 static void
100 add_token (t)
101 struct token* t;
103 obstack_grow(&token_obstack,t,sizeof (struct token));
106 /* Consume the next token out of the fifo. */
107 static void
108 consume_token()
110 if (num_tokens() == 1)
112 obstack_free(&token_obstack, obstack_base (&token_obstack));
113 first_token = 0;
115 else
116 first_token++;
119 #else
120 /* ...otherwise use macros. */
122 #define num_tokens() \
123 ((obstack_object_size(&token_obstack)/sizeof(struct token)) - first_token)
125 #define nth_token(N) \
126 (((struct token*)obstack_base(&token_obstack))+(N)+first_token)
128 #define add_token(T) obstack_grow(&token_obstack, (T), sizeof (struct token))
130 #define consume_token() \
131 (num_tokens() == 1 \
132 ? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \
133 (first_token = 0)) \
134 : first_token++)
135 #endif
137 /* Pull in enough tokens from real_yylex that the queue is N long beyond
138 the current token. */
140 static void
141 scan_tokens (n)
142 int n;
144 int i;
145 struct token *tmp;
147 /* We cannot read past certain tokens, so make sure we don't. */
148 i = num_tokens ();
149 if (i > n)
150 return;
151 while (i-- > 0)
153 tmp = nth_token (i);
154 /* Never read past these characters: they might separate
155 the current input stream from one we save away later. */
156 if (tmp->yychar == '{' || tmp->yychar == ':' || tmp->yychar == ';')
157 goto pad_tokens;
160 while (num_tokens() <= n)
162 obstack_blank(&token_obstack,sizeof (struct token));
163 tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
164 tmp->yychar = real_yylex();
165 tmp->end_of_file = end_of_file;
166 tmp->yylval = yylval;
167 end_of_file = 0;
168 if (tmp->yychar == '{'
169 || tmp->yychar == ':'
170 || tmp->yychar == ';')
172 pad_tokens:
173 while (num_tokens () <= n)
175 obstack_blank(&token_obstack,sizeof (struct token));
176 tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
177 tmp->yychar = EMPTY;
178 tmp->end_of_file = 0;
184 /* Create room for N tokens at the front of the fifo. This is used
185 to insert new tokens into the stream ahead of the current token. */
187 static void
188 shift_tokens (n)
189 int n;
191 if (first_token >= n)
192 first_token -= n;
193 else
195 int old_token_count = num_tokens ();
196 char *tmp;
198 obstack_blank (&token_obstack, (n-first_token) * sizeof (struct token));
199 if (old_token_count)
201 tmp = (char *)alloca ((num_tokens () + (n-first_token))
202 * sizeof (struct token));
203 /* This move does not rely on the system being able to handle
204 overlapping moves. */
205 bcopy (nth_token (0), tmp, old_token_count * sizeof (struct token));
206 bcopy (tmp, nth_token (n), old_token_count * sizeof (struct token));
208 first_token = 0;
212 static int
213 probe_obstack (h, obj, nlevels)
214 struct obstack *h;
215 tree obj;
216 unsigned int nlevels;
218 register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
219 register struct _obstack_chunk* plp; /* point to previous chunk if any */
221 lp = (h)->chunk;
222 /* We use >= rather than > since the object cannot be exactly at
223 the beginning of the chunk but might be an empty object exactly
224 at the end of an adjacent chunk. */
225 for (; nlevels != 0 && lp != 0 && ((tree)lp >= obj || (tree)lp->limit < obj);
226 nlevels -= 1)
228 plp = lp->prev;
229 lp = plp;
231 return nlevels != 0 && lp != 0;
234 /* from lex.c: */
235 /* Value is 1 (or 2) if we should try to make the next identifier look like
236 a typename (when it may be a local variable or a class variable).
237 Value is 0 if we treat this name in a default fashion. */
238 extern int looking_for_typename;
239 int looking_for_template;
241 extern struct obstack *current_obstack, *saveable_obstack;
242 tree got_scope;
245 yylex()
247 struct token tmp_token;
248 tree trrr;
250 retry:
251 #ifdef SPEW_DEBUG
252 if (spew_debug)
254 yylex_ctr ++;
255 fprintf(stderr, "\t\t## %d ##",yylex_ctr);
257 #endif
259 /* if we've got tokens, send them */
260 if (num_tokens())
262 tmp_token= *nth_token(0);
264 /* TMP_TOKEN.YYLVAL.TTYPE may have been allocated on the wrong obstack.
265 If we don't find it in CURRENT_OBSTACK's current or immediately
266 previous chunk, assume it was and copy it to the current obstack. */
267 if ((tmp_token.yychar == CONSTANT
268 || tmp_token.yychar == STRING)
269 && ! TREE_PERMANENT (tmp_token.yylval.ttype)
270 && ! probe_obstack (current_obstack, tmp_token.yylval.ttype, 2)
271 && ! probe_obstack (saveable_obstack, tmp_token.yylval.ttype, 2))
272 tmp_token.yylval.ttype = copy_node (tmp_token.yylval.ttype);
274 else
276 /* if not, grab the next one and think about it */
277 tmp_token.yychar = real_yylex ();
278 tmp_token.yylval = yylval;
279 tmp_token.end_of_file = end_of_file;
280 add_token(&tmp_token);
283 /* many tokens just need to be returned. At first glance, all we
284 * have to do is send them back up, but some of them are needed to
285 * figure out local context. */
286 switch(tmp_token.yychar)
288 case EMPTY:
289 /* This is a lexical no-op. */
290 consume_token ();
291 #ifdef SPEW_DEBUG
292 if (spew_debug)
293 debug_yychar (tmp_token.yychar);
294 #endif
295 goto retry;
297 case IDENTIFIER:
298 scan_tokens (1);
299 if (nth_token (1)->yychar == SCOPE)
300 /* Don't interfere with the setting from an 'aggr' prefix. */
301 looking_for_typename++;
302 else if (nth_token (1)->yychar == '<')
303 looking_for_template = 1;
305 trrr = lookup_name (tmp_token.yylval.ttype, -2);
307 if (trrr)
309 tmp_token.yychar = identifier_type (trrr);
310 switch (tmp_token.yychar)
312 case TYPENAME:
313 lastiddecl = identifier_typedecl_value (tmp_token.yylval.ttype);
314 if (lastiddecl != trrr)
316 lastiddecl = trrr;
317 if (got_scope)
318 tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr);
320 break;
321 case IDENTIFIER:
322 lastiddecl = trrr;
323 break;
324 case PTYPENAME:
325 lastiddecl = NULL_TREE;
326 break;
327 default:
328 my_friendly_abort (101);
331 else
332 lastiddecl = trrr;
333 got_scope = NULL_TREE;
334 /* and fall through to... */
335 case TYPENAME:
336 case PTYPENAME:
337 consume_token ();
338 if (looking_for_typename > 0)
339 looking_for_typename--;
340 looking_for_template = 0;
341 break;
343 case SCSPEC:
344 /* do_aggr needs to check if the previous token was RID_FRIEND,
345 so just increment first_token instead of calling consume_token. */
346 first_token++;
347 break;
348 case TYPESPEC:
349 consume_token ();
350 break;
352 case AGGR:
353 *nth_token(0) = tmp_token;
354 do_aggr ();
355 /* fall through to output... */
356 case ENUM:
357 /* Set this again, in case we are rescanning. */
358 looking_for_typename = 1;
359 /* fall through... */
360 default:
361 consume_token();
364 yylval = tmp_token.yylval;
365 yychar = tmp_token.yychar;
366 end_of_file = tmp_token.end_of_file;
367 #ifdef SPEW_DEBUG
368 if (spew_debug)
369 debug_yychar(yychar);
370 #endif
371 return yychar;
374 /* token[0] == AGGR (struct/union/enum)
375 * Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN.
376 * If token[2] == '{' or ':' then it's TYPENAME_DEFN.
377 * It's also a definition if it's a forward declaration (as in 'struct Foo;')
378 * which we can tell lf token[2] == ';' *and* token[-1] != FRIEND.
380 static int
381 do_aggr ()
383 int yc1, yc2;
385 scan_tokens (2);
386 yc1 = nth_token (1)->yychar;
387 if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
388 return 0;
389 yc2 = nth_token (2)->yychar;
390 if (yc2 == ';')
392 /* It's a forward declaration iff we were not preceded by 'friend'. */
393 if (first_token > 0 && nth_token (-1)->yychar == SCSPEC
394 && nth_token (-1)->yylval.ttype == ridpointers[(int) RID_FRIEND])
395 return 0;
397 else if (yc2 != '{' && yc2 != ':')
398 return 0;
400 switch (yc1)
402 case TYPENAME:
403 nth_token (1)->yychar = TYPENAME_DEFN;
404 break;
405 case PTYPENAME:
406 nth_token (1)->yychar = PTYPENAME_DEFN;
407 break;
408 case IDENTIFIER:
409 nth_token (1)->yychar = IDENTIFIER_DEFN;
410 break;
411 default:
412 my_friendly_abort (102);
414 return 0;
417 #ifdef SPEW_DEBUG
418 /* debug_yychar takes a yychar (token number) value and prints its name. */
419 static int
420 debug_yychar (yy)
421 int yy;
423 /* In parse.y: */
424 extern char *debug_yytranslate ();
426 int i;
428 if(yy<256) {
429 fprintf (stderr, "<%d: %c >\n", yy, yy);
430 return 0;
432 fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy));
433 return 1;
436 #endif