Commit 18aa2b04 by David Malcolm Committed by David Malcolm

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.

From-SVN: r204003
parent 2f3097a3
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> 2013-10-23 Sriraman Tallam <tmsriram@google.com>
PR target/57756 PR target/57756
...@@ -165,6 +165,21 @@ require (int t) ...@@ -165,6 +165,21 @@ require (int t)
return v; 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 /* If the next token does not have one of the codes T1 or T2, report a
parse error; otherwise return the token's value. */ parse error; otherwise return the token's value. */
static const char * static const char *
...@@ -829,6 +844,7 @@ type (options_p *optsp, bool nested) ...@@ -829,6 +844,7 @@ type (options_p *optsp, bool nested)
case STRUCT: case STRUCT:
case UNION: case UNION:
{ {
type_p base_class = NULL;
options_p opts = 0; options_p opts = 0;
/* GTY annotations follow attribute syntax /* GTY annotations follow attribute syntax
GTY_BEFORE_ID is for union/struct declarations GTY_BEFORE_ID is for union/struct declarations
...@@ -868,16 +884,39 @@ type (options_p *optsp, bool nested) ...@@ -868,16 +884,39 @@ type (options_p *optsp, bool nested)
opts = gtymarker_opt (); opts = gtymarker_opt ();
} }
bool is_user_gty = opts_have (opts, "user");
if (token () == ':') if (token () == ':')
{ {
/* Skip over C++ inheritance specification. */ if (is_gty && !is_user_gty)
while (token () != '{') {
advance (); /* 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) if (is_gty)
{ {
bool is_user_gty = opts_have (opts, "user");
if (token () == '{') if (token () == '{')
{ {
pair_p fields; pair_p fields;
...@@ -900,7 +939,8 @@ type (options_p *optsp, bool nested) ...@@ -900,7 +939,8 @@ type (options_p *optsp, bool nested)
return create_user_defined_type (s, &lexer_line); 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 () == '{') else if (token () == '{')
......
...@@ -957,6 +957,7 @@ state_writer::write_state_struct_type (type_p current) ...@@ -957,6 +957,7 @@ state_writer::write_state_struct_type (type_p current)
{ {
write_state_struct_union_type (current, "struct"); write_state_struct_union_type (current, "struct");
write_state_type (current->u.s.lang_struct); write_state_type (current->u.s.lang_struct);
write_state_type (current->u.s.base_class);
} }
/* Write a GTY user-defined struct type. */ /* Write a GTY user-defined struct type. */
...@@ -1613,6 +1614,7 @@ read_state_struct_type (type_p type) ...@@ -1613,6 +1614,7 @@ read_state_struct_type (type_p type)
read_state_options (&(type->u.s.opt)); read_state_options (&(type->u.s.opt));
read_state_lang_bitmap (&(type->u.s.bitmap)); read_state_lang_bitmap (&(type->u.s.bitmap));
read_state_type (&(type->u.s.lang_struct)); read_state_type (&(type->u.s.lang_struct));
read_state_type (&(type->u.s.base_class));
} }
else else
{ {
......
...@@ -674,7 +674,7 @@ resolve_typedef (const char *s, struct fileloc *pos) ...@@ -674,7 +674,7 @@ resolve_typedef (const char *s, struct fileloc *pos)
type_p type_p
new_structure (const char *name, enum typekind kind, struct fileloc *pos, 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 si;
type_p s = NULL; type_p s = NULL;
...@@ -748,6 +748,7 @@ new_structure (const char *name, enum typekind kind, struct fileloc *pos, ...@@ -748,6 +748,7 @@ new_structure (const char *name, enum typekind kind, struct fileloc *pos,
s->u.s.bitmap = bitmap; s->u.s.bitmap = bitmap;
if (s->u.s.lang_struct) if (s->u.s.lang_struct)
s->u.s.lang_struct->u.s.bitmap |= bitmap; s->u.s.lang_struct->u.s.bitmap |= bitmap;
s->u.s.base_class = base_class;
return s; return s;
} }
...@@ -976,7 +977,7 @@ create_optional_field_ (pair_p next, type_p type, const char *name, ...@@ -976,7 +977,7 @@ create_optional_field_ (pair_p next, type_p type, const char *name,
create_string_option (union_fields->opt, "tag", "1"); create_string_option (union_fields->opt, "tag", "1");
union_type = union_type =
new_structure (xasprintf ("%s_%d", "fake_union", id++), TYPE_UNION, 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" /* 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. */ 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)) ...@@ -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]); create_string_option (nodot, "tag", note_insn_name[c]);
} }
note_union_tp = new_structure ("rtx_def_note_subunion", TYPE_UNION, 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. */ /* 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)) ...@@ -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 = create_field (sym_flds, constant_tp, "rt_constant");
sym_flds->opt = create_string_option (nodot, "tag", "1"); sym_flds->opt = create_string_option (nodot, "tag", "1");
symbol_union_tp = new_structure ("rtx_def_symbol_subunion", TYPE_UNION, 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++) for (i = 0; i < NUM_RTX_CODE; i++)
{ {
...@@ -1319,7 +1320,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) ...@@ -1319,7 +1320,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
sname = xasprintf ("rtx_def_%s", rtx_name[i]); sname = xasprintf ("rtx_def_%s", rtx_name[i]);
substruct = new_structure (sname, TYPE_STRUCT, &lexer_line, subfields, substruct = new_structure (sname, TYPE_STRUCT, &lexer_line, subfields,
NULL); NULL, NULL);
ftag = xstrdup (rtx_name[i]); ftag = xstrdup (rtx_name[i]);
for (nmindex = 0; nmindex < strlen (ftag); nmindex++) for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
...@@ -1328,7 +1329,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) ...@@ -1328,7 +1329,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
flds->opt = create_string_option (nodot, "tag", ftag); flds->opt = create_string_option (nodot, "tag", ftag);
} }
return new_structure ("rtx_def_subunion", TYPE_UNION, &lexer_line, flds, return new_structure ("rtx_def_subunion", TYPE_UNION, &lexer_line, flds,
nodot); nodot, NULL);
} }
/* Handle `special("tree_exp")'. This is a special case for /* 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) ...@@ -1358,7 +1359,7 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
flds->opt = create_string_option (flds->opt, "default", ""); flds->opt = create_string_option (flds->opt, "default", "");
return new_structure ("tree_exp_subunion", TYPE_UNION, &lexer_line, flds, 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 /* Perform any special processing on a type T, about to become the type
......
...@@ -291,6 +291,8 @@ struct type { ...@@ -291,6 +291,8 @@ struct type {
field the original TYPE_LANG_STRUCT type. This is a dirty field the original TYPE_LANG_STRUCT type. This is a dirty
trick, see the new_structure function for details. */ trick, see the new_structure function for details. */
type_p lang_struct; type_p lang_struct;
type_p base_class; /* the parent class, if any. */
} s; } s;
/* when TYPE_SCALAR: */ /* when TYPE_SCALAR: */
...@@ -424,7 +426,7 @@ extern void do_scalar_typedef (const char *s, struct fileloc *pos); ...@@ -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 resolve_typedef (const char *s, struct fileloc *pos);
extern type_p new_structure (const char *name, enum typekind kind, extern type_p new_structure (const char *name, enum typekind kind,
struct fileloc *pos, pair_p fields, 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 *); type_p create_user_defined_type (const char *, struct fileloc *);
extern type_p find_structure (const char *s, enum typekind kind); extern type_p find_structure (const char *s, enum typekind kind);
extern type_p create_scalar_type (const char *name); extern type_p create_scalar_type (const char *name);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment