OSDN Git Service

* opts.h (cl_option_state): New structure.
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Jun 2005 06:55:47 +0000 (06:55 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Jun 2005 06:55:47 +0000 (06:55 +0000)
(get_option_state): Declare.
* opts.c (get_option_state): New function.
* toplev.c (option_affects_pch_p): New function.
(default_get_pch_validity): Store the state of all options for which
option_affects_pch_p returns true.
(default_pch_valid_p): Check the state of those options here.
Only check target_flags separately if targetm.check_pch_target_Flags
is nonnull or if TARGET_SWITCHES is defined.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100430 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/opts.c
gcc/opts.h
gcc/toplev.c

index ab0bf7a..045c42a 100644 (file)
@@ -1,5 +1,17 @@
 2005-06-01  Richard Sandiford  <rsandifo@redhat.com>
 
+       * opts.h (cl_option_state): New structure.
+       (get_option_state): Declare.
+       * opts.c (get_option_state): New function.
+       * toplev.c (option_affects_pch_p): New function.
+       (default_get_pch_validity): Store the state of all options for which
+       option_affects_pch_p returns true.
+       (default_pch_valid_p): Check the state of those options here.
+       Only check target_flags separately if targetm.check_pch_target_Flags
+       is nonnull or if TARGET_SWITCHES is defined.
+
+2005-06-01  Richard Sandiford  <rsandifo@redhat.com>
+
        * config/mips/mips-protos.h (mips_use_ins_ext_p): Remove parameter
        names.
 
index 44ed37b..6e73561 100644 (file)
@@ -1442,3 +1442,37 @@ option_enabled (int opt_idx)
       }
   return -1;
 }
+
+/* Fill STATE with the current state of option OPTION.  Return true if
+   there is some state to store.  */
+
+bool
+get_option_state (int option, struct cl_option_state *state)
+{
+  if (cl_options[option].flag_var == 0)
+    return false;
+
+  switch (cl_options[option].var_type)
+    {
+    case CLVC_BOOLEAN:
+    case CLVC_EQUAL:
+      state->data = cl_options[option].flag_var;
+      state->size = sizeof (int);
+      break;
+
+    case CLVC_BIT_CLEAR:
+    case CLVC_BIT_SET:
+      state->ch = option_enabled (option);
+      state->data = &state->ch;
+      state->size = 1;
+      break;
+
+    case CLVC_STRING:
+      state->data = *(const char **) cl_options[option].flag_var;
+      if (state->data == 0)
+       state->data = "";
+      state->size = strlen (state->data) + 1;
+      break;
+    }
+  return true;
+}
index 1794f7b..962b1ca 100644 (file)
@@ -52,6 +52,14 @@ struct cl_option
   int var_value;
 };
 
+/* Records that the state of an option consists of SIZE bytes starting
+   at DATA.  DATA might point to CH in some cases.  */
+struct cl_option_state {
+  const void *data;
+  size_t size;
+  char ch;
+};
+
 extern const struct cl_option cl_options[];
 extern const unsigned int cl_options_count;
 extern const char *const lang_names[];
@@ -77,6 +85,7 @@ extern unsigned num_in_fnames;
 
 extern void decode_options (unsigned int argc, const char **argv);
 extern int option_enabled (int opt_idx);
+extern bool get_option_state (int, struct cl_option_state *);
 extern void print_filtered_help (unsigned int);
 
 #endif
index 6cda6bb..550574f 100644 (file)
@@ -1434,6 +1434,21 @@ init_asm_output (const char *name)
     }
 }
 
+/* Return true if the state of option OPTION should be stored in PCH files
+   and checked by default_pch_valid_p.  Store the option's current state
+   in STATE if so.  */
+
+static inline bool
+option_affects_pch_p (int option, struct cl_option_state *state)
+{
+  if ((cl_options[option].flags & CL_TARGET) == 0)
+    return false;
+  if (cl_options[option].flag_var == &target_flags)
+    if (targetm.check_pch_target_flags)
+      return false;
+  return get_option_state (option, state);
+}
+
 /* Default version of get_pch_validity.
    By default, every flag difference is fatal; that will be mostly right for
    most targets, but completely right for very few.  */
@@ -1441,9 +1456,8 @@ init_asm_output (const char *name)
 void *
 default_get_pch_validity (size_t *len)
 {
-#ifdef TARGET_OPTIONS
+  struct cl_option_state state;
   size_t i;
-#endif
   char *result, *r;
 
   *len = sizeof (target_flags) + 2;
@@ -1455,6 +1469,9 @@ default_get_pch_validity (size_t *len)
        *len += strlen (*target_options[i].variable);
     }
 #endif
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      *len += state.size;
 
   result = r = xmalloc (*len);
   r[0] = flag_pic;
@@ -1475,6 +1492,12 @@ default_get_pch_validity (size_t *len)
       r += l;
     }
 #endif
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      {
+       memcpy (r, state.data, state.size);
+       r += state.size;
+      }
 
   return result;
 }
@@ -1484,6 +1507,7 @@ default_get_pch_validity (size_t *len)
 const char *
 default_pch_valid_p (const void *data_p, size_t len)
 {
+  struct cl_option_state state;
   const char *data = (const char *)data_p;
   const char *flag_that_differs = NULL;
   size_t i;
@@ -1504,9 +1528,9 @@ default_pch_valid_p (const void *data_p, size_t len)
       if (r != NULL)
        return r;
     }
+#ifdef TARGET_SWITCHES
   else if (tf != target_flags)
     {
-#ifdef TARGET_SWITCHES
       for (i = 0; i < ARRAY_SIZE (target_switches); i++)
        {
          int bits;
@@ -1520,16 +1544,9 @@ default_pch_valid_p (const void *data_p, size_t len)
              goto make_message;
            }
        }
-#endif
-      for (i = 0; i < cl_options_count; i++)
-       if (cl_options[i].flag_var == &target_flags
-           && (cl_options[i].var_value & (target_flags ^ tf)) != 0)
-         {
-           flag_that_differs = cl_options[i].opt_text + 2;
-           goto make_message;
-         }
       gcc_unreachable ();
     }
+#endif
   data += sizeof (target_flags);
   len -= sizeof (target_flags);
 
@@ -1552,6 +1569,18 @@ default_pch_valid_p (const void *data_p, size_t len)
     }
 #endif
 
+  for (i = 0; i < cl_options_count; i++)
+    if (option_affects_pch_p (i, &state))
+      {
+       if (memcmp (data, state.data, state.size) != 0)
+         {
+           flag_that_differs = cl_options[i].opt_text + 2;
+           goto make_message;
+         }
+       data += state.size;
+       len -= state.size;
+      }
+
   return NULL;
 
  make_message: