gengtype.c (enum typekind, [...]): Move to gengtype.h.

2010-11-23  Basile Starynkevitch  <basile@starynkevitch.net>
	    Jeremie Salvucci  <jeremie.salvucci@free.fr>

	* gengtype.c (enum typekind, struct options)
	(struct nested_ptr_data, struct pair, NUM_PARAM)
	(enum gc_used_num, struct type, UNION_P, UNION_OR_STRUCT_P):
	Move to gengtype.h.
	(string_type, scalar_nonchar, scalar_nonchar, scalar_char):
	Remove static, add zero state_number.
	(typedefs, structures, param_structs, variables): Remove static.
	(create_option): Remove.
	(create_string_option, create_type_option, create_nested_option):
	New functions.
	(create_nested_ptr_option): Use create_nested_option.
	(note_variable, adjust_field_rtx_def, adjust_field_type): Call the
	new create*option functions.
	(process_gc_options): Adjust for discriminated option.
	(output_mangled_typename): Handle TYPE_NONE.
	(walk_type): Test option kinds.
	(write_types_process_field): Handle TYPE_NONE and TYPE_ARRAY.
	(write_func_for_structure, write_type, write_local, write_root)
	(write_roots, note_def_vec, dump_options): Adjust for
	discriminated option.

	* gengtype.h
	(typedefs, structures, param_structs, variables, enum typekind):
	Move from gengtype.c
	(enum option_kind): New discriminating enumeration.
	(struct options): Becomes discriminated.
	(struct nested_ptr_data): Nove from gengtype.c
	(create_string_option, create_type_option, create_nested_option)
	(create_nested_ptr_option): New functions
	(struct pair, enum_gc_used_enum, NUM_PARAM, struct type, UNION_P)
	(UNION_OR_STRUCT_P): Move from gengtype.c

	* gengtype-parse.c (str_optvalue_opt, type_optvalue, option): Make
	discriminated options.


Co-Authored-By: Jeremie Salvucci <jeremie.salvucci@free.fr>

From-SVN: r167080
This commit is contained in:
Basile Starynkevitch 2010-11-23 15:13:12 +00:00 committed by Basile Starynkevitch
parent 6e223f7e4e
commit 412dc29d62
4 changed files with 431 additions and 222 deletions

View File

@ -1,3 +1,41 @@
2010-11-23 Basile Starynkevitch <basile@starynkevitch.net>
Jeremie Salvucci <jeremie.salvucci@free.fr>
* gengtype.c (enum typekind, struct options)
(struct nested_ptr_data, struct pair, NUM_PARAM)
(enum gc_used_num, struct type, UNION_P, UNION_OR_STRUCT_P):
Move to gengtype.h.
(string_type, scalar_nonchar, scalar_nonchar, scalar_char):
Remove static, add zero state_number.
(typedefs, structures, param_structs, variables): Remove static.
(create_option): Remove.
(create_string_option, create_type_option, create_nested_option):
New functions.
(create_nested_ptr_option): Use create_nested_option.
(note_variable, adjust_field_rtx_def, adjust_field_type): Call the
new create*option functions.
(process_gc_options): Adjust for discriminated option.
(output_mangled_typename): Handle TYPE_NONE.
(walk_type): Test option kinds.
(write_types_process_field): Handle TYPE_NONE and TYPE_ARRAY.
(write_func_for_structure, write_type, write_local, write_root)
(write_roots, note_def_vec, dump_options): Adjust for
discriminated option.
* gengtype.h
(typedefs, structures, param_structs, variables, enum typekind):
Move from gengtype.c
(enum option_kind): New discriminating enumeration.
(struct options): Becomes discriminated.
(struct nested_ptr_data): Nove from gengtype.c
(create_string_option, create_type_option, create_nested_option)
(create_nested_ptr_option): New functions
(struct pair, enum_gc_used_enum, NUM_PARAM, struct type, UNION_P)
(UNION_OR_STRUCT_P): Move from gengtype.c
* gengtype-parse.c (str_optvalue_opt, type_optvalue, option): Make
discriminated options.
2010-11-23 Richard Guenther <rguenther@suse.de>
* tree-ssa-sccvn.c (vn_reference_lookup_3): Avoid doing work

View File

