diff options
author | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-24 02:10:10 +0000 |
---|---|---|
committer | dmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-10-24 02:10:10 +0000 |
commit | b1ca34906da5b69134ae32187404b68c28b6fc97 (patch) | |
tree | 47f303b7d339aeffeb3949f863c13b6533cf2f60 /gcc/gengtype-parse.c | |
parent | 42e1f90cde333ab019419d2ad18b966c256ebef8 (diff) | |
download | gcc-b1ca34906da5b69134ae32187404b68c28b6fc97.tar.gz |
gengtype: parse base classes for some GTY-marked types
2013-10-23 David Malcolm <dmalcolm@redhat.com>
* gengtype-parse.c (require_without_advance): New.
(type): For GTY-marked types that are not GTY((user)), parse any
base classes, requiring them to be single-inheritance, and not
be templates. For non-GTY-marked types and GTY((user)),
continue to skip over any C++ inheritance specification.
* gengtype-state.c (state_writer::write_state_struct_type):
Write base class of type (if any).
(read_state_struct_type): Read base class of type (if any).
* gengtype.c (new_structure): Add a "base_class" parameter.
(create_optional_field_): Update for new parameter to
new_structure.
(adjust_field_rtx_def): Likewise.
(adjust_field_tree_exp): Likewise.
* gengtype.h (struct type): Add "base_class" field to the s
union field.
(new_structure): Add "base" parameter.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204003 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gengtype-parse.c')
-rw-r--r-- | gcc/gengtype-parse.c | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c index e5204c1a71d..31d493a46f5 100644 --- a/gcc/gengtype-parse.c +++ b/gcc/gengtype-parse.c @@ -165,6 +165,21 @@ require (int t) return v; } +/* As per require, but do not advance. */ +static const char * +require_without_advance (int t) +{ + int u = token (); + const char *v = T.value; + if (u != t) + { + parse_error ("expected %s, have %s", + print_token (t, 0), print_token (u, v)); + return 0; + } + return v; +} + /* If the next token does not have one of the codes T1 or T2, report a parse error; otherwise return the token's value. */ static const char * @@ -829,6 +844,7 @@ type (options_p *optsp, bool nested) case STRUCT: case UNION: { + type_p base_class = NULL; options_p opts = 0; /* GTY annotations follow attribute syntax GTY_BEFORE_ID is for union/struct declarations @@ -868,16 +884,39 @@ type (options_p *optsp, bool nested) opts = gtymarker_opt (); } + bool is_user_gty = opts_have (opts, "user"); + if (token () == ':') { - /* Skip over C++ inheritance specification. */ - while (token () != '{') - advance (); + if (is_gty && !is_user_gty) + { + /* For GTY-marked types that are not "user", parse some C++ + inheritance specifications. + We require single-inheritance from a non-template type. */ + advance (); + const char *basename = require (ID); + /* This may be either an access specifier, or the base name. */ + if (0 == strcmp (basename, "public") + || 0 == strcmp (basename, "protected") + || 0 == strcmp (basename, "private")) + basename = require (ID); + base_class = find_structure (basename, TYPE_STRUCT); + if (!base_class) + parse_error ("unrecognized base class: %s", basename); + require_without_advance ('{'); + } + else + { + /* For types lacking GTY-markings, skip over C++ inheritance + specification (and thus avoid having to parse e.g. template + types). */ + while (token () != '{') + advance (); + } } if (is_gty) { - bool is_user_gty = opts_have (opts, "user"); if (token () == '{') { pair_p fields; @@ -900,7 +939,8 @@ type (options_p *optsp, bool nested) return create_user_defined_type (s, &lexer_line); } - return new_structure (s, kind, &lexer_line, fields, opts); + return new_structure (s, kind, &lexer_line, fields, opts, + base_class); } } else if (token () == '{') |