/* 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;
/* Level for verbose messages. */
int verbosity_level;
+/* We have a type count and use it to set the state_number of newly
+ allocated types to some unique negative number. */
+static int type_count;
+
/* The backup directory should be in the same file system as the
generated files, otherwise the rename(2) system call would fail.
If NULL, no backup is made when overwriting a generated file. */
/* 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);
else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
{
ls = si;
+ type_count++;
si = XCNEW (struct type);
memcpy (si, ls, sizeof (struct type));
ls->kind = TYPE_LANG_STRUCT;
ls->u.s.lang_struct = si;
ls->u.s.fields = NULL;
si->next = NULL;
+ si->state_number = -type_count;
si->pointer_to = NULL;
si->u.s.lang_struct = ls;
}
if (ls != NULL && s == NULL)
{
+ type_count++;
s = XCNEW (struct type);
+ s->state_number = -type_count;
s->next = ls->u.s.lang_struct;
ls->u.s.lang_struct = s;
s->u.s.lang_struct = ls;
if (s == NULL)
{
+ type_count++;
s = XCNEW (struct type);
+ s->state_number = -type_count;
s->next = structures;
structures = s;
}
if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion)
return s;
+ type_count++;
s = XCNEW (struct type);
s->next = structures;
+ s->state_number = -type_count;
structures = s;
s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
s->u.s.tag = name;
break;
if (res == NULL)
{
+ type_count++;
res = XCNEW (struct type);
res->kind = TYPE_PARAM_STRUCT;
res->next = param_structs;
+ res->state_number = -type_count;
param_structs = res;
res->u.param_struct.stru = t;
memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
if (!t->pointer_to)
{
type_p r = XCNEW (struct type);
+ type_count++;
+ r->state_number = -type_count;
r->kind = TYPE_POINTER;
r->u.p = t;
t->pointer_to = r;
{
type_p v;
+ type_count++;
v = XCNEW (struct type);
v->kind = TYPE_ARRAY;
+ v->state_number = -type_count;
v->u.a.p = t;
v->u.a.len = 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_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_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);
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;
}
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)
{
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) \
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 */
/* 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);
/* 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);
}
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";
}
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;
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",
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);
}
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);
}
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;
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)
{
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;
*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])
{
else
switch (t->kind)
{
+ case TYPE_NONE:
+ gcc_unreachable ();
+ break;
case TYPE_POINTER:
oprintf (of, "P");
output_mangled_typename (of, t->u.p);
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
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)
/* 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;
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;
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);
case TYPE_SCALAR:
break;
- default:
+ case TYPE_ARRAY:
gcc_unreachable ();
}
}
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)
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,
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)
{
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
{
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)
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)
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))
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);
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");
printf ("End of %s\n\n", name);
}
-/* Dumps the internal structures of gengtype. */
+/* Dumps the internal structures of gengtype. This is useful to debug
+ gengtype itself, or to understand what it does, e.g. for plugin
+ developers. */
static void
dump_everything (void)
DBGPRINTF ("inputlist %s", inputlist);
if (read_state_filename)
{
- fatal ("read state %s not implemented yet", read_state_filename);
- /* TODO: implement read state. */
+ if (inputlist)
+ fatal ("input list %s cannot be given with a read state file %s",
+ inputlist, read_state_filename);
+ read_state (read_state_filename);
+ DBGPRINT_COUNT_TYPE ("structures after read_state", structures);
+ DBGPRINT_COUNT_TYPE ("param_structs after read_state", param_structs);
}
else if (inputlist)
{
(int) i, get_input_file_name (gt_files[i]));
}
if (verbosity_level >= 1)
- printf ("%s parsed %d files\n", progname, (int) num_gt_files);
+ printf ("%s parsed %d files with %d GTY types\n",
+ progname, (int) num_gt_files, type_count);
DBGPRINT_COUNT_TYPE ("structures after parsing", structures);
DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs);
fatal ("No plugin files given in plugin mode for %s",
plugin_output_filename);
- /* Parse our plugin files. */
+ /* Parse our plugin files and augment the state. */
for (ix = 0; ix < nb_plugin_files; ix++)
parse_file (get_input_file_name (plugin_files[ix]));
hence enlarge the param_structs list of types. */
set_gc_used (variables);
- /* We should write the state here, but it is not yet implemented. */
+ /* The state at this point is read from the state input file or by
+ parsing source files and optionally augmented by parsing plugin
+ source files. Write it now. */
if (write_state_filename)
{
- fatal ("write state %s in not yet implemented", write_state_filename);
- /* TODO: implement write state. */
+ DBGPRINT_COUNT_TYPE ("structures before write_state", structures);
+ DBGPRINT_COUNT_TYPE ("param_structs before write_state", param_structs);
+
+ if (hit_error)
+ fatal ("didn't write state file %s after errors",
+ write_state_filename);
+
+ DBGPRINTF ("before write_state %s", write_state_filename);
+ write_state (write_state_filename);
+
+ if (do_dump)
+ dump_everything ();
+
+ /* After having written the state file we return immediately to
+ avoid generating any output file. */
+ if (hit_error)
+ return 1;
+ else
+ return 0;
}