summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-24 02:10:10 +0000
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-24 02:10:10 +0000
commitb1ca34906da5b69134ae32187404b68c28b6fc97 (patch)
tree47f303b7d339aeffeb3949f863c13b6533cf2f60
parent42e1f90cde333ab019419d2ad18b966c256ebef8 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/gengtype-parse.c50
-rw-r--r--gcc/gengtype-state.c2
-rw-r--r--gcc/gengtype.c15
-rw-r--r--gcc/gengtype.h4
5 files changed, 77 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 692db4bfc14..f5c2d8b20b3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+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.
+
2013-10-23 Sriraman Tallam <tmsriram@google.com>
PR target/57756
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 () == '{')
diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c
index 96ecc7cdaf8..1e9fadeb006 100644
--- a/gcc/gengtype-state.c
+++ b/gcc/gengtype-state.c
@@ -957,6 +957,7 @@ state_writer::write_state_struct_type (type_p current)
{
write_state_struct_union_type (current, "struct");
write_state_type (current->u.s.lang_struct);
+ write_state_type (current->u.s.base_class);
}
/* Write a GTY user-defined struct type. */
@@ -1613,6 +1614,7 @@ read_state_struct_type (type_p type)
read_state_options (&(type->u.s.opt));
read_state_lang_bitmap (&(type->u.s.bitmap));
read_state_type (&(type->u.s.lang_struct));
+ read_state_type (&(type->u.s.base_class));
}
else
{
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 88e1b2796a5..a66f835a2f2 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -674,7 +674,7 @@ resolve_typedef (const char *s, struct fileloc *pos)
type_p
new_structure (const char *name, enum typekind kind, struct fileloc *pos,
- pair_p fields, options_p o)
+ pair_p fields, options_p o, type_p base_class)
{
type_p si;
type_p s = NULL;
@@ -748,6 +748,7 @@ new_structure (const char *name, enum typekind kind, struct fileloc *pos,
s->u.s.bitmap = bitmap;
if (s->u.s.lang_struct)
s->u.s.lang_struct->u.s.bitmap |= bitmap;
+ s->u.s.base_class = base_class;
return s;
}
@@ -976,7 +977,7 @@ create_optional_field_ (pair_p next, type_p type, const char *name,
create_string_option (union_fields->opt, "tag", "1");
union_type =
new_structure (xasprintf ("%s_%d", "fake_union", id++), TYPE_UNION,
- &lexer_line, union_fields, NULL);
+ &lexer_line, union_fields, NULL, 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. */
@@ -1167,7 +1168,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
create_string_option (nodot, "tag", note_insn_name[c]);
}
note_union_tp = new_structure ("rtx_def_note_subunion", TYPE_UNION,
- &lexer_line, note_flds, NULL);
+ &lexer_line, note_flds, NULL, NULL);
}
/* Create a type to represent the various forms of SYMBOL_REF_DATA. */
{
@@ -1177,7 +1178,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
sym_flds->opt = create_string_option (nodot, "tag", "1");
symbol_union_tp = new_structure ("rtx_def_symbol_subunion", TYPE_UNION,
- &lexer_line, sym_flds, NULL);
+ &lexer_line, sym_flds, NULL, NULL);
}
for (i = 0; i < NUM_RTX_CODE; i++)
{
@@ -1319,7 +1320,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
sname = xasprintf ("rtx_def_%s", rtx_name[i]);
substruct = new_structure (sname, TYPE_STRUCT, &lexer_line, subfields,
- NULL);
+ NULL, NULL);
ftag = xstrdup (rtx_name[i]);
for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
@@ -1328,7 +1329,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
flds->opt = create_string_option (nodot, "tag", ftag);
}
return new_structure ("rtx_def_subunion", TYPE_UNION, &lexer_line, flds,
- nodot);
+ nodot, NULL);
}
/* Handle `special("tree_exp")'. This is a special case for
@@ -1358,7 +1359,7 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
flds->opt = create_string_option (flds->opt, "default", "");
return new_structure ("tree_exp_subunion", TYPE_UNION, &lexer_line, flds,
- nodot);
+ nodot, NULL);
}
/* Perform any special processing on a type T, about to become the type
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
index f71ad97049d..06ebbed55a8 100644
--- a/gcc/gengtype.h
+++ b/gcc/gengtype.h
@@ -291,6 +291,8 @@ struct type {
field the original TYPE_LANG_STRUCT type. This is a dirty
trick, see the new_structure function for details. */
type_p lang_struct;
+
+ type_p base_class; /* the parent class, if any. */
} s;
/* when TYPE_SCALAR: */
@@ -424,7 +426,7 @@ extern void do_scalar_typedef (const char *s, struct fileloc *pos);
extern type_p resolve_typedef (const char *s, struct fileloc *pos);
extern type_p new_structure (const char *name, enum typekind kind,
struct fileloc *pos, pair_p fields,
- options_p o);
+ options_p o, type_p base);
type_p create_user_defined_type (const char *, struct fileloc *);
extern type_p find_structure (const char *s, enum typekind kind);
extern type_p create_scalar_type (const char *name);