diff options
author | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-04 21:29:11 +0000 |
---|---|---|
committer | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-04 21:29:11 +0000 |
commit | aeb682a27a580c32813c316b911b59b851f6f34e (patch) | |
tree | caef14d95e41d87b155a732aa16f18f483eea729 /gcc/gengtype-parse.c | |
parent | 8945e16bd0dc520c80b423cc0802c89ce551ff08 (diff) | |
parent | 8dd9f7ce09ba28909b069f5baa405ea4cc7b5c42 (diff) | |
download | gcc-aeb682a27a580c32813c316b911b59b851f6f34e.tar.gz |
Merge in trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@204366 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gengtype-parse.c')
-rw-r--r-- | gcc/gengtype-parse.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c index 244ddcc85a1..9fb554c628e 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 * @@ -822,7 +837,7 @@ struct_field_seq (void) /* Return true if OPTS contain the option named STR. */ -static bool +bool opts_have (options_p opts, const char *str) { for (options_p opt = opts; opt; opt = opt->next) @@ -873,6 +888,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 @@ -912,16 +928,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; @@ -944,7 +983,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 () == '{') |