Index: libcpp/ChangeLog
authorGeoffrey Keating <geoffk@apple.com>
Sun, 30 May 2004 00:49:06 +0000 (00:49 +0000)
committerGeoffrey Keating <geoffk@gcc.gnu.org>
Sun, 30 May 2004 00:49:06 +0000 (00:49 +0000)
2004-05-29  Geoffrey Keating  <geoffk@apple.com>

* symtab.c (ht_create): Set entries_owned.
(ht_destroy): Honour entries_owned.
(ht_expand): Likewise.
(ht_load): New.

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

* symtab.h (struct ht): New field 'entries_owned'
(ht_load): New prototype.

Index: gcc/ChangeLog
2004-05-29  Geoffrey Keating  <geoffk@apple.com>

* gengtype-yacc.y: Add NESTED_PTR token.
(option): Record `nested_ptr' option.
* gengtype-lex.l: Handle `nested_ptr' keyword.
* gengtype.c (walk_type): Process `nested_ptr' option.
* gengtype.h (struct nested_ptr_data): New.
* doc/gty.texi (GTY Options): Document `nested_ptr' option.
* stringpool.c (struct string_pool_data): Make 'entries' point to
ht_identifier instead of tree.
(gt_pch_save_stringpool): Don't adjust pointers.
(gt_pch_restore_stringpool): Call ht_load.

From-SVN: r82438

gcc/ChangeLog
gcc/doc/gty.texi
gcc/gengtype-lex.l
gcc/gengtype-yacc.y
gcc/gengtype.c
gcc/gengtype.h
gcc/stringpool.c
libcpp/ChangeLog
libcpp/include/ChangeLog
libcpp/include/symtab.h
libcpp/symtab.c

index 662bf28e60fa883d5e5d90f1f92319195c38638a..00d557730bacbede3f45672cc9c485161979133e 100644 (file)
@@ -1,3 +1,16 @@
+2004-05-29  Geoffrey Keating  <geoffk@apple.com>
+
+       * gengtype-yacc.y: Add NESTED_PTR token.
+       (option): Record `nested_ptr' option.
+       * gengtype-lex.l: Handle `nested_ptr' keyword.
+       * gengtype.c (walk_type): Process `nested_ptr' option.
+       * gengtype.h (struct nested_ptr_data): New.
+       * doc/gty.texi (GTY Options): Document `nested_ptr' option.
+       * stringpool.c (struct string_pool_data): Make 'entries' point to
+       ht_identifier instead of tree.
+       (gt_pch_save_stringpool): Don't adjust pointers.
+       (gt_pch_restore_stringpool): Call ht_load.
+
 2004-05-29  Jason Merrill  <jason@redhat.com>
 
        * gimplify.c (gimplify_expr): Don't build a statement list
index d43feca7221c56656402abfd52a78a2bd6ca5eab..c375e24042da059661b121193f876e99e57ac4a2 100644 (file)
@@ -291,6 +291,19 @@ this field is always @code{NULL}.  This is used to avoid requiring
 backends to define certain optional structures.  It doesn't work with
 language frontends.
 
+@findex nested_ptr
+@item nested_ptr (@var{type}, "@var{to expression}", "@var{from expression}")
+
+The type machinery expects all pointers to point to the start of an
+object.  Sometimes for abstraction purposes it's convenient to have
+a pointer which points inside an object.  So long as it's possible to
+convert the original object to and from the pointer, such pointers
+can still be used.  @var{type} is the type of the original object,
+the @var{to expression} returns the pointer given the original object,
+and the @var{from expression} returns the original object given
+the pointer.  The pointer will be available using the @code{%h}
+escape.
+
 @findex chain_next
 @findex chain_prev
 @item chain_next ("@var{expression}")
