OSDN Git Service

Index: gcc/ChangeLog
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Jun 2004 20:10:13 +0000 (20:10 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Jun 2004 20:10:13 +0000 (20:10 +0000)
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

* Makefile.in (CPPLIB_H): Put files in order of inclusion.
(CPP_ID_DATA_H): New.
(gtype-desc.o): Update dependencies.
(GTFILES): Use CPP_ID_DATA_H.

Index: gcc/testsuite/ChangeLog
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

* gcc.dg/pch/macro-4.c: New.
* gcc.dg/pch/macro-4.hs: New.

Index: libcpp/ChangeLog
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

* traditional.c (push_replacement_text): Set macro->traditional.
(save_replacement_text): Likewise.
* pch.c (cpp_write_pch_state): Don't write list of defined macros.
(struct save_macro_item): Delete.
(struct save_macro_data): Use a character array not the previous
structured format.
(save_macros): Save macro as text not as internal structures.
(cpp_prepare_state): Update for changes to save_macro_data.
(cpp_read_state): Don't read macros defined in PCH.  Restore
-D macros as text.
* macro.c (create_iso_definition): Honour alloc_subobject.
Clear traditional flag.
(_cpp_create_definition): Honour alloc_subobject.
* lex.c (cpp_token_val_index): New.
* internal.h: Include cpp-id-data.h.
(uchar): Move definition to cpp-id-data.h.
(U): Likewise.
(cpp_macro): Likewise.
* directives.c (struct answer): Move to cpp-id-data.h.
(do_assert): Honour alloc_subobject.

Index: libcpp/include/ChangeLog
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

* symtab.h (struct ht): Add field 'alloc_subobject'.
* cpplib.h (struct cpp_string): Add GTY marker.
(enum cpp_token_fld_kind): New.
(struct cpp_token): Add GTY markers.
(cpp_token_val_index): Prototype.
(CPP_HASHNODE_VALUE_IDX): New.
(struct cpp_hashnode): Don't skip fields of 'value' when marking.
* cpp-id-data.h: New file.

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

18 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/gengtype.c
gcc/stringpool.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pch/macro-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pch/macro-4.hs [new file with mode: 0644]
libcpp/ChangeLog
libcpp/directives.c
libcpp/include/ChangeLog
libcpp/include/cpp-id-data.h [new file with mode: 0644]
libcpp/include/cpplib.h
libcpp/include/symtab.h
libcpp/internal.h
libcpp/lex.c
libcpp/macro.c
libcpp/pch.c
libcpp/traditional.c

index 1184df7..7f5e57d 100644 (file)
@@ -1,3 +1,10 @@
+2004-06-09  Geoffrey Keating  <geoffk@apple.com>
+
+       * Makefile.in (CPPLIB_H): Put files in order of inclusion.
+       (CPP_ID_DATA_H): New.
+       (gtype-desc.o): Update dependencies.
+       (GTFILES): Use CPP_ID_DATA_H.
+
 2004-06-09  Mark Mitchell  <mark@codesourcery.com>
 
        Revert:
index 2fa566a..fc87854 100644 (file)
@@ -712,10 +712,11 @@ C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H)
 C_TREE_H = c-tree.h $(C_COMMON_H)
 SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
 PREDICT_H = predict.h predict.def
-CPPLIB_H = $(srcdir)/../libcpp/include/cpplib.h \
-       $(srcdir)/../libcpp/include/line-map.h
+CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \
+       $(srcdir)/../libcpp/include/cpplib.h
 MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h
 SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h
+CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
 TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
 TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
 TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
@@ -1522,10 +1523,11 @@ dumpvers: dumpvers.c
 
 version.o: version.c version.h
 
-gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h \
-       $(HASHTAB_H) $(TREE_H) $(RTL_H) function.h insn-config.h $(EXPR_H) $(OPTABS_H) \
-       libfuncs.h debug.h $(GGC_H) bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h \
-       cselib.h insn-addr.h $(TREE_FLOW_H)
+gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+       varray.h $(HASHTAB_H) $(SPLAY_TREE_H) bitmap.h $(TREE_H) $(RTL_H) \
+       function.h insn-config.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
+       cselib.h insn-addr.h $(OPTABS_H) libfuncs.h debug.h $(GGC_H) \
+       cgraph.h tree-alias-type.h $(TREE_FLOW_H) reload.h $(CPP_ID_DATA_H)
 
 ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
        $(HASHTAB_H) toplev.h $(PARAMS_H) hosthooks.h
@@ -2289,7 +2291,7 @@ s-preds: genpreds$(build_exeext)
        $(STAMP) s-preds
 
 GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
-  $(srcdir)/../libcpp/include/cpplib.h $(host_xm_file_list) \
+  $(CPP_ID_DATA_H) $(host_xm_file_list) \
   $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
   $(srcdir)/coverage.c $(srcdir)/function.h $(srcdir)/rtl.h \
   $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(SYMTAB_H) \
index 804ef70..5d70824 100644 (file)
@@ -875,7 +875,7 @@ note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
 }
 \f
 static void process_gc_options (options_p, enum gc_used_enum,
-                               int *, int *, int *);
+                               int *, int *, int *, type_p *);
 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
 static void set_gc_used (pair_p);
 
@@ -883,7 +883,7 @@ static void set_gc_used (pair_p);
 
 static void
 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
-                   int *pass_param, int *length)
+                   int *pass_param, int *length, type_p *nested_ptr)
 {
   options_p o;
   for (o = opt; o; o = o->next)
@@ -895,6 +895,8 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
       *pass_param = 1;
     else if (strcmp (o->name, "length") == 0)
       *length = 1;
+    else if (strcmp (o->name, "nested_ptr") == 0)
+      *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
 }
 
 /* Set the gc_used field of T to LEVEL, and handle the types it references.  */
@@ -914,18 +916,24 @@ set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
       {
        pair_p f;
        int dummy;
+       type_p dummy2;
 
-       process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy);
+       process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
+                           &dummy2);
 
        for (f = t->u.s.fields; f; f = f->next)
          {
            int maybe_undef = 0;
            int pass_param = 0;
            int length = 0;
+           type_p nested_ptr = NULL;
            process_gc_options (f->opt, level, &maybe_undef, &pass_param,
-                               &length);
+                               &length, &nested_ptr);
 
-           if (length && f->type->kind == TYPE_POINTER)
+           if (nested_ptr && f->type->kind == TYPE_POINTER)
+             set_gc_used_type (nested_ptr, GC_POINTED_TO, 
+                               pass_param ? param : NULL);
+           else if (length && f->type->kind == TYPE_POINTER)
              set_gc_used_type (f->type->u.p, GC_USED, NULL);
            else if (maybe_undef && f->type->kind == TYPE_POINTER)
              set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
@@ -1015,7 +1023,7 @@ static outf_p
 create_file (const char *name, const char *oname)
 {
   static const char *const hdr[] = {
-    "   Copyright (C) 2003 Free Software Foundation, Inc.\n",
+    "   Copyright (C) 2004 Free Software Foundation, Inc.\n",
     "\n",
     "This file is part of GCC.\n",
     "\n",
@@ -1101,6 +1109,7 @@ open_base_files (void)
       "basic-block.h", "cselib.h", "insn-addr.h", "optabs.h",
       "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
       "tree-alias-type.h", "tree-flow.h", "reload.h",
+      "cpp-id-data.h",
       NULL
     };
     const char *const *ifp;
@@ -1408,7 +1417,8 @@ struct walk_type_data
   int used_length;
   type_p orig_s;
   const char *reorder_fn;
-  int needs_cast_p;
+  bool needs_cast_p;
+  bool fn_wants_lvalue;
 };
 
 /* Print a mangled name representing T to OF.  */
@@ -1511,7 +1521,7 @@ walk_type (type_p t, struct walk_type_data *d)
   options_p oo;
   const struct nested_ptr_data *nested_ptr_d = NULL;
 
-  d->needs_cast_p = 0;
+  d->needs_cast_p = false;
   for (oo = d->opt; oo; oo = oo->next)
     if (strcmp (oo->name, "length") == 0)
       length = (const char *)oo->info;
@@ -1525,7 +1535,7 @@ walk_type (type_p t, struct walk_type_data *d)
     else if (strcmp (oo->name, "desc") == 0)
       desc = (const char *)oo->info;
     else if (strcmp (oo->name, "nested_ptr") == 0)
