From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16407 invoked by alias); 21 Sep 2010 19:12:31 -0000 Received: (qmail 15806 invoked by uid 22791); 21 Sep 2010 19:12:22 -0000 X-SWARE-Spam-Status: No, hits=-0.1 required=5.0 tests=AWL,BAYES_50,TW_CP,TW_FL,TW_GT,TW_PF,TW_VF,TW_YY X-Spam-Check-By: sourceware.org Received: from smtp-152-tuesday.nerim.net (HELO maiev.nerim.net) (194.79.134.152) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 21 Sep 2010 19:12:12 +0000 Received: from hector.lesours (ours.starynkevitch.net [213.41.244.95]) by maiev.nerim.net (Postfix) with ESMTPS id 8190D2E00F; Tue, 21 Sep 2010 21:12:08 +0200 (CEST) Received: from glinka.lesours ([192.168.0.1] helo=glinka) by hector.lesours with smtp (Exim 4.72) (envelope-from ) id 1Oy8G8-0008HT-1m; Tue, 21 Sep 2010 21:12:08 +0200 Date: Tue, 21 Sep 2010 22:43:00 -0000 From: Basile Starynkevitch To: Basile Starynkevitch Cc: gcc-patches@gcc.gnu.org Subject: gengtype improvements for plugins, thirdround! patch 3/7 [inputfile] Message-Id: <20100921211217.df1ef337.basile@starynkevitch.net> In-Reply-To: <20100921210829.5f2ea8b0.basile@starynkevitch.net> References: <20100921210301.d92889be.basile@starynkevitch.net> <20100921210829.5f2ea8b0.basile@starynkevitch.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart=_Tue__21_Sep_2010_21_12_17_+0200_y=i=yR.oi8W2Hcjv" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2010-09/txt/msg01733.txt.bz2 This is a multi-part message in MIME format. --Multipart=_Tue__21_Sep_2010_21_12_17_+0200_y=i=yR.oi8W2Hcjv Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-length: 5157 Hello All, [join work by Basile Starynkevitch & Jeremie Salvucci] References: http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02060.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00616.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00663.html http://gcc.gnu.org/ml/gcc-patches/2010-08/msg02063.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00887.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01702.html http://gcc.gnu.org/ml/gcc-patches/2010-09/msg01706.html As I told in http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00808.html I am continuing to send the complete patch series of our gengtype work. This does not mean I am ignoring the recieved feedback. I intend to send a third round of patches once this "complete!" round is ended. I am taking into account most of Laurynas comments in http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00212.html with the important exception of INPUT_FILE_MAGIC, discussed below. Laurynas latter gave more feedback in http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00887.html that we did take into account. The gengtype-lex.l & gengtype-parse.c files need to include fatal.h because it is used from gengtype.h Laurynas thinks that adding a magic number don't bring anything and is just a temporary trick we (Jeremie & me Basile) used to code this patch. This is indeed true, but I (Basile) believe that this trick is really useful to future gengtype hackers, since input files are painfully reachable from types in a non-trivial way (and that very fact is an occasion for bugs). I would like opinion of other people, in particular of reviewers, on that issue. As I told before sending our patch serie, gengtype is difficult to understand, and we insist on defensive programming. And this INPUT_FILE_MAGIC used in macro CHECK_INPUT_FILE_MAGIC is exactly a case of defensive programming (disabled unless ENABLE_CHECKING is configured). It will be very probably useful to future gengtype hackers, so I pray the allmighty reviewers to consider accepting it. The http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00842.html previous version of this patch contained two variants, one with the INPUT_FILE_MAGIC trick and one without. I would prefer the magic trick to be included, since it will definitely help any brave or foolish :-) enough gengtype hacker. If you really want me to remove the trick before committing this patch, please ask. Notice that since I added the CHECK_INPUT_FILE_MAGIC macro, the trick don't need much lines in the patch. Since struct location_s is no longer used inside GCC, the hack in new_structure to handle it is removed. The attached patch is relative to the previous patch 2 [verbosity] sent This relative patch was obtained with diff -u -p -N $(svn stat | awk '/[AM]/{print $2}') \ --from-file ../thirdround_02_verbosity/ > \ $HOME/Gengtype_Thirdround/patch3_inputfile-relto02.diff ########## gcc/ChangeLog entry is 2010-09-20 Jeremie Salvucci Basile Starynkevitch * gengtype.c (get_output_file_name, plugin_files) (get_file_srcdir_relative_path, nb_plugin_files): moved to gengtype.h. (get_file_basename, get_file_realbasename, get_file_langdir): Use an input_file as argument. (error_at_line): Use input_file-s. (gt_files, num_gt_files, this_file, system_h_file): Declared as input_file-s. (lang_dir_names, num_lang_dirs): No static. (get_lang_bitmap, set_lang_bitmap): Moved to gengtype.h. (read_input_list): Use input_file-s. (new_structure): Remove location_s hack. (creat_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): Use input_file-s. (struct flist): Removed name and added file field. (output_type_enum): Use input_file-s. (finish_root_table, write_roots): Use file not name field of struct flist. (dump_fileloc, parse_program_options): Use input_file-s. * gengtype.h (struct input_file_st, input_file): New structure and type. (INPUT_FILE_MAGIC, CHECK_INPUT_FILE_MAGIC): New macros. (gt_files, num_gt_files): New variables moved from gengtype.c. (this_file, system_h_file): New variables. (input_file_by_name): Declared new function. (get_input_file_name): New inline function. (get_lang_bitmap, set_lang_bitmap): Moved from gengtype.c and updated. (struct fileloc): field file changed type. (lang_dir_names, num_lang_dirs): moved from gengtype.c. (get_output_file_with_visibility, get_output_file_name): Use input_file-s. * gengtype-lex.l: Updated copyright year. Included errors.h. (yybegin): use input_file-s. * gengtype-parse.c: Updated copyright year. Included errors.h. (parse_error): Use input_file-s. (type): Generate anonymous names differently for GCC source input and other input. ########## Regards. -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basilestarynkevitchnet mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mine, sont seulement les miennes} *** --Multipart=_Tue__21_Sep_2010_21_12_17_+0200_y=i=yR.oi8W2Hcjv Content-Type: text/x-diff; name="patch3_inputfile-relto02.diff" Content-Disposition: attachment; filename="patch3_inputfile-relto02.diff" Content-Transfer-Encoding: 7bit Content-length: 35129 --- ../thirdround_02_verbosity//gengtype.c 2010-09-20 22:35:07.000000000 +0200 +++ gcc/gengtype.c 2010-09-21 11:02:01.000000000 +0200 @@ -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; @@ -169,12 +168,11 @@ static const char* backup_dir; 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. */ @@ -194,7 +192,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; @@ -222,68 +221,24 @@ 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_' set iff - INPUT_FILE is used by . - - 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 @@ -477,11 +432,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 (;;) { @@ -511,13 +466,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 @@ -525,13 +483,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 @@ -750,21 +708,6 @@ new_structure (const char *name, int isu if (s->u.s.lang_struct) s->u.s.lang_struct->u.s.bitmap |= bitmap; - /* Reset location_s's location to input.h so that we know where to - 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; - } - } - return s; } @@ -902,7 +845,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) + const input_file* inpf, int line) { pair_p field; @@ -911,7 +854,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; } @@ -1667,8 +1610,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; @@ -1677,26 +1621,28 @@ 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 - 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 @@ -1722,19 +1668,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; @@ -1751,16 +1697,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) @@ -1786,7 +1732,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; @@ -1797,30 +1743,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 @@ -1872,13 +1818,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; @@ -1970,7 +1916,7 @@ close_output_files (void) struct flist { struct flist *next; int started_p; - const char *name; + const input_file *file; outf_p f; }; @@ -2019,7 +1965,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); @@ -2490,7 +2436,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)) @@ -2658,16 +2604,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 @@ -3248,9 +3205,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++) @@ -3280,7 +3240,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) @@ -3289,7 +3249,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"); } } @@ -3306,7 +3266,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; @@ -3315,7 +3275,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"); } } @@ -3651,8 +3611,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"); @@ -4190,8 +4150,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 @@ -4424,89 +4384,142 @@ print_version (void) static void parse_program_options (int argc, char**argv) { - int opt = -1; + int opt = -1; while ((opt = getopt_long (argc, argv, "hvVdP:S:B:I:w:r:D", - gengtype_long_options, NULL)) >= 0) + gengtype_long_options, NULL)) >= 0) { - switch (opt) + switch (opt) { case 'h': /* --help */ - print_usage (); - break; + print_usage (); + break; case 'v': /* --verbose */ verbosity_level++; break; case 'V': /* --version */ - print_version (); - break; + print_version (); + break; case 'd': /* --dump */ - do_dump = 1; - break; + do_dump = 1; + break; case 'D': /* --debug */ - do_debug = 1; - break; + do_debug = 1; + break; case 'P': /* --plugin */ - if (optarg) - plugin_output_filename = optarg; - else - fatal ("missing plugin output file name"); - break; + if (optarg) + plugin_output_filename = optarg; + else + fatal ("missing plugin output file name"); + break; case 'S': /* --srcdir */ - if (optarg) - srcdir = optarg; - else - fatal ("missing source directory"); - srcdir_len = strlen (srcdir); - break; + if (optarg) + srcdir = optarg; + else + fatal ("missing source directory"); + srcdir_len = strlen (srcdir); + break; case 'B': /* --backupdir */ - if (optarg) - srcdir = optarg; - else - fatal ("missing backup directory"); - srcdir_len = strlen (srcdir); - break; + if (optarg) + srcdir = optarg; + else + fatal ("missing backup directory"); + srcdir_len = strlen (srcdir); + break; case 'I': /* --inputs */ - if (optarg) - inputlist = optarg; - else - fatal ("missing input list"); - break; + if (optarg) + inputlist = optarg; + else + fatal ("missing input list"); + break; case 'r': /* --read-state */ - if (optarg) - read_state_filename = optarg; - else - fatal ("missing read state file"); - DBGPRINTF ("read state %s\n", optarg); - break; + if (optarg) + read_state_filename = optarg; + else + fatal ("missing read state file"); + DBGPRINTF ("read state %s\n", optarg); + break; case 'w': /* --write-state */ - DBGPRINTF ("write state %s\n", optarg); - if (optarg) - write_state_filename = optarg; - else - fatal ("missing write state file"); - break; + DBGPRINTF ("write state %s\n", optarg); + if (optarg) + write_state_filename = optarg; + else + fatal ("missing write state file"); + break; default: - fprintf (stderr, "%s: unknown flag '%c'\n", progname, opt); - print_usage (); - fatal ("unexpected flag"); - } + fprintf (stderr, "%s: unknown flag '%c'\n", progname, opt); + print_usage (); + fatal ("unexpected flag"); + } }; - if (plugin_output_filename) + if (plugin_output_filename) { - /* In plugin mode we require some input files. */ - int i = 0; - if (optind >= argc) - fatal ("no source files given in plugin mode"); - nb_plugin_files = argc - optind; - for (i = 0; i < (int) nb_plugin_files; i++) - { - char *name = argv[i + optind]; - plugin_files[i] = name; - } + /* In plugin mode we require some input files. */ + int i = 0; + if (optind >= argc) + fatal ("no source files given in plugin mode"); + nb_plugin_files = argc - optind; + for (i = 0; i < (int) nb_plugin_files; i++) + { + char *name = argv[i + optind]; + 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) { @@ -4519,6 +4532,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); @@ -4557,10 +4576,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) @@ -4586,11 +4606,14 @@ 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; - plugin_output = create_file ("GCC", plugin_output_filename); DBGPRINTF ("created plugin_output %p named %s", (void*) plugin_output, plugin_output->name); --- ../thirdround_02_verbosity//gengtype.h 2010-09-20 22:03:42.000000000 +0200 +++ gcc/gengtype.h 2010-09-21 10:27:50.000000000 +0200 @@ -25,13 +25,116 @@ 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 { +#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_' set iff + INPUT_FILE is used by . + + 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; + 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 +168,17 @@ 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. 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; --- ../thirdround_02_verbosity//gengtype-lex.l 2010-09-21 07:40:27.000000000 +0200 +++ gcc/gengtype-lex.l 2010-09-21 07:34:33.000000000 +0200 @@ -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; } --- ../thirdround_02_verbosity//gengtype-parse.c 2010-09-21 07:40:34.000000000 +0200 +++ gcc/gengtype-parse.c 2010-09-21 07:36:06.000000000 +0200 @@ -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 ()) { @@ -713,40 +716,61 @@ 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 +778,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); --Multipart=_Tue__21_Sep_2010_21_12_17_+0200_y=i=yR.oi8W2Hcjv Content-Type: application/octet-stream; name="cumulatedpatch3_inputfile-gengtypethird-r164437.diff.gz" Content-Disposition: attachment; filename="cumulatedpatch3_inputfile-gengtypethird-r164437.diff.gz" Content-Transfer-Encoding: base64 Content-length: 21188 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 beBWqxpfMmi83TtV5fuJldfGVl7DyjEaq9akdtmpTdhUGRP2LljG3PTVug2b 8HRp3cNinmmWz9Hble+0ZQjR+PvaR3O0hQ5yPxp0dqHwoI17Yy7scZuP31pb rS05f9PsUWsc9o3K8Fm3jQlv9o3jZ902lmsBcuO4sgk1J7RxNAX0Zhl6ISFV RaPJl4sn7mtl+nCVYH2TF6ZcPWFHZCJ7auVusR4TV1pN2JhsW88tAXZrXfbU rc01b3OlYjpv95IsslsvbK32jp10LbO5uJ7bfijGgJ7gluVcbsa6ih93S46n xg2FBHM5DAtoFwBADWNQM6tZKaK/pUF0qw8c0FKMzWqT+tztXOE4Ih5nurSz I8u6pbASi3MIBpUgm/uihyFJYQX0O2CT7Pq+CB+DpFFuq8tnh9Shy1HXUy2u LrEDPCWdaaB1wXpR2yl95fCbO0WzbBBBba/UtogFv63FB81Cq3OqeFLZP7c6 leKuPGOCK9D1SWGqxUtgc2/4iibtlr1OWSWx+w6i9NHp6XJbhZk+LH+zf/C3 Tx/fHp/9rF/+D/ZVe+6HlfuowrNmxBfDXOpsCMSv5hje6TFwmTZ6uxcVgDh/ Jq9E9oawdAuN2QYU+Z+54pRnxkJl2G6j2GWR+lFw+jc6aE5LYDyrJ4TwGT2/ eOWV/OP0KOfJWU1PsfaSICtjFVb9xDfFw4A8gB9bmBqNlTXJUL7DctQtPH8l ul35hkVoulK//tx2vmHpse+1zZa16/W4s0CkGotGpCv20eBtmgD2fpz31zpI JFg46vh4MXoAv8W9VmoV54R2H7xaGpLuovF/XO9aj/enckBZ37A1B9XRdtMo cp6z/7l2fqQLHsKqKPhAMS1phNf16A4ViG1XUecHm0OMOXutjOhLNMyrQ3G6 blx2sK+akguhUx4Y9ug+JvnSkDbHR7DcRh8mnBW3as6KeQLmtS/sxBkwR8XN /zCxg7rkIUZChfNEAvKIuZFuI0cdDJpTG6KnWXWdYA+LXUtaQTeDB+0t0dpu rfJd6c0Nx1ZCd5Q4wAIakXtFXBgWX1hW98h7zVyqsX3MG0WMDwsWRmsKQL4G 5ieVjOGhcF4ZBwdRIBFQMrk1AKUXzT2oXTeiDXazH2KYkk5QaCYyjEoYgea0 VT1Vf1Hdro/6Q3Yd4N29gPWKRXdau72h24Nh906QqQ3cxbucqci1rLH74Ng6 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 5Fhk9v8AfpvXuVrYAAA= --Multipart=_Tue__21_Sep_2010_21_12_17_+0200_y=i=yR.oi8W2Hcjv--