| Index: gcc/gcc/gengtype.c
|
| diff --git a/gcc/gcc/gengtype.c b/gcc/gcc/gengtype.c
|
| index 02923a952d9abbb1a103be3d27263b80e4a8f2b6..91f3f57d7c9a77b6592f9161cfe90d6b91542c39 100644
|
| --- a/gcc/gcc/gengtype.c
|
| +++ b/gcc/gcc/gengtype.c
|
| @@ -1,5 +1,5 @@
|
| /* Process source files and output type information.
|
| - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
| + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
| Free Software Foundation, Inc.
|
|
|
| This file is part of GCC.
|
| @@ -128,18 +128,25 @@ typedef struct outf * outf_p;
|
|
|
| /* An output file, suitable for definitions, that can see declarations
|
| made in INPUT_FILE and is linked into every language that uses
|
| - INPUT_FILE. */
|
| + INPUT_FILE. May return NULL in plugin mode. */
|
| extern outf_p get_output_file_with_visibility
|
| (const char *input_file);
|
| const char *get_output_file_name (const char *);
|
|
|
| -/* Print, like fprintf, to O. */
|
| +/* Print, like fprintf, to O. No-op if O is NULL. */
|
| static void oprintf (outf_p o, const char *S, ...)
|
| ATTRIBUTE_PRINTF_2;
|
|
|
| /* The list of output files. */
|
| static outf_p output_files;
|
|
|
| +/* The plugin input files and their number; in that case only
|
| + a single file is produced. */
|
| +static char** plugin_files;
|
| +static size_t nb_plugin_files;
|
| +/* the generated plugin output name & file */
|
| +static outf_p plugin_output;
|
| +
|
| /* The output header file that is included into pretty much every
|
| source file. */
|
| static outf_p header_file;
|
| @@ -274,7 +281,7 @@ measure_input_list (FILE *list)
|
| int c;
|
| bool atbol = true;
|
| num_lang_dirs = 0;
|
| - num_gt_files = 0;
|
| + num_gt_files = plugin_files ? nb_plugin_files : 0;
|
| while ((c = getc (list)) != EOF)
|
| {
|
| n++;
|
| @@ -455,6 +462,13 @@ read_input_list (const char *listname)
|
| /* Update the global counts now that we know accurately how many
|
| things there are. (We do not bother resizing the arrays down.) */
|
| num_lang_dirs = langno;
|
| + /* Add the plugin files if provided. */
|
| + if (plugin_files)
|
| + {
|
| + size_t i;
|
| + for (i = 0; i < nb_plugin_files; i++)
|
| + gt_files[nfiles++] = plugin_files[i];
|
| + }
|
| num_gt_files = nfiles;
|
| }
|
|
|
| @@ -962,9 +976,11 @@ write_rtx_next (void)
|
| {
|
| outf_p f = get_output_file_with_visibility (NULL);
|
| int i;
|
| + if (!f)
|
| + return;
|
|
|
| oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
|
| - oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
|
| + oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
|
| for (i = 0; i < NUM_RTX_CODE; i++)
|
| if (rtx_next_new[i] == -1)
|
| oprintf (f, " 0,\n");
|
| @@ -1016,6 +1032,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
|
| switch (c)
|
| {
|
| case NOTE_INSN_MAX:
|
| + case NOTE_INSN_DELETED_LABEL:
|
| note_flds = create_field (note_flds, &string_type, "rt_str");
|
| break;
|
|
|
| @@ -1100,6 +1117,8 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
|
| t = scalar_tp, subname = "rt_int";
|
| else if (i == VALUE && aindex == 0)
|
| t = scalar_tp, subname = "rt_int";
|
| + else if (i == DEBUG_EXPR && aindex == 0)
|
| + t = tree_tp, subname = "rt_tree";
|
| else if (i == REG && aindex == 1)
|
| t = scalar_tp, subname = "rt_int";
|
| else if (i == REG && aindex == 2)
|
| @@ -1374,7 +1393,7 @@ set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
|
| &length, &skip, &nested_ptr);
|
|
|
| if (nested_ptr && f->type->kind == TYPE_POINTER)
|
| - set_gc_used_type (nested_ptr, GC_POINTED_TO,
|
| + set_gc_used_type (nested_ptr, GC_POINTED_TO,
|
| pass_param ? param : NULL);
|
| else if (length && f->type->kind == TYPE_POINTER)
|
| set_gc_used_type (f->type->u.p, GC_USED, NULL);
|
| @@ -1448,7 +1467,7 @@ static outf_p
|
| create_file (const char *name, const char *oname)
|
| {
|
| static const char *const hdr[] = {
|
| - " Copyright (C) 2004, 2007 Free Software Foundation, Inc.\n",
|
| + " Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n",
|
| "\n",
|
| "This file is part of GCC.\n",
|
| "\n",
|
| @@ -1471,6 +1490,8 @@ create_file (const char *name, const char *oname)
|
| outf_p f;
|
| size_t i;
|
|
|
| + gcc_assert (name != NULL);
|
| + gcc_assert (oname != NULL);
|
| f = XCNEW (struct outf);
|
| f->next = output_files;
|
| f->name = oname;
|
| @@ -1482,7 +1503,7 @@ create_file (const char *name, const char *oname)
|
| return f;
|
| }
|
|
|
| -/* Print, like fprintf, to O.
|
| +/* Print, like fprintf, to O.
|
| N.B. You might think this could be implemented more efficiently
|
| with vsnprintf(). Unfortunately, there are C libraries that
|
| provide that function but without the C99 semantics for its return
|
| @@ -1494,6 +1515,11 @@ oprintf (outf_p o, const char *format, ...)
|
| size_t slength;
|
| va_list ap;
|
|
|
| + /* In plugin mode, the O could be a NULL pointer, so avoid crashing
|
| + in that case. */
|
| + if (!o)
|
| + return;
|
| +
|
| va_start (ap, format);
|
| slength = vasprintf (&s, format, ap);
|
| if (s == NULL || (int)slength < 0)
|
| @@ -1523,6 +1549,9 @@ open_base_files (void)
|
| {
|
| size_t i;
|
|
|
| + if (nb_plugin_files > 0 && plugin_files)
|
| + return;
|
| +
|
| header_file = create_file ("GCC", "gtype-desc.h");
|
|
|
| base_files = XNEWVEC (outf_p, num_lang_dirs);
|
| @@ -1535,13 +1564,14 @@ open_base_files (void)
|
| {
|
| /* The order of files here matters very much. */
|
| static const char *const ifiles [] = {
|
| - "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
|
| + "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
|
| "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
|
| "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
|
| "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
|
| "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
|
| "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
|
| - "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h", NULL
|
| + "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
|
| + "target.h", "ipa-prop.h", NULL
|
| };
|
| const char *const *ifp;
|
| outf_p gtype_desc_c;
|
| @@ -1563,7 +1593,7 @@ static const char *
|
| get_file_realbasename (const char *f)
|
| {
|
| const char * lastslash = strrchr (f, '/');
|
| -
|
| +
|
| return (lastslash != NULL) ? lastslash + 1 : f;
|
| }
|
|
|
| @@ -1605,7 +1635,7 @@ get_prefix_langdir_index (const char *f)
|
| {
|
| const char * langdir = lang_dir_names [lang_index];
|
| size_t langdir_len = strlen (langdir);
|
| -
|
| +
|
| if (f_len > langdir_len
|
| && IS_DIR_SEPARATOR (f[langdir_len])
|
| && memcmp (f, langdir, langdir_len) == 0)
|
| @@ -1646,7 +1676,7 @@ get_file_gtfilename (const char *f)
|
|
|
| const char *basename = get_file_realbasename (f);
|
| const char *langdir = get_file_langdir (f);
|
| -
|
| +
|
| char * result =
|
| (langdir ? xasprintf ("gt-%s-%s", langdir, basename)
|
| : xasprintf ("gt-%s", basename));
|
| @@ -1685,6 +1715,18 @@ get_output_file_with_visibility (const char *input_file)
|
| if (input_file == NULL)
|
| input_file = "system.h";
|
|
|
| + /* In plugin mode, return NULL unless the input_file is one of the
|
| + plugin_files. */
|
| + if (plugin_files)
|
| + {
|
| + size_t i;
|
| + for (i = 0; i < nb_plugin_files; i++)
|
| + if (strcmp (input_file, plugin_files[i]) == 0)
|
| + return plugin_output;
|
| +
|
| + return NULL;
|
| + }
|
| +
|
| /* Determine the output file name. */
|
| basename = get_file_basename (input_file);
|
|
|
| @@ -1693,7 +1735,7 @@ get_output_file_with_visibility (const char *input_file)
|
| || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
|
| || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
|
| {
|
| - output_name = get_file_gtfilename (input_file);
|
| + output_name = get_file_gtfilename (input_file);
|
| for_name = basename;
|
| }
|
| /* Some headers get used by more than one front-end; hence, it
|
| @@ -1703,6 +1745,8 @@ get_output_file_with_visibility (const char *input_file)
|
| headers with source files (and their special purpose gt-*.h headers). */
|
| else if (strcmp (basename, "c-common.h") == 0)
|
| output_name = "gt-c-common.h", for_name = "c-common.c";
|
| + else if (strcmp (basename, "c-lang.h") == 0)
|
| + output_name = "gt-c-decl.h", for_name = "c-decl.c";
|
| else if (strcmp (basename, "c-tree.h") == 0)
|
| output_name = "gt-c-decl.h", for_name = "c-decl.c";
|
| else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
|
| @@ -1717,7 +1761,7 @@ get_output_file_with_visibility (const char *input_file)
|
| else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
|
| && strcmp (basename + 5, "objc-act.h") == 0)
|
| output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
|
| - else
|
| + else
|
| {
|
| int lang_index = get_prefix_langdir_index (basename);
|
|
|
| @@ -1736,6 +1780,7 @@ get_output_file_with_visibility (const char *input_file)
|
| /* If not, create it. */
|
| r = create_file (for_name, output_name);
|
|
|
| + gcc_assert (r && r->name);
|
| return r;
|
| }
|
|
|
| @@ -1746,7 +1791,36 @@ get_output_file_with_visibility (const char *input_file)
|
| const char *
|
| get_output_file_name (const char *input_file)
|
| {
|
| - return get_output_file_with_visibility (input_file)->name;
|
| + outf_p o = get_output_file_with_visibility (input_file);
|
| + if (o)
|
| + return o->name;
|
| + return NULL;
|
| +}
|
| +
|
| +/* Check if existing file is equal to the in memory buffer. */
|
| +
|
| +static bool
|
| +is_file_equal (outf_p of)
|
| +{
|
| + FILE *newfile = fopen (of->name, "r");
|
| + size_t i;
|
| + bool equal;
|
| + if (newfile == NULL)
|
| + return false;
|
| +
|
| + equal = true;
|
| + for (i = 0; i < of->bufused; i++)
|
| + {
|
| + int ch;
|
| + ch = fgetc (newfile);
|
| + if (ch == EOF || ch != (unsigned char) of->buf[i])
|
| + {
|
| + equal = false;
|
| + break;
|
| + }
|
| + }
|
| + fclose (newfile);
|
| + return equal;
|
| }
|
|
|
| /* Copy the output to its final destination,
|
| @@ -1759,35 +1833,20 @@ close_output_files (void)
|
|
|
| for (of = output_files; of; of = of->next)
|
| {
|
| - FILE * newfile;
|
| -
|
| - newfile = fopen (of->name, "r");
|
| - if (newfile != NULL )
|
| - {
|
| - int no_write_p;
|
| - size_t i;
|
| -
|
| - for (i = 0; i < of->bufused; i++)
|
| - {
|
| - int ch;
|
| - ch = fgetc (newfile);
|
| - if (ch == EOF || ch != (unsigned char) of->buf[i])
|
| - break;
|
| - }
|
| - no_write_p = i == of->bufused && fgetc (newfile) == EOF;
|
| - fclose (newfile);
|
|
|
| - if (no_write_p)
|
| - continue;
|
| - }
|
| -
|
| - newfile = fopen (of->name, "w");
|
| - if (newfile == NULL)
|
| - fatal ("opening output file %s: %s", of->name, strerror (errno));
|
| - if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
|
| - fatal ("writing output file %s: %s", of->name, strerror (errno));
|
| - if (fclose (newfile) != 0)
|
| - fatal ("closing output file %s: %s", of->name, strerror (errno));
|
| + if (!is_file_equal(of))
|
| + {
|
| + FILE *newfile = fopen (of->name, "w");
|
| + if (newfile == NULL)
|
| + fatal ("opening output file %s: %s", of->name, strerror (errno));
|
| + if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
|
| + fatal ("writing output file %s: %s", of->name, strerror (errno));
|
| + if (fclose (newfile) != 0)
|
| + fatal ("closing output file %s: %s", of->name, strerror (errno));
|
| + }
|
| + free(of->buf);
|
| + of->buf = NULL;
|
| + of->bufused = of->buflength = 0;
|
| }
|
| }
|
|
|
| @@ -1831,14 +1890,16 @@ static void write_func_for_structure
|
| const struct write_types_data *wtd);
|
| static void write_types_process_field
|
| (type_p f, const struct walk_type_data *d);
|
| -static void write_types (type_p structures,
|
| +static void write_types (outf_p output_header,
|
| + type_p structures,
|
| type_p param_structs,
|
| const struct write_types_data *wtd);
|
| static void write_types_local_process_field
|
| (type_p f, const struct walk_type_data *d);
|
| static void write_local_func_for_structure
|
| (type_p orig_s, type_p s, type_p * param);
|
| -static void write_local (type_p structures,
|
| +static void write_local (outf_p output_header,
|
| + type_p structures,
|
| type_p param_structs);
|
| static void write_enum_defn (type_p structures, type_p param_structs);
|
| static int contains_scalar_p (type_p t);
|
| @@ -1847,10 +1908,10 @@ static void finish_root_table (struct flist *flp, const char *pfx,
|
| const char *tname, const char *lastname,
|
| const char *name);
|
| static void write_root (outf_p , pair_p, type_p, const char *, int,
|
| - struct fileloc *, const char *);
|
| + struct fileloc *, const char *, bool);
|
| static void write_array (outf_p f, pair_p v,
|
| const struct write_types_data *wtd);
|
| -static void write_roots (pair_p);
|
| +static void write_roots (pair_p, bool);
|
|
|
| /* Parameters for walk_type. */
|
|
|
| @@ -2111,9 +2172,9 @@ walk_type (type_p t, struct walk_type_data *d)
|
| d->indent += 2;
|
| d->val = xasprintf ("x%d", d->counter++);
|
| oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
|
| - (nested_ptr_d->type->kind == TYPE_UNION
|
| - ? "union" : "struct"),
|
| - nested_ptr_d->type->u.s.tag,
|
| + (nested_ptr_d->type->kind == TYPE_UNION
|
| + ? "union" : "struct"),
|
| + nested_ptr_d->type->u.s.tag,
|
| d->fn_wants_lvalue ? "" : "const ",
|
| d->val);
|
| oprintf (d->of, "%*s", d->indent + 2, "");
|
| @@ -2201,7 +2262,7 @@ walk_type (type_p t, struct walk_type_data *d)
|
| else
|
| oprintf (d->of, "%s", t->u.a.len);
|
| oprintf (d->of, ");\n");
|
| -
|
| +
|
| oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
|
| d->indent, "",
|
| loopcounter, loopcounter, loopcounter, loopcounter);
|
| @@ -2653,12 +2714,15 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
|
| /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
|
|
|
| static void
|
| -write_types (type_p structures, type_p param_structs,
|
| +write_types (outf_p output_header, type_p structures, type_p param_structs,
|
| const struct write_types_data *wtd)
|
| {
|
| type_p s;
|
|
|
| - oprintf (header_file, "\n/* %s*/\n", wtd->comment);
|
| + oprintf (output_header, "\n/* %s*/\n", wtd->comment);
|
| + /* We first emit the macros and the declarations. Functions' code is
|
| + emitted afterwards. This is needed in plugin mode. */
|
| + oprintf (output_header, "/* macros and declarations */\n");
|
| for (s = structures; s; s = s->next)
|
| if (s->gc_used == GC_POINTED_TO
|
| || s->gc_used == GC_MAYBE_POINTED_TO)
|
| @@ -2669,13 +2733,13 @@ write_types (type_p structures, type_p param_structs,
|
| && s->u.s.line.file == NULL)
|
| continue;
|
|
|
| - oprintf (header_file, "#define gt_%s_", wtd->prefix);
|
| - output_mangled_typename (header_file, s);
|
| - oprintf (header_file, "(X) do { \\\n");
|
| - oprintf (header_file,
|
| + oprintf (output_header, "#define gt_%s_", wtd->prefix);
|
| + output_mangled_typename (output_header, s);
|
| + oprintf (output_header, "(X) do { \\\n");
|
| + oprintf (output_header,
|
| " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
|
| s->u.s.tag);
|
| - oprintf (header_file,
|
| + oprintf (output_header,
|
| " } while (0)\n");
|
|
|
| for (opt = s->u.s.opt; opt; opt = opt->next)
|
| @@ -2685,7 +2749,7 @@ write_types (type_p structures, type_p param_structs,
|
| if (t->kind == TYPE_STRUCT
|
| || t->kind == TYPE_UNION
|
| || t->kind == TYPE_LANG_STRUCT)
|
| - oprintf (header_file,
|
| + oprintf (output_header,
|
| "#define gt_%sx_%s gt_%sx_%s\n",
|
| wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
|
| else
|
| @@ -2697,7 +2761,7 @@ write_types (type_p structures, type_p param_structs,
|
| continue;
|
|
|
| /* Declare the marker procedure only once. */
|
| - oprintf (header_file,
|
| + oprintf (output_header,
|
| "extern void gt_%sx_%s (void *);\n",
|
| wtd->prefix, s->u.s.tag);
|
|
|
| @@ -2707,27 +2771,17 @@ write_types (type_p structures, type_p param_structs,
|
| s->u.s.tag);
|
| continue;
|
| }
|
| -
|
| - if (s->kind == TYPE_LANG_STRUCT)
|
| - {
|
| - type_p ss;
|
| - for (ss = s->u.s.lang_struct; ss; ss = ss->next)
|
| - write_func_for_structure (s, ss, NULL, wtd);
|
| - }
|
| - else
|
| - write_func_for_structure (s, s, NULL, wtd);
|
| }
|
|
|
| for (s = param_structs; s; s = s->next)
|
| if (s->gc_used == GC_POINTED_TO)
|
| {
|
| - type_p * param = s->u.param_struct.param;
|
| type_p stru = s->u.param_struct.stru;
|
|
|
| /* Declare the marker procedure. */
|
| - oprintf (header_file, "extern void gt_%s_", wtd->prefix);
|
| - output_mangled_typename (header_file, s);
|
| - oprintf (header_file, " (void *);\n");
|
| + oprintf (output_header, "extern void gt_%s_", wtd->prefix);
|
| + output_mangled_typename (output_header, s);
|
| + oprintf (output_header, " (void *);\n");
|
|
|
| if (stru->u.s.line.file == NULL)
|
| {
|
| @@ -2735,7 +2789,41 @@ write_types (type_p structures, type_p param_structs,
|
| s->u.s.tag);
|
| continue;
|
| }
|
| + }
|
|
|
| + /* At last we emit the functions code. */
|
| + oprintf (output_header, "\n/* functions code */\n");
|
| + for (s = structures; s; s = s->next)
|
| + if (s->gc_used == GC_POINTED_TO
|
| + || s->gc_used == GC_MAYBE_POINTED_TO)
|
| + {
|
| + options_p opt;
|
| +
|
| + if (s->gc_used == GC_MAYBE_POINTED_TO
|
| + && s->u.s.line.file == NULL)
|
| + continue;
|
| + for (opt = s->u.s.opt; opt; opt = opt->next)
|
| + if (strcmp (opt->name, "ptr_alias") == 0)
|
| + break;
|
| + if (opt)
|
| + continue;
|
| +
|
| + if (s->kind == TYPE_LANG_STRUCT)
|
| + {
|
| + type_p ss;
|
| + for (ss = s->u.s.lang_struct; ss; ss = ss->next)
|
| + write_func_for_structure (s, ss, NULL, wtd);
|
| + }
|
| + else
|
| + write_func_for_structure (s, s, NULL, wtd);
|
| + }
|
| + for (s = param_structs; s; s = s->next)
|
| + if (s->gc_used == GC_POINTED_TO)
|
| + {
|
| + type_p *param = s->u.param_struct.param;
|
| + type_p stru = s->u.param_struct.stru;
|
| + if (stru->u.s.line.file == NULL)
|
| + continue;
|
| if (stru->kind == TYPE_LANG_STRUCT)
|
| {
|
| type_p ss;
|
| @@ -2811,7 +2899,6 @@ write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
|
|
|
| memset (&d, 0, sizeof (d));
|
| d.of = get_output_file_with_visibility (fn);
|
| -
|
| d.process_field = write_types_local_process_field;
|
| d.opt = s->u.s.opt;
|
| d.line = &s->u.s.line;
|
| @@ -2843,11 +2930,13 @@ write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
|
| /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
|
|
|
| static void
|
| -write_local (type_p structures, type_p param_structs)
|
| +write_local (outf_p output_header, type_p structures, type_p param_structs)
|
| {
|
| type_p s;
|
|
|
| - oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
|
| + if (!output_header)
|
| + return;
|
| + oprintf (output_header, "\n/* Local pointer-walking routines. */\n");
|
| for (s = structures; s; s = s->next)
|
| if (s->gc_used == GC_POINTED_TO
|
| || s->gc_used == GC_MAYBE_POINTED_TO)
|
| @@ -2865,11 +2954,11 @@ write_local (type_p structures, type_p param_structs)
|
| || t->kind == TYPE_UNION
|
| || t->kind == TYPE_LANG_STRUCT)
|
| {
|
| - oprintf (header_file, "#define gt_pch_p_");
|
| - output_mangled_typename (header_file, s);
|
| - oprintf (header_file, " gt_pch_p_");
|
| - output_mangled_typename (header_file, t);
|
| - oprintf (header_file, "\n");
|
| + oprintf (output_header, "#define gt_pch_p_");
|
| + output_mangled_typename (output_header, s);
|
| + oprintf (output_header, " gt_pch_p_");
|
| + output_mangled_typename (output_header, t);
|
| + oprintf (output_header, "\n");
|
| }
|
| else
|
| error_at_line (&s->u.s.line,
|
| @@ -2880,9 +2969,9 @@ write_local (type_p structures, type_p param_structs)
|
| continue;
|
|
|
| /* Declare the marker procedure only once. */
|
| - oprintf (header_file, "extern void gt_pch_p_");
|
| - output_mangled_typename (header_file, s);
|
| - oprintf (header_file,
|
| + oprintf (output_header, "extern void gt_pch_p_");
|
| + output_mangled_typename (output_header, s);
|
| + oprintf (output_header,
|
| "\n (void *, void *, gt_pointer_operator, void *);\n");
|
|
|
| if (s->kind == TYPE_LANG_STRUCT)
|
| @@ -2902,9 +2991,9 @@ write_local (type_p structures, type_p param_structs)
|
| type_p stru = s->u.param_struct.stru;
|
|
|
| /* Declare the marker procedure. */
|
| - oprintf (header_file, "extern void gt_pch_p_");
|
| - output_mangled_typename (header_file, s);
|
| - oprintf (header_file,
|
| + oprintf (output_header, "extern void gt_pch_p_");
|
| + output_mangled_typename (output_header, s);
|
| + oprintf (output_header,
|
| "\n (void *, void *, gt_pointer_operator, void *);\n");
|
|
|
| if (stru->u.s.line.file == NULL)
|
| @@ -2932,6 +3021,8 @@ write_enum_defn (type_p structures, type_p param_structs)
|
| {
|
| type_p s;
|
|
|
| + if (!header_file)
|
| + return;
|
| oprintf (header_file, "\n/* Enumeration of types known. */\n");
|
| oprintf (header_file, "enum gt_types_enum {\n");
|
| for (s = structures; s; s = s->next)
|
| @@ -2982,6 +3073,8 @@ static void
|
| put_mangled_filename (outf_p f, const char *fn)
|
| {
|
| const char *name = get_output_file_name (fn);
|
| + if (!f || !name)
|
| + return;
|
| for (; *name != 0; name++)
|
| if (ISALNUM (*name))
|
| oprintf (f, "%c", *name);
|
| @@ -3006,7 +3099,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
|
| oprintf (fli2->f, "};\n\n");
|
| }
|
|
|
| - for (fli2 = flp; fli2; fli2 = fli2->next)
|
| + for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
|
| if (fli2->started_p)
|
| {
|
| lang_bitmap bitmap = get_lang_bitmap (fli2->name);
|
| @@ -3025,9 +3118,9 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
|
|
|
| {
|
| size_t fnum;
|
| - for (fnum = 0; fnum < num_lang_dirs; fnum++)
|
| + for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
|
| oprintf (base_files [fnum],
|
| - "const struct %s * const %s[] = {\n",
|
| + "EXPORTED_CONST struct %s * const %s[] = {\n",
|
| tname, name);
|
| }
|
|
|
| @@ -3040,7 +3133,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
|
|
|
| fli2->started_p = 0;
|
|
|
| - for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
|
| + for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
|
| if (bitmap & 1)
|
| {
|
| oprintf (base_files[fnum], " gt_%s_", pfx);
|
| @@ -3051,7 +3144,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
|
|
|
| {
|
| size_t fnum;
|
| - for (fnum = 0; fnum < num_lang_dirs; fnum++)
|
| + for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
|
| {
|
| oprintf (base_files[fnum], " NULL\n");
|
| oprintf (base_files[fnum], "};\n");
|
| @@ -3066,7 +3159,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
|
|
|
| static void
|
| write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
| - struct fileloc *line, const char *if_marked)
|
| + struct fileloc *line, const char *if_marked, bool emit_pch)
|
| {
|
| switch (type->kind)
|
| {
|
| @@ -3122,7 +3215,7 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
| newname = xasprintf ("%s.%s.%s",
|
| name, fld->name, validf->name);
|
| write_root (f, v, validf->type, newname, 0, line,
|
| - if_marked);
|
| + if_marked, emit_pch);
|
| free (newname);
|
| }
|
| }
|
| @@ -3134,7 +3227,8 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
| {
|
| char *newname;
|
| newname = xasprintf ("%s.%s", name, fld->name);
|
| - write_root (f, v, fld->type, newname, 0, line, if_marked);
|
| + write_root (f, v, fld->type, newname, 0, line, if_marked,
|
| + emit_pch);
|
| free (newname);
|
| }
|
| }
|
| @@ -3145,7 +3239,8 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
| {
|
| char *newname;
|
| newname = xasprintf ("%s[0]", name);
|
| - write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
|
| + write_root (f, v, type->u.a.p, newname, has_length, line, if_marked,
|
| + emit_pch);
|
| free (newname);
|
| }
|
| break;
|
| @@ -3174,20 +3269,31 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
| if (! has_length && UNION_OR_STRUCT_P (tp))
|
| {
|
| oprintf (f, " >_ggc_mx_%s,\n", tp->u.s.tag);
|
| - oprintf (f, " >_pch_nx_%s", tp->u.s.tag);
|
| + if (emit_pch)
|
| + oprintf (f, " >_pch_nx_%s", tp->u.s.tag);
|
| + else
|
| + oprintf (f, " NULL");
|
| }
|
| else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
|
| {
|
| oprintf (f, " >_ggc_m_");
|
| output_mangled_typename (f, tp);
|
| - oprintf (f, ",\n >_pch_n_");
|
| - output_mangled_typename (f, tp);
|
| + if (emit_pch)
|
| + {
|
| + oprintf (f, ",\n >_pch_n_");
|
| + output_mangled_typename (f, tp);
|
| + }
|
| + else
|
| + oprintf (f, ",\n NULL");
|
| }
|
| else if (has_length
|
| && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
|
| {
|
| oprintf (f, " >_ggc_ma_%s,\n", name);
|
| - oprintf (f, " >_pch_na_%s", name);
|
| + if (emit_pch)
|
| + oprintf (f, " >_pch_na_%s", name);
|
| + else
|
| + oprintf (f, " NULL");
|
| }
|
| else
|
| {
|
| @@ -3276,7 +3382,7 @@ write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
|
| /* Output a table describing the locations and types of VARIABLES. */
|
|
|
| static void
|
| -write_roots (pair_p variables)
|
| +write_roots (pair_p variables, bool emit_pch)
|
| {
|
| pair_p v;
|
| struct flist *flp = NULL;
|
| @@ -3308,7 +3414,7 @@ write_roots (pair_p variables)
|
| v->name, o->name);
|
|
|
| for (fli = flp; fli; fli = fli->next)
|
| - if (fli->f == f)
|
| + if (fli->f == f && f)
|
| break;
|
| if (fli == NULL)
|
| {
|
| @@ -3317,6 +3423,7 @@ write_roots (pair_p variables)
|
| fli->next = flp;
|
| fli->started_p = 0;
|
| fli->name = v->line.file;
|
| + gcc_assert(fli->name);
|
| flp = fli;
|
|
|
| oprintf (f, "\n/* GC roots. */\n\n");
|
| @@ -3358,12 +3465,12 @@ write_roots (pair_p variables)
|
| {
|
| fli->started_p = 1;
|
|
|
| - oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
|
| + oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
|
| put_mangled_filename (f, v->line.file);
|
| oprintf (f, "[] = {\n");
|
| }
|
|
|
| - write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
|
| + write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
|
| }
|
|
|
| finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
|
| @@ -3392,7 +3499,7 @@ write_roots (pair_p variables)
|
| {
|
| fli->started_p = 1;
|
|
|
| - oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
|
| + oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
|
| put_mangled_filename (f, v->line.file);
|
| oprintf (f, "[] = {\n");
|
| }
|
| @@ -3436,18 +3543,21 @@ write_roots (pair_p variables)
|
| {
|
| fli->started_p = 1;
|
|
|
| - oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
|
| + oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
|
| put_mangled_filename (f, v->line.file);
|
| oprintf (f, "[] = {\n");
|
| }
|
|
|
| write_root (f, v, v->type->u.p->u.param_struct.param[0],
|
| - v->name, length_p, &v->line, if_marked);
|
| + v->name, length_p, &v->line, if_marked, emit_pch);
|
| }
|
|
|
| finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
|
| "gt_ggc_cache_rtab");
|
|
|
| + if (!emit_pch)
|
| + return;
|
| +
|
| for (v = variables; v; v = v->next)
|
| {
|
| outf_p f = get_output_file_with_visibility (v->line.file);
|
| @@ -3472,12 +3582,12 @@ write_roots (pair_p variables)
|
| {
|
| fli->started_p = 1;
|
|
|
| - oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
|
| + oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
|
| put_mangled_filename (f, v->line.file);
|
| oprintf (f, "[] = {\n");
|
| }
|
|
|
| - write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
|
| + write_root (f, v, v->type, v->name, length_p, &v->line, NULL, emit_pch);
|
| }
|
|
|
| finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
|
| @@ -3508,7 +3618,7 @@ write_roots (pair_p variables)
|
| {
|
| fli->started_p = 1;
|
|
|
| - oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
|
| + oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
|
| put_mangled_filename (f, v->line.file);
|
| oprintf (f, "[] = {\n");
|
| }
|
| @@ -3585,17 +3695,42 @@ main (int argc, char **argv)
|
| {
|
| size_t i;
|
| static struct fileloc pos = { this_file, 0 };
|
| -
|
| + char* inputlist = 0;
|
| + outf_p output_header;
|
| + char* plugin_output_filename = NULL;
|
| /* fatal uses this */
|
| progname = "gengtype";
|
|
|
| - if (argc != 3)
|
| - fatal ("usage: gengtype srcdir input-list");
|
| + if (argc >= 6 && !strcmp (argv[1], "-P"))
|
| + {
|
| + plugin_output_filename = argv[2];
|
| + plugin_output = create_file ("GCC", plugin_output_filename);
|
| + srcdir = argv[3];
|
| + inputlist = argv[4];
|
| + nb_plugin_files = argc - 5;
|
| + plugin_files = XCNEWVEC (char *, nb_plugin_files);
|
| + for (i = 0; i < nb_plugin_files; i++)
|
| + {
|
| + /* Place an all zero lang_bitmap before the plugin file
|
| + name. */
|
| + char *name = argv[i + 5];
|
| + int len = strlen(name) + 1 + sizeof (lang_bitmap);
|
| + plugin_files[i] = XCNEWVEC (char, len) + sizeof (lang_bitmap);
|
| + strcpy (plugin_files[i], name);
|
| + }
|
| + }
|
| + else if (argc == 3)
|
| + {
|
| + srcdir = argv[1];
|
| + inputlist = argv[2];
|
| + }
|
| + else
|
| + fatal ("usage: gengtype [-P pluginout.h] srcdir input-list "
|
| + "[file1 file2 ... fileN]");
|
|
|
| - srcdir = argv[1];
|
| srcdir_len = strlen (srcdir);
|
|
|
| - read_input_list (argv[2]);
|
| + read_input_list (inputlist);
|
| if (hit_error)
|
| return 1;
|
|
|
| @@ -3610,6 +3745,7 @@ main (int argc, char **argv)
|
| do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
|
| do_scalar_typedef ("FIXED_VALUE_TYPE", &pos); pos.line++;
|
| do_scalar_typedef ("double_int", &pos); pos.line++;
|
| + do_scalar_typedef ("uint64_t", &pos); pos.line++;
|
| do_scalar_typedef ("uint8", &pos); pos.line++;
|
| do_scalar_typedef ("jword", &pos); pos.line++;
|
| do_scalar_typedef ("JCF_u2", &pos); pos.line++;
|
| @@ -3626,13 +3762,24 @@ main (int argc, char **argv)
|
|
|
| open_base_files ();
|
| write_enum_defn (structures, param_structs);
|
| - write_types (structures, param_structs, &ggc_wtd);
|
| - write_types (structures, param_structs, &pch_wtd);
|
| - write_local (structures, param_structs);
|
| - write_roots (variables);
|
| + output_header = plugin_output ? plugin_output : header_file;
|
| + write_types (output_header, structures, param_structs, &ggc_wtd);
|
| + if (plugin_files == NULL)
|
| + {
|
| + write_types (header_file, structures, param_structs, &pch_wtd);
|
| + write_local (header_file, structures, param_structs);
|
| + }
|
| + write_roots (variables, plugin_files == NULL);
|
| write_rtx_next ();
|
| close_output_files ();
|
|
|
| + if (plugin_files)
|
| + {
|
| + for (i = 0; i < nb_plugin_files; i++)
|
| + free (plugin_files[i] - sizeof (lang_bitmap));
|
| + free (plugin_files);
|
| + }
|
| +
|
| if (hit_error)
|
| return 1;
|
| return 0;
|
|
|