-      nested_ptr_d = (const struct nested_ptr_data *)oo->info ;
+      nested_ptr_d = (const struct nested_ptr_data *) oo->info;
     else if (strcmp (oo->name, "dot") == 0)
       ;
     else if (strcmp (oo->name, "tag") == 0)
@@ -1643,10 +1653,12 @@ walk_type (type_p t, struct walk_type_data *d)
                oprintf (d->of, "%*s{\n", d->indent, "");
                d->indent += 2;
                d->val = xasprintf ("x%d", d->counter++);
-               oprintf (d->of, "%*s%s %s * %s =\n", d->indent, "",
+               oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
                         (nested_ptr_d->type->kind == TYPE_UNION 
                          ? "union" : "struct"), 
-                        nested_ptr_d->type->u.s.tag, d->val);
+                        nested_ptr_d->type->u.s.tag, 
+                        d->fn_wants_lvalue ? "" : "const ",
+                        d->val);
                oprintf (d->of, "%*s", d->indent + 2, "");
                output_escaped_param (d, nested_ptr_d->convert_from,
                                      "nested_ptr");
@@ -1654,12 +1666,15 @@ walk_type (type_p t, struct walk_type_data *d)
 
                d->process_field (nested_ptr_d->type, d);
 
-               oprintf (d->of, "%*s%s = ", d->indent, "",
-                        d->prev_val[2]);
-               d->prev_val[2] = d->val;
-               output_escaped_param (d, nested_ptr_d->convert_to,
-                                     "nested_ptr");
-               oprintf (d->of, ";\n");
+               if (d->fn_wants_lvalue)
+                 {
+                   oprintf (d->of, "%*s%s = ", d->indent, "",
+                            d->prev_val[2]);
+                   d->prev_val[2] = d->val;
+                   output_escaped_param (d, nested_ptr_d->convert_to,
+                                         "nested_ptr");
+                   oprintf (d->of, ";\n");
+                 }
 
                d->indent -= 2;
                oprintf (d->of, "%*s}\n", d->indent, "");
@@ -1839,6 +1854,7 @@ walk_type (type_p t, struct walk_type_data *d)
            d->line = &f->line;
            d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
            d->opt = f->opt;
+           d->used_length = false;
 
            if (union_p && use_param_p && d->param == NULL)
              oprintf (d->of, "%*sabort();\n", d->indent, "");
@@ -2231,7 +2247,7 @@ write_types_local_process_field (type_p f, const struct walk_type_data *d)
 /* For S, a structure that's part of ORIG_S, and using parameters
    PARAM, write out a routine that:
    - Is of type gt_note_pointers
-   - If calls PROCESS_FIELD on each field of S or its substructures.
+   - Calls PROCESS_FIELD on each field of S or its substructures.
 */
 
 static void
@@ -2259,6 +2275,7 @@ write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
   d.prev_val[1] = "not valid postage";  /* Guarantee an error.  */
   d.prev_val[3] = "x";
   d.val = "(*x)";
+  d.fn_wants_lvalue = true;
 
   oprintf (d.of, "\n");
   oprintf (d.of, "void\n");
index d17f31d..0227688 100644 (file)
@@ -51,7 +51,12 @@ static struct obstack string_stack;
 
 static hashnode alloc_node (hash_table *);
 static int mark_ident (struct cpp_reader *, hashnode, const void *);
-static int ht_copy_and_clear (struct cpp_reader *, hashnode, const void *);
+
+static void *
+stringpool_ggc_alloc (size_t x)
+{
+  return ggc_alloc (x);
+}
 
 /* Initialize the string pool.  */
 void
@@ -60,6 +65,7 @@ init_stringpool (void)
   /* Create with 16K (2^14) entries.  */
   ident_hash = ht_create (14);
   ident_hash->alloc_node = alloc_node;
+  ident_hash->alloc_subobject = stringpool_ggc_alloc;
   gcc_obstack_init (&string_stack);
 }
 
@@ -212,39 +218,7 @@ struct string_pool_data GTY(())
 
 static GTY(()) struct string_pool_data * spd;
 
