@@ -123,7 +123,6 @@ struct type
-const char *get_output_file_name (const char *);
/* The list of output files. */
@@ -137,12 +136,12 @@ 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; in plugin mode only a
+ single file is produced. */
+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;
@@ -164,12 +163,11 @@ int verbosity_level;
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 *);
/* Nonzero iff an error has occurred. */
@@ -189,7 +187,8 @@ error_at_line (const struct fileloc *pos
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;
@@ -217,18 +216,17 @@ 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;
+
+/* Special files, initialized very early in main. */
+input_file* this_file; /* for gengtype.c */
+input_file* system_h_file; /* for system.h */
-/* A number of places use the name of this 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__;
-const char system_h_file[] = "system.h";
/* 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. */
@@ -246,37 +244,6 @@ static outf_p *base_files;
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 file are universal. */
- 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. */
@@ -468,11 +435,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 (;;)
{
@@ -502,13 +469,16 @@ 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 "
"for language %s", line, langno == 0
@@ -516,13 +486,13 @@ read_input_list (const char *listname)
: 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
@@ -745,16 +715,7 @@ new_structure (const char *name, int isu
write out its mark routine. */
if (!strcmp (name, "location_s") && !isunion
&& pos->file == this_file)
- {
- size_t n;
- for (n = 0; n < num_gt_files; n++)
- if (!strcmp (gt_files[n] + strlen (gt_files[n]) - strlen ("input.h"),
- "input.h"))
- {
- s->u.s.line.file = gt_files[n];
- break;
- }
- }
+ s->u.s.line.file = system_h_file;
return s;
}
@@ -893,7 +854,7 @@ note_variable (const char *s, type_p t,
/* 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)
+ input_file* inpf, int line)
{
pair_p field;
@@ -902,7 +863,7 @@ create_field_all (pair_p next, type_p ty
field->type = type;
field->name = name;
field->opt = opt;
- field->line.file = file;
+ field->line.file = inpf;
field->line.line = line;
return field;
}
@@ -1658,8 +1619,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;
@@ -1668,26 +1630,27 @@ get_file_realbasename (const char *f)
/* 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
+/* For F an input_file, return the relative path to F from $(srcdir) if the
latter is a prefix in F, or the real basename of F 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
@@ -1713,19 +1676,19 @@ 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 * r;
+ const char *srcdir_relative_path = get_file_srcdir_relative_path (inpf);
+ const char *r;
if (!srcdir_relative_path)
return NULL;
@@ -1742,16 +1705,16 @@ get_file_langdir (const char *f)
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)
@@ -1777,7 +1740,7 @@ get_file_gtfilename (const char *f)
INPUT_FILE. */
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;
@@ -1788,30 +1751,30 @@ get_output_file_with_visibility (const c
/* 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
@@ -1863,13 +1826,13 @@ get_output_file_with_visibility (const c
}
/* 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;
@@ -1951,7 +1914,7 @@ close_output_files (void)
struct flist {
struct flist *next;
int started_p;
- const char *name;
+ const input_file *file;
outf_p f;
};
@@ -2000,7 +1963,7 @@ static void write_local (outf_p output_h
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);
@@ -2471,7 +2434,7 @@ walk_type (type_p t, struct walk_type_da
{
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 +2602,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
@@ -3229,9 +3203,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 *fn)
{
- 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*, fn));
if (!f || !name)
return;
for (; *name != 0; name++)
@@ -3261,7 +3238,7 @@ finish_root_table (struct flist *flp, co
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)
@@ -3270,7 +3247,7 @@ finish_root_table (struct flist *flp, co
oprintf (base_files[fnum],
"extern const struct %s gt_%s_",
tname, pfx);
- put_mangled_filename (base_files[fnum], fli2->name);
+ put_mangled_filename (base_files[fnum], fli2->file);
oprintf (base_files[fnum], "[];\n");
}
}
@@ -3287,7 +3264,7 @@ finish_root_table (struct flist *flp, co
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;
@@ -3296,7 +3273,7 @@ finish_root_table (struct flist *flp, co
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");
}
}
@@ -3632,8 +3609,8 @@ write_roots (pair_p variables, bool emit
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");
@@ -4171,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
@@ -4461,12 +4438,64 @@ parse_program_options (int argc, char**a
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);
}
}
}
+
+/******* 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)
{
@@ -4479,6 +4508,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);
@@ -4516,10 +4551,11 @@ main (int argc, char **argv)
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]);
- }
+ for (i = 0; i < num_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)
@@ -4546,7 +4582,11 @@ main (int argc, char **argv)
/* 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;
@@ -25,13 +25,86 @@ along with GCC; see the file COPYING3.
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 {
+ 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;
+
+/* 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)
+ 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;
+ 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);
+ 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;
+ 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;
@@ -65,10 +138,14 @@ void 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. */
+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;
@@ -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,6 +24,7 @@ along with GCC; see the file COPYING3.
%{
#include "bconfig.h"
#include "system.h"
+#include "errors.h" /* for fatal, needed by gengtype.h */
#define malloc xmalloc
#define realloc xrealloc
@@ -202,7 +203,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;
}
@@ -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 @@ along with GCC; see the file COPYING3.
#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);
@@ -679,6 +681,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 ())
{
@@ -695,15 +698,15 @@ type (options_p *optsp, bool nested)
case UNION:
{
options_p opts = 0;
- /* GTY annotations follow attribute syntax
- GTY_BEFORE_ID is for union/struct declarations
- GTY_AFTER_ID is for variable declarations. */
- enum {
- NO_GTY,
- GTY_BEFORE_ID,
- GTY_AFTER_ID
- } is_gty = NO_GTY;
- bool is_union = (token () == UNION);
+ /* GTY annotations follow attribute syntax
+ GTY_BEFORE_ID is for union/struct declarations
+ GTY_AFTER_ID is for variable declarations. */
+ enum {
+ NO_GTY,
+ GTY_BEFORE_ID,
+ GTY_AFTER_ID
+ } is_gty = NO_GTY;
+ bool is_union = (token () == UNION);
advance ();
/* Top-level structures that are not explicitly tagged GTY(())
@@ -713,40 +716,62 @@ type (options_p *optsp, bool nested)
that we can't handle. */
if (nested || token () == GTY_TOKEN)
{
- is_gty = GTY_BEFORE_ID;
- opts = gtymarker_opt ();
+ is_gty = GTY_BEFORE_ID;
+ opts = gtymarker_opt ();
}
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. */
if (token () == GTY_TOKEN)
{
- is_gty = GTY_AFTER_ID;
- opts = gtymarker_opt ();
+ is_gty = GTY_AFTER_ID;
+ opts = gtymarker_opt ();
}
- if (is_gty)
- {
- if (token () == '{')
- {
- pair_p fields;
-
- if (is_gty == GTY_AFTER_ID)
- parse_error ("GTY must be specified before identifier");
-
- advance ();
- fields = struct_field_seq ();
- require ('}');
- return new_structure (s, is_union, &lexer_line, fields, opts);
- }
- }
- else if (token () == '{')
- consume_balanced ('{', '}');
+ if (is_gty)
+ {
+ if (token () == '{')
+ {
+ pair_p fields;
+
+ if (is_gty == GTY_AFTER_ID)
+ parse_error ("GTY must be specified before identifier");
+
+ advance ();
+ fields = struct_field_seq ();
+ require ('}');
+ return new_structure (s, is_union, &lexer_line, fields, opts);
+ }
+ }
+ else if (token () == '{')
+ consume_balanced ('{', '}');
if (opts)
*optsp = opts;
return find_structure (s, is_union);
@@ -754,11 +779,22 @@ type (options_p *optsp, bool nested)
case ENUM:
advance ();
- if (token () == ID)
- s = advance ();
- else
- s = xasprintf ("anonymous:%s:%d", lexer_line.file, lexer_line.line);
-
+ if (token () == ID)
+ s = advance ();
+ else
+ {
+ /* 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 ('{','}');
return create_scalar_type (s);