Introduce class rtx_reader
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 21 Sep 2016 20:55:06 +0000 (20:55 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Wed, 21 Sep 2016 20:55:06 +0000 (20:55 +0000)
Bundle up various global variables within gensupport.c into a
class rtx_reader, with a view towards making it easier to run the
code more than once in-process.

gcc/ChangeLog:
* genconstants.c (main): Introduce noop_reader and convert call
to read_md_files to a method call.
* genenums.c (main): Likewise.
* genmddeps.c (main): Likewise.
* genpreds.c (write_tm_constrs_h): Replace use of "in_fname" with
rtx_reader_ptr->get_top_level_filename ().
(write_tm_preds_h): Likewise.
(write_insn_preds_c): Likewise.
* gensupport.c (class gen_reader): New subclass of rtx_reader.
(rtx_handle_directive): Convert to...
(gen_reader::handle_unknown_directive): ...this.
(init_rtx_reader_args_cb): Convert return type from bool to
rtx_reader *.  Create a gen_reader instance, using it for the
call to read_md_files.  Return it if no errors occur.
(init_rtx_reader_args): Convert return type from bool to
rtx_reader *.
* gensupport.h (init_rtx_reader_args_cb): Likewise.
(init_rtx_reader_args_cb): Likewise.
* read-md.c (struct file_name_list): Move to class rtx_reader.
(read_md_file): Delete in favor of rtx_reader::m_read_md_file.
(read_md_filename): Delete in favor of
rtx_reader::m_read_md_filename.
(read_md_lineno): Delete in favor of rtx_reader::m_read_md_lineno.
(in_fname): Delete in favor of rtx_reader::m_toplevel_fname.
(base_dir): Delete in favor of rtx_reader::m_base_dir.
(first_dir_md_include): Delete in favor of
rtx_reader::m_first_dir_md_include.
(last_dir_md_include_ptr): Delete in favor of
rtx_reader::m_last_dir_md_include_ptr.
(max_include_len): Delete.
(rtx_reader_ptr): New.
(fatal_with_file_and_line): Use get_filename and get_lineno
accessors of rtx_reader_ptr.
(require_char_ws): Likewise.
(rtx_reader::read_char): New method, based on ::read_char.
(rtx_reader::unread_char): New method, based on ::unread_char.
(read_escape): Use get_filename and get_lineno accessors of
rtx_reader_ptr.
(read_braced_string): Use get_lineno accessor of rtx_reader_ptr.
(read_string): Use get_filename and get_lineno accessors of
rtx_reader_ptr.
(rtx_reader::rtx_reader): New ctor.
(rtx_reader::~rtx_reader): New dtor.
(handle_include): Convert from a function to...
(rtx_reader::handle_include): ...this method, converting
handle_directive from a callback to a virtual function.
(handle_file): Likewise, converting to...
(rtx_reader::handle_file): ...this method.
(handle_toplevel_file): Likewise, converting to...
(rtx_reader::handle_toplevel_file): ...this method.
(rtx_reader::get_current_location): New method.
(parse_include): Convert from a function to...
(rtx_reader::add_include_path): ...this method, dropping redundant
update to unused max_include_len.
(read_md_files): Convert from a function to...
(rtx_reader::read_md_files): ...this method, converting
handle_directive from a callback to a virtual function.
(noop_reader::handle_unknown_directive): New method.
* read-md.h (directive_handler_t): Delete this typedef.
(in_fname): Delete.
(read_md_file): Delete.
(read_md_lineno): Delete.
(read_md_filename): Delete.
(class rtx_reader): New class.
(rtx_reader_ptr): New decl.
(class noop_reader): New subclass of rtx_reader.
(read_char): Reimplement in terms of rtx_reader::read_char.
(unread_char): Reimplement in terms of rtx_reader::unread_char.
(read_md_files): Delete.
* read-rtl.c (read_rtx_code): Update for deletion of globals
read_md_filename and read_md_lineno.

From-SVN: r240333

gcc/ChangeLog
gcc/genconstants.c
gcc/genenums.c
gcc/genmddeps.c
gcc/genpreds.c
gcc/gensupport.c
gcc/gensupport.h
gcc/read-md.c
gcc/read-md.h
gcc/read-rtl.c

index f38ace0ebb04544757fe683dc0a8d0b52652dfa4..cd4052595ae9bf17550dd42c5dd7c1b9bb221a17 100644 (file)
@@ -1,3 +1,77 @@
+2016-09-21  David Malcolm  <dmalcolm@redhat.com>
+
+       * genconstants.c (main): Introduce noop_reader and convert call
+       to read_md_files to a method call.
+       * genenums.c (main): Likewise.
+       * genmddeps.c (main): Likewise.
+       * genpreds.c (write_tm_constrs_h): Replace use of "in_fname" with
+       rtx_reader_ptr->get_top_level_filename ().
+       (write_tm_preds_h): Likewise.
+       (write_insn_preds_c): Likewise.
+       * gensupport.c (class gen_reader): New subclass of rtx_reader.
+       (rtx_handle_directive): Convert to...
+       (gen_reader::handle_unknown_directive): ...this.
+       (init_rtx_reader_args_cb): Convert return type from bool to
+       rtx_reader *.  Create a gen_reader instance, using it for the
+       call to read_md_files.  Return it if no errors occur.
+       (init_rtx_reader_args): Convert return type from bool to
+       rtx_reader *.
+       * gensupport.h (init_rtx_reader_args_cb): Likewise.
+       (init_rtx_reader_args_cb): Likewise.
+       * read-md.c (struct file_name_list): Move to class rtx_reader.
+       (read_md_file): Delete in favor of rtx_reader::m_read_md_file.
+       (read_md_filename): Delete in favor of
+       rtx_reader::m_read_md_filename.
+       (read_md_lineno): Delete in favor of rtx_reader::m_read_md_lineno.
+       (in_fname): Delete in favor of rtx_reader::m_toplevel_fname.
+       (base_dir): Delete in favor of rtx_reader::m_base_dir.
+       (first_dir_md_include): Delete in favor of
+       rtx_reader::m_first_dir_md_include.
+       (last_dir_md_include_ptr): Delete in favor of
+       rtx_reader::m_last_dir_md_include_ptr.
+       (max_include_len): Delete.
+       (rtx_reader_ptr): New.
+       (fatal_with_file_and_line): Use get_filename and get_lineno
+       accessors of rtx_reader_ptr.
+       (require_char_ws): Likewise.
+       (rtx_reader::read_char): New method, based on ::read_char.
+       (rtx_reader::unread_char): New method, based on ::unread_char.
+       (read_escape): Use get_filename and get_lineno accessors of
+       rtx_reader_ptr.
+       (read_braced_string): Use get_lineno accessor of rtx_reader_ptr.
+       (read_string): Use get_filename and get_lineno accessors of
+       rtx_reader_ptr.
+       (rtx_reader::rtx_reader): New ctor.
+       (rtx_reader::~rtx_reader): New dtor.
+       (handle_include): Convert from a function to...
+       (rtx_reader::handle_include): ...this method, converting
+       handle_directive from a callback to a virtual function.
+       (handle_file): Likewise, converting to...
+       (rtx_reader::handle_file): ...this method.
+       (handle_toplevel_file): Likewise, converting to...
+       (rtx_reader::handle_toplevel_file): ...this method.
+       (rtx_reader::get_current_location): New method.
+       (parse_include): Convert from a function to...
+       (rtx_reader::add_include_path): ...this method, dropping redundant
+       update to unused max_include_len.
+       (read_md_files): Convert from a function to...
+       (rtx_reader::read_md_files): ...this method, converting
+       handle_directive from a callback to a virtual function.
+       (noop_reader::handle_unknown_directive): New method.
+       * read-md.h (directive_handler_t): Delete this typedef.
+       (in_fname): Delete.
+       (read_md_file): Delete.
+       (read_md_lineno): Delete.
+       (read_md_filename): Delete.
+       (class rtx_reader): New class.
+       (rtx_reader_ptr): New decl.
+       (class noop_reader): New subclass of rtx_reader.
+       (read_char): Reimplement in terms of rtx_reader::read_char.
+       (unread_char): Reimplement in terms of rtx_reader::unread_char.
+       (read_md_files): Delete.
+       * read-rtl.c (read_rtx_code): Update for deletion of globals
+       read_md_filename and read_md_lineno.
+
 2016-09-21  Jason Merrill  <jason@redhat.com>
 
        * input.h (from_macro_definition_at): New.
index c10e3e34cd114298ed7dceb2ae23eeeed2c40a8d..e8be5b6d6736253773d4ff49239e3078f494afa1 100644 (file)
@@ -79,7 +79,8 @@ main (int argc, const char **argv)
 {
   progname = "genconstants";
 
-  if (!read_md_files (argc, argv, NULL, NULL))
+  noop_reader reader;
+  if (!reader.read_md_files (argc, argv, NULL))
     return (FATAL_EXIT_CODE);
 
   /* Initializing the MD reader has the side effect of loading up
index db46a67b59182b6867d093dbea0a226c81a4c9f0..8af8d9a41d4ab4d7c9fc5b50bd85dbd863c5a37a 100644 (file)
@@ -49,7 +49,8 @@ main (int argc, const char **argv)
 {
   progname = "genenums";
 
-  if (!read_md_files (argc, argv, NULL, NULL))
+  noop_reader reader;
+  if (!reader.read_md_files (argc, argv, NULL))
     return (FATAL_EXIT_CODE);
 
   puts ("/* Generated automatically by the program `genenums'");
index fd26a3335f417521a788c7d3b91e0542e988b658..e3d229d496d753395ec7abf8fe5897e3e9fd8109 100644 (file)
@@ -47,7 +47,8 @@ main (int argc, const char **argv)
   progname = "genmddeps";
   include_callback = add_filedep;
 
-  if (!read_md_files (argc, argv, NULL, NULL))
+  noop_reader reader;
+  if (!reader.read_md_files (argc, argv, NULL))
     return FATAL_EXIT_CODE;
 
   *last = NULL;
index 4c9dfc65664a5a15c1bff80d59ae675498769f55..96f75bd49f26a7e9cf6d6417655b5cc1064271cc 100644 (file)
@@ -1204,7 +1204,8 @@ write_tm_constrs_h (void)
 
   printf ("\
 /* Generated automatically by the program '%s'\n\
-   from the machine description file '%s'.  */\n\n", progname, in_fname);
+   from the machine description file '%s'.  */\n\n", progname,
+         rtx_reader_ptr->get_top_level_filename ());
 
   puts ("\
 #ifndef GCC_TM_CONSTRS_H\n\
@@ -1403,7 +1404,8 @@ write_tm_preds_h (void)
 
   printf ("\
 /* Generated automatically by the program '%s'\n\
-   from the machine description file '%s'.  */\n\n", progname, in_fname);
+   from the machine description file '%s'.  */\n\n", progname,
+         rtx_reader_ptr->get_top_level_filename ());
 
   puts ("\
 #ifndef GCC_TM_PREDS_H\n\
@@ -1552,7 +1554,8 @@ write_insn_preds_c (void)
 
   printf ("\
 /* Generated automatically by the program '%s'\n\
-   from the machine description file '%s'.  */\n\n", progname, in_fname);
+   from the machine description file '%s'.  */\n\n", progname,
+         rtx_reader_ptr->get_top_level_filename ());
 
   puts ("\
 #include \"config.h\"\n\
index 4645eadfff403ca591212d6d5414c7f773ee3a93..1648c9cc6493680b8dc95739bb6fdb099aecf7e0 100644 (file)
@@ -2225,10 +2225,18 @@ process_define_subst (void)
     }
 }
 \f
