diff mbox

gengtype improvements for plugins. patch 5/N [typedopt]

Message ID 1283101940.3067.103.camel@glinka
State New
Headers show

Commit Message

Basile Starynkevitch Aug. 29, 2010, 5:12 p.m. UTC
See http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02058.html &
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02060.html &
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02063.html &
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02065.html
for the previous pieces of the patch.


The fifth piece just makes the option a discriminated union. This is
absolutely required to write & re-read a persistent state (otherwise,
there is no *simple* way to know which member of the union to use).

The patch also renamed as styline & ptyline the location sub-fields of
struct type. This is for improved readability & was and is used to help
track bugs (like e.g.
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg01992.html etc)

And most of the patch is just moving many definitions from gengtype.c to
gengtype.h. They need to be public for the future gengtype-state.c file.

As usual, I am attaching a relative patch to the previous (4th, 3rd, 
2nd, 1st) patches and a gcc/ChangeLog entry. And for completeness the
cumulated total patch against r163612 of trunk.

The generated files did not change.

Ok for trunk?


Cheers.

Comments

Basile Starynkevitch Aug. 29, 2010, 7:23 p.m. UTC | #1
See http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02058.html &
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02060.html &
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02063.html &
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02065.html & 
http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02068.html
for the previous pieces of the patch.

In my understanding, the files generated by gengtype patched as above do
not change from current trunk's behavior. Even better, the same files
are generated with the current trunk (r.163612-), with the current trunk
plus only the first patch piece applied, with the current trunk plus the
two first patch pieces applied, etc.



Ian Taylor, Diego Novillo, Paolo Bonzini and others, is that slicing in
several pieces enough for you? I hope yes!

We (Jeremie Salvucci & me Basile) strongly believe that the just
referenced patch pieces can be reviewed & should go into the trunk
before end of stage 1 of 4.6 i.e. current trunk.
Laurynas Biveinis Sept. 6, 2010, 3:13 a.m. UTC | #2
A lot of definitions in this patch are both changed slightly and moved
to gengtype.h from gengtype.c. So with respect to this particular
patch, a proper patch splitting would be separate patches for changing
things and moving things around. Then reviewers are able to see more
easily what exactly has changed in the definitions. But I guess this
patch is small enough so you don't have to resubmit it that way.

> 	(string_type, scalar_nonchar, scalar_char): Definitions made
> 	public & updated.

C has no notion of "public", what you are doing here is removing "static".

