OSDN Git Service

* trans-array.c (gfc_trans_create_temp_array): When the size is known
[pf3gnuchains/gcc-fork.git] / libcpp / pch.c
index 51175a9..cc23b4e 100644 (file)
@@ -1,5 +1,6 @@
 /* Part of CPP library.  (Precompiled header reading/writing.)
-   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -13,7 +14,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -136,11 +137,11 @@ save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
          struct cpp_string *sp;
          unsigned char *text;
          
-         sp = xmalloc (sizeof (struct cpp_string));
+         sp = XNEW (struct cpp_string);
          *slot = sp;
 
          sp->len = NODE_LEN (hn);
-         sp->text = text = xmalloc (NODE_LEN (hn));
+         sp->text = text = XNEWVEC (unsigned char, NODE_LEN (hn));
          memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
        }
     }
@@ -192,7 +193,7 @@ int
 cpp_save_state (cpp_reader *r, FILE *f)
 {
   /* Save the list of non-void identifiers for the dependency checking.  */
-  r->savedstate = xmalloc (sizeof (struct cpp_savedstate));
+  r->savedstate = XNEW (struct cpp_savedstate);
   r->savedstate->definedhash = htab_create (100, cpp_string_hash, 
                                            cpp_string_eq, NULL);
   cpp_forall_identifiers (r, save_idents, r->savedstate);
@@ -225,7 +226,7 @@ count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
        
        news.len = NODE_LEN (hn);
        news.text = NODE_NAME (hn);