-/* A read_md_files callback for reading an rtx.  */
+/* A subclass of rtx_reader which reads .md files and calls process_rtx on
+   the top-level elements.  */
 
-static void
-rtx_handle_directive (file_location loc, const char *rtx_name)
+class gen_reader : public rtx_reader
+{
+ public:
+  gen_reader () : rtx_reader () {}
+  void handle_unknown_directive (file_location, const char *);
+};
+
+void
+gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
 {
   auto_vec<rtx, 32> subrtxs;
   if (!read_rtx (rtx_name, &subrtxs))
@@ -2499,7 +2507,7 @@ check_define_attr_duplicates ()
 
 /* The entry point for initializing the reader.  */
 
-bool
+rtx_reader *
 init_rtx_reader_args_cb (int argc, const char **argv,
                         bool (*parse_opt) (const char *))
 {
@@ -2515,7 +2523,8 @@ init_rtx_reader_args_cb (int argc, const char **argv,
   split_sequence_num = 1;
   peephole2_sequence_num = 1;
 
-  read_md_files (argc, argv, parse_opt, rtx_handle_directive);
+  gen_reader *reader = new gen_reader ();
+  reader->read_md_files (argc, argv, parse_opt);
 
   if (define_attr_queue != NULL)
     check_define_attr_duplicates ();
@@ -2531,12 +2540,18 @@ init_rtx_reader_args_cb (int argc, const char **argv,
   if (define_attr_queue != NULL)
     gen_mnemonic_attr ();
 
-  return !have_error;
+  if (have_error)
+    {
+      delete reader;
+      return NULL;
+    }
+
+  return reader;
 }
 
 /* Programs that don't have their own options can use this entry point
    instead.  */
-bool
+rtx_reader *
 init_rtx_reader_args (int argc, const char **argv)
 {
   return init_rtx_reader_args_cb (argc, argv, 0);
index 645512c23f4409bca4c359fb2899544751956768..618359dac942a8fd80e1de89136460345586c6c9 100644 (file)
@@ -125,9 +125,9 @@ struct optab_pattern
 };
 
 extern rtx add_implicit_parallel (rtvec);
-extern bool init_rtx_reader_args_cb (int, const char **,
-                                    bool (*)(const char *));
-extern bool init_rtx_reader_args (int, const char **);
+extern rtx_reader *init_rtx_reader_args_cb (int, const char **,
+                                           bool (*)(const char *));
+extern rtx_reader *init_rtx_reader_args (int, const char **);
 extern bool read_md_rtx (md_rtx_info *);
 extern unsigned int get_num_insn_codes ();
 
index b422d8dc75cad8f1bfb3c20b16d413948dfd870c..f069ba5a88d4a07419be7c45939f19d192bf19e6 100644 (file)
@@ -31,12 +31,6 @@ struct ptr_loc {
   int lineno;
 };
 
-/* A singly-linked list of filenames.  */
-struct file_name_list {
-  struct file_name_list *next;
-  const char *fname;
-};
-
 /* Obstack used for allocating MD strings.  */
 struct obstack string_obstack;
 
@@ -56,34 +50,13 @@ static htab_t joined_conditions;
 /* An obstack for allocating joined_conditions entries.  */
 static struct obstack joined_conditions_obstack;
 
-/* The file we are reading.  */
-FILE *read_md_file;
-
-/* The filename of READ_MD_FILE.  */
-const char *read_md_filename;
-
-/* The current line number in READ_MD_FILE.  */
-int read_md_lineno;
-
-/* The name of the toplevel file that indirectly included READ_MD_FILE.  */
-const char *in_fname;
-
-/* The directory part of IN_FNAME.  NULL if IN_FNAME is a bare filename.  */
-static char *base_dir;
-
-/* The first directory to search.  */
-static struct file_name_list *first_dir_md_include;
-
-/* A pointer to the null terminator of the md include chain.  */
-static struct file_name_list **last_dir_md_include_ptr = &first_dir_md_include;
-
 /* This callback will be invoked whenever an md include directive is
    processed.  To be used for creation of the dependency file.  */
 void (*include_callback) (const char *);
 
-/* The current maximum length of directory names in the search path
-   for include files.  (Altered as we get more of them.)  */
-static size_t max_include_len;
+/* Global singleton.  */
+
+rtx_reader *rtx_reader_ptr;
 
 /* A table of md_constant structures, hashed by name.  Null if no
    constant expansion should occur.  */
@@ -92,8 +65,6 @@ static htab_t md_constants;
 /* A table of enum_type structures, hashed by name.  */
 static htab_t enum_types;
 
-static void handle_file (directive_handler_t);
-
 /* Given an object that starts with a char * name field, return a hash
    code for its name.  */
 
@@ -303,7 +274,8 @@ fatal_with_file_and_line (const char *msg, ...)
 
   va_start (ap, msg);
 
-  fprintf (stderr, "%s:%d: ", read_md_filename, read_md_lineno);
+  fprintf (stderr, "%s:%d: error: ", rtx_reader_ptr->get_filename (),
+          rtx_reader_ptr->get_lineno ());
   vfprintf (stderr, msg, ap);
   putc ('\n', stderr);
 
@@ -322,8 +294,9 @@ fatal_with_file_and_line (const char *msg, ...)
     }
   context[i] = '\0';
 
-  fprintf (stderr, "%s:%d: following context is `%s'\n",
-          read_md_filename, read_md_lineno, context);
+  fprintf (stderr, "%s:%d: note: following context is `%s'\n",
+          rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
+          context);
 
   va_end (ap);
   exit (1);
@@ -402,6 +375,30 @@ require_char_ws (char expected)
     fatal_expected_char (expected, ch);
 }
 
+/* Read the next character from the file.  */
+
+int
+rtx_reader::read_char (void)
+{
+  int ch;
+
+  ch = getc (m_read_md_file);
+  if (ch == '\n')
+    m_read_md_lineno++;
+
+  return ch;
+}
+
+/* Put back CH, which was the last character read from the file.  */
+
+void
+rtx_reader::unread_char (int ch)
+{
+  if (ch == '\n')
+    m_read_md_lineno--;
+  ungetc (ch, m_read_md_file);
+}
+
 /* Read an rtx code name into NAME.  It is terminated by any of the
    punctuation chars of rtx printed syntax.  */
 
@@ -512,7 +509,8 @@ read_escape (void)
       /* pass anything else through, but issue a warning.  */
     default:
       fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
-              read_md_filename, read_md_lineno, c);
+              rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
+              c);
       obstack_1grow (&string_obstack, '\\');
       break;
     }
