]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gengtype.c (enum typekind, [...]): Move to gengtype.h.
authorBasile Starynkevitch <basile@starynkevitch.net>
Tue, 23 Nov 2010 15:13:12 +0000 (15:13 +0000)
committerBasile Starynkevitch <bstarynk@gcc.gnu.org>
Tue, 23 Nov 2010 15:13:12 +0000 (15:13 +0000)
2010-11-23  Basile Starynkevitch  <basile@starynkevitch.net>
    Jeremie Salvucci  <jeremie.salvucci@free.fr>

* gengtype.c (enum typekind, struct options)
(struct nested_ptr_data, struct pair, NUM_PARAM)
(enum gc_used_num, struct type, UNION_P, UNION_OR_STRUCT_P):
Move to gengtype.h.
(string_type, scalar_nonchar, scalar_nonchar, scalar_char):
Remove static, add zero state_number.
(typedefs, structures, param_structs, variables): Remove static.
(create_option): Remove.
(create_string_option, create_type_option, create_nested_option):
New functions.
(create_nested_ptr_option): Use create_nested_option.
(note_variable, adjust_field_rtx_def, adjust_field_type): Call the
new create*option functions.
(process_gc_options): Adjust for discriminated option.
(output_mangled_typename): Handle TYPE_NONE.
(walk_type): Test option kinds.
(write_types_process_field): Handle TYPE_NONE and TYPE_ARRAY.
(write_func_for_structure, write_type, write_local, write_root)
(write_roots, note_def_vec, dump_options): Adjust for
discriminated option.

* gengtype.h
(typedefs, structures, param_structs, variables, enum typekind):
Move from gengtype.c
(enum option_kind): New discriminating enumeration.
(struct options): Becomes discriminated.
(struct nested_ptr_data): Nove from gengtype.c
(create_string_option, create_type_option, create_nested_option)
(create_nested_ptr_option): New functions
(struct pair, enum_gc_used_enum, NUM_PARAM, struct type, UNION_P)
(UNION_OR_STRUCT_P): Move from gengtype.c

* gengtype-parse.c (str_optvalue_opt, type_optvalue, option): Make
discriminated options.

Co-Authored-By: Jeremie Salvucci <jeremie.salvucci@free.fr>
From-SVN: r167080

gcc/ChangeLog
gcc/gengtype-parse.c
gcc/gengtype.c
gcc/gengtype.h

index 60c4dc92de390d33234d0e55d9993c044cb35635..09053c37400299611b093bfd38b89578b199d9a8 100644 (file)
@@ -1,3 +1,41 @@
+2010-11-23  Basile Starynkevitch  <basile@starynkevitch.net>
+           Jeremie Salvucci  <jeremie.salvucci@free.fr>
+
+       * gengtype.c (enum typekind, struct options)
+       (struct nested_ptr_data, struct pair, NUM_PARAM)
+       (enum gc_used_num, struct type, UNION_P, UNION_OR_STRUCT_P):
+       Move to gengtype.h.
+       (string_type, scalar_nonchar, scalar_nonchar, scalar_char):
+       Remove static, add zero state_number.
+       (typedefs, structures, param_structs, variables): Remove static.
+       (create_option): Remove.
+       (create_string_option, create_type_option, create_nested_option):
+       New functions.
+       (create_nested_ptr_option): Use create_nested_option.
+       (note_variable, adjust_field_rtx_def, adjust_field_type): Call the
+       new create*option functions.
+       (process_gc_options): Adjust for discriminated option.
+       (output_mangled_typename): Handle TYPE_NONE.
+       (walk_type): Test option kinds.
+       (write_types_process_field): Handle TYPE_NONE and TYPE_ARRAY.
+       (write_func_for_structure, write_type, write_local, write_root)
+       (write_roots, note_def_vec, dump_options): Adjust for
+       discriminated option.
+
+       * gengtype.h
+       (typedefs, structures, param_structs, variables, enum typekind):
+       Move from gengtype.c
+       (enum option_kind): New discriminating enumeration.
+       (struct options): Becomes discriminated.
+       (struct nested_ptr_data): Nove from gengtype.c
+       (create_string_option, create_type_option, create_nested_option)
+       (create_nested_ptr_option): New functions
+       (struct pair, enum_gc_used_enum, NUM_PARAM, struct type, UNION_P)
+       (UNION_OR_STRUCT_P): Move from gengtype.c
+
+       * gengtype-parse.c (str_optvalue_opt, type_optvalue, option): Make
+       discriminated options.
+
 2010-11-23  Richard Guenther  <rguenther@suse.de>
 
        * tree-ssa-sccvn.c (vn_reference_lookup_3): Avoid doing work
