No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / usr.bin / g++ / cc1plus / cplus-lex.c
blobff9b2eff68d8a26003a4b4df4d9fe48c373fd4c9
1 /*-
2 * This code is derived from software copyrighted by the Free Software
3 * Foundation.
5 * Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
6 */
8 #ifndef lint
9 static char sccsid[] = "@(#)cplus-lex.c 6.4 (Berkeley) 5/8/91";
10 #endif /* not lint */
12 /* Separate lexical analyzer for GNU C++.
13 Copyright (C) 1987 Free Software Foundation, Inc.
14 Hacked by Michael Tiemann (tiemann@mcc.com)
16 This file is part of GNU CC.
18 GNU CC is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 1, or (at your option)
21 any later version.
23 GNU CC is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with GNU CC; see the file COPYING. If not, write to
30 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
33 /* This file is the lexical analyzer for GNU C++. */
35 #include <sys/types.h>
36 #include <stdio.h>
37 #include <errno.h>
38 #include <setjmp.h>
39 #include <string.h>
40 #include "config.h"
41 #include "input.h"
42 #include "tree.h"
43 #ifdef VMS
44 #define _IOFBF 2 /* Missing from GNU's stdio.h */
45 #endif
46 #include "cplus-tab.h"
47 #include "cplus-parse.h"
48 #include "cplus-tree.h"
49 #include "flags.h"
50 #include "obstack.h"
51 #include "assert.h"
52 extern int errno; /* needed for VAX. */
53 extern jmp_buf toplevel;
55 #ifdef VMS
56 #define NULL_FILE "nla0:"
57 #else
58 #define NULL_FILE "/dev/null"
59 #endif
61 #define obstack_chunk_alloc xmalloc
62 #define obstack_chunk_free free
64 extern int xmalloc ();
65 extern void free ();
67 extern double atof ();
69 /* If you don't have strrchr, but instead have rindex,
70 add your machine to this list, and send mail to
71 tiemann@wheaties.ai.mit.edu. */
72 #if defined(sequent) || defined(convex)
73 #define strrchr rindex
74 #endif
75 extern char *strrchr ();
77 /* This obstack is needed to hold text. It is not safe to use
78 TOKEN_BUFFER because `check_newline' calls `yylex'. */
79 static struct obstack inline_text_obstack;
80 static char *inline_text_firstobj;
82 /* Holds translations from TREE_CODEs to operator name strings,
83 i.e., opname_tab[PLUS_EXPR] == "+". */
84 char **opname_tab;
85 char **assignop_tab;
87 #define YYEMPTY -1
88 int yychar; /* the lookahead symbol */
89 YYSTYPE yylval; /* the semantic value of the */
90 /* lookahead symbol */
92 #if 0
93 YYLTYPE yylloc; /* location data for the lookahead */
94 /* symbol */
95 #endif
97 int end_of_file;
99 /* the declaration found for the last IDENTIFIER token read in.
100 yylex must look this up to detect typedefs, which get token type TYPENAME,
101 so it is left around in case the identifier is not a typedef but is
102 used in a context which makes it a reference to a variable. */
103 tree lastiddecl;
105 /* C++ extensions */
106 tree ridpointers[]; /* need this up here */
108 /* We may keep statistics about how long which files took to compile. */
109 static int header_time, body_time;
110 static tree get_time_identifier ();
111 static tree filename_times;
112 static tree this_filename_time;
114 /* For implementing #pragma unit. */
115 tree current_unit_name;
116 tree current_unit_language;
118 /* Array for holding counts of the numbers of tokens seen. */
119 int *token_count;
121 /* Return something to represent absolute declarators containing a *.
122 TARGET is the absolute declarator that the * contains.
123 TYPE_QUALS is a list of modifiers such as const or volatile
124 to apply to the pointer type, represented as identifiers.
126 We return an INDIRECT_REF whose "contents" are TARGET
127 and whose type is the modifier list. */
129 tree
130 make_pointer_declarator (type_quals, target)
131 tree type_quals, target;
133 if (target && TREE_CODE (target) == IDENTIFIER_NODE
134 && ANON_AGGRNAME_P (target))
135 error ("type name expected before `*'");
136 return build1 (INDIRECT_REF, type_quals, target);
139 /* Return something to represent absolute declarators containing a &.
140 TARGET is the absolute declarator that the & contains.
141 TYPE_QUALS is a list of modifiers such as const or volatile
142 to apply to the reference type, represented as identifiers.
144 We return an ADDR_EXPR whose "contents" are TARGET
145 and whose type is the modifier list. */
147 tree
148 make_reference_declarator (type_quals, target)
149 tree type_quals, target;
151 if (target)
153 if (TREE_CODE (target) == ADDR_EXPR)
155 error ("cannot declare references to references");
156 return target;
158 if (TREE_CODE (target) == INDIRECT_REF)
160 error ("cannot declare pointers to references");
161 return target;
163 if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
164 error ("type name expected before `&'");
166 return build1 (ADDR_EXPR, type_quals, target);
169 /* Given a chain of STRING_CST nodes,
170 concatenate them into one STRING_CST
171 and give it a suitable array-of-chars data type. */
173 tree
174 combine_strings (strings)
175 tree strings;
177 register tree value, t;
178 register int length = 1;
179 int wide_length = 0;
180 int wide_flag = 0;
182 if (TREE_CHAIN (strings))
184 /* More than one in the chain, so concatenate. */
185 register char *p, *q;
187 /* Don't include the \0 at the end of each substring,
188 except for the last one.
189 Count wide strings and ordinary strings separately. */
190 for (t = strings; t; t = TREE_CHAIN (t))
192 if (TREE_TYPE (t) == int_array_type_node)
194 wide_length += (TREE_STRING_LENGTH (t) - 1);
195 wide_flag = 1;
197 else
198 length += (TREE_STRING_LENGTH (t) - 1);
201 /* If anything is wide, the non-wides will be converted,
202 which makes them take more space. */
203 if (wide_flag)
204 length = length * UNITS_PER_WORD + wide_length;
206 p = (char *) savealloc (length);
208 /* Copy the individual strings into the new combined string.
209 If the combined string is wide, convert the chars to ints
210 for any individual strings that are not wide. */
212 q = p;
213 for (t = strings; t; t = TREE_CHAIN (t))
215 int len = TREE_STRING_LENGTH (t) - 1;
216 if ((TREE_TYPE (t) == int_array_type_node) == wide_flag)
218 bcopy (TREE_STRING_POINTER (t), q, len);
219 q += len;
221 else
223 int i;
224 for (i = 0; i < len; i++)
225 ((int *) q)[i] = TREE_STRING_POINTER (t)[i];
226 q += len * UNITS_PER_WORD;
229 *q = 0;
231 value = make_node (STRING_CST);
232 TREE_STRING_POINTER (value) = p;
233 TREE_STRING_LENGTH (value) = length;
234 TREE_LITERAL (value) = 1;
236 else
238 value = strings;
239 length = TREE_STRING_LENGTH (value);
240 if (TREE_TYPE (value) == int_array_type_node)
241 wide_flag = 1;
244 /* Create the array type for the string constant.
245 -Wwrite-strings says make the string constant an array of const char
246 so that copying it to a non-const pointer will get a warning. */
247 if (warn_write_strings)
249 tree elements
250 = build_type_variant (wide_flag ? integer_type_node : char_type_node,
251 1, 0);
252 TREE_TYPE (value)
253 = build_array_type (elements,
254 build_index_type (build_int_2 (length - 1, 0)));
256 else
257 TREE_TYPE (value)
258 = build_array_type (wide_flag ? integer_type_node : char_type_node,
259 build_index_type (build_int_2 (length - 1, 0)));
260 TREE_LITERAL (value) = 1;
261 TREE_STATIC (value) = 1;
262 return value;
265 /* Build names and nodes for overloaded operators. */
267 /* Memoized table for operator names. */
268 tree *node_table;
270 tree
271 build_opid (code1, code2)
272 enum tree_code code1, code2;
274 register tree t = make_node (OP_IDENTIFIER);
275 register tree tmp;
276 extern struct obstack *expression_obstack, permanent_obstack;
277 struct obstack *ambient_obstack = expression_obstack;
278 expression_obstack = &permanent_obstack;
279 if (code1 != 0)
281 if ((tmp = node_table[(int)code1]) == 0)
282 node_table[(int)code1] = tmp = make_node (code1);
283 TREE_PURPOSE (t) = tmp;
285 if ((tmp = node_table[(int)code2]) == 0)
286 node_table[(int)code2] = tmp = make_node (code2);
287 TREE_VALUE (t) = tmp;
288 expression_obstack = ambient_obstack;
289 return t;
292 #ifdef __GNUC__
293 #define DEFTREECODE(SYM, NAME, TYPE, LEN) sizeof (NAME),
294 #else
295 #define DEFTREECODE(SYM, NAME, TYPE, LEN) -1,
296 #endif
297 static short opname_end[] = {
298 #include "tree.def"
299 7, /* sizeof ("@@dummy"), */
300 #include "cplus-tree.def"
302 #undef DEFTREECODE
304 /* Given a TOKEN and its estimated tree code CODE, produce a name which
305 can be recognized by lookup_name. Based on the number of PARMS,
306 build an appropriate operator fnname. This function is needed because
307 until we know how many parameters we have, we cannot reliably tell
308 what function indeed we are trying to declare.
310 NPARMS is the number of additional parameters that this operator
311 will ultimately have. If NPARMS == -1, then we are just building
312 a name, and should not complain.
314 This would be a good candidate for memoizing. */
315 tree
316 build_operator_fnname (declp, parms, nparms)
317 tree *declp;
318 tree parms;
319 int nparms;
321 tree decl = *declp;
322 char **opname_table, *opname;
323 int assignop_p = 0;
324 tree rval;
325 enum tree_code code;
326 char buf[1024];
327 int saw_class = nparms;
328 int erred = 0;
330 while (parms)
332 tree type;
333 if (parms == void_list_node)
334 break;
336 if (! saw_class)
338 type = TREE_VALUE (parms);
339 if (TREE_CODE (type) == REFERENCE_TYPE)
340 type = TREE_TYPE (type);
341 if (TREE_CODE (type) == POINTER_TYPE)
342 type = TREE_TYPE (type);
343 if (IS_AGGR_TYPE (type))
344 saw_class = 1;
346 nparms++;
347 parms = TREE_CHAIN (parms);
350 if (TREE_CODE (decl) == TYPE_EXPR)
352 /* @@ may need to perform type instantiation here. */
353 if (nparms > 1)
354 error ("wrong number of arguments to type conversion operator");
356 /* The grammar will swallow an "()" if one was given.
357 We attempt to correct for this lossage here. */
358 if (TREE_OPERAND (decl, 0)
359 && TREE_CODE (TREE_OPERAND (decl, 0)) == CALL_EXPR)
361 rval = build_typename_overload (groktypename (build_tree_list (TREE_TYPE (decl), NULL_TREE)));
362 yychar = LEFT_RIGHT;
364 else
366 rval = build_typename_overload (groktypename (build_tree_list (TREE_TYPE (decl), TREE_OPERAND (decl, 0))));
368 return rval;
371 if (TREE_PURPOSE (decl))
372 if (TREE_CODE (TREE_PURPOSE (decl)) == MODIFY_EXPR)
374 opname_table = assignop_tab;
375 assignop_p = 1;
377 else
378 abort ();
379 else
380 opname_table = opname_tab;
382 code = TREE_CODE (TREE_VALUE (decl));
383 opname = opname_table[(int) code];
385 if (assignop_p)
387 if (nparms == 1 || nparms > 2)
388 error ("wrong number of parameters op `operator %s'", opname);
390 else switch (code)
392 case ERROR_MARK:
393 rval = get_identifier ("<invalid operator>");
394 TREE_OVERLOADED (rval) = 1;
395 return rval;
397 /* AC/DC */
398 case PLUS_EXPR:
399 if (nparms == 1)
400 code = CONVERT_EXPR;
401 else if (nparms != 2)
402 erred = 1;
403 break;
405 case ADDR_EXPR:
406 case BIT_AND_EXPR:
407 if (nparms == 1)
408 code = ADDR_EXPR;
409 else if (nparms == 2)
410 code = BIT_AND_EXPR;
411 else
413 code = BIT_AND_EXPR;
414 erred = 1;
416 break;
418 case MULT_EXPR:
419 case INDIRECT_REF:
420 if (nparms == 1)
421 code = INDIRECT_REF;
422 else if (nparms == 2)
423 code = MULT_EXPR;
424 else
426 code = MULT_EXPR;
427 erred = 1;
429 break;
431 case MINUS_EXPR:
432 case NEGATE_EXPR:
433 if (nparms == 1)
434 code = NEGATE_EXPR;
435 else if (nparms == 2)
436 code = MINUS_EXPR;
437 else
439 code = MINUS_EXPR;
440 erred = 1;
442 break;
444 case POINTSAT:
445 if (nparms == 1 || nparms < 0)
446 code = COMPONENT_REF;
447 else
449 erred = -1;
450 error ("wrong number of parameters to `operator ->()'");
452 break;
454 case METHOD_CALL_EXPR:
455 switch (nparms)
457 case 0:
458 case 1:
459 erred = -1;
460 error ("too few arguments to `operator ->()(...)'");
461 break;
462 /* 4 happens when we pass in the canonical number
463 of arguments. */
464 case 4:
465 nparms = 3;
466 case -1:
467 case 2:
468 case 3:
469 break;
470 default:
471 erred = -1;
472 error ("too many arguments to `operator ->()(...)'");
473 break;
475 break;
477 /* The two following entrys are for two different ways of
478 encoding `operator ='. */
479 case NOP_EXPR:
480 if (nparms != 2 && nparms >= 0)
481 erred = 1;
482 break;
484 case MODIFY_EXPR:
485 if (nparms != 2 && nparms >= 0)
486 erred = 1;
487 break;
489 case NEW_EXPR:
490 if (saw_class == 0)
492 if (nparms > 1)
493 return get_identifier (OPERATOR_NEW_FORMAT);
494 return get_identifier ("__builtin_new");
496 break;
498 case DELETE_EXPR:
499 if (saw_class == 0)
501 if (nparms > 1)
502 error ("too many parameters to `operator ::delete'");
503 return get_identifier ("__builtin_delete");
505 if (nparms > 2)
506 erred = 1;
507 break;
509 /* Whatever it was, we know its arity. Just check that it
510 has the right number of parameters defined. */
511 default:
512 /* These are the only operators which do not need
513 to have a class-type associated with them. */
515 if (code == PREDECREMENT_EXPR
516 || code == POSTINCREMENT_EXPR
517 || code == COMPONENT_REF)
519 if (nparms > 1)
520 erred = 1;
522 else if (nparms < 0
523 || code == CALL_EXPR
524 || code == METHOD_CALL_EXPR)
526 else if (nparms != tree_code_length [(int) code])
527 erred = 1;
528 break;
531 if (erred > 0)
532 error ("wrong number of parameters to `operator %s'", opname);
533 else if (erred == 0 && code != TREE_CODE (TREE_VALUE (decl)))
535 enum tree_code assign_code = ERROR_MARK;
536 if (TREE_PURPOSE (decl))
537 assign_code = TREE_CODE (TREE_PURPOSE (decl));
538 decl = build_opid (assign_code, code);
539 *declp = decl;
542 if (! saw_class)
543 error ("`operator %s' must have at least one class type", opname);
545 if (assignop_p)
547 sprintf (buf, OPERATOR_ASSIGN_FORMAT, tree_code_name [(int) code]);
548 buf[opname_end[(int) code] + sizeof (OPERATOR_ASSIGN_FORMAT) - 3] = '\0';
550 else
552 sprintf (buf, OPERATOR_FORMAT, tree_code_name [(int) code]);
553 buf[opname_end[(int) code] + sizeof (OPERATOR_FORMAT) - 3] = '\0';
555 rval = get_identifier (buf);
556 TREE_OVERLOADED (rval) = 1;
557 return rval;
560 char *
561 operator_name_string (name)
562 tree name;
564 char *opname = IDENTIFIER_POINTER (name)
565 + sizeof (OPERATOR_FORMAT) - sizeof ("%s");
566 int i, assign;
568 /* Works for builtin and user defined types. */
569 if (IDENTIFIER_GLOBAL_VALUE (name)
570 && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
571 return IDENTIFIER_POINTER (name);
573 if (! strncmp (opname, "assign", 6))
575 opname += 7;
576 assign = 1;
578 else
579 assign = 0;
581 for (i = 0; i < LAST_CPLUS_TREE_CODE; i++)
583 if (! strncmp (opname, tree_code_name[i], opname_end[i]))
584 break;
587 assert (i != LAST_CPLUS_TREE_CODE);
589 if (assign)
590 return assignop_tab[i];
591 else
592 return opname_tab[i];
595 int lineno; /* current line number in file being read */
597 FILE *finput; /* input file.
598 Normally a pipe from the preprocessor. */
599 static FILE *finput1; /* Real input files: 1 is main input file */
600 static FILE *finput2; /* 2 is input file for inline functions */
602 int interface_only; /* whether or not current file is only for
603 interface definitions. */
604 int interface_unknown; /* whether or not we know this class
605 to behave according to #pragma interface. */
607 /* lexical analyzer */
609 static int maxtoken; /* Current nominal length of token buffer. */
610 char *token_buffer; /* Pointer to token buffer.
611 Actual allocated length is maxtoken + 2. */
612 static int max_wide; /* Current nominal length of wide_buffer. */
613 static int *wide_buffer; /* Pointer to wide-string buffer.
614 Actual allocated length is max_wide + 1. */
616 #define NORID RID_UNUSED
618 /* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$ gplus.gperf */
619 struct resword { char *name; short token; enum rid rid;};
621 #define MIN_WORD_LENGTH 2
622 #define MAX_WORD_LENGTH 13
623 #define MIN_HASH_VALUE 4
624 #define MAX_HASH_VALUE 147
626 71 keywords
627 144 is the maximum key range
630 #ifdef __GNUC__
631 inline
632 #endif
633 static int
634 hash (str, len)
635 register char *str;
636 register int unsigned len;
638 static unsigned char hash_table[] =
640 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
641 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
642 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
643 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
644 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
645 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
646 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
647 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
648 147, 147, 147, 147, 147, 147, 147, 147, 147, 147,
649 147, 147, 147, 147, 147, 0, 147, 19, 6, 27,
650 37, 0, 12, 1, 15, 63, 147, 4, 0, 56,
651 20, 15, 42, 147, 31, 5, 26, 39, 32, 10,
652 147, 40, 147, 147, 147, 147, 147, 147,
654 register int hval = len ;
656 switch (hval)
658 default:
659 case 4:
660 hval += hash_table[str[3]];
661 case 3:
662 case 2:
663 case 1:
664 hval += hash_table[str[0]];
666 return hval + hash_table[str[len - 1]] ;
669 #ifdef __GNUC__
670 inline
671 #endif
672 struct resword *
673 is_reserved_word (str, len)
674 register char *str;
675 register unsigned int len;
678 static struct resword wordlist[] =
680 {"",}, {"",}, {"",}, {"",},
681 {"else", ELSE, NORID,},
682 {"",},
683 {"long", TYPESPEC, RID_LONG,},
684 {"",}, {"",}, {"",}, {"",},
685 {"__alignof__", ALIGNOF, NORID},
686 {"__asm__", ASM, NORID},
687 {"",}, {"",},
688 {"while", WHILE, NORID,},
689 {"",}, {"",}, {"",}, {"",}, {"",},
690 {"__alignof", ALIGNOF, NORID},
691 {"all", ALL, NORID /* Extension */,},
692 {"sizeof", SIZEOF, NORID,},
693 {"__const__", TYPE_QUAL, RID_CONST},
694 {"__volatile", TYPE_QUAL, RID_VOLATILE},
695 {"extern", SCSPEC, RID_EXTERN,},
696 {"__volatile__", TYPE_QUAL, RID_VOLATILE},
697 {"__inline", SCSPEC, RID_INLINE},
698 {"exception", AGGR, RID_EXCEPTION /* Extension */,},
699 {"__inline__", SCSPEC, RID_INLINE},
700 {"case", CASE, NORID,},
701 {"except", EXCEPT, NORID /* Extension */,},
702 {"new", NEW, NORID,},
703 {"break", BREAK, NORID,},
704 {"goto", GOTO, NORID,},
705 {"",},
706 {"__attribute", ATTRIBUTE, NORID},
707 {"",},
708 {"__attribute__", ATTRIBUTE, NORID},
709 {"this", THIS, NORID,},
710 {"raise", RAISE, NORID /* Extension */,},
711 {"class", AGGR, RID_CLASS,},
712 {"delete", DELETE, NORID,},
713 {"typeof", TYPEOF, NORID,},
714 {"typedef", SCSPEC, RID_TYPEDEF,},
715 {"for", FOR, NORID,},
716 {"raises", RAISES, NORID /* Extension */,},
717 {"__const", TYPE_QUAL, RID_CONST},
718 {"double", TYPESPEC, RID_DOUBLE,},
719 {"__typeof__", TYPEOF, NORID},
720 {"",},
721 {"switch", SWITCH, NORID,},
722 {"auto", SCSPEC, RID_AUTO,},
723 {"do", DO, NORID,},
724 {"friend", SCSPEC, RID_FRIEND,},
725 {"",},
726 {"reraise", RERAISE, NORID /* Extension */,},
727 {"",},
728 {"volatile", TYPE_QUAL, RID_VOLATILE,},
729 {"__typeof", TYPEOF, NORID},
730 {"continue", CONTINUE, NORID,},
731 {"float", TYPESPEC, RID_FLOAT,},
732 {"const", TYPE_QUAL, RID_CONST,},
733 {"static", SCSPEC, RID_STATIC,},
734 {"virtual", SCSPEC, RID_VIRTUAL,},
735 {"__asm", ASM, NORID},
736 {"short", TYPESPEC, RID_SHORT,},
737 {"signed", TYPESPEC, RID_SIGNED,},
738 {"try", TRY, NORID /* Extension */,},
739 {"",}, {"",}, {"",},
740 {"__signed__", TYPESPEC, RID_SIGNED},
741 {"catch", CATCH, NORID,},
742 {"public", PUBLIC, NORID,},
743 {"struct", AGGR, RID_RECORD,},
744 {"if", IF, NORID,},
745 {"asm", ASM, NORID,},
746 {"union", AGGR, RID_UNION,},
747 {"",},
748 {"private", PRIVATE, NORID,},
749 {"",}, {"",}, {"",},
750 {"operator", OPERATOR, NORID,},
751 {"",}, {"",}, {"",},
752 {"default", DEFAULT, NORID,},
753 {"dynamic", DYNAMIC, NORID,},
754 {"overload", OVERLOAD, NORID,},
755 {"int", TYPESPEC, RID_INT,},
756 {"char", TYPESPEC, RID_CHAR,},
757 {"",}, {"",},
758 {"return", RETURN, NORID,},
759 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
760 {"",}, {"",},
761 {"__signed", TYPESPEC, RID_SIGNED},
762 {"",},
763 {"void", TYPESPEC, RID_VOID,},
764 {"",}, {"",}, {"",},
765 {"protected", PROTECTED, NORID,},
766 {"",},
767 {"enum", ENUM, NORID,},
768 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
769 {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
770 {"inline", SCSPEC, RID_INLINE,},
771 {"register", SCSPEC, RID_REGISTER,},
772 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
773 {"",}, {"",}, {"",}, {"",},
774 {"unsigned", TYPESPEC, RID_UNSIGNED,},
777 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
779 register int key = hash (str, len);
781 if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)
783 register char *s = wordlist[key].name;
785 if (*s == *str && !strcmp (str + 1, s + 1))
786 return &wordlist[key];
789 return 0;
792 /* The elements of `ridpointers' are identifier nodes
793 for the reserved type names and storage classes.
794 It is indexed by a RID_... value. */
796 tree ridpointers[(int) RID_MAX];
798 int check_newline ();
800 static int skip_white_space ();
802 static tree
803 get_time_identifier (name)
804 char *name;
806 tree time_identifier;
807 int len = strlen (name);
808 char *buf = (char *)alloca (len + 6);
809 strcpy (buf, "file ");
810 bcopy (name, buf+5, len);
811 buf[len+5] = '\0';
812 time_identifier = get_identifier (buf);
813 if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
815 int temp = allocation_temporary_p ();
816 if (temp)
817 end_temporary_allocation ();
818 IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
819 IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
820 IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times;
821 filename_times = time_identifier;
822 if (temp)
823 resume_temporary_allocation ();
825 return time_identifier;
828 #ifdef __GNUC__
829 __inline
830 #endif
831 static int
832 my_gettime ()
834 int old_quiet_flag = quiet_flag;
835 int this_time;
836 quiet_flag = 0;
837 this_time = gettime ();
838 quiet_flag = old_quiet_flag;
839 return this_time;
842 /* Table indexed by tree code giving a string containing a character
843 classifying the tree code. Possibilities are
844 t, d, s, c, r and e. See cplus-tree.def for details. */
846 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
848 char *cplus_tree_code_type[] = {
849 "x",
850 #include "cplus-tree.def"
852 #undef DEFTREECODE
854 /* Table indexed by tree code giving number of expression
855 operands beyond the fixed part of the node structure.
856 Not used for types or decls. */
858 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
860 int cplus_tree_code_length[] = {
862 #include "cplus-tree.def"
864 #undef DEFTREECODE
866 /* Names of tree components.
867 Used for printing out the tree and error messages. */
868 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
870 char *cplus_tree_code_name[] = {
871 "@@dummy",
872 #include "cplus-tree.def"
874 #undef DEFTREECODE
876 void
877 init_filename_times ()
879 this_filename_time = get_time_identifier ("<top level>");
880 if (flag_detailed_statistics)
882 header_time = 0;
883 body_time = my_gettime ();
884 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time;
888 /* Use 4.4 BSD fropen() stdio function to fake re-reads of inline functions.
889 We just decrement the buffer count until it reaches zero. */
891 static unsigned next_inline_count = 0;
893 static int
894 read_next_inline(unused_cookie, unused_buf, count)
895 void *unused_cookie;
896 char *unused_buf;
897 unsigned count;
899 count = count > next_inline_count ? next_inline_count : count;
900 next_inline_count -= count;
901 return count;
904 /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
905 Stuck this hack in to get the files open correctly; this is called
906 in place of init_lex if we are an unexec'd binary. */
907 void
908 reinit_lex_for_unexec ()
910 finput1 = finput;
911 finput2 = fropen ((void *) 0, read_next_inline);
912 init_filename_times ();
915 void
916 init_lex ()
918 extern int *init_parse ();
919 extern char *(*decl_printable_name) ();
920 extern char *lang_printable_name ();
921 extern struct rtx_def *(*lang_expand_expr) ();
922 extern struct rtx_def *cplus_expand_expr ();
924 int i;
926 /* Make identifier nodes long enough for the language-specific slots. */
927 set_identifier_size (sizeof (struct lang_identifier));
928 decl_printable_name = lang_printable_name;
929 lang_expand_expr = cplus_expand_expr;
931 tree_code_type
932 = (char **) realloc (tree_code_type,
933 sizeof (char *) * LAST_CPLUS_TREE_CODE);
934 tree_code_length
935 = (int *) realloc (tree_code_length,
936 sizeof (int) * LAST_CPLUS_TREE_CODE);
937 tree_code_name
938 = (char **) realloc (tree_code_name,
939 sizeof (char *) * LAST_CPLUS_TREE_CODE);
940 bcopy (cplus_tree_code_type,
941 tree_code_type + LAST_AND_UNUSED_TREE_CODE,
942 (LAST_CPLUS_TREE_CODE - LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
943 bcopy (cplus_tree_code_length,
944 tree_code_length + LAST_AND_UNUSED_TREE_CODE,
945 (LAST_CPLUS_TREE_CODE - LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
946 bcopy (cplus_tree_code_name,
947 tree_code_name + LAST_AND_UNUSED_TREE_CODE,
948 (LAST_CPLUS_TREE_CODE - LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
950 node_table = (tree *)oballoc (LAST_CPLUS_TREE_CODE * sizeof (tree));
951 opname_tab = (char **)oballoc (LAST_CPLUS_TREE_CODE * sizeof (char *));
952 assignop_tab = (char **)oballoc (LAST_CPLUS_TREE_CODE * sizeof (char *));
954 for (i = 0; i < LAST_CPLUS_TREE_CODE; i++)
955 /* Our only interest is _ref and _expr. */
956 if (tree_code_type[i][0] == 'r' || tree_code_type[i][0] == 'e')
958 char *end = (char *)strrchr (tree_code_name[i], '_');
959 if (end)
960 opname_end[i] = end - tree_code_name[i];
961 #ifndef __GNUC__
962 else
963 opname_end[i] = strlen (tree_code_name[i]);
964 #endif
966 #ifndef __GNUC__
967 else
968 opname_end[i] = strlen (tree_code_name[i]);
969 #endif
971 init_method ();
972 obstack_init (&inline_text_obstack);
973 inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
975 /* Start it at 0, because check_newline is called at the very beginning
976 and will increment it to 1. */
977 lineno = 0;
978 finput1 = finput;
979 finput2 = fropen ((void *) 0, read_next_inline);
980 current_function_decl = NULL;
982 maxtoken = 40;
983 token_buffer = (char *) xmalloc (maxtoken + 2);
984 max_wide = 40;
985 wide_buffer = (int *) xmalloc (max_wide + 1);
987 ridpointers[(int) RID_INT] = get_identifier ("int");
988 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
989 build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
990 ridpointers[(int) RID_CHAR] = get_identifier ("char");
991 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
992 build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
993 ridpointers[(int) RID_VOID] = get_identifier ("void");
994 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID],
995 build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]));
996 ridpointers[(int) RID_FLOAT] = get_identifier ("float");
997 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT],
998 build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT]));
999 ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
1000 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE],
1001 build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE]));
1002 ridpointers[(int) RID_SHORT] = get_identifier ("short");
1003 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT],
1004 build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT]));
1005 ridpointers[(int) RID_LONG] = get_identifier ("long");
1006 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG],
1007 build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]));
1008 ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
1009 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED],
1010 build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]));
1011 ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
1012 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED],
1013 build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED]));
1014 ridpointers[(int) RID_INLINE] = get_identifier ("inline");
1015 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE],
1016 build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE]));
1017 ridpointers[(int) RID_CONST] = get_identifier ("const");
1018 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST],
1019 build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST]));
1020 ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
1021 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
1022 build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
1023 ridpointers[(int) RID_AUTO] = get_identifier ("auto");
1024 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
1025 build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
1026 ridpointers[(int) RID_STATIC] = get_identifier ("static");
1027 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC],
1028 build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]));
1029 ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
1030 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN],
1031 build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]));
1032 ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
1033 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF],
1034 build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF]));
1035 ridpointers[(int) RID_REGISTER] = get_identifier ("register");
1036 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
1037 build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
1039 /* C++ extensions. These are probably not correctly named. */
1040 class_type_node = build_int_2 (class_type, 0);
1041 TREE_TYPE (class_type_node) = class_type_node;
1042 ridpointers[(int) RID_CLASS] = class_type_node;
1044 record_type_node = build_int_2 (record_type, 0);
1045 TREE_TYPE (record_type_node) = record_type_node;
1046 ridpointers[(int) RID_RECORD] = record_type_node;
1048 union_type_node = build_int_2 (union_type, 0);
1049 TREE_TYPE (union_type_node) = union_type_node;
1050 ridpointers[(int) RID_UNION] = union_type_node;
1052 enum_type_node = build_int_2 (enum_type, 0);
1053 TREE_TYPE (enum_type_node) = enum_type_node;
1054 ridpointers[(int) RID_ENUM] = enum_type_node;
1056 ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
1057 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
1058 build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
1059 ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
1060 SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
1061 build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
1063 /* Exception handling extensions. */
1064 exception_type_node = build_int_2 (exception_type, 0);
1065 TREE_TYPE (exception_type_node) = exception_type_node;
1066 ridpointers[(int) RID_EXCEPTION] = exception_type_node;
1068 opname_tab[(int) COMPONENT_REF] = "->";
1069 opname_tab[(int) METHOD_CALL_EXPR] = "->()";
1070 opname_tab[(int) INDIRECT_REF] = "(unary *)";
1071 opname_tab[(int) ARRAY_REF] = "[]";
1072 opname_tab[(int) MODIFY_EXPR] = "=";
1073 opname_tab[(int) NEW_EXPR] = "new";
1074 opname_tab[(int) DELETE_EXPR] = "delete";
1075 opname_tab[(int) COND_EXPR] = "... ? ... : ...";
1076 opname_tab[(int) CALL_EXPR] = "()";
1077 opname_tab[(int) PLUS_EXPR] = "+";
1078 opname_tab[(int) MINUS_EXPR] = "-";
1079 opname_tab[(int) MULT_EXPR] = "*";
1080 opname_tab[(int) TRUNC_DIV_EXPR] = "/";
1081 opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
1082 opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
1083 opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
1084 opname_tab[(int) TRUNC_MOD_EXPR] = "%";
1085 opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
1086 opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
1087 opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
1088 opname_tab[(int) NEGATE_EXPR] = "-";
1089 opname_tab[(int) MIN_EXPR] = "<?";
1090 opname_tab[(int) MAX_EXPR] = ">?";
1091 opname_tab[(int) ABS_EXPR] = "abs";
1092 opname_tab[(int) FFS_EXPR] = "ffs";
1093 opname_tab[(int) LSHIFT_EXPR] = "<<";
1094 opname_tab[(int) RSHIFT_EXPR] = ">>";
1095 opname_tab[(int) BIT_IOR_EXPR] = "|";
1096 opname_tab[(int) BIT_XOR_EXPR] = "^";
1097 opname_tab[(int) BIT_AND_EXPR] = "&";
1098 opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
1099 opname_tab[(int) BIT_NOT_EXPR] = "~";
1100 opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
1101 opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
1102 opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
1103 opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
1104 opname_tab[(int) TRUTH_NOT_EXPR] = "!";
1105 opname_tab[(int) LT_EXPR] = "<";
1106 opname_tab[(int) LE_EXPR] = "<=";
1107 opname_tab[(int) GT_EXPR] = ">";
1108 opname_tab[(int) GE_EXPR] = ">=";
1109 opname_tab[(int) EQ_EXPR] = "==";
1110 opname_tab[(int) NE_EXPR] = "!=";
1111 opname_tab[(int) IN_EXPR] = "in";
1112 opname_tab[(int) SET_LE_EXPR] = "subset";
1113 opname_tab[(int) CARD_EXPR] = "#";
1114 opname_tab[(int) RANGE_EXPR] = "..";
1115 opname_tab[(int) CONVERT_EXPR] = "(unary +)";
1116 opname_tab[(int) ADDR_EXPR] = "(unary &)";
1117 opname_tab[(int) PREDECREMENT_EXPR] = "--";
1118 opname_tab[(int) PREINCREMENT_EXPR] = "++";
1119 opname_tab[(int) POSTDECREMENT_EXPR] = "--";
1120 opname_tab[(int) POSTINCREMENT_EXPR] = "++";
1121 opname_tab[(int) COMPOUND_EXPR] = ",";
1122 assignop_tab[(int) NOP_EXPR] = "=";
1123 assignop_tab[(int) PLUS_EXPR] = "+=";
1124 assignop_tab[(int) MINUS_EXPR] = "-=";
1125 assignop_tab[(int) MULT_EXPR] = "*=";
1126 assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
1127 assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
1128 assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
1129 assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
1130 assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
1131 assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
1132 assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
1133 assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
1134 assignop_tab[(int) MIN_EXPR] = "<?=";
1135 assignop_tab[(int) MAX_EXPR] = ">?=";
1136 assignop_tab[(int) LSHIFT_EXPR] = "<<=";
1137 assignop_tab[(int) RSHIFT_EXPR] = ">>=";
1138 assignop_tab[(int) BIT_IOR_EXPR] = "|=";
1139 assignop_tab[(int) BIT_XOR_EXPR] = "^=";
1140 assignop_tab[(int) BIT_AND_EXPR] = "&=";
1142 init_filename_times ();
1144 #define UNSET_RESERVED_WORD(STRING) \
1145 do { is_reserved_word (STRING, sizeof (STRING) - 1)->name = ""; } while (0)
1147 if (! flag_handle_exceptions)
1149 /* Easiest way to not reconize exception
1150 handling extenions... */
1151 UNSET_RESERVED_WORD ("all");
1152 UNSET_RESERVED_WORD ("except");
1153 UNSET_RESERVED_WORD ("exception");
1154 UNSET_RESERVED_WORD ("raise");
1155 UNSET_RESERVED_WORD ("raises");
1156 UNSET_RESERVED_WORD ("reraise");
1157 UNSET_RESERVED_WORD ("try");
1159 if (flag_no_asm)
1160 UNSET_RESERVED_WORD ("asm");
1161 if (flag_no_asm || flag_traditional)
1162 UNSET_RESERVED_WORD ("typeof");
1163 token_count = init_parse ();
1164 interface_unknown = 1;
1167 void
1168 reinit_parse_for_function ()
1170 current_base_init_list = NULL_TREE;
1171 current_member_init_list = NULL_TREE;
1174 /* Functions and data structures for #pragma interface.
1176 `#pragma implementation' means that the main file being compiled
1177 is considered to implement (provide) the classes that appear in
1178 its main body. I.e., if this is file "foo.cc", and class `bar'
1179 is defined in "foo.cc", then we say that "foo.cc implements bar".
1181 All main input files "implement" themselves automagically.
1183 `#pragma interface' means that unless this file (of the form "foo.h"
1184 is not presently being included by file "foo.cc", the
1185 CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none
1186 of the vtables nor any of the inline functions defined in foo.h
1187 will every be output.
1189 There are cases when we want to link files such as "defs.h" and
1190 "main.cc". In this case, we give "defs.h" a `#pragma interface',
1191 and "main.cc" has `#pragma implementation "defs.h"'. */
1193 struct impl_files
1195 char *filename;
1196 struct impl_files *next;
1199 static struct impl_files *impl_file_chain;
1201 /* Helper function to load global variables with interface
1202 information. */
1203 static void
1204 extract_interface_info ()
1206 tree fileinfo = get_time_identifier (input_filename);
1207 fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
1208 interface_only = TREE_INT_CST_LOW (fileinfo);
1209 interface_unknown = TREE_INT_CST_HIGH (fileinfo);
1212 /* Return nonzero if S and T are not considered part of an
1213 INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */
1214 static int
1215 interface_strcmp (s)
1216 char *s;
1218 /* Set the interface/implementation bits for this scope. */
1219 struct impl_files *ifiles;
1220 char *s1 = strrchr (s, '/');
1221 if (s1++ == 0)
1222 s1 = s;
1223 s = s1;
1225 for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
1227 char *t1 = ifiles->filename;
1228 s1 = s;
1230 if (*s1 != *t1 || *s1 == 0)
1231 continue;
1233 while (*s1 == *t1 && *s1 != 0)
1234 s1++, t1++;
1236 /* A match. */
1237 if (*s1 == *t1)
1238 return 0;
1240 /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */
1241 if (strchr (s1, '.'))
1242 continue;
1244 if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
1245 continue;
1247 /* A match. */
1248 return 0;
1251 /* No matches. */
1252 return 1;
1255 void
1256 set_typedecl_interface_info (prev, vars)
1257 tree prev, vars;
1259 tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
1260 tree fileinfo = IDENTIFIER_CLASS_VALUE (id);
1261 tree type = TREE_TYPE (vars);
1263 CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
1264 = interface_strcmp (DECL_SOURCE_FILE (vars));
1267 void
1268 set_vardecl_interface_info (prev, vars)
1269 tree prev, vars;
1271 #if 0
1272 tree type = DECL_VPARENT (vars);
1273 #else
1274 tree type = DECL_CONTEXT (vars);
1275 #endif
1277 if (CLASSTYPE_INTERFACE_UNKNOWN (type) == 0)
1279 if (CLASSTYPE_INTERFACE_ONLY (type))
1280 set_typedecl_interface_info (prev, TYPE_NAME (type));
1281 TREE_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
1282 TREE_PUBLIC (vars) = ! CLASSTYPE_INTERFACE_ONLY (type);
1283 CLASSTYPE_VTABLE_NEEDS_WRITING (type) |= TREE_PUBLIC (vars);
1287 /* Called from the top level: if there are any pending inlines to
1288 do, set up to process them now. */
1289 void
1290 do_pending_inlines ()
1292 if (finput == finput1)
1294 struct pending_inline *prev = 0, *tail;
1295 struct pending_inline *t =
1296 (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1297 sizeof (struct pending_inline));
1299 /* Record state we were in when we decided to process
1300 inline functions instead. */
1301 t->next = pending_inlines;
1302 pending_inlines = t;
1303 t->lineno = lineno;
1304 t->filename = input_filename;
1305 t->fndecl = NULL_TREE;
1306 t->token = yychar;
1307 t->token_value = yylval.itype;
1309 /* Reverse the pending inline functions, since
1310 they were cons'd instead of appended. */
1312 for (; t; t = tail)
1314 tail = t->next;
1315 t->next = prev;
1316 prev = t;
1318 pending_inlines = prev;
1320 /* Now start processing the first inline function. */
1321 t = pending_inlines;
1322 pending_inlines = pending_inlines->next;
1324 finput = finput2;
1325 clearerr(finput2);
1326 setvbuf (finput2, t->buf, _IOFBF, t->len - 1);
1327 next_inline_count = t->len - 1;
1329 lineno = t->lineno;
1330 input_filename = t->filename;
1331 yychar = PRE_PARSED_FUNCTION_DECL;
1332 yylval.ttype = t->fndecl;
1333 if (flag_default_inline)
1334 TREE_INLINE (t->fndecl) = 1;
1338 /* Since inline methods can refer to text which has not yet been seen,
1339 we store the text of the method in a structure which is placed in the
1340 DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.
1341 After parsing the body of the class definition, the FUNCTION_DECL's are
1342 scanned to see which ones have this field set. Those are then digested
1343 one at a time.
1345 This function's FUNCTION_DECL will have a bit set in its common so
1346 that we know to watch out for it. */
1348 void
1349 consume_string (this_obstack)
1350 register struct obstack *this_obstack;
1352 register char c;
1355 c = getc (finput);
1356 if (c == '\\')
1358 obstack_1grow (this_obstack, c);
1359 c = getch ();
1360 obstack_1grow (this_obstack, c);
1361 continue;
1363 if (c == '\n')
1365 if (pedantic)
1366 warning ("ANSI C forbids newline in string constant");
1367 lineno++;
1369 obstack_1grow (this_obstack, c);
1371 while (c != '\"');
1374 static int nextchar = -1;
1375 static int nextyychar = -1;
1376 static YYSTYPE nextyylval;
1377 static tree nextlastiddecl;
1379 /* Get input from stream. When compiling under Cadillac,
1380 the bytes must be coaxed out via their read protocol.
1381 Otherwise, they come easily via standard input interface. */
1383 getch ()
1385 register int ch = getc (finput);
1386 return ch;
1389 /* Return next non-whitespace input character, which may come
1390 from `finput', or from `nextchar'. */
1391 static int
1392 yynextch ()
1394 int c;
1396 if (nextchar >= 0)
1398 c = nextchar;
1399 nextchar = -1;
1401 else c = getc (finput);
1402 return skip_white_space (c);
1405 /* Unget character CH from the input stream.
1406 If RESCAN is non-zero, then we want to `see' this
1407 character as the next input token. */
1408 void
1409 yyungetc (ch, rescan)
1410 int ch;
1411 int rescan;
1413 /* Unget a characater from the input stream. */
1414 if (yychar == YYEMPTY || rescan == 0)
1415 ungetc (ch, finput);
1416 else
1418 if (nextyychar >= 0)
1419 abort ();
1420 nextyychar = yychar;
1421 nextyylval = yylval;
1422 yychar = ch;
1426 void
1427 reinit_parse_for_method (yychar, decl)
1428 int yychar;
1429 tree decl;
1431 register char c = 0;
1432 int blev = 1;
1433 tree fndecl = decl;
1434 int starting_lineno = lineno;
1435 char *starting_filename = input_filename;
1436 int len;
1438 if (yychar != '{')
1440 if (yychar != ':' && yychar != RETURN)
1442 yyerror ("parse error in method specification");
1443 yychar = '{';
1445 obstack_1grow (&inline_text_obstack, yychar);
1446 while (c >= 0)
1448 int this_lineno = lineno;
1450 c = yynextch ();
1452 /* Don't lose our cool if there are lots of comments. */
1453 if (lineno - this_lineno)
1454 if (lineno - this_lineno == 1)
1455 obstack_1grow (&inline_text_obstack, '\n');
1456 else
1458 char buf[12];
1459 sprintf (buf, "\n# %d \"", lineno);
1460 len = strlen (buf);
1461 obstack_grow (&inline_text_obstack, buf, len);
1463 len = strlen (input_filename);
1464 obstack_grow (&inline_text_obstack, input_filename, len);
1465 obstack_1grow (&inline_text_obstack, '\"');
1466 obstack_1grow (&inline_text_obstack, '\n');
1469 /* strings must be read differently than text. */
1470 if (c == '\"')
1472 obstack_1grow (&inline_text_obstack, c);
1473 consume_string (&inline_text_obstack);
1474 c = yynextch ();
1476 while (c > ' ') /* ASCII dependent! */
1478 obstack_1grow (&inline_text_obstack, c);
1479 if (c == '{') goto main_loop;
1480 if (c == '\"')
1481 consume_string (&inline_text_obstack);
1482 if (c == ';')
1484 error ("function body for constructor missing");
1485 obstack_1grow (&inline_text_obstack, '{');
1486 obstack_1grow (&inline_text_obstack, '}');
1487 len += 2;
1488 goto done;
1490 c = getch ();
1492 if (c == '\n')
1493 lineno++;
1494 obstack_1grow (&inline_text_obstack, c);
1496 if (c == EOF)
1498 error_with_file_and_line (starting_filename,
1499 starting_lineno,
1500 "parse error in method specification");
1503 else obstack_1grow (&inline_text_obstack, '{');
1505 main_loop:
1506 while (c >= 0)
1508 int this_lineno = lineno;
1510 c = skip_white_space (getc (finput));
1512 /* Don't lose our cool if there are lots of comments. */
1513 if (lineno - this_lineno)
1514 if (lineno - this_lineno == 1)
1515 obstack_1grow (&inline_text_obstack, '\n');
1516 else
1518 char buf[12];
1519 sprintf (buf, "\n# %d \"", lineno);
1520 len = strlen (buf);
1521 obstack_grow (&inline_text_obstack, buf, len);
1523 len = strlen (input_filename);
1524 obstack_grow (&inline_text_obstack, input_filename, len);
1525 obstack_1grow (&inline_text_obstack, '\"');
1526 obstack_1grow (&inline_text_obstack, '\n');
1529 while (c > ' ')
1531 obstack_1grow (&inline_text_obstack, c);
1532 if (c == '{') blev++;
1533 else if (c == '}')
1535 blev--;
1536 if (blev == 0)
1537 goto done;
1539 else if (c == '\"')
1540 consume_string (&inline_text_obstack);
1541 c = getch ();
1543 if (c == '\n')
1544 lineno++;
1545 obstack_1grow (&inline_text_obstack, c);
1547 done:
1548 current_base_init_list = NULL_TREE;
1549 current_member_init_list = NULL_TREE;
1551 #ifdef USG_STDIO
1552 len = obstack_object_size (&inline_text_obstack);
1553 /* If the buffer given to setvbuf is shorter than eight bytes long,
1554 setvbuf will (in violation of its man page) ignore the buffer
1555 and call malloc to get a bigger one. */
1556 while (len < 8)
1558 len++;
1559 obstack_1grow (&inline_text_obstack, ' ');
1561 #endif
1563 obstack_1grow (&inline_text_obstack, '\0');
1564 len = obstack_object_size (&inline_text_obstack);
1566 if (fndecl == void_type_node)
1568 /* Happens when we get two declarations of the same
1569 function in the same scope. */
1570 char *buf = obstack_base (&inline_text_obstack);
1571 obstack_free (&inline_text_obstack, buf);
1572 return;
1574 else
1576 struct pending_inline *t;
1577 char *buf = obstack_base (&inline_text_obstack);
1579 obstack_finish (&inline_text_obstack);
1581 t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1582 sizeof (struct pending_inline));
1583 t->buf = buf;
1584 t->len = len;
1585 t->lineno = starting_lineno;
1586 t->filename = starting_filename;
1587 t->token = YYEMPTY;
1588 DECL_PENDING_INLINE_INFO (fndecl) = t;
1592 /* Build a default function named NAME for type TYPE.
1593 KIND says what to build. Currently only two kinds of default functions
1594 are recognized:
1596 When KIND == 0, build default X(X&) constructor.
1597 When KIND == 1, build default destructor. */
1599 tree
1600 cons_up_default_function (type, name, kind)
1601 tree type, name;
1602 int kind;
1604 extern tree void_list_node;
1605 int len;
1606 tree fn, args;
1607 tree argtype;
1609 switch (kind)
1611 case 0:
1612 /* Destructor. */
1613 name = build_parse_node (BIT_NOT_EXPR, name);
1614 /* Fall through... */
1615 case 2:
1616 /* Default constructor. */
1617 args = void_list_node;
1618 break;
1620 case 3:
1621 type = build_type_variant (type, 1, 0);
1622 /* Fall through... */
1623 case 1:
1624 argtype = build_reference_type (type);
1625 args = tree_cons (NULL_TREE,
1626 build_tree_list (hash_tree_chain (argtype, NULL_TREE),
1627 get_identifier ("arg")),
1628 void_list_node);
1629 break;
1631 default:
1632 abort ();
1635 fn = start_method (NULL_TREE,
1636 build_parse_node (CALL_EXPR, name, args, NULL_TREE),
1637 NULL_TREE);
1638 if (fn == void_type_node)
1639 return fn;
1641 obstack_1grow (&inline_text_obstack, '{');
1642 obstack_1grow (&inline_text_obstack, '}');
1643 #ifdef USG_STDIO
1644 len = 2;
1645 while (len++ < 8)
1646 obstack_1grow (&inline_text_obstack, ' ');
1647 #endif
1649 obstack_1grow (&inline_text_obstack, '\0');
1650 current_base_init_list = NULL_TREE;
1651 current_member_init_list = NULL_TREE;
1653 len = obstack_object_size (&inline_text_obstack);
1656 struct pending_inline *t;
1657 char *buf = obstack_base (&inline_text_obstack);
1659 obstack_finish (&inline_text_obstack);
1661 t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
1662 sizeof (struct pending_inline));
1663 t->buf = buf;
1664 t->len = len;
1665 t->lineno = lineno;
1666 t->filename = input_filename;
1667 t->token = YYEMPTY;
1668 DECL_PENDING_INLINE_INFO (fn) = t;
1669 /* We make this declaration private (static in the C sense). */
1670 TREE_PUBLIC (fn) = 0;
1672 finish_method (fn);
1673 DECL_COMPILER_GENERATED_P (fn) = 1;
1674 return fn;
1677 /* Heuristic to tell whether the user is missing a semicolon
1678 after a struct or enum declaration. Emit an error message
1679 if we know the user has blown it. */
1680 void
1681 check_for_missing_semicolon (type)
1682 tree type;
1684 if (yychar < 0)
1685 yychar = yylex ();
1687 if (yychar > 255
1688 && yychar != IDENTIFIER
1689 && yychar != TYPENAME)
1691 if (ANON_AGGRNAME_P (DECL_NAME (TYPE_NAME (type))))
1692 error ("semicolon missing after %s declaration",
1693 TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
1694 else
1695 error ("semicolon missing after declaration of `%s'",
1696 TYPE_NAME_STRING (type));
1697 shadow_tag (build_tree_list (0, type));
1699 /* Could probably also hack cases where class { ... } f (); appears. */
1702 void
1703 note_got_semicolon (type)
1704 tree type;
1706 if (IS_AGGR_TYPE (type))
1707 CLASSTYPE_GOT_SEMICOLON (type) = 1;
1710 /* If C is not whitespace, return C.
1711 Otherwise skip whitespace and return first nonwhite char read. */
1713 static int
1714 skip_white_space (c)
1715 register int c;
1717 #if 0
1718 register int inside;
1719 #endif
1721 for (;;)
1723 switch (c)
1725 /* Don't recognize comments in cc1: all comments are removed by cpp,
1726 and cpp output can include / and * consecutively as operators. */
1727 #if 0
1728 case '/':
1729 c = getc (finput);
1730 if (c != '*' && c != '/')
1732 ungetc (c, finput);
1733 return '/';
1736 if (c == '/')
1738 while (c != EOF)
1740 c = getch ();
1741 if (c == '\n')
1743 ungetc (c, finput);
1744 break;
1747 if (c == EOF)
1749 error ("unterminated comment");
1750 return EOF;
1752 c = getch ();
1753 break;
1756 c = getch ();
1758 inside = 1;
1759 while (inside)
1761 if (c == '*')
1763 while (c == '*')
1764 c = getch ();
1766 if (c == '/')
1768 inside = 0;
1769 c = getch ();
1772 else if (c == '\n')
1774 lineno++;
1775 c = getch ();
1777 else if (c == EOF)
1779 error ("unterminated comment");
1780 break;
1782 else
1783 c = getch ();
1786 break;
1787 #endif
1789 case '\n':
1790 c = check_newline ();
1791 break;
1793 case ' ':
1794 case '\t':
1795 case '\f':
1796 case '\r':
1797 case '\v':
1798 case '\b':
1800 c = getc (finput);
1801 while (c == ' ' || c == '\t');
1802 break;
1804 case '\\':
1805 c = getch ();
1806 if (c == '\n')
1807 lineno++;
1808 else
1809 error ("stray '\\' in program");
1810 c = getch ();
1811 break;
1813 default:
1814 return (c);
1821 /* Make the token buffer longer, preserving the data in it.
1822 P should point to just beyond the last valid character in the old buffer.
1823 The value we return is a pointer to the new buffer
1824 at a place corresponding to P. */
1826 static char *
1827 extend_token_buffer (p)
1828 char *p;
1830 int offset = p - token_buffer;
1832 maxtoken = maxtoken * 2 + 10;
1833 token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
1835 return token_buffer + offset;
1838 #ifdef HAVE_UNDUMP
1839 #ifndef MERGED
1840 /* This includes code from write_segment, stolen from unexec.c */
1842 void dump_data()
1844 int new;
1845 register caddr_t ptr, end;
1846 register int i, nwrite, ret;
1847 char buf[80];
1848 extern int errno;
1849 char zeros[128];
1851 extern int been_here_before, just_done_unexec, my_edata;
1852 extern char *dump_source_name;
1853 extern char *asm_file_name, previous_asm_file_name[];
1854 char dump_file_name[256]; /* Fixed-sized buffer -- sigh. */
1855 caddr_t end_of_data, end_of_heap;
1856 int data_size, token;
1857 register int c;
1859 bzero (zeros, sizeof zeros);
1861 /* Here we have just seen `#pragma dump '.
1862 The name to dump to, a string constant, may follow. */
1865 c = getch ();
1866 while (c == ' ' || c == '\t');
1868 /* If no argument, default to something like "dumped-cc1plus". */
1869 if (c == '\n')
1871 char *tmp;
1872 strcpy (dump_file_name, "dumped-");
1873 if (tmp = strrchr (dump_source_name, '/'))
1874 dump_source_name = tmp + 1;
1875 strcat (dump_file_name, dump_source_name);
1877 else
1879 ungetc (c, finput);
1880 token = yylex ();
1881 if (token != STRING
1882 || TREE_CODE (yylval.ttype) != STRING_CST)
1884 error ("invalid #pragma dump");
1885 return;
1888 strcpy (dump_file_name, TREE_STRING_POINTER (yylval.ttype));
1891 been_here_before = 1; /* Raise the flag! */
1892 strcpy(previous_asm_file_name, asm_file_name);
1893 printf("\nDumping %s to %s...\n", dump_source_name, dump_file_name);
1895 end_of_heap = (caddr_t)sbrk(0);
1896 end_of_data = (caddr_t)((int)(&my_edata)&~(getpagesize()-1));
1897 data_size = (int)(end_of_heap-end_of_data);
1898 printf("Data size = %d\n", data_size);
1900 new = creat (dump_file_name, 0666);
1902 ptr = end_of_data;
1903 end = end_of_heap;
1905 for (i = 0; ptr < end;)
1907 /* distance to next multiple of 128. */
1908 nwrite = (((int) ptr + 128) & -128) - (int) ptr;
1909 /* But not beyond specified end. */
1910 if (nwrite > end - ptr) nwrite = end - ptr;
1911 ret = write (new, ptr, nwrite);
1912 /* If write gets a page fault, it means we reached
1913 a gap between the old text segment and the old data segment.
1914 This gap has probably been remapped into part of the text segment.
1915 So write zeros for it. */
1916 if (ret == -1 && errno == EFAULT)
1917 write (new, zeros, nwrite);
1918 else if (nwrite != ret)
1920 sprintf (buf,
1921 "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
1922 ptr, new, nwrite, ret, errno);
1923 perror (buf);
1924 return;
1926 i += nwrite;
1927 ptr += nwrite;
1930 close (new);
1932 just_done_unexec = 1; /* Tell toplev not to output ending. */
1934 #endif
1935 #endif
1937 static int
1938 get_last_nonwhite_on_line ()
1940 register int c;
1942 /* Is this the last nonwhite stuff on the line? */
1943 if (nextchar >= 0)
1944 c = nextchar, nextchar = -1;
1945 else
1946 c = getc (finput);
1948 while (c == ' ' || c == '\t')
1949 c = getc (finput);
1950 return c;
1953 /* At the beginning of a line, increment the line number
1954 and process any #-directive on this line.
1955 If the line is a #-directive, read the entire line and return a newline.
1956 Otherwise, return the line's first non-whitespace character. */
1959 check_newline ()
1961 register int c;
1962 register int token;
1964 lineno++;
1966 /* Read first nonwhite char on the line. */
1969 c = getc (finput);
1970 while (c == ' ' || c == '\t');
1972 if (c != '#')
1974 /* If not #, return it so caller will use it. */
1975 return c;
1978 /* Read first nonwhite char after the `#'. */
1981 c = getch ();
1982 while (c == ' ' || c == '\t');
1984 /* If a letter follows, then if the word here is `line', skip
1985 it and ignore it; otherwise, ignore the line, with an error
1986 if the word isn't `pragma'. */
1988 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
1990 if (c == 'p')
1992 if (getch () == 'r'
1993 && getch () == 'a'
1994 && getch () == 'g'
1995 && getch () == 'm'
1996 && getch () == 'a')
1997 /* Change by Bryan Boreham, Kewill, Sun Jul 23 15:53:24 1989.
1998 This whole section added to support dumping of
1999 compilations in the middle. */
2001 /* Read first nonwhite char after the `#pragma'. */
2004 c = getch ();
2005 while (c == ' ' || c == '\t');
2007 #ifndef MERGED
2008 /* See if it is "dump" */
2010 if (c == 'd'
2011 && getch () == 'u'
2012 && getch () == 'm'
2013 && getch () == 'p'
2014 && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2016 #ifndef HAVE_UNDUMP
2017 ; /* Are you crazy? */
2018 #else
2019 ungetc (c, finput);
2020 dump_data();
2021 longjmp (toplevel, 1);
2022 #endif
2024 else
2025 #endif
2026 if (c == 'v'
2027 && getch () == 't'
2028 && getch () == 'a'
2029 && getch () == 'b'
2030 && getch () == 'l'
2031 && getch () == 'e'
2032 && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2034 extern tree pending_vtables;
2036 /* More follows: it must be a string constant (class name). */
2037 token = yylex ();
2038 if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2040 error ("invalid #pragma vtable");
2041 goto skipline;
2043 if (write_virtuals != 2)
2045 warning ("use `+e2' option to enable #pragma vtable");
2046 goto skipline;
2048 pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables);
2049 if (nextchar < 0)
2050 nextchar = getch ();
2051 c = nextchar;
2052 if (c != '\n')
2053 warning ("trailing characters ignored");
2055 else if (c == 'u'
2056 && getch () == 'n'
2057 && getch () == 'i'
2058 && getch () == 't'
2059 && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2061 /* More follows: it must be a string constant (unit name). */
2062 token = yylex ();
2063 if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2065 error ("invalid #pragma unit");
2066 goto skipline;
2068 current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype));
2069 current_unit_language = current_lang_name;
2070 if (nextchar < 0)
2071 nextchar = getch ();
2072 c = nextchar;
2073 if (c != '\n')
2074 warning ("trailing characters ignored");
2076 else if (c == 'i')
2078 tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
2079 c = getch ();
2081 if (c == 'n'
2082 && getch () == 't'
2083 && getch () == 'e'
2084 && getch () == 'r'
2085 && getch () == 'f'
2086 && getch () == 'a'
2087 && getch () == 'c'
2088 && getch () == 'e'
2089 && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2091 /* read to newline. */
2092 while (c != '\n')
2093 c = getch ();
2095 write_virtuals = 3;
2097 if (impl_file_chain == 0)
2099 char *filename;
2100 tree fi;
2102 /* If this is zero at this point, then we are
2103 auto-implementing. */
2104 if (main_input_filename == 0)
2105 main_input_filename = input_filename;
2107 filename = strrchr (main_input_filename, '/');
2108 if (filename++ == 0)
2109 filename = main_input_filename;
2110 fi = get_time_identifier (filename);
2111 fi = IDENTIFIER_CLASS_VALUE (fi);
2112 TREE_INT_CST_LOW (fi) = 0;
2113 TREE_INT_CST_LOW (fi) = 0;
2114 /* Get default. */
2115 impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
2116 impl_file_chain->filename = filename;
2117 impl_file_chain->next = 0;
2120 interface_only = interface_strcmp (input_filename);
2121 interface_unknown = 0;
2122 TREE_INT_CST_LOW (fileinfo) = interface_only;
2123 TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
2125 else if (c == 'm'
2126 && getch () == 'p'
2127 && getch () == 'l'
2128 && getch () == 'e'
2129 && getch () == 'm'
2130 && getch () == 'e'
2131 && getch () == 'n'
2132 && getch () == 't'
2133 && getch () == 'a'
2134 && getch () == 't'
2135 && getch () == 'i'
2136 && getch () == 'o'
2137 && getch () == 'n'
2138 && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
2140 char *main_filename = main_input_filename ? main_input_filename : input_filename;
2141 char *tmp;
2143 while (c == ' ' || c == '\t')
2144 c = getch ();
2145 if (c != '\n')
2147 ungetc (c, finput);
2148 token = yylex ();
2149 if (token != STRING
2150 || TREE_CODE (yylval.ttype) != STRING_CST)
2152 error ("invalid `#pragma implementation'");
2153 goto skipline;
2155 main_filename = TREE_STRING_POINTER (yylval.ttype);
2157 tmp = strrchr (main_filename, '/');
2158 if (tmp++)
2159 main_filename = tmp;
2161 /* read to newline. */
2162 while (c != '\n')
2163 c = getch ();
2165 if (write_virtuals == 3)
2167 struct impl_files *ifiles = impl_file_chain;
2168 while (ifiles)
2170 if (! strcmp (ifiles->filename, main_filename))
2171 break;
2172 ifiles = ifiles->next;
2174 if (ifiles == 0)
2176 ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
2177 ifiles->filename = main_filename;
2178 ifiles->next = impl_file_chain;
2179 impl_file_chain = ifiles;
2182 else if (main_input_filename == input_filename
2183 || ! strcmp (input_filename, main_filename))
2185 write_virtuals = 3;
2186 if (impl_file_chain == 0)
2188 impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
2189 impl_file_chain->filename = main_filename;
2190 impl_file_chain->next = 0;
2193 else
2194 error ("`#pragma implementation' can only appear at top-level");
2195 interface_only = 0;
2196 interface_unknown = 0;
2197 TREE_INT_CST_LOW (fileinfo) = interface_only;
2198 TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
2202 goto skipline;
2205 else if (c == 'l')
2207 if (getch () == 'i'
2208 && getch () == 'n'
2209 && getch () == 'e'
2210 && ((c = getch ()) == ' ' || c == '\t'))
2211 goto linenum;
2213 else if (c == 'i')
2215 if (getch () == 'd'
2216 && getch () == 'e'
2217 && getch () == 'n'
2218 && getch () == 't'
2219 && ((c = getch ()) == ' ' || c == '\t'))
2221 /* Conditionally used. */
2222 extern FILE *asm_out_file;
2224 if (pedantic)
2225 error ("ANSI C does not allow #ident");
2227 /* Here we have just seen `#ident '.
2228 A string constant should follow. */
2230 while (c == ' ' || c == '\t')
2231 c = getch ();
2233 /* If no argument, ignore the line. */
2234 if (c == '\n')
2235 return c;
2237 ungetc (c, finput);
2238 token = yylex ();
2239 if (token != STRING
2240 || TREE_CODE (yylval.ttype) != STRING_CST)
2242 error ("invalid #ident");
2243 goto skipline;
2246 #ifdef ASM_OUTPUT_IDENT
2247 ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
2248 #endif
2250 /* Skip the rest of this line. */
2251 goto skipline;
2254 else if (c == 'n')
2256 if (getch () == 'e'
2257 && getch () == 'w'
2258 && getch () == 'w'
2259 && getch () == 'o'
2260 && getch () == 'r'
2261 && getch () == 'l'
2262 && getch () == 'd'
2263 && ((c = getch ()) == ' ' || c == '\t'))
2265 /* Used to test incremental compilation. */
2266 sorry ("#pragma newworld");
2267 goto skipline;
2270 error ("undefined or invalid # directive");
2271 goto skipline;
2274 linenum:
2275 /* Here we have either `#line' or `# <nonletter>'.
2276 In either case, it should be a line number; a digit should follow. */
2278 while (c == ' ' || c == '\t')
2279 c = getch ();
2281 /* If the # is the only nonwhite char on the line,
2282 just ignore it. Check the new newline. */
2283 if (c == '\n')
2284 return c;
2286 /* Something follows the #; read a token. */
2288 ungetc (c, finput);
2289 token = yylex ();
2291 if (token == CONSTANT
2292 && TREE_CODE (yylval.ttype) == INTEGER_CST)
2294 int old_lineno = lineno;
2295 /* subtract one, because it is the following line that
2296 gets the specified number */
2298 int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
2299 c = get_last_nonwhite_on_line ();
2300 if (c == '\n')
2302 /* No more: store the line number and check following line. */
2303 lineno = l;
2304 return c;
2306 ungetc (c, finput);
2308 /* More follows: it must be a string constant (filename). */
2310 token = yylex ();
2311 if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
2313 error ("invalid #line");
2314 goto skipline;
2317 /* Changing files again. This means currently collected time
2318 is charged against header time, and body time starts back
2319 at 0. */
2320 if (flag_detailed_statistics)
2322 int this_time = my_gettime ();
2323 tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
2324 header_time += this_time - body_time;
2325 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
2326 += this_time - body_time;
2327 this_filename_time = time_identifier;
2328 body_time = this_time;
2331 if (flag_cadillac)
2332 cadillac_note_source ();
2334 input_filename
2335 = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
2336 strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
2337 lineno = l;
2338 #ifdef FIELD_XREF
2339 FIELD_xref_file(input_filename);
2340 #endif
2342 if (main_input_filename == 0)
2344 extern int been_here_before;
2345 struct impl_files *ifiles = impl_file_chain;
2347 if (ifiles)
2349 while (ifiles->next)
2350 ifiles = ifiles->next;
2351 ifiles->filename = (char *)strrchr (input_filename, '/');
2352 if (ifiles->filename++ == 0)
2353 ifiles->filename = input_filename;
2356 main_input_filename = input_filename;
2357 if (write_virtuals == 3)
2358 walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
2361 extract_interface_info ();
2363 c = get_last_nonwhite_on_line ();
2364 if (c == '\n')
2366 if (flag_cadillac)
2367 cadillac_switch_source (-1);
2368 return c;
2370 ungetc (c, finput);
2372 token = yylex ();
2374 /* `1' after file name means entering new file.
2375 `2' after file name means just left a file. */
2377 if (token == CONSTANT
2378 && TREE_CODE (yylval.ttype) == INTEGER_CST)
2380 if (TREE_INT_CST_LOW (yylval.ttype) == 1)
2382 struct file_stack *p
2383 = (struct file_stack *) xmalloc (sizeof (struct file_stack));
2384 input_file_stack->line = old_lineno;
2385 p->next = input_file_stack;
2386 p->name = input_filename;
2387 input_file_stack = p;
2388 input_file_stack_tick++;
2390 if (flag_cadillac)
2391 cadillac_push_source ();
2393 else if (input_file_stack->next)
2395 struct file_stack *p = input_file_stack;
2397 if (flag_cadillac)
2398 cadillac_pop_source ();
2400 input_file_stack = p->next;
2401 free (p);
2402 input_file_stack_tick++;
2404 else
2405 error ("#-lines for entering and leaving files don't match");
2407 else if (flag_cadillac)
2408 cadillac_switch_source (-1);
2410 /* If NEXTCHAR is not end of line, we don't care what it is. */
2411 if (nextchar == '\n')
2412 return '\n';
2414 else
2415 error ("invalid #-line");
2417 /* skip the rest of this line. */
2418 skipline:
2419 if (c == '\n')
2420 return c;
2421 while ((c = getch ()) != EOF && c != '\n');
2422 return c;
2425 #if 0
2426 #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0)
2427 #define isdigit(char) (char >= '0' && char <= '9')
2428 #else
2429 #include <ctype.h>
2430 #endif
2432 #define ENDFILE -1 /* token that represents end-of-file */
2434 static int
2435 readescape ()
2437 register int c = getc (finput);
2438 register int count, code;
2439 int firstdig;
2441 switch (c)
2443 case 'x':
2444 code = 0;
2445 count = 0;
2446 while (1)
2448 c = getch ();
2449 if (! isxdigit (c))
2451 ungetc (c, finput);
2452 break;
2454 code *= 16;
2455 if (c >= 'a' && c <= 'f')
2456 code += c - 'a' + 10;
2457 if (c >= 'A' && c <= 'F')
2458 code += c - 'A' + 10;
2459 if (c >= '0' && c <= '9')
2460 code += c - '0';
2461 if (count == 0)
2462 firstdig = code;
2463 count++;
2465 if (count == 0)
2466 error ("\\x used with no following hex digits");
2467 else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
2468 || ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
2469 <= firstdig))
2470 warning ("hex escape out of range");
2471 return code;
2473 case '0': case '1': case '2': case '3': case '4':
2474 case '5': case '6': case '7':
2475 code = 0;
2476 count = 0;
2477 while ((c <= '7') && (c >= '0') && (count++ < 3))
2479 code = (code * 8) + (c - '0');
2480 c = getch ();
2482 ungetc (c, finput);
2483 return code;
2485 case '\\': case '\'': case '"':
2486 return c;
2488 case '\n':
2489 lineno++;
2490 return -1;
2492 case 'n':
2493 return TARGET_NEWLINE;
2495 case 't':
2496 return TARGET_TAB;
2498 case 'r':
2499 return TARGET_CR;
2501 case 'f':
2502 return TARGET_FF;
2504 case 'b':
2505 return TARGET_BS;
2507 case 'a':
2508 return TARGET_BELL;
2510 case 'v':
2511 return TARGET_VT;
2513 case 'E':
2514 return 033;
2516 case '?':
2517 /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */
2518 case '(':
2519 case '{':
2520 case '[':
2521 return c;
2523 if (c >= 040 && c <= 0177)
2524 warning ("unknown escape sequence `\\%c'", c);
2525 else
2526 warning ("unknown escape sequence: `\\' followed by char code 0x%x", c);
2527 return c;
2530 /* Value is 1 if we should try to make the next identifier look like a
2531 typename (when it may be a local variable or a class variable).
2532 Value is 0 if we treat this name in a default fashion.
2533 Value is -1 if we must not see a type name. */
2534 int looking_for_typename = 0;
2536 void
2537 dont_see_typename ()
2539 looking_for_typename = -1;
2540 if (yychar == TYPENAME)
2542 yychar = IDENTIFIER;
2543 lastiddecl = 0;
2547 void
2548 see_typename ()
2550 looking_for_typename = 0;
2551 if (yychar == IDENTIFIER)
2553 lastiddecl = lookup_name (yylval.ttype);
2554 if (lastiddecl == 0 && flag_labels_ok)
2555 lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
2556 else if (lastiddecl != 0
2557 && TREE_CODE (lastiddecl) == TYPE_DECL)
2558 yychar = TYPENAME;
2562 tree do_identifier (token)
2563 register tree token;
2565 register tree id = lastiddecl;
2567 if (yychar == YYEMPTY)
2568 yychar = yylex ();
2569 /* Scope class declarations before global
2570 declarations. */
2571 if (id == IDENTIFIER_GLOBAL_VALUE (token)
2572 && current_class_type != 0
2573 && TYPE_SIZE (current_class_type) == 0)
2575 /* Could be from one of the base classes. */
2576 tree field = lookup_field (current_class_type, token, 1);
2577 if (field == 0)
2579 else if (field == error_mark_node)
2580 /* We have already generated the error message.
2581 But we still want to return this value. */
2582 id = lookup_field (current_class_type, token, 0);
2583 else if (TREE_CODE (field) == VAR_DECL
2584 || TREE_CODE (field) == CONST_DECL)
2585 id = field;
2586 else if (TREE_CODE (field) != FIELD_DECL)
2587 abort ();
2588 else
2590 error_with_decl (field, "invalid use of member `%s' from base class `%s'",
2591 TYPE_NAME_STRING (DECL_FIELD_CONTEXT (field)));
2592 id = error_mark_node;
2593 return id;
2597 if (!id || id == error_mark_node)
2599 if (yychar == '(' || yychar == LEFT_RIGHT)
2601 id = implicitly_declare (token);
2602 assemble_external (id);
2603 TREE_USED (id) = 1;
2605 else if (current_function_decl == 0)
2607 error ("`%s' undeclared, outside of functions",
2608 IDENTIFIER_POINTER (token));
2609 id = error_mark_node;
2611 else
2613 if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node
2614 || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
2616 extern int undeclared_variable_notice;
2618 error ("`%s' undeclared (first use this function)",
2619 IDENTIFIER_POINTER (token));
2621 if (! undeclared_variable_notice)
2623 error ("(Each undeclared identifier is reported only once");
2624 error ("for each function it appears in.)");
2625 undeclared_variable_notice = 1;
2628 id = error_mark_node;
2629 /* Prevent repeated error messages. */
2630 IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
2631 SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
2634 /* TREE_USED is set in `hack_identifier'. */
2635 if (TREE_CODE (id) == CONST_DECL)
2637 if (IDENTIFIER_CLASS_VALUE (token) == id)
2639 /* Check visibility. */
2640 enum visibility_type visibility
2641 = compute_visibility (CLASSTYPE_AS_LIST (current_class_type), id);
2642 if (visibility == visibility_private)
2643 error_with_decl (id, "enum `%s' is private");
2644 /* protected is OK, since it's an enum of `this'. */
2646 id = DECL_INITIAL (id);
2648 else id = hack_identifier (id, token, yychar);
2649 return id;
2653 yylex ()
2655 tree tmp;
2656 register int c;
2657 register int value;
2658 int wide_flag = 0;
2659 int dollar_seen = 0;
2661 relex:
2662 if (nextyychar >= 0)
2664 value = nextyychar;
2665 yylval = nextyylval;
2666 lastiddecl = nextlastiddecl;
2667 nextyychar = -1;
2668 if (value == IDENTIFIER)
2670 tmp = yylval.ttype;
2671 goto resume_identifier_processing;
2673 goto done;
2675 if (nextchar >= 0)
2676 c = nextchar, nextchar = -1;
2677 else
2678 c = getc (finput);
2680 /* Effectively do c = skip_white_space (c)
2681 but do it faster in the usual cases. */
2682 while (1)
2683 switch (c)
2685 case ' ':
2686 case '\t':
2687 case '\f':
2688 case '\r':
2689 case '\v':
2690 case '\b':
2691 c = getc (finput);
2692 break;
2694 case '\n':
2695 case '/':
2696 case '\\':
2697 c = skip_white_space (c);
2698 default:
2699 goto found_nonwhite;
2701 found_nonwhite:
2703 token_buffer[0] = c;
2704 token_buffer[1] = 0;
2706 /* yylloc.first_line = lineno; */
2708 switch (c)
2710 case EOF:
2711 token_buffer[0] = '\0';
2712 if (pending_inlines)
2714 struct pending_inline *t;
2716 t = pending_inlines;
2717 #ifdef DO_METHODS_THE_OLD_WAY
2718 yylval.itype = t->token_value;
2719 value = t->token;
2720 #else
2721 if (t->fndecl == 0)
2723 yylval.itype = t->token_value;
2724 value = t->token;
2726 else
2728 yylval.ttype = t->fndecl;
2729 value = PRE_PARSED_FUNCTION_DECL;
2731 #endif
2733 lineno = t->lineno;
2734 /* yylloc.first_line = lineno; */
2735 input_filename = t->filename;
2737 if (t->next)
2739 /* The buffer we used will be freed at the
2740 end of this function. */
2741 pending_inlines = pending_inlines->next;
2742 clearerr(finput2);
2743 setvbuf (finput2, t->buf, _IOFBF, t->len - 1);
2744 next_inline_count = t->len - 1;
2746 else
2748 pending_inlines = NULL;
2749 finput = finput1;
2750 obstack_free (&inline_text_obstack, inline_text_firstobj);
2752 /* The space used by T will be freed after all inline
2753 functions have been processed. */
2754 if (value <= 0)
2755 goto relex;
2756 else
2757 goto done;
2759 end_of_file = 1;
2760 value = ENDFILE;
2761 break;
2763 case '$':
2764 if (dollars_in_ident)
2766 dollar_seen = 1;
2767 goto letter;
2769 value = '$';
2770 goto done;
2772 case 'L':
2773 /* Capital L may start a wide-string or wide-character constant. */
2775 register int c = getch ();
2776 if (c == '\'')
2778 wide_flag = 1;
2779 goto char_constant;
2781 if (c == '"')
2783 wide_flag = 1;
2784 goto string_constant;
2786 ungetc (c, finput);
2789 case 'A': case 'B': case 'C': case 'D': case 'E':
2790 case 'F': case 'G': case 'H': case 'I': case 'J':
2791 case 'K': case 'M': case 'N': case 'O':
2792 case 'P': case 'Q': case 'R': case 'S': case 'T':
2793 case 'U': case 'V': case 'W': case 'X': case 'Y':
2794 case 'Z':
2795 case 'a': case 'b': case 'c': case 'd': case 'e':
2796 case 'f': case 'g': case 'h': case 'i': case 'j':
2797 case 'k': case 'l': case 'm': case 'n': case 'o':
2798 case 'p': case 'q': case 'r': case 's': case 't':
2799 case 'u': case 'v': case 'w': case 'x': case 'y':
2800 case 'z':
2801 case '_':
2802 letter:
2804 register char *p;
2806 p = token_buffer;
2807 while (isalnum(c) || (c == '_') || c == '$')
2809 if (p >= token_buffer + maxtoken)
2810 p = extend_token_buffer (p);
2811 if (c == '$' && ! dollars_in_ident)
2812 break;
2814 *p++ = c;
2815 c = getc (finput);
2818 *p = 0;
2819 nextchar = c;
2821 value = IDENTIFIER;
2822 yylval.itype = 0;
2824 /* Try to recognize a keyword. Uses minimum-perfect hash function */
2827 register struct resword *ptr;
2829 if (ptr = is_reserved_word (token_buffer, p - token_buffer))
2831 if (current_lang_name != lang_name_cplusplus)
2833 if (ptr->rid != 0
2834 && (ptr->rid == RID_CLASS
2835 || ptr->rid == RID_FRIEND
2836 || ptr->rid == RID_VIRTUAL
2837 || (flag_no_asm && ptr->rid == RID_INLINE)))
2839 ptr = 0;
2840 goto not_reserved_word_after_all;
2842 if (flag_traditional
2843 && ((int) ptr->token == TYPEOF
2844 || ptr->rid == RID_SIGNED
2845 || ptr->rid == RID_INLINE))
2847 ptr = 0;
2848 goto not_reserved_word_after_all;
2851 if (ptr->rid)
2853 tree old_ttype = ridpointers[(int) ptr->rid];
2855 /* If this provides a type for us, then revert lexical
2856 state to standard state. */
2857 if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
2858 && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
2859 && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
2860 looking_for_typename = 0;
2862 /* Check if this is a language-type declaration.
2863 Just glimpse the next non-white character. */
2864 nextchar = skip_white_space (nextchar);
2865 if (nextchar == '"')
2867 /* We are looking at a string. Complain
2868 if the token before the string is no `extern'.
2870 Could cheat some memory by placing this string
2871 on the temporary_, instead of the saveable_
2872 obstack. */
2874 if (ptr->rid != RID_EXTERN)
2875 error ("invalid modifier `%s' for language string",
2876 ptr->name);
2877 yylex ();
2878 value = EXTERN_LANG_STRING;
2879 yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
2880 break;
2882 yylval.ttype = old_ttype;
2884 value = (int) ptr->token;
2886 not_reserved_word_after_all:
2890 /* If we did not find a keyword, look for an identifier
2891 (or a typename). */
2893 #ifdef FIELD_XREF
2894 if (value == IDENTIFIER || value == TYPESPEC)
2895 FIELD_xref_ref(current_function_decl,token_buffer);
2896 #endif
2897 if (value == IDENTIFIER)
2899 tmp = get_identifier (token_buffer);
2900 #ifndef VMS
2901 /* Make sure that user does not collide with our internal
2902 naming scheme. */
2903 if (JOINER == '$'
2904 && dollar_seen
2905 && (THIS_NAME_P (tmp)
2906 || VPTR_NAME_P (tmp)
2907 || DESTRUCTOR_NAME_P (tmp)
2908 || WRAPPER_OR_ANTI_WRAPPER_NAME_P (tmp)
2909 || OPERATOR_NAME_P (tmp)
2910 || VTABLE_NAME_P (tmp)
2911 || OPERATOR_TYPENAME_P (tmp)
2912 || TEMP_NAME_P (tmp)
2913 || ANON_AGGRNAME_P (tmp)
2914 || ANON_PARMNAME_P (tmp)))
2915 warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
2916 token_buffer);
2917 #endif
2919 /* Come into here if we must reprocess an identifier. */
2920 resume_identifier_processing:
2922 if (looking_for_typename == 1
2923 && TREE_TYPE (tmp) != 0)
2924 lastiddecl = TREE_TYPE (tmp);
2925 else lastiddecl = lookup_name (tmp);
2927 if (lastiddecl && TREE_CODE (lastiddecl) == TYPE_DECL
2928 && looking_for_typename >= 0)
2930 /* This call could blow away yylval. */
2932 c = skip_white_space (nextchar);
2933 if (c == ':')
2935 c = getch ();
2936 if (c == ':')
2938 nextchar = -1;
2939 value = TYPENAME_SCOPE;
2941 else
2943 nextchar = c;
2944 value = TYPENAME_COLON;
2947 else if (c == '.'
2948 && current_function_decl == NULL_TREE
2949 && current_class_type == NULL_TREE)
2951 c = getch ();
2952 if (c == '.')
2954 nextchar = -1;
2955 c = getch ();
2956 if (c != '.')
2957 error ("missing '.' in `...'");
2958 value = TYPENAME_ELLIPSIS;
2959 tmp = build_tree_list (NULL_TREE, build_tree_list (TREE_TYPE (lastiddecl), NULL_TREE));
2961 else
2963 nextchar = c;
2964 warning ("use of obsolete scope operator `.'; use `::' instead");
2965 value = TYPENAME_SCOPE;
2967 looking_for_typename = 0;
2969 else
2971 nextchar = c;
2972 value = TYPENAME;
2973 if (looking_for_typename == 1)
2975 looking_for_typename = 0;
2976 #if 0
2977 yylval.ttype = TREE_TYPE (lastiddecl);
2978 break;
2979 #endif
2983 else if (lastiddecl == 0 && flag_labels_ok)
2984 lastiddecl = IDENTIFIER_LABEL_VALUE (tmp);
2986 yylval.ttype = tmp;
2988 if (value == NEW && ! global_bindings_p ())
2990 looking_for_typename = 1;
2991 value = NEW;
2992 goto done;
2995 break;
2997 case '0': case '1': case '2': case '3': case '4':
2998 case '5': case '6': case '7': case '8': case '9':
2999 case '.':
3001 register char *p;
3002 int base = 10;
3003 int count = 0;
3004 int largest_digit = 0;
3005 int numdigits = 0;
3006 /* for multi-precision arithmetic,
3007 we store only 8 live bits in each short,
3008 giving us 64 bits of reliable precision */
3009 short shorts[8];
3011 enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
3012 = NOT_FLOAT;
3014 p = token_buffer;
3015 *p++ = c;
3017 /* Optimize for most frequent case. */
3018 if (c == '0' || c == '1')
3020 register int c1 = getch ();
3021 if (! isalnum (c1) && c1 != '.')
3023 /* Terminate string. */
3024 *p = 0;
3025 if (c == '0')
3026 yylval.ttype = integer_zero_node;
3027 else
3028 yylval.ttype = integer_one_node;
3029 nextchar = c1;
3030 value = CONSTANT;
3031 goto done;
3033 ungetc (c1, finput);
3036 for (count = 0; count < 8; count++)
3037 shorts[count] = 0;
3039 if (c == '0')
3041 *p++ = (c = getch ());
3042 if ((c == 'x') || (c == 'X'))
3044 base = 16;
3045 *p++ = (c = getch ());
3047 else
3049 base = 8;
3050 numdigits++;
3054 /* Read all the digits-and-decimal-points. */
3056 while (c == '.'
3057 || (isalnum (c) && (c != 'l') && (c != 'L')
3058 && (c != 'u') && (c != 'U')
3059 && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
3061 if (c == '.')
3063 if (base == 16)
3064 error ("floating constant may not be in radix 16");
3065 if (floatflag == AFTER_POINT)
3067 error ("malformed floating constant");
3068 floatflag = TOO_MANY_POINTS;
3070 else
3071 floatflag = AFTER_POINT;
3073 base = 10;
3074 *p++ = c = getch ();
3075 /* Accept '.' as the start of a floating-point number
3076 only when it is followed by a digit.
3077 Otherwise, unread the following non-digit
3078 and use the '.' as a structural token. */
3079 if (p == token_buffer + 2 && !isdigit (c))
3081 if (c == '.')
3083 c = getch ();
3084 if (c == '.')
3086 *p++ = '.';
3087 *p = '\0';
3088 value = ELLIPSIS;
3089 goto done;
3091 nextchar = c;
3092 token_buffer[2] = '\0';
3093 value = RANGE;
3094 goto done;
3096 nextchar = c;
3097 token_buffer[1] = '\0';
3098 value = '.';
3099 goto done;
3102 else
3104 /* It is not a decimal point.
3105 It should be a digit (perhaps a hex digit). */
3107 if (isdigit (c))
3109 c = c - '0';
3111 else if (base <= 10)
3113 if ((c&~040) == 'E')
3115 base = 10;
3116 floatflag = AFTER_POINT;
3117 break; /* start of exponent */
3119 error ("nondigits in number and not hexadecimal");
3120 c = 0;
3122 else if (c >= 'a')
3124 c = c - 'a' + 10;
3126 else
3128 c = c - 'A' + 10;
3130 if (c >= largest_digit)
3131 largest_digit = c;
3132 numdigits++;
3134 for (count = 0; count < 8; count++)
3136 (shorts[count] *= base);
3137 if (count)
3139 shorts[count] += (shorts[count-1] >> 8);
3140 shorts[count-1] &= (1<<8)-1;
3142 else shorts[0] += c;
3145 if (p >= token_buffer + maxtoken - 3)
3146 p = extend_token_buffer (p);
3147 *p++ = (c = getch ());
3151 if (numdigits == 0)
3152 error ("numeric constant with no digits");
3154 if (largest_digit >= base)
3155 error ("numeric constant contains digits beyond the radix");
3157 /* Remove terminating char from the token buffer and delimit the string */
3158 *--p = 0;
3160 if (floatflag != NOT_FLOAT)
3162 tree type = double_type_node;
3163 char f_seen = 0;
3164 char l_seen = 0;
3165 double value;
3167 /* Read explicit exponent if any, and put it in tokenbuf. */
3169 if ((c == 'e') || (c == 'E'))
3171 if (p >= token_buffer + maxtoken - 3)
3172 p = extend_token_buffer (p);
3173 *p++ = c;
3174 c = getch ();
3175 if ((c == '+') || (c == '-'))
3177 *p++ = c;
3178 c = getch ();
3180 if (! isdigit (c))
3181 error ("floating constant exponent has no digits");
3182 while (isdigit (c))
3184 if (p >= token_buffer + maxtoken - 3)
3185 p = extend_token_buffer (p);
3186 *p++ = c;
3187 c = getch ();
3191 *p = 0;
3192 errno = 0;
3193 value = atof (token_buffer);
3194 #ifdef ERANGE
3195 if (errno == ERANGE && !flag_traditional)
3197 char *p1 = token_buffer;
3198 /* Check for "0.0" and variants;
3199 Sunos 4 spuriously returns ERANGE for them. */
3200 while (*p1 == '0') p1++;
3201 if (*p1 == '.') p1++;
3202 while (*p1 == '0') p1++;
3203 if (*p1 != 0)
3204 warning ("floating point number exceeds range of `double'");
3206 #endif
3208 /* Read the suffixes to choose a data type. */
3209 while (1)
3211 if (c == 'f' || c == 'F')
3213 if (f_seen)
3214 error ("two `f's in floating constant");
3215 f_seen = 1;
3216 type = float_type_node;
3218 else if (c == 'l' || c == 'L')
3220 if (l_seen)
3221 error ("two `l's in floating constant");
3222 l_seen = 1;
3223 type = long_double_type_node;
3225 else
3227 if (isalnum (c))
3229 error ("garbage at end of number");
3230 while (isalnum (c))
3232 if (p >= token_buffer + maxtoken - 3)
3233 p = extend_token_buffer (p);
3234 *p++ = c;
3235 c = getch ();
3238 break;
3240 if (p >= token_buffer + maxtoken - 3)
3241 p = extend_token_buffer (p);
3242 *p++ = c;
3243 c = getch ();
3246 /* Create a node with determined type and value. */
3247 yylval.ttype = build_real (type, value);
3249 ungetc (c, finput);
3250 *p = 0;
3252 else
3254 tree type;
3255 int spec_unsigned = 0;
3256 int spec_long = 0;
3258 while (1)
3260 if (c == 'u' || c == 'U')
3262 if (spec_unsigned)
3263 error ("two `u's in integer constant");
3264 spec_unsigned = 1;
3266 else if (c == 'l' || c == 'L')
3268 if (spec_long)
3269 error ("two `l's in integer constant");
3270 spec_long = 1;
3272 else
3274 if (isalnum (c))
3276 error ("garbage at end of number");
3277 while (isalnum (c))
3279 if (p >= token_buffer + maxtoken - 3)
3280 p = extend_token_buffer (p);
3281 *p++ = c;
3282 c = getch ();
3285 break;
3287 if (p >= token_buffer + maxtoken - 3)
3288 p = extend_token_buffer (p);
3289 *p++ = c;
3290 c = getch ();
3293 ungetc (c, finput);
3295 if (shorts[7] | shorts[6] | shorts[5] | shorts[4])
3296 warning ("integer constant out of range");
3298 /* This is simplified by the fact that our constant
3299 is always positive. */
3300 yylval.ttype
3301 = build_int_2 ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0],
3304 if (!spec_long && !spec_unsigned
3305 && int_fits_type_p (yylval.ttype, integer_type_node))
3306 type = integer_type_node;
3308 else if (!spec_long && base != 10
3309 && int_fits_type_p (yylval.ttype, unsigned_type_node))
3310 type = unsigned_type_node;
3312 else if (!spec_unsigned
3313 && int_fits_type_p (yylval.ttype, long_integer_type_node))
3314 type = long_integer_type_node;
3316 else
3318 type = long_unsigned_type_node;
3319 if (! int_fits_type_p (yylval.ttype, long_unsigned_type_node))
3320 warning ("integer constant out of range");
3322 TREE_TYPE (yylval.ttype) = type;
3325 value = CONSTANT; break;
3328 case '\'':
3329 char_constant:
3331 register int result = 0;
3332 register num_chars = 0;
3333 int width = TYPE_PRECISION (char_type_node);
3334 int max_chars;
3336 if (wide_flag) width = TYPE_PRECISION (integer_type_node);
3338 max_chars = TYPE_PRECISION (integer_type_node) / width;
3340 while (1)
3342 tryagain:
3344 c = getch ();
3346 if (c == '\'' || c == EOF)
3347 break;
3349 if (c == '\\')
3351 c = readescape ();
3352 if (c < 0)
3353 goto tryagain;
3354 if (width < HOST_BITS_PER_INT
3355 && (unsigned) c >= (1 << width))
3356 warning ("escape sequence out of range for character");
3358 else if (c == '\n')
3360 if (pedantic)
3361 warning ("ANSI C forbids newline in character constant");
3362 lineno++;
3365 num_chars++;
3366 if (num_chars > maxtoken - 4)
3367 extend_token_buffer (token_buffer);
3369 token_buffer[num_chars] = c;
3371 /* Merge character into result; ignore excess chars. */
3372 if (num_chars < max_chars + 1)
3374 if (width < HOST_BITS_PER_INT)
3375 result = (result << width) | (c & ((1 << width) - 1));
3376 else
3377 result = c;
3381 token_buffer[num_chars + 1] = '\'';
3382 token_buffer[num_chars + 2] = 0;
3384 if (c != '\'')
3385 error ("malformatted character constant");
3386 else if (num_chars == 0)
3387 error ("empty character constant");
3388 else if (num_chars > max_chars)
3390 num_chars = max_chars;
3391 error ("character constant too long");
3393 else if (num_chars != 1 && ! flag_traditional)
3394 warning ("multi-character character constant");
3396 /* If char type is signed, sign-extend the constant. */
3397 if (! wide_flag)
3399 int num_bits = num_chars * width;
3400 if (TREE_UNSIGNED (char_type_node)
3401 || ((result >> (num_bits - 1)) & 1) == 0)
3402 yylval.ttype
3403 = build_int_2 (result & ((unsigned) ~0
3404 >> (HOST_BITS_PER_INT - num_bits)),
3406 else
3407 yylval.ttype
3408 = build_int_2 (result | ~((unsigned) ~0
3409 >> (HOST_BITS_PER_INT - num_bits)),
3410 -1);
3411 TREE_TYPE (yylval.ttype) = char_type_node;
3413 else
3415 yylval.ttype = build_int_2 (result, 0);
3416 TREE_TYPE (yylval.ttype) = integer_type_node;
3418 value = CONSTANT; break;
3421 case '"':
3422 string_constant:
3424 int *widep;
3425 register char *p;
3427 c = getch ();
3428 p = token_buffer + 1;
3430 if (wide_flag)
3431 widep = wide_buffer;
3433 while (c != '"' && c >= 0)
3435 if (c == '\\')
3437 c = readescape ();
3438 if (c < 0)
3439 goto skipnewline;
3440 if (!wide_flag && c >= (1 << BITS_PER_UNIT))
3441 warning ("escape sequence out of range for character");
3443 else if (c == '\n')
3445 if (pedantic)
3446 warning ("ANSI C forbids newline in string constant");
3447 lineno++;
3450 /* Store the char in C into the appropriate buffer. */
3452 if (wide_flag)
3454 if (widep == wide_buffer + max_wide)
3456 int n = widep - wide_buffer;
3457 max_wide *= 2;
3458 wide_buffer = (int *) xrealloc (wide_buffer, max_wide + 1);
3459 widep = wide_buffer + n;
3461 *widep++ = c;
3463 else
3465 if (p == token_buffer + maxtoken)
3466 p = extend_token_buffer (p);
3467 *p++ = c;
3470 skipnewline:
3471 c = getch ();
3472 if (c == EOF) {
3473 error("Unterminated string");
3474 break;
3478 /* We have read the entire constant.
3479 Construct a STRING_CST for the result. */
3481 if (wide_flag)
3483 /* If this is a L"..." wide-string, make a vector
3484 of the ints in wide_buffer. */
3485 *widep = 0;
3486 /* We have not implemented the case where `int'
3487 on the target and on the execution machine differ in size. */
3488 assert (TYPE_PRECISION (integer_type_node) == sizeof (int) * BITS_PER_UNIT);
3489 yylval.ttype = build_string ((widep - wide_buffer) * sizeof (int),
3490 (char *)wide_buffer);
3491 TREE_TYPE (yylval.ttype) = int_array_type_node;
3493 else
3495 *p = 0;
3496 yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
3497 TREE_TYPE (yylval.ttype) = char_array_type_node;
3500 *p++ = '"';
3501 *p = 0;
3503 value = STRING; break;
3506 case '+':
3507 case '-':
3508 case '&':
3509 case '|':
3510 case '<':
3511 case '>':
3512 case '*':
3513 case '/':
3514 case '%':
3515 case '^':
3516 case '!':
3517 case '=':
3519 register int c1;
3521 combine:
3523 switch (c)
3525 case '+':
3526 yylval.code = PLUS_EXPR; break;
3527 case '-':
3528 yylval.code = MINUS_EXPR; break;
3529 case '&':
3530 yylval.code = BIT_AND_EXPR; break;
3531 case '|':
3532 yylval.code = BIT_IOR_EXPR; break;
3533 case '*':
3534 yylval.code = MULT_EXPR; break;
3535 case '/':
3536 yylval.code = TRUNC_DIV_EXPR; break;
3537 case '%':
3538 yylval.code = TRUNC_MOD_EXPR; break;
3539 case '^':
3540 yylval.code = BIT_XOR_EXPR; break;
3541 case LSHIFT:
3542 yylval.code = LSHIFT_EXPR; break;
3543 case RSHIFT:
3544 yylval.code = RSHIFT_EXPR; break;
3545 case '<':
3546 yylval.code = LT_EXPR; break;
3547 case '>':
3548 yylval.code = GT_EXPR; break;
3551 token_buffer[1] = c1 = getch ();
3552 token_buffer[2] = 0;
3554 if (c1 == '=')
3556 switch (c)
3558 case '<':
3559 value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
3560 case '>':
3561 value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
3562 case '!':
3563 value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
3564 case '=':
3565 value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
3567 value = ASSIGN; goto done;
3569 else if (c == c1)
3570 switch (c)
3572 case '+':
3573 value = PLUSPLUS; goto done;
3574 case '-':
3575 value = MINUSMINUS; goto done;
3576 case '&':
3577 value = ANDAND; goto done;
3578 case '|':
3579 value = OROR; goto done;
3580 case '<':
3581 c = LSHIFT;
3582 goto combine;
3583 case '>':
3584 c = RSHIFT;
3585 goto combine;
3587 else if ((c == '-') && (c1 == '>'))
3589 nextchar = skip_white_space (getch ());
3590 if (nextchar == '(')
3592 int next_c = skip_white_space (getch ());
3593 if (next_c == ')')
3595 nextchar = -1;
3596 value = POINTSAT_LEFT_RIGHT;
3597 goto done;
3599 ungetc (next_c, finput);
3601 value = POINTSAT;
3602 goto done;
3604 else if (c1 == '?' && (c == '<' || c == '>'))
3606 token_buffer[3] = 0;
3608 c1 = getch ();
3609 yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
3610 if (c1 == '=')
3612 /* <?= or >?= expression. */
3613 token_buffer[2] = c1;
3614 value = ASSIGN;
3616 else
3618 value = MIN_MAX;
3619 nextchar = c1;
3621 if (pedantic)
3622 error ("use of `operator %s' is not standard C++",
3623 token_buffer);
3624 goto done;
3627 nextchar = c1;
3628 token_buffer[1] = 0;
3630 if ((c == '<') || (c == '>'))
3631 value = ARITHCOMPARE;
3632 else value = c;
3633 goto done;
3636 case ':':
3637 c = getch ();
3638 if (c == ':')
3640 token_buffer[1] = ':';
3641 token_buffer[2] = '\0';
3642 value = SCOPE;
3643 yylval.itype = 1;
3645 else
3647 nextchar = c;
3648 value = ':';
3650 break;
3652 case 0:
3653 /* Don't make yyparse think this is eof. */
3654 value = 1;
3655 break;
3657 case '(':
3658 /* try, weakly, to handle casts to pointers to functions. */
3659 nextchar = skip_white_space (getch ());
3660 if (nextchar == '*')
3662 int next_c = skip_white_space (getch ());
3663 if (next_c == ')')
3665 nextchar = -1;
3666 yylval.ttype = build1 (INDIRECT_REF, 0, 0);
3667 value = PAREN_STAR_PAREN;
3669 else
3671 ungetc (next_c, finput);
3672 value = c;
3675 /* Go down for a (X::*) or (X::&). */
3676 else if (isalpha (nextchar) || nextchar == '_' || nextchar == '$')
3678 YYSTYPE this_yylval = yylval;
3679 tree this_lastiddecl = lastiddecl;
3680 nextyychar = yylex ();
3681 if (nextyychar == TYPENAME_SCOPE)
3683 if (nextchar < 0)
3684 nextchar = skip_white_space (getch ());
3685 if (nextchar == '*' || nextchar == '&')
3687 int next_c = skip_white_space (getch ());
3688 if (next_c == ')')
3690 nextyychar = -1;
3691 if (nextchar == '*')
3693 value = PAREN_X_SCOPE_STAR_PAREN;
3694 yylval.ttype = build_parse_node (SCOPE_REF, yylval.ttype,
3695 build_parse_node (INDIRECT_REF, 0));
3697 else
3699 value = PAREN_X_SCOPE_REF_PAREN;
3700 yylval.ttype = build_parse_node (SCOPE_REF, yylval.ttype,
3701 build_parse_node (ADDR_EXPR, 0));
3703 nextchar = -1;
3705 else
3707 ungetc (next_c, finput);
3708 nextyylval = yylval;
3709 nextlastiddecl = lastiddecl;
3710 yylval = this_yylval;
3711 lastiddecl = this_lastiddecl;
3712 value = c;
3715 else
3717 nextyylval = yylval;
3718 nextlastiddecl = lastiddecl;
3719 yylval = this_yylval;
3720 lastiddecl = this_lastiddecl;
3721 value = c;
3724 else
3726 nextyylval = yylval;
3727 nextlastiddecl = lastiddecl;
3728 yylval = this_yylval;
3729 lastiddecl = this_lastiddecl;
3730 value = c;
3733 else if (nextchar == ')')
3735 nextchar = -1;
3736 yylval.ttype = NULL_TREE;
3737 value = LEFT_RIGHT;
3739 else value = c;
3740 break;
3742 default:
3743 value = c;
3746 done:
3747 /* yylloc.last_line = lineno; */
3748 #ifdef GATHER_STATISTICS
3749 token_count[value] += 1;
3750 #endif
3752 return value;
3755 typedef enum
3757 d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
3758 id_kind, op_id_kind, perm_list_kind, temp_list_kind,
3759 x_kind, lang_decl, lang_type, all_kinds
3760 } tree_node_kind;
3761 extern int tree_node_kinds[];
3762 extern int tree_node_sizes[];
3763 extern char *tree_node_kind_names[];
3765 /* Place to save freed lang_decls which were allocated on the
3766 permanent_obstack. @@ Not currently used. */
3767 tree free_lang_decl_chain;
3769 tree
3770 build_lang_decl (code, name, type)
3771 enum tree_code code;
3772 tree name;
3773 tree type;
3775 extern struct obstack *current_obstack, *saveable_obstack;
3776 extern struct obstack permanent_obstack;
3777 register tree t = build_decl (code, name, type);
3778 struct obstack *obstack = current_obstack;
3779 register int i = sizeof (struct lang_decl) / sizeof (int);
3780 register int *pi;
3782 if (! TREE_PERMANENT (t))
3783 obstack = saveable_obstack;
3785 #ifdef LANG_DECL_PERMANENT
3786 if (free_lang_decl_chain && obstack == &permanent_obstack)
3788 pi = (int *)free_lang_decl_chain;
3789 free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
3791 else
3792 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
3793 #else
3794 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
3795 #endif
3797 while (i > 0)
3798 pi[--i] = 0;
3800 DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
3801 #ifdef LANG_DECL_PERMANENT
3802 LANG_DECL_PERMANENT ((struct lang_decl *) pi)
3803 = obstack == &permanent_obstack;
3804 #endif
3805 DECL_MAIN_VARIANT (t) = t;
3806 DECL_ORIGINAL_NAME (t) = name;
3807 if (current_lang_name == lang_name_cplusplus)
3809 DECL_LANGUAGE (t) = lang_cplusplus;
3811 #ifndef NO_AUTO_OVERLOAD
3812 if (code == FUNCTION_DECL && name != 0
3813 && ! (IDENTIFIER_LENGTH (name) == 4
3814 && IDENTIFIER_POINTER (name)[0] == 'm'
3815 && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
3816 && ! (IDENTIFIER_LENGTH (name) > 10
3817 && IDENTIFIER_POINTER (name)[0] == '_'
3818 && IDENTIFIER_POINTER (name)[1] == '_'
3819 && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
3820 TREE_OVERLOADED (name) = 1;
3821 #endif
3823 else if (current_lang_name == lang_name_c)
3824 DECL_LANGUAGE (t) = lang_c;
3825 else abort ();
3827 #ifdef GATHER_STATISTICS
3828 tree_node_kinds[(int)lang_decl] += 1;
3829 tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
3830 #endif
3832 return t;
3835 tree
3836 build_lang_field_decl (code, name, type)
3837 enum tree_code code;
3838 tree name;
3839 tree type;
3841 extern struct obstack *current_obstack, *saveable_obstack;
3842 register tree t = build_decl (code, name, type);
3843 struct obstack *obstack = current_obstack;
3844 register int i = sizeof (struct lang_decl_flags) / sizeof (int);
3845 register int *pi;
3847 if (! TREE_PERMANENT (t))
3848 obstack = saveable_obstack;
3850 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
3851 while (i > 0)
3852 pi[--i] = 0;
3854 DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
3855 return t;
3858 tree
3859 make_lang_type (code)
3860 enum tree_code code;
3862 extern struct obstack *current_obstack, *saveable_obstack;
3863 register tree t = make_node (code);
3864 struct obstack *obstack = current_obstack;
3865 register int i = sizeof (struct lang_type) / sizeof (int);
3866 register int *pi;
3868 if (! TREE_PERMANENT (t))
3869 obstack = saveable_obstack;
3871 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
3872 while (i > 0)
3873 pi[--i] = 0;
3875 TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
3876 CLASSTYPE_MAIN_VARIANT (t) = t;
3877 CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
3878 CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown;
3879 CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
3881 /* Make sure this is laid out, for ease of use later.
3882 In the presence of parse errors, the normal was of assuring
3883 this might not ever get executed, so we lay it out *immediately*. */
3884 build_pointer_type (t);
3886 #ifdef GATHER_STATISTICS
3887 tree_node_kinds[(int)lang_type] += 1;
3888 tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
3889 #endif
3891 return t;
3894 void
3895 copy_decl_lang_specific (decl)
3896 tree decl;
3898 extern struct obstack *current_obstack, *saveable_obstack;
3899 register int *old = (int *)DECL_LANG_SPECIFIC (decl);
3900 struct obstack *obstack = current_obstack;
3901 register int i = sizeof (struct lang_decl) / sizeof (int);
3902 register int *pi;
3904 if (! TREE_PERMANENT (decl))
3905 obstack = saveable_obstack;
3907 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
3908 while (i-- > 0)
3909 pi[i] = old[i];
3911 DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
3913 #ifdef GATHER_STATISTICS
3914 tree_node_kinds[(int)lang_decl] += 1;
3915 tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
3916 #endif
3919 void
3920 copy_type_lang_specific (type)
3921 tree type;
3923 extern struct obstack *current_obstack, *saveable_obstack;
3924 register int *old = (int *)TYPE_LANG_SPECIFIC (type);
3925 struct obstack *obstack = current_obstack;
3926 register int i = sizeof (struct lang_type) / sizeof (int);
3927 register int *pi;
3929 if (! TREE_PERMANENT (type))
3930 obstack = saveable_obstack;
3932 pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
3933 while (i-- > 0)
3934 pi[i] = old[i];
3936 TYPE_LANG_SPECIFIC (type) = (struct lang_type *) pi;
3937 CLASSTYPE_AS_LIST (type) = build_tree_list (NULL_TREE, type);
3938 if (CLASSTYPE_N_BASECLASSES (type) > 0)
3939 CLASSTYPE_BASECLASSES (type) = (tree *)obstack_copy (obstack, CLASSTYPE_BASECLASSES (type), (CLASSTYPE_N_BASECLASSES (type)+1) * sizeof (tree));
3941 #ifdef GATHER_STATISTICS
3942 tree_node_kinds[(int)lang_type] += 1;
3943 tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
3944 #endif
3947 tree
3948 build_with_cleanup (exp, type, rtl)
3949 tree exp;
3950 tree type;
3951 struct rtx_def *rtl;
3953 if (type != NULL_TREE || TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (exp)))
3955 tree rval = make_node (WITH_CLEANUP_EXPR);
3957 if (type == NULL_TREE)
3958 type = TREE_TYPE (exp);
3960 TREE_OPERAND (rval, 0) = exp;
3961 TREE_OPERAND (rval, 1) = make_node (RTL_EXPR);
3962 TREE_OPERAND (rval, 2) = build_delete (TYPE_POINTER_TO (type),
3963 build1 (ADDR_EXPR, TYPE_POINTER_TO (type), TREE_OPERAND (rval, 1)),
3964 integer_two_node, LOOKUP_NORMAL, 0);
3965 if (rtl != 0)
3966 RTL_EXPR_RTL (TREE_OPERAND (rval, 1)) = rtl;
3967 if (TREE_CODE (exp) == CALL_EXPR
3968 && TREE_VALUE (TREE_OPERAND (exp, 1)) == NULL_TREE)
3969 TREE_VALUE (TREE_OPERAND (exp, 1)) = TREE_OPERAND (rval, 1);
3970 TREE_TYPE (rval) = type;
3971 return rval;
3973 return NULL_TREE;
3976 void
3977 dump_time_statistics ()
3979 register tree prev = 0, decl, next;
3980 int this_time = my_gettime ();
3981 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
3982 += this_time - body_time;
3984 fprintf (stderr, "\n******\n");
3985 print_time ("header files (total)", header_time);
3986 print_time ("main file (total)", this_time - body_time);
3987 fprintf (stderr, "ratio = %g : 1\n",
3988 (double)header_time / (double)(this_time - body_time));
3989 fprintf (stderr, "\n******\n");
3991 for (decl = filename_times; decl; decl = next)
3993 next = IDENTIFIER_GLOBAL_VALUE (decl);
3994 IDENTIFIER_GLOBAL_VALUE (decl) = prev;
3995 prev = decl;
3998 for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
3999 print_time (IDENTIFIER_POINTER (decl),
4000 TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
4003 void
4004 compiler_error (s, v, v2)
4005 char *s;
4006 int v, v2; /* @@also used as pointer */
4008 char buf[1024];
4009 sprintf (buf, s, v, v2);
4010 error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
4013 void
4014 compiler_error_with_decl (decl, s)
4015 tree decl;
4016 char *s;
4018 char *name;
4019 count_error (0);
4021 report_error_function (0);
4023 if (TREE_CODE (decl) == PARM_DECL)
4024 fprintf (stderr, "%s:%d: ",
4025 DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
4026 DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
4027 else
4028 fprintf (stderr, "%s:%d: ",
4029 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
4031 name = lang_printable_name (decl);
4032 if (name)
4033 fprintf (stderr, s, name);
4034 else
4035 fprintf (stderr, s, "((anonymous))");
4036 fprintf (stderr, " (compiler error)\n");