This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello All, [join work by Basile Starynkevitch & Jeremie Salvucci] References: http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02060.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00616.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00663.html http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02063.html http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02065.html http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02068.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00983.html This fifth patch chunk is an improved version of http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02068.html taking into account Laurynas comments in http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00420.html The major improvment of this "completed!" chunk w.r.t. its previous version http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02068.html is mostly that I did add a lot of comments while moving definitions from old gengtype.c to new gengtype.h; while adding comments slightly increase the burden of reviewers, it should not change the behavior of gengtype, and it should hopefully help a lot any future gengtype hacker. I hope that adding comments don't decrease the probability of having this work accepted into GCC 4.6 end of stage 1. In addition to the improved comments, I made some minor cleanups w.r.t. http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02068.html (such as using OPTION_STRING instead of INFO_STRING for the kind of a string option, etc.). I also changed the indentation: old gengtype.c had severals struct FOOBAR { while it seems that the preferred indentation style (at least when looking into gimple.h or tree.h) is instead struct FOOBAR { which I suppose is the politically correct way of GCC coding. In addition of moving lots of typing definitions from gengtype.c to gengtype.h I also (and this is already the case in the previous version http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02068.html of this patch), and obviously, made the 'struct options' a typed & discriminated data, because to persist the gengtype state every union should be a sum type discriminated conveniently. The attached patch relative to the "completed!" patch 4/N [filesrules] sent in http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00983.html is obtained with diff -u -p $(svn stat . |awk '/M/{print $2}') \ --from-file ../gengtype-gcc-04-filesrules/ > \ $HOME/tmp/gengtype_patch_5_of_N__typedopt-relto04.diff In am also attaching for convenience the cumulated patches against trunk 163987 as a gzip file gengtype_patch_5_of_N__typedopt-cumulatedto04-trunkrev-163987.diff.gz ######## gcc/ChangeLog entry relative to patch 4/N completed! [filesrules] 2010-09-11 Jeremie Salvucci <jeremie.salvucci@free.fr> Basile Starynkevitch <basile@starynkevitch.net> * gengtype.c (enum typekind, struct options, struct nested_ptr_data) (struct pair, NUM_PARAM, enum gc_used_enum, struct type, UNION_P) (UNION_OR_STRUCT_P): Moved into gengtype.h (string_type, scalar_nonchar, scalar_char): Removed static and added state_number fake value. (typedefs, structures, param_structs, variables): Removed static. (create_option): Removed function. (create_string_option, create_type_option, created_nested_option): New. (created_nested_ptr_option, create_optional_field_) (adjust_field_rtx_def, adjust_field_tree_exp): Updated accordingly. (adjust_field_type, process_gc_options, output_mangled_typename) (walk_type, write_func_for_structure, write_types, write_roots) (note_def_vec, dump_options): Ditto. Access to options is protected by tests on their kind. * gengtype.h: Added a lot of comments. Moved many definitions from gengtype.h and updated them. (typedef, structures, param_structs, variables): Declared extern. (enum typekind): Moved from gengtype.c and added TYPE_NONE. (enum option_kind): New. (struct options): Added discriminating kind, and info union. (struct nested_ptr_data): Moved from gengtype.c. (create_string_option, create_type_option, create_nested_option): New. (struct pair, enum_gc_used_enum, NUM_PARAM): Moved from gengtype.c and commented more. (struct_type): Ditto, added state_number. (string_type, scalar_nonchar, scalar_char): Moved from gengtype.c. (type_lineloc): New function. (UNION_P, UNION_OR_STRUCT_P): Moved from gengtype.c and commented more. (struct outf): Indented better. * gengtype-parse.c (str_optvalue_opt, type_optvalue, option): Updated for our discriminated option. ################################################################ Comments and/or Ok for trunk are welcome! Cheers. -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mines, sont seulement les miennes} ***
Attachment:
gengtype_patch_5_of_N__typedopt-cumulatedto04-trunkrev-163987.diff.gz
Description: Binary data
--- ../gengtype-gcc-04-filesrules//gengtype.c 2010-09-10 21:45:35.000000000 +0200 +++ gcc/gengtype.c 2010-09-11 15:18:06.000000000 +0200 @@ -31,99 +31,6 @@ /* 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) - - @@ -550,26 +457,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. */ -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]); @@ -811,19 +719,48 @@ 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_option (options_p next, const char *name, const void *info) +create_string_option (options_p next, const char* name, const char* 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 = OPTION_STRING; + o->info.string = info; return o; } + +options_p +create_type_option (options_p next, const char* name, type_p info) +{ + options_p o; + o = XCNEW (struct options); + o->next = next; + o->name = name; + o->kind = OPTION_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 = OPTION_NESTED; + o->info.nested = info; + return o; +} + + /* Return an options structure for a "nested_ptr" option. */ options_p create_nested_ptr_option (options_p next, type_p t, @@ -834,7 +771,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, @@ -901,15 +838,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), this_file, line); } #define create_optional_field(next,type,name,cond) \ @@ -1041,7 +978,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)); @@ -1081,9 +1018,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); @@ -1093,10 +1030,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); @@ -1215,10 +1152,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)"); } @@ -1239,7 +1176,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); @@ -1264,12 +1201,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); } @@ -1299,10 +1236,11 @@ adjust_field_type (type_p t, options_p o for (; opt; opt = opt->next) if (strcmp (opt->name, "length") == 0) length_p = 1; - else if (strcmp (opt->name, "param_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; @@ -1319,13 +1257,14 @@ 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) + 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) @@ -1369,8 +1308,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 == OPTION_TYPE) + set_gc_used_type (o->info.type, GC_POINTED_TO, NULL); else if (strcmp (o->name, "maybe_undef") == 0) *maybe_undef = 1; @@ -1380,8 +1320,9 @@ process_gc_options (options_p opt, enum *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. */ @@ -2316,6 +2257,8 @@ output_mangled_typename (outf_p of, cons oprintf (of, "Z"); else switch (t->kind) { + case TYPE_NONE: + fatal ("uninitialized type to mangle"); case TYPE_POINTER: oprintf (of, "P"); output_mangled_typename (of, t->u.p); @@ -2409,8 +2352,8 @@ 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; + 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 @@ -2418,12 +2361,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 == 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) @@ -2678,8 +2621,9 @@ walk_type (type_p t, struct walk_type_da /* 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; @@ -2709,16 +2653,19 @@ 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 == 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; @@ -2960,14 +2907,18 @@ 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 == 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"); @@ -3139,9 +3090,10 @@ 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 == 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) @@ -3366,9 +3318,10 @@ write_local (outf_p output_header, type_ 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 == 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) @@ -3696,8 +3649,9 @@ 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 == OPTION_STRING) + desc = o->info.string; else if (strcmp (o->name, "param_is") == 0) ; else @@ -3718,8 +3672,9 @@ 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 == OPTION_STRING) + tag = oo->info.string; if (tag == NULL || strcmp (tag, desc) != 0) continue; if (validf != NULL) @@ -3895,8 +3850,9 @@ 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 == OPTION_STRING) + length = o->info.string; else if (strcmp (o->name, "deletable") == 0) deletable_p = 1; else if (strcmp (o->name, "param_is") == 0) @@ -4021,8 +3977,9 @@ 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 == OPTION_STRING) + if_marked = o->info.string; if (if_marked == NULL) continue; @@ -4158,7 +4115,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. */ @@ -4449,8 +4406,22 @@ dump_options (int indent, options_p opt) o = opt; while (o) { - printf ("%s:%s ", o->name, o->info); - o = o->next; + 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: + fatal ("corrupted option %p: %s", (void*) o, o->name); + } + o = o->next; } printf ("\n"); } --- ../gengtype-gcc-04-filesrules//gengtype.h 2010-09-10 21:46:34.000000000 +0200 +++ gcc/gengtype.h 2010-09-11 14:46:53.000000000 +0200 @@ -133,26 +133,261 @@ struct fileloc { extern const char **lang_dir_names; extern size_t num_lang_dirs; - - -/* Data types handed around within, but opaque to, the lexer and parser. */ +/* Common types, for structures defined below. */ typedef struct pair *pair_p; typedef struct type *type_p; typedef const struct type *const_type_p; typedef struct options *options_p; +/* Various things, organized as linked lists, needed both in + gengtype.c & in gengtype-state.c */ +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 zero-ed memory is + invalid. */ + TYPE_SCALAR, /* Scalar types like char. */ + TYPE_STRING, /* The string type. */ + TYPE_STRUCT, /* Type for GTY-ed struct-ures. */ + TYPE_UNION, /* Type for GTY-ed discriminated + union-s. */ + TYPE_POINTER, /* Pointer type to GTY-ed type. */ + TYPE_ARRAY, /* Array of GTY-ed types. */ + TYPE_LANG_STRUCT, /* GCC front-end language specific + struct-s. Various languages may have + homonymous but different + struct-s. */ + TYPE_PARAM_STRUCT /* Type for parametrized struct-ures, + 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 zero-ed 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; /* disciminating option kind. */ + /* the union below is discriminated by the 'kind' field above. */ + 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 zero-ed 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 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 struct-s or union-s, the 'next' field link the + global list 'structures' or 'param_structs'; for lang_struct-s, + their homonymous struct-s 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 appropriately early in main. */ +extern struct type scalar_nonchar; +extern struct type scalar_char; + +/* Gives the file location of a type, if any. */ +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 zeroed type %p", (const void*)ty); + case TYPE_STRUCT: + case TYPE_UNION: + case TYPE_LANG_STRUCT: + return CONST_CAST (struct fileloc*, &ty->u.s.line); + case TYPE_PARAM_STRUCT: + return CONST_CAST (struct fileloc*, &ty->u.param_struct.line); + 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); +} + +/* 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) + + /* Variables used to communicate between the lexer and the parser. */ extern int lexer_toplevel_done; extern struct fileloc lexer_line; /* Structure representing an output file. */ -struct outf -{ - struct outf *next; - const char *name; - size_t buflength; - size_t bufused; - char *buf; +struct outf { + struct outf *next; + const char *name; + size_t buflength; + size_t bufused; + char *buf; }; typedef struct outf* outf_p; --- ../gengtype-gcc-04-filesrules//gengtype-parse.c 2010-09-10 21:46:34.000000000 +0200 +++ gcc/gengtype-parse.c 2010-09-11 15:15:14.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, "", ""); } }
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |