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