|
|
1.1 root 1: /* Separate lexical analyzer for GNU C++.
2: Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
3: Hacked by Michael Tiemann ([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 lexical analyzer for GNU C++. */
23:
24: #include <sys/types.h>
25: #include <stdio.h>
26: #include <errno.h>
27: #include <setjmp.h>
28: #include <string.h>
29: #include "config.h"
30: #include "input.h"
31: #include "tree.h"
32: #include "cp-lex.h"
33: #include "cp-parse.h"
34: #include "cp-tree.h"
35: #include "flags.h"
36: #include "obstack.h"
37: #include <assert.h>
38: extern int errno; /* needed for VAX. */
39: extern jmp_buf toplevel;
40:
41: #define obstack_chunk_alloc xmalloc
42: #define obstack_chunk_free free
43:
44: extern int xmalloc ();
45: extern void free ();
46:
47: extern struct obstack *expression_obstack, permanent_obstack;
48: extern struct obstack *current_obstack, *saveable_obstack;
49:
50: extern double atof ();
51:
52: extern char *get_directive_line (); /* In c-common.c */
53:
54: /* Given a file name X, return the nondirectory portion.
55: Keep in mind that X can be computed more than once. */
56: #ifndef FILE_NAME_NONDIRECTORY
57: #define FILE_NAME_NONDIRECTORY(X) \
58: (strrchr (X, '/') != 0 ? strrchr (X, '/') + 1 : X)
59: #endif
60:
61: /* If you don't have strrchr, but instead have rindex,
62: add your machine to this list, and send mail to
63: [email protected]. */
64: #if defined(sequent) || defined(convex)
65: #define strrchr rindex
66: #endif
67: extern char *strrchr ();
68: void extract_interface_info ();
69:
70: /* This obstack is needed to hold text. It is not safe to use
71: TOKEN_BUFFER because `check_newline' calls `yylex'. */
72: static struct obstack inline_text_obstack;
73: static char *inline_text_firstobj;
74:
75: int end_of_file;
76:
77: extern int first_token;
78: extern struct obstack token_obstack;
79:
80: /* ??? Don't really know where this goes yet. */
81: #if 1
82: #include "cp-input.c"
83: #else
84: extern void put_back (/* int */);
85: extern int input_redirected ();
86: extern void feed_input (/* char *, int, struct obstack * */);
87: #endif
88:
89: /* Holds translations from TREE_CODEs to operator name strings,
90: i.e., opname_tab[PLUS_EXPR] == "+". */
91: char **opname_tab;
92: char **assignop_tab;
93:
94: #define YYEMPTY -2
95: extern int yychar; /* the lookahead symbol */
96: extern YYSTYPE yylval; /* the semantic value of the */
97: /* lookahead symbol */
98:
99: #if 0
100: YYLTYPE yylloc; /* location data for the lookahead */
101: /* symbol */
102: #endif
103:
104:
105: /* the declaration found for the last IDENTIFIER token read in.
106: yylex must look this up to detect typedefs, which get token type TYPENAME,
107: so it is left around in case the identifier is not a typedef but is
108: used in a context which makes it a reference to a variable. */
109: extern tree lastiddecl;
110:
111: /* C++ extensions */
112: extern tree ridpointers[]; /* need this up here */
113:
114: /* We may keep statistics about how long which files took to compile. */
115: static int header_time, body_time;
116: static tree get_time_identifier ();
117: static tree filename_times;
118: static tree this_filename_time;
119:
120: /* For implementing #pragma unit. */
121: tree current_unit_name;
122: tree current_unit_language;
123:
124: /* Array for holding counts of the numbers of tokens seen. */
125: extern int *token_count;
126:
127: /* Textual definition used for default functions. */
128: static char default_def[] = "{}";
129:
130: /* Return something to represent absolute declarators containing a *.
131: TARGET is the absolute declarator that the * contains.
132: TYPE_QUALS is a list of modifiers such as const or volatile
133: to apply to the pointer type, represented as identifiers.
134:
135: We return an INDIRECT_REF whose "contents" are TARGET
136: and whose type is the modifier list. */
137:
138: tree
139: make_pointer_declarator (type_quals, target)
140: tree type_quals, target;
141: {
142: if (target && TREE_CODE (target) == IDENTIFIER_NODE
143: && ANON_AGGRNAME_P (target))
144: error ("type name expected before `*'");
145: target = build_parse_node (INDIRECT_REF, target);
146: TREE_TYPE (target) = type_quals;
147: return target;
148: }
149:
150: /* Return something to represent absolute declarators containing a &.
151: TARGET is the absolute declarator that the & contains.
152: TYPE_QUALS is a list of modifiers such as const or volatile
153: to apply to the reference type, represented as identifiers.
154:
155: We return an ADDR_EXPR whose "contents" are TARGET
156: and whose type is the modifier list. */
157:
158: tree
159: make_reference_declarator (type_quals, target)
160: tree type_quals, target;
161: {
162: if (target)
163: {
164: if (TREE_CODE (target) == ADDR_EXPR)
165: {
166: error ("cannot declare references to references");
167: return target;
168: }
169: if (TREE_CODE (target) == INDIRECT_REF)
170: {
171: error ("cannot declare pointers to references");
172: return target;
173: }
174: if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
175: error ("type name expected before `&'");
176: }
177: target = build_parse_node (ADDR_EXPR, target);
178: TREE_TYPE (target) = type_quals;
179: return target;
180: }
181:
182: /* Build names and nodes for overloaded operators. */
183:
184: tree ansi_opname[LAST_CPLUS_TREE_CODE];
185: tree ansi_assopname[LAST_CPLUS_TREE_CODE];
186:
187: char *
188: operator_name_string (name)
189: tree name;
190: {
191: char *opname = IDENTIFIER_POINTER (name) + 2;
192: tree *opname_table;
193: int i, assign;
194:
195: /* Works for builtin and user defined types. */
196: if (IDENTIFIER_GLOBAL_VALUE (name)
197: && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
198: return IDENTIFIER_POINTER (name);
199:
200: if (opname[0] == 'a' && opname[2] != '\0')
201: {
202: opname += 1;
203: assign = 1;
204: opname_table = ansi_assopname;
205: }
206: else
207: {
208: assign = 0;
209: opname_table = ansi_opname;
210: }
211:
212: for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
213: {
214: if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
215: && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
216: break;
217: }
218:
219: if (i == LAST_CPLUS_TREE_CODE)
220: return "<invalid operator>";
221:
222: if (assign)
223: return assignop_tab[i];
224: else
225: return opname_tab[i];
226: }
227:
228: int interface_only; /* whether or not current file is only for
229: interface definitions. */
230: int interface_unknown; /* whether or not we know this class
231: to behave according to #pragma interface. */
232:
233: /* lexical analyzer */
234:
235: static int maxtoken; /* Current nominal length of token buffer. */
236: char *token_buffer; /* Pointer to token buffer.
237: Actual allocated length is maxtoken + 2. */
238: static int max_wide; /* Current nominal length of wide_buffer. */
239: static int *wide_buffer; /* Pointer to wide-string buffer.
240: Actual allocated length is max_wide + 1. */
241:
242: #define NORID RID_UNUSED
243:
244: #include "cp-hash.h"
245:
246: int check_newline ();
247:
248: static int skip_white_space ();
249:
250: static tree
251: get_time_identifier (name)
252: char *name;
253: {
254: tree time_identifier;
255: int len = strlen (name);
256: char *buf = (char *)alloca (len + 6);
257: strcpy (buf, "file ");
258: bcopy (name, buf+5, len);
259: buf[len+5] = '\0';
260: time_identifier = get_identifier (buf);
261: if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
262: {
263: push_obstacks_nochange ();
264: end_temporary_allocation ();
265: IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
266: IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
267: IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times;
268: filename_times = time_identifier;
269: pop_obstacks ();
270: }
271: return time_identifier;
272: }
273:
274: #ifdef __GNUC__
275: __inline
276: #endif
277: static int
278: my_get_run_time ()
279: {
280: int old_quiet_flag = quiet_flag;
281: int this_time;
282: quiet_flag = 0;
283: this_time = get_run_time ();
284: quiet_flag = old_quiet_flag;
285: return this_time;
286: }
287:
288: /* Table indexed by tree code giving a string containing a character
289: classifying the tree code. Possibilities are
290: t, d, s, c, r, <, 1 and 2. See cp-tree.def for details. */
291:
292: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
293:
294: char *cplus_tree_code_type[] = {
295: "x",
296: #include "cp-tree.def"
297: };
298: #undef DEFTREECODE
299:
300: /* Table indexed by tree code giving number of expression
301: operands beyond the fixed part of the node structure.
302: Not used for types or decls. */
303:
304: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
305:
306: int cplus_tree_code_length[] = {
307: 0,
308: #include "cp-tree.def"
309: };
310: #undef DEFTREECODE
311:
312: /* Names of tree components.
313: Used for printing out the tree and error messages. */
314: #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
315:
316: char *cplus_tree_code_name[] = {
317: "@@dummy",
318: #include "cp-tree.def"
319: };
320: #undef DEFTREECODE
321:
322: /* toplev.c needs to call these. */
323:
324: void
325: lang_init ()
326: {
327: /* the beginning of the file is a new line; check for # */
328: /* With luck, we discover the real source file's name from that
329: and put it in input_filename. */
330: put_back (check_newline ());
331:
332: if (flag_cadillac)
333: cadillac_start ();
334: if (flag_gnu_xref) GNU_xref_begin (input_filename);
335: }
336:
337: void
338: lang_finish ()
339: {
340: extern int errorcount, sorrycount;
341: if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
342: }
343:
344: void
345: init_filename_times ()
346: {
347: this_filename_time = get_time_identifier ("<top level>");
348: if (flag_detailed_statistics)
349: {
350: header_time = 0;
351: body_time = my_get_run_time ();
352: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time;
353: }
354: }
355:
356: /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
357: Stuck this hack in to get the files open correctly; this is called
358: in place of init_lex if we are an unexec'd binary. */
359: void
360: reinit_lang_specific ()
361: {
362: init_filename_times ();
363: reinit_search_statistics ();
364: }
365:
366: void
367: init_lex ()
368: {
369: extern int *init_parse ();
370: extern char *(*decl_printable_name) ();
371: extern char *lang_printable_name ();
372:
373: int i;
374:
375: /* Initialize the lookahead machinery. */
376: init_spew ();
377:
378: /* Make identifier nodes long enough for the language-specific slots. */
379: set_identifier_size (sizeof (struct lang_identifier));
380: decl_printable_name = lang_printable_name;
381:
382: init_cplus_expand ();
383:
384: tree_code_type
385: = (char **) realloc (tree_code_type,
386: sizeof (char *) * LAST_CPLUS_TREE_CODE);
387: tree_code_length
388: = (int *) realloc (tree_code_length,
389: sizeof (int) * LAST_CPLUS_TREE_CODE);
390: tree_code_name
391: = (char **) realloc (tree_code_name,
392: sizeof (char *) * LAST_CPLUS_TREE_CODE);
1.1.1.3 ! root 393: bcopy ((char *)cplus_tree_code_type,
! 394: (char *)(tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE),
1.1 root 395: (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
1.1.1.3 ! root 396: bcopy ((char *)cplus_tree_code_length,
! 397: (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
1.1 root 398: (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
1.1.1.3 ! root 399: bcopy ((char *)cplus_tree_code_name,
! 400: (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
1.1 root 401: (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
402:
403: opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
1.1.1.3 ! root 404: bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
1.1 root 405: assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
1.1.1.3 ! root 406: bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
1.1 root 407:
408: ansi_opname[0] = get_identifier ("<invalid operator>");
1.1.1.2 root 409: for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
1.1 root 410: {
411: ansi_opname[i] = ansi_opname[0];
412: ansi_assopname[i] = ansi_opname[0];
413: }
414:
1.1.1.2 root 415: ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml");
416: IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1;
417: ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR];
418: ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml");
419: IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1;
420: ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR];
421: ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md");
422: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1;
423: ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd");
424: IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1;
425: ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
426: ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
427: ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
428: ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi");
429: IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1;
430: ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR];
431: ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami");
432: IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1;
433: ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR];
434: ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs");
435: IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1;
436: ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars");
437: IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1;
438: ansi_opname[(int) NE_EXPR] = get_identifier ("__ne");
439: IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1;
440: ansi_opname[(int) GT_EXPR] = get_identifier ("__gt");
441: IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1;
442: ansi_opname[(int) GE_EXPR] = get_identifier ("__ge");
443: IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1;
444: ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or");
445: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1;
446: ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor");
447: IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1;
448: ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
449: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1;
450: ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt");
451: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1;
452: ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp");
453: IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1;
454: ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR];
455: ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as");
456: IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1;
457: ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR];
458: ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm");
459: IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1;
460: ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv");
461: IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1;
462: ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv");
463: IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1;
464: ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
465: ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
466: ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
467: ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
468: ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
469: ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
470: ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
471: ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
472: ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
473: ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
474: IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
475: ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
476: IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1;
477: ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR];
478: ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR];
479: ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls");
480: IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1;
481: ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als");
482: IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1;
483: ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq");
484: IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1;
485: ansi_opname[(int) LT_EXPR] = get_identifier ("__lt");
486: IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1;
487: ansi_opname[(int) LE_EXPR] = get_identifier ("__le");
488: IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1;
489: ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad");
490: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1;
491: ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad");
492: IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1;
493: ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR];
494: ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR];
495: ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er");
496: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1;
497: ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer");
498: IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1;
499: ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo");
500: IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1;
501: ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co");
502: IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1;
503: ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm");
504: IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1;
505: ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR];
506: ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf");
507: IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1;
508: ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm");
509: IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1;
510: ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl");
511: IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1;
512: ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc");
513: IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1;
514: ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw");
515: IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
516: ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
517: IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
518: ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op");
519: IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
1.1 root 520:
521: /* This is not true: these operators are not defined in ANSI,
522: but we need them anyway. */
1.1.1.2 root 523: ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn");
524: IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1;
525: ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx");
526: IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1;
527: ansi_opname[(int) COND_EXPR] = get_identifier ("__cn");
528: IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1;
529: ansi_opname[(int) METHOD_CALL_EXPR] = get_identifier ("__wr");
530: IDENTIFIER_OPNAME_P (ansi_opname[(int) METHOD_CALL_EXPR]) = 1;
1.1 root 531:
532: init_method ();
533: gcc_obstack_init (&inline_text_obstack);
534: inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
535:
536: /* Start it at 0, because check_newline is called at the very beginning
537: and will increment it to 1. */
538: lineno = 0;
539: current_function_decl = NULL;
540:
541: maxtoken = 40;
542: token_buffer = (char *) xmalloc (maxtoken + 2);
543: max_wide = 40;
544: wide_buffer = (int *) xmalloc (max_wide + 1);
545:
546: ridpointers[(int) RID_INT] = get_identifier ("int");
547: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
548: build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
549: ridpointers[(int) RID_CHAR] = get_identifier ("char");
550: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
551: build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
552: ridpointers[(int) RID_VOID] = get_identifier ("void");
553: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID],
554: build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]));
555: ridpointers[(int) RID_FLOAT] = get_identifier ("float");
556: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT],
557: build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT]));
558: ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
559: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE],
560: build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE]));
561: ridpointers[(int) RID_SHORT] = get_identifier ("short");
562: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT],
563: build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT]));
564: ridpointers[(int) RID_LONG] = get_identifier ("long");
565: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG],
566: build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]));
567: ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
568: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED],
569: build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]));
570: ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
571: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED],
572: build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED]));
573: ridpointers[(int) RID_INLINE] = get_identifier ("inline");
574: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE],
575: build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE]));
576: ridpointers[(int) RID_CONST] = get_identifier ("const");
577: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST],
578: build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST]));
579: ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
580: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
581: build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
582: ridpointers[(int) RID_AUTO] = get_identifier ("auto");
583: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
584: build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
585: ridpointers[(int) RID_STATIC] = get_identifier ("static");
586: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC],
587: build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]));
588: ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
589: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN],
590: build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]));
591: ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
592: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF],
593: build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF]));
594: ridpointers[(int) RID_REGISTER] = get_identifier ("register");
595: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
596: build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
597:
598: /* C++ extensions. These are probably not correctly named. */
599: class_type_node = build_int_2 (class_type, 0);
600: TREE_TYPE (class_type_node) = class_type_node;
601: ridpointers[(int) RID_CLASS] = class_type_node;
602:
603: record_type_node = build_int_2 (record_type, 0);
604: TREE_TYPE (record_type_node) = record_type_node;
605: ridpointers[(int) RID_RECORD] = record_type_node;
606:
607: union_type_node = build_int_2 (union_type, 0);
608: TREE_TYPE (union_type_node) = union_type_node;
609: ridpointers[(int) RID_UNION] = union_type_node;
610:
611: enum_type_node = build_int_2 (enum_type, 0);
612: TREE_TYPE (enum_type_node) = enum_type_node;
613: ridpointers[(int) RID_ENUM] = enum_type_node;
614:
615: ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
616: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
617: build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
618: ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
619: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
620: build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
621:
622: ridpointers[(int) RID_PUBLIC] = get_identifier ("public");
623: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC],
624: build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC]));
625: ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
626: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE],
627: build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE]));
628: ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
629: SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
630: build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
631:
632: /* Exception handling extensions. */
633: exception_type_node = build_int_2 (exception_type, 0);
634: TREE_TYPE (exception_type_node) = exception_type_node;
635: ridpointers[(int) RID_EXCEPTION] = exception_type_node;
636:
637: opname_tab[(int) COMPONENT_REF] = "->";
638: opname_tab[(int) MEMBER_REF] = "->*";
639: opname_tab[(int) METHOD_CALL_EXPR] = "->()";
640: opname_tab[(int) INDIRECT_REF] = "(unary *)";
641: opname_tab[(int) ARRAY_REF] = "[]";
642: opname_tab[(int) MODIFY_EXPR] = "=";
643: opname_tab[(int) NEW_EXPR] = "new";
644: opname_tab[(int) DELETE_EXPR] = "delete";
645: opname_tab[(int) COND_EXPR] = "... ? ... : ...";
646: opname_tab[(int) CALL_EXPR] = "()";
647: opname_tab[(int) PLUS_EXPR] = "+";
648: opname_tab[(int) MINUS_EXPR] = "-";
649: opname_tab[(int) MULT_EXPR] = "*";
650: opname_tab[(int) TRUNC_DIV_EXPR] = "/";
651: opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
652: opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
653: opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
654: opname_tab[(int) TRUNC_MOD_EXPR] = "%";
655: opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
656: opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
657: opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
658: opname_tab[(int) NEGATE_EXPR] = "-";
659: opname_tab[(int) MIN_EXPR] = "<?";
660: opname_tab[(int) MAX_EXPR] = ">?";
661: opname_tab[(int) ABS_EXPR] = "abs";
662: opname_tab[(int) FFS_EXPR] = "ffs";
663: opname_tab[(int) LSHIFT_EXPR] = "<<";
664: opname_tab[(int) RSHIFT_EXPR] = ">>";
665: opname_tab[(int) BIT_IOR_EXPR] = "|";
666: opname_tab[(int) BIT_XOR_EXPR] = "^";
667: opname_tab[(int) BIT_AND_EXPR] = "&";
668: opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
669: opname_tab[(int) BIT_NOT_EXPR] = "~";
670: opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
671: opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
672: opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
673: opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
674: opname_tab[(int) TRUTH_NOT_EXPR] = "!";
675: opname_tab[(int) LT_EXPR] = "<";
676: opname_tab[(int) LE_EXPR] = "<=";
677: opname_tab[(int) GT_EXPR] = ">";
678: opname_tab[(int) GE_EXPR] = ">=";
679: opname_tab[(int) EQ_EXPR] = "==";
680: opname_tab[(int) NE_EXPR] = "!=";
681: opname_tab[(int) IN_EXPR] = "in";
682: opname_tab[(int) SET_LE_EXPR] = "subset";
683: opname_tab[(int) CARD_EXPR] = "#";
684: opname_tab[(int) RANGE_EXPR] = "..";
685: opname_tab[(int) CONVERT_EXPR] = "(unary +)";
686: opname_tab[(int) ADDR_EXPR] = "(unary &)";
687: opname_tab[(int) PREDECREMENT_EXPR] = "--";
688: opname_tab[(int) PREINCREMENT_EXPR] = "++";
689: opname_tab[(int) POSTDECREMENT_EXPR] = "--";
690: opname_tab[(int) POSTINCREMENT_EXPR] = "++";
691: opname_tab[(int) COMPOUND_EXPR] = ",";
692:
693: assignop_tab[(int) NOP_EXPR] = "=";
694: assignop_tab[(int) PLUS_EXPR] = "+=";
695: assignop_tab[(int) CONVERT_EXPR] = "+=";
696: assignop_tab[(int) MINUS_EXPR] = "-=";
697: assignop_tab[(int) NEGATE_EXPR] = "-=";
698: assignop_tab[(int) MULT_EXPR] = "*=";
699: assignop_tab[(int) INDIRECT_REF] = "*=";
700: assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
701: assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
702: assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
703: assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
704: assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
705: assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
706: assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
707: assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
708: assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
709: assignop_tab[(int) MIN_EXPR] = "<?=";
710: assignop_tab[(int) MAX_EXPR] = ">?=";
711: assignop_tab[(int) LSHIFT_EXPR] = "<<=";
712: assignop_tab[(int) RSHIFT_EXPR] = ">>=";
713: assignop_tab[(int) BIT_IOR_EXPR] = "|=";
714: assignop_tab[(int) BIT_XOR_EXPR] = "^=";
715: assignop_tab[(int) BIT_AND_EXPR] = "&=";
716: assignop_tab[(int) ADDR_EXPR] = "&=";
717:
718: init_filename_times ();
719:
720: #define UNSET_RESERVED_WORD(STRING) \
721: do { is_reserved_word (STRING, sizeof (STRING) - 1)->name = ""; } while (0)
722:
723: if (flag_ansi_exceptions)
724: flag_handle_exceptions = 2;
725:
726: if (!flag_ansi_exceptions)
727: {
728: UNSET_RESERVED_WORD ("catch");
729: }
730:
731: if (! flag_handle_exceptions)
732: {
733: /* Easiest way to not recognize exception
1.1.1.2 root 734: handling extensions... */
1.1 root 735: UNSET_RESERVED_WORD ("all");
736: UNSET_RESERVED_WORD ("except");
737: UNSET_RESERVED_WORD ("exception");
738: UNSET_RESERVED_WORD ("raise");
739: UNSET_RESERVED_WORD ("raises");
740: UNSET_RESERVED_WORD ("reraise");
741: UNSET_RESERVED_WORD ("try");
742: UNSET_RESERVED_WORD ("throw");
743: }
744: else if (flag_ansi_exceptions)
745: {
746: /* Easiest way to not recognize exception
1.1.1.2 root 747: handling extensions... */
1.1 root 748: UNSET_RESERVED_WORD ("exception");
749: UNSET_RESERVED_WORD ("all");
750: UNSET_RESERVED_WORD ("except");
751: UNSET_RESERVED_WORD ("raise");
752: UNSET_RESERVED_WORD ("raises");
753: UNSET_RESERVED_WORD ("reraise");
754: is_reserved_word ("try", sizeof ("try") - 1)->token = ANSI_TRY;
755: is_reserved_word ("throw", sizeof ("throw") - 1)->token = ANSI_THROW;
756: }
757: if (! (flag_gc || flag_dossier))
758: {
759: UNSET_RESERVED_WORD ("classof");
760: UNSET_RESERVED_WORD ("headof");
761: }
762: if (flag_no_asm)
763: UNSET_RESERVED_WORD ("asm");
764: if (flag_no_asm || flag_traditional)
765: UNSET_RESERVED_WORD ("typeof");
766: #ifndef SOS
767: UNSET_RESERVED_WORD ("dynamic");
768: #endif
769:
770: token_count = init_parse ();
771: interface_unknown = 1;
772: }
773:
774: void
775: reinit_parse_for_function ()
776: {
777: current_base_init_list = NULL_TREE;
778: current_member_init_list = NULL_TREE;
779: }
780:
781: /* Functions and data structures for #pragma interface.
782:
783: `#pragma implementation' means that the main file being compiled
784: is considered to implement (provide) the classes that appear in
785: its main body. I.e., if this is file "foo.cc", and class `bar'
786: is defined in "foo.cc", then we say that "foo.cc implements bar".
787:
788: All main input files "implement" themselves automagically.
789:
790: `#pragma interface' means that unless this file (of the form "foo.h"
791: is not presently being included by file "foo.cc", the
792: CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none
793: of the vtables nor any of the inline functions defined in foo.h
794: will ever be output.
795:
796: There are cases when we want to link files such as "defs.h" and
797: "main.cc". In this case, we give "defs.h" a `#pragma interface',
798: and "main.cc" has `#pragma implementation "defs.h"'. */
799:
800: struct impl_files
801: {
802: char *filename;
803: struct impl_files *next;
804: };
805:
806: static struct impl_files *impl_file_chain;
807:
808: /* Helper function to load global variables with interface
809: information. */
810: void
811: extract_interface_info ()
812: {
813: tree fileinfo = get_time_identifier (input_filename);
814: fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
815: interface_only = TREE_INT_CST_LOW (fileinfo);
816: interface_unknown = TREE_INT_CST_HIGH (fileinfo);
817: }
818:
819: /* Return nonzero if S and T are not considered part of an
820: INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */
821: static int
822: interface_strcmp (s)
823: char *s;
824: {
825: /* Set the interface/implementation bits for this scope. */
826: struct impl_files *ifiles;
827: char *s1;
828:
829: s = FILE_NAME_NONDIRECTORY (s);
830:
831: for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
832: {
833: char *t1 = ifiles->filename;
834: s1 = s;
835:
836: if (*s1 != *t1 || *s1 == 0)
837: continue;
838:
839: while (*s1 == *t1 && *s1 != 0)
840: s1++, t1++;
841:
842: /* A match. */
843: if (*s1 == *t1)
844: return 0;
845:
846: /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */
847: if (strchr (s1, '.') || strchr (t1, '.'))
848: continue;
849:
850: if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
851: continue;
852:
853: /* A match. */
854: return 0;
855: }
856:
857: /* No matches. */
858: return 1;
859: }
860:
861: void
862: set_typedecl_interface_info (prev, vars)
863: tree prev, vars;
864: {
865: tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
866: tree fileinfo = IDENTIFIER_CLASS_VALUE (id);
867: tree type = TREE_TYPE (vars);
868:
869: CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
870: = interface_strcmp (DECL_SOURCE_FILE (vars));
871: }
872:
873: void
874: set_vardecl_interface_info (prev, vars)
875: tree prev, vars;
876: {
877: tree type = DECL_CONTEXT (vars);
878:
879: if (CLASSTYPE_INTERFACE_UNKNOWN (type) == 0)
880: {
881: if (CLASSTYPE_INTERFACE_ONLY (type))
882: set_typedecl_interface_info (prev, TYPE_NAME (type));
1.1.1.3 ! root 883: else
! 884: CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
1.1 root 885: TREE_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
1.1.1.3 ! root 886: TREE_PUBLIC (vars) = 1;
1.1 root 887: }
888: }
889:
890: /* Called from the top level: if there are any pending inlines to
891: do, set up to process them now. */
892: void
893: do_pending_inlines ()
894: {
895: struct pending_inline *prev = 0, *tail;
896: struct pending_inline *t;
897:
898: /* Reverse the pending inline functions, since
899: they were cons'd instead of appended. */
900:
901: for (t = pending_inlines; t; t = tail)
902: {
903: t->deja_vu = 1;
904: tail = t->next;
905: t->next = prev;
906: prev = t;
907: }
908: /* Reset to zero so that if the inline functions we are currently
909: processing define inline functions of their own, that is handled
910: correctly. ??? This hasn't been checked in a while. */
911: pending_inlines = 0;
912:
913: /* Now start processing the first inline function. */
914: t = prev;
915: assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE));
916: if (t->parm_vec)
917: push_template_decls (t->parm_vec, t->bindings, 0);
918: if (t->len > 0)
919: {
920: feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0);
921: lineno = t->lineno;
922: if (input_filename != t->filename)
923: {
924: input_filename = t->filename;
925: /* Get interface/implementation back in sync. */
926: extract_interface_info ();
927: }
928: yychar = PRE_PARSED_FUNCTION_DECL;
929: }
930: /* Pass back a handle on the rest of the inline functions, so that they
931: can be processed later. */
932: yylval.ttype = build_tree_list ((tree) t, t->fndecl);
933: if (flag_default_inline && t->fndecl
934: /* If we're working from a template, don't change
935: the `inline' state. */
936: && t->parm_vec == NULL_TREE)
937: TREE_INLINE (t->fndecl) = 1;
938: DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
939: }
940:
941: extern struct pending_input *to_be_restored;
942:
943: void
944: process_next_inline (t)
945: tree t;
946: {
947: struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
948: assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE));
949: if (i->parm_vec)
950: pop_template_decls (i->parm_vec, i->bindings, 0);
951: i = i->next;
952: if (yychar == YYEMPTY)
953: yychar = yylex ();
954: if (yychar != END_OF_SAVED_INPUT)
955: {
956: error ("parse error at end of saved function text");
957: /* restore_pending_input will abort unless yychar is either
958: * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
959: * hosed, feed back YYEMPTY.
960: */
961: yychar = YYEMPTY;
962: }
963: else
964: yychar = YYEMPTY;
965: restore_pending_input (to_be_restored);
966: to_be_restored = 0;
967: if (i && i->fndecl != NULL_TREE)
968: {
969: assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE));
970: if (i->parm_vec)
971: push_template_decls (i->parm_vec, i->bindings, 0);
972: feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0);
973: lineno = i->lineno;
974: input_filename = i->filename;
975: yychar = PRE_PARSED_FUNCTION_DECL;
976: yylval.ttype = build_tree_list ((tree) i, i->fndecl);
977: if (flag_default_inline
978: /* If we're working from a template, don't change
979: the `inline' state. */
980: && i->parm_vec == NULL_TREE)
981: TREE_INLINE (i->fndecl) = 1;
982: DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
983: }
984: extract_interface_info ();
985: }
986:
987: /* Since inline methods can refer to text which has not yet been seen,
988: we store the text of the method in a structure which is placed in the
989: DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.
990: After parsing the body of the class definition, the FUNCTION_DECL's are
991: scanned to see which ones have this field set. Those are then digested
992: one at a time.
993:
994: This function's FUNCTION_DECL will have a bit set in its common so
995: that we know to watch out for it. */
996:
997: void
998: consume_string (this_obstack)
999: register struct obstack *this_obstack;
1000: {
1001: register char c;
1002: do
1003: {
1004: c = getch ();
1005: if (c == '\\')
1006: {
1007: obstack_1grow (this_obstack, c);
1008: c = getch ();
1009: obstack_1grow (this_obstack, c);
1010: continue;
1011: }
1012: if (c == '\n')
1013: {
1014: if (pedantic)
1.1.1.3 ! root 1015: pedwarn ("ANSI C forbids newline in string constant");
1.1 root 1016: lineno++;
1017: }
1018: obstack_1grow (this_obstack, c);
1019: }
1020: while (c != '\"');
1021: }
1022:
1023: static int nextchar = -1;
1024: static int nextyychar = YYEMPTY;
1025: static YYSTYPE nextyylval;
1026: static tree nextlastiddecl;
1027:
1028: struct pending_input {
1029: int nextchar, yychar, nextyychar, eof;
1030: YYSTYPE yylval, nextyylval;
1031: struct obstack token_obstack;
1032: int first_token;
1033: };
1034:
1035: struct pending_input *
1036: save_pending_input ()
1037: {
1038: struct pending_input *p;
1039: p = (struct pending_input *) xmalloc (sizeof (struct pending_input));
1040: p->nextchar = nextchar;
1041: p->yychar = yychar;
1042: p->nextyychar = nextyychar;
1043: p->yylval = yylval;
1044: p->nextyylval = nextyylval;
1045: p->eof = end_of_file;
1046: yychar = nextyychar = YYEMPTY;
1047: nextchar = -1;
1048: p->first_token = first_token;
1049: p->token_obstack = token_obstack;
1050:
1051: first_token = 0;
1052: gcc_obstack_init (&token_obstack);
1053: end_of_file = 0;
1054: return p;
1055: }
1056:
1057: void
1058: restore_pending_input (p)
1059: struct pending_input *p;
1060: {
1061: assert (nextchar == -1);
1062: nextchar = p->nextchar;
1063: assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT);
1064: yychar = p->yychar;
1065: assert (nextyychar == YYEMPTY);
1066: nextyychar = p->nextyychar;
1067: yylval = p->yylval;
1068: nextyylval = p->nextyylval;
1069: first_token = p->first_token;
1070: obstack_free (&token_obstack, (char *) 0);
1071: token_obstack = p->token_obstack;
1072: end_of_file = p->eof;
1073: free (p);
1074: }
1075:
1076: /* Return next non-whitespace input character, which may come
1077: from `finput', or from `nextchar'. */
1078: static int
1079: yynextch ()
1080: {
1081: int c;
1082:
1083: if (nextchar >= 0)
1084: {
1085: c = nextchar;
1086: nextchar = -1;
1087: }
1088: else c = getch ();
1089: return skip_white_space (c);
1090: }
1091:
1092: /* Unget character CH from the input stream.
1093: If RESCAN is non-zero, then we want to `see' this
1094: character as the next input token. */
1095: void
1096: yyungetc (ch, rescan)
1097: int ch;
1098: int rescan;
1099: {
1100: /* Unget a character from the input stream. */
1101: if (yychar == YYEMPTY || rescan == 0)
1102: {
1103: if (nextchar >= 0)
1104: put_back (nextchar);
1105: nextchar = ch;
1106: }
1107: else
1108: {
1109: assert (nextyychar == YYEMPTY);
1110: nextyychar = yychar;
1111: nextyylval = yylval;
1112: yychar = ch;
1113: }
1114: }
1115:
1116: /* This function stores away the text for an inline function that should
1117: be processed later. It decides how much later, and may need to move
1118: the info between obstacks; therefore, the caller should not refer to
1119: the T parameter after calling this function.
1120:
1121: This function also stores the list of template-parameter bindings that
1122: will be needed for expanding the template, if any. */
1123:
1124: static void
1125: store_pending_inline (decl, t)
1126: tree decl;
1127: struct pending_inline *t;
1128: {
1129: extern int processing_template_defn;
1130: int delay_to_eof = 0;
1131: struct pending_inline **inlines;
1132:
1133: t->fndecl = decl;
1134: /* Default: compile right away, and no extra bindings are needed. */
1135: t->parm_vec = t->bindings = 0;
1136: if (processing_template_defn)
1137: {
1138: tree type = current_class_type;
1139: /* Assumption: In this (possibly) nested class sequence, only
1140: one name will have template parms. */
1141: while (type)
1142: {
1143: tree decl = TYPE_NAME (type);
1144: tree tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (decl));
1145: if (tmpl)
1146: {
1147: t->parm_vec = DECL_TEMPLATE_INFO (TREE_PURPOSE (tmpl))->parm_vec;
1148: t->bindings = TREE_VALUE (tmpl);
1149: }
1150: type = DECL_CONTEXT (decl);
1151: }
1152: if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
1153: || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
1154: {
1155: if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
1156: assert (TYPE_MAX_VALUE (TREE_TYPE (decl)) == current_class_type);
1157:
1158: /* Inline functions can be compiled immediately. Other functions
1159: will be output separately, so if we're in interface-only mode,
1160: punt them now, or output them now if we're doing implementations
1161: and we know no overrides will exist. Otherwise, we delay until
1162: end-of-file, to see if the definition is really required. */
1163: if (TREE_INLINE (decl))
1164: /* delay_to_eof == 0 */;
1165: else if (current_class_type && !interface_unknown)
1166: {
1167: if (interface_only)
1168: {
1169: #if 0
1170: print_node_brief (stderr, "\ndiscarding text for ", decl, 0);
1171: #endif
1172: if (t->can_free)
1173: obstack_free (&inline_text_obstack, t->buf);
1174: DECL_PENDING_INLINE_INFO (decl) = 0;
1175: return;
1176: }
1177: }
1178: /* Don't delay the processing of virtual functions. */
1179: else if (DECL_VINDEX (decl) == NULL_TREE)
1180: delay_to_eof = 1;
1181: }
1182: else
1.1.1.3 ! root 1183: my_friendly_abort (58);
1.1 root 1184: }
1185:
1186: if (delay_to_eof)
1187: {
1188: extern struct pending_inline *pending_template_expansions;
1189:
1190: if (t->can_free)
1191: {
1192: char *free_to = t->buf;
1193: t->buf = (char *) obstack_copy (&permanent_obstack, t->buf,
1194: t->len + 1);
1.1.1.3 ! root 1195: t = (struct pending_inline *) obstack_copy (&permanent_obstack,
! 1196: (char *)t, sizeof (*t));
1.1 root 1197: obstack_free (&inline_text_obstack, free_to);
1198: }
1199: inlines = &pending_template_expansions;
1200: t->can_free = 0;
1201: }
1202: else
1203: {
1204: inlines = &pending_inlines;
1205: DECL_PENDING_INLINE_INFO (decl) = t;
1206: }
1207:
1208: /* Because we use obstacks, we must process these in precise order. */
1209: t->next = *inlines;
1210: *inlines = t;
1211: }
1212:
1213: void reinit_parse_for_block ();
1214:
1215: void
1216: reinit_parse_for_method (yychar, decl)
1217: int yychar;
1218: tree decl;
1219: {
1220: int len;
1221: int starting_lineno = lineno;
1222: char *starting_filename = input_filename;
1223:
1224: reinit_parse_for_block (yychar, &inline_text_obstack, 0);
1225:
1226: len = obstack_object_size (&inline_text_obstack);
1227: current_base_init_list = NULL_TREE;
1228: current_member_init_list = NULL_TREE;
1229: if (decl == void_type_node
1230: || (current_class_type && TYPE_REDEFINED (current_class_type)))
1231: {
1232: /* Happens when we get two declarations of the same
1233: function in the same scope. */
1234: char *buf = obstack_finish (&inline_text_obstack);
1235: obstack_free (&inline_text_obstack, buf);
1236: return;
1237: }
1238: else
1239: {
1240: struct pending_inline *t;
1241: char *buf = obstack_finish (&inline_text_obstack);
1242:
1243: t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1244: sizeof (struct pending_inline));
1245: t->buf = buf;
1246: t->len = len;
1247: t->lineno = starting_lineno;
1248: t->filename = starting_filename;
1249: t->token = YYEMPTY;
1250: t->can_free = 1;
1251: t->deja_vu = 0;
1252: store_pending_inline (decl, t);
1253: }
1254: }
1255:
1256: /* Consume a block -- actually, a method or template definition beginning
1257: with `:' or `{' -- and save it away on the specified obstack.
1258:
1259: Argument IS_TEMPLATE indicates which set of error messages should be
1260: output if something goes wrong. This should really be cleaned up somehow,
1261: without loss of clarity. */
1262: void
1263: reinit_parse_for_block (yychar, obstackp, is_template)
1264: int yychar;
1265: struct obstack *obstackp;
1266: int is_template;
1267: {
1268: register int c = 0;
1269: int blev = 1;
1270: int starting_lineno = lineno;
1271: char *starting_filename = input_filename;
1272: int len;
1273: int look_for_semicolon = 0;
1274:
1275: if (yychar == '{')
1276: obstack_1grow (obstackp, '{');
1277: else if (yychar == '=')
1278: {
1279: look_for_semicolon = 1;
1280: }
1281: else
1282: {
1283: if (yychar != ':' && (yychar != RETURN || is_template))
1284: {
1285: yyerror (is_template
1286: ? "parse error in template specification"
1287: : "parse error in method specification");
1288: yychar = '{';
1289: }
1290: obstack_1grow (obstackp, yychar);
1291: while (c >= 0)
1292: {
1293: int this_lineno = lineno;
1294:
1295: c = yynextch ();
1296:
1297: /* Don't lose our cool if there are lots of comments. */
1298: if (lineno == this_lineno)
1299: ;
1300: else if (lineno - this_lineno < 10 /* + strlen (input_filename) */)
1301: {
1302: int i;
1303: for (i = lineno - this_lineno; i > 0; i--)
1304: obstack_1grow (obstackp, '\n');
1305: }
1306: else
1307: {
1308: char buf[12];
1309: sprintf (buf, "\n# %d \"", lineno);
1310: len = strlen (buf);
1311: obstack_grow (obstackp, buf, len);
1312:
1313: len = strlen (input_filename);
1314: obstack_grow (obstackp, input_filename, len);
1315: obstack_1grow (obstackp, '\"');
1316: obstack_1grow (obstackp, '\n');
1317: }
1318:
1319: /* strings must be read differently than text. */
1320: if (c == '\"')
1321: {
1322: obstack_1grow (obstackp, c);
1323: consume_string (obstackp);
1324: c = yynextch ();
1325: }
1326: while (c > ' ') /* ASCII dependent! */
1327: {
1328: obstack_1grow (obstackp, c);
1329: if (c == '{') goto main_loop;
1330: if (c == '\"')
1331: consume_string (obstackp);
1332: if (c == ';')
1333: {
1334: error (is_template
1335: ? "template body missing"
1336: : "function body for constructor missing");
1337: obstack_1grow (obstackp, '{');
1338: obstack_1grow (obstackp, '}');
1339: len += 2;
1340: goto done;
1341: }
1342: c = getch ();
1343: }
1344: if (c == '\n')
1345: lineno++;
1346: obstack_1grow (obstackp, c);
1347: }
1348: if (c == EOF)
1349: {
1350: error_with_file_and_line (starting_filename,
1351: starting_lineno,
1352: "end of file read inside definition");
1353: }
1354: }
1355:
1356: main_loop:
1357: while (c >= 0)
1358: {
1359: int this_lineno = lineno;
1360:
1361: c = skip_white_space (getch ());
1362:
1363: /* Don't lose our cool if there are lots of comments. */
1364: if (lineno - this_lineno)
1365: if (lineno - this_lineno == 1)
1366: obstack_1grow (obstackp, '\n');
1367: else
1368: {
1369: char buf[12];
1370: sprintf (buf, "\n# %d \"", lineno);
1371: len = strlen (buf);
1372: obstack_grow (obstackp, buf, len);
1373:
1374: len = strlen (input_filename);
1375: obstack_grow (obstackp, input_filename, len);
1376: obstack_1grow (obstackp, '\"');
1377: obstack_1grow (obstackp, '\n');
1378: }
1379:
1380: while (c > ' ')
1381: {
1382: obstack_1grow (obstackp, c);
1383: if (c == '{') blev++;
1384: else if (c == '}')
1385: {
1386: blev--;
1387: if (blev == 0 && !look_for_semicolon)
1388: goto done;
1389: }
1390: else if (c == '\"')
1391: consume_string (obstackp);
1392: else if (c == ';' && look_for_semicolon && blev == 0)
1393: goto done;
1394: c = getch ();
1395: }
1396: if (c == '\n')
1397: lineno++;
1398: obstack_1grow (obstackp, c);
1399: }
1400: done:
1401: obstack_1grow (obstackp, '\0');
1402: }
1403:
1404: /* Build a default function named NAME for type TYPE.
1405: KIND says what to build.
1406:
1407: When KIND == 0, build default destructor.
1408: When KIND == 1, build virtual destructor.
1409: When KIND == 2, build default constructor.
1410: When KIND == 3, build default X(const X&) constructor.
1411: When KIND == 4, build default X(X&) constructor. */
1412:
1413: tree
1414: cons_up_default_function (type, name, kind)
1415: tree type, name;
1416: int kind;
1417: {
1418: extern tree void_list_node, constructor_name ();
1419: int len;
1420: tree declspecs = NULL_TREE;
1421: tree fn, args;
1422: tree argtype;
1423:
1424: name = constructor_name (name);
1425: switch (kind)
1426: {
1427: /* Destructors. */
1428: case 1:
1429: declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);
1430: /* Fall through... */
1431: case 0:
1432: name = build_parse_node (BIT_NOT_EXPR, name);
1433: /* Fall through... */
1434: case 2:
1435: /* Default constructor. */
1436: args = void_list_node;
1437: break;
1438:
1439: case 3:
1440: type = build_type_variant (type, 1, 0);
1441: /* Fall through... */
1442: case 4:
1443: argtype = build_reference_type (type);
1444: args = tree_cons (NULL_TREE,
1445: build_tree_list (hash_tree_chain (argtype, NULL_TREE),
1446: get_identifier ("arg")),
1447: void_list_node);
1448: break;
1449:
1450: default:
1.1.1.3 ! root 1451: my_friendly_abort (59);
1.1 root 1452: }
1453:
1454: fn = start_method (declspecs,
1455: build_parse_node (CALL_EXPR, name, args, NULL_TREE),
1456: NULL_TREE);
1457: if (fn == void_type_node)
1458: return fn;
1459:
1460: current_base_init_list = NULL_TREE;
1461: current_member_init_list = NULL_TREE;
1462:
1463: len = 3;
1464:
1465: {
1466: struct pending_inline *t;
1467:
1468: t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1469: sizeof (struct pending_inline));
1470: t->buf = default_def;
1471: t->len = len;
1472: t->lineno = lineno;
1473: t->filename = input_filename;
1474: t->token = YYEMPTY;
1475: t->can_free = 0;
1476: t->deja_vu = 0;
1477: store_pending_inline (fn, t);
1478: /* We make this declaration private (static in the C sense). */
1479: TREE_PUBLIC (fn) = 0;
1480: }
1481: finish_method (fn);
1482: DECL_CLASS_CONTEXT (fn) = type;
1483: /* Show that this function was generated by the compiler. */
1484: DECL_IGNORED_P (fn) = 1;
1485: return fn;
1486: }
1487:
1488: /* Heuristic to tell whether the user is missing a semicolon
1489: after a struct or enum declaration. Emit an error message
1490: if we know the user has blown it. */
1491: void
1492: check_for_missing_semicolon (type)
1493: tree type;
1494: {
1495: if (yychar < 0)
1496: yychar = yylex ();
1497:
1498: if (yychar > 255
1499: && yychar != IDENTIFIER
1500: && yychar != TYPENAME)
1501: {
1502: if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
1503: error ("semicolon missing after %s declaration",
1504: TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
1505: else
1506: error ("semicolon missing after declaration of `%s'",
1507: TYPE_NAME_STRING (type));
1508: shadow_tag (build_tree_list (0, type));
1509: }
1510: /* Could probably also hack cases where class { ... } f (); appears. */
1511: clear_anon_tags ();
1512: }
1513:
1514: void
1515: note_got_semicolon (type)
1516: tree type;
1517: {
1518: if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
1.1.1.3 ! root 1519: my_friendly_abort (60);
1.1 root 1520: if (IS_AGGR_TYPE (type))
1521: CLASSTYPE_GOT_SEMICOLON (type) = 1;
1522: }
1523:
1524: void
1525: note_list_got_semicolon (declspecs)
1526: tree declspecs;
1527: {
1528: tree link;
1529:
1530: for (link = declspecs; link; link = TREE_CHAIN (link))
1531: {
1532: tree type = TREE_VALUE (link);
1533: if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
1534: note_got_semicolon (type);
1535: }
1536: clear_anon_tags ();
1537: }
1538:
1539: /* If C is not whitespace, return C.
1540: Otherwise skip whitespace and return first nonwhite char read. */
1541:
1542: static int
1543: skip_white_space (c)
1544: register int c;
1545: {
1546: for (;;)
1547: {
1548: switch (c)
1549: {
1550: case '\n':
1551: c = check_newline ();
1552: break;
1553:
1554: case ' ':
1555: case '\t':
1556: case '\f':
1557: case '\r':
1558: case '\v':
1559: case '\b':
1560: do
1561: c = getch ();
1562: while (c == ' ' || c == '\t');
1563: break;
1564:
1565: case '\\':
1566: c = getch ();
1567: if (c == '\n')
1568: lineno++;
1569: else
1570: error ("stray '\\' in program");
1571: c = getch ();
1572: break;
1573:
1574: default:
1575: return (c);
1576: }
1577: }
1578: }
1579:
1580:
1581:
1582: /* Make the token buffer longer, preserving the data in it.
1583: P should point to just beyond the last valid character in the old buffer.
1584: The value we return is a pointer to the new buffer
1585: at a place corresponding to P. */
1586:
1587: static char *
1588: extend_token_buffer (p)
1589: char *p;
1590: {
1591: int offset = p - token_buffer;
1592:
1593: maxtoken = maxtoken * 2 + 10;
1594: token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
1595:
1596: return token_buffer + offset;
1597: }
1598:
1599: static int
1600: get_last_nonwhite_on_line ()
1601: {
1602: register int c;
1603:
1604: /* Is this the last nonwhite stuff on the line? */
1605: if (nextchar >= 0)
1606: c = nextchar, nextchar = -1;
1607: else
1608: c = getch ();
1609:
1610: while (c == ' ' || c == '\t')
1611: c = getch ();
1612: return c;
1613: }
1614:
1615: /* At the beginning of a line, increment the line number
1616: and process any #-directive on this line.
1617: If the line is a #-directive, read the entire line and return a newline.
1618: Otherwise, return the line's first non-whitespace character. */
1619:
1620: int
1621: check_newline ()
1622: {
1623: register int c;
1624: register int token;
1625:
1626: lineno++;
1627:
1628: /* Read first nonwhite char on the line. */
1629:
1630: do
1631: c = getch ();
1632: while (c == ' ' || c == '\t');
1633:
1634: if (c != '#')
1635: {
1636: /* If not #, return it so caller will use it. */
1637: return c;
1638: }
1639:
1640: /* Read first nonwhite char after the `#'. */
1641:
1642: do
1643: c = getch ();
1644: while (c == ' ' || c == '\t');
1645:
1646: /* If a letter follows, then if the word here is `line', skip
1647: it and ignore it; otherwise, ignore the line, with an error
1648: if the word isn't `pragma'. */
1649:
1650: if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
1651: {
1652: if (c == 'p')
1653: {
1654: if (getch () == 'r'
1655: && getch () == 'a'
1656: && getch () == 'g'
1657: && getch () == 'm'
1658: && getch () == 'a')
1659: {
1660: /* Read first nonwhite char after the `#pragma'. */
1661:
1662: do
1663: c = getch ();
1664: while (c == ' ' || c == '\t');
1665:
1666: if (c == 'v'
1667: && getch () == 't'
1668: && getch () == 'a'
1669: && getch () == 'b'
1670: && getch () == 'l'
1671: && getch () == 'e'
1672: && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
1673: {
1674: extern tree pending_vtables;
1675:
1676: /* More follows: it must be a string constant (class name). */
1677: token = real_yylex ();
1678: if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
1679: {
1680: error ("invalid #pragma vtable");
1681: goto skipline;
1682: }
1683: if (write_virtuals != 2)
1684: {
1685: warning ("use `+e2' option to enable #pragma vtable");
1686: goto skipline;
1687: }
1688: pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables);
1689: if (nextchar < 0)
1690: nextchar = getch ();
1691: c = nextchar;
1692: if (c != '\n')
1693: warning ("trailing characters ignored");
1694: }
1695: else if (c == 'u'
1696: && getch () == 'n'
1697: && getch () == 'i'
1698: && getch () == 't'
1699: && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
1700: {
1701: /* More follows: it must be a string constant (unit name). */
1702: token = real_yylex ();
1703: if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
1704: {
1705: error ("invalid #pragma unit");
1706: goto skipline;
1707: }
1708: current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype));
1709: current_unit_language = current_lang_name;
1710: if (nextchar < 0)
1711: nextchar = getch ();
1712: c = nextchar;
1713: if (c != '\n')
1714: warning ("trailing characters ignored");
1715: }
1716: else if (c == 'i')
1717: {
1718: tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
1719: c = getch ();
1720:
1721: if (c == 'n'
1722: && getch () == 't'
1723: && getch () == 'e'
1724: && getch () == 'r'
1725: && getch () == 'f'
1726: && getch () == 'a'
1727: && getch () == 'c'
1728: && getch () == 'e'
1729: && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
1730: {
1731: /* read to newline. */
1732: while (c != '\n')
1733: c = getch ();
1734:
1735: write_virtuals = 3;
1736:
1737: if (impl_file_chain == 0)
1738: {
1739: char *filename;
1740: tree fi;
1741:
1742: /* If this is zero at this point, then we are
1743: auto-implementing. */
1744: if (main_input_filename == 0)
1745: main_input_filename = input_filename;
1746:
1747: filename = FILE_NAME_NONDIRECTORY (main_input_filename);
1748: fi = get_time_identifier (filename);
1749: fi = IDENTIFIER_CLASS_VALUE (fi);
1750: TREE_INT_CST_LOW (fi) = 0;
1751: TREE_INT_CST_HIGH (fi) = 1;
1752: /* Get default. */
1753: impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
1754: impl_file_chain->filename = filename;
1755: impl_file_chain->next = 0;
1756: }
1757:
1758: interface_only = interface_strcmp (input_filename);
1759: interface_unknown = 0;
1760: TREE_INT_CST_LOW (fileinfo) = interface_only;
1761: TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
1762: }
1763: else if (c == 'm'
1764: && getch () == 'p'
1765: && getch () == 'l'
1766: && getch () == 'e'
1767: && getch () == 'm'
1768: && getch () == 'e'
1769: && getch () == 'n'
1770: && getch () == 't'
1771: && getch () == 'a'
1772: && getch () == 't'
1773: && getch () == 'i'
1774: && getch () == 'o'
1775: && getch () == 'n'
1776: && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
1777: {
1778: char *main_filename = main_input_filename ? main_input_filename : input_filename;
1779: char *tmp;
1780:
1781: while (c == ' ' || c == '\t')
1782: c = getch ();
1783: if (c != '\n')
1784: {
1785: put_back (c);
1786: token = real_yylex ();
1787: if (token != STRING
1788: || TREE_CODE (yylval.ttype) != STRING_CST)
1789: {
1790: error ("invalid `#pragma implementation'");
1791: goto skipline;
1792: }
1793: main_filename = TREE_STRING_POINTER (yylval.ttype);
1794: }
1795: main_filename = FILE_NAME_NONDIRECTORY (main_filename);
1796:
1797: /* read to newline. */
1798: while (c != '\n')
1799: c = getch ();
1800:
1801: if (write_virtuals == 3)
1802: {
1803: struct impl_files *ifiles = impl_file_chain;
1804: while (ifiles)
1805: {
1806: if (! strcmp (ifiles->filename, main_filename))
1807: break;
1808: ifiles = ifiles->next;
1809: }
1810: if (ifiles == 0)
1811: {
1812: ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
1813: ifiles->filename = main_filename;
1814: ifiles->next = impl_file_chain;
1815: impl_file_chain = ifiles;
1816: }
1817: }
1818: else if (main_input_filename == input_filename
1819: || ! strcmp (input_filename, main_filename))
1820: {
1821: write_virtuals = 3;
1822: if (impl_file_chain == 0)
1823: {
1824: impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
1825: impl_file_chain->filename = main_filename;
1826: impl_file_chain->next = 0;
1827: }
1828: }
1829: else
1830: error ("`#pragma implementation' can only appear at top-level");
1831: interface_only = 0;
1832: /* We make this non-zero so that we infer decl linkage
1833: in the impl file only for variables first declared
1834: in the interface file. */
1835: interface_unknown = 1;
1836: TREE_INT_CST_LOW (fileinfo) = interface_only;
1837: TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
1838: }
1839: }
1840: }
1841: goto skipline;
1842: }
1843: else if (c == 'd')
1844: {
1845: if (getch () == 'e'
1846: && getch () == 'f'
1847: && getch () == 'i'
1848: && getch () == 'n'
1849: && getch () == 'e'
1850: && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
1851: {
1852: #ifdef DWARF_DEBUGGING_INFO
1853: if ((debug_info_level == DINFO_LEVEL_VERBOSE)
1854: && (write_symbols == DWARF_DEBUG))
1855: dwarfout_define (lineno, get_directive_line (finput));
1856: #endif /* DWARF_DEBUGGING_INFO */
1857: goto skipline;
1858: }
1859: }
1860: else if (c == 'u')
1861: {
1862: if (getch () == 'n'
1863: && getch () == 'd'
1864: && getch () == 'e'
1865: && getch () == 'f'
1866: && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
1867: {
1868: #ifdef DWARF_DEBUGGING_INFO
1869: if ((debug_info_level == DINFO_LEVEL_VERBOSE)
1870: && (write_symbols == DWARF_DEBUG))
1871: dwarfout_undef (lineno, get_directive_line (finput));
1872: #endif /* DWARF_DEBUGGING_INFO */
1873: goto skipline;
1874: }
1875: }
1876: else if (c == 'l')
1877: {
1878: if (getch () == 'i'
1879: && getch () == 'n'
1880: && getch () == 'e'
1881: && ((c = getch ()) == ' ' || c == '\t'))
1882: goto linenum;
1883: }
1884: else if (c == 'i')
1885: {
1886: if (getch () == 'd'
1887: && getch () == 'e'
1888: && getch () == 'n'
1889: && getch () == 't'
1890: && ((c = getch ()) == ' ' || c == '\t'))
1891: {
1892: /* Conditionally used. */
1893: extern FILE *asm_out_file;
1894:
1895: if (pedantic)
1896: error ("ANSI C does not allow #ident");
1897:
1898: /* Here we have just seen `#ident '.
1899: A string constant should follow. */
1900:
1901: while (c == ' ' || c == '\t')
1902: c = getch ();
1903:
1904: /* If no argument, ignore the line. */
1905: if (c == '\n')
1906: return c;
1907:
1908: put_back (c);
1909: token = real_yylex ();
1910: if (token != STRING
1911: || TREE_CODE (yylval.ttype) != STRING_CST)
1912: {
1913: error ("invalid #ident");
1914: goto skipline;
1915: }
1916:
1917: #ifdef ASM_OUTPUT_IDENT
1918: ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
1919: #endif
1920:
1921: /* Skip the rest of this line. */
1922: goto skipline;
1923: }
1924: }
1925: else if (c == 'n')
1926: {
1927: if (getch () == 'e'
1928: && getch () == 'w'
1929: && getch () == 'w'
1930: && getch () == 'o'
1931: && getch () == 'r'
1932: && getch () == 'l'
1933: && getch () == 'd'
1934: && ((c = getch ()) == ' ' || c == '\t'))
1935: {
1936: /* Used to test incremental compilation. */
1937: sorry ("#pragma newworld");
1938: goto skipline;
1939: }
1940: }
1941: error ("undefined or invalid # directive");
1942: goto skipline;
1943: }
1944:
1945: linenum:
1946: /* Here we have either `#line' or `# <nonletter>'.
1947: In either case, it should be a line number; a digit should follow. */
1948:
1949: while (c == ' ' || c == '\t')
1950: c = getch ();
1951:
1952: /* If the # is the only nonwhite char on the line,
1953: just ignore it. Check the new newline. */
1954: if (c == '\n')
1955: return c;
1956:
1957: /* Something follows the #; read a token. */
1958:
1959: put_back (c);
1960: token = real_yylex ();
1961:
1962: if (token == CONSTANT
1963: && TREE_CODE (yylval.ttype) == INTEGER_CST)
1964: {
1965: int old_lineno = lineno;
1966: int used_up = 0;
1967: /* subtract one, because it is the following line that
1968: gets the specified number */
1969:
1970: int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
1971: c = get_last_nonwhite_on_line ();
1972: if (c == '\n')
1973: {
1974: /* No more: store the line number and check following line. */
1975: lineno = l;
1976: return c;
1977: }
1978: put_back (c);
1979:
1980: /* More follows: it must be a string constant (filename). */
1981:
1982: token = real_yylex ();
1983: if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
1984: {
1985: error ("invalid #line");
1986: goto skipline;
1987: }
1988:
1989: /* Changing files again. This means currently collected time
1990: is charged against header time, and body time starts back
1991: at 0. */
1992: if (flag_detailed_statistics)
1993: {
1994: int this_time = my_get_run_time ();
1995: tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
1996: header_time += this_time - body_time;
1997: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
1998: += this_time - body_time;
1999: this_filename_time = time_identifier;
2000: body_time = this_time;
2001: }
2002:
2003: if (flag_cadillac)
2004: cadillac_note_source ();
2005:
2006: input_filename
2007: = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2008: strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2009: lineno = l;
2010: GNU_xref_file (input_filename);
2011:
2012: /* Each change of file name
2013: reinitializes whether we are now in a system header. */
2014: in_system_header = 0;
2015:
2016: if (main_input_filename == 0)
2017: {
2018: struct impl_files *ifiles = impl_file_chain;
2019:
2020: if (ifiles)
2021: {
2022: while (ifiles->next)
2023: ifiles = ifiles->next;
2024: ifiles->filename = FILE_NAME_NONDIRECTORY (input_filename);
2025: }
2026:
2027: main_input_filename = input_filename;
2028: if (write_virtuals == 3)
2029: walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2030: }
2031:
2032: extract_interface_info ();
2033:
2034: c = get_last_nonwhite_on_line ();
2035: if (c == '\n')
2036: {
2037: if (flag_cadillac)
2038: cadillac_switch_source (-1);
2039: return c;
2040: }
2041: put_back (c);
2042:
2043: token = real_yylex ();
2044: used_up = 0;
2045:
2046: /* `1' after file name means entering new file.
2047: `2' after file name means just left a file. */
2048:
2049: if (token == CONSTANT
2050: && TREE_CODE (yylval.ttype) == INTEGER_CST)
2051: {
2052: if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2053: {
2054: /* Pushing to a new file. */
2055: struct file_stack *p
2056: = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2057: input_file_stack->line = old_lineno;
2058: p->next = input_file_stack;
2059: p->name = input_filename;
2060: input_file_stack = p;
2061: input_file_stack_tick++;
2062: #ifdef DWARF_DEBUGGING_INFO
2063: if (debug_info_level == DINFO_LEVEL_VERBOSE
2064: && write_symbols == DWARF_DEBUG)
2065: dwarfout_start_new_source_file (input_filename);
2066: #endif /* DWARF_DEBUGGING_INFO */
2067:
2068: used_up = 1;
2069: if (flag_cadillac)
2070: cadillac_push_source ();
2071: }
2072: else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
2073: {
2074: /* Popping out of a file. */
2075: if (input_file_stack->next)
2076: {
2077: struct file_stack *p = input_file_stack;
2078:
2079: if (flag_cadillac)
2080: cadillac_pop_source ();
2081:
2082: input_file_stack = p->next;
2083: free (p);
2084: input_file_stack_tick++;
2085: #ifdef DWARF_DEBUGGING_INFO
2086: if (debug_info_level == DINFO_LEVEL_VERBOSE
2087: && write_symbols == DWARF_DEBUG)
2088: dwarfout_resume_previous_source_file (input_file_stack->line);
2089: #endif /* DWARF_DEBUGGING_INFO */
2090: }
2091: else
2092: error ("#-lines for entering and leaving files don't match");
2093:
2094: used_up = 1;
2095: }
2096: }
2097: else if (flag_cadillac)
2098: cadillac_switch_source (-1);
2099:
2100: /* If we have handled a `1' or a `2',
2101: see if there is another number to read. */
2102: if (used_up)
2103: {
2104: c = get_last_nonwhite_on_line ();
2105: if (c == '\n')
2106: {
2107: if (flag_cadillac)
2108: cadillac_switch_source (-1);
2109: return c;
2110: }
2111: put_back (c);
2112:
2113: token = real_yylex ();
2114: used_up = 0;
2115: }
2116:
2117: /* `3' after file name means this is a system header file. */
2118:
2119: if (token == CONSTANT
2120: && TREE_CODE (yylval.ttype) == INTEGER_CST
2121: && TREE_INT_CST_LOW (yylval.ttype) == 3)
2122: in_system_header = 1;
2123:
2124: /* If NEXTCHAR is not end of line, we don't care what it is. */
2125: if (nextchar == '\n')
2126: return '\n';
2127: }
2128: else
2129: error ("invalid #-line");
2130:
2131: /* skip the rest of this line. */
2132: skipline:
2133: if (c == '\n')
2134: return c;
2135: while ((c = getch ()) != EOF && c != '\n');
2136: return c;
2137: }
2138:
2139: #if 0
2140: #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0)
2141: #define isdigit(char) (char >= '0' && char <= '9')
2142: #else
2143: #include <ctype.h>
2144: #endif
2145:
2146: #define ENDFILE -1 /* token that represents end-of-file */
2147:
2148: static int
2149: readescape ()
2150: {
2151: register int c = getch ();
2152: register unsigned count;
2153: register int code;
2154: unsigned firstdig;
2155:
2156: switch (c)
2157: {
2158: case 'x':
2159: code = 0;
2160: count = 0;
2161: while (1)
2162: {
2163: c = getch ();
2164: if (! isxdigit (c))
2165: {
2166: put_back (c);
2167: break;
2168: }
2169: code *= 16;
2170: if (c >= 'a' && c <= 'f')
2171: code += c - 'a' + 10;
2172: if (c >= 'A' && c <= 'F')
2173: code += c - 'A' + 10;
2174: if (c >= '0' && c <= '9')
2175: code += c - '0';
2176: if (count == 0)
2177: firstdig = code;
2178: count++;
2179: }
2180: if (count == 0)
2181: error ("\\x used with no following hex digits");
2182: else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
2183: || ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
2184: <= firstdig))
2185: warning ("hex escape out of range");
2186: return code;
2187:
2188: case '0': case '1': case '2': case '3': case '4':
2189: case '5': case '6': case '7':
2190: code = 0;
2191: count = 0;
2192: while ((c <= '7') && (c >= '0') && (count++ < 3))
2193: {
2194: code = (code * 8) + (c - '0');
2195: c = getch ();
2196: }
2197: put_back (c);
2198: return code;
2199:
2200: case '\\': case '\'': case '"':
2201: return c;
2202:
2203: case '\n':
2204: lineno++;
2205: return -1;
2206:
2207: case 'n':
2208: return TARGET_NEWLINE;
2209:
2210: case 't':
2211: return TARGET_TAB;
2212:
2213: case 'r':
2214: return TARGET_CR;
2215:
2216: case 'f':
2217: return TARGET_FF;
2218:
2219: case 'b':
2220: return TARGET_BS;
2221:
2222: case 'a':
2223: return TARGET_BELL;
2224:
2225: case 'v':
2226: return TARGET_VT;
2227:
2228: case 'E':
2229: return 033;
2230:
2231: case '?':
2232: /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */
2233: case '(':
2234: case '{':
2235: case '[':
2236: return c;
2237: }
2238: if (c >= 040 && c <= 0177)
2239: warning ("unknown escape sequence `\\%c'", c);
2240: else
2241: warning ("unknown escape sequence: `\\' followed by char code 0x%x", c);
2242: return c;
2243: }
2244:
2245: /* Value is 1 if we should try to make the next identifier look like a
2246: typename (when it may be a local variable or a class variable).
2247: Value is 0 if we treat this name in a default fashion.
2248: Value is -1 if we must not see a type name. */
2249: int looking_for_typename = 0;
2250:
2251: void
2252: dont_see_typename ()
2253: {
2254: looking_for_typename = -1;
2255: if (yychar == TYPENAME || yychar == PTYPENAME)
2256: {
2257: yychar = IDENTIFIER;
2258: lastiddecl = 0;
2259: }
2260: }
2261:
2262: #ifdef __GNUC__
2263: extern __inline int identifier_type ();
2264: __inline
2265: #endif
2266: int
2267: identifier_type (decl)
2268: tree decl;
2269: {
2270: if (TREE_CODE (decl) == TEMPLATE_DECL
2271: && DECL_TEMPLATE_IS_CLASS (decl))
2272: return PTYPENAME;
2273: if (TREE_CODE (decl) != TYPE_DECL)
2274: return IDENTIFIER;
2275: return TYPENAME;
2276: }
2277:
2278: void
2279: see_typename ()
2280: {
2281: looking_for_typename = 0;
2282: if (yychar == IDENTIFIER)
2283: {
2284: lastiddecl = lookup_name (yylval.ttype, -1);
2285: if (lastiddecl == 0)
2286: {
2287: if (flag_labels_ok)
2288: lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
2289: }
2290: else
2291: yychar = identifier_type (lastiddecl);
2292: }
2293: }
2294:
2295: tree do_identifier (token)
2296: register tree token;
2297: {
2298: register tree id = lastiddecl;
2299:
2300: if (yychar == YYEMPTY)
2301: yychar = yylex ();
2302: /* Scope class declarations before global
2303: declarations. */
2304: if (id == IDENTIFIER_GLOBAL_VALUE (token)
2305: && current_class_type != 0
2306: && TYPE_SIZE (current_class_type) == 0
2307: && TREE_CODE (current_class_type) != UNINSTANTIATED_P_TYPE)
2308: {
2309: /* Could be from one of the base classes. */
2310: tree field = lookup_field (current_class_type, token, 1);
2311: if (field == 0)
2312: ;
2313: else if (field == error_mark_node)
2314: /* We have already generated the error message.
2315: But we still want to return this value. */
2316: id = lookup_field (current_class_type, token, 0);
2317: else if (TREE_CODE (field) == VAR_DECL
2318: || TREE_CODE (field) == CONST_DECL)
2319: id = field;
2320: else if (TREE_CODE (field) != FIELD_DECL)
1.1.1.3 ! root 2321: my_friendly_abort (61);
1.1 root 2322: else
2323: {
2324: error_with_decl (field, "invalid use of member `%s' from base class `%s'",
2325: TYPE_NAME_STRING (DECL_FIELD_CONTEXT (field)));
2326: id = error_mark_node;
2327: return id;
2328: }
2329: }
2330:
2331: if (!id || id == error_mark_node)
2332: {
2333: if (yychar == '(' || yychar == LEFT_RIGHT)
2334: {
2335: id = implicitly_declare (token);
2336: }
2337: else if (current_function_decl == 0)
2338: {
2339: error ("`%s' undeclared, outside of functions",
2340: IDENTIFIER_POINTER (token));
2341: id = error_mark_node;
2342: }
2343: else
2344: {
2345: if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node
2346: || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
2347: {
2348: extern int undeclared_variable_notice;
2349:
2350: error ("`%s' undeclared (first use this function)",
2351: IDENTIFIER_POINTER (token));
2352:
2353: if (! undeclared_variable_notice)
2354: {
2355: error ("(Each undeclared identifier is reported only once");
2356: error ("for each function it appears in.)");
2357: undeclared_variable_notice = 1;
2358: }
2359: }
2360: id = error_mark_node;
2361: /* Prevent repeated error messages. */
2362: IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
2363: SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
2364: }
2365: }
2366: /* TREE_USED is set in `hack_identifier'. */
2367: if (TREE_CODE (id) == CONST_DECL)
2368: {
2369: if (IDENTIFIER_CLASS_VALUE (token) == id)
2370: {
2371: /* Check visibility. */
2372: enum visibility_type visibility
2373: = compute_visibility (TYPE_BINFO (current_class_type), id);
2374: if (visibility == visibility_private)
2375: error_with_decl (id, "enum `%s' is private");
2376: /* protected is OK, since it's an enum of `this'. */
2377: }
2378: id = DECL_INITIAL (id);
2379: }
2380: else id = hack_identifier (id, token, yychar);
2381: return id;
2382: }
2383:
2384: tree
2385: identifier_typedecl_value (node)
2386: tree node;
2387: {
2388: tree t, type;
2389: type = IDENTIFIER_TYPE_VALUE (node);
2390: if (type == NULL_TREE)
2391: return NULL_TREE;
2392: #define do(X) \
2393: { \
2394: t = (X); \
2395: if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
2396: return t; \
2397: }
2398: do (IDENTIFIER_LOCAL_VALUE (node));
2399: do (IDENTIFIER_CLASS_VALUE (node));
2400: do (IDENTIFIER_GLOBAL_VALUE (node));
2401: #undef do
2402: /* Will this one ever happen? */
2403: if (TYPE_NAME (type))
2404: return TYPE_NAME (type);
1.1.1.3 ! root 2405: my_friendly_abort (62);
1.1 root 2406: }
2407:
2408: struct try_type
2409: {
2410: tree *node_var;
2411: char unsigned_flag;
2412: char long_flag;
2413: char long_long_flag;
2414: };
2415:
2416: struct try_type type_sequence[] =
2417: {
2418: { &integer_type_node, 0, 0, 0},
2419: { &unsigned_type_node, 1, 0, 0},
2420: { &long_integer_type_node, 0, 1, 0},
2421: { &long_unsigned_type_node, 1, 1, 0},
2422: { &long_long_integer_type_node, 0, 1, 1},
2423: { &long_long_unsigned_type_node, 1, 1, 1}
2424: };
2425:
2426: int
2427: real_yylex ()
2428: {
2429: tree tmp;
2430: register int c;
2431: register int value;
2432: int wide_flag = 0;
2433: int dollar_seen = 0;
2434: static tree typename_scope_in_progress;
2435:
2436: relex:
2437: if (nextchar >= 0)
2438: c = nextchar, nextchar = -1;
2439: else
2440: c = getch ();
2441:
2442: /* Effectively do c = skip_white_space (c)
2443: but do it faster in the usual cases. */
2444: while (1)
2445: switch (c)
2446: {
2447: case ' ':
2448: case '\t':
2449: case '\f':
2450: case '\r':
2451: case '\v':
2452: case '\b':
2453: c = getch ();
2454: break;
2455:
2456: case '\n':
2457: case '/':
2458: case '\\':
2459: c = skip_white_space (c);
2460: default:
2461: goto found_nonwhite;
2462: }
2463: found_nonwhite:
2464:
2465: token_buffer[0] = c;
2466: token_buffer[1] = 0;
2467:
2468: /* yylloc.first_line = lineno; */
2469:
2470: reswitch:
2471: switch (c)
2472: {
2473: case EOF:
2474: token_buffer[0] = '\0';
2475: end_of_file = 1;
2476: if (input_redirected ())
2477: value = END_OF_SAVED_INPUT;
2478: else if (do_pending_expansions ())
2479: /* this will set yychar for us */
2480: return yychar;
2481: else
2482: value = ENDFILE;
2483: break;
2484:
2485: case '$':
2486: if (dollars_in_ident)
2487: {
2488: dollar_seen = 1;
2489: goto letter;
2490: }
2491: value = '$';
2492: goto done;
2493:
2494: case 'L':
2495: /* Capital L may start a wide-string or wide-character constant. */
2496: {
2497: register int c = getch ();
2498: if (c == '\'')
2499: {
2500: wide_flag = 1;
2501: goto char_constant;
2502: }
2503: if (c == '"')
2504: {
2505: wide_flag = 1;
2506: goto string_constant;
2507: }
2508: put_back (c);
2509: }
2510:
2511: case 'A': case 'B': case 'C': case 'D': case 'E':
2512: case 'F': case 'G': case 'H': case 'I': case 'J':
2513: case 'K': case 'M': case 'N': case 'O':
2514: case 'P': case 'Q': case 'R': case 'S': case 'T':
2515: case 'U': case 'V': case 'W': case 'X': case 'Y':
2516: case 'Z':
2517: case 'a': case 'b': case 'c': case 'd': case 'e':
2518: case 'f': case 'g': case 'h': case 'i': case 'j':
2519: case 'k': case 'l': case 'm': case 'n': case 'o':
2520: case 'p': case 'q': case 'r': case 's': case 't':
2521: case 'u': case 'v': case 'w': case 'x': case 'y':
2522: case 'z':
2523: case '_':
2524: letter:
2525: {
2526: register char *p;
2527:
2528: p = token_buffer;
2529: if (input == 0)
2530: {
2531: /* We know that `token_buffer' can hold at least on char,
2532: so we install C immediately.
2533: We may have to read the value in `putback_char', so call
2534: `getch' once. */
2535: *p++ = c;
2536: c = getch ();
2537:
2538: /* Make this run fast. We know that we are reading straight
2539: from FINPUT in this case (since identifiers cannot straddle
2540: input sources. */
2541: while (isalnum (c) || (c == '_') || c == '$')
2542: {
2543: if (p >= token_buffer + maxtoken)
2544: p = extend_token_buffer (p);
2545: if (c == '$' && ! dollars_in_ident)
2546: break;
2547:
2548: *p++ = c;
2549: c = getc (finput);
2550: }
2551: }
2552: else
2553: {
2554: /* We know that `token_buffer' can hold at least on char,
2555: so we install C immediately. */
2556: *p++ = c;
2557: c = getch ();
2558:
2559: while (isalnum (c) || (c == '_') || c == '$')
2560: {
2561: if (p >= token_buffer + maxtoken)
2562: p = extend_token_buffer (p);
2563: if (c == '$' && ! dollars_in_ident)
2564: break;
2565:
2566: *p++ = c;
2567: c = getch ();
2568: }
2569: }
2570:
2571: *p = 0;
2572: nextchar = c;
2573:
2574: value = IDENTIFIER;
2575: yylval.itype = 0;
2576:
2577: /* Try to recognize a keyword. Uses minimum-perfect hash function */
2578:
2579: {
2580: register struct resword *ptr;
2581:
2582: if (ptr = is_reserved_word (token_buffer, p - token_buffer))
2583: {
2584: if (ptr->rid)
2585: {
2586: tree old_ttype = ridpointers[(int) ptr->rid];
2587:
2588: /* If this provides a type for us, then revert lexical
2589: state to standard state. */
2590: if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
2591: && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
2592: && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
2593: looking_for_typename = 0;
2594: else if (ptr->token == AGGR || ptr->token == ENUM)
2595: looking_for_typename = 1;
2596:
2597: /* Check if this is a language-type declaration.
2598: Just glimpse the next non-white character. */
2599: nextchar = skip_white_space (nextchar);
2600: if (nextchar == '"')
2601: {
2602: /* We are looking at a string. Complain
2603: if the token before the string is no `extern'.
2604:
2605: Could cheat some memory by placing this string
2606: on the temporary_, instead of the saveable_
2607: obstack. */
2608:
2609: if (ptr->rid != RID_EXTERN)
2610: error ("invalid modifier `%s' for language string",
2611: ptr->name);
2612: real_yylex ();
2613: value = EXTERN_LANG_STRING;
2614: yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
2615: break;
2616: }
2617: if (ptr->token == VISSPEC)
2618: {
2619: switch (ptr->rid)
2620: {
2621: case RID_PUBLIC:
2622: yylval.itype = visibility_public;
2623: break;
2624: case RID_PRIVATE:
2625: yylval.itype = visibility_private;
2626: break;
2627: case RID_PROTECTED:
2628: yylval.itype = visibility_protected;
2629: break;
2630: default:
1.1.1.3 ! root 2631: my_friendly_abort (63);
1.1 root 2632: }
2633: }
2634: else
2635: yylval.ttype = old_ttype;
2636: }
2637: value = (int) ptr->token;
2638: }
2639: }
2640:
2641: /* If we did not find a keyword, look for an identifier
2642: (or a typename). */
2643:
2644: if (value == IDENTIFIER || value == TYPESPEC)
2645: GNU_xref_ref (current_function_decl, token_buffer);
2646:
2647: if (value == IDENTIFIER)
2648: {
2649: tmp = get_identifier (token_buffer);
2650:
2651: #ifndef VMS
2652: /* Make sure that user does not collide with our internal
2653: naming scheme. */
2654: if (JOINER == '$'
2655: && dollar_seen
2656: && (THIS_NAME_P (tmp)
2657: || VPTR_NAME_P (tmp)
2658: || DESTRUCTOR_NAME_P (tmp)
2659: || WRAPPER_OR_ANTI_WRAPPER_NAME_P (tmp)
2660: || VTABLE_NAME_P (tmp)
2661: || TEMP_NAME_P (tmp)
2662: || ANON_AGGRNAME_P (tmp)
2663: || ANON_PARMNAME_P (tmp)))
2664: warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
2665: token_buffer);
2666: #endif
2667:
2668: yylval.ttype = tmp;
2669: }
2670: if (value == NEW && ! global_bindings_p ())
2671: {
2672: looking_for_typename = 1;
2673: value = NEW;
2674: goto done;
2675: }
2676: }
2677: break;
2678:
2679: case '.':
2680: {
2681: register int c1 = getch ();
2682: token_buffer[0] = c;
2683: token_buffer[1] = c1;
2684: if (c1 == '*')
2685: {
2686: value = DOT_STAR;
2687: token_buffer[2] = 0;
2688: goto done;
2689: }
2690: if (c1 == '.')
2691: {
2692: c1 = getch ();
2693: if (c1 == '.')
2694: {
2695: token_buffer[2] = c1;
2696: token_buffer[3] = 0;
2697: value = ELLIPSIS;
2698: goto done;
2699: }
2700: nextchar = c1;
2701: token_buffer[2] = '\0';
2702: value = RANGE;
2703: goto done;
2704: }
2705: if (isdigit (c1))
2706: {
2707: put_back (c1);
2708: goto resume_numerical_scan;
2709: }
2710: nextchar = c1;
2711: value = '.';
2712: token_buffer[1] = 0;
2713: goto done;
2714: }
2715: case '0': case '1':
2716: /* Optimize for most frequent case. */
2717: {
2718: register int c1 = getch ();
2719: if (! isalnum (c1) && c1 != '.')
2720: {
2721: /* Terminate string. */
2722: token_buffer[0] = c;
2723: token_buffer[1] = 0;
2724: if (c == '0')
2725: yylval.ttype = integer_zero_node;
2726: else
2727: yylval.ttype = integer_one_node;
2728: nextchar = c1;
2729: value = CONSTANT;
2730: goto done;
2731: }
2732: put_back (c1);
2733: }
2734: /* fall through... */
2735: case '2': case '3': case '4':
2736: case '5': case '6': case '7': case '8': case '9':
2737: resume_numerical_scan:
2738: {
2739: register char *p;
2740: int base = 10;
2741: int count = 0;
2742: int largest_digit = 0;
2743: int numdigits = 0;
2744: /* for multi-precision arithmetic,
2745: we store only 8 live bits in each short,
2746: giving us 64 bits of reliable precision */
2747: short shorts[8];
2748: int overflow = 0;
2749:
2750: enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
2751: = NOT_FLOAT;
2752:
2753: p = token_buffer;
2754: *p++ = c;
2755:
2756: for (count = 0; count < 8; count++)
2757: shorts[count] = 0;
2758:
2759: if (c == '0')
2760: {
2761: *p++ = (c = getch ());
2762: if ((c == 'x') || (c == 'X'))
2763: {
2764: base = 16;
2765: *p++ = (c = getch ());
2766: }
2767: /* Leading 0 forces octal unless the 0 is the only digit. */
2768: else if (c >= '0' && c <= '9')
2769: {
2770: base = 8;
2771: numdigits++;
2772: }
2773: else
2774: numdigits++;
2775: }
2776:
2777: /* Read all the digits-and-decimal-points. */
2778:
2779: while (c == '.'
2780: || (isalnum (c) && (c != 'l') && (c != 'L')
2781: && (c != 'u') && (c != 'U')
2782: && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
2783: {
2784: if (c == '.')
2785: {
2786: if (base == 16)
2787: error ("floating constant may not be in radix 16");
2788: if (floatflag == AFTER_POINT)
2789: {
2790: error ("malformed floating constant");
2791: floatflag = TOO_MANY_POINTS;
2792: }
2793: else
2794: floatflag = AFTER_POINT;
2795:
2796: base = 10;
2797: *p++ = c = getch ();
2798: /* Accept '.' as the start of a floating-point number
2799: only when it is followed by a digit.
2800: Otherwise, unread the following non-digit
2801: and use the '.' as a structural token. */
2802: if (p == token_buffer + 2 && !isdigit (c))
2803: {
2804: if (c == '.')
2805: {
2806: c = getch ();
2807: if (c == '.')
2808: {
2809: *p++ = '.';
2810: *p = '\0';
2811: value = ELLIPSIS;
2812: goto done;
2813: }
2814: nextchar = c;
2815: token_buffer[2] = '\0';
2816: value = RANGE;
2817: goto done;
2818: }
2819: nextchar = c;
2820: token_buffer[1] = '\0';
2821: value = '.';
2822: goto done;
2823: }
2824: }
2825: else
2826: {
2827: /* It is not a decimal point.
2828: It should be a digit (perhaps a hex digit). */
2829:
2830: if (isdigit (c))
2831: {
2832: c = c - '0';
2833: }
2834: else if (base <= 10)
2835: {
2836: if ((c&~040) == 'E')
2837: {
2838: base = 10;
2839: floatflag = AFTER_POINT;
2840: break; /* start of exponent */
2841: }
2842: error ("nondigits in number and not hexadecimal");
2843: c = 0;
2844: }
2845: else if (c >= 'a')
2846: {
2847: c = c - 'a' + 10;
2848: }
2849: else
2850: {
2851: c = c - 'A' + 10;
2852: }
2853: if (c >= largest_digit)
2854: largest_digit = c;
2855: numdigits++;
2856:
2857: for (count = 0; count < 8; count++)
2858: {
2859: shorts[count] *= base;
2860: if (count)
2861: {
2862: shorts[count] += (shorts[count-1] >> 8);
2863: shorts[count-1] &= (1<<8)-1;
2864: }
2865: else shorts[0] += c;
2866: }
2867:
2868: if (shorts[7] >= 1<<8
2869: || shorts[7] < - (1 << 8))
2870: overflow = TRUE;
2871:
2872: if (p >= token_buffer + maxtoken - 3)
2873: p = extend_token_buffer (p);
2874: *p++ = (c = getch ());
2875: }
2876: }
2877:
2878: if (numdigits == 0)
2879: error ("numeric constant with no digits");
2880:
2881: if (largest_digit >= base)
2882: error ("numeric constant contains digits beyond the radix");
2883:
2884: /* Remove terminating char from the token buffer and delimit the string */
2885: *--p = 0;
2886:
2887: if (floatflag != NOT_FLOAT)
2888: {
2889: tree type = double_type_node;
2890: char f_seen = 0;
2891: char l_seen = 0;
2892: REAL_VALUE_TYPE value;
2893: jmp_buf handler;
2894:
2895: /* Read explicit exponent if any, and put it in tokenbuf. */
2896:
2897: if ((c == 'e') || (c == 'E'))
2898: {
2899: if (p >= token_buffer + maxtoken - 3)
2900: p = extend_token_buffer (p);
2901: *p++ = c;
2902: c = getch ();
2903: if ((c == '+') || (c == '-'))
2904: {
2905: *p++ = c;
2906: c = getch ();
2907: }
2908: if (! isdigit (c))
2909: error ("floating constant exponent has no digits");
2910: while (isdigit (c))
2911: {
2912: if (p >= token_buffer + maxtoken - 3)
2913: p = extend_token_buffer (p);
2914: *p++ = c;
2915: c = getch ();
2916: }
2917: }
2918:
2919: *p = 0;
2920: errno = 0;
2921:
2922: /* Convert string to a double, checking for overflow. */
2923: if (setjmp (handler))
2924: {
2925: error ("floating constant out of range");
2926: value = dconst0;
2927: }
2928: else
2929: {
2930: set_float_handler (handler);
2931: value = REAL_VALUE_ATOF (token_buffer);
2932: set_float_handler (0);
2933: }
2934: #ifdef ERANGE
2935: if (errno == ERANGE && !flag_traditional)
2936: {
2937: char *p1 = token_buffer;
2938: /* Check for "0.0" and variants;
2939: Sunos 4 spuriously returns ERANGE for them. */
2940: while (*p1 == '0') p1++;
2941: if (*p1 == '.')
2942: {
2943: p1++;
2944: while (*p1 == '0') p1++;
2945: }
2946: if (*p1 == 'e' || *p1 == 'E')
2947: {
2948: /* with significand==0, ignore the exponent */
2949: p1++;
2950: while (*p1 != 0) p1++;
2951: }
2952: /* ERANGE is also reported for underflow,
2953: so test the value to distinguish overflow from that. */
2954: if (*p1 != 0 && (value > 1.0 || value < -1.0))
2955: warning ("floating point number exceeds range of `double'");
2956: }
2957: #endif
2958:
2959: /* Read the suffixes to choose a data type. */
2960: while (1)
2961: {
2962: if (c == 'f' || c == 'F')
2963: {
2964: if (f_seen)
2965: error ("two `f's in floating constant");
2966: f_seen = 1;
2967: type = float_type_node;
2968: value = REAL_VALUE_TRUNCATE (TYPE_MODE (type), value);
2969: }
2970: else if (c == 'l' || c == 'L')
2971: {
2972: if (l_seen)
2973: error ("two `l's in floating constant");
2974: l_seen = 1;
2975: type = long_double_type_node;
2976: }
2977: else
2978: {
2979: if (isalnum (c))
2980: {
2981: error ("garbage at end of number");
2982: while (isalnum (c))
2983: {
2984: if (p >= token_buffer + maxtoken - 3)
2985: p = extend_token_buffer (p);
2986: *p++ = c;
2987: c = getch ();
2988: }
2989: }
2990: break;
2991: }
2992: if (p >= token_buffer + maxtoken - 3)
2993: p = extend_token_buffer (p);
2994: *p++ = c;
2995: c = getch ();
2996: }
2997:
2998: /* Create a node with determined type and value. */
2999: yylval.ttype = build_real (type, value);
3000:
3001: put_back (c);
3002: *p = 0;
3003: }
3004: else
3005: {
3006: tree type;
3007: int spec_unsigned = 0;
3008: int spec_long = 0;
3009: int spec_long_long = 0;
3010:
3011: while (1)
3012: {
3013: if (c == 'u' || c == 'U')
3014: {
3015: if (spec_unsigned)
3016: error ("two `u's in integer constant");
3017: spec_unsigned = 1;
3018: }
3019: else if (c == 'l' || c == 'L')
3020: {
3021: if (spec_long)
3022: {
3023: if (spec_long_long)
3024: error ("three `l's in integer constant");
3025: else if (pedantic)
3026: pedwarn ("ANSI C forbids long long integer constants");
3027: spec_long_long = 1;
3028: }
3029: spec_long = 1;
3030: }
3031: else
3032: {
3033: if (isalnum (c))
3034: {
3035: error ("garbage at end of number");
3036: while (isalnum (c))
3037: {
3038: if (p >= token_buffer + maxtoken - 3)
3039: p = extend_token_buffer (p);
3040: *p++ = c;
3041: c = getch ();
3042: }
3043: }
3044: break;
3045: }
3046: if (p >= token_buffer + maxtoken - 3)
3047: p = extend_token_buffer (p);
3048: *p++ = c;
3049: c = getch ();
3050: }
3051:
3052: put_back (c);
3053:
3054: if ((overflow || shorts[7] || shorts[6] || shorts[5] || shorts[4])
3055: && !spec_long_long)
3056: warning ("integer constant out of range");
3057:
3058: /* If it won't fit in a signed long long, make it unsigned.
3059: We can't distinguish based on the tree node because
3060: any integer constant fits any long long type. */
3061: if (shorts[7] >= (1<<8))
3062: spec_unsigned = 1;
3063:
3064: /* This is simplified by the fact that our constant
3065: is always positive. */
3066: yylval.ttype
3067: = (build_int_2
3068: ((((long)shorts[3]<<24) + ((long)shorts[2]<<16)
3069: + ((long)shorts[1]<<8) + (long)shorts[0]),
3070: (spec_long_long
3071: ? (((long)shorts[7]<<24) + ((long)shorts[6]<<16)
3072: + ((long)shorts[5]<<8) + (long)shorts[4])
3073: : 0)));
3074:
3075: #if 0
3076: /* Find the first allowable type that the value fits in. */
3077: type = 0;
3078: for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
3079: i++)
3080: if (!(spec_long && !type_sequence[i].long_flag)
3081: && !(spec_long_long && !type_sequence[i].long_long_flag)
3082: && !(spec_unsigned && !type_sequence[i].unsigned_flag)
3083: /* A hex or octal constant traditionally is unsigned. */
3084: && !(base != 10 && flag_traditional
3085: && !type_sequence[i].unsigned_flag)
3086: /* A decimal constant can't be unsigned int
3087: unless explicitly specified. */
3088: && !(base == 10 && !spec_unsigned
3089: && *type_sequence[i].node_var == unsigned_type_node))
3090: if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
3091: {
3092: type = *type_sequence[i].node_var;
3093: break;
3094: }
3095: if (flag_traditional && type == long_unsigned_type_node
3096: && !spec_unsigned)
3097: type = long_integer_type_node;
3098:
3099: if (type == 0)
3100: {
3101: type = long_long_integer_type_node;
3102: warning ("integer constant out of range");
3103: }
3104:
3105: /* Warn about some cases where the type of a given constant
3106: changes from traditional C to ANSI C. */
3107: if (warn_traditional)
3108: {
3109: tree other_type = 0;
3110:
3111: /* This computation is the same as the previous one
3112: except that flag_traditional is used backwards. */
3113: for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
3114: i++)
3115: if (!(spec_long && !type_sequence[i].long_flag)
3116: && !(spec_long_long && !type_sequence[i].long_long_flag)
3117: && !(spec_unsigned && !type_sequence[i].unsigned_flag)
3118: /* A hex or octal constant traditionally is unsigned. */
3119: && !(base != 10 && !flag_traditional
3120: && !type_sequence[i].unsigned_flag)
3121: /* A decimal constant can't be unsigned int
3122: unless explicitly specified. */
3123: && !(base == 10 && !spec_unsigned
3124: && *type_sequence[i].node_var == unsigned_type_node))
3125: if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
3126: {
3127: other_type = *type_sequence[i].node_var;
3128: break;
3129: }
3130: if (!flag_traditional && type == long_unsigned_type_node
3131: && !spec_unsigned)
3132: type = long_integer_type_node;
3133:
3134: if (other_type != 0 && other_type != type)
3135: {
3136: if (flag_traditional)
3137: warning ("type of integer constant would be different without -traditional");
3138: else
3139: warning ("type of integer constant would be different with -traditional");
3140: }
3141: }
3142:
3143: #else /* 1 */
3144: if (!spec_long && !spec_unsigned
3145: && !(flag_traditional && base != 10)
3146: && int_fits_type_p (yylval.ttype, integer_type_node))
3147: {
3148: #if 0
3149: if (warn_traditional && base != 10)
3150: warning ("small nondecimal constant becomes signed in ANSI C");
3151: #endif
3152: type = integer_type_node;
3153: }
3154: else if (!spec_long && (base != 10 || spec_unsigned)
3155: && int_fits_type_p (yylval.ttype, unsigned_type_node))
3156: {
3157: /* Nondecimal constants try unsigned even in traditional C. */
3158: type = unsigned_type_node;
3159: }
3160:
3161: else if (!spec_unsigned && !spec_long_long
3162: && int_fits_type_p (yylval.ttype, long_integer_type_node))
3163: type = long_integer_type_node;
3164:
3165: else if (! spec_long_long
3166: && int_fits_type_p (yylval.ttype,
3167: long_unsigned_type_node))
3168: {
3169: #if 0
3170: if (warn_traditional && !spec_unsigned)
3171: warning ("large integer constant becomes unsigned in ANSI C");
3172: #endif
3173: if (flag_traditional && !spec_unsigned)
3174: type = long_integer_type_node;
3175: else
3176: type = long_unsigned_type_node;
3177: }
3178:
3179: else if (! spec_unsigned
3180: && int_fits_type_p (yylval.ttype,
3181: long_long_integer_type_node))
3182: type = long_long_integer_type_node;
3183:
3184: else if (int_fits_type_p (yylval.ttype,
3185: long_long_unsigned_type_node))
3186: {
3187: #if 0
3188: if (warn_traditional && !spec_unsigned)
3189: warning ("large nondecimal constant is unsigned in ANSI C");
3190: #endif
3191:
3192: if (flag_traditional && !spec_unsigned)
3193: type = long_long_integer_type_node;
3194: else
3195: type = long_long_unsigned_type_node;
3196: }
3197:
3198: else
3199: {
3200: type = long_long_integer_type_node;
3201: warning ("integer constant out of range");
3202: }
3203: #endif
3204:
3205: TREE_TYPE (yylval.ttype) = type;
3206: *p = 0;
3207: }
3208:
3209: value = CONSTANT; break;
3210: }
3211:
3212: case '\'':
3213: char_constant:
3214: {
3215: register int result = 0;
3216: register num_chars = 0;
3217: unsigned width = TYPE_PRECISION (char_type_node);
3218: int max_chars;
3219:
3220: if (wide_flag) width = TYPE_PRECISION (integer_type_node);
3221:
3222: max_chars = TYPE_PRECISION (integer_type_node) / width;
3223:
3224: while (1)
3225: {
3226: tryagain:
3227:
3228: c = getch ();
3229:
3230: if (c == '\'' || c == EOF)
3231: break;
3232:
3233: if (c == '\\')
3234: {
3235: c = readescape ();
3236: if (c < 0)
3237: goto tryagain;
3238: if (width < HOST_BITS_PER_INT
3239: && (unsigned) c >= (1 << width))
3240: warning ("escape sequence out of range for character");
3241: }
3242: else if (c == '\n')
3243: {
3244: if (pedantic)
1.1.1.3 ! root 3245: pedwarn ("ANSI C forbids newline in character constant");
1.1 root 3246: lineno++;
3247: }
3248:
3249: num_chars++;
3250: if (num_chars > maxtoken - 4)
3251: extend_token_buffer (token_buffer);
3252:
3253: token_buffer[num_chars] = c;
3254:
3255: /* Merge character into result; ignore excess chars. */
3256: if (num_chars < max_chars + 1)
3257: {
3258: if (width < HOST_BITS_PER_INT)
3259: result = (result << width) | (c & ((1 << width) - 1));
3260: else
3261: result = c;
3262: }
3263: }
3264:
3265: token_buffer[num_chars + 1] = '\'';
3266: token_buffer[num_chars + 2] = 0;
3267:
3268: if (c != '\'')
3269: error ("malformatted character constant");
3270: else if (num_chars == 0)
3271: error ("empty character constant");
3272: else if (num_chars > max_chars)
3273: {
3274: num_chars = max_chars;
3275: error ("character constant too long");
3276: }
3277: else if (num_chars != 1 && ! flag_traditional)
3278: warning ("multi-character character constant");
3279:
3280: /* If char type is signed, sign-extend the constant. */
3281: if (! wide_flag)
3282: {
3283: int num_bits = num_chars * width;
3284: if (TREE_UNSIGNED (char_type_node)
3285: || ((result >> (num_bits - 1)) & 1) == 0)
3286: yylval.ttype
3287: = build_int_2 (result & ((unsigned) ~0
3288: >> (HOST_BITS_PER_INT - num_bits)),
3289: 0);
3290: else
3291: yylval.ttype
3292: = build_int_2 (result | ~((unsigned) ~0
3293: >> (HOST_BITS_PER_INT - num_bits)),
3294: -1);
3295: TREE_TYPE (yylval.ttype) = char_type_node;
3296: }
3297: else
3298: {
3299: yylval.ttype = build_int_2 (result, 0);
3300: TREE_TYPE (yylval.ttype) = integer_type_node;
3301: }
3302: value = CONSTANT; break;
3303: }
3304:
3305: case '"':
3306: string_constant:
3307: {
3308: int *widep;
3309: register char *p;
3310:
3311: c = getch ();
3312: p = token_buffer + 1;
3313:
3314: if (wide_flag)
3315: widep = wide_buffer;
3316:
3317: while (c != '"' && c >= 0)
3318: {
3319: if (c == '\\')
3320: {
3321: c = readescape ();
3322: if (c < 0)
3323: goto skipnewline;
3324: if (!wide_flag && c >= (1 << BITS_PER_UNIT))
3325: warning ("escape sequence out of range for character");
3326: }
3327: else if (c == '\n')
3328: {
3329: if (pedantic)
1.1.1.3 ! root 3330: pedwarn ("ANSI C forbids newline in string constant");
1.1 root 3331: lineno++;
3332: }
3333:
3334: /* Store the char in C into the appropriate buffer. */
3335:
3336: if (wide_flag)
3337: {
3338: if (widep == wide_buffer + max_wide)
3339: {
3340: int n = widep - wide_buffer;
3341: max_wide *= 2;
3342: wide_buffer = (int *) xrealloc (wide_buffer, max_wide + 1);
3343: widep = wide_buffer + n;
3344: }
3345: *widep++ = c;
3346: }
3347: else
3348: {
3349: if (p == token_buffer + maxtoken)
3350: p = extend_token_buffer (p);
3351: *p++ = c;
3352: }
3353:
3354: skipnewline:
3355: c = getch ();
3356: if (c == EOF) {
3357: error("Unterminated string");
3358: break;
3359: }
3360: }
3361:
3362: /* We have read the entire constant.
3363: Construct a STRING_CST for the result. */
3364:
3365: if (wide_flag)
3366: {
3367: /* If this is a L"..." wide-string, make a vector
3368: of the ints in wide_buffer. */
3369: *widep = 0;
3370: /* We have not implemented the case where `int'
3371: on the target and on the execution machine differ in size. */
3372: assert (TYPE_PRECISION (integer_type_node) == sizeof (int) * BITS_PER_UNIT);
3373: yylval.ttype = build_string ((widep - wide_buffer + 1) * sizeof (int),
3374: (char *)wide_buffer);
3375: TREE_TYPE (yylval.ttype) = int_array_type_node;
3376: }
3377: else
3378: {
3379: *p = 0;
3380: yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
3381: TREE_TYPE (yylval.ttype) = char_array_type_node;
3382: }
3383:
3384: *p++ = '"';
3385: *p = 0;
3386:
3387: value = STRING; break;
3388: }
3389:
3390: case '+':
3391: case '-':
3392: case '&':
3393: case '|':
3394: case '<':
3395: case '>':
3396: case '*':
3397: case '/':
3398: case '%':
3399: case '^':
3400: case '!':
3401: case '=':
3402: {
3403: register int c1;
3404:
3405: combine:
3406:
3407: switch (c)
3408: {
3409: case '+':
3410: yylval.code = PLUS_EXPR; break;
3411: case '-':
3412: yylval.code = MINUS_EXPR; break;
3413: case '&':
3414: yylval.code = BIT_AND_EXPR; break;
3415: case '|':
3416: yylval.code = BIT_IOR_EXPR; break;
3417: case '*':
3418: yylval.code = MULT_EXPR; break;
3419: case '/':
3420: yylval.code = TRUNC_DIV_EXPR; break;
3421: case '%':
3422: yylval.code = TRUNC_MOD_EXPR; break;
3423: case '^':
3424: yylval.code = BIT_XOR_EXPR; break;
3425: case LSHIFT:
3426: yylval.code = LSHIFT_EXPR; break;
3427: case RSHIFT:
3428: yylval.code = RSHIFT_EXPR; break;
3429: case '<':
3430: yylval.code = LT_EXPR; break;
3431: case '>':
3432: yylval.code = GT_EXPR; break;
3433: }
3434:
3435: token_buffer[1] = c1 = getch ();
3436: token_buffer[2] = 0;
3437:
3438: if (c1 == '=')
3439: {
3440: switch (c)
3441: {
3442: case '<':
3443: value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
3444: case '>':
3445: value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
3446: case '!':
3447: value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
3448: case '=':
3449: value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
3450: }
3451: value = ASSIGN; goto done;
3452: }
3453: else if (c == c1)
3454: switch (c)
3455: {
3456: case '+':
3457: value = PLUSPLUS; goto done;
3458: case '-':
3459: value = MINUSMINUS; goto done;
3460: case '&':
3461: value = ANDAND; goto done;
3462: case '|':
3463: value = OROR; goto done;
3464: case '<':
3465: c = LSHIFT;
3466: goto combine;
3467: case '>':
3468: c = RSHIFT;
3469: goto combine;
3470: }
3471: else if ((c == '-') && (c1 == '>'))
3472: {
3473: nextchar = skip_white_space (getch ());
3474: if (nextchar == '(')
3475: {
3476: int next_c = skip_white_space (getch ());
3477: if (next_c == ')')
3478: {
3479: nextchar = -1;
3480: value = POINTSAT_LEFT_RIGHT;
3481: goto done;
3482: }
3483: put_back (next_c);
3484: }
3485: if (nextchar == '*')
3486: {
3487: nextchar = -1;
3488: value = POINTSAT_STAR;
3489: }
3490: else
3491: value = POINTSAT;
3492: goto done;
3493: }
3494: else if (c1 == '?' && (c == '<' || c == '>'))
3495: {
3496: token_buffer[3] = 0;
3497:
3498: c1 = getch ();
3499: yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
3500: if (c1 == '=')
3501: {
3502: /* <?= or >?= expression. */
3503: token_buffer[2] = c1;
3504: value = ASSIGN;
3505: }
3506: else
3507: {
3508: value = MIN_MAX;
3509: nextchar = c1;
3510: }
3511: if (pedantic)
3512: error ("use of `operator %s' is not standard C++",
3513: token_buffer);
3514: goto done;
3515: }
3516:
3517: nextchar = c1;
3518: token_buffer[1] = 0;
3519:
3520: value = c;
3521: goto done;
3522: }
3523:
3524: case ':':
3525: c = getch ();
3526: if (c == ':')
3527: {
3528: token_buffer[1] = ':';
3529: token_buffer[2] = '\0';
3530: value = SCOPE;
3531: yylval.itype = 1;
3532: }
3533: else
3534: {
3535: nextchar = c;
3536: value = ':';
3537: }
3538: break;
3539:
3540: case 0:
3541: /* Don't make yyparse think this is eof. */
3542: value = 1;
3543: break;
3544:
3545: case '(':
3546: /* try, weakly, to handle casts to pointers to functions. */
3547: nextchar = skip_white_space (getch ());
3548: if (nextchar == '*')
3549: {
3550: int next_c = skip_white_space (getch ());
3551: if (next_c == ')')
3552: {
3553: nextchar = -1;
3554: yylval.ttype = build1 (INDIRECT_REF, 0, 0);
3555: value = PAREN_STAR_PAREN;
3556: }
3557: else
3558: {
3559: put_back (next_c);
3560: value = c;
3561: }
3562: }
3563: else if (nextchar == ')')
3564: {
3565: nextchar = -1;
3566: yylval.ttype = NULL_TREE;
3567: value = LEFT_RIGHT;
3568: }
3569: else value = c;
3570: break;
3571:
3572: default:
3573: value = c;
3574: }
3575:
3576: done:
3577: /* yylloc.last_line = lineno; */
3578: #ifdef GATHER_STATISTICS
3579: token_count[value] += 1;
3580: #endif
3581:
3582: return value;
3583: }
3584:
3585: typedef enum
3586: {
3587: d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
3588: id_kind, op_id_kind, perm_list_kind, temp_list_kind,
3589: vec_kind, x_kind, lang_decl, lang_type, all_kinds
3590: } tree_node_kind;
3591: extern int tree_node_counts[];
3592: extern int tree_node_sizes[];
3593: extern char *tree_node_kind_names[];
3594:
3595: /* Place to save freed lang_decls which were allocated on the
3596: permanent_obstack. @@ Not currently used. */
3597: tree free_lang_decl_chain;
3598:
3599: tree
3600: build_lang_decl (code, name, type)
3601: enum tree_code code;
3602: tree name;
3603: tree type;
3604: {
3605: register tree t = build_decl (code, name, type);
3606: struct obstack *obstack = current_obstack;
3607: register int i = sizeof (struct lang_decl) / sizeof (int);
3608: register int *pi;
3609:
3610: if (! TREE_PERMANENT (t))
3611: obstack = saveable_obstack;
3612: else
3613: /* Could be that saveable is permanent and current is not. */
3614: obstack = &permanent_obstack;
3615:
3616: if (free_lang_decl_chain && obstack == &permanent_obstack)
3617: {
3618: pi = (int *)free_lang_decl_chain;
3619: free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
3620: }
3621: else
3622: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
3623:
3624: while (i > 0)
3625: pi[--i] = 0;
3626:
3627: DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
3628: LANG_DECL_PERMANENT ((struct lang_decl *) pi)
3629: = obstack == &permanent_obstack;
3630: assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
3631: == TREE_PERMANENT (t));
3632: DECL_MAIN_VARIANT (t) = t;
3633: if (current_lang_name == lang_name_cplusplus)
3634: {
3635: DECL_LANGUAGE (t) = lang_cplusplus;
3636:
3637: #ifndef NO_AUTO_OVERLOAD
3638: if (code == FUNCTION_DECL && name != 0
3639: && ! (IDENTIFIER_LENGTH (name) == 4
3640: && IDENTIFIER_POINTER (name)[0] == 'm'
3641: && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
3642: && ! (IDENTIFIER_LENGTH (name) > 10
3643: && IDENTIFIER_POINTER (name)[0] == '_'
3644: && IDENTIFIER_POINTER (name)[1] == '_'
3645: && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
3646: TREE_OVERLOADED (name) = 1;
3647: #endif
3648: }
3649: else if (current_lang_name == lang_name_c)
3650: DECL_LANGUAGE (t) = lang_c;
1.1.1.3 ! root 3651: else my_friendly_abort (64);
1.1 root 3652:
1.1.1.2 root 3653: #if 0 /* not yet, should get fixed properly later */
3654: if (code == TYPE_DECL)
3655: {
3656: tree id;
3657: id = get_identifier (build_overload_name (type, 1, 1));
3658: DECL_ASSEMBLER_NAME (t) = id;
3659: }
3660:
3661: #endif
1.1 root 3662: #ifdef GATHER_STATISTICS
3663: tree_node_counts[(int)lang_decl] += 1;
3664: tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
3665: #endif
3666:
3667: return t;
3668: }
3669:
3670: tree
3671: build_lang_field_decl (code, name, type)
3672: enum tree_code code;
3673: tree name;
3674: tree type;
3675: {
3676: extern struct obstack *current_obstack, *saveable_obstack;
3677: register tree t = build_decl (code, name, type);
3678: struct obstack *obstack = current_obstack;
3679: register int i = sizeof (struct lang_decl_flags) / sizeof (int);
3680: register int *pi;
1.1.1.2 root 3681: #if 0 /* not yet, should get fixed properly later */
3682:
3683: if (code == TYPE_DECL)
3684: {
3685: tree id;
3686: id = get_identifier (build_overload_name (type, 1, 1));
3687: DECL_ASSEMBLER_NAME (t) = id;
3688: }
3689: #endif
1.1 root 3690:
3691: if (! TREE_PERMANENT (t))
3692: obstack = saveable_obstack;
3693: else
3694: assert (obstack == &permanent_obstack);
3695:
3696: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
3697: while (i > 0)
3698: pi[--i] = 0;
3699:
3700: DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
3701: return t;
3702: }
3703:
3704: void
3705: copy_lang_decl (node)
3706: tree node;
3707: {
3708: int size;
3709: int *pi;
3710:
3711: if (TREE_CODE (node) == FIELD_DECL)
3712: size = sizeof (struct lang_decl_flags);
3713: else
3714: size = sizeof (struct lang_decl);
3715: pi = (int *)obstack_alloc (&permanent_obstack, size);
1.1.1.3 ! root 3716: bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
1.1 root 3717: DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
3718: }
3719:
3720: tree
3721: make_lang_type (code)
3722: enum tree_code code;
3723: {
3724: extern struct obstack *current_obstack, *saveable_obstack;
3725: register tree t = make_node (code);
3726: struct obstack *obstack = current_obstack;
3727: register int i = sizeof (struct lang_type) / sizeof (int);
3728: register int *pi;
3729:
3730: /* Set up some flags that give proper default behavior. */
3731: IS_AGGR_TYPE (t) = 1;
3732:
3733: if (! TREE_PERMANENT (t))
3734: obstack = saveable_obstack;
3735: else
3736: assert (obstack == &permanent_obstack);
3737:
3738: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
3739: while (i > 0)
3740: pi[--i] = 0;
3741:
3742: TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
3743: CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
3744: CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown;
3745: CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
3746: CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
3747: TYPE_BINFO (t) = make_binfo (integer_zero_node, t, 0, 0, 0);
3748: CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
3749:
3750: /* Make sure this is laid out, for ease of use later.
3751: In the presence of parse errors, the normal was of assuring
3752: this might not ever get executed, so we lay it out *immediately*. */
3753: build_pointer_type (t);
3754:
3755: #ifdef GATHER_STATISTICS
3756: tree_node_counts[(int)lang_type] += 1;
3757: tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
3758: #endif
3759:
3760: return t;
3761: }
3762:
3763: void
3764: copy_decl_lang_specific (decl)
3765: tree decl;
3766: {
3767: extern struct obstack *current_obstack, *saveable_obstack;
3768: register int *old = (int *)DECL_LANG_SPECIFIC (decl);
3769: struct obstack *obstack = current_obstack;
3770: register int i = sizeof (struct lang_decl) / sizeof (int);
3771: register int *pi;
3772:
3773: if (! TREE_PERMANENT (decl))
3774: obstack = saveable_obstack;
3775: else
3776: assert (obstack == &permanent_obstack);
3777:
3778: pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
3779: while (i-- > 0)
3780: pi[i] = old[i];
3781:
3782: DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
3783:
3784: #ifdef GATHER_STATISTICS
3785: tree_node_counts[(int)lang_decl] += 1;
3786: tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
3787: #endif
3788: }
3789:
3790: void
3791: dump_time_statistics ()
3792: {
3793: register tree prev = 0, decl, next;
3794: int this_time = my_get_run_time ();
3795: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
3796: += this_time - body_time;
3797:
3798: fprintf (stderr, "\n******\n");
3799: print_time ("header files (total)", header_time);
3800: print_time ("main file (total)", this_time - body_time);
3801: fprintf (stderr, "ratio = %g : 1\n",
3802: (double)header_time / (double)(this_time - body_time));
3803: fprintf (stderr, "\n******\n");
3804:
3805: for (decl = filename_times; decl; decl = next)
3806: {
3807: next = IDENTIFIER_GLOBAL_VALUE (decl);
3808: IDENTIFIER_GLOBAL_VALUE (decl) = prev;
3809: prev = decl;
3810: }
3811:
3812: for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
3813: print_time (IDENTIFIER_POINTER (decl),
3814: TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
3815: }
3816:
3817: void
3818: compiler_error (s, v, v2)
3819: char *s;
3820: int v, v2; /* @@also used as pointer */
3821: {
3822: char buf[1024];
3823: sprintf (buf, s, v, v2);
3824: error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
3825: }
3826:
3827: void
3828: compiler_error_with_decl (decl, s)
3829: tree decl;
3830: char *s;
3831: {
3832: char *name;
3833: count_error (0);
3834:
3835: report_error_function (0);
3836:
3837: if (TREE_CODE (decl) == PARM_DECL)
3838: fprintf (stderr, "%s:%d: ",
3839: DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
3840: DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
3841: else
3842: fprintf (stderr, "%s:%d: ",
3843: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
3844:
3845: name = lang_printable_name (decl);
3846: if (name)
3847: fprintf (stderr, s, name);
3848: else
3849: fprintf (stderr, s, "((anonymous))");
3850: fprintf (stderr, " (compiler error)\n");
3851: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.