@@ -555,7 +553,7 @@ read_braced_string (void)
 {
   int c;
   int brace_depth = 1;  /* caller-processed */
-  unsigned long starting_read_md_lineno = read_md_lineno;
+  unsigned long starting_read_md_lineno = rtx_reader_ptr->get_lineno ();
 
   obstack_1grow (&string_obstack, '{');
   while (brace_depth)
@@ -601,7 +599,7 @@ read_string (int star_if_braced)
       c = read_skip_spaces ();
     }
 
-  old_lineno = read_md_lineno;
+  old_lineno = rtx_reader_ptr->get_lineno ();
   if (c == '"')
     stringbuf = read_quoted_string ();
   else if (c == '{')
@@ -616,7 +614,7 @@ read_string (int star_if_braced)
   if (saw_paren)
     require_char_ws (')');
 
-  set_md_ptr_loc (stringbuf, read_md_filename, old_lineno);
+  set_md_ptr_loc (stringbuf, rtx_reader_ptr->get_filename (), old_lineno);
   return stringbuf;
 }
 
@@ -901,13 +899,37 @@ traverse_enum_types (htab_trav callback, void *info)
   htab_traverse (enum_types, callback, info);
 }
 
+
+/* Constructor for rtx_reader.  */
+
+rtx_reader::rtx_reader ()
+: m_toplevel_fname (NULL),
+  m_base_dir (NULL),
+  m_read_md_file (NULL),
+  m_read_md_filename (NULL),
+  m_read_md_lineno (0),
+  m_first_dir_md_include (NULL),
+  m_last_dir_md_include_ptr (&m_first_dir_md_include)
+{
+  /* Set the global singleton pointer.  */
+  rtx_reader_ptr = this;
+}
+
+/* rtx_reader's destructor.  */
+
+rtx_reader::~rtx_reader ()
+{
+  /* Clear the global singleton pointer.  */
+  rtx_reader_ptr = NULL;
+}
+
 /* Process an "include" directive, starting with the optional space
    after the "include".  Read in the file and use HANDLE_DIRECTIVE
    to process each unknown directive.  LINENO is the line number on
    which the "include" occurred.  */
 
