[llvm-commits] [gcc-plugin] r80755 - /gcc-plugin/trunk/gcc-patches/gengtype.diff

Duncan Sands baldrick at free.fr
Tue Sep 1 20:10:04 PDT 2009


Author: baldrick
Date: Tue Sep  1 22:10:04 2009
New Revision: 80755

URL: http://llvm.org/viewvc/llvm-project?rev=80755&view=rev
Log:
Patch by Basile STARYNKEVITCH that fixes gengtype
so it actually works when used with plugins, rather
than just nearly working.

Added:
    gcc-plugin/trunk/gcc-patches/gengtype.diff

Added: gcc-plugin/trunk/gcc-patches/gengtype.diff
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/gcc-patches/gengtype.diff?rev=80755&view=auto

==============================================================================
--- gcc-plugin/trunk/gcc-patches/gengtype.diff (added)
+++ gcc-plugin/trunk/gcc-patches/gengtype.diff Tue Sep  1 22:10:04 2009
@@ -0,0 +1,737 @@
+Index: lto/gcc/doc/plugins.texi
+===================================================================
+--- lto.orig/gcc/doc/plugins.texi	2009-09-01 00:16:27.962891836 +0200
++++ lto/gcc/doc/plugins.texi	2009-09-01 10:21:15.728775623 +0200
+@@ -226,12 +226,16 @@
+ their own @code{GTY}-ed data. This can be done with the
+ @code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and
+ the extra root table as @code{user_data}.  Running the @code{gengtype
+--p @var{source-dir} @var{file-list} @var{plugin*.c} ...} utility
+-generates this extra root table.
++-P @file{gt-plugin.h} @var{source-dir} @var{file-list} @var{plugin*.c}
++...} utility generates this extra root table, with the PCH related
++generated code kept wrapped with the @code{#ifdef
++GCC_PLUGIN_HAVE_PCH}, so disabled by default.
+ 
+ You should understand the details of memory management inside GCC
+ before using @code{PLUGIN_GGC_MARKING} or
+- at code{PLUGIN_REGISTER_GGC_ROOTS}.
++ at code{PLUGIN_REGISTER_GGC_ROOTS}.  Notice that using plugins which
++need these features may break the generation of precompiled headers
++[PCH], unless these plugins take specific measures.
+ 
+ 
+ @section Giving information about a plugin
+Index: lto/gcc/gengtype.c
+===================================================================
+--- lto.orig/gcc/gengtype.c	2009-09-01 10:20:35.755693766 +0200
++++ lto/gcc/gengtype.c	2009-09-01 10:21:15.732708428 +0200
+@@ -24,6 +24,7 @@
+ #include "errors.h"	/* for fatal */
+ #include "double-int.h"
+ 
++
+ /* Data types, macros, etc. used only in this file.  */
+ 
+ /* Kinds of types we can understand.  */
+@@ -64,6 +65,7 @@
+   type_p type;
+   struct fileloc line;
+   options_p opt;
++  bool inplugin;		/* flag set if appearing inside a plugin */
+ };
+ 
+ #define NUM_PARAM 10
+@@ -83,6 +85,7 @@
+   type_p next;
+   type_p pointer_to;
+   enum gc_used_enum gc_used;
++  bool inplugin;
+   union {
+     type_p p;
+     struct {
+@@ -145,6 +148,12 @@
+    directory.  */
+ static char** plugin_files;
+ static int nb_plugin_files;
++/* index of first plugin file in gt_files */
++static int first_plugin_file_ix= -1;
++/* the generated plugin output name & file */
++static char* plugin_output_filename;
++static outf_p plugin_output;
++
+ 
+ /* The output header file that is included into pretty much every
+    source file.  */
+@@ -167,12 +176,16 @@
+ 
+ 
+ /* Nonzero iff an error has occurred.  */
+-bool hit_error = false;
++bool hit_error = FALSE;
++/* Flag set when parsing a plugin file */
++bool is_plugin_file = FALSE;
++
+ 
+ static void gen_rtx_next (void);
+ static void write_rtx_next (void);
+ static void open_base_files (void);
+ static void close_output_files (void);
++static void output_delayed_functions (void);
+ 
+ /* Report an error at POS, printing MSG.  */
+ 
+@@ -465,8 +478,19 @@
+       if (plugin_files) 
+ 	{
+ 	  int i;
++	  first_plugin_file_ix = nfiles;
+ 	  for (i = 0; i < nb_plugin_files; i++)
+-	    gt_files[nfiles++] = plugin_files[i];
++	    {
++	      /* Each added entry in gt_files should have additional
++		 space for its lang_bitmap before.  */
++	      int plugfilen = strlen (plugin_files[i]);
++	      char* plugent =
++		(char*) xcalloc (1, plugfilen+1 + sizeof (lang_bitmap));
++	      plugent += sizeof (lang_bitmap);
++	      strcpy(plugent, plugin_files[i]);
++	      gt_files[nfiles++] = plugent;
++	      /* We don't bother freeing plugent ! */
++	    }
+ 	}
+       num_gt_files = nfiles;
+     }
+@@ -512,17 +536,18 @@
+ /* The one and only TYPE_STRING.  */
+ 
+ static struct type string_type = {
+-  TYPE_STRING, 0, 0, GC_USED, {0}
++  TYPE_STRING, 0, 0, GC_USED, false, {0}
+ };
+ 
+ /* The two and only TYPE_SCALARs.  Their u.scalar_is_char flags are
+    set to appropriate values at the beginning of main.  */
+ 
+ static struct type scalar_nonchar = {
+-  TYPE_SCALAR, 0, 0, GC_USED, {0}
++  TYPE_SCALAR, 0, 0, GC_USED, false, {0}
+ };
++
+ static struct type scalar_char = {
+-  TYPE_SCALAR, 0, 0, GC_USED, {0}
++  TYPE_SCALAR, 0, 0, GC_USED, false, {0}
+ };
+ 
+ /* Lists of various things.  */
+@@ -663,8 +688,9 @@
+ 		     isunion ? "union" : "struct", s->u.s.tag);
+       error_at_line (&s->u.s.line, "previous definition here");
+     }
+-
++  
+   s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
++  s->inplugin = is_plugin_file;
+   s->u.s.tag = name;
+   s->u.s.line = *pos;
+   s->u.s.fields = fields;
+@@ -709,6 +735,7 @@
+   s->next = structures;
+   structures = s;
+   s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
++  s->inplugin = is_plugin_file;
+   s->u.s.tag = name;
+   structures = s;
+   return s;
+@@ -732,6 +759,7 @@
+     {
+       res = XCNEW (struct type);
+       res->kind = TYPE_PARAM_STRUCT;
++      res->inplugin = is_plugin_file;
+       res->next = param_structs;
+       param_structs = res;
+       res->u.param_struct.stru = t;
+@@ -760,6 +788,7 @@
+     {
+       type_p r = XCNEW (struct type);
+       r->kind = TYPE_POINTER;
++      r->inplugin = is_plugin_file;
+       r->u.p = t;
+       t->pointer_to = r;
+     }
+@@ -775,6 +804,7 @@
+ 
+   v = XCNEW (struct type);
+   v->kind = TYPE_ARRAY;
++  v->inplugin = is_plugin_file;
+   v->u.a.p = t;
+   v->u.a.len = len;
+   return v;
+@@ -819,6 +849,7 @@
+   n->line = *pos;
+   n->opt = o;
+   n->next = variables;
++  n->inplugin = is_plugin_file;
+   variables = n;
+ }
+ 
+@@ -1492,6 +1523,9 @@
+   f = XCNEW (struct outf);
+   f->next = output_files;
+   f->name = oname;
++  i = f->buflength = 4096;
++  f->buf = XNEWVEC (char, i);
++  f->bufused = 0;
+   output_files = f;
+ 
+   oprintf (f, "/* Type information for %s.\n", name);
+@@ -1508,7 +1542,7 @@
+ void
+ oprintf (outf_p o, const char *format, ...)
+ {
+-  char *s;
++  char *s = NULL;
+   size_t slength;
+   va_list ap;
+ 
+@@ -1516,7 +1550,11 @@
+      in that case.  */
+   if (!o) 
+     return;
+-
++  
++  gcc_assert (o->buf != NULL);
++  
++  gcc_assert (o->bufused <= o->buflength);
++  
+   va_start (ap, format);
+   slength = vasprintf (&s, format, ap);
+   if (s == NULL || (int)slength < 0)
+@@ -1526,16 +1564,24 @@
+   if (o->bufused + slength > o->buflength)
+     {
+       size_t new_len = o->buflength;
++      char *oldbuf = o->buf;
+       if (new_len == 0)
+ 	new_len = 1024;
+       do {
+ 	new_len *= 2;
+       } while (o->bufused + slength >= new_len);
+-      o->buf = XRESIZEVEC (char, o->buf, new_len);
++      o->buf = XNEWVEC (char, new_len);
++      if (oldbuf) 
++	{
++	  memcpy(o->buf, oldbuf, o->bufused);
++	  oldbuf[0] = 0;
++	}
++      free (oldbuf);
+       o->buflength = new_len;
+     }
+   memcpy (o->buf + o->bufused, s, slength);
+   o->bufused += slength;
++  gcc_assert (o->bufused <= o->buflength);
+   free (s);
+ }
+ 
+@@ -1546,10 +1592,13 @@
+ {
+   size_t i;
+ 
+-  if (nb_plugin_files > 0 && plugin_files)
++  if (nb_plugin_files > 0 && plugin_files) 
+     return;
+-
++  
++  /* header file should be generated even in plugin mode */
+   header_file = create_file ("GCC", "gtype-desc.h");
++  
++
+ 
+   base_files = XNEWVEC (outf_p, num_lang_dirs);
+ 
+@@ -1567,7 +1616,8 @@
+       "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", 
++      NULL
+     };
+     const char *const *ifp;
+     outf_p gtype_desc_c;
+@@ -1712,15 +1762,19 @@
+     input_file = "system.h";
+ 
+   /* In plugin mode, return NULL unless the input_file is one of the
+-     plugin_files.  */
++     plugin_files or is the specified plugin_output_filename.  */
+   if (plugin_files && nb_plugin_files > 0) 
+     { 
+       int ix= -1, i;
+       for (i = 0; i < nb_plugin_files && ix < 0; i++)
+-      if (strcmp (input_file, plugin_files[i]) == 0) 
+-	ix = i;
+-      if (ix < 0) 
++	if (strcmp (input_file, plugin_files[i]) == 0) 
++	  ix = i;
++      if (ix < 0
++	  && plugin_output_filename
++	  && strcmp (input_file, plugin_output_filename)) 
+ 	return NULL;
++      if (plugin_output_filename)
++	return plugin_output;
+     }
+ 
+   /* Determine the output file name.  */
+@@ -1763,9 +1817,9 @@
+ 
+       if (lang_index >= 0)
+ 	return base_files[lang_index];
+-
++      
+       output_name = "gtype-desc.c";
+-      for_name = NULL;
++      for_name = "GCC";
+     }
+ 
+   /* Look through to see if we've ever seen this output filename before.  */
+@@ -1832,6 +1886,9 @@
+ 	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;
+     }
+ }
+ 
+@@ -1864,6 +1921,7 @@
+   const char *reorder_note_routine;
+   const char *comment;
+   int skip_hooks;		/* skip hook generation if non zero */
++  int is_pch;			/* set for PCH stuff to output ifndef  */
+ };
+ 
+ static void output_escaped_param (struct walk_type_data *d,
+@@ -1873,6 +1931,7 @@
+ static void write_func_for_structure
+      (type_p orig_s, type_p s, type_p * param,
+       const struct write_types_data *wtd);
++static void delay_func_for_structure (type_p s, 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,
+@@ -2587,6 +2646,8 @@
+     }
+   oprintf (d.of, " (void *x_p)\n");
+   oprintf (d.of, "{\n");
++  if (plugin_output && d.of == plugin_output && wtd->is_pch)
++    oprintf (d.of, "#ifdef GCC_PLUGIN_HAVE_PCH\n");
+   oprintf (d.of, "  %s %s * %sx = (%s %s *)x_p;\n",
+ 	   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
+ 	   chain_next == NULL ? "const " : "",
+@@ -2691,6 +2752,8 @@
+   oprintf (d.of, "    }\n");
+   if (chain_circular != NULL)
+     oprintf (d.of, "  while (x != xlimit);\n");
++  if (plugin_output && d.of == plugin_output && wtd->is_pch)
++    oprintf (d.of, "/* end ifdef GCC_PLUGIN_HAVE_PCH*/\n#endif\n");
+   oprintf (d.of, "}\n");
+ }
+ 
+@@ -2701,8 +2764,9 @@
+ 	     const struct write_types_data *wtd)
+ {
+   type_p s;
+-
+-  oprintf (header_file, "\n/* %s*/\n", wtd->comment);
++  outf_p outheadf = plugin_output_filename ? plugin_output : header_file;
++  
++  oprintf (outheadf, "\n/* %s*/\n", wtd->comment);
+   for (s = structures; s; s = s->next)
+     if (s->gc_used == GC_POINTED_TO
+ 	|| s->gc_used == GC_MAYBE_POINTED_TO)
+@@ -2713,13 +2777,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 (outheadf, "#define gt_%s_", wtd->prefix);
++	output_mangled_typename (outheadf, s);
++	oprintf (outheadf, "(X) do { \\\n");
++	oprintf (outheadf,
+ 		 "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
+ 		 s->u.s.tag);
+-	oprintf (header_file,
++	oprintf (outheadf,
+ 		 "  } while (0)\n");
+ 
+ 	for (opt = s->u.s.opt; opt; opt = opt->next)
+@@ -2729,7 +2793,7 @@
+ 	      if (t->kind == TYPE_STRUCT
+ 		  || t->kind == TYPE_UNION
+ 		  || t->kind == TYPE_LANG_STRUCT)
+-		oprintf (header_file,
++		oprintf (outheadf,
+ 			 "#define gt_%sx_%s gt_%sx_%s\n",
+ 			 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
+ 	      else
+@@ -2741,7 +2805,7 @@
+ 	  continue;
+ 
+ 	/* Declare the marker procedure only once.  */
+-	oprintf (header_file,
++	oprintf (outheadf,
+ 		 "extern void gt_%sx_%s (void *);\n",
+ 		 wtd->prefix, s->u.s.tag);
+ 
+@@ -2752,7 +2816,10 @@
+ 	    continue;
+ 	  }
+ 
+-	if (s->kind == TYPE_LANG_STRUCT)
++	/* in plugin mode, the write_func_for_structure should be delayed */
++	if (nb_plugin_files > 0 && plugin_output_filename)
++	  delay_func_for_structure (s, wtd);
++	else if (s->kind == TYPE_LANG_STRUCT)
+ 	  {
+ 	    type_p ss;
+ 	    for (ss = s->u.s.lang_struct; ss; ss = ss->next)
+@@ -2769,9 +2836,9 @@
+ 	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");
++	oprintf (outheadf, "extern void gt_%s_", wtd->prefix);
++	output_mangled_typename (outheadf, s);
++	oprintf (outheadf, " (void *);\n");
+ 
+ 	if (stru->u.s.line.file == NULL)
+ 	  {
+@@ -2795,6 +2862,7 @@
+ {
+   "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
+   "GC marker procedures.  ",
++  FALSE,
+   FALSE
+ };
+ 
+@@ -2803,6 +2871,7 @@
+   "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
+   "gt_pch_note_reorder",
+   "PCH type-walking procedures.  ",
++  TRUE,
+   TRUE
+ };
+ 
+@@ -2875,11 +2944,15 @@
+ 	   "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
+ 	   "\tATTRIBUTE_UNUSED void *cookie)\n");
+   oprintf (d.of, "{\n");
++  if (plugin_output && d.of == plugin_output)
++    oprintf (d.of, "#ifdef GCC_PLUGIN_HAVE_PCH\n");
+   oprintf (d.of, "  %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
+ 	   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
+ 	   s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
+   d.indent = 2;
+   walk_type (s, &d);
++  if (plugin_output && d.of == plugin_output)
++    oprintf (d.of, "/* end ifdef GCC_PLUGIN_HAVE_PCH */\n#endif\n");
+   oprintf (d.of, "}\n");
+ }
+ 
+@@ -2888,11 +2961,13 @@
+ static void
+ write_local (type_p structures, type_p param_structs)
+ {
++  outf_p outheadf = plugin_output_filename ? plugin_output : header_file;
++
+   type_p s;
+ 
+-  if (!header_file) 
++  if (!outheadf) 
+     return;
+-  oprintf (header_file, "\n/* Local pointer-walking routines.  */\n");
++  oprintf (outheadf, "\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)
+@@ -2910,11 +2985,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 (outheadf, "#define gt_pch_p_");
++		  output_mangled_typename (outheadf, s);
++		  oprintf (outheadf, " gt_pch_p_");
++		  output_mangled_typename (outheadf, t);
++		  oprintf (outheadf, "\n");
+ 		}
+ 	      else
+ 		error_at_line (&s->u.s.line,
+@@ -2925,9 +3000,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 (outheadf, "extern void gt_pch_p_");
++	output_mangled_typename (outheadf, s);
++	oprintf (outheadf,
+ 	 "\n    (void *, void *, gt_pointer_operator, void *);\n");
+ 
+ 	if (s->kind == TYPE_LANG_STRUCT)
+@@ -2947,9 +3022,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 (outheadf, "extern void gt_pch_p_");
++	output_mangled_typename (outheadf, s);
++	oprintf (outheadf,
+ 	 "\n    (void *, void *, gt_pointer_operator, void *);\n");
+ 
+ 	if (stru->u.s.line.file == NULL)
+@@ -2970,17 +3045,60 @@
+       }
+ }
+ 
+-/* Write out the 'enum' definition for gt_types_enum.  */
++/* Write out only to header_file the 'enum' definition for gt_types_enum.  */
+ 
+ static void
+ write_enum_defn (type_p structures, type_p param_structs)
+ {
+-  type_p s;
+-
++  type_p s = NULL;
++  /* in plugin mode, define dynamically the enumeration values */
++  if (plugin_output)
++    {
++      int cnt = 0;
++      oprintf (plugin_output, "\n/* Dynamic enumeration of plugin types.  */\n");
++      oprintf (plugin_output, "#ifdef GCC_PLUGIN_HAVE_PCH\n");
++      oprintf (plugin_output, "static int gccplugin_type_base;\n");
++      
++      for (s = structures; s; s = s->next)
++	{
++	  if (!s->inplugin)
++	    continue;
++	  if (s->gc_used == GC_POINTED_TO
++	      || s->gc_used == GC_MAYBE_POINTED_TO)
++	    {
++	      if (s->gc_used == GC_MAYBE_POINTED_TO
++		  && s->u.s.line.file == NULL)
++		continue;
++	      oprintf (plugin_output, "#define gt_ggc_e_");
++	      output_mangled_typename (plugin_output, s);
++	      oprintf (plugin_output,
++		       " ((gccplugin_type_base>0)?(gccplugin_type_base+%d):0)\n",
++		       cnt);
++	      cnt++;
++	    }
++	}
++      for (s = param_structs; s; s = s->next)
++	if (s->gc_used == GC_POINTED_TO && s->inplugin)
++	  {
++	    oprintf (plugin_output, "#define gt_e_");
++	    output_mangled_typename (plugin_output, s);
++	    oprintf (plugin_output,
++		     " ((gccplugin_type_base>0)?(gccplugin_type_base+%d):0)\n",
++		     cnt);
++	    cnt++;
++	  }
++      oprintf (plugin_output,
++	       "\n#define GCCPLUGIN_TYPE_COUNT %d\n", cnt);
++      oprintf (plugin_output, "/* end ifdef GCC_PLUGIN_HAVE_PCH */\n#endif\n");
++      return;
++    }
++  
++  /* write only to header_file */
+   if (!header_file) 
+     return;
+-  oprintf (header_file, "\n/* Enumeration of types known.  */\n");
++  oprintf (header_file, "\n/* Enumeration of known types.  */\n");
+   oprintf (header_file, "enum gt_types_enum {\n");
++  oprintf (header_file, "  gt_types_enum_firstempty,\n");
+   for (s = structures; s; s = s->next)
+     if (s->gc_used == GC_POINTED_TO
+ 	|| s->gc_used == GC_MAYBE_POINTED_TO)
+@@ -3332,12 +3450,15 @@
+ 
+   for (v = variables; v; v = v->next)
+     {
+-      outf_p f = get_output_file_with_visibility (v->line.file);
++      outf_p f = NULL;
+       struct flist *fli;
+       const char *length = NULL;
+       int deletable_p = 0;
+       options_p o;
+-
++      if (nb_plugin_files > 0 && plugin_output_filename && v->inplugin)
++	f = plugin_output;
++      else
++	f = get_output_file_with_visibility (v->line.file);
+       for (o = v->opt; o; o = o->next)
+ 	if (strcmp (o->name, "length") == 0)
+ 	  length = o->info;
+@@ -3629,6 +3750,74 @@
+   do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
+ }
+ 
++
++/* in plugin mode, the write of functions for structure is delayed to
++   the end; we keep a vector of these */
++struct delayedstructfunc_st 
++{
++  type_p dly_s;
++  const struct write_types_data* dly_wtd;
++};
++static struct delayedstructfunc_st* dlystructab;
++static int dlystructsiz;
++static int dlystructcnt;
++
++
++
++
++static void
++delay_func_for_structure (type_p s, const struct write_types_data* wtd)
++{
++  gcc_assert (s != NULL);
++  gcc_assert (wtd != NULL);
++  if (dlystructcnt + 1 >= dlystructsiz)
++    {
++      struct delayedstructfunc_st* oldtab = dlystructab;
++      int oldsiz = dlystructsiz;
++      int newsiz = (32 + oldsiz) * 2;
++      int i = 0;
++      gcc_assert (newsiz > dlystructcnt);
++      dlystructab = XNEWVEC(struct delayedstructfunc_st, newsiz);
++      for (i = 0; i < dlystructcnt; i++)
++	dlystructab[i] = oldtab[i];
++      for (i = dlystructcnt; i < newsiz; i++)
++	{
++	  dlystructab[i].dly_s = NULL;
++	  dlystructab[i].dly_wtd = NULL;
++	}
++      dlystructsiz = newsiz;
++      free (oldtab);
++    }
++  dlystructab[dlystructcnt].dly_s = s;
++  dlystructab[dlystructcnt].dly_wtd = wtd;
++  dlystructcnt++;
++}
++
++
++static void
++output_delayed_functions(void)
++{
++  int i = 0;
++  gcc_assert (plugin_output);
++  for (i = 0; i<dlystructcnt; i++)
++    {
++      type_p s = dlystructab[i].dly_s;
++      const struct write_types_data* wtd = dlystructab[i].dly_wtd;
++      gcc_assert (s != NULL && wtd != NULL);
++      if (s->kind == TYPE_LANG_STRUCT)
++	  {
++	    type_p ss;
++	    for (ss = s->u.s.lang_struct; ss; ss = ss->next)
++	      write_func_for_structure (s, ss, NULL, wtd);
++	  }
++	else
++	  write_func_for_structure (s, s, NULL, wtd);
++    }
++  free (dlystructab);
++  dlystructab = NULL;
++  dlystructcnt = dlystructsiz = 0;
++}
++
+ 
+ int
+ main (int argc, char **argv)
+@@ -3639,20 +3828,23 @@
+   /* fatal uses this */
+   progname = "gengtype";
+ 
+-  if (argc >= 5 && !strcmp (argv[1], "-p")) 
++  if (argc >= 6 && !strcmp (argv[1], "-P"))
+     {
+-      srcdir = argv[2];
+-      inputlist = argv[3];
+-      plugin_files = argv+4;
+-      nb_plugin_files = argc-4;
++      plugin_output_filename = argv[2];
++      plugin_output = create_file ("GCC", plugin_output_filename);
++      srcdir = argv[3];
++      inputlist = argv[4];
++      plugin_files = argv + 5;
++      nb_plugin_files = argc - 5;
+     }
++  
+   else if (argc == 3) 
+     {
+       srcdir = argv[1];
+       inputlist = argv[2];
+     } 
+   else
+-    fatal ("usage: gengtype [-p] srcdir input-list [file1 file2 ... fileN]");
++    fatal ("usage: gengtype [-P pluginout.h] srcdir input-list [file1 file2 ... fileN]");
+ 
+   srcdir_len = strlen (srcdir);
+ 
+@@ -3678,9 +3870,14 @@
+   do_scalar_typedef ("void", &pos); pos.line++;
+   do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
+ 
+-  for (i = 0; i < num_gt_files; i++)
+-    parse_file (gt_files[i]);
+-
++  for (i = 0; i < num_gt_files; i++) 
++    {
++      is_plugin_file = first_plugin_file_ix >= 0
++	&& (int)i >= first_plugin_file_ix;
++      parse_file (gt_files[i]);
++      is_plugin_file = false;
++    }
++  
+   if (hit_error)
+     return 1;
+ 
+@@ -3693,6 +3890,10 @@
+   write_local (structures, param_structs);
+   write_roots (variables);
+   write_rtx_next ();
++  
++  if (plugin_output)
++    output_delayed_functions ();
++  
+   close_output_files ();
+ 
+   if (hit_error)
+Index: lto/gcc/gengtype.h
+===================================================================
+--- lto.orig/gcc/gengtype.h	2009-09-01 00:16:27.942856818 +0200
++++ lto/gcc/gengtype.h	2009-09-01 10:21:15.728775623 +0200
+@@ -76,6 +76,9 @@
+ extern void parse_file (const char *name);
+ extern bool hit_error;
+ 
++/* flag set when parsing a plugin file */
++extern bool is_plugin_file;
++
+ /* Token codes.  */
+ enum {
+   EOF_TOKEN = 0,





More information about the llvm-commits mailing list