Warning fixes:
[gcc.git] / gcc / ch / lex.c
1 /* Lexical analyzer for GNU CHILL. -*- C -*-
2 Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19 \f
20 #include "config.h"
21 #include "system.h"
22 #include <setjmp.h>
23 #include <sys/stat.h>
24
25 #include "tree.h"
26 #include "input.h"
27
28 #include "lex.h"
29 #include "ch-tree.h"
30 #include "flags.h"
31 #include "parse.h"
32 #include "obstack.h"
33 #include "toplev.h"
34
35 #ifdef DWARF_DEBUGGING_INFO
36 #include "dwarfout.h"
37 #endif
38
39 #ifdef MULTIBYTE_CHARS
40 #include <locale.h>
41 #endif
42
43 /* include the keyword recognizers */
44 #include "hash.h"
45
46 FILE* finput;
47
48 #if 0
49 static int last_token = 0;
50 /* Sun's C compiler warns about the safer sequence
51 do { .. } while 0
52 when there's a 'return' inside the braces, so don't use it */
53 #define RETURN_TOKEN(X) { last_token = X; return (X); }
54 #endif
55
56 /* This is set non-zero to force incoming tokens to lowercase. */
57 extern int ignore_case;
58
59 extern int module_number;
60 extern int serious_errors;
61
62 /* This is non-zero to recognize only uppercase special words. */
63 extern int special_UC;
64
65 extern struct obstack permanent_obstack;
66 extern struct obstack temporary_obstack;
67
68 /* forward declarations */
69 static void close_input_file PROTO((char *));
70 static tree convert_bitstring PROTO((char *));
71 static tree convert_integer PROTO((char *));
72 static void maybe_downcase PROTO((char *));
73 static int maybe_number PROTO((char *));
74 static tree equal_number PROTO((void));
75 static void handle_use_seizefile_directive PROTO((int));
76 static int handle_name PROTO((tree));
77 static char *readstring PROTO((int, int *));
78 static void read_directive PROTO((void));
79 static tree read_identifier PROTO((int));
80 static tree read_number PROTO((int));
81 static void skip_c_comment PROTO((void));
82 static void skip_line_comment PROTO((void));
83 static int skip_whitespace PROTO((void));
84 static tree string_or_char PROTO((int, char *));
85
86 /* next variables are public, because ch-actions uses them */
87
88 /* the default grantfile name, set by lang_init */
89 tree default_grant_file = 0;
90
91 /* These tasking-related variables are NULL at the start of each
92 compiler pass, and are set to an expression tree if and when
93 a compiler directive is parsed containing an expression.
94 The NULL state is significant; it means 'no user-specified
95 signal_code (or whatever) has been parsed'. */
96
97 /* process type, set by <> PROCESS_TYPE = number <> */
98 tree process_type = NULL_TREE;
99
100 /* send buffer default priority,
101 set by <> SEND_BUFFER_DEFAULT_PRIORITY = number <> */
102 tree send_buffer_prio = NULL_TREE;
103
104 /* send signal default priority,
105 set by <> SEND_SIGNAL_DEFAULT_PRIORITY = number <> */
106 tree send_signal_prio = NULL_TREE;
107
108 /* signal code, set by <> SIGNAL_CODE = number <> */
109 tree signal_code = NULL_TREE;
110
111 /* flag for range checking */
112 int range_checking = 1;
113
114 /* flag for NULL pointer checking */
115 int empty_checking = 1;
116
117 /* flag to indicate making all procedure local variables
118 to be STATIC */
119 int all_static_flag = 0;
120
121 /* flag to indicate -fruntime-checking command line option.
122 Needed for initializing range_checking and empty_checking
123 before pass 2 */
124 int runtime_checking_flag = 1;
125
126 /* The elements of `ridpointers' are identifier nodes
127 for the reserved type names and storage classes.
128 It is indexed by a RID_... value. */
129 tree ridpointers[(int) RID_MAX];
130
131 /* Nonzero tells yylex to ignore \ in string constants. */
132 static int ignore_escape_flag = 0;
133
134 static int maxtoken; /* Current nominal length of token buffer. */
135 char *token_buffer; /* Pointer to token buffer.
136 Actual allocated length is maxtoken + 2.
137 This is not static because objc-parse.y uses it. */
138
139 /* implement yylineno handling for flex */
140 #define yylineno lineno
141
142 static int inside_c_comment = 0;
143
144 static int saw_eol = 0; /* 1 if we've just seen a '\n' */
145 static int saw_eof = 0; /* 1 if we've just seen an EOF */
146
147 typedef struct string_list
148 {
149 struct string_list *next;
150 char *str;
151 } STRING_LIST;
152
153 /* list of paths specified on the compiler command line by -L options. */
154 static STRING_LIST *seize_path_list = (STRING_LIST *)0;
155
156 /* List of seize file names. Each TREE_VALUE is an identifier
157 (file name) from a <>USE_SEIZE_FILE<> directive.
158 The TREE_PURPOSE is non-NULL if a USE_SEIZE_FILE directive has been
159 written to the grant file. */
160 static tree files_to_seize = NULL_TREE;
161 /* Last node on files_to_seize list. */
162 static tree last_file_to_seize = NULL_TREE;
163 /* Pointer into files_to_seize list: Next unparsed file to read. */
164 static tree next_file_to_seize = NULL_TREE;
165
166 /* The most recent use_seize_file directive. */
167 tree use_seizefile_name = NULL_TREE;
168
169 /* If non-NULL, the name of the seizefile we're currently processing. */
170 tree current_seizefile_name = NULL_TREE;
171 \f
172 /* called to reset for pass 2 */
173 static void
174 ch_lex_init ()
175 {
176 current_seizefile_name = NULL_TREE;
177
178 lineno = 0;
179
180 saw_eol = 0;
181 saw_eof = 0;
182 /* Initialize these compiler-directive variables. */
183 process_type = NULL_TREE;
184 send_buffer_prio = NULL_TREE;
185 send_signal_prio = NULL_TREE;
186 signal_code = NULL_TREE;
187 all_static_flag = 0;
188 /* reinitialize rnage checking and empty checking */
189 range_checking = runtime_checking_flag;
190 empty_checking = runtime_checking_flag;
191 }
192
193
194 char *
195 init_parse (filename)
196 char *filename;
197 {
198 int lowercase_standard_names = ignore_case || ! special_UC;
199
200 /* Open input file. */
201 if (filename == 0 || !strcmp (filename, "-"))
202 {
203 finput = stdin;
204 filename = "stdin";
205 }
206 else
207 finput = fopen (filename, "r");
208 if (finput == 0)
209 pfatal_with_name (filename);
210
211 #ifdef IO_BUFFER_SIZE
212 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
213 #endif
214
215 /* Make identifier nodes long enough for the language-specific slots. */
216 set_identifier_size (sizeof (struct lang_identifier));
217
218 /* Start it at 0, because check_newline is called at the very beginning
219 and will increment it to 1. */
220 lineno = 0;
221
222 /* Initialize these compiler-directive variables. */
223 process_type = NULL_TREE;
224 send_buffer_prio = NULL_TREE;
225 send_signal_prio = NULL_TREE;
226 signal_code = NULL_TREE;
227
228 maxtoken = 40;
229 token_buffer = xmalloc ((unsigned)(maxtoken + 2));
230
231 init_chill_expand ();
232
233 #define ENTER_STANDARD_NAME(RID, LOWER, UPPER) \
234 ridpointers[(int) RID] = \
235 get_identifier (lowercase_standard_names ? LOWER : UPPER)
236
237 ENTER_STANDARD_NAME (RID_ALL, "all", "ALL");
238 ENTER_STANDARD_NAME (RID_ASSERTFAIL, "assertfail", "ASSERTFAIL");
239 ENTER_STANDARD_NAME (RID_ASSOCIATION, "association", "ASSOCIATION");
240 ENTER_STANDARD_NAME (RID_BIN, "bin", "BIN");
241 ENTER_STANDARD_NAME (RID_BOOL, "bool", "BOOL");
242 ENTER_STANDARD_NAME (RID_BOOLS, "bools", "BOOLS");
243 ENTER_STANDARD_NAME (RID_BYTE, "byte", "BYTE");
244 ENTER_STANDARD_NAME (RID_CHAR, "char", "CHAR");
245 ENTER_STANDARD_NAME (RID_DOUBLE, "double", "DOUBLE");
246 ENTER_STANDARD_NAME (RID_DURATION, "duration", "DURATION");
247 ENTER_STANDARD_NAME (RID_DYNAMIC, "dynamic", "DYNAMIC");
248 ENTER_STANDARD_NAME (RID_ELSE, "else", "ELSE");
249 ENTER_STANDARD_NAME (RID_EMPTY, "empty", "EMPTY");
250 ENTER_STANDARD_NAME (RID_FALSE, "false", "FALSE");
251 ENTER_STANDARD_NAME (RID_FLOAT, "float", "FLOAT");
252 ENTER_STANDARD_NAME (RID_GENERAL, "general", "GENERAL");
253 ENTER_STANDARD_NAME (RID_IN, "in", "IN");
254 ENTER_STANDARD_NAME (RID_INLINE, "inline", "INLINE");
255 ENTER_STANDARD_NAME (RID_INOUT, "inout", "INOUT");
256 ENTER_STANDARD_NAME (RID_INSTANCE, "instance", "INSTANCE");
257 ENTER_STANDARD_NAME (RID_INT, "int", "INT");
258 ENTER_STANDARD_NAME (RID_LOC, "loc", "LOC");
259 ENTER_STANDARD_NAME (RID_LONG, "long", "LONG");
260 ENTER_STANDARD_NAME (RID_LONG_REAL, "long_real", "LONG_REAL");
261 ENTER_STANDARD_NAME (RID_NULL, "null", "NULL");
262 ENTER_STANDARD_NAME (RID_OUT, "out", "OUT");
263 ENTER_STANDARD_NAME (RID_OVERFLOW, "overflow", "OVERFLOW");
264 ENTER_STANDARD_NAME (RID_PTR, "ptr", "PTR");
265 ENTER_STANDARD_NAME (RID_READ, "read", "READ");
266 ENTER_STANDARD_NAME (RID_REAL, "real", "REAL");
267 ENTER_STANDARD_NAME (RID_RANGE, "range", "RANGE");
268 ENTER_STANDARD_NAME (RID_RANGEFAIL, "rangefail", "RANGEFAIL");
269 ENTER_STANDARD_NAME (RID_RECURSIVE, "recursive", "RECURSIVE");
270 ENTER_STANDARD_NAME (RID_SHORT, "short", "SHORT");
271 ENTER_STANDARD_NAME (RID_SIMPLE, "simple", "SIMPLE");
272 ENTER_STANDARD_NAME (RID_TIME, "time", "TIME");
273 ENTER_STANDARD_NAME (RID_TRUE, "true", "TRUE");
274 ENTER_STANDARD_NAME (RID_UBYTE, "ubyte", "UBYTE");
275 ENTER_STANDARD_NAME (RID_UINT, "uint", "UINT");
276 ENTER_STANDARD_NAME (RID_ULONG, "ulong", "ULONG");
277 ENTER_STANDARD_NAME (RID_UNSIGNED, "unsigned", "UNSIGNED");
278 ENTER_STANDARD_NAME (RID_USHORT, "ushort", "USHORT");
279 ENTER_STANDARD_NAME (RID_VOID, "void", "VOID");
280
281 return filename;
282 }
283
284 void
285 finish_parse ()
286 {
287 if (finput != NULL)
288 fclose (finput);
289 }
290 \f
291 static int yywrap ();
292
293 #define YY_PUTBACK_SIZE 5
294 #define YY_BUF_SIZE 1000
295
296 static char yy_buffer[YY_PUTBACK_SIZE + YY_BUF_SIZE];
297 static char *yy_cur = yy_buffer + YY_PUTBACK_SIZE;
298 static char *yy_lim = yy_buffer + YY_PUTBACK_SIZE;
299
300 int yy_refill ()
301 {
302 char *buf = yy_buffer + YY_PUTBACK_SIZE;
303 int c, result;
304 bcopy (yy_cur - YY_PUTBACK_SIZE, yy_buffer, YY_PUTBACK_SIZE);
305 yy_cur = buf;
306
307 retry:
308 if (saw_eof)
309 {
310 if (yywrap ())
311 return EOF;
312 saw_eof = 0;
313 goto retry;
314 }
315
316 result = 0;
317 while (saw_eol)
318 {
319 c = check_newline ();
320 if (c == EOF)
321 {
322 saw_eof = 1;
323 goto retry;
324 }
325 else if (c != '\n')
326 {
327 saw_eol = 0;
328 buf[result++] = c;
329 }
330 }
331
332 while (result < YY_BUF_SIZE)
333 {
334 c = getc(finput);
335 if (c == EOF)
336 {
337 saw_eof = 1;
338 break;
339 }
340 buf[result++] = c;
341
342 /* Because we might switch input files on a compiler directive
343 (that end with '>', don't read past a '>', just in case. */
344 if (c == '>')
345 break;
346
347 if (c == '\n')
348 {
349 #ifdef YYDEBUG
350 extern int yydebug;
351 if (yydebug)
352 fprintf (stderr, "-------------------------- finished Line %d\n",
353 yylineno);
354 #endif
355 saw_eol = 1;
356 break;
357 }
358 }
359
360 yy_lim = yy_cur + result;
361
362 return yy_lim > yy_cur ? *yy_cur++ : EOF;
363 }
364
365 #define input() (yy_cur < yy_lim ? *yy_cur++ : yy_refill ())
366
367 #define unput(c) (*--yy_cur = (c))
368 \f
369
370 int starting_pass_2 = 0;
371
372 int
373 yylex ()
374 {
375 int nextc;
376 int len;
377 char* tmp;
378 int base;
379 int ch;
380 retry:
381 ch = input ();
382 if (starting_pass_2)
383 {
384 starting_pass_2 = 0;
385 unput (ch);
386 return END_PASS_1;
387 }
388 switch (ch)
389 {
390 case ' ': case '\t': case '\n': case '\f': case '\b': case '\v': case '\r':
391 goto retry;
392 case '[':
393 return LPC;
394 case ']':
395 return RPC;
396 case '{':
397 return LC;
398 case '}':
399 return RC;
400 case '(':
401 nextc = input ();
402 if (nextc == ':')
403 return LPC;
404 unput (nextc);
405 return LPRN;
406 case ')':
407 return RPRN;
408 case ':':
409 nextc = input ();
410 if (nextc == ')')
411 return RPC;
412 else if (nextc == '=')
413 return ASGN;
414 unput (nextc);
415 return COLON;
416 case ',':
417 return COMMA;
418 case ';':
419 return SC;
420 case '+':
421 return PLUS;
422 case '-':
423 nextc = input ();
424 if (nextc == '>')
425 return ARROW;
426 if (nextc == '-')
427 {
428 skip_line_comment ();
429 goto retry;
430 }
431 unput (nextc);
432 return SUB;
433 case '*':
434 return MUL;
435 case '=':
436 return EQL;
437 case '/':
438 nextc = input ();
439 if (nextc == '/')
440 return CONCAT;
441 else if (nextc == '=')
442 return NE;
443 else if (nextc == '*')
444 {
445 skip_c_comment ();
446 goto retry;
447 }
448 unput (nextc);
449 return DIV;
450 case '<':
451 nextc = input ();
452 if (nextc == '=')
453 return LTE;
454 if (nextc == '>')
455 {
456 read_directive ();
457 goto retry;
458 }
459 unput (nextc);
460 return LT;
461 case '>':
462 nextc = input ();
463 if (nextc == '=')
464 return GTE;
465 unput (nextc);
466 return GT;
467
468 case 'D': case 'd':
469 base = 10;
470 goto maybe_digits;
471 case 'B': case 'b':
472 base = 2;
473 goto maybe_digits;
474 case 'H': case 'h':
475 base = 16;
476 goto maybe_digits;
477 case 'O': case 'o':
478 base = 8;
479 goto maybe_digits;
480 case 'C': case 'c':
481 nextc = input ();
482 if (nextc == '\'')
483 {
484 int byte_val = 0;
485 char *start;
486 int len = 0; /* Number of hex digits seen. */
487 for (;;)
488 {
489 ch = input ();
490 if (ch == '\'')
491 break;
492 if (ch == '_')
493 continue;
494 if (!ISXDIGIT (ch)) /* error on non-hex digit */
495 {
496 if (pass == 1)
497 error ("invalid C'xx' ");
498 break;
499 }
500 if (ch >= 'a')
501 ch -= ' ';
502 ch -= '0';
503 if (ch > 9)
504 ch -= 7;
505 byte_val *= 16;
506 byte_val += (int)ch;
507
508 if (len & 1) /* collected two digits, save byte */
509 obstack_1grow (&temporary_obstack, (char) byte_val);
510 len++;
511 }
512 start = obstack_finish (&temporary_obstack);
513 yylval.ttype = string_or_char (len >> 1, start);
514 obstack_free (&temporary_obstack, start);
515 return len == 2 ? SINGLECHAR : STRING;
516 }
517 unput (nextc);
518 goto letter;
519
520 maybe_digits:
521 nextc = input ();
522 if (nextc == '\'')
523 {
524 char *start;
525 obstack_1grow (&temporary_obstack, ch);
526 obstack_1grow (&temporary_obstack, nextc);
527 for (;;)
528 {
529 ch = input ();
530 if (ISALNUM (ch))
531 obstack_1grow (&temporary_obstack, ch);
532 else if (ch != '_')
533 break;
534 }
535 obstack_1grow (&temporary_obstack, '\0');
536 start = obstack_finish (&temporary_obstack);
537 if (ch != '\'')
538 {
539 unput (ch);
540 yylval.ttype = convert_integer (start); /* Pass base? */
541 return NUMBER;
542 }
543 else
544 {
545 yylval.ttype = convert_bitstring (start);
546 return BITSTRING;
547 }
548 }
549 unput (nextc);
550 goto letter;
551
552 case 'A': case 'E':
553 case 'F': case 'G': case 'I': case 'J':
554 case 'K': case 'L': case 'M': case 'N':
555 case 'P': case 'Q': case 'R': case 'S': case 'T':
556 case 'U': case 'V': case 'W': case 'X': case 'Y':
557 case 'Z':
558 case 'a': case 'e':
559 case 'f': case 'g': case 'i': case 'j':
560 case 'k': case 'l': case 'm': case 'n':
561 case 'p': case 'q': case 'r': case 's': case 't':
562 case 'u': case 'v': case 'w': case 'x': case 'y':
563 case 'z':
564 case '_':
565 letter:
566 return handle_name (read_identifier (ch));
567 case '\'':
568 tmp = readstring ('\'', &len);
569 yylval.ttype = string_or_char (len, tmp);
570 free (tmp);
571 return len == 1 ? SINGLECHAR : STRING;
572 case '\"':
573 tmp = readstring ('\"', &len);
574 yylval.ttype = build_chill_string (len, tmp);
575 free (tmp);
576 return STRING;
577 case '.':
578 nextc = input ();
579 unput (nextc);
580 if (ISDIGIT (nextc)) /* || nextc == '_') we don't start numbers with '_' */
581 goto number;
582 return DOT;
583 case '0': case '1': case '2': case '3': case '4':
584 case '5': case '6': case '7': case '8': case '9':
585 number:
586 yylval.ttype = read_number (ch);
587 return TREE_CODE (yylval.ttype) == REAL_CST ? FLOATING : NUMBER;
588 default:
589 return ch;
590 }
591 }
592
593 static void
594 close_input_file (fn)
595 char *fn;
596 {
597 if (finput == NULL)
598 abort ();
599
600 if (finput != stdin && fclose (finput) == EOF)
601 {
602 error ("can't close %s", fn);
603 abort ();
604 }
605 finput = NULL;
606 }
607
608 /* Return an identifier, starting with FIRST and then reading
609 more characters using input(). Return an IDENTIFIER_NODE. */
610
611 static tree
612 read_identifier (first)
613 int first; /* First letter of identifier */
614 {
615 tree id;
616 char *start;
617 for (;;)
618 {
619 obstack_1grow (&temporary_obstack, first);
620 first = input ();
621 if (first == EOF)
622 break;
623 if (! ISALNUM (first) && first != '_')
624 {
625 unput (first);
626 break;
627 }
628 }
629 obstack_1grow (&temporary_obstack, '\0');
630 start = obstack_finish (&temporary_obstack);
631 maybe_downcase (start);
632 id = get_identifier (start);
633 obstack_free (&temporary_obstack, start);
634 return id;
635 }
636
637 /* Given an identifier ID, check to see if it is a reserved name,
638 and return the appropriate token type. */
639
640 static int
641 handle_name (id)
642 tree id;
643 {
644 struct resword *tp;
645 tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
646 if (tp != NULL
647 && special_UC == ISUPPER ((unsigned char) tp->name[0])
648 && (tp->flags == RESERVED || tp->flags == PREDEF))
649 {
650 if (tp->rid != NORID)
651 yylval.ttype = ridpointers[tp->rid];
652 else if (tp->token == THIS)
653 yylval.ttype = lookup_name (get_identifier ("__whoami"));
654 return tp->token;
655 }
656 yylval.ttype = id;
657 return NAME;
658 }
659
660 static tree
661 read_number (ch)
662 int ch; /* Initial character */
663 {
664 tree num;
665 char *start;
666 int is_float = 0;
667 for (;;)
668 {
669 if (ch != '_')
670 obstack_1grow (&temporary_obstack, ch);
671 ch = input ();
672 if (! ISDIGIT (ch) && ch != '_')
673 break;
674 }
675 if (ch == '.')
676 {
677 do
678 {
679 if (ch != '_')
680 obstack_1grow (&temporary_obstack, ch);
681 ch = input ();
682 } while (ISDIGIT (ch) || ch == '_');
683 is_float++;
684 }
685 if (ch == 'd' || ch == 'D' || ch == 'e' || ch == 'E')
686 {
687 /* Convert exponent indication [eEdD] to 'e'. */
688 obstack_1grow (&temporary_obstack, 'e');
689 ch = input ();
690 if (ch == '+' || ch == '-')
691 {
692 obstack_1grow (&temporary_obstack, ch);
693 ch = input ();
694 }
695 if (ISDIGIT (ch) || ch == '_')
696 {
697 do
698 {
699 if (ch != '_')
700 obstack_1grow (&temporary_obstack, ch);
701 ch = input ();
702 } while (ISDIGIT (ch) || ch == '_');
703 }
704 else
705 {
706 error ("malformed exponent part of floating-point literal");
707 }
708 is_float++;
709 }
710 if (ch != EOF)
711 unput (ch);
712 obstack_1grow (&temporary_obstack, '\0');
713 start = obstack_finish (&temporary_obstack);
714 if (is_float)
715 {
716 REAL_VALUE_TYPE value;
717 tree type = double_type_node;
718 errno = 0;
719 value = REAL_VALUE_ATOF (start, TYPE_MODE (type));
720 obstack_free (&temporary_obstack, start);
721 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
722 && REAL_VALUE_ISINF (value) && pedantic)
723 pedwarn ("real number exceeds range of REAL");
724 num = build_real (type, value);
725 }
726 else
727 num = convert_integer (start);
728 CH_DERIVED_FLAG (num) = 1;
729 return num;
730 }
731
732 /* Skip to the end of a compiler directive. */
733
734 static void
735 skip_directive ()
736 {
737 int ch = input ();
738 for (;;)
739 {
740 if (ch == EOF)
741 {
742 error ("end-of-file in '<>' directive");
743 break;
744 }
745 if (ch == '\n')
746 break;
747 if (ch == '<')
748 {
749 ch = input ();
750 if (ch == '>')
751 break;
752 }
753 ch = input ();
754 }
755 starting_pass_2 = 0;
756 }
757
758 /* Read a compiler directive. ("<>{WS}" have already been read. ) */
759 static void
760 read_directive ()
761 {
762 struct resword *tp;
763 tree id;
764 int ch = skip_whitespace();
765 if (ISALPHA (ch) || ch == '_')
766 id = read_identifier (ch);
767 else if (ch == EOF)
768 {
769 error ("end-of-file in '<>' directive");
770 to_global_binding_level ();
771 return;
772 }
773 else
774 {
775 warning ("unrecognized compiler directive");
776 skip_directive ();
777 return;
778 }
779 tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
780 if (tp == NULL || special_UC != ISUPPER ((unsigned char) tp->name[0]))
781 {
782 if (pass == 1)
783 warning ("unrecognized compiler directive `%s'",
784 IDENTIFIER_POINTER (id));
785 }
786 else
787 switch (tp->token)
788 {
789 case ALL_STATIC_OFF:
790 all_static_flag = 0;
791 break;
792 case ALL_STATIC_ON:
793 all_static_flag = 1;
794 break;
795 case EMPTY_OFF:
796 empty_checking = 0;
797 break;
798 case EMPTY_ON:
799 empty_checking = 1;
800 break;
801 case IGNORED_DIRECTIVE:
802 break;
803 case PROCESS_TYPE_TOKEN:
804 process_type = equal_number ();
805 break;
806 case RANGE_OFF:
807 range_checking = 0;
808 break;
809 case RANGE_ON:
810 range_checking = 1;
811 break;
812 case SEND_SIGNAL_DEFAULT_PRIORITY:
813 send_signal_prio = equal_number ();
814 break;
815 case SEND_BUFFER_DEFAULT_PRIORITY:
816 send_buffer_prio = equal_number ();
817 break;
818 case SIGNAL_CODE:
819 signal_code = equal_number ();
820 break;
821 case USE_SEIZE_FILE:
822 handle_use_seizefile_directive (0);
823 break;
824 case USE_SEIZE_FILE_RESTRICTED:
825 handle_use_seizefile_directive (1);
826 break;
827 default:
828 if (pass == 1)
829 warning ("unrecognized compiler directive `%s'",
830 IDENTIFIER_POINTER (id));
831 break;
832 }
833 skip_directive ();
834 }
835
836 \f
837 tree
838 build_chill_string (len, str)
839 int len;
840 char *str;
841 {
842 tree t;
843
844 push_obstacks (&permanent_obstack, &permanent_obstack);
845 t = build_string (len, str);
846 TREE_TYPE (t) = build_string_type (char_type_node,
847 build_int_2 (len, 0));
848 CH_DERIVED_FLAG (t) = 1;
849 pop_obstacks ();
850 return t;
851 }
852
853
854 static tree
855 string_or_char (len, str)
856 int len;
857 char *str;
858 {
859 tree result;
860
861 push_obstacks (&permanent_obstack, &permanent_obstack);
862 if (len == 1)
863 {
864 result = build_int_2 ((unsigned char)str[0], 0);
865 CH_DERIVED_FLAG (result) = 1;
866 TREE_TYPE (result) = char_type_node;
867 }
868 else
869 result = build_chill_string (len, str);
870 pop_obstacks ();
871 return result;
872 }
873
874
875 static void
876 maybe_downcase (str)
877 char *str;
878 {
879 if (! ignore_case)
880 return;
881 while (*str)
882 {
883 if (ISUPPER ((unsigned char) *str))
884 *str = tolower ((unsigned char)*str);
885 str++;
886 }
887 }
888
889
890 static int
891 maybe_number (s)
892 char *s;
893 {
894 char fc;
895
896 /* check for decimal number */
897 if (*s >= '0' && *s <= '9')
898 {
899 while (*s)
900 {
901 if (*s >= '0' && *s <= '9')
902 s++;
903 else
904 return 0;
905 }
906 return 1;
907 }
908
909 fc = *s;
910 if (s[1] != '\'')
911 return 0;
912 s += 2;
913 while (*s)
914 {
915 switch (fc)
916 {
917 case 'd':
918 case 'D':
919 if (*s < '0' || *s > '9')
920 return 0;
921 break;
922 case 'h':
923 case 'H':
924 if (!ISXDIGIT ((unsigned char) *s))
925 return 0;
926 break;
927 case 'b':
928 case 'B':
929 if (*s < '0' || *s > '1')
930 return 0;
931 break;
932 case 'o':
933 case 'O':
934 if (*s < '0' || *s > '7')
935 return 0;
936 break;
937 default:
938 return 0;
939 }
940 s++;
941 }
942 return 1;
943 }
944 \f
945 static char *
946 readstring (terminator, len)
947 char terminator;
948 int *len;
949 {
950 int c;
951 unsigned allocated = 1024;
952 char *tmp = xmalloc (allocated);
953 unsigned i = 0;
954
955 for (;;)
956 {
957 c = input ();
958 if (c == terminator)
959 {
960 if ((c = input ()) != terminator)
961 {
962 unput (c);
963 break;
964 }
965 else
966 c = terminator;
967 }
968 if (c == '\n' || c == EOF)
969 goto unterminated;
970 if (c == '^')
971 {
972 c = input();
973 if (c == EOF || c == '\n')
974 goto unterminated;
975 if (c == '^')
976 goto storeit;
977 if (c == '(')
978 {
979 int cc, count = 0;
980 int base = 10;
981 int next_apos = 0;
982 int check_base = 1;
983 c = 0;
984 while (1)
985 {
986 cc = input ();
987 if (cc == terminator)
988 {
989 if (!(terminator == '\'' && next_apos))
990 {
991 error ("unterminated control sequence");
992 serious_errors++;
993 goto done;
994 }
995 }
996 if (cc == EOF || cc == '\n')
997 {
998 c = cc;
999 goto unterminated;
1000 }
1001 if (next_apos)
1002 {
1003 next_apos = 0;
1004 if (cc != '\'')
1005 {
1006 error ("invalid integer literal in control sequence");
1007 serious_errors++;
1008 goto done;
1009 }
1010 continue;
1011 }
1012 if (cc == ' ' || cc == '\t')
1013 continue;
1014 if (cc == ')')
1015 {
1016 if ((c < 0 || c > 255) && (pass == 1))
1017 error ("control sequence overflow");
1018 if (! count && pass == 1)
1019 error ("invalid control sequence");
1020 break;
1021 }
1022 else if (cc == ',')
1023 {
1024 if ((c < 0 || c > 255) && (pass == 1))
1025 error ("control sequence overflow");
1026 if (! count && pass == 1)
1027 error ("invalid control sequence");
1028 tmp[i++] = c;
1029 if (i == allocated)
1030 {
1031 allocated += 1024;
1032 tmp = xrealloc (tmp, allocated);
1033 }
1034 c = count = 0;
1035 base = 10;
1036 check_base = 1;
1037 continue;
1038 }
1039 else if (cc == '_')
1040 {
1041 if (! count && pass == 1)
1042 error ("invalid integer literal in control sequence");
1043 continue;
1044 }
1045 if (check_base)
1046 {
1047 if (cc == 'D' || cc == 'd')
1048 {
1049 base = 10;
1050 next_apos = 1;
1051 }
1052 else if (cc == 'H' || cc == 'h')
1053 {
1054 base = 16;
1055 next_apos = 1;
1056 }
1057 else if (cc == 'O' || cc == 'o')
1058 {
1059 base = 8;
1060 next_apos = 1;
1061 }
1062 else if (cc == 'B' || cc == 'b')
1063 {
1064 base = 2;
1065 next_apos = 1;
1066 }
1067 check_base = 0;
1068 if (next_apos)
1069 continue;
1070 }
1071 if (base == 2)
1072 {
1073 if (cc < '0' || cc > '1')
1074 cc = -1;
1075 else
1076 cc -= '0';
1077 }
1078 else if (base == 8)
1079 {
1080 if (cc < '0' || cc > '8')
1081 cc = -1;
1082 else
1083 cc -= '0';
1084 }
1085 else if (base == 10)
1086 {
1087 if (! ISDIGIT (cc))
1088 cc = -1;
1089 else
1090 cc -= '0';
1091 }
1092 else if (base == 16)
1093 {
1094 if (!ISXDIGIT (cc))
1095 cc = -1;
1096 else
1097 {
1098 if (cc >= 'a')
1099 cc -= ' ';
1100 cc -= '0';
1101 if (cc > 9)
1102 cc -= 7;
1103 }
1104 }
1105 else
1106 {
1107 error ("invalid base in read control sequence");
1108 abort ();
1109 }
1110 if (cc == -1)
1111 {
1112 /* error in control sequence */
1113 if (pass == 1)
1114 error ("invalid digit in control sequence");
1115 cc = 0;
1116 }
1117 c = (c * base) + cc;
1118 count++;
1119 }
1120 }
1121 else
1122 c ^= 64;
1123 }
1124 storeit:
1125 tmp[i++] = c;
1126 if (i == allocated)
1127 {
1128 allocated += 1024;
1129 tmp = xrealloc (tmp, allocated);
1130 }
1131 }
1132 done:
1133 tmp [*len = i] = '\0';
1134 return tmp;
1135
1136 unterminated:
1137 if (c == '\n')
1138 unput ('\n');
1139 *len = 1;
1140 if (pass == 1)
1141 error ("unterminated string literal");
1142 to_global_binding_level ();
1143 tmp[0] = '\0';
1144 return tmp;
1145 }
1146 \f
1147 /* Convert an integer INTCHARS into an INTEGER_CST.
1148 INTCHARS is on the temporary_obstack, and is popped by this function. */
1149
1150 static tree
1151 convert_integer (intchars)
1152 char *intchars;
1153 {
1154 #ifdef YYDEBUG
1155 extern int yydebug;
1156 #endif
1157 char *p = intchars;
1158 char *oldp = p;
1159 int base = 10, tmp;
1160 int valid_chars = 0;
1161 int overflow = 0;
1162 tree type;
1163 HOST_WIDE_INT val_lo = 0, val_hi = 0;
1164 tree val;
1165
1166 /* determine the base */
1167 switch (*p)
1168 {
1169 case 'd':
1170 case 'D':
1171 p += 2;
1172 break;
1173 case 'o':
1174 case 'O':
1175 p += 2;
1176 base = 8;
1177 break;
1178 case 'h':
1179 case 'H':
1180 p += 2;
1181 base = 16;
1182 break;
1183 case 'b':
1184 case 'B':
1185 p += 2;
1186 base = 2;
1187 break;
1188 default:
1189 if (!ISDIGIT (*p)) /* this test is for equal_number () */
1190 {
1191 obstack_free (&temporary_obstack, intchars);
1192 return 0;
1193 }
1194 break;
1195 }
1196
1197 while (*p)
1198 {
1199 tmp = *p++;
1200 if ((tmp == '\'') || (tmp == '_'))
1201 continue;
1202 if (tmp < '0')
1203 goto bad_char;
1204 if (tmp >= 'a') /* uppercase the char */
1205 tmp -= ' ';
1206 switch (base) /* validate the characters */
1207 {
1208 case 2:
1209 if (tmp > '1')
1210 goto bad_char;
1211 break;
1212 case 8:
1213 if (tmp > '7')
1214 goto bad_char;
1215 break;
1216 case 10:
1217 if (tmp > '9')
1218 goto bad_char;
1219 break;
1220 case 16:
1221 if (tmp > 'F')
1222 goto bad_char;
1223 if (tmp > '9' && tmp < 'A')
1224 goto bad_char;
1225 break;
1226 default:
1227 abort ();
1228 }
1229 tmp -= '0';
1230 if (tmp > 9)
1231 tmp -= 7;
1232 if (mul_double (val_lo, val_hi, base, 0, &val_lo, &val_hi))
1233 overflow++;
1234 add_double (val_lo, val_hi, tmp, 0, &val_lo, &val_hi);
1235 if (val_hi < 0)
1236 overflow++;
1237 valid_chars++;
1238 }
1239 bad_char:
1240 obstack_free (&temporary_obstack, intchars);
1241 if (!valid_chars)
1242 {
1243 if (pass == 2)
1244 error ("invalid number format `%s'", oldp);
1245 return 0;
1246 }
1247 val = build_int_2 (val_lo, val_hi);
1248 /* We set the type to long long (or long long unsigned) so that
1249 constant fold of literals is less likely to overflow. */
1250 if (int_fits_type_p (val, long_long_integer_type_node))
1251 type = long_long_integer_type_node;
1252 else
1253 {
1254 if (! int_fits_type_p (val, long_long_unsigned_type_node))
1255 overflow++;
1256 type = long_long_unsigned_type_node;
1257 }
1258 TREE_TYPE (val) = type;
1259 CH_DERIVED_FLAG (val) = 1;
1260
1261 if (overflow)
1262 error ("integer literal too big");
1263
1264 return val;
1265 }
1266 \f
1267 /* Convert a bitstring literal on the temporary_obstack to
1268 a bitstring CONSTRUCTOR. Free the literal from the obstack. */
1269
1270 static tree
1271 convert_bitstring (p)
1272 char *p;
1273 {
1274 #ifdef YYDEBUG
1275 extern int yydebug;
1276 #endif
1277 int bl = 0, valid_chars = 0, bits_per_char = 0, c, k;
1278 tree initlist = NULL_TREE;
1279 tree val;
1280
1281 /* Move p to stack so we can re-use temporary_obstack for result. */
1282 char *oldp = (char*) alloca (strlen (p) + 1);
1283 if (oldp == 0) fatal ("stack space exhausted");
1284 strcpy (oldp, p);
1285 obstack_free (&temporary_obstack, p);
1286 p = oldp;
1287
1288 switch (*p)
1289 {
1290 case 'h':
1291 case 'H':
1292 bits_per_char = 4;
1293 break;
1294 case 'o':
1295 case 'O':
1296 bits_per_char = 3;
1297 break;
1298 case 'b':
1299 case 'B':
1300 bits_per_char = 1;
1301 break;
1302 }
1303 p += 2;
1304
1305 while (*p)
1306 {
1307 c = *p++;
1308 if (c == '_' || c == '\'')
1309 continue;
1310 if (c >= 'a')
1311 c -= ' ';
1312 c -= '0';
1313 if (c > 9)
1314 c -= 7;
1315 valid_chars++;
1316
1317 for (k = BYTES_BIG_ENDIAN ? bits_per_char - 1 : 0;
1318 BYTES_BIG_ENDIAN ? k >= 0 : k < bits_per_char;
1319 bl++, BYTES_BIG_ENDIAN ? k-- : k++)
1320 {
1321 if (c & (1 << k))
1322 initlist = tree_cons (NULL_TREE, build_int_2 (bl, 0), initlist);
1323 }
1324 }
1325 #if 0
1326 /* as long as BOOLS(0) is valid it must tbe possible to
1327 specify an empty bitstring */
1328 if (!valid_chars)
1329 {
1330 if (pass == 2)
1331 error ("invalid number format `%s'", oldp);
1332 return 0;
1333 }
1334 #endif
1335 val = build (CONSTRUCTOR,
1336 build_bitstring_type (size_int (bl)),
1337 NULL_TREE, nreverse (initlist));
1338 TREE_CONSTANT (val) = 1;
1339 CH_DERIVED_FLAG (val) = 1;
1340 return val;
1341 }
1342 \f
1343 /* Check if two filenames name the same file.
1344 This is done by stat'ing both files and comparing their inodes.
1345
1346 Note: we have to take care of seize_path_list. Therefore do it the same
1347 way as in yywrap. FIXME: This probably can be done better. */
1348
1349 static int
1350 same_file (filename1, filename2)
1351 char *filename1;
1352 char *filename2;
1353 {
1354 struct stat s[2];
1355 char *fn_input[2];
1356 int i, stat_status;
1357
1358 if (grant_only_flag)
1359 /* do nothing in this case */
1360 return 0;
1361
1362 /* if filenames are equal -- return 1, cause there is no need
1363 to search in the include list in this case */
1364 if (strcmp (filename1, filename2) == 0)
1365 return 1;
1366
1367 fn_input[0] = filename1;
1368 fn_input[1] = filename2;
1369
1370 for (i = 0; i < 2; i++)
1371 {
1372 stat_status = stat (fn_input[i], &s[i]);
1373 if (stat_status < 0 &&
1374 strchr (fn_input[i], '/') == 0)
1375 {
1376 STRING_LIST *plp;
1377 char *path;
1378
1379 for (plp = seize_path_list; plp != 0; plp = plp->next)
1380 {
1381 path = (char *)xmalloc (strlen (fn_input[i]) +
1382 strlen (plp->str) + 2);
1383 sprintf (path, "%s/%s", plp->str, fn_input[i]);
1384 stat_status = stat (path, &s[i]);
1385 free (path);
1386 if (stat_status >= 0)
1387 break;
1388 }
1389 }
1390 if (stat_status < 0)
1391 pfatal_with_name (fn_input[i]);
1392 }
1393 return s[0].st_ino == s[1].st_ino && s[0].st_dev == s[1].st_dev;
1394 }
1395
1396 /*
1397 * Note that simply appending included file names to a list in this
1398 * way completely eliminates the need for nested files, and the
1399 * associated book-keeping, since the EOF processing in the lexer
1400 * will simply process the files one at a time, in the order that the
1401 * USE_SEIZE_FILE directives were scanned.
1402 */
1403 static void
1404 handle_use_seizefile_directive (restricted)
1405 int restricted;
1406 {
1407 tree seen;
1408 int len;
1409 int c = skip_whitespace ();
1410 char *use_seizefile_str = readstring (c, &len);
1411
1412 if (pass > 1)
1413 return;
1414
1415 if (c != '\'' && c != '\"')
1416 {
1417 error ("USE_SEIZE_FILE directive must be followed by string");
1418 return;
1419 }
1420
1421 use_seizefile_name = get_identifier (use_seizefile_str);
1422 CH_USE_SEIZEFILE_RESTRICTED (use_seizefile_name) = restricted;
1423
1424 if (!grant_only_flag)
1425 {
1426 /* If file foo.ch contains a <> use_seize_file "bar.grt" <>,
1427 and file bar.ch contains a <> use_seize_file "foo.grt" <>,
1428 then if we're compiling foo.ch, we will indirectly be
1429 asked to seize foo.grt. Don't. */
1430 extern char *grant_file_name;
1431 if (strcmp (use_seizefile_str, grant_file_name) == 0)
1432 return;
1433
1434 /* Check if the file is already on the list. */
1435 for (seen = files_to_seize; seen != NULL_TREE; seen = TREE_CHAIN (seen))
1436 if (same_file (IDENTIFIER_POINTER (TREE_VALUE (seen)),
1437 use_seizefile_str))
1438 return; /* Previously seen; nothing to do. */
1439 }
1440
1441 /* Haven't been asked to seize this file yet, so add
1442 its name to the list. */
1443 {
1444 tree pl = perm_tree_cons (0, use_seizefile_name, NULL_TREE);
1445 if (files_to_seize == NULL_TREE)
1446 files_to_seize = pl;
1447 else
1448 TREE_CHAIN (last_file_to_seize) = pl;
1449 if (next_file_to_seize == NULL_TREE)
1450 next_file_to_seize = pl;
1451 last_file_to_seize = pl;
1452 }
1453 }
1454
1455
1456 /*
1457 * get input, convert to lower case for comparison
1458 */
1459 int
1460 getlc (file)
1461 FILE *file;
1462 {
1463 register int c;
1464
1465 c = getc (file);
1466 if (ISUPPER (c) && ignore_case)
1467 c = tolower (c);
1468 return c;
1469 }
1470 \f
1471 #if defined HANDLE_PRAGMA
1472 /* Local versions of these macros, that can be passed as function pointers. */
1473 static int
1474 pragma_getc ()
1475 {
1476 return getc (finput);
1477 }
1478
1479 static void
1480 pragma_ungetc (arg)
1481 int arg;
1482 {
1483 ungetc (arg, finput);
1484 }
1485 #endif /* HANDLE_PRAGMA */
1486
1487 #ifdef HANDLE_GENERIC_PRAGMAS
1488 /* Handle a generic #pragma directive.
1489 BUFFER contains the text we read after `#pragma'. Processes the entire input
1490 line and return non-zero iff the pragma was successfully processed. */
1491
1492 static int
1493 handle_generic_pragma (buffer)
1494 char * buffer;
1495 {
1496 register int c;
1497
1498 for (;;)
1499 {
1500 char * buff;
1501
1502 handle_pragma_token (buffer, NULL);
1503
1504 c = getc (finput);
1505
1506 while (c == ' ' || c == '\t')
1507 c = getc (finput);
1508 ungetc (c, finput);
1509
1510 if (c == '\n' || c == EOF)
1511 return handle_pragma_token (NULL, NULL);
1512
1513 /* Read the next word of the pragma into the buffer. */
1514 buff = buffer;
1515 do
1516 {
1517 * buff ++ = c;
1518 c = getc (finput);
1519 }
1520 while (c != EOF && isascii (c) && ! isspace (c) && c != '\n'
1521 && buff < buffer + 128); /* XXX shared knowledge about size of buffer. */
1522
1523 ungetc (c, finput);
1524
1525 * -- buff = 0;
1526 }
1527 }
1528 #endif /* HANDLE_GENERIC_PRAGMAS */
1529 \f
1530 /* At the beginning of a line, increment the line number and process
1531 any #-directive on this line. If the line is a #-directive, read
1532 the entire line and return a newline. Otherwise, return the line's
1533 first non-whitespace character.
1534
1535 (Each language front end has a check_newline() function that is called
1536 from lang_init() for that language. One of the things this function
1537 must do is read the first line of the input file, and if it is a #line
1538 directive, extract the filename from it and use it to initialize
1539 main_input_filename. Proper generation of debugging information in
1540 the normal "front end calls cpp then calls cc1XXXX environment" depends
1541 upon this being done.) */
1542
1543 int
1544 check_newline ()
1545 {
1546 register int c;
1547
1548 lineno++;
1549
1550 /* Read first nonwhite char on the line. */
1551
1552 c = getc (finput);
1553
1554 while (c == ' ' || c == '\t')
1555 c = getc (finput);
1556
1557 if (c != '#' || inside_c_comment)
1558 {
1559 /* If not #, return it so caller will use it. */
1560 return c;
1561 }
1562
1563 /* Read first nonwhite char after the `#'. */
1564
1565 c = getc (finput);
1566 while (c == ' ' || c == '\t')
1567 c = getc (finput);
1568
1569 /* If a letter follows, then if the word here is `line', skip
1570 it and ignore it; otherwise, ignore the line, with an error
1571 if the word isn't `pragma', `ident', `define', or `undef'. */
1572
1573 if (ISUPPER (c) && ignore_case)
1574 c = tolower (c);
1575
1576 if (c >= 'a' && c <= 'z')
1577 {
1578 if (c == 'p')
1579 {
1580 if (getlc (finput) == 'r'
1581 && getlc (finput) == 'a'
1582 && getlc (finput) == 'g'
1583 && getlc (finput) == 'm'
1584 && getlc (finput) == 'a'
1585 && (c = getlc (finput), ISSPACE (c)))
1586 {
1587 #ifdef HANDLE_PRAGMA
1588 static char buffer [128];
1589 char * buff = buffer;
1590
1591 /* Read the pragma name into a buffer. */
1592 while (c = getlc (finput), ISSPACE (c))
1593 continue;
1594
1595 do
1596 {
1597 * buff ++ = c;
1598 c = getlc (finput);
1599 }
1600 while (c != EOF && ! ISSPACE (c) && c != '\n'
1601 && buff < buffer + 128);
1602
1603 pragma_ungetc (c);
1604
1605 * -- buff = 0;
1606
1607 if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
1608 goto skipline;
1609 #endif /* HANDLE_PRAGMA */
1610
1611 #ifdef HANDLE_GENERIC_PRAGMAS
1612 if (handle_generic_pragma (buffer))
1613 goto skipline;
1614 #endif /* HANDLE_GENERIC_PRAGMAS */
1615
1616 goto skipline;
1617 }
1618 }
1619
1620 else if (c == 'd')
1621 {
1622 if (getlc (finput) == 'e'
1623 && getlc (finput) == 'f'
1624 && getlc (finput) == 'i'
1625 && getlc (finput) == 'n'
1626 && getlc (finput) == 'e'
1627 && (c = getlc (finput), ISSPACE (c)))
1628 {
1629 #if 0 /*def DWARF_DEBUGGING_INFO*/
1630 if (c != '\n'
1631 && (debug_info_level == DINFO_LEVEL_VERBOSE)
1632 && (write_symbols == DWARF_DEBUG))
1633 dwarfout_define (lineno, get_directive_line (finput));
1634 #endif /* DWARF_DEBUGGING_INFO */
1635 goto skipline;
1636 }
1637 }
1638 else if (c == 'u')
1639 {
1640 if (getlc (finput) == 'n'
1641 && getlc (finput) == 'd'
1642 && getlc (finput) == 'e'
1643 && getlc (finput) == 'f'
1644 && (c = getlc (finput), ISSPACE (c)))
1645 {
1646 #if 0 /*def DWARF_DEBUGGING_INFO*/
1647 if (c != '\n'
1648 && (debug_info_level == DINFO_LEVEL_VERBOSE)
1649 && (write_symbols == DWARF_DEBUG))
1650 dwarfout_undef (lineno, get_directive_line (finput));
1651 #endif /* DWARF_DEBUGGING_INFO */
1652 goto skipline;
1653 }
1654 }
1655 else if (c == 'l')
1656 {
1657 if (getlc (finput) == 'i'
1658 && getlc (finput) == 'n'
1659 && getlc (finput) == 'e'
1660 && ((c = getlc (finput)) == ' ' || c == '\t'))
1661 goto linenum;
1662 }
1663 #if 0
1664 else if (c == 'i')
1665 {
1666 if (getlc (finput) == 'd'
1667 && getlc (finput) == 'e'
1668 && getlc (finput) == 'n'
1669 && getlc (finput) == 't'
1670 && ((c = getlc (finput)) == ' ' || c == '\t'))
1671 {
1672 /* #ident. The pedantic warning is now in cccp.c. */
1673
1674 /* Here we have just seen `#ident '.
1675 A string constant should follow. */
1676
1677 while (c == ' ' || c == '\t')
1678 c = getlc (finput);
1679
1680 /* If no argument, ignore the line. */
1681 if (c == '\n')
1682 return c;
1683
1684 ungetc (c, finput);
1685 token = yylex ();
1686 if (token != STRING
1687 || TREE_CODE (yylval.ttype) != STRING_CST)
1688 {
1689 error ("invalid #ident");
1690 goto skipline;
1691 }
1692
1693 if (!flag_no_ident)
1694 {
1695 #ifdef ASM_OUTPUT_IDENT
1696 extern FILE *asm_out_file;
1697 ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
1698 #endif
1699 }
1700
1701 /* Skip the rest of this line. */
1702 goto skipline;
1703 }
1704 }
1705 #endif
1706
1707 error ("undefined or invalid # directive");
1708 goto skipline;
1709 }
1710
1711 linenum:
1712 /* Here we have either `#line' or `# <nonletter>'.
1713 In either case, it should be a line number; a digit should follow. */
1714
1715 while (c == ' ' || c == '\t')
1716 c = getlc (finput);
1717
1718 /* If the # is the only nonwhite char on the line,
1719 just ignore it. Check the new newline. */
1720 if (c == '\n')
1721 return c;
1722
1723 /* Something follows the #; read a token. */
1724
1725 if (ISDIGIT(c))
1726 {
1727 int old_lineno = lineno;
1728 int used_up = 0;
1729 int l = 0;
1730 extern struct obstack permanent_obstack;
1731
1732 do
1733 {
1734 l = l * 10 + (c - '0'); /* FIXME Not portable */
1735 c = getlc(finput);
1736 } while (ISDIGIT(c));
1737 /* subtract one, because it is the following line that
1738 gets the specified number */
1739
1740 l--;
1741
1742 /* Is this the last nonwhite stuff on the line? */
1743 c = getlc (finput);
1744 while (c == ' ' || c == '\t')
1745 c = getlc (finput);
1746 if (c == '\n')
1747 {
1748 /* No more: store the line number and check following line. */
1749 lineno = l;
1750 return c;
1751 }
1752
1753 /* More follows: it must be a string constant (filename). */
1754
1755 /* Read the string constant, but don't treat \ as special. */
1756 ignore_escape_flag = 1;
1757 ignore_escape_flag = 0;
1758
1759 if (c != '\"')
1760 {
1761 error ("invalid #line");
1762 goto skipline;
1763 }
1764
1765 for (;;)
1766 {
1767 c = getc (finput);
1768 if (c == EOF || c == '\n')
1769 {
1770 error ("invalid #line");
1771 return c;
1772 }
1773 if (c == '\"')
1774 {
1775 obstack_1grow(&permanent_obstack, 0);
1776 input_filename = obstack_finish (&permanent_obstack);
1777 break;
1778 }
1779 obstack_1grow(&permanent_obstack, c);
1780 }
1781
1782 lineno = l;
1783
1784 /* Each change of file name
1785 reinitializes whether we are now in a system header. */
1786 in_system_header = 0;
1787
1788 if (main_input_filename == 0)
1789 main_input_filename = input_filename;
1790
1791 /* Is this the last nonwhite stuff on the line? */
1792 c = getlc (finput);
1793 while (c == ' ' || c == '\t')
1794 c = getlc (finput);
1795 if (c == '\n')
1796 return c;
1797
1798 used_up = 0;
1799
1800 /* `1' after file name means entering new file.
1801 `2' after file name means just left a file. */
1802
1803 if (ISDIGIT (c))
1804 {
1805 if (c == '1')
1806 {
1807 /* Pushing to a new file. */
1808 struct file_stack *p
1809 = (struct file_stack *) xmalloc (sizeof (struct file_stack));
1810 input_file_stack->line = old_lineno;
1811 p->next = input_file_stack;
1812 p->name = input_filename;
1813 input_file_stack = p;
1814 input_file_stack_tick++;
1815 #ifdef DWARF_DEBUGGING_INFO
1816 if (debug_info_level == DINFO_LEVEL_VERBOSE
1817 && write_symbols == DWARF_DEBUG)
1818 dwarfout_start_new_source_file (input_filename);
1819 #endif /* DWARF_DEBUGGING_INFO */
1820
1821 used_up = 1;
1822 }
1823 else if (c == '2')
1824 {
1825 /* Popping out of a file. */
1826 if (input_file_stack->next)
1827 {
1828 struct file_stack *p = input_file_stack;
1829 input_file_stack = p->next;
1830 free (p);
1831 input_file_stack_tick++;
1832 #ifdef DWARF_DEBUGGING_INFO
1833 if (debug_info_level == DINFO_LEVEL_VERBOSE
1834 && write_symbols == DWARF_DEBUG)
1835 dwarfout_resume_previous_source_file (input_file_stack->line);
1836 #endif /* DWARF_DEBUGGING_INFO */
1837 }
1838 else
1839 error ("#-lines for entering and leaving files don't match");
1840
1841 used_up = 1;
1842 }
1843 }
1844
1845 /* If we have handled a `1' or a `2',
1846 see if there is another number to read. */
1847 if (used_up)
1848 {
1849 /* Is this the last nonwhite stuff on the line? */
1850 c = getlc (finput);
1851 while (c == ' ' || c == '\t')
1852 c = getlc (finput);
1853 if (c == '\n')
1854 return c;
1855 used_up = 0;
1856 }
1857
1858 /* `3' after file name means this is a system header file. */
1859
1860 if (c == '3')
1861 in_system_header = 1;
1862 }
1863 else
1864 error ("invalid #-line");
1865
1866 /* skip the rest of this line. */
1867 skipline:
1868 while (c != '\n' && c != EOF)
1869 c = getc (finput);
1870 return c;
1871 }
1872
1873
1874 tree
1875 get_chill_filename ()
1876 {
1877 return (build_chill_string (
1878 strlen (input_filename) + 1, /* +1 to get a zero terminated string */
1879 input_filename));
1880 }
1881
1882 tree
1883 get_chill_linenumber ()
1884 {
1885 return build_int_2 ((HOST_WIDE_INT)lineno, 0);
1886 }
1887
1888
1889 /* Assuming '/' and '*' have been read, skip until we've
1890 read the terminating '*' and '/'. */
1891
1892 static void
1893 skip_c_comment ()
1894 {
1895 int c = input();
1896 int start_line = lineno;
1897
1898 inside_c_comment++;
1899 for (;;)
1900 if (c == EOF)
1901 {
1902 error_with_file_and_line (input_filename, start_line,
1903 "unterminated comment");
1904 break;
1905 }
1906 else if (c != '*')
1907 c = input();
1908 else if ((c = input ()) == '/')
1909 break;
1910 inside_c_comment--;
1911 }
1912
1913
1914 /* Assuming "--" has been read, skip until '\n'. */
1915
1916 static void
1917 skip_line_comment ()
1918 {
1919 for (;;)
1920 {
1921 int c = input ();
1922
1923 if (c == EOF)
1924 return;
1925 if (c == '\n')
1926 break;
1927 }
1928 unput ('\n');
1929 }
1930
1931
1932 static int
1933 skip_whitespace ()
1934 {
1935 for (;;)
1936 {
1937 int c = input ();
1938
1939 if (c == EOF)
1940 return c;
1941 if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v')
1942 continue;
1943 if (c == '/')
1944 {
1945 c = input ();
1946 if (c == '*')
1947 {
1948 skip_c_comment ();
1949 continue;
1950 }
1951 else
1952 {
1953 unput (c);
1954 return '/';
1955 }
1956 }
1957 if (c == '-')
1958 {
1959 c = input ();
1960 if (c == '-')
1961 {
1962 skip_line_comment ();
1963 continue;
1964 }
1965 else
1966 {
1967 unput (c);
1968 return '-';
1969 }
1970 }
1971 return c;
1972 }
1973 }
1974 \f
1975 /*
1976 * avoid recursive calls to yylex to parse the ' = digits' or
1977 * ' = SYNvalue' which are supposed to follow certain compiler
1978 * directives. Read the input stream, and return the value parsed.
1979 */
1980 /* FIXME: overflow check in here */
1981 /* FIXME: check for EOF around here */
1982 static tree
1983 equal_number ()
1984 {
1985 int c, result;
1986 char *tokenbuf;
1987 char *cursor;
1988 tree retval = integer_zero_node;
1989
1990 c = skip_whitespace();
1991 if ((char)c != '=')
1992 {
1993 if (pass == 2)
1994 error ("missing `=' in compiler directive");
1995 return integer_zero_node;
1996 }
1997 c = skip_whitespace();
1998
1999 /* collect token into tokenbuf for later analysis */
2000 while (TRUE)
2001 {
2002 if (ISSPACE (c) || c == '<')
2003 break;
2004 obstack_1grow (&temporary_obstack, c);
2005 c = input ();
2006 }
2007 unput (c); /* put uninteresting char back */
2008 obstack_1grow (&temporary_obstack, '\0'); /* terminate token */
2009 tokenbuf = obstack_finish (&temporary_obstack);
2010 maybe_downcase (tokenbuf);
2011
2012 if (*tokenbuf == '-')
2013 /* will fail in the next test */
2014 result = BITSTRING;
2015 else if (maybe_number (tokenbuf))
2016 {
2017 if (pass == 1)
2018 return integer_zero_node;
2019 push_obstacks_nochange ();
2020 end_temporary_allocation ();
2021 yylval.ttype = convert_integer (tokenbuf);
2022 tokenbuf = 0; /* Was freed by convert_integer. */
2023 result = yylval.ttype ? NUMBER : 0;
2024 pop_obstacks ();
2025 }
2026 else
2027 result = 0;
2028
2029 if (result == NUMBER)
2030 {
2031 retval = yylval.ttype;
2032 }
2033 else if (result == BITSTRING)
2034 {
2035 if (pass == 1)
2036 error ("invalid value follows `=' in compiler directive");
2037 goto finish;
2038 }
2039 else /* not a number */
2040 {
2041 cursor = tokenbuf;
2042 c = *cursor;
2043 if (!ISALPHA (c) && c != '_')
2044 {
2045 if (pass == 1)
2046 error ("invalid value follows `=' in compiler directive");
2047 goto finish;
2048 }
2049
2050 for (cursor = &tokenbuf[1]; *cursor != '\0'; cursor++)
2051 if (ISALPHA ((unsigned char) *cursor) || *cursor == '_' ||
2052 ISDIGIT (*cursor))
2053 continue;
2054 else
2055 {
2056 if (pass == 1)
2057 error ("invalid `%c' character in name", *cursor);
2058 goto finish;
2059 }
2060 if (pass == 1)
2061 goto finish;
2062 else
2063 {
2064 tree value = lookup_name (get_identifier (tokenbuf));
2065 if (value == NULL_TREE
2066 || TREE_CODE (value) != CONST_DECL
2067 || TREE_CODE (DECL_INITIAL (value)) != INTEGER_CST)
2068 {
2069 if (pass == 2)
2070 error ("`%s' not integer constant synonym ",
2071 tokenbuf);
2072 goto finish;
2073 }
2074 obstack_free (&temporary_obstack, tokenbuf);
2075 tokenbuf = 0;
2076 push_obstacks_nochange ();
2077 end_temporary_allocation ();
2078 retval = convert (chill_taskingcode_type_node, DECL_INITIAL (value));
2079 pop_obstacks ();
2080 }
2081 }
2082
2083 /* check the value */
2084 if (TREE_CODE (retval) != INTEGER_CST)
2085 {
2086 if (pass == 2)
2087 error ("invalid value follows `=' in compiler directive");
2088 }
2089 else if (TREE_INT_CST_HIGH (retval) != 0 ||
2090 TREE_INT_CST_LOW (retval) > TREE_INT_CST_LOW (TYPE_MAX_VALUE (chill_unsigned_type_node)))
2091 {
2092 if (pass == 2)
2093 error ("value out of range in compiler directive");
2094 }
2095 finish:
2096 if (tokenbuf)
2097 obstack_free (&temporary_obstack, tokenbuf);
2098 return retval;
2099 }
2100 \f
2101 /*
2102 * add a possible grant-file path to the list
2103 */
2104 void
2105 register_seize_path (path)
2106 char *path;
2107 {
2108 int pathlen = strlen (path);
2109 char *new_path = (char *)xmalloc (pathlen + 1);
2110 STRING_LIST *pl = (STRING_LIST *)xmalloc (sizeof (STRING_LIST));
2111
2112 /* strip off trailing slash if any */
2113 if (path[pathlen - 1] == '/')
2114 pathlen--;
2115
2116 memcpy (new_path, path, pathlen);
2117 pl->str = new_path;
2118 pl->next = seize_path_list;
2119 seize_path_list = pl;
2120 }
2121
2122
2123 /* Used by decode_decl to indicate that a <> use_seize_file NAME <>
2124 directive has been written to the grantfile. */
2125
2126 void
2127 mark_use_seizefile_written (name)
2128 tree name;
2129 {
2130 tree node;
2131
2132 for (node = files_to_seize; node != NULL_TREE; node = TREE_CHAIN (node))
2133 if (TREE_VALUE (node) == name)
2134 {
2135 TREE_PURPOSE (node) = integer_one_node;
2136 break;
2137 }
2138 }
2139
2140
2141 static int
2142 yywrap ()
2143 {
2144 extern char *chill_real_input_filename;
2145
2146 close_input_file (input_filename);
2147
2148 use_seizefile_name = NULL_TREE;
2149
2150 if (next_file_to_seize && !grant_only_flag)
2151 {
2152 FILE *grt_in = NULL;
2153 char *seizefile_name_chars
2154 = IDENTIFIER_POINTER (TREE_VALUE (next_file_to_seize));
2155
2156 /* find a seize file, open it. If it's not at the path the
2157 * user gave us, and that path contains no slashes, look on
2158 * the seize_file paths, specified by the '-I' options.
2159 */
2160 grt_in = fopen (seizefile_name_chars, "r");
2161 if (grt_in == NULL
2162 && strchr (seizefile_name_chars, '/') == NULL)
2163 {
2164 STRING_LIST *plp;
2165 char *path;
2166
2167 for (plp = seize_path_list; plp != NULL; plp = plp->next)
2168 {
2169 path = (char *)xmalloc (strlen (seizefile_name_chars)
2170 + strlen (plp->str) + 2);
2171
2172 sprintf (path, "%s/%s", plp->str, seizefile_name_chars);
2173 grt_in = fopen (path, "r");
2174 if (grt_in == NULL)
2175 free (path);
2176 else
2177 {
2178 seizefile_name_chars = path;
2179 break;
2180 }
2181 }
2182 }
2183
2184 if (grt_in == NULL)
2185 pfatal_with_name (seizefile_name_chars);
2186
2187 finput = grt_in;
2188 input_filename = seizefile_name_chars;
2189
2190 lineno = 0;
2191 current_seizefile_name = TREE_VALUE (next_file_to_seize);
2192
2193 next_file_to_seize = TREE_CHAIN (next_file_to_seize);
2194
2195 saw_eof = 0;
2196 return 0;
2197 }
2198
2199 if (pass == 1)
2200 {
2201 next_file_to_seize = files_to_seize;
2202 current_seizefile_name = NULL_TREE;
2203
2204 if (strcmp (main_input_filename, "stdin"))
2205 finput = fopen (chill_real_input_filename, "r");
2206 else
2207 finput = stdin;
2208 if (finput == NULL)
2209 {
2210 error ("can't reopen %s", chill_real_input_filename);
2211 return 1;
2212 }
2213 input_filename = main_input_filename;
2214 ch_lex_init ();
2215 lineno = 0;
2216 /* Read a line directive if there is one. */
2217 ungetc (check_newline (), finput);
2218 starting_pass_2 = 1;
2219 saw_eof = 0;
2220 if (module_number == 0)
2221 warning ("no modules seen");
2222 return 0;
2223 }
2224 return 1;
2225 }