-static void
-handle_include (file_location loc, directive_handler_t handle_directive)
+void
+rtx_reader::handle_include (file_location loc)
 {
   const char *filename;
   const char *old_filename;
@@ -924,7 +946,7 @@ handle_include (file_location loc, directive_handler_t handle_directive)
       struct file_name_list *stackp;
 
       /* Search the directory path, trying to open the file.  */
-      for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
+      for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next)
        {
          static const char sep[2] = { DIR_SEPARATOR, '\0' };
 
@@ -940,8 +962,8 @@ handle_include (file_location loc, directive_handler_t handle_directive)
      filename with BASE_DIR.  */
   if (input_file == NULL)
     {
-      if (base_dir)
-       pathname = concat (base_dir, filename, NULL);
+      if (m_base_dir)
+       pathname = concat (m_base_dir, filename, NULL);
       else
        pathname = xstrdup (filename);
       input_file = fopen (pathname, "r");
@@ -957,21 +979,22 @@ handle_include (file_location loc, directive_handler_t handle_directive)
   /* Save the old cursor.  Note that the LINENO argument to this
      function is the beginning of the include statement, while
      read_md_lineno has already been advanced.  */
-  old_file = read_md_file;
-  old_filename = read_md_filename;
-  old_lineno = read_md_lineno;
+  old_file = m_read_md_file;
+  old_filename = m_read_md_filename;
+  old_lineno = m_read_md_lineno;
 
   if (include_callback)
     include_callback (pathname);
 
-  read_md_file = input_file;
-  read_md_filename = pathname;
-  handle_file (handle_directive);
+  m_read_md_file = input_file;
+  m_read_md_filename = pathname;
+
+  handle_file ();
 
   /* Restore the old cursor.  */
-  read_md_file = old_file;
-  read_md_filename = old_filename;
-  read_md_lineno = old_lineno;
+  m_read_md_file = old_file;
+  m_read_md_filename = old_filename;
+  m_read_md_lineno = old_lineno;
 
   /* Do not free the pathname.  It is attached to the various rtx
      queue elements.  */
@@ -981,16 +1004,16 @@ handle_include (file_location loc, directive_handler_t handle_directive)
    read_md_filename are valid.  Use HANDLE_DIRECTIVE to handle
    unknown directives.  */
 
-static void
-handle_file (directive_handler_t handle_directive)
+void
+rtx_reader::handle_file ()
 {
   struct md_name directive;
   int c;
 
-  read_md_lineno = 1;
+  m_read_md_lineno = 1;
   while ((c = read_skip_spaces ()) != EOF)
     {
-      file_location loc (read_md_filename, read_md_lineno);
+      file_location loc = get_current_location ();
       if (c != '(')
        fatal_expected_char ('(', c);
 
@@ -1002,49 +1025,51 @@ handle_file (directive_handler_t handle_directive)
       else if (strcmp (directive.string, "define_c_enum") == 0)
        handle_enum (loc, false);
       else if (strcmp (directive.string, "include") == 0)
-       handle_include (loc, handle_directive);
-      else if (handle_directive)
-       handle_directive (loc, directive.string);
+       handle_include (loc);
       else
-       read_skip_construct (1, loc);
+       handle_unknown_directive (loc, directive.string);
 
       require_char_ws (')');
     }
-  fclose (read_md_file);
+  fclose (m_read_md_file);
 }
 
-/* Like handle_file, but for top-level files.  Set up in_fname and
-   base_dir accordingly.  */
+/* Like handle_file, but for top-level files.  Set up m_toplevel_fname
+   and m_base_dir accordingly.  */
 
-static void
-handle_toplevel_file (directive_handler_t handle_directive)
+void
+rtx_reader::handle_toplevel_file ()
 {
   const char *base;
 
-  in_fname = read_md_filename;
-  base = lbasename (in_fname);
-  if (base == in_fname)
-    base_dir = NULL;
+  m_toplevel_fname = m_read_md_filename;
+  base = lbasename (m_toplevel_fname);
+  if (base == m_toplevel_fname)
+    m_base_dir = NULL;
   else
-    base_dir = xstrndup (in_fname, base - in_fname);
+    m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname);
+
+  handle_file ();
+}
 
-  handle_file (handle_directive);
+file_location
+rtx_reader::get_current_location () const
+{
+  return file_location (m_read_md_filename, m_read_md_lineno);
 }
 
 /* Parse a -I option with argument ARG.  */
 
-static void
-parse_include (const char *arg)
+void
+rtx_reader::add_include_path (const char *arg)
 {
   struct file_name_list *dirtmp;
 
   dirtmp = XNEW (struct file_name_list);
   dirtmp->next = 0;
   dirtmp->fname = arg;
-  *last_dir_md_include_ptr = dirtmp;
-  last_dir_md_include_ptr = &dirtmp->next;
-  if (strlen (dirtmp->fname) > max_include_len)
-    max_include_len = strlen (dirtmp->fname);
+  *m_last_dir_md_include_ptr = dirtmp;
+  m_last_dir_md_include_ptr = &dirtmp->next;
 }
 
 /* The main routine for reading .md files.  Try to process all the .md
@@ -1054,16 +1079,11 @@ parse_include (const char *arg)
 
    PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
    It should return true if it recognizes the argument or false if a
-   generic error should be reported.
-
-   If HANDLE_DIRECTIVE is nonnull, the parser calls it for each
-   unknown directive, otherwise it just skips such directives.
-   See the comment above the directive_handler_t definition for
-   details about the callback's interface.  */
+   generic error should be reported.  */
 
 bool
-read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
-              directive_handler_t handle_directive)
+rtx_reader::read_md_files (int argc, const char **argv,
+                          bool (*parse_opt) (const char *))
 {
   int i;
   bool no_more_options;
@@ -1101,9 +1121,9 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
        if (argv[i][1] == 'I')
          {
            if (argv[i][2] != '\0')
-             parse_include (argv[i] + 2);
+             add_include_path (argv[i] + 2);
            else if (++i < argc)
-             parse_include (argv[i]);
+             add_include_path (argv[i]);
            else
              fatal ("directory name missing after -I option");
            continue;
@@ -1131,9 +1151,9 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
              if (already_read_stdin)
                fatal ("cannot read standard input twice");
 
-             read_md_file = stdin;
-             read_md_filename = "<stdin>";
-             handle_toplevel_file (handle_directive);
+             m_read_md_file = stdin;
+             m_read_md_filename = "<stdin>";
+             handle_toplevel_file ();
              already_read_stdin = true;
              continue;
            }
@@ -1149,14 +1169,14 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
 
       /* If we get here we are looking at a non-option argument, i.e.
         a file to be processed.  */
-      read_md_filename = argv[i];
-      read_md_file = fopen (read_md_filename, "r");
-      if (read_md_file == 0)
+      m_read_md_filename = argv[i];
+      m_read_md_file = fopen (m_read_md_filename, "r");
+      if (m_read_md_file == 0)
        {
-         perror (read_md_filename);
+         perror (m_read_md_filename);
          return false;
        }
-      handle_toplevel_file (handle_directive);
+      handle_toplevel_file ();
       num_files++;
     }
 
