From: David Malcolm <dmalcolm@redhat.com>
To: Jeff Law <law@redhat.com>,
gcc-patches@gcc.gnu.org,
Richard Sandiford <rdsandiford@googlemail.com>
Cc: David Malcolm <dmalcolm@redhat.com>
Subject: [PATCH, v2] Introduce class rtx_reader
Date: Wed, 21 Sep 2016 17:22:00 -0000 [thread overview]
Message-ID: <1474477046-19647-1-git-send-email-dmalcolm@redhat.com> (raw)
In-Reply-To: <332206d9-45f6-8502-1310-479b53ac3a62@redhat.com>
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)
}
}
\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);
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 = "<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);
+}
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
next prev parent reply other threads:[~2016-09-21 16:27 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-09 0:01 [PATCH 0/9] RFC: selftests based on RTL dumps David Malcolm
2016-09-09 0:01 ` [PATCH 1/9] Introduce class rtx_reader David Malcolm
2016-09-16 22:15 ` Jeff Law
2016-09-21 17:22 ` David Malcolm [this message]
2016-09-21 20:44 ` [PATCH, v2] " Richard Sandiford
2016-09-09 0:01 ` [PATCH 8/9] final.c selftests David Malcolm
2016-09-16 21:12 ` Jeff Law
2016-09-16 21:41 ` David Malcolm
2016-09-19 21:38 ` Jeff Law
2016-09-09 0:01 ` [PATCH 2/9] Add selftest::read_file David Malcolm
2016-09-16 21:19 ` Jeff Law
2016-09-09 0:01 ` [PATCH 3/9] selftest.h: add temp_override fixture David Malcolm
2016-09-14 22:24 ` Trevor Saunders
2016-09-16 20:37 ` Jeff Law
2016-09-09 0:01 ` [PATCH 7/9] combine.c selftests David Malcolm
2016-09-16 20:45 ` Jeff Law
2016-09-16 21:39 ` David Malcolm
2016-09-09 0:01 ` [PATCH 9/9] cse.c selftests David Malcolm
2016-09-16 20:34 ` Jeff Law
2016-09-16 21:28 ` David Malcolm
2016-09-19 17:37 ` Jeff Law
2016-09-22 3:23 ` [PATCH] Introduce selftest::locate_file David Malcolm
2016-09-28 16:33 ` Jeff Law
2016-09-09 0:01 ` [PATCH 4/9] Expose forcibly_ggc_collect and run it after all selftests David Malcolm
2016-09-16 20:30 ` Jeff Law
2016-09-09 0:01 ` [PATCH 6/9] df selftests David Malcolm
2016-09-16 20:40 ` Jeff Law
2016-09-16 21:34 ` David Malcolm
2016-09-09 0:13 ` [PATCH 5/9] Introduce class function_reader David Malcolm
2016-09-16 21:31 ` Jeff Law
2016-09-16 22:04 ` David Malcolm
2016-09-19 21:39 ` Jeff Law
2016-09-12 14:14 ` [PATCH 0/9] RFC: selftests based on RTL dumps Bernd Schmidt
2016-09-12 18:59 ` David Malcolm
2016-09-13 11:35 ` Bernd Schmidt
2016-09-14 10:33 ` Bernd Schmidt
2016-09-16 20:26 ` Jeff Law
2016-09-16 21:28 ` David Malcolm
2016-09-19 17:50 ` Jeff Law
2016-09-20 14:34 ` Register numbers in RTL dumps (was Re: [PATCH 0/9] RFC: selftests based on RTL dumps) David Malcolm
2016-09-20 14:38 ` Bernd Schmidt
2016-09-20 15:26 ` Jeff Law
2016-09-20 15:38 ` Bernd Schmidt
2016-09-20 19:35 ` David Malcolm
2016-09-21 18:59 ` [PATCH] print-rtx.c: add 'h', v' and 'p' prefixes to regnos David Malcolm
2016-09-28 16:30 ` Jeff Law
2016-09-28 16:33 ` Bernd Schmidt
2016-09-28 17:11 ` Jeff Law
2016-09-28 17:19 ` Bernd Schmidt
2016-09-29 13:00 ` David Malcolm
2016-09-29 17:32 ` Jeff Law
2016-09-13 20:39 ` [PATCH 0/9] RFC: selftests based on RTL dumps Jeff Law
2016-09-14 8:44 ` Richard Biener
2016-09-16 20:16 ` Jeff Law
2016-09-16 21:27 ` David Malcolm
2016-09-19 12:21 ` Bernd Schmidt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1474477046-19647-1-git-send-email-dmalcolm@redhat.com \
--to=dmalcolm@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=law@redhat.com \
--cc=rdsandiford@googlemail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).