-       slot = htab_find (ss->definedhash, &news);
+       slot = (void **) htab_find (ss->definedhash, &news);
        if (slot == NULL)
          {
            ss->hashsize += NODE_LEN (hn) + 1;
@@ -264,7 +265,7 @@ write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
        
        news.len = NODE_LEN (hn);
        news.text = NODE_NAME (hn);
-       slot = htab_find (ss->definedhash, &news);
+       slot = (void **) htab_find (ss->definedhash, &news);
        if (slot == NULL)
          {
            ss->defs[ss->n_defs] = hn;
@@ -309,13 +310,13 @@ cpp_write_pch_deps (cpp_reader *r, FILE *f)
   ss->n_defs = 0;
   cpp_forall_identifiers (r, count_defs, ss);
 
-  ss->defs = xmalloc (ss->n_defs * sizeof (cpp_hashnode *));
+  ss->defs = XNEWVEC (cpp_hashnode *, ss->n_defs);
   ss->n_defs = 0;
   cpp_forall_identifiers (r, write_defs, ss);
 
   /* Sort the list, copy it into a buffer, and write it out.  */
   qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
-  definedstrs = ss->definedstrs = xmalloc (ss->hashsize);
+  definedstrs = ss->definedstrs = XNEWVEC (unsigned char, ss->hashsize);
   for (i = 0; i < ss->n_defs; ++i)
     {
       size_t len = NODE_LEN (ss->defs[i]);
@@ -345,17 +346,6 @@ cpp_write_pch_deps (cpp_reader *r, FILE *f)
 int
 cpp_write_pch_state (cpp_reader *r, FILE *f)
 {
-  struct macrodef_struct z;
-
-  /* Write out the list of defined identifiers.  */
-  cpp_forall_identifiers (r, write_macdef, f);
-  memset (&z, 0, sizeof (z));
-  if (fwrite (&z, sizeof (z), 1, f) != 1)
-    {
-      cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
-      return -1;
-    }
-
   if (!r->deps)
     r->deps = deps_init ();
 
@@ -400,7 +390,7 @@ collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn,
       if (nl->n_defs == nl->asize)
         {
           nl->asize *= 2;
-          nl->defs = xrealloc (nl->defs, nl->asize * sizeof (cpp_hashnode *));
+          nl->defs = XRESIZEVEC (cpp_hashnode *, nl->defs, nl->asize);
         }
 
       nl->defs[nl->n_defs] = hn;
@@ -428,7 +418,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
 {
   struct macrodef_struct m;
   size_t namebufsz = 256;
-  unsigned char *namebuf = xmalloc (namebufsz);
+  unsigned char *namebuf = XNEWVEC (unsigned char, namebufsz);
   unsigned char *undeftab = NULL;
   struct ht_node_list nl = { 0, 0, 0 };
   unsigned char *first, *last;
@@ -447,13 +437,22 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
       if (m.name_length == 0)
        break;
 
+      /* If this file is already preprocessed, there won't be any
+        macros defined, and that's OK.  */
+      if (CPP_OPTION (r, preprocessed))
+       {
+         if (lseek (fd, m.definition_length, SEEK_CUR) == -1)
+           goto error;
+         continue;
+       }
+
       if (m.definition_length > namebufsz)
        {
          free (namebuf);
          namebufsz = m.definition_length + 256;
-         namebuf = xmalloc (namebufsz);
+         namebuf = XNEWVEC (unsigned char, namebufsz);
        }
-      
+
       if ((size_t)read (fd, namebuf, m.definition_length) 
          != m.definition_length)
        goto error;
@@ -489,14 +488,14 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
 
   /* Read in the list of identifiers that must not be defined.
      Check that they really aren't.  */
-  undeftab = xmalloc (m.definition_length);
+  undeftab = XNEWVEC (unsigned char, m.definition_length);
   if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length)
     goto error;
 
   /* Collect identifiers from the current hash table.  */
   nl.n_defs = 0;
   nl.asize = 10;
-  nl.defs = xmalloc (nl.asize * sizeof (cpp_hashnode *));
+  nl.defs = XNEWVEC (cpp_hashnode *, nl.asize);
   cpp_forall_identifiers (r, &collect_ht_nodes, &nl);
   qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
  
@@ -544,46 +543,64 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
   return 1;
 }
 
-/* Save all the existing macros and assertions.  
-   This code assumes that there might be hundreds, but not thousands of
-   existing definitions.  */
-
-struct save_macro_item {
-  struct save_macro_item *next;
-  struct cpp_hashnode macs[64];
-};
+/* Save all the existing macros.  */
 
 struct save_macro_data 
 {
-  struct save_macro_item *macros;
+  uchar **defns;
   size_t count;
+  size_t array_size;
   char **saved_pragmas;
 };
 
-/* Save the definition of a single macro, so that it will persist across
-   a PCH restore.  */
+/* Save the definition of a single macro, so that it will persist
+   across a PCH restore.  Because macro data is in GCed memory, which
+   will be blown away by PCH, it must be temporarily copied to
+   malloced memory.  (The macros will refer to identifier nodes which
+   are also GCed and so on, so the copying is done by turning them
+   into self-contained strings.)  The assumption is that most macro
+   definitions will come from the PCH file, not from the compilation
+   before the PCH file is loaded, so it doesn't matter that this is
+   a little expensive.
+
+   It would reduce the cost even further if macros defined in the PCH
+   file were not saved in this way, but this is not done (yet), except
+   for builtins, and for #assert by default.  */
 
 static int 
-save_macros (cpp_reader *r ATTRIBUTE_UNUSED, cpp_hashnode *h, void *data_p)
+save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
 {
   struct save_macro_data *data = (struct save_macro_data *)data_p;
   if (h->type != NT_VOID
       && (h->flags & NODE_BUILTIN) == 0)
     {
-      cpp_hashnode *save;
-      if (data->count == ARRAY_SIZE (data->macros->macs))
+      if (data->count == data->array_size)
        {
-         struct save_macro_item *d = data->macros;
-         data->macros = xmalloc (sizeof (struct save_macro_item));
-         data->macros->next = d;
-         data->count = 0;
+         data->array_size *= 2;
+         data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size)); 
+       }
+      
+      switch (h->type)
+       {
+       case NT_ASSERTION:
+         /* Not currently implemented.  */
+         return 1;
+
+       case NT_MACRO:
+         {
+           const uchar * defn = cpp_macro_definition (r, h);
+           size_t defnlen = ustrlen (defn);
+
+           data->defns[data->count] = (uchar *) xmemdup (defn, defnlen,
+                                                          defnlen + 2);
+           data->defns[data->count][defnlen] = '\n';
+         }
+         break;
+         
+       default:
+         abort ();
        }
-      save = data->macros->macs + data->count;
       data->count++;
-      memcpy (save, h, sizeof (struct cpp_hashnode));
-      HT_STR (&save->ident) = xmemdup (HT_STR (HT_NODE (save)),
-                                      HT_LEN (HT_NODE (save)),
-                                      HT_LEN (HT_NODE (save)) + 1);
     }
   return 1;
 }
@@ -594,10 +611,11 @@ save_macros (cpp_reader *r ATTRIBUTE_UNUSED, cpp_hashnode *h, void *data_p)
 void
 cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
 {
-  struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
+  struct save_macro_data *d = XNEW (struct save_macro_data);
   
-  d->macros = NULL;
-  d->count = ARRAY_SIZE (d->macros->macs);
+  d->array_size = 512;
+  d->defns = XNEWVEC (uchar *, d->array_size);
+  d->count = 0;
   cpp_forall_identifiers (r, save_macros, d);
   d->saved_pragmas = _cpp_save_pragma_names (r);
   *data = d;
@@ -611,12 +629,8 @@ int
 cpp_read_state (cpp_reader *r, const char *name, FILE *f,
                struct save_macro_data *data)
 {
-  struct macrodef_struct m;
-  size_t defnlen = 256;
-  unsigned char *defn = xmalloc (defnlen);
+  size_t i;
   struct lexer_state old_state;
-  struct save_macro_item *d;
-  size_t i, mac_count;
 
   /* Restore spec_nodes, which will be full of references to the old 
      hashtable entries and so will now be invalid.  */
@@ -628,70 +642,28 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
     s->n__VA_ARGS__     = cpp_lookup (r, DSC("__VA_ARGS__"));
   }
 
-  /* Run through the carefully-saved macros, insert them.  */
-  d = data->macros;
-  mac_count = data->count;
-  while (d)
-    {
-      struct save_macro_item *nextd;
-      for (i = 0; i < mac_count; i++)
-       {
-         cpp_hashnode *h;
-         
-         h = cpp_lookup (r, HT_STR (HT_NODE (&d->macs[i])), 
-                         HT_LEN (HT_NODE (&d->macs[i])));
-         h->type = d->macs[i].type;
-         h->flags = d->macs[i].flags;
-         h->value = d->macs[i].value;
-         free ((void *)HT_STR (HT_NODE (&d->macs[i])));
-       }
-      nextd = d->next;
-      free (d);
-      d = nextd;
-      mac_count = ARRAY_SIZE (d->macs);
-    }
-
-  _cpp_restore_pragma_names (r, data->saved_pragmas);
-
-  free (data);
-
   old_state = r->state;
-
   r->state.in_directive = 1;
   r->state.prevent_expansion = 1;
   r->state.angled_headers = 0;
 
-  /* Read in the identifiers that must be defined.  */
-  for (;;)
+  /* Run through the carefully-saved macros, insert them.  */
+  for (i = 0; i < data->count; i++)
     {
       cpp_hashnode *h;
-      
-      if (fread (&m, sizeof (m), 1, f) != 1)
-       goto error;
-      
-      if (m.name_length == 0)
-       break;
+      size_t namelen;
+      uchar *defn;
 
-      if (defnlen < m.definition_length + 1)
-       {
-         defnlen = m.definition_length + 256;
-         defn = xrealloc (defn, defnlen);
-       }
-
-      if (fread (defn, 1, m.definition_length, f) != m.definition_length)
-       goto error;
-      defn[m.definition_length] = '\n';
-      
-      h = cpp_lookup (r, defn, m.name_length);
+      namelen = ustrcspn (data->defns[i], "( \n");
+      h = cpp_lookup (r, data->defns[i], namelen);
+      defn = data->defns[i] + namelen;
 
-      if (h->type == NT_MACRO)
-       _cpp_free_definition (h);
-      if (m.flags & NODE_POISONED)
-       h->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
-      else if (m.name_length != m.definition_length)
+      /* The PCH file is valid, so we know that if there is a definition
+        from the PCH file it must be the same as the one we had
+        originally, and so do not need to restore it.  */
+      if (h->type == NT_VOID)
        {
-         if (cpp_push_buffer (r, defn + m.name_length, 
-                              m.definition_length - m.name_length, true)
+         if (cpp_push_buffer (r, defn, ustrchr (defn, '\n') - defn, true)
              != NULL)
            {
              _cpp_clean_line (r);
@@ -702,11 +674,14 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
          else
            abort ();
        }
-    }
 
+      free (data->defns[i]);
+    }
   r->state = old_state;
-  free (defn);
-  defn = NULL;
+
+  _cpp_restore_pragma_names (r, data->saved_pragmas);
+
+  free (data);
 
   if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL)
       != 0)