--- ../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, "", "");
     }
 }
 
