From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 81422 invoked by alias); 21 Sep 2016 16:27:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 81413 invoked by uid 89); 21 Sep 2016 16:27:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.0 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=sk:check_d, 1853, him, reader X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 21 Sep 2016 16:27:21 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7B3819D0C1; Wed, 21 Sep 2016 16:27:20 +0000 (UTC) Received: from c64.redhat.com (vpn-234-99.phx2.redhat.com [10.3.234.99]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8LGRJaB017228; Wed, 21 Sep 2016 12:27:19 -0400 From: David Malcolm To: Jeff Law , gcc-patches@gcc.gnu.org, Richard Sandiford Cc: David Malcolm Subject: [PATCH, v2] Introduce class rtx_reader Date: Wed, 21 Sep 2016 17:22:00 -0000 Message-Id: <1474477046-19647-1-git-send-email-dmalcolm@redhat.com> In-Reply-To: <332206d9-45f6-8502-1310-479b53ac3a62@redhat.com> References: <332206d9-45f6-8502-1310-479b53ac3a62@redhat.com> X-IsSubscribed: yes X-SW-Source: 2016-09/txt/msg01449.txt.bz2 On Fri, 2016-09-16 at 16:04 -0600, Jeff Law wrote: > On 09/08/2016 06:30 PM, David Malcolm wrote: > > 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. > I don't see anything terribly objectionable here. > > It looks like you use a singleton to avoid passing the object around > everywhere, but given the state of all this prior to this patch, I > can > live with the cleanup as a whole. Indeed; the point of the patch is to bundle up some global state to better allow the reader to be run more than once in-process, so that the RTL frontend can have selftests; having more than one reader *alive* at once is out-of-scope. Hence the use of a singleton, to minimize the amount of churn. > I'll note Richard Sandiford. hasn't chimed in here. You might ping > him > directly to see if he's got any feedback. If he doesn't prior to say > Wed, this is OK for the trunk. > > jeff Thanks. Here's a slightly tweaked version, fixing a couple of missing NULL initializations in the rtx_reader ctor (of m_base_dir and m_read_md_file), which avoids a crash for the file-not-found case. Successfully bootstrapped®rtested on x86_64-pc-linux-gnu. Richard: do you have any feedback on this? Otherwise, I'll assume this is still OK for trunk in a few days. 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. --- gcc/genconstants.c | 3 +- gcc/genenums.c | 3 +- gcc/genmddeps.c | 3 +- gcc/genpreds.c | 9 ++- gcc/gensupport.c | 29 +++++-- gcc/gensupport.h | 6 +- gcc/read-md.c | 227 ++++++++++++++++++++++++++++++----------------------- gcc/read-md.h | 98 ++++++++++++++++++----- gcc/read-rtl.c | 3 +- 9 files changed, 244 insertions(+), 137 deletions(-) diff --git a/gcc/genconstants.c b/gcc/genconstants.c index c10e3e3..e8be5b6 100644 --- a/gcc/genconstants.c +++ b/gcc/genconstants.c @@ -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 diff --git a/gcc/genenums.c b/gcc/genenums.c index db46a67..8af8d9a 100644 --- a/gcc/genenums.c +++ b/gcc/genenums.c @@ -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'"); diff --git a/gcc/genmddeps.c b/gcc/genmddeps.c index fd26a33..e3d229d 100644 --- a/gcc/genmddeps.c +++ b/gcc/genmddeps.c @@ -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; diff --git a/gcc/genpreds.c b/gcc/genpreds.c index 4c9dfc6..96f75bd 100644 --- a/gcc/genpreds.c +++ b/gcc/genpreds.c @@ -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\ diff --git a/gcc/gensupport.c b/gcc/gensupport.c index 4645ead..1648c9c 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -2225,10 +2225,18 @@ process_define_subst (void) } } -/* 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 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); diff --git a/gcc/gensupport.h b/gcc/gensupport.h index 645512c..618359d 100644 --- a/gcc/gensupport.h +++ b/gcc/gensupport.h @@ -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 (); diff --git a/gcc/read-md.c b/gcc/read-md.c index b422d8d..f069ba5 100644 --- a/gcc/read-md.c +++ b/gcc/read-md.c @@ -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 = ""; - handle_toplevel_file (handle_directive); + m_read_md_file = stdin; + m_read_md_filename = ""; + 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 = ""; - handle_toplevel_file (handle_directive); + m_read_md_file = stdin; + m_read_md_filename = ""; + 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); +} diff --git a/gcc/read-md.h b/gcc/read-md.h index fa25951..82a628b 100644 --- a/gcc/read-md.h +++ b/gcc/read-md.h @@ -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 */ diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 4614e35..eda9382 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -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 *); } -- 1.8.5.3