OSDN Git Service

* doc/tm.texi (defmac SMALL_REGISTER_CLASSES): Remove.
[pf3gnuchains/gcc-fork.git] / libcpp / pch.c
index f656418..2fb7ba5 100644 (file)
@@ -33,6 +33,8 @@ static int comp_hashnodes (const void *, const void *);
 static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *);
 static int write_defs (cpp_reader *, cpp_hashnode *, void *);
 static int save_macros (cpp_reader *, cpp_hashnode *, void *);
+static int _cpp_save_pushed_macros (cpp_reader *, FILE *);
+static int _cpp_restore_pushed_macros (cpp_reader *, FILE *);
 
 /* This structure represents a macro definition on disk.  */
 struct macrodef_struct
@@ -378,9 +380,140 @@ cpp_write_pch_state (cpp_reader *r, FILE *f)
       return -1;
     }
 
+  /* Write saved macros.  */
+  if (! _cpp_save_pushed_macros (r, f))
+    {
+      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
+      return -1;
+    }
+
   return 0;
 }
 
+static int
+_cpp_restore_pushed_macros (cpp_reader *r, FILE *f)
+{
+  size_t count_saved = 0;
+  size_t i;
+  struct def_pragma_macro *p;
+  size_t nlen;
+  cpp_hashnode *h = NULL;
+  cpp_macro *m;
+  uchar *defn;
+  size_t defnlen;
+
+  if (fread (&count_saved, sizeof (count_saved), 1, f) != 1)
+    return 0;
+  if (! count_saved)
+    return 1;
+  for (i = 0; i < count_saved; i++)
+    {
+      if (fread (&nlen, sizeof (nlen), 1, f) != 1)
+       return 0;
+      p = XNEW (struct def_pragma_macro);
+      p->name = XNEWVAR (char, nlen + 1);
+      p->name[nlen] = 0;
+      if (fread (p->name, nlen, 1, f) != 1)
+       return 0;
+      /* Save old state.  */
+      m = cpp_push_definition (r, p->name);
+      if (fread (&defnlen, sizeof (defnlen), 1, f) != 1)
+       return 0;
+      defn = XNEWVAR (uchar, defnlen + 2);
+      defn[defnlen] = '\n';
+      defn[defnlen + 1] = 0;
+
+      if (fread (defn, defnlen, 1, f) != 1)
+       return 0;
+      cpp_pop_definition (r, p->name, NULL);
+      {
+       size_t namelen;
+       uchar *dn;
+
+       namelen = ustrcspn (defn, "( \n");
+       h = cpp_lookup (r, defn, namelen);
+       dn = defn + namelen;
+
+       h->type = NT_VOID;
+       h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
+       if (cpp_push_buffer (r, dn, ustrchr (dn, '\n') - dn, true)
+           != NULL)
+         {
+           _cpp_clean_line (r);
+           if (!_cpp_create_definition (r, h))
+             abort ();
+           _cpp_pop_buffer (r);
+         }
+       else
+         abort ();
+      }
+      p->value = cpp_push_definition (r, p->name);
+
+      free (defn);
+      p->next = r->pushed_macros;
+      r->pushed_macros = p;
+      /* Restore current state.  */
+      cpp_pop_definition (r, p->name, m);
+    }
+  return 1;
+}
+
+static int
+_cpp_save_pushed_macros (cpp_reader *r, FILE *f)
+{
+  size_t count_saved = 0;
+  size_t i;
+  struct def_pragma_macro *p,**pp;
+  cpp_hashnode *node;
+  cpp_macro *m;
+  size_t defnlen;
+  const uchar *defn;
+
+  /* Get count. */
+  p = r->pushed_macros;
+  while (p != NULL)
+    {
+      count_saved++;
+      p = p->next;
+    }
+  if (fwrite (&count_saved, sizeof (count_saved), 1, f) != 1)
+    return 0;
+  if (!count_saved)
+    return 1;
+
+  pp = (struct def_pragma_macro **) alloca (sizeof (struct def_pragma_macro *)
+                                           * count_saved);
+  /* Store them in reverse order.  */
+  p = r->pushed_macros;
+  i = count_saved;
+  while (p != NULL)
+    {
+      --i;
+      pp[i] = p;
+      p = p->next;
+    }
+  for (i = 0; i < count_saved; i++)
+    {
+      /* Save old state.  */
+      m = cpp_push_definition (r, pp[i]->name);
+      /* Set temporary macro name to saved state.  */
+      cpp_pop_definition (r, pp[i]->name, pp[i]->value);
+      node = _cpp_lex_identifier (r, pp[i]->name);
+      defnlen = strlen (pp[i]->name);
+      if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
+         || fwrite (pp[i]->name, defnlen, 1, f) != 1)
+       return 0;
+      defn = cpp_macro_definition (r, node);
+      defnlen = ustrlen (defn);
+      if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
+         || fwrite (defn, defnlen, 1, f) != 1)
+       return 0;
+      /* Restore current state.  */
+      cpp_pop_definition (r, pp[i]->name, m);
+    }
+  return 1;
+}
+
 
 /* Data structure to transform hash table nodes into a sorted list */
 
@@ -480,9 +613,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
          || h->flags & NODE_POISONED)
        {
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                      "%s: not used because `%.*s' is poisoned",
-                      name, m.name_length, namebuf);
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                               "%s: not used because `%.*s' is poisoned",
+                               name, m.name_length, namebuf);
          goto fail;
        }
 
@@ -502,9 +635,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
            continue;
 
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                      "%s: not used because `%.*s' not defined",
-                      name, m.name_length, namebuf);
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                               "%s: not used because `%.*s' not defined",
+                               name, m.name_length, namebuf);
          goto fail;
        }
 
@@ -514,7 +647,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
          || memcmp (namebuf, newdefn, m.definition_length) != 0)
        {
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
               "%s: not used because `%.*s' defined as `%s' not `%.*s'",
                       name, m.name_length, namebuf, newdefn + m.name_length,
                       m.definition_length - m.name_length,
@@ -555,9 +688,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
       else
        {
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                      "%s: not used because `%s' is defined",
-                      name, first);
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                               "%s: not used because `%s' is defined",
+                               name, first);
          goto fail;
        }
     }
@@ -575,9 +708,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
   if (counter && r->counter)
     {
       if (CPP_OPTION (r, warn_invalid_pch))
-       cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                  "%s: not used because `__COUNTER__' is invalid",
-                  name);
+       cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                           "%s: not used because `__COUNTER__' is invalid",
+                           name);
        goto fail;
     }
 
@@ -752,6 +885,9 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
   if (!r->counter)
     r->counter = counter;
 
+  /* Read pushed macros. */
+  if (! _cpp_restore_pushed_macros (r, f))
+    goto error;
   return 0;
 
  error: