[AArch64] Use new target pass registration framework for FMA steering pass
[official-gcc.git] / gcc / read-md.c
blobe158be55f9a749491a5b020a1f2b82e8519c8790
1 /* MD reader for GCC.
2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "bconfig.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "errors.h"
24 #include "read-md.h"
26 /* Associates PTR (which can be a string, etc.) with the file location
27 specified by FILENAME and LINENO. */
28 struct ptr_loc {
29 const void *ptr;
30 const char *filename;
31 int lineno;
34 /* Obstack used for allocating MD strings. */
35 struct obstack string_obstack;
37 /* A table of ptr_locs, hashed on the PTR field. */
38 static htab_t ptr_locs;
40 /* An obstack for the above. Plain xmalloc is a bit heavyweight for a
41 small structure like ptr_loc. */
42 static struct obstack ptr_loc_obstack;
44 /* A hash table of triples (A, B, C), where each of A, B and C is a condition
45 and A is equivalent to "B && C". This is used to keep track of the source
46 of conditions that are made up of separate MD strings (such as the split
47 condition of a define_insn_and_split). */
48 static htab_t joined_conditions;
50 /* An obstack for allocating joined_conditions entries. */
51 static struct obstack joined_conditions_obstack;
53 /* This callback will be invoked whenever an md include directive is
54 processed. To be used for creation of the dependency file. */
55 void (*include_callback) (const char *);
57 /* Global singleton. */
59 rtx_reader *rtx_reader_ptr;
61 /* A table of md_constant structures, hashed by name. Null if no
62 constant expansion should occur. */
63 static htab_t md_constants;
65 /* A table of enum_type structures, hashed by name. */
66 static htab_t enum_types;
68 /* Given an object that starts with a char * name field, return a hash
69 code for its name. */
71 hashval_t
72 leading_string_hash (const void *def)
74 return htab_hash_string (*(const char *const *) def);
77 /* Given two objects that start with char * name fields, return true if
78 they have the same name. */
80 int
81 leading_string_eq_p (const void *def1, const void *def2)
83 return strcmp (*(const char *const *) def1,
84 *(const char *const *) def2) == 0;
87 /* Return a hash value for the pointer pointed to by DEF. */
89 static hashval_t
90 leading_ptr_hash (const void *def)
92 return htab_hash_pointer (*(const void *const *) def);
95 /* Return true if DEF1 and DEF2 are pointers to the same pointer. */
97 static int
98 leading_ptr_eq_p (const void *def1, const void *def2)
100 return *(const void *const *) def1 == *(const void *const *) def2;
103 /* Associate PTR with the file position given by FILENAME and LINENO. */
105 static void
106 set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
108 struct ptr_loc *loc;
110 loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
111 sizeof (struct ptr_loc));
112 loc->ptr = ptr;
113 loc->filename = filename;
114 loc->lineno = lineno;
115 *htab_find_slot (ptr_locs, loc, INSERT) = loc;
118 /* Return the position associated with pointer PTR. Return null if no
119 position was set. */
121 static const struct ptr_loc *
122 get_md_ptr_loc (const void *ptr)
124 return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
127 /* Associate NEW_PTR with the same file position as OLD_PTR. */
129 void
130 copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
132 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
133 if (loc != 0)
134 set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
137 /* If PTR is associated with a known file position, print a #line
138 directive for it to OUTF. */
140 void
141 fprint_md_ptr_loc (FILE *outf, const void *ptr)
143 const struct ptr_loc *loc = get_md_ptr_loc (ptr);
144 if (loc != 0)
145 fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename);
148 /* Special fprint_md_ptr_loc for writing to STDOUT. */
149 void
150 print_md_ptr_loc (const void *ptr)
152 fprint_md_ptr_loc (stdout, ptr);
155 /* Return a condition that satisfies both COND1 and COND2. Either string
156 may be null or empty. */
158 const char *
159 join_c_conditions (const char *cond1, const char *cond2)
161 char *result;
162 const void **entry;
164 if (cond1 == 0 || cond1[0] == 0)
165 return cond2;
167 if (cond2 == 0 || cond2[0] == 0)
168 return cond1;
170 if (strcmp (cond1, cond2) == 0)
171 return cond1;
173 result = concat ("(", cond1, ") && (", cond2, ")", NULL);
174 obstack_ptr_grow (&joined_conditions_obstack, result);
175 obstack_ptr_grow (&joined_conditions_obstack, cond1);
176 obstack_ptr_grow (&joined_conditions_obstack, cond2);
177 entry = XOBFINISH (&joined_conditions_obstack, const void **);
178 *htab_find_slot (joined_conditions, entry, INSERT) = entry;
179 return result;
182 /* Print condition COND to OUTF, wrapped in brackets. If COND was created
183 by join_c_conditions, recursively invoke this function for the original
184 conditions and join the result with "&&". Otherwise print a #line
185 directive for COND if its original file position is known. */
187 void
188 fprint_c_condition (FILE *outf, const char *cond)
190 const char **halves = (const char **) htab_find (joined_conditions, &cond);
191 if (halves != 0)
193 fprintf (outf, "(");
194 fprint_c_condition (outf, halves[1]);
195 fprintf (outf, " && ");
196 fprint_c_condition (outf, halves[2]);
197 fprintf (outf, ")");
199 else
201 fputc ('\n', outf);
202 fprint_md_ptr_loc (outf, cond);
203 fprintf (outf, "(%s)", cond);
207 /* Special fprint_c_condition for writing to STDOUT. */
209 void
210 print_c_condition (const char *cond)
212 fprint_c_condition (stdout, cond);
215 /* A vfprintf-like function for reporting an error against line LINENO
216 of the current MD file. */
218 static void ATTRIBUTE_PRINTF(2,0)
219 message_at_1 (file_location loc, const char *msg, va_list ap)
221 fprintf (stderr, "%s:%d:%d: ", loc.filename, loc.lineno, loc.colno);
222 vfprintf (stderr, msg, ap);
223 fputc ('\n', stderr);
226 /* A printf-like function for reporting a message against location LOC. */
228 void
229 message_at (file_location loc, const char *msg, ...)
231 va_list ap;
233 va_start (ap, msg);
234 message_at_1 (loc, msg, ap);
235 va_end (ap);
238 /* Like message_at, but treat the condition as an error. */
240 void
241 error_at (file_location loc, const char *msg, ...)
243 va_list ap;
245 va_start (ap, msg);
246 message_at_1 (loc, msg, ap);
247 va_end (ap);
248 have_error = 1;
251 /* Like message_at, but treat the condition as a fatal error. */
253 void
254 fatal_at (file_location loc, const char *msg, ...)
256 va_list ap;
258 va_start (ap, msg);
259 message_at_1 (loc, msg, ap);
260 va_end (ap);
261 exit (1);
264 /* A printf-like function for reporting an error against the current
265 position in the MD file. */
267 void
268 fatal_with_file_and_line (const char *msg, ...)
270 char context[64];
271 size_t i;
272 int c;
273 va_list ap;
275 va_start (ap, msg);
277 fprintf (stderr, "%s:%d:%d: error: ", rtx_reader_ptr->get_filename (),
278 rtx_reader_ptr->get_lineno (), rtx_reader_ptr->get_colno ());
279 vfprintf (stderr, msg, ap);
280 putc ('\n', stderr);
282 /* Gather some following context. */
283 for (i = 0; i < sizeof (context)-1; ++i)
285 c = read_char ();
286 if (c == EOF)
287 break;
288 if (c == '\r' || c == '\n')
290 unread_char (c);
291 break;
293 context[i] = c;
295 context[i] = '\0';
297 fprintf (stderr, "%s:%d:%d: note: following context is `%s'\n",
298 rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
299 rtx_reader_ptr->get_colno (), context);
301 va_end (ap);
302 exit (1);
305 /* Report that we found character ACTUAL when we expected to find
306 character EXPECTED. */
308 void
309 fatal_expected_char (int expected, int actual)
311 if (actual == EOF)
312 fatal_with_file_and_line ("expected character `%c', found EOF",
313 expected);
314 else
315 fatal_with_file_and_line ("expected character `%c', found `%c'",
316 expected, actual);
319 /* Read chars from the MD file until a non-whitespace char and return that.
320 Comments, both Lisp style and C style, are treated as whitespace. */
323 read_skip_spaces (void)
325 int c;
327 while (1)
329 c = read_char ();
330 switch (c)
332 case ' ': case '\t': case '\f': case '\r': case '\n':
333 break;
335 case ';':
337 c = read_char ();
338 while (c != '\n' && c != EOF);
339 break;
341 case '/':
343 int prevc;
344 c = read_char ();
345 if (c != '*')
347 unread_char (c);
348 fatal_with_file_and_line ("stray '/' in file");
351 prevc = 0;
352 while ((c = read_char ()) && c != EOF)
354 if (prevc == '*' && c == '/')
355 break;
356 prevc = c;
359 break;
361 default:
362 return c;
367 /* Consume any whitespace, then consume the next non-whitespace
368 character, issuing a fatal error if it is not EXPECTED. */
370 void
371 require_char_ws (char expected)
373 int ch = read_skip_spaces ();
374 if (ch != expected)
375 fatal_expected_char (expected, ch);
378 /* Read the next character from the file. */
381 rtx_reader::read_char (void)
383 int ch;
385 ch = getc (m_read_md_file);
386 if (ch == '\n')
388 m_read_md_lineno++;
389 m_last_line_colno = m_read_md_colno;
390 m_read_md_colno = 0;
392 else
393 m_read_md_colno++;
395 return ch;
398 /* Put back CH, which was the last character read from the file. */
400 void
401 rtx_reader::unread_char (int ch)
403 if (ch == '\n')
405 m_read_md_lineno--;
406 m_read_md_colno = m_last_line_colno;
408 else
409 m_read_md_colno--;
410 ungetc (ch, m_read_md_file);
413 /* Read an rtx code name into NAME. It is terminated by any of the
414 punctuation chars of rtx printed syntax. */
416 void
417 read_name (struct md_name *name)
419 int c;
420 size_t i;
421 int angle_bracket_depth;
423 c = read_skip_spaces ();
425 i = 0;
426 angle_bracket_depth = 0;
427 while (1)
429 if (c == '<')
430 angle_bracket_depth++;
432 if ((c == '>') && (angle_bracket_depth > 0))
433 angle_bracket_depth--;
435 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
436 || c == EOF)
437 break;
438 if (angle_bracket_depth == 0)
440 if (c == ':' || c == ')' || c == ']'
441 || c == '"' || c == '/' || c == '(' || c == '[')
443 unread_char (c);
444 break;
448 if (i == sizeof (name->buffer) - 1)
449 fatal_with_file_and_line ("name too long");
450 name->buffer[i++] = c;
452 c = read_char ();
455 if (i == 0)
456 fatal_with_file_and_line ("missing name or number");
458 name->buffer[i] = 0;
459 name->string = name->buffer;
461 if (md_constants)
463 /* Do constant expansion. */
464 struct md_constant *def;
468 struct md_constant tmp_def;
470 tmp_def.name = name->string;
471 def = (struct md_constant *) htab_find (md_constants, &tmp_def);
472 if (def)
473 name->string = def->value;
475 while (def);
479 /* Subroutine of the string readers. Handles backslash escapes.
480 Caller has read the backslash, but not placed it into the obstack. */
482 static void
483 read_escape (void)
485 int c = read_char ();
487 switch (c)
489 /* Backslash-newline is replaced by nothing, as in C. */
490 case '\n':
491 return;
493 /* \" \' \\ are replaced by the second character. */
494 case '\\':
495 case '"':
496 case '\'':
497 break;
499 /* Standard C string escapes:
500 \a \b \f \n \r \t \v
501 \[0-7] \x
502 all are passed through to the output string unmolested.
503 In normal use these wind up in a string constant processed
504 by the C compiler, which will translate them appropriately.
505 We do not bother checking that \[0-7] are followed by up to
506 two octal digits, or that \x is followed by N hex digits.
507 \? \u \U are left out because they are not in traditional C. */
508 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
509 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
510 case '7': case 'x':
511 obstack_1grow (&string_obstack, '\\');
512 break;
514 /* \; makes stuff for a C string constant containing
515 newline and tab. */
516 case ';':
517 obstack_grow (&string_obstack, "\\n\\t", 4);
518 return;
520 /* pass anything else through, but issue a warning. */
521 default:
522 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
523 rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
525 obstack_1grow (&string_obstack, '\\');
526 break;
529 obstack_1grow (&string_obstack, c);
532 /* Read a double-quoted string onto the obstack. Caller has scanned
533 the leading quote. */
535 char *
536 read_quoted_string (void)
538 int c;
540 while (1)
542 c = read_char (); /* Read the string */
543 if (c == '\\')
545 read_escape ();
546 continue;
548 else if (c == '"' || c == EOF)
549 break;
551 obstack_1grow (&string_obstack, c);
554 obstack_1grow (&string_obstack, 0);
555 return XOBFINISH (&string_obstack, char *);
558 /* Read a braced string (a la Tcl) onto the string obstack. Caller
559 has scanned the leading brace. Note that unlike quoted strings,
560 the outermost braces _are_ included in the string constant. */
562 static char *
563 read_braced_string (void)
565 int c;
566 int brace_depth = 1; /* caller-processed */
567 unsigned long starting_read_md_lineno = rtx_reader_ptr->get_lineno ();
569 obstack_1grow (&string_obstack, '{');
570 while (brace_depth)
572 c = read_char (); /* Read the string */
574 if (c == '{')
575 brace_depth++;
576 else if (c == '}')
577 brace_depth--;
578 else if (c == '\\')
580 read_escape ();
581 continue;
583 else if (c == EOF)
584 fatal_with_file_and_line
585 ("missing closing } for opening brace on line %lu",
586 starting_read_md_lineno);
588 obstack_1grow (&string_obstack, c);
591 obstack_1grow (&string_obstack, 0);
592 return XOBFINISH (&string_obstack, char *);
595 /* Read some kind of string constant. This is the high-level routine
596 used by read_rtx. It handles surrounding parentheses, leading star,
597 and dispatch to the appropriate string constant reader. */
599 char *
600 read_string (int star_if_braced)
602 char *stringbuf;
603 int saw_paren = 0;
604 int c, old_lineno;
606 c = read_skip_spaces ();
607 if (c == '(')
609 saw_paren = 1;
610 c = read_skip_spaces ();
613 old_lineno = rtx_reader_ptr->get_lineno ();
614 if (c == '"')
615 stringbuf = read_quoted_string ();
616 else if (c == '{')
618 if (star_if_braced)
619 obstack_1grow (&string_obstack, '*');
620 stringbuf = read_braced_string ();
622 else
623 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
625 if (saw_paren)
626 require_char_ws (')');
628 set_md_ptr_loc (stringbuf, rtx_reader_ptr->get_filename (), old_lineno);
629 return stringbuf;
632 /* Skip the rest of a construct that started at line LINENO and that
633 is currently nested by DEPTH levels of parentheses. */
635 static void
636 read_skip_construct (int depth, file_location loc)
638 struct md_name name;
639 int c;
643 c = read_skip_spaces ();
644 if (c == EOF)
646 error_at (loc, "unterminated construct");
647 exit (1);
649 switch (c)
651 case '(':
652 depth++;
653 break;
655 case ')':
656 depth--;
657 break;
659 case ':':
660 case '[':
661 case ']':
662 case '/':
663 break;
665 case '\"':
666 case '{':
667 unread_char (c);
668 read_string (false);
669 break;
671 default:
672 unread_char (c);
673 read_name (&name);
674 break;
677 while (depth > 0);
678 unread_char (c);
681 /* Given a string, return the number of comma-separated elements in it.
682 Return 0 for the null string. */
685 n_comma_elts (const char *s)
687 int n;
689 if (*s == '\0')
690 return 0;
692 for (n = 1; *s; s++)
693 if (*s == ',')
694 n++;
696 return n;
699 /* Given a pointer to a (char *), return a pointer to the beginning of the
700 next comma-separated element in the string. Advance the pointer given
701 to the end of that element. Return NULL if at end of string. Caller
702 is responsible for copying the string if necessary. White space between
703 a comma and an element is ignored. */
705 const char *
706 scan_comma_elt (const char **pstr)
708 const char *start;
709 const char *p = *pstr;
711 if (*p == ',')
712 p++;
713 while (ISSPACE (*p))
714 p++;
716 if (*p == '\0')
717 return NULL;
719 start = p;
721 while (*p != ',' && *p != '\0')
722 p++;
724 *pstr = p;
725 return start;
728 /* Convert STRING to uppercase. */
730 void
731 upcase_string (char *string)
733 int i;
735 for (i = 0; string[i]; i++)
736 string[i] = TOUPPER (string[i]);
739 /* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
740 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
741 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
743 static struct md_constant *
744 add_constant (htab_t defs, char *name, char *value,
745 struct enum_type *parent_enum)
747 struct md_constant *def, tmp_def;
748 void **entry_ptr;
750 tmp_def.name = name;
751 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
752 if (*entry_ptr)
754 def = (struct md_constant *) *entry_ptr;
755 if (strcmp (def->value, value) != 0)
756 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
757 def->name, def->value, value);
758 else if (parent_enum || def->parent_enum)
759 fatal_with_file_and_line ("redefinition of `%s'", def->name);
760 free (name);
761 free (value);
763 else
765 def = XNEW (struct md_constant);
766 def->name = name;
767 def->value = value;
768 def->parent_enum = parent_enum;
769 *entry_ptr = def;
771 return def;
774 /* Process a define_constants directive, starting with the optional space
775 after the "define_constants". */
777 static void
778 handle_constants (void)
780 int c;
781 htab_t defs;
783 require_char_ws ('[');
785 /* Disable constant expansion during definition processing. */
786 defs = md_constants;
787 md_constants = 0;
788 while ( (c = read_skip_spaces ()) != ']')
790 struct md_name name, value;
792 if (c != '(')
793 fatal_expected_char ('(', c);
795 read_name (&name);
796 read_name (&value);
797 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
799 require_char_ws (')');
801 md_constants = defs;
804 /* For every constant definition, call CALLBACK with two arguments:
805 a pointer a pointer to the constant definition and INFO.
806 Stop when CALLBACK returns zero. */
808 void
809 traverse_md_constants (htab_trav callback, void *info)
811 htab_traverse (md_constants, callback, info);
814 /* Return a malloc()ed decimal string that represents number NUMBER. */
816 static char *
817 md_decimal_string (int number)
819 /* A safe overestimate. +1 for sign, +1 for null terminator. */
820 char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
822 sprintf (buffer, "%d", number);
823 return xstrdup (buffer);
826 /* Process a define_enum or define_c_enum directive, starting with
827 the optional space after the "define_enum". LINENO is the line
828 number on which the directive started and MD_P is true if the
829 directive is a define_enum rather than a define_c_enum. */
831 static void
832 handle_enum (file_location loc, bool md_p)
834 char *enum_name, *value_name;
835 struct md_name name;
836 struct enum_type *def;
837 struct enum_value *ev;
838 void **slot;
839 int c;
841 enum_name = read_string (false);
842 slot = htab_find_slot (enum_types, &enum_name, INSERT);
843 if (*slot)
845 def = (struct enum_type *) *slot;
846 if (def->md_p != md_p)
847 error_at (loc, "redefining `%s' as a different type of enum",
848 enum_name);
850 else
852 def = XNEW (struct enum_type);
853 def->name = enum_name;
854 def->md_p = md_p;
855 def->values = 0;
856 def->tail_ptr = &def->values;
857 def->num_values = 0;
858 *slot = def;
861 require_char_ws ('[');
863 while ((c = read_skip_spaces ()) != ']')
865 if (c == EOF)
867 error_at (loc, "unterminated construct");
868 exit (1);
870 unread_char (c);
871 read_name (&name);
873 ev = XNEW (struct enum_value);
874 ev->next = 0;
875 if (md_p)
877 value_name = concat (def->name, "_", name.string, NULL);
878 upcase_string (value_name);
879 ev->name = xstrdup (name.string);
881 else
883 value_name = xstrdup (name.string);
884 ev->name = value_name;
886 ev->def = add_constant (md_constants, value_name,
887 md_decimal_string (def->num_values), def);
889 *def->tail_ptr = ev;
890 def->tail_ptr = &ev->next;
891 def->num_values++;
895 /* Try to find the definition of the given enum. Return null on failure. */
897 struct enum_type *
898 lookup_enum_type (const char *name)
900 return (struct enum_type *) htab_find (enum_types, &name);
903 /* For every enum definition, call CALLBACK with two arguments:
904 a pointer to the constant definition and INFO. Stop when CALLBACK
905 returns zero. */
907 void
908 traverse_enum_types (htab_trav callback, void *info)
910 htab_traverse (enum_types, callback, info);
914 /* Constructor for rtx_reader. */
916 rtx_reader::rtx_reader ()
917 : m_toplevel_fname (NULL),
918 m_base_dir (NULL),
919 m_read_md_file (NULL),
920 m_read_md_filename (NULL),
921 m_read_md_lineno (0),
922 m_read_md_colno (0),
923 m_first_dir_md_include (NULL),
924 m_last_dir_md_include_ptr (&m_first_dir_md_include)
926 /* Set the global singleton pointer. */
927 rtx_reader_ptr = this;
930 /* rtx_reader's destructor. */
932 rtx_reader::~rtx_reader ()
934 /* Clear the global singleton pointer. */
935 rtx_reader_ptr = NULL;
938 /* Process an "include" directive, starting with the optional space
939 after the "include". Read in the file and use HANDLE_DIRECTIVE
940 to process each unknown directive. LINENO is the line number on
941 which the "include" occurred. */
943 void
944 rtx_reader::handle_include (file_location loc)
946 const char *filename;
947 const char *old_filename;
948 int old_lineno, old_colno;
949 char *pathname;
950 FILE *input_file, *old_file;
952 filename = read_string (false);
953 input_file = NULL;
955 /* If the specified file name is absolute, skip the include stack. */
956 if (!IS_ABSOLUTE_PATH (filename))
958 struct file_name_list *stackp;
960 /* Search the directory path, trying to open the file. */
961 for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next)
963 static const char sep[2] = { DIR_SEPARATOR, '\0' };
965 pathname = concat (stackp->fname, sep, filename, NULL);
966 input_file = fopen (pathname, "r");
967 if (input_file != NULL)
968 break;
969 free (pathname);
973 /* If we haven't managed to open the file yet, try combining the
974 filename with BASE_DIR. */
975 if (input_file == NULL)
977 if (m_base_dir)
978 pathname = concat (m_base_dir, filename, NULL);
979 else
980 pathname = xstrdup (filename);
981 input_file = fopen (pathname, "r");
984 if (input_file == NULL)
986 free (pathname);
987 error_at (loc, "include file `%s' not found", filename);
988 return;
991 /* Save the old cursor. Note that the LINENO argument to this
992 function is the beginning of the include statement, while
993 read_md_lineno has already been advanced. */
994 old_file = m_read_md_file;
995 old_filename = m_read_md_filename;
996 old_lineno = m_read_md_lineno;
997 old_colno = m_read_md_colno;
999 if (include_callback)
1000 include_callback (pathname);
1002 m_read_md_file = input_file;
1003 m_read_md_filename = pathname;
1005 handle_file ();
1007 /* Restore the old cursor. */
1008 m_read_md_file = old_file;
1009 m_read_md_filename = old_filename;
1010 m_read_md_lineno = old_lineno;
1011 m_read_md_colno = old_colno;
1013 /* Do not free the pathname. It is attached to the various rtx
1014 queue elements. */
1017 /* Process the current file, assuming that read_md_file and
1018 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
1019 unknown directives. */
1021 void
1022 rtx_reader::handle_file ()
1024 struct md_name directive;
1025 int c;
1027 m_read_md_lineno = 1;
1028 m_read_md_colno = 0;
1029 while ((c = read_skip_spaces ()) != EOF)
1031 file_location loc = get_current_location ();
1032 if (c != '(')
1033 fatal_expected_char ('(', c);
1035 read_name (&directive);
1036 if (strcmp (directive.string, "define_constants") == 0)
1037 handle_constants ();
1038 else if (strcmp (directive.string, "define_enum") == 0)
1039 handle_enum (loc, true);
1040 else if (strcmp (directive.string, "define_c_enum") == 0)
1041 handle_enum (loc, false);
1042 else if (strcmp (directive.string, "include") == 0)
1043 handle_include (loc);
1044 else
1045 handle_unknown_directive (loc, directive.string);
1047 require_char_ws (')');
1049 fclose (m_read_md_file);
1052 /* Like handle_file, but for top-level files. Set up m_toplevel_fname
1053 and m_base_dir accordingly. */
1055 void
1056 rtx_reader::handle_toplevel_file ()
1058 const char *base;
1060 m_toplevel_fname = m_read_md_filename;
1061 base = lbasename (m_toplevel_fname);
1062 if (base == m_toplevel_fname)
1063 m_base_dir = NULL;
1064 else
1065 m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname);
1067 handle_file ();
1070 file_location
1071 rtx_reader::get_current_location () const
1073 return file_location (m_read_md_filename, m_read_md_lineno, m_read_md_colno);
1076 /* Parse a -I option with argument ARG. */
1078 void
1079 rtx_reader::add_include_path (const char *arg)
1081 struct file_name_list *dirtmp;
1083 dirtmp = XNEW (struct file_name_list);
1084 dirtmp->next = 0;
1085 dirtmp->fname = arg;
1086 *m_last_dir_md_include_ptr = dirtmp;
1087 m_last_dir_md_include_ptr = &dirtmp->next;
1090 /* The main routine for reading .md files. Try to process all the .md
1091 files specified on the command line and return true if no error occurred.
1093 ARGC and ARGV are the arguments to main.
1095 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1096 It should return true if it recognizes the argument or false if a
1097 generic error should be reported. */
1099 bool
1100 rtx_reader::read_md_files (int argc, const char **argv,
1101 bool (*parse_opt) (const char *))
1103 int i;
1104 bool no_more_options;
1105 bool already_read_stdin;
1106 int num_files;
1108 /* Initialize global data. */
1109 obstack_init (&string_obstack);
1110 ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1111 obstack_init (&ptr_loc_obstack);
1112 joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1113 obstack_init (&joined_conditions_obstack);
1114 md_constants = htab_create (31, leading_string_hash,
1115 leading_string_eq_p, (htab_del) 0);
1116 enum_types = htab_create (31, leading_string_hash,
1117 leading_string_eq_p, (htab_del) 0);
1119 /* Unlock the stdio streams. */
1120 unlock_std_streams ();
1122 /* First we loop over all the options. */
1123 for (i = 1; i < argc; i++)
1124 if (argv[i][0] == '-')
1126 /* An argument consisting of exactly one dash is a request to
1127 read stdin. This will be handled in the second loop. */
1128 if (argv[i][1] == '\0')
1129 continue;
1131 /* An argument consisting of just two dashes causes option
1132 parsing to cease. */
1133 if (argv[i][1] == '-' && argv[i][2] == '\0')
1134 break;
1136 if (argv[i][1] == 'I')
1138 if (argv[i][2] != '\0')
1139 add_include_path (argv[i] + 2);
1140 else if (++i < argc)
1141 add_include_path (argv[i]);
1142 else
1143 fatal ("directory name missing after -I option");
1144 continue;
1147 /* The program may have provided a callback so it can
1148 accept its own options. */
1149 if (parse_opt && parse_opt (argv[i]))
1150 continue;
1152 fatal ("invalid option `%s'", argv[i]);
1155 /* Now loop over all input files. */
1156 num_files = 0;
1157 no_more_options = false;
1158 already_read_stdin = false;
1159 for (i = 1; i < argc; i++)
1161 if (argv[i][0] == '-')
1163 if (argv[i][1] == '\0')
1165 /* Read stdin. */
1166 if (already_read_stdin)
1167 fatal ("cannot read standard input twice");
1169 m_read_md_file = stdin;
1170 m_read_md_filename = "<stdin>";
1171 handle_toplevel_file ();
1172 already_read_stdin = true;
1173 continue;
1175 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1177 /* No further arguments are to be treated as options. */
1178 no_more_options = true;
1179 continue;
1181 else if (!no_more_options)
1182 continue;
1185 /* If we get here we are looking at a non-option argument, i.e.
1186 a file to be processed. */
1187 m_read_md_filename = argv[i];
1188 m_read_md_file = fopen (m_read_md_filename, "r");
1189 if (m_read_md_file == 0)
1191 perror (m_read_md_filename);
1192 return false;
1194 handle_toplevel_file ();
1195 num_files++;
1198 /* If we get to this point without having seen any files to process,
1199 read the standard input now. */
1200 if (num_files == 0 && !already_read_stdin)
1202 m_read_md_file = stdin;
1203 m_read_md_filename = "<stdin>";
1204 handle_toplevel_file ();
1207 return !have_error;
1210 /* class noop_reader : public rtx_reader */
1212 /* A dummy implementation which skips unknown directives. */
1213 void
1214 noop_reader::handle_unknown_directive (file_location loc, const char *)
1216 read_skip_construct (1, loc);