@@ -29,100 +29,6 @@
#include "obstack.h"
#include "gengtype.h"
-/* 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)
-
-
/* Rhe name of the file containing the list of input files. */
@@ -469,18 +375,18 @@ 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. */
-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. */
@@ -649,7 +555,7 @@ new_structure (const char *name, int isu
if (si->u.s.bitmap == bitmap)
s = si;
}
- else if (si->u.s.line.ifile != NULL && si->u.s.bitmap != bitmap)
+ else if (si->u.s.styline.ifile != NULL && si->u.s.bitmap != bitmap)
{
ls = si;
si = XCNEW (struct type);
@@ -681,17 +587,17 @@ new_structure (const char *name, int isu
structures = s;
}
- if (s->u.s.line.ifile != NULL
+ if (s->u.s.styline.ifile != NULL
|| (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
{
error_at_line (pos, "duplicate definition of '%s %s'",
isunion ? "union" : "struct", s->u.s.tag);
- error_at_line (&s->u.s.line, "previous definition here");
+ error_at_line (&s->u.s.styline, "previous definition here");
}
s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
s->u.s.tag = name;
- s->u.s.line = *pos;
+ s->u.s.styline = *pos;
s->u.s.fields = fields;
s->u.s.opt = o;
s->u.s.bitmap = bitmap;
@@ -709,7 +615,7 @@ new_structure (const char *name, int isu
if (!strcmp (gtfilnam + strlen (gtfilnam) - strlen ("input.h"),
"input.h"))
{
- s->u.s.line.ifile = gt_files[n];
+ s->u.s.styline.ifile = gt_files[n];
break;
}
}
@@ -799,7 +705,6 @@ type_p
create_array (type_p t, const char *len)
{
type_p v;
-
v = XCNEW (struct type);
v->kind = TYPE_ARRAY;
v->u.a.p = t;
@@ -807,16 +712,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. */
+/* Create various options structures with name NAME and info INFO.
+ NEXT is the next option in the chain. */
+
+options_p
+create_string_option (options_p next, const char* name, const char* info)
+{
+ options_p o;
+ o = XCNEW (struct options);
+ o->next = next;
+ o->name = name;
+ o->kind = INFO_STRING;
+ o->info.string = info;
+ return o;
+}
+
options_p
-create_option (options_p next, const char *name, const void *info)
+create_type_option (options_p next, const char* name, type_p info)
{
- options_p o = XNEW (struct options);
+ options_p o;
+ o = XCNEW (struct options);
o->next = next;
o->name = name;
- o->info = (const char*) info;
+ o->kind = INFO_TYPE;
+ o->info.type = info;
+ return o;
+}
+
+options_p
+create_nested_option (options_p next, const char* name,
+ struct nested_ptr_data* info)
+{
+ options_p o;
+ o = XCNEW (struct options);
+ o->next = next;
+ o->name = name;
+ o->kind = INFO_NESTED;
+ o->info.nested = info;
return o;
}
@@ -830,7 +763,7 @@ create_nested_ptr_option (options_p next
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,
@@ -898,15 +831,15 @@ create_optional_field_ (pair_p next, typ
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_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),
+ create_string_option (0, "desc", cond),
input_file_name (this_file), line);
}
#define create_optional_field(next,type,name,cond) \
@@ -1038,7 +971,7 @@ adjust_field_rtx_def (type_p t, options_
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));
@@ -1078,9 +1011,9 @@ adjust_field_rtx_def (type_p t, options_
/* 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);
@@ -1090,10 +1023,10 @@ adjust_field_rtx_def (type_p t, options_
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);
@@ -1212,10 +1145,10 @@ adjust_field_rtx_def (type_p t, options_
subname));
subfields->opt = nodot;
if (t == note_union_tp)
- subfields->opt = create_option (subfields->opt, "desc",
+ subfields->opt = create_string_option (subfields->opt, "desc",
"NOTE_KIND (&%0)");
if (t == symbol_union_tp)
- subfields->opt = create_option (subfields->opt, "desc",
+ subfields->opt = create_string_option (subfields->opt, "desc",
"CONSTANT_POOL_ADDRESS_P (&%0)");
}
@@ -1236,7 +1169,7 @@ adjust_field_rtx_def (type_p t, options_
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);
@@ -1261,12 +1194,12 @@ adjust_field_tree_exp (type_p t, options
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",
+ flds->opt = create_string_option (nodot, "length",
"TREE_OPERAND_LENGTH ((tree) &%0)");
- flds->opt = create_option (flds->opt, "default", "");
+ flds->opt = create_string_option (flds->opt, "default", "");
return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
}
@@ -1316,13 +1249,13 @@ adjust_field_type (type_p t, options_p o
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)
{
- 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)
@@ -1366,8 +1299,9 @@ process_gc_options (options_p opt, enum
{
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 == INFO_TYPE)
+ set_gc_used_type (o->info.type,
GC_POINTED_TO, NULL);
else if (strcmp (o->name, "maybe_undef") == 0)
*maybe_undef = 1;
@@ -1378,7 +1312,7 @@ process_gc_options (options_p opt, enum
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;
+ *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. */
@@ -2232,6 +2166,8 @@ output_mangled_typename (outf_p of, cons
oprintf (of, "Z");
else switch (t->kind)
{
+ case TYPE__NONE:
+ fatal ("uninitialized type");
case TYPE_POINTER:
oprintf (of, "P");
output_mangled_typename (of, t->u.p);
@@ -2326,7 +2262,7 @@ walk_type (type_p t, struct walk_type_da
d->needs_cast_p = false;
for (oo = d->opt; oo; oo = oo->next)
if (strcmp (oo->name, "length") == 0)
- length = oo->info;
+ 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
@@ -2334,12 +2270,12 @@ walk_type (type_p t, struct walk_type_da
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 == INFO_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 == INFO_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)
@@ -2427,7 +2363,7 @@ walk_type (type_p t, struct walk_type_da
case TYPE_POINTER:
{
if (maybe_undef_p
- && t->u.p->u.s.line.ifile == NULL)
+ && t->u.p->u.s.styline.ifile == NULL)
{
oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
break;
@@ -2581,7 +2517,7 @@ walk_type (type_p t, struct walk_type_da
int seen_default_p = 0;
options_p o;
- if (! t->u.s.line.ifile)
+ if (! t->u.s.styline.ifile)
error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
@@ -2589,13 +2525,13 @@ walk_type (type_p t, struct walk_type_da
error_at_line (d->line,
"structure `%s' defined for mismatching languages",
t->u.s.tag);
- error_at_line (&t->u.s.line, "one structure defined here");
+ error_at_line (&t->u.s.styline, "one structure defined here");
}
/* 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 == INFO_STRING)
+ desc = o->info.string;
d->prev_val[2] = oldval;
d->prev_val[1] = oldprevval2;
@@ -2625,16 +2561,16 @@ walk_type (type_p t, struct walk_type_da
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 == INFO_STRING)
+ dot = oo->info.string;
+ else if (strcmp (oo->name, "tag") == 0 && oo->kind == INFO_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 == INFO_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;
@@ -2762,13 +2698,13 @@ write_types_process_field (type_p f, con
oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
if (f->u.p->kind == TYPE_PARAM_STRUCT
- && f->u.p->u.param_struct.line.ifile != NULL)
+ && f->u.p->u.param_struct.ptyline.ifile != NULL)
{
oprintf (d->of, ", gt_e_");
output_mangled_typename (d->of, f);
}
else if (UNION_OR_STRUCT_P (f)
- && f->u.p->u.s.line.ifile != NULL)
+ && f->u.p->u.s.styline.ifile != NULL)
{
oprintf (d->of, ", gt_ggc_e_");
output_mangled_typename (d->of, f);
@@ -2810,12 +2746,12 @@ write_types_process_field (type_p f, con
static void
output_type_enum (outf_p of, type_p s)
{
- if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.line.ifile != NULL)
+ if (s->kind == TYPE_PARAM_STRUCT && s->u.param_struct.ptyline.ifile != NULL)
{
oprintf (of, ", gt_e_");
output_mangled_typename (of, s);
}
- else if (UNION_OR_STRUCT_P (s) && s->u.s.line.ifile != NULL)
+ else if (UNION_OR_STRUCT_P (s) && s->u.s.styline.ifile != NULL)
{
oprintf (of, ", gt_ggc_e_");
output_mangled_typename (of, s);
@@ -2834,9 +2770,9 @@ get_output_file_for_structure (const_typ
int i;
if (UNION_OR_STRUCT_P (s))
- fn = s->u.s.line.ifile;
+ fn = s->u.s.styline.ifile;
else if (s->kind == TYPE_PARAM_STRUCT)
- fn = s->u.param_struct.line.ifile;
+ fn = s->u.param_struct.ptyline.ifile;
gcc_assert (!fn || fn->inpmagic == INPUT_FILE_MAGIC);
@@ -2844,7 +2780,7 @@ get_output_file_for_structure (const_typ
for (i = NUM_PARAM - 1; i >= 0; i--)
if (param && param[i] && param[i]->kind == TYPE_POINTER
&& UNION_OR_STRUCT_P (param[i]->u.p))
- fn = param[i]->u.p->u.s.line.ifile;
+ fn = param[i]->u.p->u.s.styline.ifile;
gcc_assert (!fn || fn->inpmagic == INPUT_FILE_MAGIC);
@@ -2874,19 +2810,23 @@ write_func_for_structure (type_p orig_s,
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 == INFO_STRING)
+ chain_next = opt->info.string;
+ else if (strcmp (opt->name, "chain_prev") == 0
+ && opt->kind == INFO_STRING)
+ chain_prev = opt->info.string;
+ else if (strcmp (opt->name, "chain_circular") == 0
+ && opt->kind == INFO_STRING)
+ chain_circular = opt->info.string;
+ else if (strcmp (opt->name, "mark_hook") == 0
+ && opt->kind == INFO_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");
+ error_at_line (&s->u.s.styline, "chain_prev without chain_next");
if (chain_circular != NULL && chain_next != NULL)
- error_at_line (&s->u.s.line, "chain_circular with chain_next");
+ error_at_line (&s->u.s.styline, "chain_circular with chain_next");
if (chain_circular != NULL)
chain_next = chain_circular;
@@ -2894,7 +2834,7 @@ write_func_for_structure (type_p orig_s,
d.cookie = wtd;
d.orig_s = orig_s;
d.opt = s->u.s.opt;
- d.line = &s->u.s.line;
+ d.line = &s->u.s.styline;
d.bitmap = s->u.s.bitmap;
d.param = param;
d.prev_val[0] = "*x";
@@ -3039,7 +2979,7 @@ write_types (outf_p output_header, type_
options_p opt;
if (s->gc_used == GC_MAYBE_POINTED_TO
- && s->u.s.line.ifile == NULL)
+ && s->u.s.styline.ifile == NULL)
continue;
oprintf (output_header, "#define gt_%s_", wtd->prefix);
@@ -3052,9 +2992,9 @@ write_types (outf_p output_header, type_
" } 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 == INFO_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)
@@ -3062,7 +3002,7 @@ write_types (outf_p output_header, type_
"#define gt_%sx_%s gt_%sx_%s\n",
wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
else
- error_at_line (&s->u.s.line,
+ error_at_line (&s->u.s.styline,
"structure alias is not a structure");
break;
}
@@ -3074,7 +3014,7 @@ write_types (outf_p output_header, type_
"extern void gt_%sx_%s (void *);\n",
wtd->prefix, s->u.s.tag);
- if (s->u.s.line.ifile == NULL)
+ if (s->u.s.styline.ifile == NULL)
{
fprintf (stderr, "warning: structure `%s' used but not defined\n",
s->u.s.tag);
@@ -3092,7 +3032,7 @@ write_types (outf_p output_header, type_
output_mangled_typename (output_header, s);
oprintf (output_header, " (void *);\n");
- if (stru->u.s.line.ifile == NULL)
+ if (stru->u.s.styline.ifile == NULL)
{
fprintf (stderr, "warning: structure `%s' used but not defined\n",
s->u.s.tag);
@@ -3109,7 +3049,7 @@ write_types (outf_p output_header, type_
options_p opt;
if (s->gc_used == GC_MAYBE_POINTED_TO
- && s->u.s.line.ifile == NULL)
+ && s->u.s.styline.ifile == NULL)
continue;
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "ptr_alias") == 0)
@@ -3131,7 +3071,7 @@ write_types (outf_p output_header, type_
{
type_p *param = s->u.param_struct.param;
type_p stru = s->u.param_struct.stru;
- if (stru->u.s.line.ifile == NULL)
+ if (stru->u.s.styline.ifile == NULL)
continue;
if (stru->kind == TYPE_LANG_STRUCT)
{
@@ -3202,7 +3142,7 @@ write_local_func_for_structure (const_ty
d.of = get_output_file_for_structure (s, param);
d.process_field = write_types_local_process_field;
d.opt = s->u.s.opt;
- d.line = &s->u.s.line;
+ d.line = &s->u.s.styline;
d.bitmap = s->u.s.bitmap;
d.param = param;
d.prev_val[0] = d.prev_val[2] = "*x";
@@ -3244,13 +3184,13 @@ write_local (outf_p output_header, type_
{
options_p opt;
- if (s->u.s.line.ifile == NULL)
+ if (s->u.s.styline.ifile == NULL)
continue;
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 == INFO_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)
@@ -3262,7 +3202,7 @@ write_local (outf_p output_header, type_
oprintf (output_header, "\n");
}
else
- error_at_line (&s->u.s.line,
+ error_at_line (&s->u.s.styline,
"structure alias is not a structure");
break;
}
@@ -3297,7 +3237,7 @@ write_local (outf_p output_header, type_
oprintf (output_header,
"\n (void *, void *, gt_pointer_operator, void *);\n");
- if (stru->u.s.line.ifile == NULL)
+ if (stru->u.s.styline.ifile == NULL)
{
fprintf (stderr, "warning: structure `%s' used but not defined\n",
s->u.s.tag);
@@ -3324,7 +3264,7 @@ write_local (outf_p output_header, type_
|| (UNION_OR_STRUCT_P (s) && \
(((s)->gc_used == GC_POINTED_TO) \
|| ((s)->gc_used == GC_MAYBE_POINTED_TO \
- && s->u.s.line.ifile != NULL) \
+ && s->u.s.styline.ifile != NULL) \
|| ((s)->gc_used == GC_USED \
&& strncmp (s->u.s.tag, "anonymous", strlen ("anonymous"))))))
@@ -3558,8 +3498,8 @@ write_root (outf_p f, pair_p v, type_p t
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 == INFO_STRING)
+ desc = o->info.string;
else if (strcmp (o->name, "param_is") == 0)
;
else
@@ -3580,8 +3520,8 @@ write_root (outf_p f, pair_p v, type_p t
options_p oo;
for (oo = ufld->opt; oo; oo = oo->next)
- if (strcmp (oo->name, "tag") == 0)
- tag = oo->info;
+ if (strcmp (oo->name, "tag") == 0 && oo->kind == INFO_STRING)
+ tag = oo->info.string;
if (tag == NULL || strcmp (tag, desc) != 0)
continue;
if (validf != NULL)
@@ -3757,8 +3697,8 @@ write_roots (pair_p variables, bool emit
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 == INFO_STRING)
+ length = o->info.string;
else if (strcmp (o->name, "deletable") == 0)
deletable_p = 1;
else if (strcmp (o->name, "param_is") == 0)
@@ -3883,8 +3823,8 @@ write_roots (pair_p variables, bool emit
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;
+ else if (strcmp (o->name, "if_marked") == 0 && o->kind == INFO_STRING)
+ if_marked = o->info.string;
if (if_marked == NULL)
continue;
@@ -4020,7 +3960,7 @@ note_def_vec (const char *type_name, boo
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. */
@@ -4311,7 +4251,21 @@ dump_options (int indent, options_p opt)
o = opt;
while (o)
{
- printf ("%s:%s ", o->name, o->info);
+ switch (o->kind) {
+ case INFO_STRING:
+ printf ("%s:string %s ", o->name, o->info.string);
+ break;
+ case INFO_TYPE:
+ printf ("%s:type ", o->name);
+ dump_type (indent+1, o->info.type);
+ break;
+ case INFO_NESTED:
+ printf ("%s:nested ", o->name);
+ break;
+ case INFO__NONE:
+ fatal ("corrupted option %p: %s", (void*) o, o->name);
+ break;
+ }
o = o->next;
}
printf ("\n");
@@ -4338,7 +4292,7 @@ dump_type_u_s (int indent, type_p t)
gcc_assert (t->kind == TYPE_STRUCT || t->kind == TYPE_UNION
|| t->kind == TYPE_LANG_STRUCT);
printf ("%*cu.s.tag = %s\n", indent, ' ', t->u.s.tag);
- dump_fileloc (indent, t->u.s.line);
+ dump_fileloc (indent, t->u.s.styline);
printf ("%*cu.s.fields =\n", indent, ' ');
fields = t->u.s.fields;
while (fields)
@@ -4375,7 +4329,7 @@ dump_type_u_param_struct (int indent, ty
gcc_assert (t->kind == TYPE_PARAM_STRUCT);
printf ("%*cu.param_struct.stru:\n", indent, ' ');
dump_type_list (indent, t->u.param_struct.stru);
- dump_fileloc (indent, t->u.param_struct.line);
+ dump_fileloc (indent, t->u.param_struct.ptyline);
for (i = 0; i < NUM_PARAM; i++)
{
if (t->u.param_struct.param[i] == NULL)
@@ -1,5 +1,6 @@
/* Process source files and output type information.
- Copyright (C) 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2007, 2008, 2010
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -109,12 +110,182 @@ struct fileloc {
int line;
};
-/* Data types handed around within, but opaque to, the lexer and parser. */
+/* Common types. */
typedef struct pair *pair_p;
typedef struct type *type_p;
typedef const struct type *const_type_p;
typedef struct options *options_p;
+
+/* Kinds of types we can understand. */
+enum typekind {
+ TYPE__NONE=0, /* Never used, so any zero-ed type is
+ invalid. */
+ TYPE_SCALAR,
+ TYPE_STRING,
+ TYPE_STRUCT,
+ TYPE_UNION,
+ TYPE_POINTER,
+ TYPE_ARRAY,
+ TYPE_LANG_STRUCT,
+ TYPE_PARAM_STRUCT
+};
+
+/* Discriminating kind for options. */
+enum info_kind {
+ INFO__NONE=0, /* Never used. */
+ INFO_STRING,
+ INFO_TYPE,
+ INFO_NESTED
+};
+
+/* A way to pass data through to the output end. */
+struct options
+{
+ struct options *next;
+ const char *name;
+ enum info_kind kind;
+ /* the union below is discriminated by the 'kind' field above. */
+ union {
+ const char* string;
+ type_p type;
+ struct nested_ptr_data* nested;
+ } 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;
+};
+
+/* A description of a type. */
+enum gc_used_enum
+{
+ GC_UNUSED=0, /* We need that zero-ed types are
+ initially unused. */
+ 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
+};
+
+
+
+#define NUM_PARAM 10
+
+/* Our type structure describes all types handled by gengtype. */
+struct type
+{
+ enum typekind kind; /* Discriminating kind. */
+ int state_number; /* State number used when writing &
+ reading the persistent state. */
+ type_p next;
+ type_p pointer_to;
+ enum gc_used_enum gc_used;
+
+ /* The following union is discriminated by the 'kind' field above. */
+ union {
+ /* when TYPE_POINTER: */
+ type_p p;
+
+ /* when TYPE_STRUCT or TYPE_UNION or TYPE_LANG_STRUCT: */
+ struct {
+ const char *tag;
+ struct fileloc styline;
+ pair_p fields;
+ options_p opt;
+ lang_bitmap bitmap;
+ type_p lang_struct;
+ } s;
+
+ /* when TYPE_SCALAR: */
+ bool scalar_is_char;
+
+ /* when TYPE_ARRAY: */
+ struct {
+ type_p p;
+ const char *len;
+ } a;
+
+ /* when TYPE_PARAM_STRUCT: */
+ struct {
+ type_p stru;
+ type_p param[NUM_PARAM];
+ struct fileloc ptyline;
+ } 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 appropriately. */
+extern struct type scalar_non_char;
+extern struct type scalar_char;
+
+
+static inline struct fileloc*
+type_lineloc (const_type_p ty)
+{
+ if (!ty) return NULL;
+ switch (ty->kind) {
+ case TYPE__NONE:
+ fatal("type_lineloc on bad none ty %p", (const void*)ty);
+ break;
+ case TYPE_STRUCT:
+ case TYPE_UNION:
+ case TYPE_LANG_STRUCT:
+ return CONST_CAST (struct fileloc*, &ty->u.s.styline);
+ case TYPE_PARAM_STRUCT:
+ return CONST_CAST (struct fileloc*, &ty->u.param_struct.ptyline);
+ case TYPE_SCALAR:
+ case TYPE_STRING:
+ case TYPE_POINTER:
+ case TYPE_ARRAY:
+ return NULL;
+ }
+ fatal("type_lineloc on corrupted type %p kd#%d", (const void*)ty, (int) ty->kind);
+ return NULL;
+}
+
+static inline input_file*
+type_ifile (const_type_p ty)
+{
+ struct fileloc* l = type_lineloc (ty);
+ if (l) return l->ifile;
+ return NULL;
+}
+
+#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)
+
+
/* Variables used to communicate between the lexer and the parser. */
extern int lexer_toplevel_done;
extern struct fileloc lexer_line;
@@ -128,7 +299,7 @@ struct outf
size_t bufused;
char *buf;
};
-typedef struct outf * outf_p;
+typedef struct outf* outf_p;
/* The list of output files. */
extern outf_p output_files;
@@ -178,7 +349,10 @@ extern type_p find_structure (const char
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_string_option (options_p next, const char* name, const char* info);
+extern options_p create_type_option (options_p next, const char* name, type_p info);
+extern options_p create_nested_option (options_p next, const char* name,
+ struct nested_ptr_data* 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,
@@ -343,7 +343,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 '*'*
@@ -381,7 +381,7 @@ type_optvalue (options_p prev, const cha
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 ')' */
@@ -431,7 +431,7 @@ option (options_p prev)
parse_error ("expected an option keyword, have %s",
print_cur_token ());
advance ();
- return create_option (prev, "", "");
+ return create_string_option (prev, "", "");
}
}