-/* Copy HP into the corresponding entry in HT2, and then clear
-   the cpplib parts of HP.  */
-
-static int
-ht_copy_and_clear (cpp_reader *r ATTRIBUTE_UNUSED, hashnode hp, const void *ht2_p)
-{
-  cpp_hashnode *h = CPP_HASHNODE (hp);
-  struct ht *ht2 = (struct ht *) ht2_p;
-
-  if (h->type != NT_VOID
-      && (h->flags & NODE_BUILTIN) == 0)
-    {
-      cpp_hashnode *h2 = CPP_HASHNODE (ht_lookup (ht2,
-                                                 NODE_NAME (h),
-                                                 NODE_LEN (h),
-                                                 HT_ALLOC));
-      h2->type = h->type;
-      memcpy (&h2->value, &h->value, sizeof (h->value));
-
-      h->type = NT_VOID;
-      memset (&h->value, 0, sizeof (h->value));
-    }
-  return 1;
-}
-
-/* The hash table as it was before gt_pch_save_stringpool was called.  */
-
-static struct ht *saved_ident_hash;
-
-/* Prepare the stringpool to be written (by clearing all the cpp parts
-   of each entry) and place the data to be saved in SPD.  Save the
-   current state in SAVED_IDENT_HASH so that gt_pch_fixup_stringpool
-   can restore it.  */
+/* Save the stringpool data in SPD.  */
 
 void
 gt_pch_save_stringpool (void)
@@ -255,10 +229,6 @@ gt_pch_save_stringpool (void)
   spd->entries = ggc_alloc (sizeof (spd->entries[0]) * spd->nslots);
   memcpy (spd->entries, ident_hash->entries,
          spd->nslots * sizeof (spd->entries[0]));
-
-  saved_ident_hash = ht_create (14);
-  saved_ident_hash->alloc_node = alloc_node;
-  ht_forall (ident_hash, ht_copy_and_clear, saved_ident_hash);
 }
 
 /* Return the stringpool to its state before gt_pch_save_stringpool
@@ -267,9 +237,6 @@ gt_pch_save_stringpool (void)
 void
 gt_pch_fixup_stringpool (void)
 {
-  ht_forall (saved_ident_hash, ht_copy_and_clear, ident_hash);
-  ht_destroy (saved_ident_hash);
-  saved_ident_hash = 0;
 }
 
 /* A PCH file has been restored, which loaded SPD; fill the real hash table
index 332e3f0..c9565dd 100644 (file)
@@ -1,3 +1,8 @@
+2004-06-09  Geoffrey Keating  <geoffk@apple.com>
+
+       * gcc.dg/pch/macro-4.c: New.
+       * gcc.dg/pch/macro-4.hs: New.
+
 2004-06-09  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
        PR fortran/13249
diff --git a/gcc/testsuite/gcc.dg/pch/macro-4.c b/gcc/testsuite/gcc.dg/pch/macro-4.c
new file mode 100644 (file)
index 0000000..1c199fa
--- /dev/null
@@ -0,0 +1,8 @@
+#define DEFN aa + bb
+
+#include "macro-4.h"
+
+int foo(int aa, int bb)
+{
+  return DEFN;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/macro-4.hs b/gcc/testsuite/gcc.dg/pch/macro-4.hs
new file mode 100644 (file)
index 0000000..5af162d
--- /dev/null
@@ -0,0 +1 @@
+/* No content!  */
index d81a049..cc2b931 100644 (file)
@@ -1,3 +1,27 @@
+2004-06-09  Geoffrey Keating  <geoffk@apple.com>
+
+       * traditional.c (push_replacement_text): Set macro->traditional.
+       (save_replacement_text): Likewise.
+       * pch.c (cpp_write_pch_state): Don't write list of defined macros.
+       (struct save_macro_item): Delete.
+       (struct save_macro_data): Use a character array not the previous
+       structured format.
+       (save_macros): Save macro as text not as internal structures.
+       (cpp_prepare_state): Update for changes to save_macro_data.
+       (cpp_read_state): Don't read macros defined in PCH.  Restore
+       -D macros as text.  
+       * macro.c (create_iso_definition): Honour alloc_subobject.
+       Clear traditional flag.
+       (_cpp_create_definition): Honour alloc_subobject.
+       * lex.c (cpp_token_val_index): New.
+       * internal.h: Include cpp-id-data.h.
+       (uchar): Move definition to cpp-id-data.h.
+       (U): Likewise.
+       (cpp_macro): Likewise.
+       * directives.c (struct answer): Move to cpp-id-data.h.
+       (do_assert): Honour alloc_subobject.
+       
+
 2004-06-09  Paolo Bonzini  <bonzini@gnu.org>
 
        * Makefile.am (all-local): New.
