Commit 812b1403 by David Malcolm Committed by David Malcolm

Introduce class rtx_reader

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
parent 0d715437
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> 2016-09-21 Jason Merrill <jason@redhat.com>
* input.h (from_macro_definition_at): New. * input.h (from_macro_definition_at): New.
......
...@@ -79,7 +79,8 @@ main (int argc, const char **argv) ...@@ -79,7 +79,8 @@ main (int argc, const char **argv)
{ {
progname = "genconstants"; 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); return (FATAL_EXIT_CODE);
/* Initializing the MD reader has the side effect of loading up /* Initializing the MD reader has the side effect of loading up
......
...@@ -49,7 +49,8 @@ main (int argc, const char **argv) ...@@ -49,7 +49,8 @@ main (int argc, const char **argv)
{ {
progname = "genenums"; 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); return (FATAL_EXIT_CODE);
puts ("/* Generated automatically by the program `genenums'"); puts ("/* Generated automatically by the program `genenums'");
......
...@@ -47,7 +47,8 @@ main (int argc, const char **argv) ...@@ -47,7 +47,8 @@ main (int argc, const char **argv)
progname = "genmddeps"; progname = "genmddeps";
include_callback = add_filedep; 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; return FATAL_EXIT_CODE;
*last = NULL; *last = NULL;
......
...@@ -1204,7 +1204,8 @@ write_tm_constrs_h (void) ...@@ -1204,7 +1204,8 @@ write_tm_constrs_h (void)
printf ("\ printf ("\
/* Generated automatically by the program '%s'\n\ /* 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 ("\ puts ("\
#ifndef GCC_TM_CONSTRS_H\n\ #ifndef GCC_TM_CONSTRS_H\n\
...@@ -1403,7 +1404,8 @@ write_tm_preds_h (void) ...@@ -1403,7 +1404,8 @@ write_tm_preds_h (void)
printf ("\ printf ("\
/* Generated automatically by the program '%s'\n\ /* 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 ("\ puts ("\
#ifndef GCC_TM_PREDS_H\n\ #ifndef GCC_TM_PREDS_H\n\
...@@ -1552,7 +1554,8 @@ write_insn_preds_c (void) ...@@ -1552,7 +1554,8 @@ write_insn_preds_c (void)
printf ("\ printf ("\
/* Generated automatically by the program '%s'\n\ /* 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 ("\ puts ("\
#include \"config.h\"\n\ #include \"config.h\"\n\
......
...@@ -2225,10 +2225,18 @@ process_define_subst (void) ...@@ -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 class gen_reader : public rtx_reader
rtx_handle_directive (file_location loc, const char *rtx_name) {
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; auto_vec<rtx, 32> subrtxs;
if (!read_rtx (rtx_name, &subrtxs)) if (!read_rtx (rtx_name, &subrtxs))
...@@ -2499,7 +2507,7 @@ check_define_attr_duplicates () ...@@ -2499,7 +2507,7 @@ check_define_attr_duplicates ()
/* The entry point for initializing the reader. */ /* The entry point for initializing the reader. */
bool rtx_reader *
init_rtx_reader_args_cb (int argc, const char **argv, init_rtx_reader_args_cb (int argc, const char **argv,
bool (*parse_opt) (const char *)) bool (*parse_opt) (const char *))
{ {
...@@ -2515,7 +2523,8 @@ init_rtx_reader_args_cb (int argc, const char **argv, ...@@ -2515,7 +2523,8 @@ init_rtx_reader_args_cb (int argc, const char **argv,
split_sequence_num = 1; split_sequence_num = 1;
peephole2_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) if (define_attr_queue != NULL)
check_define_attr_duplicates (); check_define_attr_duplicates ();
...@@ -2531,12 +2540,18 @@ init_rtx_reader_args_cb (int argc, const char **argv, ...@@ -2531,12 +2540,18 @@ init_rtx_reader_args_cb (int argc, const char **argv,
if (define_attr_queue != NULL) if (define_attr_queue != NULL)
gen_mnemonic_attr (); 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 /* Programs that don't have their own options can use this entry point
instead. */ instead. */
bool rtx_reader *
init_rtx_reader_args (int argc, const char **argv) init_rtx_reader_args (int argc, const char **argv)
{ {
return init_rtx_reader_args_cb (argc, argv, 0); return init_rtx_reader_args_cb (argc, argv, 0);
......
...@@ -125,9 +125,9 @@ struct optab_pattern ...@@ -125,9 +125,9 @@ struct optab_pattern
}; };
extern rtx add_implicit_parallel (rtvec); extern rtx add_implicit_parallel (rtvec);
extern bool init_rtx_reader_args_cb (int, const char **, extern rtx_reader *init_rtx_reader_args_cb (int, const char **,
bool (*)(const char *)); bool (*)(const char *));
extern bool init_rtx_reader_args (int, const char **); extern rtx_reader *init_rtx_reader_args (int, const char **);
extern bool read_md_rtx (md_rtx_info *); extern bool read_md_rtx (md_rtx_info *);
extern unsigned int get_num_insn_codes (); extern unsigned int get_num_insn_codes ();
......
...@@ -31,12 +31,6 @@ struct ptr_loc { ...@@ -31,12 +31,6 @@ struct ptr_loc {
int lineno; 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. */ /* Obstack used for allocating MD strings. */
struct obstack string_obstack; struct obstack string_obstack;
...@@ -56,34 +50,13 @@ static htab_t joined_conditions; ...@@ -56,34 +50,13 @@ static htab_t joined_conditions;
/* An obstack for allocating joined_conditions entries. */ /* An obstack for allocating joined_conditions entries. */
static struct obstack joined_conditions_obstack; 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 /* This callback will be invoked whenever an md include directive is
processed. To be used for creation of the dependency file. */ processed. To be used for creation of the dependency file. */
void (*include_callback) (const char *); void (*include_callback) (const char *);
/* The current maximum length of directory names in the search path /* Global singleton. */
for include files. (Altered as we get more of them.) */
static size_t max_include_len; rtx_reader *rtx_reader_ptr;
/* A table of md_constant structures, hashed by name. Null if no /* A table of md_constant structures, hashed by name. Null if no
constant expansion should occur. */ constant expansion should occur. */
...@@ -92,8 +65,6 @@ static htab_t md_constants; ...@@ -92,8 +65,6 @@ static htab_t md_constants;
/* A table of enum_type structures, hashed by name. */ /* A table of enum_type structures, hashed by name. */
static htab_t enum_types; 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 /* Given an object that starts with a char * name field, return a hash
code for its name. */ code for its name. */
...@@ -303,7 +274,8 @@ fatal_with_file_and_line (const char *msg, ...) ...@@ -303,7 +274,8 @@ fatal_with_file_and_line (const char *msg, ...)
va_start (ap, 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); vfprintf (stderr, msg, ap);
putc ('\n', stderr); putc ('\n', stderr);
...@@ -322,8 +294,9 @@ fatal_with_file_and_line (const char *msg, ...) ...@@ -322,8 +294,9 @@ fatal_with_file_and_line (const char *msg, ...)
} }
context[i] = '\0'; context[i] = '\0';
fprintf (stderr, "%s:%d: following context is `%s'\n", fprintf (stderr, "%s:%d: note: following context is `%s'\n",
read_md_filename, read_md_lineno, context); rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
context);
va_end (ap); va_end (ap);
exit (1); exit (1);
...@@ -402,6 +375,30 @@ require_char_ws (char expected) ...@@ -402,6 +375,30 @@ require_char_ws (char expected)
fatal_expected_char (expected, ch); 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 /* Read an rtx code name into NAME. It is terminated by any of the
punctuation chars of rtx printed syntax. */ punctuation chars of rtx printed syntax. */
...@@ -512,7 +509,8 @@ read_escape (void) ...@@ -512,7 +509,8 @@ read_escape (void)
/* pass anything else through, but issue a warning. */ /* pass anything else through, but issue a warning. */
default: default:
fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n", 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, '\\'); obstack_1grow (&string_obstack, '\\');
break; break;
} }
...@@ -555,7 +553,7 @@ read_braced_string (void) ...@@ -555,7 +553,7 @@ read_braced_string (void)
{ {
int c; int c;
int brace_depth = 1; /* caller-processed */ 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, '{'); obstack_1grow (&string_obstack, '{');
while (brace_depth) while (brace_depth)
...@@ -601,7 +599,7 @@ read_string (int star_if_braced) ...@@ -601,7 +599,7 @@ read_string (int star_if_braced)
c = read_skip_spaces (); c = read_skip_spaces ();
} }
old_lineno = read_md_lineno; old_lineno = rtx_reader_ptr->get_lineno ();
if (c == '"') if (c == '"')
stringbuf = read_quoted_string (); stringbuf = read_quoted_string ();
else if (c == '{') else if (c == '{')
...@@ -616,7 +614,7 @@ read_string (int star_if_braced) ...@@ -616,7 +614,7 @@ read_string (int star_if_braced)
if (saw_paren) if (saw_paren)
require_char_ws (')'); 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; return stringbuf;
} }
...@@ -901,13 +899,37 @@ traverse_enum_types (htab_trav callback, void *info) ...@@ -901,13 +899,37 @@ traverse_enum_types (htab_trav callback, void *info)
htab_traverse (enum_types, callback, 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 /* Process an "include" directive, starting with the optional space
after the "include". Read in the file and use HANDLE_DIRECTIVE after the "include". Read in the file and use HANDLE_DIRECTIVE
to process each unknown directive. LINENO is the line number on to process each unknown directive. LINENO is the line number on
which the "include" occurred. */ which the "include" occurred. */
static void void
handle_include (file_location loc, directive_handler_t handle_directive) rtx_reader::handle_include (file_location loc)
{ {
const char *filename; const char *filename;
const char *old_filename; const char *old_filename;
...@@ -924,7 +946,7 @@ handle_include (file_location loc, directive_handler_t handle_directive) ...@@ -924,7 +946,7 @@ handle_include (file_location loc, directive_handler_t handle_directive)
struct file_name_list *stackp; struct file_name_list *stackp;
/* Search the directory path, trying to open the file. */ /* 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' }; static const char sep[2] = { DIR_SEPARATOR, '\0' };
...@@ -940,8 +962,8 @@ handle_include (file_location loc, directive_handler_t handle_directive) ...@@ -940,8 +962,8 @@ handle_include (file_location loc, directive_handler_t handle_directive)
filename with BASE_DIR. */ filename with BASE_DIR. */
if (input_file == NULL) if (input_file == NULL)
{ {
if (base_dir) if (m_base_dir)
pathname = concat (base_dir, filename, NULL); pathname = concat (m_base_dir, filename, NULL);
else else
pathname = xstrdup (filename); pathname = xstrdup (filename);
input_file = fopen (pathname, "r"); input_file = fopen (pathname, "r");
...@@ -957,21 +979,22 @@ handle_include (file_location loc, directive_handler_t handle_directive) ...@@ -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 /* Save the old cursor. Note that the LINENO argument to this
function is the beginning of the include statement, while function is the beginning of the include statement, while
read_md_lineno has already been advanced. */ read_md_lineno has already been advanced. */
old_file = read_md_file; old_file = m_read_md_file;
old_filename = read_md_filename; old_filename = m_read_md_filename;
old_lineno = read_md_lineno; old_lineno = m_read_md_lineno;
if (include_callback) if (include_callback)
include_callback (pathname); include_callback (pathname);
read_md_file = input_file; m_read_md_file = input_file;
read_md_filename = pathname; m_read_md_filename = pathname;
handle_file (handle_directive);
handle_file ();
/* Restore the old cursor. */ /* Restore the old cursor. */
read_md_file = old_file; m_read_md_file = old_file;
read_md_filename = old_filename; m_read_md_filename = old_filename;
read_md_lineno = old_lineno; m_read_md_lineno = old_lineno;
/* Do not free the pathname. It is attached to the various rtx /* Do not free the pathname. It is attached to the various rtx
queue elements. */ queue elements. */
...@@ -981,16 +1004,16 @@ handle_include (file_location loc, directive_handler_t handle_directive) ...@@ -981,16 +1004,16 @@ handle_include (file_location loc, directive_handler_t handle_directive)
read_md_filename are valid. Use HANDLE_DIRECTIVE to handle read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
unknown directives. */ unknown directives. */
static void void
handle_file (directive_handler_t handle_directive) rtx_reader::handle_file ()
{ {
struct md_name directive; struct md_name directive;
int c; int c;
read_md_lineno = 1; m_read_md_lineno = 1;
while ((c = read_skip_spaces ()) != EOF) while ((c = read_skip_spaces ()) != EOF)
{ {
file_location loc (read_md_filename, read_md_lineno); file_location loc = get_current_location ();
if (c != '(') if (c != '(')
fatal_expected_char ('(', c); fatal_expected_char ('(', c);
...@@ -1002,49 +1025,51 @@ handle_file (directive_handler_t handle_directive) ...@@ -1002,49 +1025,51 @@ handle_file (directive_handler_t handle_directive)
else if (strcmp (directive.string, "define_c_enum") == 0) else if (strcmp (directive.string, "define_c_enum") == 0)
handle_enum (loc, false); handle_enum (loc, false);
else if (strcmp (directive.string, "include") == 0) else if (strcmp (directive.string, "include") == 0)
handle_include (loc, handle_directive); handle_include (loc);
else if (handle_directive)
handle_directive (loc, directive.string);
else else
read_skip_construct (1, loc); handle_unknown_directive (loc, directive.string);
require_char_ws (')'); 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 /* Like handle_file, but for top-level files. Set up m_toplevel_fname
base_dir accordingly. */ and m_base_dir accordingly. */
static void void
handle_toplevel_file (directive_handler_t handle_directive) rtx_reader::handle_toplevel_file ()
{ {
const char *base; const char *base;
in_fname = read_md_filename; m_toplevel_fname = m_read_md_filename;
base = lbasename (in_fname); base = lbasename (m_toplevel_fname);
if (base == in_fname) if (base == m_toplevel_fname)
base_dir = NULL; m_base_dir = NULL;
else 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. */ /* Parse a -I option with argument ARG. */
static void void
parse_include (const char *arg) rtx_reader::add_include_path (const char *arg)
{ {
struct file_name_list *dirtmp; struct file_name_list *dirtmp;
dirtmp = XNEW (struct file_name_list); dirtmp = XNEW (struct file_name_list);
dirtmp->next = 0; dirtmp->next = 0;
dirtmp->fname = arg; dirtmp->fname = arg;
*last_dir_md_include_ptr = dirtmp; *m_last_dir_md_include_ptr = dirtmp;
last_dir_md_include_ptr = &dirtmp->next; m_last_dir_md_include_ptr = &dirtmp->next;
if (strlen (dirtmp->fname) > max_include_len)
max_include_len = strlen (dirtmp->fname);
} }
/* The main routine for reading .md files. Try to process all the .md /* The main routine for reading .md files. Try to process all the .md
...@@ -1054,16 +1079,11 @@ parse_include (const char *arg) ...@@ -1054,16 +1079,11 @@ parse_include (const char *arg)
PARSE_OPT, if nonnull, is passed all unknown command-line arguments. PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
It should return true if it recognizes the argument or false if a It should return true if it recognizes the argument or false if a
generic error should be reported. 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. */
bool bool
read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *), rtx_reader::read_md_files (int argc, const char **argv,
directive_handler_t handle_directive) bool (*parse_opt) (const char *))
{ {
int i; int i;
bool no_more_options; bool no_more_options;
...@@ -1101,9 +1121,9 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *), ...@@ -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][1] == 'I')
{ {
if (argv[i][2] != '\0') if (argv[i][2] != '\0')
parse_include (argv[i] + 2); add_include_path (argv[i] + 2);
else if (++i < argc) else if (++i < argc)
parse_include (argv[i]); add_include_path (argv[i]);
else else
fatal ("directory name missing after -I option"); fatal ("directory name missing after -I option");
continue; continue;
...@@ -1131,9 +1151,9 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *), ...@@ -1131,9 +1151,9 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
if (already_read_stdin) if (already_read_stdin)
fatal ("cannot read standard input twice"); fatal ("cannot read standard input twice");
read_md_file = stdin; m_read_md_file = stdin;
read_md_filename = "<stdin>"; m_read_md_filename = "<stdin>";
handle_toplevel_file (handle_directive); handle_toplevel_file ();
already_read_stdin = true; already_read_stdin = true;
continue; continue;
} }
...@@ -1149,14 +1169,14 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *), ...@@ -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. /* If we get here we are looking at a non-option argument, i.e.
a file to be processed. */ a file to be processed. */
read_md_filename = argv[i]; m_read_md_filename = argv[i];
read_md_file = fopen (read_md_filename, "r"); m_read_md_file = fopen (m_read_md_filename, "r");
if (read_md_file == 0) if (m_read_md_file == 0)
{ {
perror (read_md_filename); perror (m_read_md_filename);
return false; return false;
} }
handle_toplevel_file (handle_directive); handle_toplevel_file ();
num_files++; num_files++;
} }
...@@ -1164,10 +1184,19 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *), ...@@ -1164,10 +1184,19 @@ read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
read the standard input now. */ read the standard input now. */
if (num_files == 0 && !already_read_stdin) if (num_files == 0 && !already_read_stdin)
{ {
read_md_file = stdin; m_read_md_file = stdin;
read_md_filename = "<stdin>"; m_read_md_filename = "<stdin>";
handle_toplevel_file (handle_directive); handle_toplevel_file ();
} }
return !have_error; 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);
}
...@@ -90,16 +90,81 @@ struct enum_type { ...@@ -90,16 +90,81 @@ struct enum_type {
unsigned int num_values; unsigned int num_values;
}; };
/* A callback that handles a single .md-file directive, up to but not 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 including the closing ')'. It takes two arguments: the file position
at which the directive started, and the name of the directive. The next at which the directive started, and the name of the directive. The next
unread character is the optional space after the directive name. */ unread character is the optional space after the directive name. */
typedef void (*directive_handler_t) (file_location, const char *); 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 const char *in_fname;
extern FILE *read_md_file;
extern int read_md_lineno;
extern const char *read_md_filename;
extern struct obstack string_obstack; extern struct obstack string_obstack;
extern void (*include_callback) (const char *); extern void (*include_callback) (const char *);
...@@ -108,12 +173,7 @@ extern void (*include_callback) (const char *); ...@@ -108,12 +173,7 @@ extern void (*include_callback) (const char *);
static inline int static inline int
read_char (void) read_char (void)
{ {
int ch; return rtx_reader_ptr->read_char ();
ch = getc (read_md_file);
if (ch == '\n')
read_md_lineno++;
return ch;
} }
/* Put back CH, which was the last character read from the MD file. */ /* Put back CH, which was the last character read from the MD file. */
...@@ -121,9 +181,7 @@ read_char (void) ...@@ -121,9 +181,7 @@ read_char (void)
static inline void static inline void
unread_char (int ch) unread_char (int ch)
{ {
if (ch == '\n') rtx_reader_ptr->unread_char (ch);
read_md_lineno--;
ungetc (ch, read_md_file);
} }
extern hashval_t leading_string_hash (const void *); extern hashval_t leading_string_hash (const void *);
...@@ -151,7 +209,5 @@ extern void upcase_string (char *); ...@@ -151,7 +209,5 @@ extern void upcase_string (char *);
extern void traverse_md_constants (htab_trav, void *); extern void traverse_md_constants (htab_trav, void *);
extern void traverse_enum_types (htab_trav, void *); extern void traverse_enum_types (htab_trav, void *);
extern struct enum_type *lookup_enum_type (const char *); 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 */ #endif /* GCC_READ_MD_H */
...@@ -1234,6 +1234,7 @@ read_rtx_code (const char *code_name) ...@@ -1234,6 +1234,7 @@ read_rtx_code (const char *code_name)
|| GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT)) || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
{ {
char line_name[20]; 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 *fn = (read_md_filename ? read_md_filename : "rtx");
const char *slash; const char *slash;
for (slash = fn; *slash; slash ++) for (slash = fn; *slash; slash ++)
...@@ -1241,7 +1242,7 @@ read_rtx_code (const char *code_name) ...@@ -1241,7 +1242,7 @@ read_rtx_code (const char *code_name)
fn = slash + 1; fn = slash + 1;
obstack_1grow (&string_obstack, '*'); obstack_1grow (&string_obstack, '*');
obstack_grow (&string_obstack, fn, strlen (fn)); 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); obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
stringbuf = XOBFINISH (&string_obstack, char *); stringbuf = XOBFINISH (&string_obstack, char *);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment