spew.c (yylex): Give diagnostic.
[gcc.git] / gcc / cp / spew.c
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)
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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22
23 /* This file is the type analyzer for GNU C++. To debug it, define SPEW_DEBUG
24 when compiling parse.c and spew.c. */
25
26 #include "config.h"
27 #include "system.h"
28 #include "input.h"
29 #include "tree.h"
30 #include "lex.h"
31 #include "cp-tree.h"
32 #include "parse.h"
33 #include "flags.h"
34 #include "obstack.h"
35
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
38 backtracking. */
39
40 /* fifo of tokens recognized and available to parser. */
41 struct token {
42 /* The values for YYCHAR will fit in a short. */
43 short yychar;
44 short end_of_file;
45 YYSTYPE yylval;
46 };
47
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));
51
52 #ifdef SPEW_DEBUG
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));
58 #endif
59
60 /* From lex.c: */
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;
70
71 struct obstack token_obstack;
72 int first_token;
73
74 #ifdef SPEW_DEBUG
75 int spew_debug = 0;
76 static unsigned int yylex_ctr = 0;
77 static int debug_yychar ();
78 #endif
79
80 /* Initialize token_obstack. Called once, from init_parse. */
81
82 void
83 init_spew ()
84 {
85 gcc_obstack_init (&token_obstack);
86 }
87
88 #ifdef SPEW_DEBUG
89 /* Use functions for debugging... */
90
91 /* Return the number of tokens available on the fifo. */
92
93 static int
94 num_tokens ()
95 {
96 return (obstack_object_size (&token_obstack) / sizeof (struct token))
97 - first_token;
98 }
99
100 /* Fetch the token N down the line from the head of the fifo. */
101
102 static struct token*
103 nth_token (n)
104 int n;
105 {
106 /* could just have this do slurp_ implicitly, but this way is easier
107 to debug... */
108 my_friendly_assert (n < num_tokens (), 298);
109 return ((struct token*)obstack_base (&token_obstack)) + n + first_token;
110 }
111
112 /* Add a token to the token fifo. */
113
114 static void
115 add_token (t)
116 struct token* t;
117 {
118 obstack_grow (&token_obstack, t, sizeof (struct token));
119 }
120
121 /* Consume the next token out of the fifo. */
122
123 static void
124 consume_token ()
125 {
126 if (num_tokens () == 1)
127 {
128 obstack_free (&token_obstack, obstack_base (&token_obstack));
129 first_token = 0;
130 }
131 else
132 first_token++;
133 }
134
135 #else
136 /* ...otherwise use macros. */
137
138 #define num_tokens() \
139 ((obstack_object_size (&token_obstack) / sizeof (struct token)) - first_token)
140
141 #define nth_token(N) \
142 (((struct token*)obstack_base (&token_obstack))+(N)+first_token)
143
144 #define add_token(T) obstack_grow (&token_obstack, (T), sizeof (struct token))
145
146 #define consume_token() \
147 (num_tokens () == 1 \
148 ? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \
149 (first_token = 0)) \
150 : first_token++)
151 #endif
152
153 /* Pull in enough tokens from real_yylex that the queue is N long beyond
154 the current token. */
155
156 static void
157 scan_tokens (n)
158 int n;
159 {
160 int i;
161 struct token *tmp;
162
163 /* We cannot read past certain tokens, so make sure we don't. */
164 i = num_tokens ();
165 if (i > n)
166 return;
167 while (i-- > 0)
168 {
169 tmp = nth_token (i);
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 == ';')
173 goto pad_tokens;
174 }
175
176 while (num_tokens () <= n)
177 {
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;
183 end_of_file = 0;
184 if (tmp->yychar == '{'
185 || tmp->yychar == ':'
186 || tmp->yychar == ';')
187 {
188 pad_tokens:
189 while (num_tokens () <= n)
190 {
191 obstack_blank (&token_obstack, sizeof (struct token));
192 tmp = ((struct token *)obstack_next_free (&token_obstack))-1;
193 tmp->yychar = EMPTY;
194 tmp->end_of_file = 0;
195 }
196 }
197 }
198 }
199
200 /* Like _obstack_allocated_p, but stop after checking NLEVELS chunks. */
201
202 static int
203 probe_obstack (h, obj, nlevels)
204 struct obstack *h;
205 tree obj;
206 unsigned int nlevels;
207 {
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 */
210
211 lp = (h)->chunk;
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);
216 nlevels -= 1)
217 {
218 plp = lp->prev;
219 lp = plp;
220 }
221 return nlevels != 0 && lp != 0;
222 }
223
224 /* from lex.c: */
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;
231
232 extern struct obstack *current_obstack, *saveable_obstack;
233 tree got_scope;
234 tree got_object;
235
236 int
237 peekyylex ()
238 {
239 scan_tokens (0);
240 return nth_token (0)->yychar;
241 }
242
243 int
244 yylex ()
245 {
246 struct token tmp_token;
247 tree trrr;
248 int old_looking_for_typename = 0;
249
250 retry:
251 #ifdef SPEW_DEBUG
252 if (spew_debug)
253 {
254 yylex_ctr ++;
255 fprintf (stderr, "\t\t## %d ##", yylex_ctr);
256 }
257 #endif
258
259 if (do_snarf_defarg)
260 {
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;
265 do_snarf_defarg = 0;
266 add_token (&tmp_token);
267 }
268
269 /* if we've got tokens, send them */
270 else if (num_tokens ())
271 {
272 tmp_token= *nth_token (0);
273
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);
283 }
284 else
285 {
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);
291 }
292
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)
297 {
298 case EMPTY:
299 /* This is a lexical no-op. */
300 consume_token ();
301 #ifdef SPEW_DEBUG
302 if (spew_debug)
303 debug_yychar (tmp_token.yychar);
304 #endif
305 goto retry;
306
307 case IDENTIFIER:
308 scan_tokens (1);
309 if (nth_token (1)->yychar == SCOPE)
310 {
311 /* Don't interfere with the setting from an 'aggr' prefix. */
312 old_looking_for_typename = looking_for_typename;
313 looking_for_typename = 1;
314 }
315 else if (nth_token (1)->yychar == '<')
316 looking_for_template = 1;
317
318 trrr = lookup_name (tmp_token.yylval.ttype, -2);
319
320 if (trrr)
321 {
322 tmp_token.yychar = identifier_type (trrr);
323 switch (tmp_token.yychar)
324 {
325 case TYPENAME:
326 case SELFNAME:
327 case NSNAME:
328 case PTYPENAME:
329 lastiddecl = trrr;
330
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;
335 break;
336
337 case PFUNCNAME:
338 case IDENTIFIER:
339 lastiddecl = trrr;
340 break;
341
342 default:
343 my_friendly_abort (101);
344 }
345 }
346 else
347 lastiddecl = NULL_TREE;
348 got_scope = NULL_TREE;
349 /* and fall through to... */
350 case IDENTIFIER_DEFN:
351 case TYPENAME:
352 case TYPENAME_DEFN:
353 case PTYPENAME:
354 case PTYPENAME_DEFN:
355 consume_token ();
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;
360 break;
361
362 case SCSPEC:
363 /* If export, warn that it's unimplemented and go on. */
364 if (tmp_token.yylval.ttype == get_identifier("export"))
365 {
366 warning ("keyword 'export' not implemented and will be ignored");
367 consume_token ();
368 goto retry;
369 }
370 else
371 {
372 ++first_token;
373 break;
374 }
375
376 case NEW:
377 /* do_aggr needs to check if the previous token was RID_NEW,
378 so just increment first_token instead of calling consume_token. */
379 ++first_token;
380 break;
381
382 case TYPESPEC:
383 consume_token ();
384 break;
385
386 case AGGR:
387 *nth_token (0) = tmp_token;
388 do_aggr ();
389 /* fall through to output... */
390 case ENUM:
391 /* Set this again, in case we are rescanning. */
392 looking_for_typename = 2;
393 /* fall through... */
394 default:
395 consume_token ();
396 }
397
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;
402
403 yylval = tmp_token.yylval;
404 yychar = tmp_token.yychar;
405 end_of_file = tmp_token.end_of_file;
406 #ifdef SPEW_DEBUG
407 if (spew_debug)
408 debug_yychar (yychar);
409 #endif
410
411 return yychar;
412 }
413
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. */
419
420 static int
421 do_aggr ()
422 {
423 int yc1, yc2;
424
425 scan_tokens (2);
426 yc1 = nth_token (1)->yychar;
427 if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME)
428 return 0;
429 yc2 = nth_token (2)->yychar;
430 if (yc2 == ';')
431 {
432 /* It's a forward declaration iff we were not preceded by
433 'friend' or `new'. */
434 if (first_token > 0)
435 {
436 if (nth_token (-1)->yychar == SCSPEC
437 && nth_token (-1)->yylval.ttype == ridpointers[(int) RID_FRIEND])
438 return 0;
439 if (nth_token (-1)->yychar == NEW)
440 return 0;
441 }
442 }
443 else if (yc2 != '{' && yc2 != ':')
444 return 0;
445
446 switch (yc1)
447 {
448 case TYPENAME:
449 nth_token (1)->yychar = TYPENAME_DEFN;
450 break;
451 case PTYPENAME:
452 nth_token (1)->yychar = PTYPENAME_DEFN;
453 break;
454 case IDENTIFIER:
455 nth_token (1)->yychar = IDENTIFIER_DEFN;
456 break;
457 default:
458 my_friendly_abort (102);
459 }
460 return 0;
461 }
462
463 #ifdef SPEW_DEBUG
464 /* debug_yychar takes a yychar (token number) value and prints its name. */
465
466 static int
467 debug_yychar (yy)
468 int yy;
469 {
470 /* In parse.y: */
471 extern char *debug_yytranslate ();
472
473 int i;
474
475 if (yy<256) {
476 fprintf (stderr, "<%d: %c >\n", yy, yy);
477 return 0;
478 }
479 fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy));
480 return 1;
481 }
482
483 #endif