index 5a6a342..16873da 100644 (file)
@@ -26,14 +26,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "mkdeps.h"
 #include "obstack.h"
 
-/* Chained list of answers to an assertion.  */
-struct answer
-{
-  struct answer *next;
-  unsigned int count;
-  cpp_token first[1];
-};
-
 /* Stack of conditionals currently in progress
    (including both successful and failing conditionals).  */
 struct if_stack
@@ -1727,6 +1719,8 @@ do_assert (cpp_reader *pfile)
   node = parse_assertion (pfile, &new_answer, T_ASSERT);
   if (node)
     {
+      size_t answer_size;
+
       /* Place the new answer in the answer list.  First check there
          is not a duplicate.  */
       new_answer->next = 0;
@@ -1741,11 +1735,20 @@ do_assert (cpp_reader *pfile)
          new_answer->next = node->value.answers;
        }
 
+      answer_size = sizeof (struct answer) + ((new_answer->count - 1)
+                                             * sizeof (cpp_token));
+      /* Commit or allocate storage for the object.  */
+      if (pfile->hash_table->alloc_subobject)
+       {
+         struct answer *temp_answer = new_answer;
+         new_answer = pfile->hash_table->alloc_subobject (answer_size);
+         memcpy (new_answer, temp_answer, answer_size);
+       }
+      else
+       BUFF_FRONT (pfile->a_buff) += answer_size;
+
       node->type = NT_ASSERTION;
       node->value.answers = new_answer;
-      BUFF_FRONT (pfile->a_buff) += (sizeof (struct answer)
-                                    + (new_answer->count - 1)
-                                    * sizeof (cpp_token));
       check_eol (pfile);
     }
 }
index a2f4bc5..0dbd0c3 100644 (file)
@@ -1,3 +1,14 @@
+2004-06-09  Geoffrey Keating  <geoffk@apple.com>
+
+       * symtab.h (struct ht): Add field 'alloc_subobject'.
+       * cpplib.h (struct cpp_string): Add GTY marker.
+       (enum cpp_token_fld_kind): New.
+       (struct cpp_token): Add GTY markers.
+       (cpp_token_val_index): Prototype.
+       (CPP_HASHNODE_VALUE_IDX): New.
+       (struct cpp_hashnode): Don't skip fields of 'value' when marking.
+       * cpp-id-data.h: New file.
+
 2004-05-29  Geoffrey Keating  <geoffk@apple.com>
 
        * symtab.h (struct ht): New field 'entries_owned'
diff --git a/libcpp/include/cpp-id-data.h b/libcpp/include/cpp-id-data.h
new file mode 100644 (file)
index 0000000..bdeaeba
--- /dev/null
@@ -0,0 +1,77 @@
+/* Structures that hang off cpp_identifier, for PCH.
+   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002, 2003, 2004 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
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+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.  */
+
+#include "cpplib.h"
+
+#ifndef HAVE_UCHAR
+typedef unsigned char uchar;
+#endif
+#define U (const uchar *)  /* Intended use: U"string" */
+
+/* Chained list of answers to an assertion.  */
+struct answer GTY(())
+{
+  struct answer *next;
+  unsigned int count;
+  cpp_token GTY ((length ("%h.count"))) first[1];
+};
+
+/* Each macro definition is recorded in a cpp_macro structure.
+   Variadic macros cannot occur with traditional cpp.  */
+struct cpp_macro GTY(())
+{
+  /* Parameters, if any.  */
+  cpp_hashnode ** GTY ((nested_ptr (union tree_node,
+               "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
+                       "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"),
+                       length ("%h.paramc")))
+    params;
+
+  /* Replacement tokens (ISO) or replacement text (traditional).  See
+     comment at top of cpptrad.c for how traditional function-like
+     macros are encoded.  */
+  union cpp_macro_u
+  {
+    cpp_token * GTY ((tag ("0"), length ("%0.count"))) tokens;
+    const uchar * GTY ((tag ("1"))) text;
+  } GTY ((desc ("%1.traditional"))) exp;
+
+  /* Definition line number.  */
+  source_location line;
+
+  /* Number of tokens in expansion, or bytes for traditional macros.  */
+  unsigned int count;
+
+  /* Number of parameters.  */
+  unsigned short paramc;
+
+  /* If a function-like macro.  */
+  unsigned int fun_like : 1;
+
+  /* If a variadic macro.  */
+  unsigned int variadic : 1;
+
+  /* If macro defined in system header.  */
+  unsigned int syshdr   : 1;
+
+  /* Nonzero if it has been expanded or had its existence tested.  */
+  unsigned int used     : 1;
+
+  /* Indicate which field of 'exp' is in use.  */
+  unsigned int traditional : 1;
+};
index cf701b5..dab3157 100644 (file)
@@ -156,7 +156,7 @@ enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_STDC89, CLK_STDC94, CLK_STDC99,
             CLK_GNUCXX, CLK_CXX98, CLK_ASM};
 
 /* Payload of a NUMBER, STRING, CHAR or COMMENT token.  */
