summaryrefslogtreecommitdiff
path: root/gcc/gengtype-parse.c
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-04 21:29:11 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-04 21:29:11 +0000
commitaeb682a27a580c32813c316b911b59b851f6f34e (patch)
treecaef14d95e41d87b155a732aa16f18f483eea729 /gcc/gengtype-parse.c
parent8945e16bd0dc520c80b423cc0802c89ce551ff08 (diff)
parent8dd9f7ce09ba28909b069f5baa405ea4cc7b5c42 (diff)
downloadgcc-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.c52
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 () == '{')