@@ -1164,10 +1184,19 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
      read the standard input now.  */
   if (num_files == 0 && !already_read_stdin)
     {
-      read_md_file = stdin;
-      read_md_filename = "<stdin>";
-      handle_toplevel_file (handle_directive);
+      m_read_md_file = stdin;
+      m_read_md_filename = "<stdin>";
+      handle_toplevel_file ();
     }
 
   return !have_error;
 }
+
+/* class noop_reader : public rtx_reader */
+
+/* A dummy implementation which skips unknown directives.  */
+void
+noop_reader::handle_unknown_directive (file_location loc, const char *)
+{
+  read_skip_construct (1, loc);
+}
index fa259517a26bb49815a37a4178718df4e673f6fb..82a628bedfa2830a4e3e94dba3306b862ac9f5c9 100644 (file)
@@ -90,16 +90,81 @@ struct enum_type {
   unsigned int num_values;
 };
 
-/* A callback that handles a single .md-file directive, up to but not
-   including the closing ')'.  It takes two arguments: the file position
-   at which the directive started, and the name of the directive.  The next
-   unread character is the optional space after the directive name.  */
-typedef void (*directive_handler_t) (file_location, const char *);
-
-extern const char *in_fname;
-extern FILE *read_md_file;
-extern int read_md_lineno;
-extern const char *read_md_filename;
+class rtx_reader
+{
+ public:
+  rtx_reader ();
+  virtual ~rtx_reader ();
+
+  bool read_md_files (int, const char **, bool (*) (const char *));
+
+  /* A hook that handles a single .md-file directive, up to but not
+     including the closing ')'.  It takes two arguments: the file position
+     at which the directive started, and the name of the directive.  The next
+     unread character is the optional space after the directive name.  */
+  virtual void handle_unknown_directive (file_location, const char *) = 0;
+
+  file_location get_current_location () const;
+
+  int read_char (void);
+  void unread_char (int ch);
+
+  const char *get_top_level_filename () const { return m_toplevel_fname; }
+  const char *get_filename () const { return m_read_md_filename; }
+  int get_lineno () const { return m_read_md_lineno; }
+
+ private:
+  /* A singly-linked list of filenames.  */
+  struct file_name_list {
+    struct file_name_list *next;
+    const char *fname;
+  };
+
+ private:
+  void handle_file ();
+  void handle_toplevel_file ();
+  void handle_include (file_location loc);
+  void add_include_path (const char *arg);
+
+ private:
+  /* The name of the toplevel file that indirectly included
+     m_read_md_file.  */
+  const char *m_toplevel_fname;
+
+  /* The directory part of m_toplevel_fname
+     NULL if m_toplevel_fname is a bare filename.  */
+  char *m_base_dir;
+
+  /* The file we are reading.  */
+  FILE *m_read_md_file;
+
+  /* The filename of m_read_md_file.  */
+  const char *m_read_md_filename;
+
+  /* The current line number in m_read_md_file.  */
+  int m_read_md_lineno;
+
+  /* The first directory to search.  */
+  file_name_list *m_first_dir_md_include;
+
+  /* A pointer to the null terminator of the md include chain.  */
+  file_name_list **m_last_dir_md_include_ptr;
+};
+
+/* Global singleton.  */
+extern rtx_reader *rtx_reader_ptr;
+
+/* An rtx_reader subclass which skips unknown directives.  */
+
+class noop_reader : public rtx_reader
+{
+ public:
+  noop_reader () : rtx_reader () {}
+
+  /* A dummy implementation which skips unknown directives.  */
+  void handle_unknown_directive (file_location, const char *);
+};
+
 extern struct obstack string_obstack;
 extern void (*include_callback) (const char *);
 