+enum typekind {
+    TYPE__NONE=0,		/* Never used, so any zero-ed type is
+				   invalid. */

Why not just TYPE_NONE ?

+    INFO__NONE=0,		/* Never used. */

Same.

+struct options
+{
+    struct options *next;
+    const char *name;
+    enum info_kind kind;
+  /* the union below is discriminated by the 'kind' field above. */

Watch indentation.

+/* Our type structure describes all types handled by gengtype. */
+struct type
+{
...
+      struct fileloc styline;
...
+      struct fileloc ptyline;
...
+};

I think these two renames are redudant. The original "struct fileloc
line" is non-ambiguous, not to mention that using it would reduce the
patch size.

+create_type_option (options_p next, const char* name, type_p info)

+options_p
+create_nested_option (options_p next, const char* name,
+		      struct nested_ptr_data* info)

These two need their own comments.


I think this patch is a great improvement to gengtype internals and I
would like very much to see it committed. I cannot approve it, but it
looks good to me with the comments addressed.


2010/8/29 Basile Starynkevitch <basile@starynkevitch.net>:
>
> See http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02058.html &
> http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02060.html &
> http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02063.html &
> http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02065.html
> for the previous pieces of the patch.
>
>
> The fifth piece just makes the option a discriminated union. This is
> absolutely required to write & re-read a persistent state (otherwise,
> there is no *simple* way to know which member of the union to use).
>
> The patch also renamed as styline & ptyline the location sub-fields of
> struct type. This is for improved readability & was and is used to help
> track bugs (like e.g.
> http://gcc.gnu.org/ml/gcc-patches/2010-08/msg01992.html etc)
>
> And most of the patch is just moving many definitions from gengtype.c to
> gengtype.h. They need to be public for the future gengtype-state.c file.
>
> As usual, I am attaching a relative patch to the previous (4th, 3rd,
> 2nd, 1st) patches and a gcc/ChangeLog entry. And for completeness the
> cumulated total patch against r163612 of trunk.
>
> The generated files did not change.
>
> Ok for trunk?
>
>
> Cheers.
>
> --
> Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
> email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
> 8, rue de la Faiencerie, 92340 Bourg La Reine, France
> *** opinions {are only mine, sont seulement les miennes} ***
>
Laurynas Biveinis Sept. 6, 2010, 3:15 a.m. UTC | #3
2010/8/29 Basile Starynkevitch <basile@starynkevitch.net>:
> Ian Taylor, Diego Novillo, Paolo Bonzini and others, is that slicing in
> several pieces enough for you? I hope yes!

FWIW, I think Basile's and Jeremie's submission is split well enough
for reviews.

> I am not able to break the gengtype-state.c into independent & testable
> pieces. Is it acceptable to send an entire new file in a patch?

Yes.

> What should be the ChangeLog entry for an entire new file. Is just a
> simple line
>   * gengtype-state.c: Added file.
> enough

I believe so.
diff mbox

Patch

--- ../gengtype-gcc-04/gengtype.c	2010-08-29 13:20:46.000000000 +0200
+++ gcc/gengtype.c	2010-08-29 18:29:02.000000000 +0200
@@ -29,100 +29,6 @@ 
 #include "obstack.h"
 #include "gengtype.h"
 
-/* Data types, macros, etc. used only in this file.  */
-
-/* Kinds of types we can understand.  */
-enum typekind {
-  TYPE_SCALAR,
-  TYPE_STRING,
-  TYPE_STRUCT,
-  TYPE_UNION,
-  TYPE_POINTER,
-  TYPE_ARRAY,
-  TYPE_LANG_STRUCT,
-  TYPE_PARAM_STRUCT
-};
-
-/* A way to pass data through to the output end.  */
-struct options
-{
-  struct options *next;
-  const char *name;
-  const char *info;
-};
-
-/* Option data for the 'nested_ptr' option.  */
-struct nested_ptr_data
-{
-  type_p type;
-  const char *convert_to;
-  const char *convert_from;
-};
-
-/* A name and a type.  */
-struct pair
-{
-  pair_p next;
-  const char *name;
-  type_p type;
-  struct fileloc line;
-  options_p opt;
-};
-
-#define NUM_PARAM 10
-
-/* A description of a type.  */
-enum gc_used_enum
-  {
-    GC_UNUSED = 0,
-    GC_USED,
-    /* Used for structures whose definitions we haven't seen so far when
-       we encounter a pointer to it that is annotated with ``maybe_undef''.
-       If after reading in everything we don't have source file
-       information for it, we assume that it never has been defined. */
-    GC_MAYBE_POINTED_TO,
-    GC_POINTED_TO
-  };
-
-struct type
-{
-  enum typekind kind;
-  type_p next;
-  type_p pointer_to;
-  enum gc_used_enum gc_used;
-  union {
-    type_p p;
-    struct {
-      const char *tag;
-      struct fileloc line;
-      pair_p fields;
-      options_p opt;
-      lang_bitmap bitmap;
-      type_p lang_struct;
-    } s;
-    bool scalar_is_char;
-    struct {
-      type_p p;
-      const char *len;
-    } a;
-    struct {
-      type_p stru;
-      type_p param[NUM_PARAM];
-      struct fileloc line;
-    } param_struct;
-  } u;
-};
-
-#define UNION_P(x)					\
- ((x)->kind == TYPE_UNION || 				\
-  ((x)->kind == TYPE_LANG_STRUCT 			\
-   && (x)->u.s.lang_struct->kind == TYPE_UNION))
-#define UNION_OR_STRUCT_P(x)			\
- ((x)->kind == TYPE_UNION 			\
-  || (x)->kind == TYPE_STRUCT 			\
-  || (x)->kind == TYPE_LANG_STRUCT)
-
-
 
 
 /* Rhe name of the file containing the list of input files. */
@@ -469,18 +375,18 @@  read_input_list (const char *listname)
 
 /* The one and only TYPE_STRING.  */
 
-static struct type string_type = {
-  TYPE_STRING, 0, 0, GC_USED, {0}
+struct type string_type = {
+  TYPE_STRING, 0, 0, 0, GC_USED, {0}
 };
 
 /* The two and only TYPE_SCALARs.  Their u.scalar_is_char flags are
    set to appropriate values at the beginning of main.  */
 
-static struct type scalar_nonchar = {
-  TYPE_SCALAR, 0, 0, GC_USED, {0}
+struct type scalar_nonchar = {
+  TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
 };
-static struct type scalar_char = {
-  TYPE_SCALAR, 0, 0, GC_USED, {0}
+struct type scalar_char = {
+  TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
 };
 
 /* Lists of various things.  */
@@ -649,7 +555,7 @@  new_structure (const char *name, int isu
 	      if (si->u.s.bitmap == bitmap)
 		s = si;
 	  }
-	else if (si->u.s.line.ifile != NULL && si->u.s.bitmap != bitmap)
+	else if (si->u.s.styline.ifile != NULL && si->u.s.bitmap != bitmap)
 	  {
 	    ls = si;
 	    si = XCNEW (struct type);
@@ -681,17 +587,17 @@  new_structure (const char *name, int isu
       structures = s;
     }
 
-  if (s->u.s.line.ifile != NULL
+  if (s->u.s.styline.ifile != NULL
       || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
     {
       error_at_line (pos, "duplicate definition of '%s %s'",
 		     isunion ? "union" : "struct", s->u.s.tag);
-      error_at_line (&s->u.s.line, "previous definition here");
+      error_at_line (&s->u.s.styline, "previous definition here");
     }
 
   s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
   s->u.s.tag = name;
-  s->u.s.line = *pos;
+  s->u.s.styline = *pos;
   s->u.s.fields = fields;
   s->u.s.opt = o;
   s->u.s.bitmap = bitmap;
@@ -709,7 +615,7 @@  new_structure (const char *name, int isu
 	if (!strcmp (gtfilnam + strlen (gtfilnam) - strlen ("input.h"),
 		     "input.h"))
 	  {
-	    s->u.s.line.ifile = gt_files[n];
+	    s->u.s.styline.ifile = gt_files[n];
 	    break;
 	  }
       }
@@ -799,7 +705,6 @@  type_p
 create_array (type_p t, const char *len)
 {
   type_p v;
-
   v = XCNEW (struct type);
   v->kind = TYPE_ARRAY;
   v->u.a.p = t;
@@ -807,16 +712,44 @@  create_array (type_p t, const char *len)
   return v;
 }
 
-/* Return an options structure with name NAME and info INFO.  NEXT is the
-   next option in the chain.  */
+/* Create various options structures with name NAME and info INFO.
+   NEXT is the next option in the chain.  */
+
+options_p
+create_string_option (options_p next, const char* name, const char* info)
+{
+  options_p o;
+  o = XCNEW (struct options);
+  o->next = next;
+  o->name = name;
+  o->kind = INFO_STRING;
+  o->info.string = info;
+  return o;
+}
+
 
 options_p
-create_option (options_p next, const char *name, const void *info)
+create_type_option (options_p next, const char* name, type_p info)
 {
-  options_p o = XNEW (struct options);
+  options_p o;
+  o = XCNEW (struct options);
   o->next = next;
   o->name = name;
-  o->info = (const char*) info;
+  o->kind = INFO_TYPE;
+  o->info.type = info;
+  return o;
+}
+
+options_p
+create_nested_option (options_p next, const char* name, 
+		      struct nested_ptr_data* info)
+{
+    options_p o;
+    o = XCNEW (struct options);
+    o->next = next;
+    o->name = name;
+    o->kind = INFO_NESTED;
+    o->info.nested = info;
   return o;
 }
 
@@ -830,7 +763,7 @@  create_nested_ptr_option (options_p next
   d->type = adjust_field_type (t, 0);
   d->convert_to = to;
   d->convert_from = from;
-  return create_option (next, "nested_ptr", d);
+  return create_nested_option (next, "nested_ptr", d);
 }
 
 /* Add a variable named S of type T with options O defined at POS,
@@ -898,15 +831,15 @@  create_optional_field_ (pair_p next, typ
      The field has a tag of "1".  This allows us to make the presence
      of a field of type TYPE depend on some boolean "desc" being true.  */
   union_fields = create_field (NULL, type, "");
-  union_fields->opt = create_option (union_fields->opt, "dot", "");
-  union_fields->opt = create_option (union_fields->opt, "tag", "1");
+  union_fields->opt = create_string_option (union_fields->opt, "dot", "");
+  union_fields->opt = create_string_option (union_fields->opt, "tag", "1");
   union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
 			      &lexer_line, union_fields, NULL);
 
   /* Create the field and give it the new fake union type.  Add a "desc"
      tag that specifies the condition under which the field is valid.  */
   return create_field_all (next, union_type, name,
-			   create_option (0, "desc", cond),
+			   create_string_option (0, "desc", cond),
 			   input_file_name (this_file), line);
 }
 #define create_optional_field(next,type,name,cond)	\
@@ -1038,7 +971,7 @@  adjust_field_rtx_def (type_p t, options_
       return &string_type;
     }
 
-  nodot = create_option (NULL, "dot", "");
+  nodot = create_string_option (NULL, "dot", "");
 
   rtx_tp = create_pointer (find_structure ("rtx_def", 0));
   rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
@@ -1078,9 +1011,9 @@  adjust_field_rtx_def (type_p t, options_
 	/* NOTE_INSN_MAX is used as the default field for line
 	   number notes.  */
 	if (c == NOTE_INSN_MAX)
-	  note_flds->opt = create_option (nodot, "default", "");
+	  note_flds->opt = create_string_option (nodot, "default", "");
 	else
-	  note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
+	  note_flds->opt = create_string_option (nodot, "tag", note_insn_name[c]);
       }
     note_union_tp = new_structure ("rtx_def_note_subunion", 1,
 				   &lexer_line, note_flds, NULL);
@@ -1090,10 +1023,10 @@  adjust_field_rtx_def (type_p t, options_
     pair_p sym_flds;
 
     sym_flds = create_field (NULL, tree_tp, "rt_tree");
-    sym_flds->opt = create_option (nodot, "default", "");
+    sym_flds->opt = create_string_option (nodot, "default", "");
 
     sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
-    sym_flds->opt = create_option (nodot, "tag", "1");
+    sym_flds->opt = create_string_option (nodot, "tag", "1");
 
     symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
 				     &lexer_line, sym_flds, NULL);
@@ -1212,10 +1145,10 @@  adjust_field_rtx_def (type_p t, options_
 					       subname));
 	  subfields->opt = nodot;
 	  if (t == note_union_tp)
-	    subfields->opt = create_option (subfields->opt, "desc",
+	    subfields->opt = create_string_option (subfields->opt, "desc",
 					    "NOTE_KIND (&%0)");
 	  if (t == symbol_union_tp)
-	    subfields->opt = create_option (subfields->opt, "desc",
+	    subfields->opt = create_string_option (subfields->opt, "desc",
 					    "CONSTANT_POOL_ADDRESS_P (&%0)");
 	}
 
@@ -1236,7 +1169,7 @@  adjust_field_rtx_def (type_p t, options_
 	ftag[nmindex] = TOUPPER (ftag[nmindex]);
 
       flds = create_field (flds, substruct, "");
-      flds->opt = create_option (nodot, "tag", ftag);
+      flds->opt = create_string_option (nodot, "tag", ftag);
     }
 
   return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
@@ -1261,12 +1194,12 @@  adjust_field_tree_exp (type_p t, options
       return &string_type;
     }
 
-  nodot = create_option (NULL, "dot", "");
+  nodot = create_string_option (NULL, "dot", "");
 
   flds = create_field (NULL, t, "");
-  flds->opt = create_option (nodot, "length",
+  flds->opt = create_string_option (nodot, "length",
 			     "TREE_OPERAND_LENGTH ((tree) &%0)");
-  flds->opt = create_option (flds->opt, "default", "");
+  flds->opt = create_string_option (flds->opt, "default", "");
 
   return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
 }
@@ -1316,13 +1249,13 @@  adjust_field_type (type_p t, options_p o
 	if (params[num] != NULL)
 	  error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
 	if (! ISDIGIT (opt->name[5]))
-	  params[num] = create_pointer (CONST_CAST2(type_p, const char *, opt->info));
+	  params[num] = create_pointer (opt->info.type);
 	else
-	  params[num] = CONST_CAST2 (type_p, const char *, opt->info);
+	  params[num] = opt->info.type;
       }
     else if (strcmp (opt->name, "special") == 0)
       {
-	const char *special_name = opt->info;
+	const char *special_name = opt->info.string;
 	if (strcmp (special_name, "tree_exp") == 0)
 	  t = adjust_field_tree_exp (t, opt);
 	else if (strcmp (special_name, "rtx_def") == 0)
@@ -1366,8 +1299,9 @@  process_gc_options (options_p opt, enum
 {
   options_p o;
   for (o = opt; o; o = o->next)
-    if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
-      set_gc_used_type (CONST_CAST2 (type_p, const char *, o->info),
+    if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO
+	&& o->kind == INFO_TYPE)
+      set_gc_used_type (o->info.type,
 			GC_POINTED_TO, NULL);
     else if (strcmp (o->name, "maybe_undef") == 0)
       *maybe_undef = 1;
@@ -1378,7 +1312,7 @@  process_gc_options (options_p opt, enum
     else if (strcmp (o->name, "skip") == 0)
       *skip = 1;
     else if (strcmp (o->name, "nested_ptr") == 0)
-      *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
+      *nested_ptr = ((const struct nested_ptr_data *) o->info.nested)->type;
 }
 
 /* Set the gc_used field of T to LEVEL, and handle the types it references.  */
@@ -2232,6 +2166,8 @@  output_mangled_typename (outf_p of, cons
     oprintf (of, "Z");
   else switch (t->kind)
     {
+    case TYPE__NONE:
+      fatal ("uninitialized type");
     case TYPE_POINTER:
       oprintf (of, "P");
       output_mangled_typename (of, t->u.p);
@@ -2326,7 +2262,7 @@  walk_type (type_p t, struct walk_type_da
   d->needs_cast_p = false;
   for (oo = d->opt; oo; oo = oo->next)
     if (strcmp (oo->name, "length") == 0)
-      length = oo->info;
+      length = oo->info.string;
     else if (strcmp (oo->name, "maybe_undef") == 0)
       maybe_undef_p = 1;
     else if (strncmp (oo->name, "use_param", 9) == 0
@@ -2334,12 +2270,12 @@  walk_type (type_p t, struct walk_type_da
       use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
     else if (strcmp (oo->name, "use_params") == 0)
       use_params_p = 1;
-    else if (strcmp (oo->name, "desc") == 0)
-      desc = oo->info;
+    else if (strcmp (oo->name, "desc") == 0 && oo->kind == INFO_STRING)
+      desc = oo->info.string;
     else if (strcmp (oo->name, "mark_hook") == 0)
       ;
-    else if (strcmp (oo->name, "nested_ptr") == 0)
-      nested_ptr_d = (const struct nested_ptr_data *) oo->info;
+    else if (strcmp (oo->name, "nested_ptr") == 0 && oo->kind == INFO_NESTED)
+      nested_ptr_d = (const struct nested_ptr_data *) oo->info.nested;
     else if (strcmp (oo->name, "dot") == 0)
       ;
     else if (strcmp (oo->name, "tag") == 0)
@@ -2427,7 +2363,7 @@  walk_type (type_p t, struct walk_type_da
     case TYPE_POINTER:
       {
 	if (maybe_undef_p
-	    && t->u.p->u.s.line.ifile == NULL)
+	    && t->u.p->u.s.styline.ifile == NULL)
 	  {
 	    oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
 	    break;
@@ -2581,7 +2517,7 @@  walk_type (type_p t, struct walk_type_da
 	int seen_default_p = 0;
 	options_p o;
 
-	if (! t->u.s.line.ifile)
+	if (! t->u.s.styline.ifile)
 	  error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
 
 	if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
@@ -2589,13 +2525,13 @@  walk_type (type_p t, struct walk_type_da
 	    error_at_line (d->line,
 			   "structure `%s' defined for mismatching languages",
 			   t->u.s.tag);
-	    error_at_line (&t->u.s.line, "one structure defined here");
+	    error_at_line (&t->u.s.styline, "one structure defined here");
 	  }
 
 	/* Some things may also be defined in the structure's options.  */
 	for (o = t->u.s.opt; o; o = o->next)
-	  if (! desc && strcmp (o->name, "desc") == 0)
-	    desc = o->info;
+	  if (! desc && strcmp (o->name, "desc") == 0 && o->kind == INFO_STRING)
+	    desc = o->info.string;
 
 	d->prev_val[2] = oldval;
 	d->prev_val[1] = oldprevval2;
@@ -2625,16 +2561,16 @@  walk_type (type_p t, struct walk_type_da
 
 	    d->reorder_fn = NULL;
 	    for (oo = f->opt; oo; oo = oo->next)
-	      if (strcmp (oo->name, "dot") == 0)
-		dot = oo->info;
-	      else if (strcmp (oo->name, "tag") == 0)
-		tagid = oo->info;
+	      if (strcmp (oo->name, "dot") == 0&& oo->kind == INFO_STRING)
+		dot = oo->info.string;
+	      else if (strcmp (oo->name, "tag") == 0 && oo->kind == INFO_STRING)
+		tagid = oo->info.string;
 	      else if (strcmp (oo->name, "skip") == 0)
 		skip_p = 1;
 	      else if (strcmp (oo->name, "default") == 0)
 		default_p = 1;
-	      else if (strcmp (oo->name, "reorder") == 0)
-		d->reorder_fn = oo->info;
+	      else if (strcmp (oo->name, "reorder") == 0 && oo->kind == INFO_STRING)
+		d->reorder_fn = oo->info.string;
 	      else if (strncmp (oo->name, "use_param", 9) == 0
 		       && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
 		use_param_p = 1;
@@ -2762,13 +2698,13 @@  write_types_process_field (type_p f, con
 	    oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
 
 	  if (f->u.p->kind == TYPE_PARAM_STRUCT
-	      && f->u.p->u.param_struct.line.ifile != NULL)
+	      && f->u.p->u.param_struct.ptyline.ifile != NULL)
 	    {
 	      oprintf (d->of, ", gt_e_");
 	      output_mangled_typename (d->of, f);
 	    }
 	  else if (UNION_OR_STRUCT_P (f)
-		   && f->u.p->u.s.line.ifile != NULL)
+		   && f->u.p->u.s.styline.ifile != NULL)
 	    {
 	      oprintf (d->of, ", gt_ggc_e_");
 	      output_mangled_typename (d->of, f);
@@ -2810,12 +2746,12 @@  write_types_process_field (type_p f, con
 static void
 output_type_enum (outf_p of, type_p s)
 {
-  if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.line.ifile != NULL)
+  if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.ptyline.ifile != NULL)
     {
       oprintf (of, ", gt_e_");
       output_mangled_typename (of, s);
     }
-  else if (UNION_OR_STRUCT_P (s) && s->u.s.line.ifile != NULL)
+  else if (UNION_OR_STRUCT_P (s) && s->u.s.styline.ifile != NULL)
     {
       oprintf (of, ", gt_ggc_e_");
       output_mangled_typename (of, s);
@@ -2834,9 +2770,9 @@  get_output_file_for_structure (const_typ
   int i;
 
   if (UNION_OR_STRUCT_P (s))
-    fn = s->u.s.line.ifile;
+    fn = s->u.s.styline.ifile;
   else if (s->kind == TYPE_PARAM_STRUCT)
-    fn = s->u.param_struct.line.ifile;
+    fn = s->u.param_struct.ptyline.ifile;
 
   gcc_assert (!fn || fn->inpmagic == INPUT_FILE_MAGIC);
 
@@ -2844,7 +2780,7 @@  get_output_file_for_structure (const_typ
   for (i = NUM_PARAM - 1; i >= 0; i--)
     if (param && param[i] && param[i]->kind == TYPE_POINTER
 	&& UNION_OR_STRUCT_P (param[i]->u.p))
-      fn = param[i]->u.p->u.s.line.ifile;
+      fn = param[i]->u.p->u.s.styline.ifile;
 
   gcc_assert (!fn || fn->inpmagic == INPUT_FILE_MAGIC);
 
@@ -2874,19 +2810,23 @@  write_func_for_structure (type_p orig_s,
   d.of = get_output_file_for_structure (s, param);
 
   for (opt = s->u.s.opt; opt; opt = opt->next)
-    if (strcmp (opt->name, "chain_next") == 0)
-      chain_next = opt->info;
-    else if (strcmp (opt->name, "chain_prev") == 0)
-      chain_prev = opt->info;
-    else if (strcmp (opt->name, "chain_circular") == 0)
-      chain_circular = opt->info;
-    else if (strcmp (opt->name, "mark_hook") == 0)
-      mark_hook_name = opt->info;
+    if (strcmp (opt->name, "chain_next") == 0
+	&& opt->kind == INFO_STRING)
+      chain_next = opt->info.string;
+    else if (strcmp (opt->name, "chain_prev") == 0 
+	     && opt->kind == INFO_STRING)
+      chain_prev = opt->info.string;
+    else if (strcmp (opt->name, "chain_circular") == 0
+	     && opt->kind == INFO_STRING)
+      chain_circular = opt->info.string;
+    else if (strcmp (opt->name, "mark_hook") == 0 
+	     && opt->kind == INFO_STRING)
+      mark_hook_name = opt->info.string;
 
   if (chain_prev != NULL && chain_next == NULL)
-    error_at_line (&s->u.s.line, "chain_prev without chain_next");
+    error_at_line (&s->u.s.styline, "chain_prev without chain_next");
   if (chain_circular != NULL && chain_next != NULL)
-    error_at_line (&s->u.s.line, "chain_circular with chain_next");
+    error_at_line (&s->u.s.styline, "chain_circular with chain_next");
   if (chain_circular != NULL)
     chain_next = chain_circular;
 
@@ -2894,7 +2834,7 @@  write_func_for_structure (type_p orig_s,
   d.cookie = wtd;
   d.orig_s = orig_s;
   d.opt = s->u.s.opt;
-  d.line = &s->u.s.line;
+  d.line = &s->u.s.styline;
   d.bitmap = s->u.s.bitmap;
   d.param = param;
   d.prev_val[0] = "*x";
@@ -3039,7 +2979,7 @@  write_types (outf_p output_header, type_
 	options_p opt;
 
 	if (s->gc_used == GC_MAYBE_POINTED_TO
-	    && s->u.s.line.ifile == NULL)
+	    && s->u.s.styline.ifile == NULL)
 	  continue;
 
 	oprintf (output_header, "#define gt_%s_", wtd->prefix);
@@ -3052,9 +2992,9 @@  write_types (outf_p output_header, type_
 		 "  } while (0)\n");
 
 	for (opt = s->u.s.opt; opt; opt = opt->next)
-	  if (strcmp (opt->name, "ptr_alias") == 0)
+	  if (strcmp (opt->name, "ptr_alias") == 0 && opt->kind == INFO_TYPE)
 	    {
-	      const_type_p const t = (const_type_p) opt->info;
+	      const_type_p const t = (const_type_p) opt->info.type;
 	      if (t->kind == TYPE_STRUCT
 		  || t->kind == TYPE_UNION
 		  || t->kind == TYPE_LANG_STRUCT)
@@ -3062,7 +3002,7 @@  write_types (outf_p output_header, type_
 			 "#define gt_%sx_%s gt_%sx_%s\n",
 			 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
 	      else
-		error_at_line (&s->u.s.line,
+		error_at_line (&s->u.s.styline,
 			       "structure alias is not a structure");
 	      break;
 	    }
@@ -3074,7 +3014,7 @@  write_types (outf_p output_header, type_
 		 "extern void gt_%sx_%s (void *);\n",
 		 wtd->prefix, s->u.s.tag);
 
-	if (s->u.s.line.ifile == NULL)
+	if (s->u.s.styline.ifile == NULL)
 	  {
 	    fprintf (stderr, "warning: structure `%s' used but not defined\n",
 		     s->u.s.tag);
@@ -3092,7 +3032,7 @@  write_types (outf_p output_header, type_
 	output_mangled_typename (output_header, s);
 	oprintf (output_header, " (void *);\n");
 
-	if (stru->u.s.line.ifile == NULL)
+	if (stru->u.s.styline.ifile == NULL)
 	  {
 	    fprintf (stderr, "warning: structure `%s' used but not defined\n",
 		     s->u.s.tag);
@@ -3109,7 +3049,7 @@  write_types (outf_p output_header, type_
 	options_p opt;
 
 	if (s->gc_used == GC_MAYBE_POINTED_TO
-	    && s->u.s.line.ifile == NULL)
+	    && s->u.s.styline.ifile == NULL)
 	  continue;
 	for (opt = s->u.s.opt; opt; opt = opt->next)
 	  if (strcmp (opt->name, "ptr_alias") == 0)
@@ -3131,7 +3071,7 @@  write_types (outf_p output_header, type_
       {
 	type_p *param = s->u.param_struct.param;
 	type_p stru = s->u.param_struct.stru;
-	if (stru->u.s.line.ifile == NULL)
+	if (stru->u.s.styline.ifile == NULL)
 	  continue;
 	if (stru->kind == TYPE_LANG_STRUCT)
 	  {
@@ -3202,7 +3142,7 @@  write_local_func_for_structure (const_ty
   d.of = get_output_file_for_structure (s, param);
   d.process_field = write_types_local_process_field;
   d.opt = s->u.s.opt;
-  d.line = &s->u.s.line;
+  d.line = &s->u.s.styline;
   d.bitmap = s->u.s.bitmap;
   d.param = param;
   d.prev_val[0] = d.prev_val[2] = "*x";
@@ -3244,13 +3184,13 @@  write_local (outf_p output_header, type_
       {
 	options_p opt;
 
-	if (s->u.s.line.ifile == NULL)
+	if (s->u.s.styline.ifile == NULL)
 	  continue;
 
 	for (opt = s->u.s.opt; opt; opt = opt->next)
-	  if (strcmp (opt->name, "ptr_alias") == 0)
+	  if (strcmp (opt->name, "ptr_alias") == 0 && opt->kind == INFO_TYPE)
 	    {
-	      const_type_p const t = (const_type_p) opt->info;
+	      const_type_p const t = (const_type_p) opt->info.type;
 	      if (t->kind == TYPE_STRUCT
 		  || t->kind == TYPE_UNION
 		  || t->kind == TYPE_LANG_STRUCT)
@@ -3262,7 +3202,7 @@  write_local (outf_p output_header, type_
 		  oprintf (output_header, "\n");
 		}
 	      else
-		error_at_line (&s->u.s.line,
+		error_at_line (&s->u.s.styline,
 			       "structure alias is not a structure");
 	      break;
 	    }
@@ -3297,7 +3237,7 @@  write_local (outf_p output_header, type_
 	oprintf (output_header,
 	 "\n    (void *, void *, gt_pointer_operator, void *);\n");
 
-	if (stru->u.s.line.ifile == NULL)
+	if (stru->u.s.styline.ifile == NULL)
 	  {
 	    fprintf (stderr, "warning: structure `%s' used but not defined\n",
 		     s->u.s.tag);
@@ -3324,7 +3264,7 @@  write_local (outf_p output_header, type_
    || (UNION_OR_STRUCT_P (s) &&						\
        (((s)->gc_used == GC_POINTED_TO)					\
 	|| ((s)->gc_used == GC_MAYBE_POINTED_TO				\
-	    && s->u.s.line.ifile != NULL)				\
+	    && s->u.s.styline.ifile != NULL)				\
 	|| ((s)->gc_used == GC_USED					\
 	    && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))))))
 
@@ -3558,8 +3498,8 @@  write_root (outf_p f, pair_p v, type_p t
 	    for (o = fld->opt; o; o = o->next)
 	      if (strcmp (o->name, "skip") == 0)
 		skip_p = 1;
-	      else if (strcmp (o->name, "desc") == 0)
-		desc = o->info;
+	      else if (strcmp (o->name, "desc") == 0 && o->kind == INFO_STRING)
+		desc = o->info.string;
 	      else if (strcmp (o->name, "param_is") == 0)
 		;
 	      else
@@ -3580,8 +3520,8 @@  write_root (outf_p f, pair_p v, type_p t
 		    options_p oo;
 
 		    for (oo = ufld->opt; oo; oo = oo->next)
-		      if (strcmp (oo->name, "tag") == 0)
-			tag = oo->info;
+		      if (strcmp (oo->name, "tag") == 0 && oo->kind == INFO_STRING)
+			tag = oo->info.string;
 		    if (tag == NULL || strcmp (tag, desc) != 0)
 		      continue;
 		    if (validf != NULL)
@@ -3757,8 +3697,8 @@  write_roots (pair_p variables, bool emit
       options_p o;
 
       for (o = v->opt; o; o = o->next)
-	if (strcmp (o->name, "length") == 0)
-	  length = o->info;
+	if (strcmp (o->name, "length") == 0 && o->kind == INFO_STRING)
+	  length = o->info.string;
 	else if (strcmp (o->name, "deletable") == 0)
 	  deletable_p = 1;
 	else if (strcmp (o->name, "param_is") == 0)
@@ -3883,8 +3823,8 @@  write_roots (pair_p variables, bool emit
       for (o = v->opt; o; o = o->next)
 	if (strcmp (o->name, "length") == 0)
 	  length_p = 1;
-	else if (strcmp (o->name, "if_marked") == 0)
-	  if_marked = o->info;
+	else if (strcmp (o->name, "if_marked") == 0 && o->kind == INFO_STRING)
+	  if_marked = o->info.string;
 
       if (if_marked == NULL)
 	continue;
@@ -4020,7 +3960,7 @@  note_def_vec (const char *type_name, boo
   else
     {
       t = resolve_typedef (type_name, pos);
-      o = create_option (0, "length", "%h.num");
+      o = create_string_option (0, "length", "%h.num");
     }
 
   /* We assemble the field list in reverse order.  */
@@ -4311,7 +4251,21 @@  dump_options (int indent, options_p opt)
   o = opt;
   while (o)
     {
-       printf ("%s:%s ", o->name, o->info);
+      switch (o->kind) {
+      case INFO_STRING:
+	printf ("%s:string %s ", o->name, o->info.string);
+	break;
+      case INFO_TYPE:
+	printf ("%s:type ", o->name);
+	dump_type (indent+1, o->info.type);
+	break;
+      case INFO_NESTED:
+	printf ("%s:nested ", o->name);
+	break;
+      case INFO__NONE:
+	fatal ("corrupted option %p: %s", (void*) o, o->name);
+	break;
+      }
        o = o->next;
     }
   printf ("\n");
@@ -4338,7 +4292,7 @@  dump_type_u_s (int indent, type_p t)
   gcc_assert (t->kind == TYPE_STRUCT || t->kind == TYPE_UNION
 	      || t->kind == TYPE_LANG_STRUCT);
   printf ("%*cu.s.tag = %s\n", indent, ' ', t->u.s.tag);
-  dump_fileloc (indent, t->u.s.line);
+  dump_fileloc (indent, t->u.s.styline);
   printf ("%*cu.s.fields =\n", indent, ' ');
   fields = t->u.s.fields;
   while (fields)
@@ -4375,7 +4329,7 @@  dump_type_u_param_struct (int indent, ty
   gcc_assert (t->kind == TYPE_PARAM_STRUCT);
   printf ("%*cu.param_struct.stru:\n", indent, ' ');
   dump_type_list (indent, t->u.param_struct.stru);
-  dump_fileloc (indent, t->u.param_struct.line);
+  dump_fileloc (indent, t->u.param_struct.ptyline);
   for (i = 0; i < NUM_PARAM; i++)
     {
       if (t->u.param_struct.param[i] == NULL)
--- ../gengtype-gcc-04/gengtype.h	2010-08-29 11:13:49.000000000 +0200
+++ gcc/gengtype.h	2010-08-29 16:44:58.000000000 +0200
@@ -1,5 +1,6 @@ 
 /* Process source files and output type information.
-   Copyright (C) 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2007, 2008, 2010
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -109,12 +110,182 @@  struct fileloc {
   int line;
 };
 
-/* Data types handed around within, but opaque to, the lexer and parser.  */
+/* Common types.  */
 typedef struct pair *pair_p;
 typedef struct type *type_p;
 typedef const struct type *const_type_p;
 typedef struct options *options_p;
 
+
+/* Kinds of types we can understand.  */
+enum typekind {
+    TYPE__NONE=0,		/* Never used, so any zero-ed type is
+				   invalid. */
+    TYPE_SCALAR,
+    TYPE_STRING,
+    TYPE_STRUCT,
+    TYPE_UNION,
+    TYPE_POINTER,
+    TYPE_ARRAY,
+    TYPE_LANG_STRUCT,
+    TYPE_PARAM_STRUCT
+};
+
+/* Discriminating kind for options. */
+enum info_kind {
+    INFO__NONE=0,		/* Never used. */
+    INFO_STRING,
+    INFO_TYPE,
+    INFO_NESTED
+};
+
+/* A way to pass data through to the output end.  */
+struct options
+{
+    struct options *next;
+    const char *name;
+    enum info_kind kind;
+  /* the union below is discriminated by the 'kind' field above. */
+    union {
+	const char* string;
+	type_p type;
+	struct nested_ptr_data* nested;
+    } info;
+};
+
+
+
+/* Option data for the 'nested_ptr' option.  */
+struct nested_ptr_data
+{
+    type_p type;
+    const char *convert_to;
+    const char *convert_from;
+};
+
+/* A name and a type.  */
+struct pair
+{
+    pair_p next;
+    const char *name;
+    type_p type;
+    struct fileloc line;
+    options_p opt;
+};
+
+/* A description of a type.  */
+enum gc_used_enum
+{
+    GC_UNUSED=0, 		/* We need that zero-ed types are
+				   initially unused. */
+    GC_USED,
+    /* Used for structures whose definitions we haven't seen so far when
+       we encounter a pointer to it that is annotated with ``maybe_undef''.
+       If after reading in everything we don't have source file
+       information for it, we assume that it never has been defined. */
+    GC_MAYBE_POINTED_TO,
+    GC_POINTED_TO
+};
+
+
+
+#define NUM_PARAM 10
+
+/* Our type structure describes all types handled by gengtype. */
+struct type
+{
+  enum typekind kind;		/* Discriminating kind. */
+  int state_number;		/* State number used when writing &
+				   reading the persistent state. */
+  type_p next;
+  type_p pointer_to;
+  enum gc_used_enum gc_used;
+
+  /* The following union is discriminated by the 'kind' field above. */
+  union {
+    /* when TYPE_POINTER:  */
+    type_p p;
+
+    /* when TYPE_STRUCT or TYPE_UNION or TYPE_LANG_STRUCT: */		
+    struct {	
+      const char *tag;
+      struct fileloc styline;
+      pair_p fields;
+      options_p opt;
+      lang_bitmap bitmap;
+      type_p lang_struct;
+    } s;
+
+    /* when TYPE_SCALAR: */
+    bool scalar_is_char;
+
+    /* when TYPE_ARRAY: */
+    struct {
+      type_p p;
+      const char *len;
+    } a;
+
+    /* when TYPE_PARAM_STRUCT: */
+    struct {
+      type_p stru;
+      type_p param[NUM_PARAM];
+      struct fileloc ptyline;
+    } param_struct;
+
+  } u;
+};
+
+/* The one and only TYPE_STRING.  */
+extern struct type string_type;
+
+/* The two and only TYPE_SCALARs.  Their u.scalar_is_char flags are
+   set appropriately.  */
+extern struct type scalar_non_char;
+extern struct type scalar_char;
+
+
+static inline struct fileloc*
+type_lineloc (const_type_p ty)
+{
+    if (!ty) return NULL;
+    switch (ty->kind) {
+    case TYPE__NONE: 
+	fatal("type_lineloc on bad none ty %p", (const void*)ty);
+	break;
+    case TYPE_STRUCT:
+    case TYPE_UNION:
+    case TYPE_LANG_STRUCT:
+	return CONST_CAST (struct fileloc*, &ty->u.s.styline);
+    case TYPE_PARAM_STRUCT:
+	return CONST_CAST (struct fileloc*, &ty->u.param_struct.ptyline);
+    case TYPE_SCALAR:
+    case TYPE_STRING:
+    case TYPE_POINTER:
+    case TYPE_ARRAY:
+	return NULL;
+    }
+    fatal("type_lineloc on corrupted type %p kd#%d", (const void*)ty, (int) ty->kind);
+    return NULL;
+}
+
+static inline input_file*
+type_ifile (const_type_p ty)
+{
+    struct fileloc* l = type_lineloc (ty);
+    if (l) return l->ifile;
+    return NULL;
+}
+
+#define UNION_P(x)					\
+    ((x)->kind == TYPE_UNION ||				\
+     ((x)->kind == TYPE_LANG_STRUCT 			\
+      && (x)->u.s.lang_struct->kind == TYPE_UNION))
+#define UNION_OR_STRUCT_P(x)			\
+    ((x)->kind == TYPE_UNION 			\
+     || (x)->kind == TYPE_STRUCT		\
+     || (x)->kind == TYPE_LANG_STRUCT)
+
+
 /* Variables used to communicate between the lexer and the parser.  */
 extern int lexer_toplevel_done;
 extern struct fileloc lexer_line;
@@ -128,7 +299,7 @@  struct outf
     size_t bufused;
     char *buf;
 };
-typedef struct outf * outf_p;
+typedef struct outf* outf_p;
 
 /* The list of output files.  */
 extern outf_p output_files;
@@ -178,7 +349,10 @@  extern type_p find_structure (const char
 extern type_p create_scalar_type (const char *name);
 extern type_p create_pointer (type_p t);
 extern type_p create_array (type_p t, const char *len);
-extern options_p create_option (options_p, const char *name, const void *info);
+extern options_p create_string_option (options_p next, const char* name, const char* info);
+extern options_p create_type_option (options_p next, const char* name, type_p info);
+extern options_p create_nested_option (options_p next, const char* name, 
+				       struct nested_ptr_data* info);
 extern options_p create_nested_ptr_option (options_p, type_p t,
 					   const char *from, const char *to);
 extern pair_p create_field_at (pair_p next, type_p type, const char *name,
--- ../gengtype-gcc-04/gengtype-parse.c	2010-08-29 11:13:38.000000000 +0200
+++ gcc/gengtype-parse.c	2010-08-29 18:29:48.000000000 +0200
@@ -343,7 +343,7 @@  str_optvalue_opt (options_p prev)
       value = string_seq ();
       require (')');
     }
-  return create_option (prev, name, value);
+  return create_string_option (prev, name, value);
 }
 
 /* absdecl: type '*'*
@@ -381,7 +381,7 @@  type_optvalue (options_p prev, const cha
   require ('(');
   ty = absdecl ();
   require (')');
-  return create_option (prev, name, ty);
+  return create_type_option (prev, name, ty);
 }
 
 /* Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' */
@@ -431,7 +431,7 @@  option (options_p prev)
       parse_error ("expected an option keyword, have %s",
 		   print_cur_token ());
       advance ();
-      return create_option (prev, "", "");
+      return create_string_option (prev, "", "");
     }
 }