index 476a9fd203c6227188e81158a2c47f189854df32..8f0b0c532334183912b6e64388263c0ce6ed704a 100644 (file)
@@ -372,7 +372,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 '*'*
@@ -410,7 +410,7 @@ type_optvalue (options_p prev, const char *name)
   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 ')' */
@@ -459,7 +459,7 @@ option (options_p prev)
     default:
       parse_error ("expected an option keyword, have %s", print_cur_token ());
       advance ();
-      return create_option (prev, "", "");
+      return create_string_option (prev, "", "");
     }
 }
 
index 7f7feb0d9870687c76b2c964d17b889cbb0b12b9..8d13d0eb1d177bf93b01efa6bb3cc87280439cd9 100644 (file)
 
 /* 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)
-
-
-
-
 
 /* The list of output files.  */
 outf_p output_files;
@@ -554,27 +454,27 @@ 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.  */
+   set early in 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.  */
 
-static pair_p typedefs;
-static type_p structures;
-static type_p param_structs;
-static pair_p variables;
+pair_p typedefs;
+type_p structures;
+type_p param_structs;
+pair_p variables;
 
 static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
 static type_p adjust_field_tree_exp (type_p t, options_p opt);
@@ -800,16 +700,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.  */
+/* Return a string options structure 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 = XNEW (struct options);
+  o->kind = OPTION_STRING;
+  o->next = next;
+  o->name = name;
+  o->info.string = info;
+  return o;
+}
 
+/* Create a type options structure with name NAME and info INFO.  NEXT
+   is the next option in the chain.  */
 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);
   o->next = next;
   o->name = name;
-  o->info = (const char *) info;
+  o->kind = OPTION_TYPE;
+  o->info.type = info;
+  return o;
+}
+
+/* Create a nested pointer options structure with name NAME and info
+   INFO.  NEXT is the next option in the chain.  */
+options_p
+create_nested_option (options_p next, const char* name,
+                      struct nested_ptr_data* info)
+{
+  options_p o;
+  o = XNEW (struct options);
+  o->next = next;
+  o->name = name;
+  o->kind = OPTION_NESTED;
+  o->info.nested = info;
   return o;
 }
 
@@ -823,12 +751,11 @@ create_nested_ptr_option (options_p next, type_p t,
   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,
    to `variables'.  */
-
 void
 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
 {
@@ -890,15 +817,19 @@ create_optional_field_ (pair_p next, type_p type, const char *name,
      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_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
-                             &lexer_line, union_fields, NULL);
+  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), this_file, line);
+                          create_string_option (0, "desc", cond), 
+                          this_file, line);
 }
 
 #define create_optional_field(next,type,name,cond)     \
@@ -1031,14 +962,16 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
       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));
   tree_tp = create_pointer (find_structure ("tree_node", 1));
   mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
-  reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
-  basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
+  reg_attrs_tp = 
+    create_pointer (find_structure ("reg_attrs", 0));
+  basic_block_tp = 
+    create_pointer (find_structure ("basic_block_def", 0));
   constant_tp =
     create_pointer (find_structure ("constant_descriptor_rtx", 0));
   scalar_tp = &scalar_nonchar; /* rtunion int */
@@ -1072,9 +1005,11 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
        /* 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);
@@ -1082,13 +1017,10 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
   /* Create a type to represent the various forms of SYMBOL_REF_DATA.  */
   {
     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);
   }
@@ -1152,9 +1084,10 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
                t = scalar_tp, subname = "rt_int";
              else
                {
-                 error_at_line (&lexer_line,
-                                "rtx type `%s' has `0' in position %lu, can't handle",
-                                rtx_name[i], (unsigned long) aindex);
+                 error_at_line 
+                   (&lexer_line,
+                    "rtx type `%s' has `0' in position %lu, can't handle",
+                    rtx_name[i], (unsigned long) aindex);
                  t = &string_type;
                  subname = "rt_int";
                }
@@ -1190,10 +1123,11 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
              break;
 
            default:
-             error_at_line (&lexer_line,
-                            "rtx type `%s' has `%c' in position %lu, can't handle",
-                            rtx_name[i], rtx_format[i][aindex],
-                            (unsigned long) aindex);
+             error_at_line
+               (&lexer_line,
+                "rtx type `%s' has `%c' in position %lu, can't handle",
+                rtx_name[i], rtx_format[i][aindex],
+                (unsigned long) aindex);
              t = &string_type;
              subname = "rt_int";
              break;
@@ -1205,16 +1139,19 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
                                               subname));
          subfields->opt = nodot;
          if (t == note_union_tp)
-           subfields->opt = create_option (subfields->opt, "desc",
-                                           "NOTE_KIND (&%0)");
+           subfields->opt =
+             create_string_option (subfields->opt, "desc",
+                                   "NOTE_KIND (&%0)");
          if (t == symbol_union_tp)
-           subfields->opt = create_option (subfields->opt, "desc",
-                                           "CONSTANT_POOL_ADDRESS_P (&%0)");
+           subfields->opt = 
+             create_string_option (subfields->opt, "desc",
+                                   "CONSTANT_POOL_ADDRESS_P (&%0)");
        }
 
       if (i == SYMBOL_REF)
        {
-         /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds.  */
+         /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P
+            holds.  */
          type_p field_tp = find_structure ("block_symbol", 0);
          subfields
            = create_optional_field (subfields, field_tp, "block_sym",
@@ -1227,11 +1164,9 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
       ftag = xstrdup (rtx_name[i]);
       for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
        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);
 }
 
@@ -1254,12 +1189,12 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
       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",
-                            "TREE_OPERAND_LENGTH ((tree) &%0)");
-  flds->opt = create_option (flds->opt, "default", "");
+  flds->opt = create_string_option (nodot, "length",
+                                   "TREE_OPERAND_LENGTH ((tree) &%0)");
+  flds->opt = create_string_option (flds->opt, "default", "");
 
   return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
 }
@@ -1289,10 +1224,11 @@ adjust_field_type (type_p t, options_p opt)
   for (; opt; opt = opt->next)
     if (strcmp (opt->name, "length") == 0)
       length_p = 1;
-    else if (strcmp (opt->name, "param_is") == 0
-            || (strncmp (opt->name, "param", 5) == 0
-                && ISDIGIT (opt->name[5])
-                && strcmp (opt->name + 6, "_is") == 0))
+    else if ((strcmp (opt->name, "param_is") == 0
+             || (strncmp (opt->name, "param", 5) == 0
+                 && ISDIGIT (opt->name[5])
+                 && strcmp (opt->name + 6, "_is") == 0))
+            && opt->kind == OPTION_TYPE)
       {
        int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
 
@@ -1309,14 +1245,14 @@ adjust_field_type (type_p t, options_p opt)
        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)
+    else if (strcmp (opt->name, "special") == 0
+            && opt->kind == OPTION_STRING)
       {
-       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)
@@ -1359,8 +1295,9 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
 {
   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 == OPTION_TYPE)
+      set_gc_used_type (o->info.type,
                        GC_POINTED_TO, NULL);
     else if (strcmp (o->name, "maybe_undef") == 0)
       *maybe_undef = 1;
@@ -1370,12 +1307,13 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
       *length = 1;
     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;
+    else if (strcmp (o->name, "nested_ptr") == 0
+            && o->kind == OPTION_NESTED)
+      *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.  */
 