@@ -108,12 +173,7 @@ extern void (*include_callback) (const char *);
 static inline int
 read_char (void)
 {
-  int ch;
-
-  ch = getc (read_md_file);
-  if (ch == '\n')
-    read_md_lineno++;
-  return ch;
+  return rtx_reader_ptr->read_char ();
 }
 
 /* Put back CH, which was the last character read from the MD file.  */
@@ -121,9 +181,7 @@ read_char (void)
 static inline void
 unread_char (int ch)
 {
-  if (ch == '\n')
-    read_md_lineno--;
-  ungetc (ch, read_md_file);
+  rtx_reader_ptr->unread_char (ch);
 }
 
 extern hashval_t leading_string_hash (const void *);
@@ -151,7 +209,5 @@ extern void upcase_string (char *);
 extern void traverse_md_constants (htab_trav, void *);
 extern void traverse_enum_types (htab_trav, void *);
 extern struct enum_type *lookup_enum_type (const char *);
-extern bool read_md_files (int, const char **, bool (*) (const char *),
-                          directive_handler_t);
 
 #endif /* GCC_READ_MD_H */
index 4614e356f7aa8b1263f9a85a866f3638a8292d86..eda938265c588a253e7baa1b93f5165bc2295c3e 100644 (file)
@@ -1234,6 +1234,7 @@ read_rtx_code (const char *code_name)
                  || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
            {
              char line_name[20];
+             const char *read_md_filename = rtx_reader_ptr->get_filename ();
              const char *fn = (read_md_filename ? read_md_filename : "rtx");
              const char *slash;
              for (slash = fn; *slash; slash ++)
@@ -1241,7 +1242,7 @@ read_rtx_code (const char *code_name)
                  fn = slash + 1;
              obstack_1grow (&string_obstack, '*');
              obstack_grow (&string_obstack, fn, strlen (fn));
-             sprintf (line_name, ":%d", read_md_lineno);
+             sprintf (line_name, ":%d", rtx_reader_ptr->get_lineno ());
              obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
              stringbuf = XOBFINISH (&string_obstack, char *);
            }