From: Basile Starynkevitch <basile@starynkevitch.net>
To: Laurynas Biveinis <laurynas.biveinis@gmail.com>
Cc: gcc-patches@gcc.gnu.org
Subject: gengtype plugin improvement last2round - patch3 [inputfile]
Date: Wed, 20 Oct 2010 20:39:00 -0000 [thread overview]
Message-ID: <20101020220935.cac67eac.basile@starynkevitch.net> (raw)
In-Reply-To: <m339s2w5kf.fsf@fleche.redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2723 bytes --]
Hello all,
References:
http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01742.html
http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01536.html
http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01452.html
and others linked from them.
After having separately commited the removal of location_s and having
taken account Laurynas's comments
http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01452.html I am attaching
a patch on gengtype adding a real input_file structure relative to
trunk rev 165733.
### gcc/ChangeLog entry ###
2010-10-20 Basile Starynkevitch <basile@starynkevitch.net>
Jeremie Salvucci <basile@starynkevitch.net>
* gengtype.c (plugin_files, gt_files, this_file, system_file):
Change type to input_file.
(get_file_basename, get_file_realbasename)
(get_file_srcdir_relative_path, get_file_langdir): Change
argument type to input_file.
(error_at_line): Use input_file.
(lang_dir_names, num_lang_dirs): Not static anymore.
(get_lang_bitmap, set_lang_bitmap): Moved to gengtype.h.
(read_input_file_name, read_input_list, note_variable)
(create_field_all, get_file_realbasename)
(get_file_srcdir_relative_path, get_file_basename)
(get_file_langdir, get_file_gtfilename)
(get_output_file_with_visibility, get_output_file_name)
(put_mangled_filename, walk_type, get_output_file_for_structure)
(parse_program_options)
(struct flist): Use input_file.
(input_file_htab): Add variable.
(input_file_by_name, htab_hash_inputfile, htab_eq_inputfile):
Added functions.
(main): Initialize input_file_htab and this_file and
system_file, use input_file.
* gengtype.h (struct input_file_st, input_file): Add struct and
type.
(CHECK_INPUT_FILE_MAGIC): Added macro.
(gt_files, num_gt_files, this_file, system_file): Moved from
gengtype.c and declared as input_file-s.
(input_file_by_name, get_file_srcdir_relative_path)
(get_lang_bitmap, set_lang_bitmap)
(get_output_file_with_visibility, get_output_file_name): Ditto.
(get_input_file_name): New inlined function.
(struct fileloc): Use input_file.
(lang_dir_names, num_lang_dirs): Moved from gengtype.c.
* gengtype-lex.l: Include errors.h.
(yybegin): Use input_file_by_name.
* gengtype-parse.c: Includes errors.h.
(parse_error): Use input_file.
(type): Counts the anonymous pseudo-identifiers.
* Makefile.in (gengtype-lex.o, gengtype-parse.o): Depends upon
errors.h
#####
Ok for trunk?
PS. I might not have time to send more patches before the GCC Summit next week
(my slides are unfinished).
--
Basile STARYNKEVITCH http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mine, sont seulement les miennes} ***
[-- Attachment #2: gengtype-last2round-inputfile-r165733.diff --]
[-- Type: text/x-diff, Size: 52592 bytes --]
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c (revision 165733)
+++ gcc/gengtype.c (working copy)
@@ -128,7 +128,6 @@ struct type
-const char *get_output_file_name (const char *);
/* The list of output files. */
@@ -142,12 +141,11 @@ outf_p header_file;
/* The name of the file containing the list of input files. */
static char *inputlist;
-/* The plugin input files and their number; in that case only
- a single file is produced. */
-static char **plugin_files;
+/* The plugin input files and their number. */
+static input_file** plugin_files;
static size_t nb_plugin_files;
-/* The generated plugin output file and name. */
+/* the generated plugin output file and name in plugin mode. */
static outf_p plugin_output;
static char *plugin_output_filename;
@@ -174,12 +172,11 @@ static const char* backup_dir; /* (-B) program opt
static outf_p create_file (const char *, const char *);
-static const char *get_file_basename (const char *);
-static const char *get_file_realbasename (const char *);
-static const char *get_file_srcdir_relative_path (const char *);
+static const char * get_file_basename (const input_file *);
+static const char * get_file_realbasename (const input_file *);
static int get_prefix_langdir_index (const char *);
-static const char *get_file_langdir (const char *);
+static const char * get_file_langdir (const input_file *);
\f
/* Nonzero iff an error has occurred. */
@@ -199,7 +196,8 @@ error_at_line (const struct fileloc *pos, const ch
va_start (ap, msg);
- fprintf (stderr, "%s:%d: ", pos->file, pos->line);
+ gcc_assert (pos != NULL && pos->file != NULL);
+ fprintf (stderr, "%s:%d: ", get_input_file_name (pos->file), pos->line);
vfprintf (stderr, msg, ap);
fputc ('\n', stderr);
hit_error = true;
@@ -227,76 +225,30 @@ xasprintf (const char *format, ...)
/* Input file handling. */
/* Table of all input files. */
-static const char **gt_files;
-static size_t num_gt_files;
+input_file** gt_files;
+size_t num_gt_files;
-/* A number of places use the name of this "gengtype.h" file for a
+/* A number of places use the name of this "gengtype.c" file for a
location for things that we can't rely on the source to define.
- Make sure we can still use pointer comparison on filenames. */
-const char this_file[] = __FILE__;
+ Initialized early in main. */
+input_file* this_file;
/* The "system.h" file is likewise specially useful. */
-const char system_h_file[] = "system.h";
+input_file* system_h_file;
/* Vector of per-language directories. */
-static const char **lang_dir_names;
-static size_t num_lang_dirs;
+const char **lang_dir_names;
+size_t num_lang_dirs;
/* An array of output files suitable for definitions. There is one
BASE_FILES entry for each language. */
static outf_p *base_files;
-/* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
- INPUT_FILE is used by <lang>.
- This function should be written to assume that a file _is_ used
- if the situation is unclear. If it wrongly assumes a file _is_ used,
- a linker error will result. If it wrongly assumes a file _is not_ used,
- some GC roots may be missed, which is a much harder-to-debug problem.
-
- The relevant bitmap is stored immediately before the file's name in the
- buffer set up by read_input_list. It may be unaligned, so we have to
- read it byte-by-byte. */
-
-static lang_bitmap
-get_lang_bitmap (const char *gtfile)
-{
-
- if (gtfile == this_file || gtfile == system_h_file)
- {
- /* Things defined in this "gengtype.c" file or in "system.h" are
- universal (and there is no space for their lang_bitmap before
- their file names). */
- return (((lang_bitmap) 1) << num_lang_dirs) - 1;
- }
- else
- {
- lang_bitmap n = 0;
- int i;
- for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
- n = (n << CHAR_BIT) + (unsigned char) gtfile[i];
- return n;
- }
-}
-
-/* Set the bitmap returned by get_lang_bitmap. The only legitimate
- caller of this function is read_input_list. */
-static void
-set_lang_bitmap (char *gtfile, lang_bitmap n)
-{
- int i;
- for (i = -1; i >= -(int) sizeof (lang_bitmap); i--)
- {
- gtfile[i] = n & ((1U << CHAR_BIT) - 1);
- n >>= CHAR_BIT;
- }
-}
-
-
#if ENABLE_CHECKING
/* Utility debugging function, printing the various type counts within
a list of types. Called thru the DBGPRINT_COUNT_TYPE macro. */
void
-dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
+dbgprint_count_type_at (const char *fil, int lin, const char*msg, type_p t)
{
int nb_types = 0, nb_scalar = 0, nb_string = 0;
int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0;
@@ -482,11 +434,11 @@ read_input_list (const char *listname)
size_t nfiles = 0;
lang_bitmap curlangs = (1 << num_lang_dirs) - 1;
- epos.file = listname;
+ epos.file = input_file_by_name (listname);
epos.line = 0;
lang_dir_names = XNEWVEC (const char *, num_lang_dirs);
- gt_files = XNEWVEC (const char *, num_gt_files);
+ gt_files = XNEWVEC (input_file *, num_gt_files);
for (;;)
{
@@ -517,29 +469,30 @@ read_input_list (const char *listname)
else
{
size_t i;
+ input_file *inpf = input_file_by_name (line);
gcc_assert (nfiles <= num_gt_files);
for (i = 0; i < nfiles; i++)
- if (strcmp (gt_files[i], line) == 0)
+ /* Since the input_file-s are uniquely hash-consed, we
+ can just compare pointers! */
+ if (gt_files[i] == inpf)
{
/* Throw away the string we just read, and add the
current language to the existing string's bitmap. */
- lang_bitmap bmap = get_lang_bitmap (gt_files[i]);
+ lang_bitmap bmap = get_lang_bitmap (inpf);
if (bmap & curlangs)
- error_at_line (&epos,
- "file %s specified more than once "
+ error_at_line (&epos, "file %s specified more than once "
"for language %s", line,
- langno ==
- 0 ? "(all)" : lang_dir_names[langno -
- 1]);
+ langno == 0
+ ? "(all)" : lang_dir_names[langno - 1]);
bmap |= curlangs;
- set_lang_bitmap (CONST_CAST (char *, gt_files[i]), bmap);
+ set_lang_bitmap (inpf, bmap);
here = committed;
goto next_line;
}
- set_lang_bitmap (line, curlangs);
- gt_files[nfiles++] = line;
+ set_lang_bitmap (inpf, curlangs);
+ gt_files[nfiles++] = inpf;
}
}
/* Update the global counts now that we know accurately how many
@@ -886,7 +839,7 @@ note_variable (const char *s, type_p t, options_p
/* Most-general structure field creator. */
static pair_p
create_field_all (pair_p next, type_p type, const char *name, options_p opt,
- const char *file, int line)
+ const input_file* inpf, int line)
{
pair_p field;
@@ -895,7 +848,7 @@ create_field_all (pair_p next, type_p type, const
field->type = type;
field->name = name;
field->opt = opt;
- field->line.file = file;
+ field->line.file = inpf;
field->line.line = line;
return field;
}
@@ -1080,7 +1033,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUS
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));
- constant_tp =
+ constant_tp =
create_pointer (find_structure ("constant_descriptor_rtx", 0));
scalar_tp = &scalar_nonchar; /* rtunion int */
@@ -1350,7 +1303,7 @@ adjust_field_type (type_p t, options_p opt)
if (params[num] != NULL)
error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
if (!ISDIGIT (opt->name[5]))
- params[num] =
+ params[num] =
create_pointer (CONST_CAST2 (type_p, const char *, opt->info));
else
params[num] = CONST_CAST2 (type_p, const char *, opt->info);
@@ -1395,7 +1348,7 @@ static void set_gc_used (pair_p);
static void
process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
- int *pass_param, int *length, int *skip,
+ int *pass_param, int *length, int *skip,
type_p *nested_ptr)
{
options_p o;
@@ -1508,6 +1461,7 @@ set_gc_used (pair_p variables)
pair_p p;
for (p = variables; p; p = p->next)
{
+ DBGPRINTF ("set_gc_used p %p '%s' nbvars %d", (void*) p, p->name, nbvars);
set_gc_used_type (p->type, GC_USED, NULL);
nbvars++;
};
@@ -1592,10 +1546,10 @@ oprintf (outf_p o, const char *format, ...)
size_t new_len = o->buflength;
if (new_len == 0)
new_len = 1024;
- do
+ do
{
new_len *= 2;
- }
+ }
while (o->bufused + slength >= new_len);
o->buf = XRESIZEVEC (char, o->buf, new_len);
o->buflength = new_len;
@@ -1653,8 +1607,9 @@ open_base_files (void)
components skipped. */
static const char *
-get_file_realbasename (const char *f)
+get_file_realbasename (const input_file *inpf)
{
+ const char* f = get_input_file_name (inpf);
const char *lastslash = strrchr (f, '/');
return (lastslash != NULL) ? lastslash + 1 : f;
@@ -1663,26 +1618,28 @@ static const char *
/* For F a filename, return the relative path to F from $(srcdir) if the
latter is a prefix in F, NULL otherwise. */
-static const char *
-get_file_srcdir_relative_path (const char *f)
+const char *
+get_file_srcdir_relative_path (const input_file *inpf)
{
- if (strlen (f) > srcdir_len
- && IS_DIR_SEPARATOR (f[srcdir_len])
- && memcmp (f, srcdir, srcdir_len) == 0)
- return f + srcdir_len + 1;
+ const char* fname = get_input_file_name (inpf);
+ if (strlen (fname) > srcdir_len
+ && IS_DIR_SEPARATOR (fname[srcdir_len])
+ && memcmp (fname, srcdir, srcdir_len) == 0)
+ return fname + srcdir_len + 1;
else
return NULL;
}
-/* For F a filename, return the relative path to F from $(srcdir) if the
- latter is a prefix in F, or the real basename of F otherwise. */
+/* For INPF an input_file, return the relative path to INPF from
+ $(srcdir) if the latter is a prefix in INPF, or the real basename
+ of INPF otherwise. */
static const char *
-get_file_basename (const char *f)
+get_file_basename (const input_file *inpf)
{
- const char *srcdir_path = get_file_srcdir_relative_path (f);
+ const char * srcdir_path = get_file_srcdir_relative_path (inpf);
- return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (f);
+ return (srcdir_path != NULL) ? srcdir_path : get_file_realbasename (inpf);
}
/* For F a filename, return the lang_dir_names relative index of the language
@@ -1708,18 +1665,18 @@ get_prefix_langdir_index (const char *f)
return -1;
}
-/* For F a filename, return the name of language directory where F is located,
- if any, NULL otherwise. */
+/* For INPF an input_file, return the name of language directory where
+ INPF is located, if any, NULL otherwise. */
static const char *
-get_file_langdir (const char *f)
+get_file_langdir (const input_file *inpf)
{
/* Get the relative path to F from $(srcdir) and find the language by
comparing the prefix with language directory names. If F is not even
srcdir relative, no point in looking further. */
int lang_index;
- const char *srcdir_relative_path = get_file_srcdir_relative_path (f);
+ const char *srcdir_relative_path = get_file_srcdir_relative_path (inpf);
const char *r;
if (!srcdir_relative_path)
@@ -1736,16 +1693,15 @@ static const char *
return r;
}
-/* The gt- output file name for F. */
-
+/* The gt- output file name for INPF. */
static const char *
-get_file_gtfilename (const char *f)
+get_file_gtfilename (const input_file *inpf)
{
/* Cook up an initial version of the gt- file name from the file real
basename and the language name, if any. */
- const char *basename = get_file_realbasename (f);
- const char *langdir = get_file_langdir (f);
+ const char *basename = get_file_realbasename (inpf);
+ const char *langdir = get_file_langdir (inpf);
char *result =
(langdir ? xasprintf ("gt-%s-%s", langdir, basename)
@@ -1767,11 +1723,12 @@ static const char *
}
/* An output file, suitable for definitions, that can see declarations
- made in INPUT_FILE and is linked into every language that uses
- INPUT_FILE. */
+ made in INPF and is linked into every language that uses INPF.
+ Since the result is cached inside INPF, that argument cannot be
+ declared constant. */
outf_p
-get_output_file_with_visibility (const char *input_file)
+get_output_file_with_visibility (input_file* inpf)
{
outf_p r;
size_t len;
@@ -1782,30 +1739,30 @@ outf_p
/* This can happen when we need a file with visibility on a
structure that we've never seen. We have to just hope that it's
globally visible. */
- if (input_file == NULL)
- input_file = "system.h";
+ if (inpf == NULL)
+ inpf = system_h_file;
- /* In plugin mode, return NULL unless the input_file is one of the
- plugin_files. */
+ /* In plugin mode, return NULL unless the INPF is one of the
+ plugin_files. We can compare input_file-s by pointer equality. */
if (plugin_files)
{
size_t i;
for (i = 0; i < nb_plugin_files; i++)
- if (strcmp (input_file, plugin_files[i]) == 0)
+ if (inpf == plugin_files[i])
return plugin_output;
return NULL;
}
/* Determine the output file name. */
- basename = get_file_basename (input_file);
+ basename = get_file_basename (inpf);
len = strlen (basename);
if ((len > 2 && memcmp (basename + len - 2, ".c", 2) == 0)
|| (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 (inpf);
for_name = basename;
}
/* Some headers get used by more than one front-end; hence, it
@@ -1830,8 +1787,7 @@ outf_p
else if (strncmp (basename, "cp", 2) == 0 && IS_DIR_SEPARATOR (basename[2])
&& strcmp (basename + 3, "name-lookup.h") == 0)
output_name = "gt-cp-name-lookup.h", for_name = "cp/name-lookup.c";
- else if (strncmp (basename, "objc", 4) == 0
- && IS_DIR_SEPARATOR (basename[4])
+ 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
@@ -1858,13 +1814,13 @@ outf_p
}
/* The name of an output file, suitable for definitions, that can see
- declarations made in INPUT_FILE and is linked into every language
- that uses INPUT_FILE. */
+ declarations made in INPF and is linked into every language
+ that uses INPF. */
const char *
-get_output_file_name (const char *input_file)
+get_output_file_name (input_file *inpf)
{
- outf_p o = get_output_file_with_visibility (input_file);
+ outf_p o = get_output_file_with_visibility (inpf);
if (o)
return o->name;
return NULL;
@@ -1902,8 +1858,8 @@ is_file_equal (outf_p of)
static void
close_output_files (void)
{
+ outf_p of;
int nbwrittenfiles = 0;
- outf_p of;
for (of = output_files; of; of = of->next)
{
@@ -1936,11 +1892,12 @@ close_output_files (void)
progname, nbwrittenfiles, of->name, backupname);
else if (verbosity_level >= 1)
printf ("%s write #%-3d %s\n", progname, nbwrittenfiles, of->name);
+ if (backupname)
free (backupname);
}
else
{
- /* output file remains unchanged. */
+ /* Output file remains unchanged. */
if (verbosity_level >= 2)
printf ("%s keep %s\n", progname, of->name);
}
@@ -1952,11 +1909,12 @@ close_output_files (void)
printf ("%s wrote %d files.\n", progname, nbwrittenfiles);
}
\f
-struct flist
+\f
+struct flist
{
struct flist *next;
int started_p;
- const char *name;
+ const input_file *file;
outf_p f;
};
@@ -1966,8 +1924,8 @@ struct walk_type_data;
For structures, given a pointer to the item in 'val'.
For misc. pointers, given the item in 'val'.
*/
-typedef void (*process_field_fn) (type_p f, const struct walk_type_data * p);
-typedef void (*func_name_fn) (type_p s, const struct walk_type_data * p);
+typedef void (*process_field_fn) (type_p f, const struct walk_type_data *p);
+typedef void (*func_name_fn) (type_p s, const struct walk_type_data *p);
/* Parameters for write_types. */
@@ -1999,10 +1957,10 @@ static void write_types_local_process_field
static void write_local_func_for_structure
(const_type_p orig_s, type_p s, type_p *param);
static void write_local (outf_p output_header,
- type_p structures, type_p param_structs);
+ 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);
-static void put_mangled_filename (outf_p, const char *);
+static void put_mangled_filename (outf_p, const input_file *);
static void finish_root_table (struct flist *flp, const char *pfx,
const char *tname, const char *lastname,
const char *name);
@@ -2041,7 +1999,7 @@ output_mangled_typename (outf_p of, const_type_p t
{
if (t == NULL)
oprintf (of, "Z");
- else
+ else
switch (t->kind)
{
case TYPE_POINTER:
@@ -2057,8 +2015,8 @@ output_mangled_typename (outf_p of, const_type_p t
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_LANG_STRUCT:
- oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag),
- t->u.s.tag);
+ oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag),
+ t->u.s.tag);
break;
case TYPE_PARAM_STRUCT:
{
@@ -2088,7 +2046,7 @@ output_escaped_param (struct walk_type_data *d, co
for (p = param; *p; p++)
if (*p != '%')
oprintf (d->of, "%c", *p);
- else
+ else
switch (*++p)
{
case 'h':
@@ -2311,7 +2269,7 @@ walk_type (type_p t, struct walk_type_data *d)
oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
d->indent += 2;
oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
- oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent,
+ oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent,
"", loopcounter, loopcounter);
output_escaped_param (d, length, "length");
oprintf (d->of, "); i%d++) {\n", loopcounter);
@@ -2472,7 +2430,7 @@ walk_type (type_p t, struct walk_type_data *d)
{
fprintf (stderr,
"%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
- d->line->file, d->line->line, f->name);
+ get_input_file_name (d->line->file), d->line->line, f->name);
continue;
}
else if (union_p && !(default_p || tagid))
@@ -2639,16 +2597,27 @@ output_type_enum (outf_p of, type_p s)
static outf_p
get_output_file_for_structure (const_type_p s, type_p *param)
{
- const char *fn = s->u.s.line.file;
+ const input_file* fn = NULL;
int i;
+ if (UNION_OR_STRUCT_P (s))
+ fn = s->u.s.line.file;
+ else if (s->kind == TYPE_PARAM_STRUCT)
+ fn = s->u.param_struct.line.file;
+
+ CHECK_INPUT_FILE_MAGIC (fn);
+
/* This is a hack, and not the good kind either. */
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.file;
- return get_output_file_with_visibility (fn);
+ CHECK_INPUT_FILE_MAGIC (fn);
+
+ /* The call to get_output_file_with_visibility may update fn by
+ caching its result inside, so we need the CONST_CAST. */
+ return get_output_file_with_visibility (CONST_CAST (input_file*, fn));
}
/* For S, a structure that's part of ORIG_S, and using parameters
@@ -2825,8 +2794,8 @@ static void
write_types (outf_p output_header, type_p structures, type_p param_structs,
const struct write_types_data *wtd)
{
+ type_p s;
int nbfun = 0; /* Count the emitted functions. */
- type_p s;
oprintf (output_header, "\n/* %s*/\n", wtd->comment);
/* We first emit the macros and the declarations. Functions' code is
@@ -2931,12 +2900,9 @@ write_types (outf_p output_header, type_p structur
}
}
else
- {
- /* Structure s is not possibly pointed to, so can be ignored. */
DBGPRINTF ("ignored s @ %p '%s' gc_used#%d",
(void*)s, s->u.s.tag,
(int) s->gc_used);
- }
for (s = param_structs; s; s = s->next)
if (s->gc_used == GC_POINTED_TO)
@@ -2966,22 +2932,21 @@ write_types (outf_p output_header, type_p structur
}
}
else
- {
- /* Param structure s is not pointed to, so should be ignored. */
DBGPRINTF ("ignored s @ %p", (void*)s);
- }
if (verbosity_level >= 2)
printf ("%s emitted %d routines for %s\n",
progname, nbfun, wtd->comment);
}
-static const struct write_types_data ggc_wtd = {
+static const struct write_types_data ggc_wtd =
+{
"ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
"GC marker procedures. ",
FALSE
};
-static const struct write_types_data pch_wtd = {
+static const struct write_types_data pch_wtd =
+{
"pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
"gt_pch_note_reorder",
"PCH type-walking procedures. ",
@@ -3068,7 +3033,8 @@ write_local (outf_p output_header, type_p structur
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)
+ if (s->gc_used == GC_POINTED_TO
+ || s->gc_used == GC_MAYBE_POINTED_TO)
{
options_p opt;
@@ -3080,7 +3046,8 @@ write_local (outf_p output_header, type_p structur
{
const_type_p const t = (const_type_p) opt->info;
if (t->kind == TYPE_STRUCT
- || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
+ || t->kind == TYPE_UNION
+ || t->kind == TYPE_LANG_STRUCT)
{
oprintf (output_header, "#define gt_pch_p_");
output_mangled_typename (output_header, s);
@@ -3169,10 +3136,10 @@ write_enum_defn (type_p structures, type_p param_s
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)
if (USED_BY_TYPED_GC_P (s))
{
- nbstruct++;
DBGPRINTF ("write_enum_defn s @ %p nbstruct %d",
(void*) s, nbstruct);
if (UNION_OR_STRUCT_P (s))
@@ -3181,23 +3148,25 @@ write_enum_defn (type_p structures, type_p param_s
oprintf (header_file, " gt_ggc_e_");
output_mangled_typename (header_file, s);
oprintf (header_file, ",\n");
+ nbstruct++;
}
+
for (s = param_structs; s; s = s->next)
if (s->gc_used == GC_POINTED_TO)
{
- nbparamstruct++;
DBGPRINTF ("write_enum_defn s %p nbparamstruct %d",
(void*) s, nbparamstruct);
oprintf (header_file, " gt_e_");
output_mangled_typename (header_file, s);
oprintf (header_file, ",\n");
+ nbparamstruct++;
}
+
oprintf (header_file, " gt_types_enum_last\n");
oprintf (header_file, "};\n");
if (verbosity_level >= 2)
printf ("%s handled %d GTY-ed structures & %d parameterized structures.\n",
progname, nbstruct, nbparamstruct);
-
}
/* Might T contain any non-pointer elements? */
@@ -3222,9 +3191,12 @@ contains_scalar_p (type_p t)
/* Mangle FN and print it to F. */
static void
-put_mangled_filename (outf_p f, const char *fn)
+put_mangled_filename (outf_p f, const input_file *inpf)
{
- const char *name = get_output_file_name (fn);
+ /* The call to get_output_file_name may indirectly update fn since
+ get_output_file_with_visibility caches its result inside, so we
+ need the CONST_CAST. */
+ const char *name = get_output_file_name (CONST_CAST (input_file*, inpf));
if (!f || !name)
return;
for (; *name != 0; name++)
@@ -3254,15 +3226,16 @@ finish_root_table (struct flist *flp, const char *
for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
if (fli2->started_p)
{
- lang_bitmap bitmap = get_lang_bitmap (fli2->name);
+ lang_bitmap bitmap = get_lang_bitmap (fli2->file);
int fnum;
for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
if (bitmap & 1)
{
oprintf (base_files[fnum],
- "extern const struct %s gt_%s_", tname, pfx);
- put_mangled_filename (base_files[fnum], fli2->name);
+ "extern const struct %s gt_%s_",
+ tname, pfx);
+ put_mangled_filename (base_files[fnum], fli2->file);
oprintf (base_files[fnum], "[];\n");
}
}
@@ -3271,14 +3244,15 @@ finish_root_table (struct flist *flp, const char *
size_t fnum;
for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
oprintf (base_files[fnum],
- "EXPORTED_CONST struct %s * const %s[] = {\n", tname, name);
+ "EXPORTED_CONST struct %s * const %s[] = {\n",
+ tname, name);
}
for (fli2 = flp; fli2; fli2 = fli2->next)
if (fli2->started_p)
{
- lang_bitmap bitmap = get_lang_bitmap (fli2->name);
+ lang_bitmap bitmap = get_lang_bitmap (fli2->file);
int fnum;
fli2->started_p = 0;
@@ -3287,7 +3261,7 @@ finish_root_table (struct flist *flp, const char *
if (bitmap & 1)
{
oprintf (base_files[fnum], " gt_%s_", pfx);
- put_mangled_filename (base_files[fnum], fli2->name);
+ put_mangled_filename (base_files[fnum], fli2->file);
oprintf (base_files[fnum], ",\n");
}
}
@@ -3428,7 +3402,8 @@ write_root (outf_p f, pair_p v, type_p type, const
error_at_line (line,
"both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
name, fld->name, validf->name,
- name, fld->name, ufld->name, tag);
+ name, fld->name, ufld->name,
+ tag);
validf = ufld;
}
if (validf != NULL)
@@ -3523,7 +3498,9 @@ write_root (outf_p f, pair_p v, type_p type, const
break;
default:
- error_at_line (line, "global `%s' is unimplemented type", name);
+ error_at_line (line,
+ "global `%s' is unimplemented type",
+ name);
}
}
@@ -3549,7 +3526,8 @@ write_array (outf_p f, pair_p v, const struct writ
if (wtd->param_prefix)
{
oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
- oprintf (f, " (void *, void *, gt_pointer_operator, void *);\n");
+ oprintf (f,
+ " (void *, void *, gt_pointer_operator, void *);\n");
oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
wtd->param_prefix, v->name);
oprintf (d.of,
@@ -3564,7 +3542,8 @@ write_array (outf_p f, pair_p v, const struct writ
}
d.opt = v->opt;
- oprintf (f, "static void gt_%sa_%s (void *);\n", wtd->prefix, v->name);
+ oprintf (f, "static void gt_%sa_%s (void *);\n",
+ wtd->prefix, v->name);
oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
wtd->prefix, v->name);
oprintf (f, "{\n");
@@ -3585,7 +3564,9 @@ write_roots (pair_p variables, bool emit_pch)
for (v = variables; v; v = v->next)
{
- outf_p f = get_output_file_with_visibility (v->line.file);
+ outf_p f =
+ get_output_file_with_visibility (CONST_CAST (input_file*,
+ v->line.file));
struct flist *fli;
const char *length = NULL;
int deletable_p = 0;
@@ -3599,7 +3580,8 @@ write_roots (pair_p variables, bool emit_pch)
else if (strcmp (o->name, "param_is") == 0)
;
else if (strncmp (o->name, "param", 5) == 0
- && ISDIGIT (o->name[5]) && strcmp (o->name + 6, "_is") == 0)
+ && ISDIGIT (o->name[5])
+ && strcmp (o->name + 6, "_is") == 0)
;
else if (strcmp (o->name, "if_marked") == 0)
;
@@ -3617,8 +3599,8 @@ write_roots (pair_p variables, bool emit_pch)
fli->f = f;
fli->next = flp;
fli->started_p = 0;
- fli->name = v->line.file;
- gcc_assert (fli->name);
+ fli->file = v->line.file;
+ gcc_assert (fli->file);
flp = fli;
oprintf (f, "\n/* GC roots. */\n\n");
@@ -3637,7 +3619,9 @@ write_roots (pair_p variables, bool emit_pch)
for (v = variables; v; v = v->next)
{
- outf_p f = get_output_file_with_visibility (v->line.file);
+ outf_p f =
+ get_output_file_with_visibility (CONST_CAST (input_file*,
+ v->line.file));
struct flist *fli;
int skip_p = 0;
int length_p = 0;
@@ -3673,7 +3657,9 @@ write_roots (pair_p variables, bool emit_pch)
for (v = variables; v; v = v->next)
{
- outf_p f = get_output_file_with_visibility (v->line.file);
+ outf_p f =
+ get_output_file_with_visibility (CONST_CAST (input_file*,
+ v->line.file));
struct flist *fli;
int skip_p = 1;
options_p o;
@@ -3708,7 +3694,9 @@ write_roots (pair_p variables, bool emit_pch)
for (v = variables; v; v = v->next)
{
- outf_p f = get_output_file_with_visibility (v->line.file);
+ outf_p f =
+ get_output_file_with_visibility (CONST_CAST (input_file*,
+ v->line.file));
struct flist *fli;
const char *if_marked = NULL;
int length_p = 0;
@@ -3727,8 +3715,7 @@ write_roots (pair_p variables, bool emit_pch)
|| v->type->u.p->kind != TYPE_PARAM_STRUCT
|| v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
{
- error_at_line (&v->line,
- "if_marked option used but not hash table");
+ error_at_line (&v->line, "if_marked option used but not hash table");
continue;
}
@@ -3756,7 +3743,9 @@ write_roots (pair_p variables, bool emit_pch)
for (v = variables; v; v = v->next)
{
- outf_p f = get_output_file_with_visibility (v->line.file);
+ outf_p f =
+ get_output_file_with_visibility (CONST_CAST (input_file*,
+ v->line.file));
struct flist *fli;
int length_p = 0;
int if_marked_p = 0;
@@ -3791,7 +3780,9 @@ write_roots (pair_p variables, bool emit_pch)
for (v = variables; v; v = v->next)
{
- outf_p f = get_output_file_with_visibility (v->line.file);
+ outf_p f =
+ get_output_file_with_visibility (CONST_CAST (input_file*,
+ v->line.file));
struct flist *fli;
int skip_p = 0;
options_p o;
@@ -3910,10 +3901,8 @@ variable_size_p (const type_p s)
return false;
}
-enum alloc_quantity
-{ single, vector };
-enum alloc_zone
-{ any_zone, specific_zone };
+enum alloc_quantity { single, vector };
+enum alloc_zone { any_zone, specific_zone };
/* Writes one typed allocator definition for type identifier TYPE_NAME with
optional type specifier TYPE_SPECIFIER. The allocator name will contain
@@ -4045,8 +4034,7 @@ output_typename (outf_p of, const_type_p t)
{
int i;
for (i = 0; i < NUM_PARAM; i++)
- if (t->u.param_struct.param[i] != NULL)
- {
+ if (t->u.param_struct.param[i] != NULL) {
output_typename (of, t->u.param_struct.param[i]);
oprintf (of, "_");
}
@@ -4109,32 +4097,15 @@ dump_typekind (int indent, enum typekind kind)
printf ("%*ckind = ", indent, ' ');
switch (kind)
{
- case TYPE_SCALAR:
- printf ("TYPE_SCALAR");
- break;
- case TYPE_STRING:
- printf ("TYPE_STRING");
- break;
- case TYPE_STRUCT:
- printf ("TYPE_STRUCT");
- break;
- case TYPE_UNION:
- printf ("TYPE_UNION");
- break;
- case TYPE_POINTER:
- printf ("TYPE_POINTER");
- break;
- case TYPE_ARRAY:
- printf ("TYPE_ARRAY");
- break;
- case TYPE_LANG_STRUCT:
- printf ("TYPE_LANG_STRUCT");
- break;
- case TYPE_PARAM_STRUCT:
- printf ("TYPE_PARAM_STRUCT");
- break;
- default:
- gcc_unreachable ();
+ case TYPE_SCALAR: printf ("TYPE_SCALAR"); break;
+ case TYPE_STRING: printf ("TYPE_STRING"); break;
+ case TYPE_STRUCT: printf ("TYPE_STRUCT"); break;
+ case TYPE_UNION: printf ("TYPE_UNION"); break;
+ case TYPE_POINTER: printf ("TYPE_POINTER"); break;
+ case TYPE_ARRAY: printf ("TYPE_ARRAY"); break;
+ case TYPE_LANG_STRUCT: printf ("TYPE_LANG_STRUCT"); break;
+ case TYPE_PARAM_STRUCT: printf ("TYPE_PARAM_STRUCT"); break;
+ default: gcc_unreachable ();
}
printf ("\n");
}
@@ -4147,20 +4118,11 @@ dump_gc_used (int indent, enum gc_used_enum gc_use
printf ("%*cgc_used = ", indent, ' ');
switch (gc_used)
{
- case GC_UNUSED:
- printf ("GC_UNUSED");
- break;
- case GC_USED:
- printf ("GC_USED");
- break;
- case GC_MAYBE_POINTED_TO:
- printf ("GC_MAYBE_POINTED_TO");
- break;
- case GC_POINTED_TO:
- printf ("GC_POINTED_TO");
- break;
- default:
- gcc_unreachable ();
+ case GC_UNUSED: printf ("GC_UNUSED"); break;
+ case GC_USED: printf ("GC_USED"); break;
+ case GC_MAYBE_POINTED_TO: printf ("GC_MAYBE_POINTED_TO"); break;
+ case GC_POINTED_TO: printf ("GC_POINTED_TO"); break;
+ default: gcc_unreachable ();
}
printf ("\n");
}
@@ -4186,8 +4148,8 @@ dump_options (int indent, options_p opt)
static void
dump_fileloc (int indent, struct fileloc line)
{
- printf ("%*cfileloc: file = %s, line = %d\n", indent, ' ', line.file,
- line.line);
+ printf ("%*cfileloc: file = %s, line = %d\n", indent, ' ',
+ get_input_file_name (line.file), line.line);
}
/* Recursively dumps the struct, union, or a language-specific
@@ -4384,12 +4346,17 @@ static void
print_usage (void)
{
printf ("Usage: %s\n", progname);
- printf ("\t -h | --help " " \t# Give this help.\n");
+ printf ("\t -h | --help "
+ " \t# Give this help.\n");
printf ("\t -D | --debug "
- " \t# Give debug output to debug %s itself.\n", progname);
- printf ("\t -V | --version " " \t# Give version information.\n");
- printf ("\t -v | --verbose \t# Increase verbosity. Can be given several times.\n");
- printf ("\t -d | --dump " " \t# Dump state for debugging.\n");
+ " \t# Give debug output to debug %s itself.\n",
+ progname);
+ printf ("\t -V | --version "
+ " \t# Give version information.\n");
+ printf ("\t -v | --verbose "
+ " \t# Increase verbosity. Can be given several times.\n");
+ printf ("\t -d | --dump "
+ " \t# Dump state for debugging.\n");
printf ("\t -P | --plugin <output-file> <plugin-src> ... "
" \t# Generate for plugin.\n");
printf ("\t -S | --srcdir <GCC-directory> "
@@ -4398,8 +4365,10 @@ print_usage (void)
" \t# Specify the backup directory for updated files.\n");
printf ("\t -I | --inputs <input-list> "
" \t# Specify the file with source files list.\n");
- printf ("\t -w | --write-state <state-file> " " \t# Write a state file.\n");
- printf ("\t -r | --read-state <state-file> " " \t# Read a state file.\n");
+ printf ("\t -w | --write-state <state-file> "
+ " \t# Write a state file.\n");
+ printf ("\t -r | --read-state <state-file> "
+ " \t# Read a state file.\n");
}
static void
@@ -4414,7 +4383,7 @@ static void
parse_program_options (int argc, char **argv)
{
int opt = -1;
- while ((opt = getopt_long (argc, argv, "hVvdP:S:B:I:w:r:D",
+ while ((opt = getopt_long (argc, argv, "hvVdP:S:B:I:w:r:D",
gengtype_long_options, NULL)) >= 0)
{
switch (opt)
@@ -4422,6 +4391,9 @@ parse_program_options (int argc, char **argv)
case 'h': /* --help */
print_usage ();
break;
+ case 'v': /* --verbose */
+ verbosity_level++;
+ break;
case 'V': /* --version */
print_version ();
break;
@@ -4431,9 +4403,6 @@ parse_program_options (int argc, char **argv)
case 'D': /* --debug */
do_debug = 1;
break;
- case 'v': /* --verbose */
- verbosity_level++;
- break;
case 'P': /* --plugin */
if (optarg)
plugin_output_filename = optarg;
@@ -4486,16 +4455,69 @@ parse_program_options (int argc, char **argv)
if (optind >= argc)
fatal ("no source files given in plugin mode");
nb_plugin_files = argc - optind;
- plugin_files = XNEWVEC (char*, nb_plugin_files);
+ plugin_files = XNEWVEC (input_file*, nb_plugin_files);
for (i = 0; i < (int) nb_plugin_files; i++)
{
char *name = argv[i + optind];
- plugin_files[i] = name;
+ plugin_files[i] = input_file_by_name (name);
}
}
}
+\f
+/******* Manage input files. ******/
+
+/* Hash table of unique input file names. */
+static htab_t input_file_htab;
+
+/* Find or allocate a new input_file by hash-consing it. */
+input_file*
+input_file_by_name (const char* name)
+{
+ PTR* slot;
+ input_file* f = NULL;
+ int namlen = 0;
+ if (!name)
+ return NULL;
+ namlen = strlen (name);
+ f = XCNEWVAR (input_file, sizeof (input_file)+namlen+2);
+ f->inpbitmap = 0;
+ f->inpoutf = NULL;
+ f->inpmagic = INPUT_FILE_MAGIC;
+ strcpy (f->inpname, name);
+ slot = htab_find_slot (input_file_htab, f, INSERT);
+ gcc_assert (slot != NULL);
+ if (*slot)
+ {
+ /* Already known input file. */
+ free (f);
+ return (input_file*)(*slot);
+ }
+ /* New input file. */
+ *slot = f;
+ return f;
+ }
+
+/* Hash table support routines for input_file-s. */
+static hashval_t
+htab_hash_inputfile (const void *p)
+{
+ const input_file *inpf = (const input_file *) p;
+ gcc_assert (inpf);
+ return htab_hash_string (get_input_file_name (inpf));
+}
+
+static int
+htab_eq_inputfile (const void *x, const void *y)
+{
+ const input_file *inpfx = (const input_file *) x;
+ const input_file *inpfy = (const input_file *) y;
+ gcc_assert (inpfx != NULL && inpfy != NULL);
+ return !strcmp (get_input_file_name (inpfx), get_input_file_name (inpfy));
+}
+
+
int
main (int argc, char **argv)
{
@@ -4508,6 +4530,12 @@ main (int argc, char **argv)
/* Set the scalar_is_char union number for predefined scalar types. */
scalar_nonchar.u.scalar_is_char = FALSE;
scalar_char.u.scalar_is_char = TRUE;
+ /* Create the hash-table used to hash-cons input files. */
+ input_file_htab =
+ htab_create (800, htab_hash_inputfile, htab_eq_inputfile, NULL);
+ /* Initialize our special input files. */
+ this_file = input_file_by_name (__FILE__);
+ system_h_file = input_file_by_name ("system.h");
parse_program_options (argc, argv);
@@ -4519,7 +4547,7 @@ main (int argc, char **argv)
DBGPRINTF ("gengtype started pid %d at %s",
(int) getpid (), ctime (&now));
}
-#endif /* ENABLE_CHECKING */
+#endif /* ENABLE_CHECKING */
/* Parse the input list and the input files. */
DBGPRINTF ("inputlist %s", inputlist);
@@ -4535,38 +4563,27 @@ main (int argc, char **argv)
read_input_list. */
pos.file = this_file;
pos.line = __LINE__ + 1;
- do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
- pos.line++;
- 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++;
- do_scalar_typedef ("void", &pos);
- pos.line++;
- do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)),
- &pos);
+ do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
+ 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++;
+ do_scalar_typedef ("void", &pos); pos.line++;
+ do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
read_input_list (inputlist);
for (i = 0; i < num_gt_files; i++)
{
- parse_file (gt_files[i]);
- DBGPRINTF ("parsed file #%d %s", (int) i, gt_files[i]);
+ parse_file (get_input_file_name (gt_files[i]));
+ DBGPRINTF ("parsed file #%d %s", (int) i, get_input_file_name (gt_files[i]));
}
+ DBGPRINT_COUNT_TYPE ("structures after parsing", structures);
+ DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs);
if (verbosity_level >= 1)
printf ("%s parsed %d files\n", progname, (int) num_gt_files);
- DBGPRINT_COUNT_TYPE ("structures after parsing", structures);
- DBGPRINT_COUNT_TYPE ("param_structs after parsing", param_structs);
-
}
else
fatal ("either an input list or a read state file should be given");
@@ -4577,23 +4594,24 @@ main (int argc, char **argv)
if (plugin_output_filename)
{
size_t ix = 0;
- /* In plugin mode, we should have read a state file, and have
+ /* In plugin mode, we better have read a state file, and have
given at least one plugin file. */
if (!read_state_filename)
- fatal ("No read state given in plugin mode for %s",
- plugin_output_filename);
+ warning ("No read state given in plugin mode for %s", plugin_output_filename);
- if (nb_plugin_files == 0 || !plugin_files)
- fatal ("No plugin files given in plugin mode for %s",
- plugin_output_filename);
+ if (nb_plugin_files <= 0 || !plugin_files)
+ fatal ("No plugin files given in plugin mode for %s", plugin_output_filename);
/* Parse our plugin files. */
for (ix = 0; ix < nb_plugin_files; ix++)
- parse_file (plugin_files[ix]);
+ {
+ parse_file (get_input_file_name (plugin_files[ix]));
+ DBGPRINTF ("parsed plugin file #%d %s", (int) ix,
+ get_input_file_name (plugin_files[ix]));
+ }
if (hit_error)
return 1;
-
plugin_output = create_file ("GCC", plugin_output_filename);
DBGPRINTF ("created plugin_output %p named %s",
(void *) plugin_output, plugin_output->name);
Index: gcc/gengtype.h
===================================================================
--- gcc/gengtype.h (revision 165733)
+++ gcc/gengtype.h (working copy)
@@ -25,14 +25,117 @@
represented by a bitmap. */
typedef unsigned lang_bitmap;
-/* A file position, mostly for error messages.
- The FILE element may be compared using pointer equality. */
+/* Variable length structure representing an input file. A hash table
+ ensure uniqueness for a given input file name. The only function
+ allocating input_file-s is input_file_by_name. */
+struct input_file_st
+{
+#if ENABLE_CHECKING
+ /* The magic number is intended to help debugging gengtype. We
+ check that it is indeed what it should be. This could help
+ catching bugs where an input_file pointer is bogus. */
+ int inpmagic; /* Always INPUT_FILE_MAGIC. */
+#endif /*ENABLE_CHECKING*/
+ struct outf* inpoutf; /* Cached corresponding output file, computed
+ in get_output_file_with_visibility. */
+ lang_bitmap inpbitmap; /* The set of languages using this file. */
+ char inpname[1]; /* a flexible array, ended by a null char. */
+};
+typedef struct input_file_st input_file;
+
+#if ENABLE_CHECKING
+/* 0x371c433f is 924599103 in decimal, and was randomly choosen. The
+ input file magic number is intended to help catching bugs. */
+#define INPUT_FILE_MAGIC 0x371c433f
+ /* This is a fancy assert which displays a more precise message. It
+ should never happen! But it can help a lot when hacking
+ gengtype. */
+#define CHECK_INPUT_FILE_MAGIC(Inpf) \
+ do { \
+ const input_file* badinpf = Inpf; \
+ if (badinpf && badinpf->inpmagic != INPUT_FILE_MAGIC) \
+ fatal ("corrupted input file %p bad magic %d in %s:%d", \
+ (const void*) badinpf, badinpf->inpmagic, \
+ lbasename (__FILE__), __LINE__); \
+ } while (0)
+#else
+#define CHECK_INPUT_FILE_MAGIC(Inpf) do{} while (0)
+#endif /* ENABLE_CHECKING */
+
+/* Table of all input files, and its size. */
+extern input_file** gt_files;
+extern size_t num_gt_files;
+
+/* A number of places use the name of this "gengtype.c" file for a
+ location for things that we can't rely on the source to define. We
+ also need to refer to the "system.h" file specifically. These two
+ pointers are initialized early in main. */
+extern input_file* this_file;
+extern input_file* system_h_file;
+
+/* Retrieve or create the input_file for a given name, which is a file
+ path. This is the only function allocating input_file-s and it is
+ hash-consing them. */
+input_file* input_file_by_name (const char* name);
+
+
+/* For F an input_file, return the relative path to F from $(srcdir)
+ if the latter is a prefix in F, NULL otherwise. */
+const char *get_file_srcdir_relative_path (const input_file *inpf);
+
+/* Get the name of an input file. */
+static inline const char*
+get_input_file_name (const input_file *inpf)
+{
+ if (inpf)
+ {
+ CHECK_INPUT_FILE_MAGIC (inpf);
+ return inpf->inpname;
+ }
+ return NULL;
+}
+
+/* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
+ INPUT_FILE is used by <lang>.
+
+ This function should be written to assume that a file _is_ used
+ if the situation is unclear. If it wrongly assumes a file _is_ used,
+ a linker error will result. If it wrongly assumes a file _is not_ used,
+ some GC roots may be missed, which is a much harder-to-debug problem.
+ */
+
+static inline lang_bitmap
+get_lang_bitmap (const input_file* inpf)
+{
+ if (inpf == NULL)
+ return 0;
+ CHECK_INPUT_FILE_MAGIC (inpf);
+ return inpf->inpbitmap;
+}
+
+/* Set the bitmap returned by get_lang_bitmap. The only legitimate
+ callers of this function are read_input_list & read_state_*. */
+static inline void
+set_lang_bitmap (input_file* inpf, lang_bitmap n)
+{
+ gcc_assert (inpf);
+ CHECK_INPUT_FILE_MAGIC (inpf);
+ inpf->inpbitmap = n;
+}
+
+/* A file position, mostly for error messages. The FILE element may
+ be compared using pointer equality since it is hash-consed. */
struct fileloc
{
- const char *file;
+ const input_file *file;
int line;
};
+
+/* Vector of per-language directories. */
+extern const char **lang_dir_names;
+extern size_t num_lang_dirs;
+
/* Data types handed around within, but opaque to, the lexer and parser. */
typedef struct pair *pair_p;
typedef struct type *type_p;
@@ -67,10 +170,18 @@ oprintf (outf_p o, const char *S, ...)
ATTRIBUTE_PRINTF_2;
/* An output file, suitable for definitions, that can see declarations
- made in INPUT_FILE and is linked into every language that uses
- INPUT_FILE. May return NULL in plugin mode. */
-extern outf_p get_output_file_with_visibility (const char *input_file);
+ made in INPF and is linked into every language that uses INPF. May
+ return NULL in plugin mode. The INPF argument is almost const, but
+ since the result is cached in its inpoutf field it cannot be
+ declared const, because this function stores the computed output
+ file in that field to speed it up for further invocations. */
+outf_p get_output_file_with_visibility (input_file* inpf);
+/* The name of an output file, suitable for definitions, that can see
+ declarations made in INPF and is linked into every language that
+ uses INPF. May return NULL. */
+const char *get_output_file_name (input_file *inpf);
+
/* Source directory. */
extern const char *srcdir; /* (-S) program argument. */
Index: gcc/gengtype-lex.l
===================================================================
--- gcc/gengtype-lex.l (revision 165733)
+++ gcc/gengtype-lex.l (working copy)
@@ -1,6 +1,6 @@
/* -*- indented-text -*- */
/* Process source files and output type information.
- Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009
+ Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
@@ -24,7 +24,9 @@ along with GCC; see the file COPYING3. If not see
%{
#include "bconfig.h"
#include "system.h"
+#include "errors.h" /* for fatal, needed by gengtype.h */
+
#define malloc xmalloc
#define realloc xrealloc
@@ -202,7 +204,7 @@ yybegin (const char *fname)
perror (fname);
exit (1);
}
- lexer_line.file = fname;
+ lexer_line.file = input_file_by_name (fname);
lexer_line.line = 1;
}
Index: gcc/gengtype-parse.c
===================================================================
--- gcc/gengtype-parse.c (revision 165733)
+++ gcc/gengtype-parse.c (working copy)
@@ -1,5 +1,5 @@
/* Process source files and output type information.
- Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2010 Free Software Foundation, Inc.
This file is part of GCC.
@@ -19,6 +19,7 @@
#include "bconfig.h"
#include "system.h"
+#include "errors.h" /* for fatal, needed by gengtype.h */
#include "gengtype.h"
/* This is a simple recursive-descent parser which understands a subset of
@@ -135,7 +136,8 @@ parse_error (const char *msg, ...)
{
va_list ap;
- fprintf (stderr, "%s:%d: parse error: ", lexer_line.file, lexer_line.line);
+ fprintf (stderr, "%s:%d: parse error: ",
+ get_input_file_name (lexer_line.file), lexer_line.line);
va_start (ap, msg);
vfprintf (stderr, msg, ap);
@@ -708,6 +710,7 @@ static type_p
type (options_p *optsp, bool nested)
{
const char *s;
+ static int anonymous_count; /* To generate unique pseudo-identifiers! */
*optsp = 0;
switch (token ())
{
@@ -750,7 +753,32 @@ type (options_p *optsp, bool nested)
if (token () == ID)
s = advance ();
else
- s = xasprintf ("anonymous:%s:%d", lexer_line.file, lexer_line.line);
+ {
+ /* We don't want to wire in the source directory (because
+ in plugin mode, the source directory can be unavailable
+ since gengtype has read its state). So if the input is
+ from GCC source directory, we use its relative path to
+ build an anonymous unique tag. */
+ const char* relp = get_file_srcdir_relative_path (lexer_line.file);
+ anonymous_count++;
+ if (relp)
+ {
+ /* The input file is a GCC source file, we use a double
+ colon after anonymous. To be sure s is truly unique,
+ we also use anonymous_count. */
+ s = xasprintf ("anonymous::%s:%d::%d",
+ relp, lexer_line.line, anonymous_count);
+ }
+ else
+ {
+ /* The input file is outside of GCC source tree, we use
+ a single colon after anonymous. To be sure s is
+ truly unique, we also use anonymous_count. */
+ s = xasprintf ("anonymous:%s:%d::%d",
+ get_input_file_name (lexer_line.file),
+ lexer_line.line, anonymous_count);
+ }
+ }
/* Unfortunately above GTY_TOKEN check does not capture the
typedef struct_type GTY case. */
@@ -787,7 +815,19 @@ type (options_p *optsp, bool nested)
if (token () == ID)
s = advance ();
else
- s = xasprintf ("anonymous:%s:%d", lexer_line.file, lexer_line.line);
+ {
+ /* Again, we don't want to wire in the GCC source tree
+ directory. */
+ const char* relp = get_file_srcdir_relative_path (lexer_line.file);
+ anonymous_count++;
+ if (relp)
+ s = xasprintf ("anonymous::%s:%d::%d",
+ relp, lexer_line.line, anonymous_count);
+ else
+ s = xasprintf ("anonymous:%s:%d::%d",
+ get_input_file_name (lexer_line.file),
+ lexer_line.line, anonymous_count);
+ }
if (token () == '{')
consume_balanced ('{', '}');
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in (revision 165733)
+++ gcc/Makefile.in (working copy)
@@ -3893,9 +3893,10 @@ build/genextract.o : genextract.c $(RTL_BASE_H) $(
build/genflags.o : genflags.c $(RTL_BASE_H) $(OBSTACK_H) $(BCONFIG_H) \
$(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
build/gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
-build/gengtype-lex.o : gengtype-lex.c gengtype.h $(BCONFIG_H) $(SYSTEM_H)
+build/gengtype-lex.o : gengtype-lex.c gengtype.h $(BCONFIG_H) $(SYSTEM_H) \
+ errors.h
build/gengtype-parse.o : gengtype-parse.c gengtype.h $(BCONFIG_H) \
- $(SYSTEM_H)
+ $(SYSTEM_H) errors.h
build/gengtype.o : gengtype.c $(BCONFIG_H) $(SYSTEM_H) gengtype.h \
rtl.def insn-notes.def errors.h double-int.h $(HASHTAB_H)
build/genmddeps.o: genmddeps.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
next prev parent reply other threads:[~2010-10-20 20:09 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-21 19:41 gengtype improvements for plugins, thirdround! patch 1/7 [declprog] Basile Starynkevitch
2010-09-21 22:07 ` gengtype improvements for plugins, thirdround! patch 2/7 [verbosity] Basile Starynkevitch
2010-09-21 22:43 ` gengtype improvements for plugins, thirdround! patch 3/7 [inputfile] Basile Starynkevitch
2010-09-22 0:29 ` gengtype improvements for plugins, thirdround! patch 4/7 [filerules] Basile Starynkevitch
2010-09-22 1:50 ` gengtype improvements for plugins, thirdround! patch 5/7 [typedopt] Basile Starynkevitch
2010-09-22 1:58 ` gengtype improvements for plugins, thirdround! patch 6/7 [wstate] Basile Starynkevitch
2010-09-22 2:16 ` Basile Starynkevitch
2010-09-22 3:03 ` gengtype improvements for plugins, thirdround! patch 7/7 [doc] Basile Starynkevitch
2010-09-22 14:17 ` Laurynas Biveinis
2010-09-22 14:08 ` gengtype improvements for plugins, thirdround! patch 6/7 [wstate] Laurynas Biveinis
2010-09-22 12:13 ` gengtype improvements for plugins, thirdround! patch 5/7 [typedopt] Laurynas Biveinis
2010-09-23 19:17 ` Basile Starynkevitch
2010-09-23 19:29 ` Diego Novillo
2010-09-23 19:39 ` Richard Guenther
2010-09-22 12:06 ` gengtype improvements for plugins, thirdround! patch 4/7 [filerules] Laurynas Biveinis
2010-09-22 12:05 ` gengtype improvements for plugins, thirdround! patch 3/7 [inputfile] Laurynas Biveinis
2010-10-18 17:21 ` gengtype patch removing location_s Basile Starynkevitch
2010-10-19 6:57 ` Laurynas Biveinis
2010-10-19 7:11 ` Basile Starynkevitch
2010-10-19 7:27 ` Laurynas Biveinis
2010-10-19 7:29 ` Basile Starynkevitch
2010-10-19 8:17 ` Laurynas Biveinis
2010-10-19 8:49 ` Dave Korn
2010-10-19 16:38 ` Tom Tromey
2010-10-20 20:39 ` Basile Starynkevitch [this message]
2010-10-21 4:46 ` gengtype plugin improvement last2round - patch3 [inputfile] Laurynas Biveinis
2010-09-22 11:11 ` gengtype improvements for plugins, thirdround! patch 2/7 [verbosity] Laurynas Biveinis
2010-09-22 11:08 ` gengtype improvements for plugins, thirdround! patch 1/7 [declprog] Laurynas Biveinis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101020220935.cac67eac.basile@starynkevitch.net \
--to=basile@starynkevitch.net \
--cc=gcc-patches@gcc.gnu.org \
--cc=laurynas.biveinis@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).