index 19d7691f35e9a612ed3c553bb0828c3af714441a..d7fa27ff3bcf631a28c56ada5410a0a0f1542b54 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- indented-text -*- */
 /* Process source files and output type information.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -235,6 +235,7 @@ ITYPE       {IWORD}({WS}{IWORD})*
 "struct"/[^[:alnum:]_]         { return STRUCT; }
 "enum"/[^[:alnum:]_]           { return ENUM; }
 "ptr_alias"/[^[:alnum:]_]      { return ALIAS; }
+"nested_ptr"/[^[:alnum:]_]     { return NESTED_PTR; }
 [0-9]+                         { return NUM; }
 "param"[0-9]*"_is"/[^[:alnum:]_]               { 
   yylval.s = xmemdup (yytext, yyleng, yyleng+1);
index 02136dc0d2974f2b4657a61baa4365b92a6087e7..2e7b6a7057514ed4382613974b750d0c1c630079 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- indented-text -*- */
 /* Process source files and output type information.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -44,6 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 %token STRUCT
 %token ENUM
 %token ALIAS
+%token NESTED_PTR
 %token <s>PARAM_IS
 %token NUM
 %token PERCENTPERCENT "%%"
@@ -279,6 +280,13 @@ option:   ID
             { $$ = create_option ($1, (void *)$3); }
        | type_option '(' type ')'
            { $$ = create_option ($1, adjust_field_type ($3, NULL)); }
+       | NESTED_PTR '(' type ',' stringseq ',' stringseq ')'
+           {
+             struct nested_ptr_data d =
+               { adjust_field_type ($3, NULL), $5, $7 };
+             $$ = create_option ("nested_ptr",
+                                 xmemdup (&d, sizeof (d), sizeof (d)));
+           }
        ;
 
 optionseq: option
index 95c88efd48bc0dd4dcb6b973ffcf4c490db6f874..804ef70320a1900f176cdd89e025113b1c3348b3 100644 (file)
@@ -1509,6 +1509,7 @@ walk_type (type_p t, struct walk_type_data *d)
   int use_param_num = -1;
   int use_params_p = 0;
   options_p oo;
+  const struct nested_ptr_data *nested_ptr_d = NULL;
 
   d->needs_cast_p = 0;
   for (oo = d->opt; oo; oo = oo->next)
@@ -1523,6 +1524,8 @@ walk_type (type_p t, struct walk_type_data *d)
       use_params_p = 1;
     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 ;
     else if (strcmp (oo->name, "dot") == 0)
       ;
     else if (strcmp (oo->name, "tag") == 0)
@@ -1623,7 +1626,48 @@ walk_type (type_p t, struct walk_type_data *d)
                break;
              }
 
-           d->process_field (t->u.p, d);
+           if (nested_ptr_d)
+             {
+               const char *oldprevval2 = d->prev_val[2];
+
+               if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
+                 {
+                   error_at_line (d->line,
+                                  "field `%s' has invalid "
+                                  "option `nested_ptr'\n",
+                                  d->val);
+                   return;
+                 }
+
+               d->prev_val[2] = d->val;
+               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, "",
+                        (nested_ptr_d->type->kind == TYPE_UNION 
+                         ? "union" : "struct"), 
+                        nested_ptr_d->type->u.s.tag, d->val);
+               oprintf (d->of, "%*s", d->indent + 2, "");
+               output_escaped_param (d, nested_ptr_d->convert_from,
+                                     "nested_ptr");
+               oprintf (d->of, ";\n");
+
+               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");
+
+               d->indent -= 2;
+               oprintf (d->of, "%*s}\n", d->indent, "");
+               d->val = d->prev_val[2];
+               d->prev_val[2] = oldprevval2;
+             }
+           else
+             d->process_field (t->u.p, d);
          }
        else
          {
index 55ece1150737ef91b837feb56f08e2c986fd286a..bf3c5624ced69483fd7f8e9320f63c17ea874b03 100644 (file)
@@ -37,6 +37,17 @@ enum typekind {
   TYPE_PARAM_STRUCT
 };
 
+typedef struct pair *pair_p;
+typedef struct type *type_p;
+typedef unsigned lang_bitmap;
+
+/* Option data for the 'nested_ptr' option.  */
+struct nested_ptr_data {
+  type_p type;
+  const char *convert_to;
+  const char *convert_from;
+};    
+
 /* A way to pass data through to the output end.  */
 typedef struct options {
   struct options *next;
@@ -44,10 +55,6 @@ typedef struct options {
   const void *info;
 } *options_p;
 
-typedef struct pair *pair_p;
-typedef struct type *type_p;
-typedef unsigned lang_bitmap;
-
 /* A name and a type.  */
 struct pair {
   pair_p next;
index 781518b9f7d4b549942213aa8b71605f90fb469b..d17f31decdde9da68c8505ec76f16e8311312b43 100644 (file)
@@ -1,5 +1,5 @@
 /* String pool for GCC.
-   Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -201,7 +201,11 @@ gt_pch_n_S (const void *x)
 
 struct string_pool_data GTY(())
 {
-  tree * GTY((length ("%h.nslots"))) entries;
+  struct ht_identifier * * 
+    GTY((length ("%h.nslots"),
+        nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
+                    "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
+    entries;
   unsigned int nslots;
   unsigned int nelements;
 };
@@ -237,25 +241,20 @@ ht_copy_and_clear (cpp_reader *r ATTRIBUTE_UNUSED, hashnode hp, const void *ht2_
 
 static struct ht *saved_ident_hash;
 
-/* The hash table contains pointers to the cpp_hashnode inside the
-   lang_identifier.  The PCH machinery can't handle pointers that refer
-   to the inside of an object, so to save the hash table for PCH the
-   pointers are adjusted and stored in the variable SPD.  */
+/* 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.  */
 
 void
 gt_pch_save_stringpool (void)
 {
-  unsigned int i;
-
   spd = ggc_alloc (sizeof (*spd));
   spd->nslots = ident_hash->nslots;
   spd->nelements = ident_hash->nelements;
-  spd->entries = ggc_alloc (sizeof (tree *) * spd->nslots);
-  for (i = 0; i < spd->nslots; i++)
-    if (ident_hash->entries[i] != NULL)
-      spd->entries[i] = HT_IDENT_TO_GCC_IDENT (ident_hash->entries[i]);
-    else
-      spd->entries[i] = NULL;
+  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;
@@ -274,23 +273,12 @@ gt_pch_fixup_stringpool (void)
 }
 
 /* A PCH file has been restored, which loaded SPD; fill the real hash table
-   with adjusted pointers from SPD.  */
+   from SPD.  */
 
 void
 gt_pch_restore_stringpool (void)
 {
-  unsigned int i;
-
-  ident_hash->nslots = spd->nslots;
-  ident_hash->nelements = spd->nelements;
-  ident_hash->entries = xrealloc (ident_hash->entries,
-                                 sizeof (hashnode) * spd->nslots);
-  for (i = 0; i < spd->nslots; i++)
-    if (spd->entries[i] != NULL)
-      ident_hash->entries[i] = GCC_IDENT_TO_HT_IDENT (spd->entries[i]);
-    else
-      ident_hash->entries[i] = NULL;
-
+  ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
   spd = NULL;
 }
 
index 8ebe6f52baca24191013bbdbdfa8b6e570934212..71a449504b047fc1293bc39b5eb9dac1d25f726c 100644 (file)
@@ -1,3 +1,10 @@
+2004-05-29  Geoffrey Keating  <geoffk@apple.com>
+
+       * symtab.c (ht_create): Set entries_owned.
+       (ht_destroy): Honour entries_owned.
+       (ht_expand): Likewise.
+       (ht_load): New.
+
 2004-05-26  Paolo Bonzini  <bonzini@gnu.org>
 
        PR bootstrap/15651
index f6c47fa6daf0d712cc9f4f56ad5c43c4e03c827c..a2f4bc5e3ef3c9e3f052c3d14469df8d4c5a78ad 100644 (file)
@@ -1,3 +1,8 @@
+2004-05-29  Geoffrey Keating  <geoffk@apple.com>
+
+       * symtab.h (struct ht): New field 'entries_owned'
+       (ht_load): New prototype.
+
 2004-05-23  Paolo Bonzini  <bonzini@gnu.org>
 
        * cpplib.h: Moved from gcc.  Change header guard name.
index 8b793320b56c758d9f21eddc5a2b62127930dfeb..85e285b419fe351aa5f9680e67c2f90160223065 100644 (file)
@@ -1,5 +1,5 @@
 /* Hash tables.
-   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 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
@@ -58,6 +58,9 @@ struct ht
   /* Table usage statistics.  */
   unsigned int searches;
   unsigned int collisions;
+
+  /* Should 'entries' be freed when it is no longer needed?  */
+  bool entries_owned;
 };
 
 /* Initialize the hashtable with 2 ^ order entries.  */
@@ -75,6 +78,10 @@ extern hashnode ht_lookup (hash_table *, const unsigned char *,
 typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *);
 extern void ht_forall (hash_table *, ht_cb, const void *);
 
+/* Restore the hash table.  */
+extern void ht_load (hash_table *ht, hashnode *entries,
+                    unsigned int nslots, unsigned int nelements, bool own);
+
 /* Dump allocation statistics to stderr.  */
 extern void ht_dump_statistics (hash_table *);
 
index 39cecedf72f39cd8ad668e797a4105cc0ece5c75..c80dfa25cc0e661e3baa7682183cec70b637a8eb 100644 (file)
@@ -1,5 +1,5 @@
 /* Hash tables.
-   Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 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
@@ -68,6 +68,7 @@ ht_create (unsigned int order)
   obstack_alignment_mask (&table->stack) = 0;
 
   table->entries = xcalloc (nslots, sizeof (hashnode));
+  table->entries_owned = true;
   table->nslots = nslots;
   return table;
 }
@@ -78,7 +79,8 @@ void
 ht_destroy (hash_table *table)
 {
   obstack_free (&table->stack, NULL);
-  free (table->entries);
+  if (table->entries_owned)
+    free (table->entries);
   free (table);
 }
 
@@ -199,7 +201,9 @@ ht_expand (hash_table *table)
       }
   while (++p < limit);
 
-  free (table->entries);
+  if (table->entries_owned)
+    free (table->entries);
+  table->entries_owned = true;
   table->entries = nentries;
   table->nslots = size;
 }
@@ -222,6 +226,20 @@ ht_forall (hash_table *table, ht_cb cb, const void *v)
   while (++p < limit);
 }
 
+/* Restore the hash table.  */
+void
+ht_load (hash_table *ht, hashnode *entries,
+        unsigned int nslots, unsigned int nelements,
+        bool own)
+{
+  if (ht->entries_owned)
+    free (ht->entries);
+  ht->entries = entries;
+  ht->nslots = nslots;
+  ht->nelements = nelements;
+  ht->entries_owned = own;
+}
+
 /* Dump allocation statistics to stderr.  */
 
 void