diff options
author | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-05-13 15:17:34 +0000 |
---|---|---|
committer | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-05-13 15:17:34 +0000 |
commit | 782fb91549b1b0dd149e81db8a0f74276133f265 (patch) | |
tree | 8bffdaf2d5d6487778cb3b5ae5abfe405d0963d4 /gcc/gengtype.c | |
parent | b988436fafc82cb15cabb125d8fd66839148c4f1 (diff) | |
download | gcc-782fb91549b1b0dd149e81db8a0f74276133f265.tar.gz |
gengtype: Support explicit pointers in template arguments
gcc/
2014-05-13 David Malcolm <dmalcolm@redhat.com>
* gengtype-parse.c (require3): Eliminate in favor of...
(require4): New.
(require_template_declaration): Update to support optional single *
on a type.
* gengtype.c (get_ultimate_base_class): Add a non-const overload.
(create_user_defined_type): Handle a single level of explicit
pointerness within template arguments.
(struct write_types_data): Add field "kind".
(filter_type_name): Handle "*" character.
(write_user_func_for_structure_ptr): Require a write_types_data
rather than just a prefix string, so that we can look up the kind
of the wtd and use it as an index into wrote_user_func_for_ptr,
ensuring that such functions are written at most once. Support
subclasses by invoking the marking function of the ultimate base
class.
(write_user_func_for_structure_body): Require a write_types_data
rather than just a prefix string, so that we can pass this to
write_user_func_for_structure_ptr.
(write_func_for_structure): Likewise.
(ggc_wtd): Add initializer of new "kind" field.
(pch_wtd): Likewise.
* gengtype.h (enum write_types_kinds): New.
(struct type): Add field wrote_user_func_for_ptr to the "s"
union member.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210379 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gengtype.c')
-rw-r--r-- | gcc/gengtype.c | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/gcc/gengtype.c b/gcc/gengtype.c index b6e171822c8..21da84b77d9 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -145,6 +145,14 @@ get_ultimate_base_class (const_type_p s) s = s->u.s.base_class; return s; } + +static type_p +get_ultimate_base_class (type_p s) +{ + while (s->u.s.base_class) + s = s->u.s.base_class; + return s; +} /* Input file handling. */ @@ -589,7 +597,7 @@ create_user_defined_type (const char *type_name, struct fileloc *pos) /* We only accept simple template declarations (see require_template_declaration), so we only need to parse a comma-separated list of strings, implicitly assumed to - be type names. */ + be type names, potentially with "*" characters. */ char *arg = open_bracket + 1; char *type_id = strtok (arg, ",>"); pair_p fields = 0; @@ -597,8 +605,28 @@ create_user_defined_type (const char *type_name, struct fileloc *pos) { /* Create a new field for every type found inside the template parameter list. */ - const char *field_name = xstrdup (type_id); - type_p arg_type = resolve_typedef (field_name, pos); + + /* Support a single trailing "*" character. */ + const char *star = strchr (type_id, '*'); + int is_ptr = (star != NULL); + size_t offset_to_star = star - type_id; + if (is_ptr) + offset_to_star = star - type_id; + + char *field_name = xstrdup (type_id); + + type_p arg_type; + if (is_ptr) + { + /* Strip off the first '*' character (and any subsequent text). */ + *(field_name + offset_to_star) = '\0'; + + arg_type = find_structure (field_name, TYPE_STRUCT); + arg_type = create_pointer (arg_type); + } + else + arg_type = resolve_typedef (field_name, pos); + fields = create_field_at (fields, arg_type, field_name, 0, pos); type_id = strtok (0, ",>"); } @@ -2461,6 +2489,7 @@ struct write_types_data const char *reorder_note_routine; const char *comment; int skip_hooks; /* skip hook generation if non zero */ + enum write_types_kinds kind; }; static void output_escaped_param (struct walk_type_data *d, @@ -2537,7 +2566,8 @@ filter_type_name (const char *type_name) size_t i; char *s = xstrdup (type_name); for (i = 0; i < strlen (s); i++) - if (s[i] == '<' || s[i] == '>' || s[i] == ':' || s[i] == ',') + if (s[i] == '<' || s[i] == '>' || s[i] == ':' || s[i] == ',' + || s[i] == '*') s[i] = '_'; return s; } @@ -3501,10 +3531,10 @@ write_marker_function_name (outf_p of, type_p s, const char *prefix) /* Write on OF a user-callable routine to act as an entry point for the marking routine for S, generated by write_func_for_structure. - PREFIX is the prefix to use to distinguish ggc and pch markers. */ + WTD distinguishes between ggc and pch markers. */ static void -write_user_func_for_structure_ptr (outf_p of, type_p s, const char *prefix) +write_user_func_for_structure_ptr (outf_p of, type_p s, const write_types_data *wtd) { /* Parameterized structures are not supported in user markers. There is no way for the marker function to know which specific type @@ -3534,13 +3564,23 @@ write_user_func_for_structure_ptr (outf_p of, type_p s, const char *prefix) break; } + DBGPRINTF ("write_user_func_for_structure_ptr: %s %s", s->u.s.tag, + wtd->prefix); + + /* Only write the function once. */ + if (s->u.s.wrote_user_func_for_ptr[wtd->kind]) + return; + s->u.s.wrote_user_func_for_ptr[wtd->kind] = true; + oprintf (of, "\nvoid\n"); - oprintf (of, "gt_%sx (", prefix); + oprintf (of, "gt_%sx (", wtd->prefix); write_type_decl (of, s); oprintf (of, " *& x)\n"); oprintf (of, "{\n"); oprintf (of, " if (x)\n "); - write_marker_function_name (of, alias_of ? alias_of : s, prefix); + write_marker_function_name (of, + alias_of ? alias_of : get_ultimate_base_class (s), + wtd->prefix); oprintf (of, " ((void *) x);\n"); oprintf (of, "}\n"); } @@ -3578,7 +3618,8 @@ write_user_func_for_structure_body (type_p s, const char *prefix, which just marks the fields of T. */ static void -write_user_marking_functions (type_p s, const char *prefix, +write_user_marking_functions (type_p s, + const write_types_data *w, struct walk_type_data *d) { gcc_assert (s->kind == TYPE_USER_STRUCT); @@ -3590,10 +3631,10 @@ write_user_marking_functions (type_p s, const char *prefix, { type_p pointed_to_type = fld_type->u.p; if (union_or_struct_p (pointed_to_type)) - write_user_func_for_structure_ptr (d->of, pointed_to_type, prefix); + write_user_func_for_structure_ptr (d->of, pointed_to_type, w); } else if (union_or_struct_p (fld_type)) - write_user_func_for_structure_body (fld_type, prefix, d); + write_user_func_for_structure_body (fld_type, w->prefix, d); } } @@ -3791,7 +3832,7 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param, oprintf (d.of, "}\n"); if (orig_s->kind == TYPE_USER_STRUCT) - write_user_marking_functions (orig_s, wtd->prefix, &d); + write_user_marking_functions (orig_s, wtd, &d); } @@ -3969,14 +4010,14 @@ write_types (outf_p output_header, type_p structures, type_p param_structs, static const struct write_types_data ggc_wtd = { "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL, "GC marker procedures. ", - FALSE + FALSE, WTK_GGC }; static const struct write_types_data pch_wtd = { "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object", "gt_pch_note_reorder", "PCH type-walking procedures. ", - TRUE + TRUE, WTK_PCH }; /* Write out the local pointer-walking routines. */ |