1 /* Lexical analyzer for GNU CHILL. -*- C -*-
2 Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
38 #ifdef MULTIBYTE_CHARS
42 /* include the keyword recognizers */
48 static int last_token = 0;
49 /* Sun's C compiler warns about the safer sequence
51 when there's a 'return' inside the braces, so don't use it */
52 #define RETURN_TOKEN(X) { last_token = X; return (X); }
55 /* This is set non-zero to force incoming tokens to lowercase. */
56 extern int ignore_case;
58 extern int module_number;
59 extern int serious_errors;
61 /* This is non-zero to recognize only uppercase special words. */
62 extern int special_UC;
64 extern struct obstack permanent_obstack;
65 extern struct obstack temporary_obstack;
67 /* forward declarations */
68 static void close_input_file PARAMS ((const char *));
69 static tree convert_bitstring PARAMS ((char *));
70 static tree convert_integer PARAMS ((char *));
71 static void maybe_downcase PARAMS ((char *));
72 static int maybe_number PARAMS ((const char *));
73 static tree equal_number PARAMS ((void));
74 static void handle_use_seizefile_directive PARAMS ((int));
75 static int handle_name PARAMS ((tree));
76 static char *readstring PARAMS ((int, int *));
77 static void read_directive PARAMS ((void));
78 static tree read_identifier PARAMS ((int));
79 static tree read_number PARAMS ((int));
80 static void skip_c_comment PARAMS ((void));
81 static void skip_line_comment PARAMS ((void));
82 static int skip_whitespace PARAMS ((void));
83 static tree string_or_char PARAMS ((int, const char *));
84 static void ch_lex_init PARAMS ((void));
85 static void skip_directive PARAMS ((void));
86 static int same_file PARAMS ((const char *, const char *));
87 static int getlc PARAMS ((FILE *));
89 /* next variables are public, because ch-actions uses them */
91 /* the default grantfile name, set by lang_init */
92 tree default_grant_file = 0;
94 /* These tasking-related variables are NULL at the start of each
95 compiler pass, and are set to an expression tree if and when
96 a compiler directive is parsed containing an expression.
97 The NULL state is significant; it means 'no user-specified
98 signal_code (or whatever) has been parsed'. */
100 /* process type, set by <> PROCESS_TYPE = number <> */
101 tree process_type = NULL_TREE;
103 /* send buffer default priority,
104 set by <> SEND_BUFFER_DEFAULT_PRIORITY = number <> */
105 tree send_buffer_prio = NULL_TREE;
107 /* send signal default priority,
108 set by <> SEND_SIGNAL_DEFAULT_PRIORITY = number <> */
109 tree send_signal_prio = NULL_TREE;
111 /* signal code, set by <> SIGNAL_CODE = number <> */
112 tree signal_code = NULL_TREE;
114 /* flag for range checking */
115 int range_checking = 1;
117 /* flag for NULL pointer checking */
118 int empty_checking = 1;
120 /* flag to indicate making all procedure local variables
122 int all_static_flag = 0;
124 /* flag to indicate -fruntime-checking command line option.
125 Needed for initializing range_checking and empty_checking
127 int runtime_checking_flag = 1;
129 /* The elements of `ridpointers' are identifier nodes
130 for the reserved type names and storage classes.
131 It is indexed by a RID_... value. */
132 tree ridpointers[(int) RID_MAX];
134 /* Nonzero tells yylex to ignore \ in string constants. */
135 static int ignore_escape_flag = 0;
137 static int maxtoken; /* Current nominal length of token buffer. */
138 char *token_buffer; /* Pointer to token buffer.
139 Actual allocated length is maxtoken + 2.
140 This is not static because objc-parse.y uses it. */
142 /* implement yylineno handling for flex */
143 #define yylineno lineno
145 static int inside_c_comment = 0;
147 static int saw_eol = 0; /* 1 if we've just seen a '\n' */
148 static int saw_eof = 0; /* 1 if we've just seen an EOF */
150 typedef struct string_list
152 struct string_list *next;
156 /* list of paths specified on the compiler command line by -L options. */
157 static STRING_LIST *seize_path_list = (STRING_LIST *)0;
159 /* List of seize file names. Each TREE_VALUE is an identifier
160 (file name) from a <>USE_SEIZE_FILE<> directive.
161 The TREE_PURPOSE is non-NULL if a USE_SEIZE_FILE directive has been
162 written to the grant file. */
163 static tree files_to_seize = NULL_TREE;
164 /* Last node on files_to_seize list. */
165 static tree last_file_to_seize = NULL_TREE;
166 /* Pointer into files_to_seize list: Next unparsed file to read. */
167 static tree next_file_to_seize = NULL_TREE;
169 /* The most recent use_seize_file directive. */
170 tree use_seizefile_name = NULL_TREE;
172 /* If non-NULL, the name of the seizefile we're currently processing. */
173 tree current_seizefile_name = NULL_TREE;
175 /* called to reset for pass 2 */
179 current_seizefile_name = NULL_TREE;
185 /* Initialize these compiler-directive variables. */
186 process_type = NULL_TREE;
187 send_buffer_prio = NULL_TREE;
188 send_signal_prio = NULL_TREE;
189 signal_code = NULL_TREE;
191 /* reinitialize rnage checking and empty checking */
192 range_checking = runtime_checking_flag;
193 empty_checking = runtime_checking_flag;
198 init_parse (filename)
199 const char *filename;
201 int lowercase_standard_names = ignore_case || ! special_UC;
203 /* Open input file. */
204 if (filename == 0 || !strcmp (filename, "-"))
210 finput = fopen (filename, "r");
213 fatal_io_error ("can't open %s", filename);
215 #ifdef IO_BUFFER_SIZE
216 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
219 /* Make identifier nodes long enough for the language-specific slots. */
220 set_identifier_size (sizeof (struct lang_identifier));
222 /* Start it at 0, because check_newline is called at the very beginning
223 and will increment it to 1. */
226 /* Initialize these compiler-directive variables. */
227 process_type = NULL_TREE;
228 send_buffer_prio = NULL_TREE;
229 send_signal_prio = NULL_TREE;
230 signal_code = NULL_TREE;
233 token_buffer = xmalloc ((unsigned)(maxtoken + 2));
235 init_chill_expand ();
237 #define ENTER_STANDARD_NAME(RID, LOWER, UPPER) \
238 ridpointers[(int) RID] = \
239 get_identifier (lowercase_standard_names ? LOWER : UPPER)
241 ENTER_STANDARD_NAME (RID_ALL, "all", "ALL");
242 ENTER_STANDARD_NAME (RID_ASSERTFAIL, "assertfail", "ASSERTFAIL");
243 ENTER_STANDARD_NAME (RID_ASSOCIATION, "association", "ASSOCIATION");
244 ENTER_STANDARD_NAME (RID_BIN, "bin", "BIN");
245 ENTER_STANDARD_NAME (RID_BOOL, "bool", "BOOL");
246 ENTER_STANDARD_NAME (RID_BOOLS, "bools", "BOOLS");
247 ENTER_STANDARD_NAME (RID_BYTE, "byte", "BYTE");
248 ENTER_STANDARD_NAME (RID_CHAR, "char", "CHAR");
249 ENTER_STANDARD_NAME (RID_DOUBLE, "double", "DOUBLE");
250 ENTER_STANDARD_NAME (RID_DURATION, "duration", "DURATION");
251 ENTER_STANDARD_NAME (RID_DYNAMIC, "dynamic", "DYNAMIC");
252 ENTER_STANDARD_NAME (RID_ELSE, "else", "ELSE");
253 ENTER_STANDARD_NAME (RID_EMPTY, "empty", "EMPTY");
254 ENTER_STANDARD_NAME (RID_FALSE, "false", "FALSE");
255 ENTER_STANDARD_NAME (RID_FLOAT, "float", "FLOAT");
256 ENTER_STANDARD_NAME (RID_GENERAL, "general", "GENERAL");
257 ENTER_STANDARD_NAME (RID_IN, "in", "IN");
258 ENTER_STANDARD_NAME (RID_INLINE, "inline", "INLINE");
259 ENTER_STANDARD_NAME (RID_INOUT, "inout", "INOUT");
260 ENTER_STANDARD_NAME (RID_INSTANCE, "instance", "INSTANCE");
261 ENTER_STANDARD_NAME (RID_INT, "int", "INT");
262 ENTER_STANDARD_NAME (RID_LOC, "loc", "LOC");
263 ENTER_STANDARD_NAME (RID_LONG, "long", "LONG");
264 ENTER_STANDARD_NAME (RID_LONG_REAL, "long_real", "LONG_REAL");
265 ENTER_STANDARD_NAME (RID_NULL, "null", "NULL");
266 ENTER_STANDARD_NAME (RID_OUT, "out", "OUT");
267 ENTER_STANDARD_NAME (RID_OVERFLOW, "overflow", "OVERFLOW");
268 ENTER_STANDARD_NAME (RID_PTR, "ptr", "PTR");
269 ENTER_STANDARD_NAME (RID_READ, "read", "READ");
270 ENTER_STANDARD_NAME (RID_REAL, "real", "REAL");
271 ENTER_STANDARD_NAME (RID_RANGE, "range", "RANGE");
272 ENTER_STANDARD_NAME (RID_RANGEFAIL, "rangefail", "RANGEFAIL");
273 ENTER_STANDARD_NAME (RID_RECURSIVE, "recursive", "RECURSIVE");
274 ENTER_STANDARD_NAME (RID_SHORT, "short", "SHORT");
275 ENTER_STANDARD_NAME (RID_SIMPLE, "simple", "SIMPLE");
276 ENTER_STANDARD_NAME (RID_TIME, "time", "TIME");
277 ENTER_STANDARD_NAME (RID_TRUE, "true", "TRUE");
278 ENTER_STANDARD_NAME (RID_UBYTE, "ubyte", "UBYTE");
279 ENTER_STANDARD_NAME (RID_UINT, "uint", "UINT");
280 ENTER_STANDARD_NAME (RID_ULONG, "ulong", "ULONG");
281 ENTER_STANDARD_NAME (RID_UNSIGNED, "unsigned", "UNSIGNED");
282 ENTER_STANDARD_NAME (RID_USHORT, "ushort", "USHORT");
283 ENTER_STANDARD_NAME (RID_VOID, "void", "VOID");
295 static int yywrap PARAMS ((void));
296 static int yy_refill PARAMS ((void));
298 #define YY_PUTBACK_SIZE 5
299 #define YY_BUF_SIZE 1000
301 static char yy_buffer[YY_PUTBACK_SIZE + YY_BUF_SIZE];
302 static char *yy_cur = yy_buffer + YY_PUTBACK_SIZE;
303 static char *yy_lim = yy_buffer + YY_PUTBACK_SIZE;
308 char *buf = yy_buffer + YY_PUTBACK_SIZE;
310 bcopy (yy_cur - YY_PUTBACK_SIZE, yy_buffer, YY_PUTBACK_SIZE);
325 c = check_newline ();
338 while (result < YY_BUF_SIZE)
348 /* Because we might switch input files on a compiler directive
349 (that end with '>', don't read past a '>', just in case. */
358 fprintf (stderr, "-------------------------- finished Line %d\n",
366 yy_lim = yy_cur + result;
368 return yy_lim > yy_cur ? *yy_cur++ : EOF;
371 #define input() (yy_cur < yy_lim ? *yy_cur++ : yy_refill ())
373 #define unput(c) (*--yy_cur = (c))
376 int starting_pass_2 = 0;
396 case ' ': case '\t': case '\n': case '\f': case '\b': case '\v': case '\r':
418 else if (nextc == '=')
434 skip_line_comment ();
447 else if (nextc == '=')
449 else if (nextc == '*')
492 int len = 0; /* Number of hex digits seen. */
500 if (!ISXDIGIT (ch)) /* error on non-hex digit */
503 error ("invalid C'xx' ");
514 if (len & 1) /* collected two digits, save byte */
515 obstack_1grow (&temporary_obstack, (char) byte_val);
518 start = obstack_finish (&temporary_obstack);
519 yylval.ttype = string_or_char (len >> 1, start);
520 obstack_free (&temporary_obstack, start);
521 return len == 2 ? SINGLECHAR : STRING;
531 obstack_1grow (&temporary_obstack, ch);
532 obstack_1grow (&temporary_obstack, nextc);
537 obstack_1grow (&temporary_obstack, ch);
541 obstack_1grow (&temporary_obstack, '\0');
542 start = obstack_finish (&temporary_obstack);
546 yylval.ttype = convert_integer (start); /* Pass base? */
551 yylval.ttype = convert_bitstring (start);
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':
565 case 'f': case 'g': case 'i': case 'j':
566 case 'k': case 'l': case 'm': case 'n':
567 case 'p': case 'q': case 'r': case 's': case 't':
568 case 'u': case 'v': case 'w': case 'x': case 'y':
572 return handle_name (read_identifier (ch));
574 tmp = readstring ('\'', &len);
575 yylval.ttype = string_or_char (len, tmp);
577 return len == 1 ? SINGLECHAR : STRING;
579 tmp = readstring ('\"', &len);
580 yylval.ttype = build_chill_string (len, tmp);
586 if (ISDIGIT (nextc)) /* || nextc == '_') we don't start numbers with '_' */
589 case '0': case '1': case '2': case '3': case '4':
590 case '5': case '6': case '7': case '8': case '9':
592 yylval.ttype = read_number (ch);
593 return TREE_CODE (yylval.ttype) == REAL_CST ? FLOATING : NUMBER;
600 close_input_file (fn)
606 if (finput != stdin && fclose (finput) == EOF)
608 error ("can't close %s", fn);
614 /* Return an identifier, starting with FIRST and then reading
615 more characters using input(). Return an IDENTIFIER_NODE. */
618 read_identifier (first)
619 int first; /* First letter of identifier */
625 obstack_1grow (&temporary_obstack, first);
629 if (! ISALNUM (first) && first != '_')
635 obstack_1grow (&temporary_obstack, '\0');
636 start = obstack_finish (&temporary_obstack);
637 maybe_downcase (start);
638 id = get_identifier (start);
639 obstack_free (&temporary_obstack, start);
643 /* Given an identifier ID, check to see if it is a reserved name,
644 and return the appropriate token type. */
651 tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
653 && special_UC == ISUPPER ((unsigned char) tp->name[0])
654 && (tp->flags == RESERVED || tp->flags == PREDEF))
656 if (tp->rid != NORID)
657 yylval.ttype = ridpointers[tp->rid];
658 else if (tp->token == THIS)
659 yylval.ttype = lookup_name (get_identifier ("__whoami"));
668 int ch; /* Initial character */
676 obstack_1grow (&temporary_obstack, ch);
678 if (! ISDIGIT (ch) && ch != '_')
686 obstack_1grow (&temporary_obstack, ch);
688 } while (ISDIGIT (ch) || ch == '_');
691 if (ch == 'd' || ch == 'D' || ch == 'e' || ch == 'E')
693 /* Convert exponent indication [eEdD] to 'e'. */
694 obstack_1grow (&temporary_obstack, 'e');
696 if (ch == '+' || ch == '-')
698 obstack_1grow (&temporary_obstack, ch);
701 if (ISDIGIT (ch) || ch == '_')
706 obstack_1grow (&temporary_obstack, ch);
708 } while (ISDIGIT (ch) || ch == '_');
712 error ("malformed exponent part of floating-point literal");
718 obstack_1grow (&temporary_obstack, '\0');
719 start = obstack_finish (&temporary_obstack);
722 REAL_VALUE_TYPE value;
723 tree type = double_type_node;
725 value = REAL_VALUE_ATOF (start, TYPE_MODE (type));
726 obstack_free (&temporary_obstack, start);
727 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
728 && REAL_VALUE_ISINF (value) && pedantic)
729 pedwarn ("real number exceeds range of REAL");
730 num = build_real (type, value);
733 num = convert_integer (start);
734 CH_DERIVED_FLAG (num) = 1;
738 /* Skip to the end of a compiler directive. */
748 error ("end-of-file in '<>' directive");
764 /* Read a compiler directive. ("<>{WS}" have already been read. ) */
770 int ch = skip_whitespace();
771 if (ISALPHA (ch) || ch == '_')
772 id = read_identifier (ch);
775 error ("end-of-file in '<>' directive");
776 to_global_binding_level ();
781 warning ("unrecognized compiler directive");
785 tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
786 if (tp == NULL || special_UC != ISUPPER ((unsigned char) tp->name[0]))
789 warning ("unrecognized compiler directive `%s'",
790 IDENTIFIER_POINTER (id));
807 case IGNORED_DIRECTIVE:
809 case PROCESS_TYPE_TOKEN:
810 process_type = equal_number ();
818 case SEND_SIGNAL_DEFAULT_PRIORITY:
819 send_signal_prio = equal_number ();
821 case SEND_BUFFER_DEFAULT_PRIORITY:
822 send_buffer_prio = equal_number ();
825 signal_code = equal_number ();
828 handle_use_seizefile_directive (0);
830 case USE_SEIZE_FILE_RESTRICTED:
831 handle_use_seizefile_directive (1);
835 warning ("unrecognized compiler directive `%s'",
836 IDENTIFIER_POINTER (id));
844 build_chill_string (len, str)
850 push_obstacks (&permanent_obstack, &permanent_obstack);
851 t = build_string (len, str);
852 TREE_TYPE (t) = build_string_type (char_type_node,
853 build_int_2 (len, 0));
854 CH_DERIVED_FLAG (t) = 1;
861 string_or_char (len, str)
867 push_obstacks (&permanent_obstack, &permanent_obstack);
870 result = build_int_2 ((unsigned char)str[0], 0);
871 CH_DERIVED_FLAG (result) = 1;
872 TREE_TYPE (result) = char_type_node;
875 result = build_chill_string (len, str);
889 *str = TOLOWER (*str);
901 /* check for decimal number */
902 if (*s >= '0' && *s <= '9')
906 if (*s >= '0' && *s <= '9')
924 if (*s < '0' || *s > '9')
929 if (!ISXDIGIT ((unsigned char) *s))
934 if (*s < '0' || *s > '1')
939 if (*s < '0' || *s > '7')
951 readstring (terminator, len)
956 unsigned allocated = 1024;
957 char *tmp = xmalloc (allocated);
965 if ((c = input ()) != terminator)
973 if (c == '\n' || c == EOF)
978 if (c == EOF || c == '\n')
992 if (cc == terminator)
994 if (!(terminator == '\'' && next_apos))
996 error ("unterminated control sequence");
1001 if (cc == EOF || cc == '\n')
1011 error ("invalid integer literal in control sequence");
1017 if (cc == ' ' || cc == '\t')
1021 if ((c < 0 || c > 255) && (pass == 1))
1022 error ("control sequence overflow");
1023 if (! count && pass == 1)
1024 error ("invalid control sequence");
1029 if ((c < 0 || c > 255) && (pass == 1))
1030 error ("control sequence overflow");
1031 if (! count && pass == 1)
1032 error ("invalid control sequence");
1037 tmp = xrealloc (tmp, allocated);
1046 if (! count && pass == 1)
1047 error ("invalid integer literal in control sequence");
1052 if (cc == 'D' || cc == 'd')
1057 else if (cc == 'H' || cc == 'h')
1062 else if (cc == 'O' || cc == 'o')
1067 else if (cc == 'B' || cc == 'b')
1078 if (cc < '0' || cc > '1')
1085 if (cc < '0' || cc > '8')
1090 else if (base == 10)
1097 else if (base == 16)
1112 error ("invalid base in read control sequence");
1117 /* error in control sequence */
1119 error ("invalid digit in control sequence");
1122 c = (c * base) + cc;
1134 tmp = xrealloc (tmp, allocated);
1138 tmp [*len = i] = '\0';
1146 error ("unterminated string literal");
1147 to_global_binding_level ();
1152 /* Convert an integer INTCHARS into an INTEGER_CST.
1153 INTCHARS is on the temporary_obstack, and is popped by this function. */
1156 convert_integer (intchars)
1165 int valid_chars = 0;
1168 HOST_WIDE_INT val_lo = 0, val_hi = 0;
1171 /* determine the base */
1194 if (!ISDIGIT (*p)) /* this test is for equal_number () */
1196 obstack_free (&temporary_obstack, intchars);
1205 if ((tmp == '\'') || (tmp == '_'))
1209 if (tmp >= 'a') /* uppercase the char */
1211 switch (base) /* validate the characters */
1228 if (tmp > '9' && tmp < 'A')
1237 if (mul_double (val_lo, val_hi, base, 0, &val_lo, &val_hi))
1239 add_double (val_lo, val_hi, tmp, 0, &val_lo, &val_hi);
1245 obstack_free (&temporary_obstack, intchars);
1249 error ("invalid number format `%s'", oldp);
1252 val = build_int_2 (val_lo, val_hi);
1253 /* We set the type to long long (or long long unsigned) so that
1254 constant fold of literals is less likely to overflow. */
1255 if (int_fits_type_p (val, long_long_integer_type_node))
1256 type = long_long_integer_type_node;
1259 if (! int_fits_type_p (val, long_long_unsigned_type_node))
1261 type = long_long_unsigned_type_node;
1263 TREE_TYPE (val) = type;
1264 CH_DERIVED_FLAG (val) = 1;
1267 error ("integer literal too big");
1272 /* Convert a bitstring literal on the temporary_obstack to
1273 a bitstring CONSTRUCTOR. Free the literal from the obstack. */
1276 convert_bitstring (p)
1282 int bl = 0, valid_chars = 0, bits_per_char = 0, c, k;
1283 tree initlist = NULL_TREE;
1286 /* Move p to stack so we can re-use temporary_obstack for result. */
1287 char *oldp = (char*) alloca (strlen (p) + 1);
1289 obstack_free (&temporary_obstack, p);
1312 if (c == '_' || c == '\'')
1321 for (k = BYTES_BIG_ENDIAN ? bits_per_char - 1 : 0;
1322 BYTES_BIG_ENDIAN ? k >= 0 : k < bits_per_char;
1323 bl++, BYTES_BIG_ENDIAN ? k-- : k++)
1326 initlist = tree_cons (NULL_TREE, build_int_2 (bl, 0), initlist);
1330 /* as long as BOOLS(0) is valid it must tbe possible to
1331 specify an empty bitstring */
1335 error ("invalid number format `%s'", oldp);
1339 val = build (CONSTRUCTOR,
1340 build_bitstring_type (size_int (bl)),
1341 NULL_TREE, nreverse (initlist));
1342 TREE_CONSTANT (val) = 1;
1343 CH_DERIVED_FLAG (val) = 1;
1347 /* Check if two filenames name the same file.
1348 This is done by stat'ing both files and comparing their inodes.
1350 Note: we have to take care of seize_path_list. Therefore do it the same
1351 way as in yywrap. FIXME: This probably can be done better. */
1354 same_file (filename1, filename2)
1355 const char *filename1;
1356 const char *filename2;
1359 const char *fn_input[2];
1362 if (grant_only_flag)
1363 /* do nothing in this case */
1366 /* if filenames are equal -- return 1, cause there is no need
1367 to search in the include list in this case */
1368 if (strcmp (filename1, filename2) == 0)
1371 fn_input[0] = filename1;
1372 fn_input[1] = filename2;
1374 for (i = 0; i < 2; i++)
1376 stat_status = stat (fn_input[i], &s[i]);
1378 && strchr (fn_input[i], '/') == 0)
1383 for (plp = seize_path_list; plp != 0; plp = plp->next)
1385 path = (char *) xmalloc (strlen (fn_input[i])
1386 + strlen (plp->str) + 2);
1387 sprintf (path, "%s/%s", plp->str, fn_input[i]);
1388 stat_status = stat (path, &s[i]);
1390 if (stat_status >= 0)
1395 if (stat_status < 0)
1396 fatal_io_error ("can't find %s", fn_input[i]);
1398 return s[0].st_ino == s[1].st_ino && s[0].st_dev == s[1].st_dev;
1402 * Note that simply appending included file names to a list in this
1403 * way completely eliminates the need for nested files, and the
1404 * associated book-keeping, since the EOF processing in the lexer
1405 * will simply process the files one at a time, in the order that the
1406 * USE_SEIZE_FILE directives were scanned.
1409 handle_use_seizefile_directive (restricted)
1414 int c = skip_whitespace ();
1415 char *use_seizefile_str = readstring (c, &len);
1420 if (c != '\'' && c != '\"')
1422 error ("USE_SEIZE_FILE directive must be followed by string");
1426 use_seizefile_name = get_identifier (use_seizefile_str);
1427 CH_USE_SEIZEFILE_RESTRICTED (use_seizefile_name) = restricted;
1429 if (!grant_only_flag)
1431 /* If file foo.ch contains a <> use_seize_file "bar.grt" <>,
1432 and file bar.ch contains a <> use_seize_file "foo.grt" <>,
1433 then if we're compiling foo.ch, we will indirectly be
1434 asked to seize foo.grt. Don't. */
1435 extern char *grant_file_name;
1436 if (strcmp (use_seizefile_str, grant_file_name) == 0)
1439 /* Check if the file is already on the list. */
1440 for (seen = files_to_seize; seen != NULL_TREE; seen = TREE_CHAIN (seen))
1441 if (same_file (IDENTIFIER_POINTER (TREE_VALUE (seen)),
1443 return; /* Previously seen; nothing to do. */
1446 /* Haven't been asked to seize this file yet, so add
1447 its name to the list. */
1449 tree pl = perm_tree_cons (0, use_seizefile_name, NULL_TREE);
1450 if (files_to_seize == NULL_TREE)
1451 files_to_seize = pl;
1453 TREE_CHAIN (last_file_to_seize) = pl;
1454 if (next_file_to_seize == NULL_TREE)
1455 next_file_to_seize = pl;
1456 last_file_to_seize = pl;
1462 * get input, convert to lower case for comparison
1476 #if defined HANDLE_PRAGMA
1477 /* Local versions of these macros, that can be passed as function pointers. */
1481 return getc (finput);
1488 ungetc (arg, finput);
1490 #endif /* HANDLE_PRAGMA */
1492 #ifdef HANDLE_GENERIC_PRAGMAS
1493 /* Handle a generic #pragma directive.
1494 BUFFER contains the text we read after `#pragma'. Processes the entire input
1495 line and return non-zero iff the pragma was successfully processed. */
1498 handle_generic_pragma (buffer)
1507 handle_pragma_token (buffer, NULL);
1511 while (c == ' ' || c == '\t')
1515 if (c == '\n' || c == EOF)
1516 return handle_pragma_token (NULL, NULL);
1518 /* Read the next word of the pragma into the buffer. */
1525 while (c != EOF && ! ISSPACE (c) && buff < buffer + 128);
1526 /* XXX shared knowledge about size of buffer. */
1533 #endif /* HANDLE_GENERIC_PRAGMAS */
1535 /* At the beginning of a line, increment the line number and process
1536 any #-directive on this line. If the line is a #-directive, read
1537 the entire line and return a newline. Otherwise, return the line's
1538 first non-whitespace character.
1540 (Each language front end has a check_newline() function that is called
1541 from lang_init() for that language. One of the things this function
1542 must do is read the first line of the input file, and if it is a #line
1543 directive, extract the filename from it and use it to initialize
1544 main_input_filename. Proper generation of debugging information in
1545 the normal "front end calls cpp then calls cc1XXXX environment" depends
1546 upon this being done.) */
1555 /* Read first nonwhite char on the line. */
1559 while (c == ' ' || c == '\t')
1562 if (c != '#' || inside_c_comment)
1564 /* If not #, return it so caller will use it. */
1568 /* Read first nonwhite char after the `#'. */
1571 while (c == ' ' || c == '\t')
1574 /* If a letter follows, then if the word here is `line', skip
1575 it and ignore it; otherwise, ignore the line, with an error
1576 if the word isn't `pragma', `ident', `define', or `undef'. */
1581 if (c >= 'a' && c <= 'z')
1585 if (getlc (finput) == 'r'
1586 && getlc (finput) == 'a'
1587 && getlc (finput) == 'g'
1588 && getlc (finput) == 'm'
1589 && getlc (finput) == 'a'
1590 && (c = getlc (finput), ISSPACE (c)))
1592 #ifdef HANDLE_PRAGMA
1593 static char buffer [128];
1594 char * buff = buffer;
1596 /* Read the pragma name into a buffer. */
1597 while (c = getlc (finput), ISSPACE (c))
1605 while (c != EOF && ! ISSPACE (c) && c != '\n'
1606 && buff < buffer + 128);
1612 if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
1614 #endif /* HANDLE_PRAGMA */
1616 #ifdef HANDLE_GENERIC_PRAGMAS
1617 if (handle_generic_pragma (buffer))
1619 #endif /* HANDLE_GENERIC_PRAGMAS */
1627 if (getlc (finput) == 'e'
1628 && getlc (finput) == 'f'
1629 && getlc (finput) == 'i'
1630 && getlc (finput) == 'n'
1631 && getlc (finput) == 'e'
1632 && (c = getlc (finput), ISSPACE (c)))
1634 #if 0 /*def DWARF_DEBUGGING_INFO*/
1636 && (debug_info_level == DINFO_LEVEL_VERBOSE)
1637 && (write_symbols == DWARF_DEBUG))
1638 dwarfout_define (lineno, get_directive_line (finput));
1639 #endif /* DWARF_DEBUGGING_INFO */
1645 if (getlc (finput) == 'n'
1646 && getlc (finput) == 'd'
1647 && getlc (finput) == 'e'
1648 && getlc (finput) == 'f'
1649 && (c = getlc (finput), ISSPACE (c)))
1651 #if 0 /*def DWARF_DEBUGGING_INFO*/
1653 && (debug_info_level == DINFO_LEVEL_VERBOSE)
1654 && (write_symbols == DWARF_DEBUG))
1655 dwarfout_undef (lineno, get_directive_line (finput));
1656 #endif /* DWARF_DEBUGGING_INFO */
1662 if (getlc (finput) == 'i'
1663 && getlc (finput) == 'n'
1664 && getlc (finput) == 'e'
1665 && ((c = getlc (finput)) == ' ' || c == '\t'))
1671 if (getlc (finput) == 'd'
1672 && getlc (finput) == 'e'
1673 && getlc (finput) == 'n'
1674 && getlc (finput) == 't'
1675 && ((c = getlc (finput)) == ' ' || c == '\t'))
1677 /* #ident. The pedantic warning is now in cpp. */
1679 /* Here we have just seen `#ident '.
1680 A string constant should follow. */
1682 while (c == ' ' || c == '\t')
1685 /* If no argument, ignore the line. */
1692 || TREE_CODE (yylval.ttype) != STRING_CST)
1694 error ("invalid #ident");
1700 #ifdef ASM_OUTPUT_IDENT
1701 extern FILE *asm_out_file;
1702 ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
1706 /* Skip the rest of this line. */
1712 error ("undefined or invalid # directive");
1717 /* Here we have either `#line' or `# <nonletter>'.
1718 In either case, it should be a line number; a digit should follow. */
1720 while (c == ' ' || c == '\t')
1723 /* If the # is the only nonwhite char on the line,
1724 just ignore it. Check the new newline. */
1728 /* Something follows the #; read a token. */
1732 int old_lineno = lineno;
1735 extern struct obstack permanent_obstack;
1739 l = l * 10 + (c - '0'); /* FIXME Not portable */
1741 } while (ISDIGIT(c));
1742 /* subtract one, because it is the following line that
1743 gets the specified number */
1747 /* Is this the last nonwhite stuff on the line? */
1749 while (c == ' ' || c == '\t')
1753 /* No more: store the line number and check following line. */
1758 /* More follows: it must be a string constant (filename). */
1760 /* Read the string constant, but don't treat \ as special. */
1761 ignore_escape_flag = 1;
1762 ignore_escape_flag = 0;
1766 error ("invalid #line");
1773 if (c == EOF || c == '\n')
1775 error ("invalid #line");
1780 obstack_1grow(&permanent_obstack, 0);
1781 input_filename = obstack_finish (&permanent_obstack);
1784 obstack_1grow(&permanent_obstack, c);
1789 /* Each change of file name
1790 reinitializes whether we are now in a system header. */
1791 in_system_header = 0;
1793 if (main_input_filename == 0)
1794 main_input_filename = input_filename;
1796 /* Is this the last nonwhite stuff on the line? */
1798 while (c == ' ' || c == '\t')
1805 /* `1' after file name means entering new file.
1806 `2' after file name means just left a file. */
1812 /* Pushing to a new file. */
1813 struct file_stack *p
1814 = (struct file_stack *) xmalloc (sizeof (struct file_stack));
1815 input_file_stack->line = old_lineno;
1816 p->next = input_file_stack;
1817 p->name = input_filename;
1818 input_file_stack = p;
1819 input_file_stack_tick++;
1820 #ifdef DWARF_DEBUGGING_INFO
1821 if (debug_info_level == DINFO_LEVEL_VERBOSE
1822 && write_symbols == DWARF_DEBUG)
1823 dwarfout_start_new_source_file (input_filename);
1824 #endif /* DWARF_DEBUGGING_INFO */
1830 /* Popping out of a file. */
1831 if (input_file_stack->next)
1833 struct file_stack *p = input_file_stack;
1834 input_file_stack = p->next;
1836 input_file_stack_tick++;
1837 #ifdef DWARF_DEBUGGING_INFO
1838 if (debug_info_level == DINFO_LEVEL_VERBOSE
1839 && write_symbols == DWARF_DEBUG)
1840 dwarfout_resume_previous_source_file (input_file_stack->line);
1841 #endif /* DWARF_DEBUGGING_INFO */
1844 error ("#-lines for entering and leaving files don't match");
1850 /* If we have handled a `1' or a `2',
1851 see if there is another number to read. */
1854 /* Is this the last nonwhite stuff on the line? */
1856 while (c == ' ' || c == '\t')
1863 /* `3' after file name means this is a system header file. */
1866 in_system_header = 1;
1869 error ("invalid #-line");
1871 /* skip the rest of this line. */
1873 while (c != '\n' && c != EOF)
1880 get_chill_filename ()
1882 return (build_chill_string (
1883 strlen (input_filename) + 1, /* +1 to get a zero terminated string */
1888 get_chill_linenumber ()
1890 return build_int_2 ((HOST_WIDE_INT)lineno, 0);
1894 /* Assuming '/' and '*' have been read, skip until we've
1895 read the terminating '*' and '/'. */
1901 int start_line = lineno;
1907 error_with_file_and_line (input_filename, start_line,
1908 "unterminated comment");
1913 else if ((c = input ()) == '/')
1919 /* Assuming "--" has been read, skip until '\n'. */
1922 skip_line_comment ()
1946 if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v')
1967 skip_line_comment ();
1981 * avoid recursive calls to yylex to parse the ' = digits' or
1982 * ' = SYNvalue' which are supposed to follow certain compiler
1983 * directives. Read the input stream, and return the value parsed.
1985 /* FIXME: overflow check in here */
1986 /* FIXME: check for EOF around here */
1993 tree retval = integer_zero_node;
1995 c = skip_whitespace();
1999 error ("missing `=' in compiler directive");
2000 return integer_zero_node;
2002 c = skip_whitespace();
2004 /* collect token into tokenbuf for later analysis */
2007 if (ISSPACE (c) || c == '<')
2009 obstack_1grow (&temporary_obstack, c);
2012 unput (c); /* put uninteresting char back */
2013 obstack_1grow (&temporary_obstack, '\0'); /* terminate token */
2014 tokenbuf = obstack_finish (&temporary_obstack);
2015 maybe_downcase (tokenbuf);
2017 if (*tokenbuf == '-')
2018 /* will fail in the next test */
2020 else if (maybe_number (tokenbuf))
2023 return integer_zero_node;
2024 push_obstacks_nochange ();
2025 end_temporary_allocation ();
2026 yylval.ttype = convert_integer (tokenbuf);
2027 tokenbuf = 0; /* Was freed by convert_integer. */
2028 result = yylval.ttype ? NUMBER : 0;
2034 if (result == NUMBER)
2036 retval = yylval.ttype;
2038 else if (result == BITSTRING)
2041 error ("invalid value follows `=' in compiler directive");
2044 else /* not a number */
2048 if (!ISALPHA (c) && c != '_')
2051 error ("invalid value follows `=' in compiler directive");
2055 for (cursor = &tokenbuf[1]; *cursor != '\0'; cursor++)
2056 if (ISALPHA ((unsigned char) *cursor) || *cursor == '_' ||
2062 error ("invalid `%c' character in name", *cursor);
2069 tree value = lookup_name (get_identifier (tokenbuf));
2070 if (value == NULL_TREE
2071 || TREE_CODE (value) != CONST_DECL
2072 || TREE_CODE (DECL_INITIAL (value)) != INTEGER_CST)
2075 error ("`%s' not integer constant synonym ",
2079 obstack_free (&temporary_obstack, tokenbuf);
2081 push_obstacks_nochange ();
2082 end_temporary_allocation ();
2083 retval = convert (chill_taskingcode_type_node, DECL_INITIAL (value));
2088 /* check the value */
2089 if (TREE_CODE (retval) != INTEGER_CST)
2092 error ("invalid value follows `=' in compiler directive");
2094 else if (TREE_INT_CST_HIGH (retval) != 0 ||
2095 TREE_INT_CST_LOW (retval) > TREE_INT_CST_LOW (TYPE_MAX_VALUE (chill_unsigned_type_node)))
2098 error ("value out of range in compiler directive");
2102 obstack_free (&temporary_obstack, tokenbuf);
2107 * add a possible grant-file path to the list
2110 register_seize_path (path)
2113 int pathlen = strlen (path);
2114 char *new_path = (char *)xmalloc (pathlen + 1);
2115 STRING_LIST *pl = (STRING_LIST *)xmalloc (sizeof (STRING_LIST));
2117 /* strip off trailing slash if any */
2118 if (path[pathlen - 1] == '/')
2121 memcpy (new_path, path, pathlen);
2123 pl->next = seize_path_list;
2124 seize_path_list = pl;
2128 /* Used by decode_decl to indicate that a <> use_seize_file NAME <>
2129 directive has been written to the grantfile. */
2132 mark_use_seizefile_written (name)
2137 for (node = files_to_seize; node != NULL_TREE; node = TREE_CHAIN (node))
2138 if (TREE_VALUE (node) == name)
2140 TREE_PURPOSE (node) = integer_one_node;
2149 extern char *chill_real_input_filename;
2151 close_input_file (input_filename);
2153 use_seizefile_name = NULL_TREE;
2155 if (next_file_to_seize && !grant_only_flag)
2157 FILE *grt_in = NULL;
2158 const char *seizefile_name_chars
2159 = IDENTIFIER_POINTER (TREE_VALUE (next_file_to_seize));
2161 /* find a seize file, open it. If it's not at the path the
2162 * user gave us, and that path contains no slashes, look on
2163 * the seize_file paths, specified by the '-I' options.
2165 grt_in = fopen (seizefile_name_chars, "r");
2167 && strchr (seizefile_name_chars, '/') == NULL)
2172 for (plp = seize_path_list; plp != NULL; plp = plp->next)
2174 path = (char *)xmalloc (strlen (seizefile_name_chars)
2175 + strlen (plp->str) + 2);
2177 sprintf (path, "%s/%s", plp->str, seizefile_name_chars);
2178 grt_in = fopen (path, "r");
2183 seizefile_name_chars = path;
2190 fatal_io_error ("can't open %s", seizefile_name_chars);
2193 input_filename = seizefile_name_chars;
2196 current_seizefile_name = TREE_VALUE (next_file_to_seize);
2198 next_file_to_seize = TREE_CHAIN (next_file_to_seize);
2206 next_file_to_seize = files_to_seize;
2207 current_seizefile_name = NULL_TREE;
2209 if (strcmp (main_input_filename, "stdin"))
2210 finput = fopen (chill_real_input_filename, "r");
2215 error ("can't reopen %s", chill_real_input_filename);
2218 input_filename = main_input_filename;
2221 /* Read a line directive if there is one. */
2222 ungetc (check_newline (), finput);
2223 starting_pass_2 = 1;
2225 if (module_number == 0)
2226 warning ("no modules seen");