]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/read-md.c
[PR89528] reset debug uses of return value when dropping dead RTL call
[thirdparty/gcc.git] / gcc / read-md.c
index 6fe26000eb5db5995b59e0ba5e5f77bcefa970b3..8247640bd0d03f2cdcd0ffb92d294246c8620ddb 100644 (file)
@@ -1,5 +1,5 @@
 /* MD reader for GCC.
-   Copyright (C) 1987-2016 Free Software Foundation, Inc.
+   Copyright (C) 1987-2019 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -17,14 +17,32 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+/* This file is compiled twice: once for the generator programs
+   once for the compiler.  */
+#ifdef GENERATOR_FILE
 #include "bconfig.h"
+#else
+#include "config.h"
+#endif
 #include "system.h"
 #include "coretypes.h"
+#ifdef GENERATOR_FILE
 #include "errors.h"
+#endif /* #ifdef GENERATOR_FILE */
 #include "statistics.h"
 #include "vec.h"
 #include "read-md.h"
 
+#ifndef GENERATOR_FILE
+
+/* Minimal reimplementation of errors.c for use by RTL frontend
+   within cc1.  */
+
+int have_error = 0;
+
+#endif /* #ifndef GENERATOR_FILE */
+
+
 /* Associates PTR (which can be a string, etc.) with the file location
    specified by FILENAME and LINENO.  */
 struct ptr_loc {
@@ -39,7 +57,7 @@ void (*include_callback) (const char *);
 
 /* Global singleton.  */
 
-rtx_reader *rtx_reader_ptr;
+md_reader *md_reader_ptr;
 
 /* Given an object that starts with a char * name field, return a hash
    code for its name.  */
@@ -79,7 +97,7 @@ leading_ptr_eq_p (const void *def1, const void *def2)
 /* Associate PTR with the file position given by FILENAME and LINENO.  */
 
 void
-rtx_reader::set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
+md_reader::set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
 {
   struct ptr_loc *loc;
 
@@ -95,7 +113,7 @@ rtx_reader::set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
    position was set.  */
 
 const struct ptr_loc *
-rtx_reader::get_md_ptr_loc (const void *ptr)
+md_reader::get_md_ptr_loc (const void *ptr)
 {
   return (const struct ptr_loc *) htab_find (m_ptr_locs, &ptr);
 }
@@ -103,7 +121,7 @@ rtx_reader::get_md_ptr_loc (const void *ptr)
 /* Associate NEW_PTR with the same file position as OLD_PTR.  */
 
 void
-rtx_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
+md_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
 {
   const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
   if (loc != 0)
@@ -114,7 +132,7 @@ rtx_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
    directive for it to OUTF.  */
 
 void
-rtx_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
+md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
 {
   const struct ptr_loc *loc = get_md_ptr_loc (ptr);
   if (loc != 0)
@@ -123,7 +141,7 @@ rtx_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
 
 /* Special fprint_md_ptr_loc for writing to STDOUT.  */
 void
-rtx_reader::print_md_ptr_loc (const void *ptr)
+md_reader::print_md_ptr_loc (const void *ptr)
 {
   fprint_md_ptr_loc (stdout, ptr);
 }
@@ -132,7 +150,7 @@ rtx_reader::print_md_ptr_loc (const void *ptr)
    may be null or empty.  */
 
 const char *
-rtx_reader::join_c_conditions (const char *cond1, const char *cond2)
+md_reader::join_c_conditions (const char *cond1, const char *cond2)
 {
   char *result;
   const void **entry;
@@ -161,7 +179,7 @@ rtx_reader::join_c_conditions (const char *cond1, const char *cond2)
    directive for COND if its original file position is known.  */
 
 void
-rtx_reader::fprint_c_condition (FILE *outf, const char *cond)
+md_reader::fprint_c_condition (FILE *outf, const char *cond)
 {
   const char **halves = (const char **) htab_find (m_joined_conditions, &cond);
   if (halves != 0)
@@ -183,7 +201,7 @@ rtx_reader::fprint_c_condition (FILE *outf, const char *cond)
 /* Special fprint_c_condition for writing to STDOUT.  */
 
 void
-rtx_reader::print_c_condition (const char *cond)
+md_reader::print_c_condition (const char *cond)
 {
   fprint_c_condition (stdout, cond);
 }
@@ -250,8 +268,9 @@ fatal_with_file_and_line (const char *msg, ...)
 
   va_start (ap, msg);
 
-  fprintf (stderr, "%s:%d:%d: error: ", rtx_reader_ptr->get_filename (),
-          rtx_reader_ptr->get_lineno (), rtx_reader_ptr->get_colno ());
+  fprintf (stderr, "%s:%d:%d: error: ", md_reader_ptr->get_filename (),
+          md_reader_ptr->get_lineno (),
+          md_reader_ptr->get_colno ());
   vfprintf (stderr, msg, ap);
   putc ('\n', stderr);
 
@@ -271,8 +290,9 @@ fatal_with_file_and_line (const char *msg, ...)
   context[i] = '\0';
 
   fprintf (stderr, "%s:%d:%d: note: following context is `%s'\n",
-          rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
-          rtx_reader_ptr->get_colno (), context);
+          md_reader_ptr->get_filename (),
+          md_reader_ptr->get_lineno (),
+          md_reader_ptr->get_colno (), context);
 
   va_end (ap);
   exit (1);
@@ -340,21 +360,44 @@ read_skip_spaces (void)
     }
 }
 
+/* Consume the next character, issuing a fatal error if it is not
+   EXPECTED.  */
+
+void
+md_reader::require_char (char expected)
+{
+  int ch = read_char ();
+  if (ch != expected)
+    fatal_expected_char (expected, ch);
+}
+
 /* Consume any whitespace, then consume the next non-whitespace
    character, issuing a fatal error if it is not EXPECTED.  */
 
 void
-require_char_ws (char expected)
+md_reader::require_char_ws (char expected)
 {
   int ch = read_skip_spaces ();
   if (ch != expected)
     fatal_expected_char (expected, ch);
 }
 
+/* Consume any whitespace, then consume the next word (as per read_name),
+   issuing a fatal error if it is not EXPECTED.  */
+
+void
+md_reader::require_word_ws (const char *expected)
+{
+  struct md_name name;
+  read_name (&name);
+  if (strcmp (name.string, expected))
+    fatal_with_file_and_line ("missing '%s'", expected);
+}
+
 /* Read the next character from the file.  */
 
 int
-rtx_reader::read_char (void)
+md_reader::read_char (void)
 {
   int ch;
 
@@ -368,13 +411,23 @@ rtx_reader::read_char (void)
   else
     m_read_md_colno++;
 
+  /* If we're filtering lines, treat everything before the range of
+     interest as a space, and as EOF for everything after.  */
+  if (m_first_line && m_last_line)
+    {
+      if (m_read_md_lineno < m_first_line)
+       return ' ';
+      if (m_read_md_lineno > m_last_line)
+       return EOF;
+    }
+
   return ch;
 }
 
 /* Put back CH, which was the last character read from the file.  */
 
 void
-rtx_reader::unread_char (int ch)
+md_reader::unread_char (int ch)
 {
   if (ch == '\n')
     {
@@ -386,11 +439,21 @@ rtx_reader::unread_char (int ch)
   ungetc (ch, m_read_md_file);
 }
 
+/* Peek at the next character from the file without consuming it.  */
+
+int
+md_reader::peek_char (void)
+{
+  int ch = read_char ();
+  unread_char (ch);
+  return ch;
+}
+
 /* Read an rtx code name into NAME.  It is terminated by any of the
    punctuation chars of rtx printed syntax.  */
 
-void
-rtx_reader::read_name (struct md_name *name)
+bool
+md_reader::read_name_1 (struct md_name *name, file_location *out_loc)
 {
   int c;
   size_t i;
@@ -398,6 +461,8 @@ rtx_reader::read_name (struct md_name *name)
 
   c = read_skip_spaces ();
 
+  *out_loc = get_current_location ();
+
   i = 0;
   angle_bracket_depth = 0;
   while (1)
@@ -429,7 +494,7 @@ rtx_reader::read_name (struct md_name *name)
     }
 
   if (i == 0)
-    fatal_with_file_and_line ("missing name or number");
+    return false;
 
   name->buffer[i] = 0;
   name->string = name->buffer;
@@ -450,13 +515,43 @@ rtx_reader::read_name (struct md_name *name)
        }
       while (def);
     }
+
+  return true;
+}
+
+/* Read an rtx code name into NAME.  It is terminated by any of the
+   punctuation chars of rtx printed syntax.  */
+
+file_location
+md_reader::read_name (struct md_name *name)
+{
+  file_location loc;
+  if (!read_name_1 (name, &loc))
+    fatal_with_file_and_line ("missing name or number");
+  return loc;
+}
+
+file_location
+md_reader::read_name_or_nil (struct md_name *name)
+{
+  file_location loc;
+  if (!read_name_1 (name, &loc))
+    {
+      file_location loc = get_current_location ();
+      read_skip_construct (0, loc);
+      /* Skip the ')'.  */
+      read_char ();
+      name->buffer[0] = 0;
+      name->string = name->buffer;
+    }
+  return loc;
 }
 
 /* Subroutine of the string readers.  Handles backslash escapes.
    Caller has read the backslash, but not placed it into the obstack.  */
 
 void
-rtx_reader::read_escape ()
+md_reader::read_escape ()
 {
   int c = read_char ();
 
@@ -509,7 +604,7 @@ rtx_reader::read_escape ()
    the leading quote.  */
 
 char *
-rtx_reader::read_quoted_string ()
+md_reader::read_quoted_string ()
 {
   int c;
 
@@ -536,7 +631,7 @@ rtx_reader::read_quoted_string ()
    the outermost braces _are_ included in the string constant.  */
 
 char *
-rtx_reader::read_braced_string ()
+md_reader::read_braced_string ()
 {
   int c;
   int brace_depth = 1;  /* caller-processed */
@@ -573,7 +668,7 @@ rtx_reader::read_braced_string ()
    and dispatch to the appropriate string constant reader.  */
 
 char *
-rtx_reader::read_string (int star_if_braced)
+md_reader::read_string (int star_if_braced)
 {
   char *stringbuf;
   int saw_paren = 0;
@@ -595,6 +690,14 @@ rtx_reader::read_string (int star_if_braced)
        obstack_1grow (&m_string_obstack, '*');
       stringbuf = read_braced_string ();
     }
+  else if (saw_paren && c == 'n')
+    {
+      /* Handle (nil) by returning NULL.  */
+      require_char ('i');
+      require_char ('l');
+      require_char_ws (')');
+      return NULL;
+    }
   else
     fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
 
@@ -609,7 +712,7 @@ rtx_reader::read_string (int star_if_braced)
    is currently nested by DEPTH levels of parentheses.  */
 
 void
-rtx_reader::read_skip_construct (int depth, file_location loc)
+md_reader::read_skip_construct (int depth, file_location loc)
 {
   struct md_name name;
   int c;
@@ -751,7 +854,7 @@ add_constant (htab_t defs, char *name, char *value,
    after the "define_constants".  */
 
 void
-rtx_reader::handle_constants ()
+md_reader::handle_constants ()
 {
   int c;
   htab_t defs;
@@ -782,7 +885,7 @@ rtx_reader::handle_constants ()
    Stop when CALLBACK returns zero.  */
 
 void
-rtx_reader::traverse_md_constants (htab_trav callback, void *info)
+md_reader::traverse_md_constants (htab_trav callback, void *info)
 {
   htab_traverse (get_md_constants (), callback, info);
 }
@@ -805,7 +908,7 @@ md_decimal_string (int number)
    directive is a define_enum rather than a define_c_enum.  */
 
 void
-rtx_reader::handle_enum (file_location loc, bool md_p)
+md_reader::handle_enum (file_location loc, bool md_p)
 {
   char *enum_name, *value_name;
   struct md_name name;
@@ -871,7 +974,7 @@ rtx_reader::handle_enum (file_location loc, bool md_p)
 /* Try to find the definition of the given enum.  Return null on failure.  */
 
 struct enum_type *
-rtx_reader::lookup_enum_type (const char *name)
+md_reader::lookup_enum_type (const char *name)
 {
   return (struct enum_type *) htab_find (m_enum_types, &name);
 }
@@ -881,26 +984,32 @@ rtx_reader::lookup_enum_type (const char *name)
    returns zero.  */
 
 void
-rtx_reader::traverse_enum_types (htab_trav callback, void *info)
+md_reader::traverse_enum_types (htab_trav callback, void *info)
 {
   htab_traverse (m_enum_types, callback, info);
 }
 
 
-/* Constructor for rtx_reader.  */
+/* Constructor for md_reader.  */
 
-rtx_reader::rtx_reader ()
-: m_toplevel_fname (NULL),
+md_reader::md_reader (bool compact)
+: m_compact (compact),
+  m_toplevel_fname (NULL),
   m_base_dir (NULL),
   m_read_md_file (NULL),
   m_read_md_filename (NULL),
   m_read_md_lineno (0),
   m_read_md_colno (0),
   m_first_dir_md_include (NULL),
-  m_last_dir_md_include_ptr (&m_first_dir_md_include)
+  m_last_dir_md_include_ptr (&m_first_dir_md_include),
+  m_first_line (0),
+  m_last_line (0),
+  m_first_overload (NULL),
+  m_next_overload_ptr (&m_first_overload),
+  m_overloads_htab (NULL)
 {
   /* Set the global singleton pointer.  */
-  rtx_reader_ptr = this;
+  md_reader_ptr = this;
 
   obstack_init (&m_string_obstack);
 
@@ -920,9 +1029,9 @@ rtx_reader::rtx_reader ()
   unlock_std_streams ();
 }
 
-/* rtx_reader's destructor.  */
+/* md_reader's destructor.  */
 
-rtx_reader::~rtx_reader ()
+md_reader::~md_reader ()
 {
   free (m_base_dir);
 
@@ -939,7 +1048,7 @@ rtx_reader::~rtx_reader ()
   obstack_free (&m_string_obstack, NULL);
 
   /* Clear the global singleton pointer.  */
-  rtx_reader_ptr = NULL;
+  md_reader_ptr = NULL;
 }
 
 /* Process an "include" directive, starting with the optional space
@@ -948,7 +1057,7 @@ rtx_reader::~rtx_reader ()
    which the "include" occurred.  */
 
 void
-rtx_reader::handle_include (file_location loc)
+md_reader::handle_include (file_location loc)
 {
   const char *filename;
   const char *old_filename;
@@ -1026,7 +1135,7 @@ rtx_reader::handle_include (file_location loc)
    unknown directives.  */
 
 void
-rtx_reader::handle_file ()
+md_reader::handle_file ()
 {
   struct md_name directive;
   int c;
@@ -1060,7 +1169,7 @@ rtx_reader::handle_file ()
    and m_base_dir accordingly.  */
 
 void
-rtx_reader::handle_toplevel_file ()
+md_reader::handle_toplevel_file ()
 {
   const char *base;
 
@@ -1075,7 +1184,7 @@ rtx_reader::handle_toplevel_file ()
 }
 
 file_location
-rtx_reader::get_current_location () const
+md_reader::get_current_location () const
 {
   return file_location (m_read_md_filename, m_read_md_lineno, m_read_md_colno);
 }
@@ -1083,7 +1192,7 @@ rtx_reader::get_current_location () const
 /* Parse a -I option with argument ARG.  */
 
 void
-rtx_reader::add_include_path (const char *arg)
+md_reader::add_include_path (const char *arg)
 {
   struct file_name_list *dirtmp;
 
@@ -1094,6 +1203,8 @@ rtx_reader::add_include_path (const char *arg)
   m_last_dir_md_include_ptr = &dirtmp->next;
 }
 
+#ifdef GENERATOR_FILE
+
 /* The main routine for reading .md files.  Try to process all the .md
    files specified on the command line and return true if no error occurred.
 
@@ -1104,8 +1215,8 @@ rtx_reader::add_include_path (const char *arg)
    generic error should be reported.  */
 
 bool
-rtx_reader::read_md_files (int argc, const char **argv,
-                          bool (*parse_opt) (const char *))
+md_reader::read_md_files (int argc, const char **argv,
+                         bool (*parse_opt) (const char *))
 {
   int i;
   bool no_more_options;
@@ -1200,7 +1311,45 @@ rtx_reader::read_md_files (int argc, const char **argv,
   return !have_error;
 }
 
-/* class noop_reader : public rtx_reader */
+#endif /* #ifdef GENERATOR_FILE */
+
+/* Read FILENAME.  */
+
+bool
+md_reader::read_file (const char *filename)
+{
+  m_read_md_filename = filename;
+  m_read_md_file = fopen (m_read_md_filename, "r");
+  if (m_read_md_file == 0)
+    {
+      perror (m_read_md_filename);
+      return false;
+    }
+  handle_toplevel_file ();
+  return !have_error;
+}
+
+/* Read FILENAME, filtering to just the given lines.  */
+
+bool
+md_reader::read_file_fragment (const char *filename,
+                              int first_line,
+                              int last_line)
+{
+  m_read_md_filename = filename;
+  m_read_md_file = fopen (m_read_md_filename, "r");
+  if (m_read_md_file == 0)
+    {
+      perror (m_read_md_filename);
+      return false;
+    }
+  m_first_line = first_line;
+  m_last_line = last_line;
+  handle_toplevel_file ();
+  return !have_error;
+}
+
+/* class noop_reader : public md_reader */
 
 /* A dummy implementation which skips unknown directives.  */
 void