Commit bd117bb6 by Basile Starynkevitch Committed by Basile Starynkevitch

plugins.texi (Interacting with the GCC Garbage Collector): Mention the plugin mode of gengtype.

2009-06-16  Basile Starynkevitch  <basile@starynkevitch.net>

	* gcc/doc/plugins.texi (Interacting with the GCC Garbage Collector):
	Mention the plugin mode of gengtype.
	* gcc/doc/gty.texi (Source Files Containing Type Information):
	Likewise.
	* gcc/gengtype.c: Updated copyright.
	(plugin_files, nb_plugin_files) Added new static variables.
	(measure_input_list) Care about plugin_files.
	(write_rtx_next): Added early return in plugin mode.
	(create_file): Updated copyright year in generated file. Added
	asserts.
	(oprintf): Added early return if NULL outf.
	(get_output_file_with_visibility): Care of plugin_files.
	(get_output_file_name): May return null.
	(write_local): Added early return.
	(put_mangled_filename): Ditto.
	(finish_root_table): Added check for base_files.
	(write_roots): Care about null when plugins.
	(main): Added plugin mode.

From-SVN: r148515
parent e1b7793c
2009-06-16 Basile Starynkevitch <basile@starynkevitch.net>
* doc/plugins.texi (Interacting with the GCC Garbage Collector):
Mention the plugin mode of gengtype.
* doc/gty.texi (Source Files Containing Type Information):
Likewise.
* gengtype.c: Updated copyright.
(plugin_files, nb_plugin_files) Added new static variables.
(measure_input_list) Care about plugin_files.
(write_rtx_next): Added early return in plugin mode.
(create_file): Updated copyright year in generated file. Added
asserts.
(oprintf): Added early return if NULL outf.
(get_output_file_with_visibility): Care of plugin_files.
(get_output_file_name): May return null.
(write_local): Added early return.
(put_mangled_filename): Ditto.
(finish_root_table): Added check for base_files.
(write_roots): Care about null when plugins.
(main): Added plugin mode.
2009-06-15 Ian Lance Taylor <iant@google.com> 2009-06-15 Ian Lance Taylor <iant@google.com>
* df-problems.c (df_simulate_one_insn_forwards): Fix braces in * df-problems.c (df_simulate_one_insn_forwards): Fix braces in
......
...@@ -450,6 +450,14 @@ For language frontends, there is another file that needs to be included ...@@ -450,6 +450,14 @@ For language frontends, there is another file that needs to be included
somewhere. It will be called @file{gtype-@var{lang}.h}, where somewhere. It will be called @file{gtype-@var{lang}.h}, where
@var{lang} is the name of the subdirectory the language is contained in. @var{lang} is the name of the subdirectory the language is contained in.
Plugins can add additional root tables. Run the @code{gengtype}
utility in plugin mode as @code{gengtype -p @var{source-dir}
@var{file-list} @var{plugin*.c}} with your plugin files
@var{plugin*.c} using @code{GTY} to generate the corresponding
@var{gt-plugin*.h} files. The GCC build tree is needed to be present in
that mode.
@node Invoking the garbage collector @node Invoking the garbage collector
@section How to invoke the garbage collector @section How to invoke the garbage collector
@cindex garbage collector, invocation @cindex garbage collector, invocation
......
...@@ -198,13 +198,15 @@ Some plugins may need to have GGC mark additional data. This can be ...@@ -198,13 +198,15 @@ Some plugins may need to have GGC mark additional data. This can be
done by registering a callback (called with a null @code{gcc_data}) done by registering a callback (called with a null @code{gcc_data})
for the @code{PLUGIN_GGC_MARKING} event. Such callbacks can call the for the @code{PLUGIN_GGC_MARKING} event. Such callbacks can call the
@code{ggc_set_mark} routine, preferably thru the @code{ggc_mark} macro @code{ggc_set_mark} routine, preferably thru the @code{ggc_mark} macro
(and conversly, these routines should usually not be used in plugins (and conversely, these routines should usually not be used in plugins
outside of the @code{PLUGIN_GGC_MARKING} event). outside of the @code{PLUGIN_GGC_MARKING} event).
Some plugins may need to add extra GGC root tables, e.g. to handle Some plugins may need to add extra GGC root tables, e.g. to handle
their own @code{GTY}-ed data. This can be done with the their own @code{GTY}-ed data. This can be done with the
@code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and the @code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and
extra root table as @code{user_data}. the extra root table as @code{user_data}. Running the @code{gengtype
-p @var{source-dir} @var{file-list} @var{plugin*.c} ...} utility
generates this extra root table.
You should understand the details of memory management inside GCC You should understand the details of memory management inside GCC
before using @code{PLUGIN_GGC_MARKING} or before using @code{PLUGIN_GGC_MARKING} or
......
...@@ -128,18 +128,24 @@ typedef struct outf * outf_p; ...@@ -128,18 +128,24 @@ typedef struct outf * outf_p;
/* An output file, suitable for definitions, that can see declarations /* An output file, suitable for definitions, that can see declarations
made in INPUT_FILE and is linked into every language that uses 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 extern outf_p get_output_file_with_visibility
(const char *input_file); (const char *input_file);
const char *get_output_file_name (const char *); 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, ...) static void oprintf (outf_p o, const char *S, ...)
ATTRIBUTE_PRINTF_2; ATTRIBUTE_PRINTF_2;
/* The list of output files. */ /* The list of output files. */
static outf_p output_files; static outf_p output_files;
/* The plugin input files and their number; in that case only
corresponding gt-<plugin>.h are generated in the current
directory. */
static char** plugin_files;
static int nb_plugin_files;
/* The output header file that is included into pretty much every /* The output header file that is included into pretty much every
source file. */ source file. */
static outf_p header_file; static outf_p header_file;
...@@ -274,7 +280,7 @@ measure_input_list (FILE *list) ...@@ -274,7 +280,7 @@ measure_input_list (FILE *list)
int c; int c;
bool atbol = true; bool atbol = true;
num_lang_dirs = 0; num_lang_dirs = 0;
num_gt_files = 0; num_gt_files = plugin_files ? nb_plugin_files : 0;
while ((c = getc (list)) != EOF) while ((c = getc (list)) != EOF)
{ {
n++; n++;
...@@ -455,6 +461,13 @@ read_input_list (const char *listname) ...@@ -455,6 +461,13 @@ read_input_list (const char *listname)
/* Update the global counts now that we know accurately how many /* Update the global counts now that we know accurately how many
things there are. (We do not bother resizing the arrays down.) */ things there are. (We do not bother resizing the arrays down.) */
num_lang_dirs = langno; num_lang_dirs = langno;
/* Add the plugin files if provided. */
if (plugin_files)
{
int i;
for (i = 0; i < nb_plugin_files; i++)
gt_files[nfiles++] = plugin_files[i];
}
num_gt_files = nfiles; num_gt_files = nfiles;
} }
...@@ -962,6 +975,8 @@ write_rtx_next (void) ...@@ -962,6 +975,8 @@ write_rtx_next (void)
{ {
outf_p f = get_output_file_with_visibility (NULL); outf_p f = get_output_file_with_visibility (NULL);
int i; int i;
if (!f)
return;
oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n"); oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n"); oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
...@@ -1449,7 +1464,7 @@ static outf_p ...@@ -1449,7 +1464,7 @@ static outf_p
create_file (const char *name, const char *oname) create_file (const char *name, const char *oname)
{ {
static const char *const hdr[] = { 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", "\n",
"This file is part of GCC.\n", "This file is part of GCC.\n",
"\n", "\n",
...@@ -1472,6 +1487,8 @@ create_file (const char *name, const char *oname) ...@@ -1472,6 +1487,8 @@ create_file (const char *name, const char *oname)
outf_p f; outf_p f;
size_t i; size_t i;
gcc_assert (name != NULL);
gcc_assert (oname != NULL);
f = XCNEW (struct outf); f = XCNEW (struct outf);
f->next = output_files; f->next = output_files;
f->name = oname; f->name = oname;
...@@ -1495,6 +1512,11 @@ oprintf (outf_p o, const char *format, ...) ...@@ -1495,6 +1512,11 @@ oprintf (outf_p o, const char *format, ...)
size_t slength; size_t slength;
va_list ap; 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); va_start (ap, format);
slength = vasprintf (&s, format, ap); slength = vasprintf (&s, format, ap);
if (s == NULL || (int)slength < 0) if (s == NULL || (int)slength < 0)
...@@ -1524,6 +1546,9 @@ open_base_files (void) ...@@ -1524,6 +1546,9 @@ open_base_files (void)
{ {
size_t i; size_t i;
if (nb_plugin_files > 0 && plugin_files)
return;
header_file = create_file ("GCC", "gtype-desc.h"); header_file = create_file ("GCC", "gtype-desc.h");
base_files = XNEWVEC (outf_p, num_lang_dirs); base_files = XNEWVEC (outf_p, num_lang_dirs);
...@@ -1686,6 +1711,18 @@ get_output_file_with_visibility (const char *input_file) ...@@ -1686,6 +1711,18 @@ get_output_file_with_visibility (const char *input_file)
if (input_file == NULL) if (input_file == NULL)
input_file = "system.h"; input_file = "system.h";
/* In plugin mode, return NULL unless the input_file is one of the
plugin_files. */
if (plugin_files && nb_plugin_files > 0)
{
int ix= -1, i;
for (i = 0; i < nb_plugin_files && ix < 0; i++)
if (strcmp (input_file, plugin_files[i]) == 0)
ix = i;
if (ix < 0)
return NULL;
}
/* Determine the output file name. */ /* Determine the output file name. */
basename = get_file_basename (input_file); basename = get_file_basename (input_file);
...@@ -1737,6 +1774,7 @@ get_output_file_with_visibility (const char *input_file) ...@@ -1737,6 +1774,7 @@ get_output_file_with_visibility (const char *input_file)
/* If not, create it. */ /* If not, create it. */
r = create_file (for_name, output_name); r = create_file (for_name, output_name);
gcc_assert (r && r->name);
return r; return r;
} }
...@@ -1747,7 +1785,10 @@ get_output_file_with_visibility (const char *input_file) ...@@ -1747,7 +1785,10 @@ get_output_file_with_visibility (const char *input_file)
const char * const char *
get_output_file_name (const char *input_file) 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;
} }
/* Copy the output to its final destination, /* Copy the output to its final destination,
...@@ -2812,7 +2853,6 @@ write_local_func_for_structure (type_p orig_s, type_p s, type_p *param) ...@@ -2812,7 +2853,6 @@ write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
memset (&d, 0, sizeof (d)); memset (&d, 0, sizeof (d));
d.of = get_output_file_with_visibility (fn); d.of = get_output_file_with_visibility (fn);
d.process_field = write_types_local_process_field; d.process_field = write_types_local_process_field;
d.opt = s->u.s.opt; d.opt = s->u.s.opt;
d.line = &s->u.s.line; d.line = &s->u.s.line;
...@@ -2848,6 +2888,8 @@ write_local (type_p structures, type_p param_structs) ...@@ -2848,6 +2888,8 @@ write_local (type_p structures, type_p param_structs)
{ {
type_p s; type_p s;
if (!header_file)
return;
oprintf (header_file, "\n/* Local pointer-walking routines. */\n"); oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
for (s = structures; s; s = s->next) for (s = structures; s; s = s->next)
if (s->gc_used == GC_POINTED_TO if (s->gc_used == GC_POINTED_TO
...@@ -2933,6 +2975,8 @@ write_enum_defn (type_p structures, type_p param_structs) ...@@ -2933,6 +2975,8 @@ write_enum_defn (type_p structures, type_p param_structs)
{ {
type_p s; type_p s;
if (!header_file)
return;
oprintf (header_file, "\n/* Enumeration of types known. */\n"); oprintf (header_file, "\n/* Enumeration of types known. */\n");
oprintf (header_file, "enum gt_types_enum {\n"); oprintf (header_file, "enum gt_types_enum {\n");
for (s = structures; s; s = s->next) for (s = structures; s; s = s->next)
...@@ -2983,6 +3027,8 @@ static void ...@@ -2983,6 +3027,8 @@ static void
put_mangled_filename (outf_p f, const char *fn) put_mangled_filename (outf_p f, const char *fn)
{ {
const char *name = get_output_file_name (fn); const char *name = get_output_file_name (fn);
if (!f || !name)
return;
for (; *name != 0; name++) for (; *name != 0; name++)
if (ISALNUM (*name)) if (ISALNUM (*name))
oprintf (f, "%c", *name); oprintf (f, "%c", *name);
...@@ -3007,7 +3053,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname, ...@@ -3007,7 +3053,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
oprintf (fli2->f, "};\n\n"); 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) if (fli2->started_p)
{ {
lang_bitmap bitmap = get_lang_bitmap (fli2->name); lang_bitmap bitmap = get_lang_bitmap (fli2->name);
...@@ -3026,7 +3072,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname, ...@@ -3026,7 +3072,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
{ {
size_t fnum; 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], oprintf (base_files [fnum],
"EXPORTED_CONST struct %s * const %s[] = {\n", "EXPORTED_CONST struct %s * const %s[] = {\n",
tname, name); tname, name);
...@@ -3041,7 +3087,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname, ...@@ -3041,7 +3087,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
fli2->started_p = 0; 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) if (bitmap & 1)
{ {
oprintf (base_files[fnum], " gt_%s_", pfx); oprintf (base_files[fnum], " gt_%s_", pfx);
...@@ -3052,7 +3098,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname, ...@@ -3052,7 +3098,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
{ {
size_t fnum; 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], " NULL\n");
oprintf (base_files[fnum], "};\n"); oprintf (base_files[fnum], "};\n");
...@@ -3309,7 +3355,7 @@ write_roots (pair_p variables) ...@@ -3309,7 +3355,7 @@ write_roots (pair_p variables)
v->name, o->name); v->name, o->name);
for (fli = flp; fli; fli = fli->next) for (fli = flp; fli; fli = fli->next)
if (fli->f == f) if (fli->f == f && f)
break; break;
if (fli == NULL) if (fli == NULL)
{ {
...@@ -3318,6 +3364,7 @@ write_roots (pair_p variables) ...@@ -3318,6 +3364,7 @@ write_roots (pair_p variables)
fli->next = flp; fli->next = flp;
fli->started_p = 0; fli->started_p = 0;
fli->name = v->line.file; fli->name = v->line.file;
gcc_assert(fli->name);
flp = fli; flp = fli;
oprintf (f, "\n/* GC roots. */\n\n"); oprintf (f, "\n/* GC roots. */\n\n");
...@@ -3586,17 +3633,28 @@ main (int argc, char **argv) ...@@ -3586,17 +3633,28 @@ main (int argc, char **argv)
{ {
size_t i; size_t i;
static struct fileloc pos = { this_file, 0 }; static struct fileloc pos = { this_file, 0 };
char* inputlist = 0;
/* fatal uses this */ /* fatal uses this */
progname = "gengtype"; progname = "gengtype";
if (argc != 3) if (argc >= 5 && !strcmp (argv[1], "-p"))
fatal ("usage: gengtype srcdir input-list"); {
srcdir = argv[2];
inputlist = argv[3];
plugin_files = argv+4;
nb_plugin_files = argc-4;
}
else if (argc == 3)
{
srcdir = argv[1]; srcdir = argv[1];
inputlist = argv[2];
}
else
fatal ("usage: gengtype [-p] srcdir input-list [file1 file2 ... fileN]");
srcdir_len = strlen (srcdir); srcdir_len = strlen (srcdir);
read_input_list (argv[2]); read_input_list (inputlist);
if (hit_error) if (hit_error)
return 1; return 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment