From patchwork Sun Aug 29 17:12:20 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Basile Starynkevitch X-Patchwork-Id: 62947 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 438C9B70D6 for ; Mon, 30 Aug 2010 03:12:46 +1000 (EST) Received: (qmail 8232 invoked by alias); 29 Aug 2010 17:12:44 -0000 Received: (qmail 8218 invoked by uid 22791); 29 Aug 2010 17:12:40 -0000 X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL, BAYES_50, MIME_BASE64_BLANKS, RCVD_IN_DNSWL_NONE, TW_WT X-Spam-Check-By: sourceware.org Received: from smtp-100-sunday.noc.nerim.net (HELO mallaury.nerim.net) (62.4.17.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 29 Aug 2010 17:12:32 +0000 Received: from hector.lesours (ours.starynkevitch.net [213.41.244.95]) by mallaury.nerim.net (Postfix) with ESMTP id 3BB42A1057; Sun, 29 Aug 2010 19:12:26 +0200 (CEST) Received: from glinka.lesours ([192.168.0.1]) by hector.lesours with esmtp (Exim 4.72) (envelope-from ) id 1OplQg-0001qL-0o; Sun, 29 Aug 2010 19:12:26 +0200 Subject: Re: gengtype improvements for plugins. patch 5/N [typedopt] From: Basile Starynkevitch Reply-To: basile@starynkevitch.net To: jeremie.salvucci@free.fr Cc: gcc-patches@gcc.gnu.org In-Reply-To: <1283081687.3067.86.camel@glinka> References: <1283012591.3067.17.camel@glinka> <20100828170603.GA1108@gmx.de> <1283016347.3067.43.camel@glinka> <1283062592.3067.50.camel@glinka> <1283063995.3067.63.camel@glinka> <1283077287.3067.78.camel@glinka> <1283077418.3067.79.camel@glinka> <1283081687.3067.86.camel@glinka> Date: Sun, 29 Aug 2010 19:12:20 +0200 Message-ID: <1283101940.3067.103.camel@glinka> Mime-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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. --- ../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, "", ""); } }