+/* Set the gc_used field of T to LEVEL, and handle the types it references.  */
 static void
 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
 {
@@ -2318,6 +2256,9 @@ output_mangled_typename (outf_p of, const_type_p t)
   else
     switch (t->kind)
       {
+      case TYPE_NONE:
+       gcc_unreachable ();
+       break;
       case TYPE_POINTER:
        oprintf (of, "P");
        output_mangled_typename (of, t->u.p);
@@ -2413,8 +2354,8 @@ walk_type (type_p t, struct walk_type_data *d)
 
   d->needs_cast_p = false;
   for (oo = d->opt; oo; oo = oo->next)
-    if (strcmp (oo->name, "length") == 0)
-      length = oo->info;
+    if (strcmp (oo->name, "length") == 0 && oo->kind == OPTION_STRING)
+      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
@@ -2422,12 +2363,13 @@ walk_type (type_p t, struct walk_type_data *d)
       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 == OPTION_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 == OPTION_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)
@@ -2675,8 +2617,9 @@ walk_type (type_p t, struct walk_type_data *d)
 
        /* 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 == OPTION_STRING)
+           desc = o->info.string;
 
        d->prev_val[2] = oldval;
        d->prev_val[1] = oldprevval2;
@@ -2707,16 +2650,19 @@ walk_type (type_p t, struct walk_type_data *d)
 
            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 == OPTION_STRING)
+               dot = oo->info.string;
+             else if (strcmp (oo->name, "tag") == 0
+                      && oo->kind == OPTION_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 == OPTION_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;
@@ -2830,6 +2776,8 @@ write_types_process_field (type_p f, const struct walk_type_data *d)
 
   switch (f->kind)
     {
+    case TYPE_NONE:
+      gcc_unreachable ();
     case TYPE_POINTER:
       oprintf (d->of, "%*s%s (%s%s", d->indent, "",
               wtd->subfield_marker_routine, cast, d->val);
@@ -2882,7 +2830,7 @@ write_types_process_field (type_p f, const struct walk_type_data *d)
     case TYPE_SCALAR:
       break;
 
-    default:
+    case TYPE_ARRAY:
       gcc_unreachable ();
     }
 }
@@ -2950,17 +2898,19 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
 
   memset (&d, 0, sizeof (d));
   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 == OPTION_STRING)
+      chain_next = opt->info.string;
+    else if (strcmp (opt->name, "chain_prev") == 0
+            && opt->kind == OPTION_STRING)
+      chain_prev = opt->info.string;
+    else if (strcmp (opt->name, "chain_circular") == 0
+            && opt->kind == OPTION_STRING)
+      chain_circular = opt->info.string;
+    else if (strcmp (opt->name, "mark_hook") == 0
+            && opt->kind == OPTION_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");
   if (chain_circular != NULL && chain_next != NULL)
@@ -3127,9 +3077,10 @@ write_types (outf_p output_header, type_p structures, type_p param_structs,
        oprintf (output_header, "  } 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 == OPTION_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)
                oprintf (output_header,
@@ -3352,11 +3303,11 @@ write_local (outf_p output_header, type_p structures, type_p param_structs)
 
        if (s->u.s.line.file == NULL)
          continue;
-
-       for (opt = s->u.s.opt; opt; opt = opt->next)
-         if (strcmp (opt->name, "ptr_alias") == 0)
+       for (opt = s->u.s.opt; opt; opt = opt->next)
+         if (strcmp (opt->name, "ptr_alias") == 0
+             && opt->kind == OPTION_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)
                {
@@ -3679,8 +3630,9 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
            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 == OPTION_STRING)
+               desc = o->info.string;
              else if (strcmp (o->name, "param_is") == 0)
                ;
              else
@@ -3699,10 +3651,10 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
                  {
                    const char *tag = NULL;
                    options_p oo;
-
-                   for (oo = ufld->opt; oo; oo = oo->next)
-                     if (strcmp (oo->name, "tag") == 0)
-                       tag = oo->info;
+                   for (oo = ufld->opt; oo; oo = oo->next)
+                     if (strcmp (oo->name, "tag") == 0
+                         && oo->kind == OPTION_STRING)
+                       tag = oo->info.string;
                    if (tag == NULL || strcmp (tag, desc) != 0)
                      continue;
                    if (validf != NULL)
@@ -3873,10 +3825,10 @@ write_roots (pair_p variables, bool emit_pch)
       const char *length = NULL;
       int deletable_p = 0;
       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 == OPTION_STRING)
+         length = o->info.string;
        else if (strcmp (o->name, "deletable") == 0)
          deletable_p = 1;
        else if (strcmp (o->name, "param_is") == 0)
@@ -4003,12 +3955,11 @@ write_roots (pair_p variables, bool emit_pch)
       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;
-
-      if (if_marked == NULL)
+       else if (strcmp (o->name, "if_marked") == 0
+                      && o->kind == OPTION_STRING)
+         if_marked = o->info.string;
+       if (if_marked == NULL)
        continue;
-
       if (v->type->kind != TYPE_POINTER
          || v->type->u.p->kind != TYPE_PARAM_STRUCT
          || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
@@ -4143,9 +4094,8 @@ note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
   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.  */
   fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
   fields = create_field_at (fields, len_ty, "alloc", 0, pos);
@@ -4463,7 +4413,21 @@ dump_options (int indent, options_p opt)
   o = opt;
   while (o)
     {
-      printf ("%s:%s ", o->name, o->info);
+      switch (o->kind)
+       {
+       case OPTION_STRING:
+         printf ("%s:string %s ", o->name, o->info.string);
+         break;
+       case OPTION_TYPE:
+         printf ("%s:type ", o->name);
+         dump_type (indent+1, o->info.type);
+         break;
+       case OPTION_NESTED:
+         printf ("%s:nested ", o->name);
+         break;
+       case OPTION_NONE:
+         gcc_unreachable ();
+       }
       o = o->next;
     }
   printf ("\n");
index 77f121e6c580e51ea8245fcfe7d3fda8d58218ac..2046e40d6e976d798022259903729ff6483f3bd9 100644 (file)
@@ -116,6 +116,218 @@ typedef struct options *options_p;
 extern int lexer_toplevel_done;
 extern struct fileloc lexer_line;
 
+/* Various things, organized as linked lists, needed both in
+   gengtype.c & in gengtype-state.c files.  */
+extern pair_p typedefs;
+extern type_p structures;
+extern type_p param_structs;
+extern pair_p variables;
+
+
+
+/* Discrimating kind of types we can understand.  */
+
+enum typekind {
+  TYPE_NONE=0,          /* Never used, so zeroed memory is invalid.  */
+  TYPE_SCALAR,          /* Scalar types like char.  */
+  TYPE_STRING,          /* The string type.  */
+  TYPE_STRUCT,          /* Type for GTY-ed structs.  */
+  TYPE_UNION,           /* Type for GTY-ed discriminated unions.  */
+  TYPE_POINTER,         /* Pointer type to GTY-ed type.  */
+  TYPE_ARRAY,           /* Array of GTY-ed types.  */
+  TYPE_LANG_STRUCT,     /* GCC front-end language specific structs.
+                           Various languages may have homonymous but
+                           different structs.  */
+  TYPE_PARAM_STRUCT     /* Type for parametrized structs, e.g. hash_t
+                           hash-tables, ...  See (param_is, use_param,
+                           param1_is, param2_is,... use_param1,
+                           use_param_2,... use_params) GTY
+                           options.  */
+};
+
+/* Discriminating kind for options.  */
+enum option_kind {
+  OPTION_NONE=0,        /* Never used, so zeroed memory is invalid.  */
+  OPTION_STRING,        /* A string-valued option.  Most options are
+                           strings.  */
+  OPTION_TYPE,          /* A type-valued option.  */
+  OPTION_NESTED         /* Option data for 'nested_ptr'.  */
+};
+
+
+/* A way to pass data through to the output end.  */
+struct options {
+  struct options *next;         /* next option of the same pair.  */
+  const char *name;             /* GTY option name.  */
+  enum option_kind kind;        /* discriminating option kind.  */
+  union {
+    const char* string;                    /* When OPTION_STRING.  */
+    type_p type;                           /* When OPTION_TYPE.  */
+    struct nested_ptr_data* nested;        /* when OPTION_NESTED.  */
+  } info;
+};
+
+
+/* Option data for the 'nested_ptr' option.  */
+struct nested_ptr_data {
+  type_p type;
+  const char *convert_to;
+  const char *convert_from;
+};
+
+/* Some functions to create various options structures with name NAME
+   and info INFO.  NEXT is the next option in the chain.  */
+
+/* Create a string option.  */
+options_p create_string_option (options_p next, const char* name,
+                                const char* info);
+
+/* Create a type option.  */
+options_p create_type_option (options_p next, const char* name,
+                              type_p info);
+
+/* Create a nested option.  */
+options_p create_nested_option (options_p next, const char* name,
+                               struct nested_ptr_data* info);
+
+/* Create a nested pointer option.  */
+options_p create_nested_ptr_option (options_p, type_p t,
+                                    const char *from, const char *to);
+
+/* A name and a type.  */
+struct pair {
+  pair_p next;                  /* The next pair in the linked list.  */
+  const char *name;             /* The defined name.  */
+  type_p type;                  /* Its GTY-ed type.  */
+  struct fileloc line;          /* The file location.  */
+  options_p opt;                /* GTY options, as a linked list.  */
+};
+
+/* Usage information for GTY-ed types.  Gengtype has to care only of
+   used GTY-ed types.  Types are initially unused, and their usage is
+   computed by set_gc_used_type and set_gc_used functions.  */
+
+enum gc_used_enum {
+
+  /* We need that zeroed types are initially unused.  */
+  GC_UNUSED=0,
+
+  /* The GTY-ed type is used, e.g by a GTY-ed variable or a field
+     inside a GTY-ed used type.  */
+  GC_USED,
+
+  /* For GTY-ed 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,
+
+  /* For known GTY-ed structures which are pointed to by GTY-ed
+     variables or fields.  */
+  GC_POINTED_TO
+};
+
+/* We can have at most ten type parameters in parameterized structures.  */
+#define NUM_PARAM 10
+
+/* Our type structure describes all types handled by gengtype.  */
+struct type {
+  /* Discriminating kind, cannot be TYPE_NONE.  */
+  enum typekind kind;
+
+  /* For top-level structs or unions, the 'next' field links the
+     global list 'structures' or 'param_structs'; for lang_structs,
+     their homonymous structs are linked using this 'next' field.  The
+     homonymous list starts at the s.lang_struct field of the
+     lang_struct.  See the new_structure function for details.  This is
+     tricky!  */
+  type_p next;
+
+  /* State number used when writing & reading the persistent state.  A
+     type with a positive number has already been written.  For ease
+     of debugging, newly allocated types have a unique negative
+     number.  */
+  int state_number;
+
+  /* Each GTY-ed type which is pointed to by some GTY-ed type knows
+     the GTY pointer type pointing to it.  See create_pointer
+     function.  */
+  type_p pointer_to;
+
+  /* Type usage information, computed by set_gc_used_type and
+     set_gc_used functions.  */
+  enum gc_used_enum gc_used;
+
+  /* The following union is discriminated by the 'kind' field above.  */
+  union {
+    /* TYPE__NONE is impossible.  */
+
+    /* when TYPE_POINTER:  */
+    type_p p;
+
+    /* when TYPE_STRUCT or TYPE_UNION or TYPE_LANG_STRUCT, we have an
+       aggregate type containing fields: */
+    struct {
+      const char *tag;          /* the aggragate tag, if any.  */
+      struct fileloc line;      /* the source location.  */
+      pair_p fields;            /* the linked list of fields.  */
+      options_p opt;            /* the GTY options if any.  */
+      lang_bitmap bitmap;       /* the set of front-end languages
+                                   using that GTY-ed aggregate.  */
+      /* For TYPE_LANG_STRUCT, the lang_struct field gives the first
+         element of a linked list of homonymous struct or union types.
+         Within this list, each homonymous type has as its lang_struct
+         field the original TYPE_LANG_STRUCT type.  This is a dirty
+         trick, see the new_structure function for details.  */
+      type_p lang_struct;
+    } s;
+
+    /* when TYPE_SCALAR: */
+    bool scalar_is_char;
+
+    /* when TYPE_ARRAY: */
+    struct {
+      type_p p;                 /* The array component type.  */
+      const char *len;          /* The string if any giving its length.  */
+    } a;
+
+    /* When TYPE_PARAM_STRUCT for (param_is, use_param, param1_is,
+       param2_is, ... use_param1, use_param_2, ... use_params) GTY
+       options.  */
+    struct {
+      type_p stru;              /* The generic GTY-ed type.  */
+      type_p param[NUM_PARAM];  /* The actual parameter types.  */
+      struct fileloc line;      /* The source location.  */
+    } 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 early in main.  */
+extern struct type scalar_nonchar;
+extern struct type scalar_char;
+
+/* Test if a type is a union, either a plain one or a language
+   specific one.  */
+#define UNION_P(x)                                      \
+    ((x)->kind == TYPE_UNION ||                         \
+     ((x)->kind == TYPE_LANG_STRUCT                     \
+      && (x)->u.s.lang_struct->kind == TYPE_UNION))
+
+/* Test if a type is a union or a structure, perhaps a language
+   specific one.  */
+#define UNION_OR_STRUCT_P(x)                   \
+    ((x)->kind == TYPE_UNION                   \
+     || (x)->kind == TYPE_STRUCT               \
+     || (x)->kind == TYPE_LANG_STRUCT)
+
+
+
 /* Structure representing an output file.  */
 struct outf
 {
@@ -180,11 +392,6 @@ extern type_p find_structure (const char *s, int isunion);
 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_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, options_p opt,
                               struct fileloc *pos);