@ -372,7 +372,7 @@ str_optvalue_opt (options_p prev)
value = string_seq ();
require (')');
}
return create_option (prev, name, value);
return create_string_option (prev, name, value);
}
/* absdecl: type '*'*
@ -410,7 +410,7 @@ type_optvalue (options_p prev, const char *name)
require ('(');
ty = absdecl ();
require (')');
return create_option (prev, name, ty);
return create_type_option (prev, name, ty);
}
/* Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' */
@ -459,7 +459,7 @@ option (options_p prev)
default:
parse_error ("expected an option keyword, have %s", print_cur_token ());
advance ();
return create_option (prev, "", "");
return create_string_option (prev, "", "");
}
}

View File

@ -31,106 +31,6 @@
/* Data types, macros, etc. used only in this file. */
/* Kinds of types we can understand. */
enum typekind
{
TYPE_SCALAR,
TYPE_STRING,
TYPE_STRUCT,
TYPE_UNION,
TYPE_POINTER,
TYPE_ARRAY,
TYPE_LANG_STRUCT,
TYPE_PARAM_STRUCT
};
/* A way to pass data through to the output end. */
struct options
{
struct options *next;
const char *name;
const char *info;
};
/* Option data for the 'nested_ptr' option. */
struct nested_ptr_data
{
type_p type;
const char *convert_to;
const char *convert_from;
};
/* A name and a type. */
struct pair
{
pair_p next;
const char *name;
type_p type;
struct fileloc line;
options_p opt;
};
#define NUM_PARAM 10
/* A description of a type. */
enum gc_used_enum
{
GC_UNUSED = 0,
GC_USED,
/* Used for structures whose definitions we haven't seen so far when
we encounter a pointer to it that is annotated with ``maybe_undef''.
If after reading in everything we don't have source file
information for it, we assume that it never has been defined. */
GC_MAYBE_POINTED_TO,
GC_POINTED_TO
};
struct type
{
enum typekind kind;
type_p next;
type_p pointer_to;
enum gc_used_enum gc_used;
union
{
type_p p;
struct
{
const char *tag;
struct fileloc line;
pair_p fields;
options_p opt;
lang_bitmap bitmap;
type_p lang_struct;
} s;
bool scalar_is_char;
struct
{
type_p p;
const char *len;
} a;
struct
{
type_p stru;
type_p param[NUM_PARAM];
struct fileloc line;
} param_struct;
} u;
};
#define UNION_P(x) \
((x)->kind == TYPE_UNION || \
((x)->kind == TYPE_LANG_STRUCT \
&& (x)->u.s.lang_struct->kind == TYPE_UNION))
#define UNION_OR_STRUCT_P(x) \
((x)->kind == TYPE_UNION \
|| (x)->kind == TYPE_STRUCT \
|| (x)->kind == TYPE_LANG_STRUCT)
/* The list of output files. */
outf_p output_files;
@ -554,27 +454,27 @@ read_input_list (const char *listname)
/* The one and only TYPE_STRING. */
static struct type string_type = {
TYPE_STRING, 0, 0, GC_USED, {0}
struct type string_type = {
TYPE_STRING, 0, 0, 0, GC_USED, {0}
};
/* The two and only TYPE_SCALARs. Their u.scalar_is_char flags are
set to appropriate values at the beginning of main. */
set early in main. */
static struct type scalar_nonchar = {
TYPE_SCALAR, 0, 0, GC_USED, {0}
struct type scalar_nonchar = {
TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
};
static struct type scalar_char = {
TYPE_SCALAR, 0, 0, GC_USED, {0}
struct type scalar_char = {
TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
};
/* Lists of various things. */
static pair_p typedefs;
static type_p structures;
static type_p param_structs;
static pair_p variables;
pair_p typedefs;
type_p structures;
type_p param_structs;
pair_p variables;
static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
static type_p adjust_field_tree_exp (type_p t, options_p opt);
@ -800,16 +700,44 @@ create_array (type_p t, const char *len)
return v;
}
/* Return an options structure with name NAME and info INFO. NEXT is the
next option in the chain. */
/* Return a string options structure with name NAME and info INFO.
NEXT is the next option in the chain. */
options_p
create_option (options_p next, const char *name, const void *info)
create_string_option (options_p next, const char *name, const char *info)
{
options_p o = XNEW (struct options);
o->kind = OPTION_STRING;
o->next = next;
o->name = name;
o->info.string = info;
return o;
}
/* Create a type options structure with name NAME and info INFO. NEXT
is the next option in the chain. */
options_p
create_type_option (options_p next, const char* name, type_p info)
{
options_p o = XNEW (struct options);
o->next = next;
o->name = name;
o->info = (const char *) info;
o->kind = OPTION_TYPE;
o->info.type = info;
return o;
}
/* Create a nested pointer options structure with name NAME and info
INFO. NEXT is the next option in the chain. */
options_p
create_nested_option (options_p next, const char* name,
struct nested_ptr_data* info)
{
options_p o;
o = XNEW (struct options);
o->next = next;
o->name = name;
o->kind = OPTION_NESTED;
o->info.nested = info;
return o;
}
@ -823,12 +751,11 @@ create_nested_ptr_option (options_p next, type_p t,
d->type = adjust_field_type (t, 0);
d->convert_to = to;
d->convert_from = from;
return create_option (next, "nested_ptr", d);
return create_nested_option (next, "nested_ptr", d);
}
/* Add a variable named S of type T with options O defined at POS,
to `variables'. */
void
note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
{
@ -890,15 +817,19 @@ create_optional_field_ (pair_p next, type_p type, const char *name,
The field has a tag of "1". This allows us to make the presence
of a field of type TYPE depend on some boolean "desc" being true. */
union_fields = create_field (NULL, type, "");
union_fields->opt = create_option (union_fields->opt, "dot", "");
union_fields->opt = create_option (union_fields->opt, "tag", "1");
union_type = new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
&lexer_line, union_fields, NULL);
union_fields->opt =
create_string_option (union_fields->opt, "dot", "");
union_fields->opt =
create_string_option (union_fields->opt, "tag", "1");
union_type =
new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
&lexer_line, union_fields, 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. */
return create_field_all (next, union_type, name,
create_option (0, "desc", cond), this_file, line);
create_string_option (0, "desc", cond),
this_file, line);
}
#define create_optional_field(next,type,name,cond) \
@ -1031,14 +962,16 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
return &string_type;
}
nodot = create_option (NULL, "dot", "");
nodot = create_string_option (NULL, "dot", "");
rtx_tp = create_pointer (find_structure ("rtx_def", 0));
rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
tree_tp = create_pointer (find_structure ("tree_node", 1));
mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
reg_attrs_tp =
create_pointer (find_structure ("reg_attrs", 0));
basic_block_tp =
create_pointer (find_structure ("basic_block_def", 0));
constant_tp =
create_pointer (find_structure ("constant_descriptor_rtx", 0));
scalar_tp = &scalar_nonchar; /* rtunion int */
@ -1072,9 +1005,11 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
/* NOTE_INSN_MAX is used as the default field for line
number notes. */
if (c == NOTE_INSN_MAX)
note_flds->opt = create_option (nodot, "default", "");
note_flds->opt =
create_string_option (nodot, "default", "");
else
note_flds->opt = create_option (nodot, "tag", note_insn_name[c]);
note_flds->opt =
create_string_option (nodot, "tag", note_insn_name[c]);
}
note_union_tp = new_structure ("rtx_def_note_subunion", 1,
&lexer_line, note_flds, NULL);
@ -1082,13 +1017,10 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
/* Create a type to represent the various forms of SYMBOL_REF_DATA. */
{
pair_p sym_flds;
sym_flds = create_field (NULL, tree_tp, "rt_tree");
sym_flds->opt = create_option (nodot, "default", "");
sym_flds->opt = create_string_option (nodot, "default", "");
sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
sym_flds->opt = create_option (nodot, "tag", "1");
sym_flds->opt = create_string_option (nodot, "tag", "1");
symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
&lexer_line, sym_flds, NULL);
}
@ -1152,9 +1084,10 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
t = scalar_tp, subname = "rt_int";
else
{
error_at_line (&lexer_line,
"rtx type `%s' has `0' in position %lu, can't handle",
rtx_name[i], (unsigned long) aindex);
error_at_line
(&lexer_line,
"rtx type `%s' has `0' in position %lu, can't handle",
rtx_name[i], (unsigned long) aindex);
t = &string_type;
subname = "rt_int";
}
@ -1190,10 +1123,11 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
break;
default:
error_at_line (&lexer_line,
"rtx type `%s' has `%c' in position %lu, can't handle",
rtx_name[i], rtx_format[i][aindex],
(unsigned long) aindex);
error_at_line
(&lexer_line,
"rtx type `%s' has `%c' in position %lu, can't handle",
rtx_name[i], rtx_format[i][aindex],
(unsigned long) aindex);
t = &string_type;
subname = "rt_int";
break;
@ -1205,16 +1139,19 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
subname));
subfields->opt = nodot;
if (t == note_union_tp)
subfields->opt = create_option (subfields->opt, "desc",
"NOTE_KIND (&%0)");
subfields->opt =
create_string_option (subfields->opt, "desc",
"NOTE_KIND (&%0)");
if (t == symbol_union_tp)
subfields->opt = create_option (subfields->opt, "desc",
"CONSTANT_POOL_ADDRESS_P (&%0)");
subfields->opt =
create_string_option (subfields->opt, "desc",
"CONSTANT_POOL_ADDRESS_P (&%0)");
}
if (i == SYMBOL_REF)
{
/* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */
/* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P
holds. */
type_p field_tp = find_structure ("block_symbol", 0);
subfields
= create_optional_field (subfields, field_tp, "block_sym",
@ -1227,11 +1164,9 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
ftag = xstrdup (rtx_name[i]);
for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
ftag[nmindex] = TOUPPER (ftag[nmindex]);
flds = create_field (flds, substruct, "");
flds->opt = create_option (nodot, "tag", ftag);
flds->opt = create_string_option (nodot, "tag", ftag);
}
return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
}
@ -1254,12 +1189,12 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
return &string_type;
}
nodot = create_option (NULL, "dot", "");
nodot = create_string_option (NULL, "dot", "");
flds = create_field (NULL, t, "");
flds->opt = create_option (nodot, "length",
"TREE_OPERAND_LENGTH ((tree) &%0)");
flds->opt = create_option (flds->opt, "default", "");
flds->opt = create_string_option (nodot, "length",
"TREE_OPERAND_LENGTH ((tree) &%0)");
flds->opt = create_string_option (flds->opt, "default", "");
return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
}
@ -1289,10 +1224,11 @@ adjust_field_type (type_p t, options_p opt)
for (; opt; opt = opt->next)
if (strcmp (opt->name, "length") == 0)
length_p = 1;
else if (strcmp (opt->name, "param_is") == 0
|| (strncmp (opt->name, "param", 5) == 0
&& ISDIGIT (opt->name[5])
&& strcmp (opt->name + 6, "_is") == 0))
else if ((strcmp (opt->name, "param_is") == 0
|| (strncmp (opt->name, "param", 5) == 0
&& ISDIGIT (opt->name[5])
&& strcmp (opt->name + 6, "_is") == 0))
&& opt->kind == OPTION_TYPE)
{
int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
@ -1309,14 +1245,14 @@ adjust_field_type (type_p t, options_p opt)
if (params[num] != NULL)
error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
if (!ISDIGIT (opt->name[5]))
params[num] =
create_pointer (CONST_CAST2 (type_p, const char *, opt->info));
params[num] = create_pointer (opt->info.type);
else
params[num] = CONST_CAST2 (type_p, const char *, opt->info);
params[num] = opt->info.type;
}
else if (strcmp (opt->name, "special") == 0)
else if (strcmp (opt->name, "special") == 0
&& opt->kind == OPTION_STRING)
{
const char *special_name = opt->info;
const char *special_name = opt->info.string;
if (strcmp (special_name, "tree_exp") == 0)
t = adjust_field_tree_exp (t, opt);
else if (strcmp (special_name, "rtx_def") == 0)
@ -1359,8 +1295,9 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
{
options_p o;
for (o = opt; o; o = o->next)
if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
set_gc_used_type (CONST_CAST2 (type_p, const char *, o->info),
if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO
&& o->kind == OPTION_TYPE)
set_gc_used_type (o->info.type,
GC_POINTED_TO, NULL);
else if (strcmp (o->name, "maybe_undef") == 0)
*maybe_undef = 1;
@ -1370,12 +1307,13 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
*length = 1;
else if (strcmp (o->name, "skip") == 0)
*skip = 1;
else if (strcmp (o->name, "nested_ptr") == 0)
*nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
else if (strcmp (o->name, "nested_ptr") == 0
&& o->kind == OPTION_NESTED)
*nested_ptr = ((const struct nested_ptr_data *) o->info.nested)->type;
}
/* Set the gc_used field of T to LEVEL, and handle the types it references. */
/* Set the gc_used field of T to LEVEL, and handle the types it references. */
static void
set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
{
@ -2318,6 +2256,9 @@ output_mangled_typename (outf_p of, const_type_p t)
else
switch (t->kind)
{
case TYPE_NONE:
gcc_unreachable ();
break;
case TYPE_POINTER:
oprintf (of, "P");
output_mangled_typename (of, t->u.p);
@ -2413,8 +2354,8 @@ walk_type (type_p t, struct walk_type_data *d)
d->needs_cast_p = false;
for (oo = d->opt; oo; oo = oo->next)
if (strcmp (oo->name, "length") == 0)
length = oo->info;
if (strcmp (oo->name, "length") == 0 && oo->kind == OPTION_STRING)
length = oo->info.string;
else if (strcmp (oo->name, "maybe_undef") == 0)
maybe_undef_p = 1;
else if (strncmp (oo->name, "use_param", 9) == 0
@ -2422,12 +2363,13 @@ walk_type (type_p t, struct walk_type_data *d)
use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
else if (strcmp (oo->name, "use_params") == 0)
use_params_p = 1;
else if (strcmp (oo->name, "desc") == 0)
desc = oo->info;
else if (strcmp (oo->name, "desc") == 0 && oo->kind == OPTION_STRING)
desc = oo->info.string;
else if (strcmp (oo->name, "mark_hook") == 0)
;
else if (strcmp (oo->name, "nested_ptr") == 0)
nested_ptr_d = (const struct nested_ptr_data *) oo->info;
else if (strcmp (oo->name, "nested_ptr") == 0
&& oo->kind == OPTION_NESTED)
nested_ptr_d = (const struct nested_ptr_data *) oo->info.nested;
else if (strcmp (oo->name, "dot") == 0)
;
else if (strcmp (oo->name, "tag") == 0)
@ -2675,8 +2617,9 @@ walk_type (type_p t, struct walk_type_data *d)
/* Some things may also be defined in the structure's options. */
for (o = t->u.s.opt; o; o = o->next)
if (!desc && strcmp (o->name, "desc") == 0)
desc = o->info;
if (!desc && strcmp (o->name, "desc") == 0
&& o->kind == OPTION_STRING)
desc = o->info.string;
d->prev_val[2] = oldval;
d->prev_val[1] = oldprevval2;
@ -2707,16 +2650,19 @@ walk_type (type_p t, struct walk_type_data *d)
d->reorder_fn = NULL;
for (oo = f->opt; oo; oo = oo->next)
if (strcmp (oo->name, "dot") == 0)
dot = oo->info;
else if (strcmp (oo->name, "tag") == 0)
tagid = oo->info;
if (strcmp (oo->name, "dot") == 0
&& oo->kind == OPTION_STRING)
dot = oo->info.string;
else if (strcmp (oo->name, "tag") == 0
&& oo->kind == OPTION_STRING)
tagid = oo->info.string;
else if (strcmp (oo->name, "skip") == 0)
skip_p = 1;
else if (strcmp (oo->name, "default") == 0)
default_p = 1;
else if (strcmp (oo->name, "reorder") == 0)
d->reorder_fn = oo->info;
else if (strcmp (oo->name, "reorder") == 0
&& oo->kind == OPTION_STRING)
d->reorder_fn = oo->info.string;
else if (strncmp (oo->name, "use_param", 9) == 0
&& (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
use_param_p = 1;
@ -2830,6 +2776,8 @@ write_types_process_field (type_p f, const struct walk_type_data *d)
switch (f->kind)
{
case TYPE_NONE:
gcc_unreachable ();
case TYPE_POINTER:
oprintf (d->of, "%*s%s (%s%s", d->indent, "",
wtd->subfield_marker_routine, cast, d->val);
@ -2882,7 +2830,7 @@ write_types_process_field (type_p f, const struct walk_type_data *d)
case TYPE_SCALAR:
break;
default:
case TYPE_ARRAY:
gcc_unreachable ();
}
}
@ -2950,17 +2898,19 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
memset (&d, 0, sizeof (d));
d.of = get_output_file_for_structure (s, param);
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "chain_next") == 0)
chain_next = opt->info;
else if (strcmp (opt->name, "chain_prev") == 0)
chain_prev = opt->info;
else if (strcmp (opt->name, "chain_circular") == 0)
chain_circular = opt->info;
else if (strcmp (opt->name, "mark_hook") == 0)
mark_hook_name = opt->info;
if (strcmp (opt->name, "chain_next") == 0
&& opt->kind == OPTION_STRING)
chain_next = opt->info.string;
else if (strcmp (opt->name, "chain_prev") == 0
&& opt->kind == OPTION_STRING)
chain_prev = opt->info.string;
else if (strcmp (opt->name, "chain_circular") == 0
&& opt->kind == OPTION_STRING)
chain_circular = opt->info.string;
else if (strcmp (opt->name, "mark_hook") == 0
&& opt->kind == OPTION_STRING)
mark_hook_name = opt->info.string;
if (chain_prev != NULL && chain_next == NULL)
error_at_line (&s->u.s.line, "chain_prev without chain_next");
if (chain_circular != NULL && chain_next != NULL)
@ -3127,9 +3077,10 @@ write_types (outf_p output_header, type_p structures, type_p param_structs,
oprintf (output_header, " } while (0)\n");
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "ptr_alias") == 0)
if (strcmp (opt->name, "ptr_alias") == 0
&& opt->kind == OPTION_TYPE)
{
const_type_p const t = (const_type_p) opt->info;
const_type_p const t = (const_type_p) opt->info.type;
if (t->kind == TYPE_STRUCT
|| t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
oprintf (output_header,
@ -3352,11 +3303,11 @@ write_local (outf_p output_header, type_p structures, type_p param_structs)
if (s->u.s.line.file == NULL)
continue;
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "ptr_alias") == 0)
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "ptr_alias") == 0
&& opt->kind == OPTION_TYPE)
{
const_type_p const t = (const_type_p) opt->info;
const_type_p const t = (const_type_p) opt->info.type;
if (t->kind == TYPE_STRUCT
|| t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
{
@ -3679,8 +3630,9 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
for (o = fld->opt; o; o = o->next)
if (strcmp (o->name, "skip") == 0)
skip_p = 1;
else if (strcmp (o->name, "desc") == 0)
desc = o->info;
else if (strcmp (o->name, "desc") == 0
&& o->kind == OPTION_STRING)
desc = o->info.string;
else if (strcmp (o->name, "param_is") == 0)
;
else
@ -3699,10 +3651,10 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
{
const char *tag = NULL;
options_p oo;
for (oo = ufld->opt; oo; oo = oo->next)
if (strcmp (oo->name, "tag") == 0)
tag = oo->info;
for (oo = ufld->opt; oo; oo = oo->next)
if (strcmp (oo->name, "tag") == 0
&& oo->kind == OPTION_STRING)
tag = oo->info.string;
if (tag == NULL || strcmp (tag, desc) != 0)
continue;
if (validf != NULL)
@ -3873,10 +3825,10 @@ write_roots (pair_p variables, bool emit_pch)
const char *length = NULL;
int deletable_p = 0;
options_p o;
for (o = v->opt; o; o = o->next)
if (strcmp (o->name, "length") == 0)
length = o->info;
if (strcmp (o->name, "length") == 0
&& o->kind == OPTION_STRING)
length = o->info.string;
else if (strcmp (o->name, "deletable") == 0)
deletable_p = 1;
else if (strcmp (o->name, "param_is") == 0)
@ -4003,12 +3955,11 @@ write_roots (pair_p variables, bool emit_pch)
for (o = v->opt; o; o = o->next)
if (strcmp (o->name, "length") == 0)
length_p = 1;
else if (strcmp (o->name, "if_marked") == 0)
if_marked = o->info;
if (if_marked == NULL)
else if (strcmp (o->name, "if_marked") == 0
&& o->kind == OPTION_STRING)
if_marked = o->info.string;
if (if_marked == NULL)
continue;
if (v->type->kind != TYPE_POINTER
|| v->type->u.p->kind != TYPE_PARAM_STRUCT
|| v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
@ -4143,9 +4094,8 @@ note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
else
{
t = resolve_typedef (type_name, pos);
o = create_option (0, "length", "%h.num");
o = create_string_option (0, "length", "%h.num");
}
/* We assemble the field list in reverse order. */
fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
fields = create_field_at (fields, len_ty, "alloc", 0, pos);
@ -4463,7 +4413,21 @@ dump_options (int indent, options_p opt)
o = opt;
while (o)
{
printf ("%s:%s ", o->name, o->info);
switch (o->kind)
{
case OPTION_STRING:
printf ("%s:string %s ", o->name, o->info.string);
break;
case OPTION_TYPE:
printf ("%s:type ", o->name);
dump_type (indent+1, o->info.type);
break;
case OPTION_NESTED:
printf ("%s:nested ", o->name);
break;
case OPTION_NONE:
gcc_unreachable ();
}
o = o->next;
}
printf ("\n");

View File

@ -116,6 +116,218 @@ typedef struct options *options_p;
extern int lexer_toplevel_done;
extern struct fileloc lexer_line;
/* Various things, organized as linked lists, needed both in
gengtype.c & in gengtype-state.c files. */
extern pair_p typedefs;
extern type_p structures;
extern type_p param_structs;
extern pair_p variables;
/* Discrimating kind of types we can understand. */
enum typekind {
TYPE_NONE=0, /* Never used, so zeroed memory is invalid. */
TYPE_SCALAR, /* Scalar types like char. */
TYPE_STRING, /* The string type. */
TYPE_STRUCT, /* Type for GTY-ed structs. */
TYPE_UNION, /* Type for GTY-ed discriminated unions. */
TYPE_POINTER, /* Pointer type to GTY-ed type. */
TYPE_ARRAY, /* Array of GTY-ed types. */
TYPE_LANG_STRUCT, /* GCC front-end language specific structs.
Various languages may have homonymous but
different structs. */
TYPE_PARAM_STRUCT /* Type for parametrized structs, e.g. hash_t
hash-tables, ... See (param_is, use_param,
param1_is, param2_is,... use_param1,
use_param_2,... use_params) GTY
options. */
};
/* Discriminating kind for options. */
enum option_kind {
OPTION_NONE=0, /* Never used, so zeroed memory is invalid. */
OPTION_STRING, /* A string-valued option. Most options are
strings. */
OPTION_TYPE, /* A type-valued option. */
OPTION_NESTED /* Option data for 'nested_ptr'. */
};
/* A way to pass data through to the output end. */
struct options {
struct options *next; /* next option of the same pair. */
const char *name; /* GTY option name. */
enum option_kind kind; /* discriminating option kind. */
union {
const char* string; /* When OPTION_STRING. */
type_p type; /* When OPTION_TYPE. */
struct nested_ptr_data* nested; /* when OPTION_NESTED. */
} info;
};
/* Option data for the 'nested_ptr' option. */
struct nested_ptr_data {
type_p type;
const char *convert_to;
const char *convert_from;
};
/* Some functions to create various options structures with name NAME
and info INFO. NEXT is the next option in the chain. */
/* Create a string option. */
options_p create_string_option (options_p next, const char* name,
const char* info);
/* Create a type option. */
options_p create_type_option (options_p next, const char* name,
type_p info);
/* Create a nested option. */
options_p create_nested_option (options_p next, const char* name,
struct nested_ptr_data* info);
/* Create a nested pointer option. */
options_p create_nested_ptr_option (options_p, type_p t,
const char *from, const char *to);
/* A name and a type. */
struct pair {
pair_p next; /* The next pair in the linked list. */
const char *name; /* The defined name. */
type_p type; /* Its GTY-ed type. */
struct fileloc line; /* The file location. */
options_p opt; /* GTY options, as a linked list. */
};
/* Usage information for GTY-ed types. Gengtype has to care only of
used GTY-ed types. Types are initially unused, and their usage is
computed by set_gc_used_type and set_gc_used functions. */
enum gc_used_enum {
/* We need that zeroed types are initially unused. */
GC_UNUSED=0,
/* The GTY-ed type is used, e.g by a GTY-ed variable or a field
inside a GTY-ed used type. */
GC_USED,
/* For GTY-ed structures whose definitions we haven't seen so far
when we encounter a pointer to it that is annotated with
``maybe_undef''. If after reading in everything we don't have
source file information for it, we assume that it never has been
defined. */
GC_MAYBE_POINTED_TO,
/* For known GTY-ed structures which are pointed to by GTY-ed
variables or fields. */
GC_POINTED_TO
};
/* We can have at most ten type parameters in parameterized structures. */
#define NUM_PARAM 10
/* Our type structure describes all types handled by gengtype. */
struct type {
/* Discriminating kind, cannot be TYPE_NONE. */
enum typekind kind;
/* For top-level structs or unions, the 'next' field links the
global list 'structures' or 'param_structs'; for lang_structs,
their homonymous structs are linked using this 'next' field. The
homonymous list starts at the s.lang_struct field of the
lang_struct. See the new_structure function for details. This is
tricky! */
type_p next;
/* State number used when writing & reading the persistent state. A
type with a positive number has already been written. For ease
of debugging, newly allocated types have a unique negative
number. */
int state_number;
/* Each GTY-ed type which is pointed to by some GTY-ed type knows
the GTY pointer type pointing to it. See create_pointer
function. */
type_p pointer_to;
/* Type usage information, computed by set_gc_used_type and
set_gc_used functions. */
enum gc_used_enum gc_used;
/* The following union is discriminated by the 'kind' field above. */
union {
/* TYPE__NONE is impossible. */
/* when TYPE_POINTER: */
type_p p;
/* when TYPE_STRUCT or TYPE_UNION or TYPE_LANG_STRUCT, we have an
aggregate type containing fields: */
struct {
const char *tag; /* the aggragate tag, if any. */
struct fileloc line; /* the source location. */
pair_p fields; /* the linked list of fields. */
options_p opt; /* the GTY options if any. */
lang_bitmap bitmap; /* the set of front-end languages
using that GTY-ed aggregate. */
/* For TYPE_LANG_STRUCT, the lang_struct field gives the first
element of a linked list of homonymous struct or union types.
Within this list, each homonymous type has as its lang_struct
field the original TYPE_LANG_STRUCT type. This is a dirty
trick, see the new_structure function for details. */
type_p lang_struct;
} s;
/* when TYPE_SCALAR: */
bool scalar_is_char;
/* when TYPE_ARRAY: */
struct {
type_p p; /* The array component type. */
const char *len; /* The string if any giving its length. */
} a;
/* When TYPE_PARAM_STRUCT for (param_is, use_param, param1_is,
param2_is, ... use_param1, use_param_2, ... use_params) GTY
options. */
struct {
type_p stru; /* The generic GTY-ed type. */
type_p param[NUM_PARAM]; /* The actual parameter types. */
struct fileloc line; /* The source location. */
} param_struct;
} u;
};
/* The one and only TYPE_STRING. */
extern struct type string_type;
/* The two and only TYPE_SCALARs. Their u.scalar_is_char flags are
set early in main. */
extern struct type scalar_nonchar;
extern struct type scalar_char;
/* Test if a type is a union, either a plain one or a language
specific one. */
#define UNION_P(x) \
((x)->kind == TYPE_UNION || \
((x)->kind == TYPE_LANG_STRUCT \
&& (x)->u.s.lang_struct->kind == TYPE_UNION))
/* Test if a type is a union or a structure, perhaps a language
specific one. */
#define UNION_OR_STRUCT_P(x) \
((x)->kind == TYPE_UNION \
|| (x)->kind == TYPE_STRUCT \
|| (x)->kind == TYPE_LANG_STRUCT)
/* Structure representing an output file. */
struct outf
{
@ -180,11 +392,6 @@ extern type_p find_structure (const char *s, int isunion);
extern type_p create_scalar_type (const char *name);
extern type_p create_pointer (type_p t);
extern type_p create_array (type_p t, const char *len);
extern options_p create_option (options_p, const char *name,
const void *info);
extern options_p create_nested_ptr_option (options_p, type_p t,
const char *from,
const char *to);
extern pair_p create_field_at (pair_p next, type_p type,
const char *name, options_p opt,
struct fileloc *pos);