-struct cpp_string
+struct cpp_string GTY(())
 {
   unsigned int len;
   const unsigned char *text;
@@ -171,23 +171,48 @@ struct cpp_string
 #define NO_EXPAND      (1 << 5) /* Do not macro-expand this token.  */
 #define BOL            (1 << 6) /* Token at beginning of line.  */
 
+/* Specify which field, if any, of the cpp_token union is used.  */
+
+enum cpp_token_fld_kind {
+  CPP_TOKEN_FLD_NODE,
+  CPP_TOKEN_FLD_SOURCE,
+  CPP_TOKEN_FLD_STR,
+  CPP_TOKEN_FLD_ARG_NO,
+  CPP_TOKEN_FLD_NONE
+};
+
 /* A preprocessing token.  This has been carefully packed and should
    occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  */
-struct cpp_token
+struct cpp_token GTY(())
 {
   source_location src_loc;     /* Location of first char of token.  */
   ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT;  /* token type */
   unsigned char flags;         /* flags - see above */
 
-  union
+  union cpp_token_u
   {
-    cpp_hashnode *node;                /* An identifier.  */
-    const cpp_token *source;   /* Inherit padding from this token.  */
-    struct cpp_string str;     /* A string, or number.  */
-    unsigned int arg_no;       /* Argument no. for a CPP_MACRO_ARG.  */
-  } val;
+    /* An identifier.  */
+    cpp_hashnode *
+      GTY ((nested_ptr (union tree_node,
+               "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
+                       "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"),
+           tag ("CPP_TOKEN_FLD_NODE")))
+        node;
+        
+    /* Inherit padding from this token.  */
+    cpp_token * GTY ((tag ("CPP_TOKEN_FLD_SOURCE"))) source;
+
+    /* A string, or number.  */
+    struct cpp_string GTY ((tag ("CPP_TOKEN_FLD_STR"))) str;
+
+    /* Argument no. for a CPP_MACRO_ARG.  */
+    unsigned int GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) arg_no;
+  } GTY ((desc ("cpp_token_val_index (&%1)"))) val;
 };
 
+/* Say which field is in use.  */
+extern enum cpp_token_fld_kind cpp_token_val_index (cpp_token *tok);
+
 /* A type wide enough to hold any multibyte source character.
    cpplib's character constant interpreter requires an unsigned type.
    Also, a typedef for the signed equivalent.
@@ -498,6 +523,23 @@ enum builtin_type
 #define NODE_LEN(NODE)         HT_LEN (&(NODE)->ident)
 #define NODE_NAME(NODE)                HT_STR (&(NODE)->ident)
 
+/* Specify which field, if any, of the union is used.  */
+
+enum {
+  NTV_MACRO,
+  NTV_ANSWER,
+  NTV_BUILTIN,
+  NTV_ARGUMENT,
+  NTV_NONE
+};
+
+#define CPP_HASHNODE_VALUE_IDX(HNODE)                          \
+  ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT               \
+   : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN)    \
+                              ? NTV_BUILTIN : NTV_MACRO)       \
+   : HNODE.type == NT_ASSERTION ? NTV_ANSWER                   \
+   : NTV_NONE)
+
 /* The common part of an identifier node shared amongst all 3 C front
    ends.  Also used to store CPP identifiers, which are a superset of
    identifiers in the grammatical sense.  */
@@ -515,14 +557,14 @@ struct cpp_hashnode GTY(())
   union _cpp_hashnode_value
   {
     /* If a macro.  */
-    cpp_macro * GTY((skip)) macro;
+    cpp_macro * GTY((tag ("NTV_MACRO"))) macro;
     /* Answers to an assertion.  */
-    struct answer * GTY ((skip)) answers;
+    struct answer * GTY ((tag ("NTV_ANSWER"))) answers;
     /* Code for a builtin macro.  */
-    enum builtin_type GTY ((tag ("1"))) builtin;
+    enum builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
     /* Macro argument index.  */
-    unsigned short GTY ((tag ("0"))) arg_index;
-  } GTY ((desc ("0"))) value;
+    unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index;
+  } GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
 };
 
 /* Call this first to get a handle to pass to other functions.
index d11e4ef..0b2a848 100644 (file)
@@ -46,8 +46,11 @@ struct ht
   struct obstack stack;
 
   hashnode *entries;
-  /* Call back.  */
+  /* Call back, allocate a node.  */
   hashnode (*alloc_node) (hash_table *);
+  /* Call back, allocate something that hangs off a node like a cpp_macro.  
+     NULL means use the usual allocator.  */
+  void * (*alloc_subobject) (size_t);
 
   unsigned int nslots;         /* Total slots in the entries array.  */
   unsigned int nelements;      /* Number of live elements.  */
index 3608201..fd3facf 100644 (file)
@@ -24,6 +24,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define LIBCPP_INTERNAL_H
 
 #include "symtab.h"
+#include "cpp-id-data.h"
 
 #if defined HAVE_ICONV_H && defined HAVE_ICONV
 #include <iconv.h>
@@ -45,11 +46,6 @@ struct cset_converter
   iconv_t cd;
 };
 
-#ifndef HAVE_UCHAR
-typedef unsigned char uchar;
-#endif
-#define U (const uchar *)  /* Intended use: U"string" */
-
 #define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t))
 
 /* Test if a sign is valid within a preprocessing number.  */
@@ -90,44 +86,6 @@ struct dummy
 #define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1))
 #define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT)
 
-/* Each macro definition is recorded in a cpp_macro structure.
-   Variadic macros cannot occur with traditional cpp.  */
-struct cpp_macro
-{
-  /* Parameters, if any.  */
-  cpp_hashnode **params;
-
-  /* Replacement tokens (ISO) or replacement text (traditional).  See
-     comment at top of cpptrad.c for how traditional function-like
-     macros are encoded.  */
-  union
-  {
-    cpp_token *tokens;
-    const uchar *text;
-  } exp;
-
-  /* Definition line number.  */
-  fileline line;
-
-  /* Number of tokens in expansion, or bytes for traditional macros.  */
-  unsigned int count;
-
-  /* Number of parameters.  */
-  unsigned short paramc;
-
-  /* If a function-like macro.  */
-  unsigned int fun_like : 1;
-
-  /* If a variadic macro.  */
-  unsigned int variadic : 1;
-
-  /* If macro defined in system header.  */
-  unsigned int syshdr   : 1;
-
-  /* Nonzero if it has been expanded or had its existence tested.  */
-  unsigned int used     : 1;
-};
-
 #define _cpp_mark_macro_used(NODE) do {                                        \
   if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN))     \
     (NODE)->value.macro->used = 1; } while (0)
index 37df6ef..7eafb13 100644 (file)
@@ -1556,3 +1556,25 @@ _cpp_aligned_alloc (cpp_reader *pfile, size_t len)
   buff->cur = result + len;
   return result;
 }
+
+/* Say which field of TOK is in use.  */
+
+enum cpp_token_fld_kind
+cpp_token_val_index (cpp_token *tok)
+{
+  switch (TOKEN_SPELL (tok))
+    {
+    case SPELL_IDENT:
+      return CPP_TOKEN_FLD_NODE;
+    case SPELL_LITERAL:
+      return CPP_TOKEN_FLD_STR;
+    case SPELL_NONE:
+      if (tok->type == CPP_MACRO_ARG)
+       return CPP_TOKEN_FLD_ARG_NO;
+      else if (tok->type == CPP_PADDING)
+       return CPP_TOKEN_FLD_SOURCE;
+      /* else fall through */
+    default:
+      return CPP_TOKEN_FLD_NONE;
+    }
+}
index cfc42b4..dc58b31 100644 (file)
@@ -1408,8 +1408,16 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
       if (!ok)
        return false;
 
