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