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
This commit is contained in:
parent
0d7154371d
commit
812b1403a8
@ -1,3 +1,77 @@
|
||||
2016-09-21 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* genconstants.c (main): Introduce noop_reader and convert call
|
||||
to read_md_files to a method call.
|
||||
* genenums.c (main): Likewise.
|
||||
* genmddeps.c (main): Likewise.
|
||||
* genpreds.c (write_tm_constrs_h): Replace use of "in_fname" with
|
||||
rtx_reader_ptr->get_top_level_filename ().
|
||||
(write_tm_preds_h): Likewise.
|
||||
(write_insn_preds_c): Likewise.
|
||||
* gensupport.c (class gen_reader): New subclass of rtx_reader.
|
||||
(rtx_handle_directive): Convert to...
|
||||
(gen_reader::handle_unknown_directive): ...this.
|
||||
(init_rtx_reader_args_cb): Convert return type from bool to
|
||||
rtx_reader *. Create a gen_reader instance, using it for the
|
||||
call to read_md_files. Return it if no errors occur.
|
||||
(init_rtx_reader_args): Convert return type from bool to
|
||||
rtx_reader *.
|
||||
* gensupport.h (init_rtx_reader_args_cb): Likewise.
|
||||
(init_rtx_reader_args_cb): Likewise.
|
||||
* read-md.c (struct file_name_list): Move to class rtx_reader.
|
||||
(read_md_file): Delete in favor of rtx_reader::m_read_md_file.
|
||||
(read_md_filename): Delete in favor of
|
||||
rtx_reader::m_read_md_filename.
|
||||
(read_md_lineno): Delete in favor of rtx_reader::m_read_md_lineno.
|
||||
(in_fname): Delete in favor of rtx_reader::m_toplevel_fname.
|
||||
(base_dir): Delete in favor of rtx_reader::m_base_dir.
|
||||
(first_dir_md_include): Delete in favor of
|
||||
rtx_reader::m_first_dir_md_include.
|
||||
(last_dir_md_include_ptr): Delete in favor of
|
||||
rtx_reader::m_last_dir_md_include_ptr.
|
||||
(max_include_len): Delete.
|
||||
(rtx_reader_ptr): New.
|
||||
(fatal_with_file_and_line): Use get_filename and get_lineno
|
||||
accessors of rtx_reader_ptr.
|
||||
(require_char_ws): Likewise.
|
||||
(rtx_reader::read_char): New method, based on ::read_char.
|
||||
(rtx_reader::unread_char): New method, based on ::unread_char.
|
||||
(read_escape): Use get_filename and get_lineno accessors of
|
||||
rtx_reader_ptr.
|
||||
(read_braced_string): Use get_lineno accessor of rtx_reader_ptr.
|
||||
(read_string): Use get_filename and get_lineno accessors of
|
||||
rtx_reader_ptr.
|
||||
(rtx_reader::rtx_reader): New ctor.
|
||||
(rtx_reader::~rtx_reader): New dtor.
|
||||
(handle_include): Convert from a function to...
|
||||
(rtx_reader::handle_include): ...this method, converting
|
||||
handle_directive from a callback to a virtual function.
|
||||
(handle_file): Likewise, converting to...
|
||||
(rtx_reader::handle_file): ...this method.
|
||||
(handle_toplevel_file): Likewise, converting to...
|
||||
(rtx_reader::handle_toplevel_file): ...this method.
|
||||
(rtx_reader::get_current_location): New method.
|
||||
(parse_include): Convert from a function to...
|
||||
(rtx_reader::add_include_path): ...this method, dropping redundant
|
||||
update to unused max_include_len.
|
||||
(read_md_files): Convert from a function to...
|
||||
(rtx_reader::read_md_files): ...this method, converting
|
||||
handle_directive from a callback to a virtual function.
|
||||
(noop_reader::handle_unknown_directive): New method.
|
||||
* read-md.h (directive_handler_t): Delete this typedef.
|
||||
(in_fname): Delete.
|
||||
(read_md_file): Delete.
|
||||
(read_md_lineno): Delete.
|
||||
(read_md_filename): Delete.
|
||||
(class rtx_reader): New class.
|
||||
(rtx_reader_ptr): New decl.
|
||||
(class noop_reader): New subclass of rtx_reader.
|
||||
(read_char): Reimplement in terms of rtx_reader::read_char.
|
||||
(unread_char): Reimplement in terms of rtx_reader::unread_char.
|
||||
(read_md_files): Delete.
|
||||
* read-rtl.c (read_rtx_code): Update for deletion of globals
|
||||
read_md_filename and read_md_lineno.
|
||||
|
||||
2016-09-21 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* input.h (from_macro_definition_at): New.
|
||||
|
@ -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
|
||||
|
@ -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'");
|
||||
|
@ -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;
|
||||
|
@ -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\
|
||||
|
@ -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<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);
|
||||
|
@ -125,9 +125,9 @@ struct optab_pattern
|
||||
};
|
||||
|
||||
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 *));
|
||||
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 unsigned int get_num_insn_codes ();
|
||||
|
||||
|
227
gcc/read-md.c
227
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_directive);
|
||||
handle_file ();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -90,16 +90,81 @@ struct enum_type {
|
||||
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
|
||||
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 *);
|
||||
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 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 */
|
||||
|
@ -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 *);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user