-      /* Success.  Commit the parameter array.  */
-      BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
+      /* Success.  Commit or allocate the parameter array.  */
+      if (pfile->hash_table->alloc_subobject)
+       {
+         cpp_token *tokns = pfile->hash_table->alloc_subobject
+           (sizeof (cpp_token) * macro->paramc);
+         memcpy (tokns, macro->params, sizeof (cpp_token) * macro->paramc);
+         macro->params = tokns;
+       }
+      else
+       BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
       macro->fun_like = 1;
     }
   else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
@@ -1472,6 +1480,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
     }
 
   macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff);
+  macro->traditional = 0;
 
   /* Don't count the CPP_EOF.  */
   macro->count--;
@@ -1480,8 +1489,16 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
   if (macro->count)
     macro->exp.tokens[0].flags &= ~PREV_WHITE;
 
-  /* Commit the memory.  */
-  BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
+  /* Commit or allocate the memory.  */
+  if (pfile->hash_table->alloc_subobject)
+    {
+      cpp_token *tokns = pfile->hash_table->alloc_subobject (sizeof (cpp_token)
+                                                            * macro->count);
+      memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count);
+      macro->exp.tokens = tokns;
+    }
+  else
+    BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
 
   return true;
 }
@@ -1494,7 +1511,10 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
   unsigned int i;
   bool ok;
 
-  macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
+  if (pfile->hash_table->alloc_subobject)
+    macro = pfile->hash_table->alloc_subobject (sizeof (cpp_macro));
+  else
+    macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
   macro->line = pfile->directive_line;
   macro->params = 0;
   macro->paramc = 0;
index 51175a9..a9d139a 100644 (file)
@@ -347,15 +347,6 @@ 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 ();
 
@@ -544,46 +535,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)
+       {
+         data->array_size *= 2;
+         data->defns = xrealloc (data->defns, (data->array_size 
+                                               * sizeof (uchar *)));
+       }
+      
+      switch (h->type)
        {
-         struct save_macro_item *d = data->macros;
-         data->macros = xmalloc (sizeof (struct save_macro_item));
-         data->macros->next = d;
-         data->count = 0;
+       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] = 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;
 }
@@ -596,8 +605,9 @@ cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
 {
   struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
   
-  d->macros = NULL;
-  d->count = ARRAY_SIZE (d->macros->macs);
+  d->array_size = 512;
+  d->defns = xmalloc (d->array_size * sizeof (d->defns[0]));
+  d->count = 0;
   cpp_forall_identifiers (r, save_macros, d);
   d->saved_pragmas = _cpp_save_pragma_names (r);
   *data = d;
@@ -612,11 +622,9 @@ 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);
-  struct lexer_state old_state;
   struct save_macro_item *d;
   size_t i, mac_count;
+  struct lexer_state old_state;
 
   /* Restore spec_nodes, which will be full of references to the old 
      hashtable entries and so will now be invalid.  */
@@ -628,70 +636,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;
-
-      if (defnlen < m.definition_length + 1)
-       {
-         defnlen = m.definition_length + 256;
-         defn = xrealloc (defn, defnlen);
-       }
+      size_t namelen;
+      uchar *defn;
 
-      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 = strcspn (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 +668,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)
index f4ce9f6..38e301c 100644 (file)
@@ -701,6 +701,7 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
       cpp_macro *macro = node->value.macro;
       macro->used = 1;
       text = macro->exp.text;
+      macro->traditional = 1;
       len = macro->count;
     }
 
@@ -934,6 +935,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
       memcpy (exp, pfile->out.base, len);
       exp[len] = '\n';
       macro->exp.text = exp;
+      macro->traditional = 1;
       macro->count = len;
     }
   else
@@ -949,6 +951,7 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
       exp = BUFF_FRONT (pfile->a_buff);
       block = (struct block *) (exp + macro->count);
       macro->exp.text = exp;
+      macro->traditional = 1;
 
       /* Write out the block information.  */
       block->text_len = len;