]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gcc-plugin.h (plugin_event): Add PLUGIN_INFO.
authorRafael Avila de Espindola <espindola@google.com>
Thu, 16 Apr 2009 13:12:20 +0000 (13:12 +0000)
committerRafael Espindola <espindola@gcc.gnu.org>
Thu, 16 Apr 2009 13:12:20 +0000 (13:12 +0000)
2009-04-16  Rafael Avila de Espindola  <espindola@google.com>

* gcc-plugin.h (plugin_event): Add PLUGIN_INFO.
(plugin_info): New.
* opts.c (common_handle_option): Don't call print_version.
* plugin.c (plugin_name_args): Add version.
(register_plugin_info): New.
(register_callback): Handle PLUGIN_INFO.
(try_init_one_plugin): New.
(init_one_plugin): Use try_init_one_plugin. Only free plugin_name_args
if failed to init.
(finalize_one_plugin): New.
(finalize_plugins): New.
(print_one_plugin): New.
(print_plugins_versions): New.
* plugin.h (print_plugins_versions): New.
(finalize_plugins): New.
* toplev.c (compile_file): Don't call initialize_plugins.
(print_version): Call print_plugins_versions.
(toplev_main): Call initialize_plugins. Print version if needed.
Call finalize_plugins.

From-SVN: r146187

gcc/ChangeLog
gcc/gcc-plugin.h
gcc/opts.c
gcc/plugin.c
gcc/plugin.h
gcc/toplev.c

index cd6b608eed9b6ce287e9f1001b7a1a3519d60d0a..8179454cbe73ba7601a8b7b422e767f19c2873c4 100644 (file)
@@ -1,3 +1,25 @@
+2009-04-16  Rafael Avila de Espindola  <espindola@google.com>
+
+       * gcc-plugin.h (plugin_event): Add PLUGIN_INFO.
+       (plugin_info): New.
+       * opts.c (common_handle_option): Don't call print_version.
+       * plugin.c (plugin_name_args): Add version.
+       (register_plugin_info): New.
+       (register_callback): Handle PLUGIN_INFO.
+       (try_init_one_plugin): New.
+       (init_one_plugin): Use try_init_one_plugin. Only free plugin_name_args
+       if failed to init.
+       (finalize_one_plugin): New.
+       (finalize_plugins): New.
+       (print_one_plugin): New.
+       (print_plugins_versions): New.
+       * plugin.h (print_plugins_versions): New.
+       (finalize_plugins): New.
+       * toplev.c (compile_file): Don't call initialize_plugins.
+       (print_version): Call print_plugins_versions.
+       (toplev_main): Call initialize_plugins. Print version if needed.
+       Call finalize_plugins.
+
 2009-04-16  Rafael Avila de Espindola  <espindola@google.com>
 
        * common.opt (fversion): New.
index 4a45c1e2c4819387b112aa0eb55d10a25c4af6b5..8627720acd23221f3988b4f38737d7e1039788f5 100644 (file)
@@ -28,6 +28,7 @@ enum plugin_event
   PLUGIN_FINISH_UNIT,           /* Useful for summary processing.  */
   PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE.  */
   PLUGIN_FINISH,                /* Called before GCC exits.  */
+  PLUGIN_INFO,                  /* Information about the plugin */
   PLUGIN_EVENT_LAST             /* Dummy event used for indexing callback
                                    array.  */
 };
@@ -58,6 +59,13 @@ struct plugin_pass
   enum pass_positioning_ops pos_op; /* how to insert the new pass.  */
 };
 
+/* Additional information about the plugin. Used by --help and --version. */
+
+struct plugin_info
+{
+  const char *version;
+};
+
 /* Function type for the plugin initialization routine. Each plugin module
    should define this as an externally-visible function with name
    "plugin_init."
index 352ed5a5b714fe6adf2e3c33b00e632b9e3342bd..785e5d019ac699f7a84c76d2880a1a261926ba7e 100644 (file)
@@ -1563,7 +1563,6 @@ common_handle_option (size_t scode, const char *arg, int value,
 
     case OPT_fversion:
     case OPT__version:
-      print_version (stderr, "");
       exit_after_options = true;
       break;
 
index 92e88a8d5344093b9e90a457af82ac66c9ffcb98..95297a7d395f4fd14e8152d1af47d959cb415d07 100644 (file)
@@ -47,6 +47,7 @@ const char *plugin_event_name[] =
   "PLUGIN_FINISH_UNIT",
   "PLUGIN_CXX_CP_PRE_GENERICIZE",
   "PLUGIN_FINISH",
+  "PLUGIN_INFO",
   "PLUGIN_EVENT_LAST"
 };
 
@@ -59,6 +60,7 @@ struct plugin_name_args
   const char *full_name;
   int argc;
   struct plugin_argument *argv;
+  const char *version;
 };
 
 /* Hash table for the plugin_name_args objects created during command-line
@@ -450,6 +452,17 @@ register_pass (const char *plugin_name, struct plugin_pass *pass_info)
 }
 
 
+/* Register additional plugin information. NAME is the name passed to
+   plugin_init. INFO is the information that should be registered. */
+
+static void
+register_plugin_info (const char* name, struct plugin_info *info)
+{
+  void **slot = htab_find_slot (plugin_name_args_tab, name, NO_INSERT);
+  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
+  plugin->version = info->version;
+}
+
 /* Called from the plugin's initialization code. Register a single callback.
    This function can be called multiple times.
 
@@ -469,6 +482,9 @@ register_callback (const char *plugin_name,
       case PLUGIN_PASS_MANAGER_SETUP:
         register_pass (plugin_name, (struct plugin_pass *) user_data);
         break;
+      case PLUGIN_INFO:
+       register_plugin_info (plugin_name, (struct plugin_info *) user_data);
+       break;
       case PLUGIN_FINISH_TYPE:
       case PLUGIN_FINISH_UNIT:
       case PLUGIN_CXX_CP_PRE_GENERICIZE:
@@ -541,18 +557,11 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
 #define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q)
 #define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq)
 
-/* Routine to dlopen and initialize one plugin. This function is passed to
-   (and called by) the hash table traverse routine. Return 1 for the
-   htab_traverse to continue scan, 0 to stop.
+/* Try to initialize PLUGIN. Return true if successful. */
 
-   SLOT - slot of the hash table element
-   INFO - auxiliary pointer handed to hash table traverse routine
-          (unused in this function)  */
-
-static int
-init_one_plugin (void **slot, void * ARG_UNUSED (info))
+static bool
+try_init_one_plugin (struct plugin_name_args *plugin)
 {
-  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
   void *dl_handle;
   plugin_init_func plugin_init;
   char *err;
@@ -562,7 +571,7 @@ init_one_plugin (void **slot, void * ARG_UNUSED (info))
   if (!dl_handle)
     {
       error ("Cannot load plugin %s\n%s", plugin->full_name, dlerror ());
-      return 1;
+      return false;
     }
 
   /* Clear any existing error.  */
@@ -576,24 +585,41 @@ init_one_plugin (void **slot, void * ARG_UNUSED (info))
     {
       error ("Cannot find %s in plugin %s\n%s", str_plugin_init_func_name,
              plugin->full_name, err);
-      return 1;
+      return false;
     }
 
   /* Call the plugin-provided initialization routine with the arguments.  */
   if ((*plugin_init) (plugin->base_name, plugin->argc, plugin->argv))
     {
       error ("Fail to initialize plugin %s", plugin->full_name);
-      return 1;
+      return false;
     }
 
-  /* We can now delete the plugin_name_args object as it will no longer
-     be used. Note that base_name and argv fields (both of which were also
-     dynamically allocated) are not freed as they could still be used by
-     the plugin code.  */
-  XDELETE (plugin);
+  return true;
+}
+
+
+/* Routine to dlopen and initialize one plugin. This function is passed to
+   (and called by) the hash table traverse routine. Return 1 for the
+   htab_traverse to continue scan, 0 to stop.
+
+   SLOT - slot of the hash table element
+   INFO - auxiliary pointer handed to hash table traverse routine
+          (unused in this function)  */
 
+static int
+init_one_plugin (void **slot, void * ARG_UNUSED (info))
+{
+  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
+  bool ok = try_init_one_plugin (plugin);
+  if (!ok)
+    {
+      htab_remove_elt (plugin_name_args_tab, plugin->base_name);
+      XDELETE (plugin);
+    }
   return 1;
 }
+
 #endif /* ENABLE_PLUGIN  */
 
 /* Main plugin initialization function.  Called from compile_file() in
@@ -613,11 +639,73 @@ initialize_plugins (void)
   htab_traverse_noresize (plugin_name_args_tab, init_one_plugin, NULL);
 #endif
 
+  timevar_pop (TV_PLUGIN_INIT);
+}
+
+/* Release memory used by one plugin. */
+
+static int
+finalize_one_plugin (void **slot, void * ARG_UNUSED (info))
+{
+  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
+  XDELETE (plugin);
+  return 1;
+}
+
+/* Free memory allocated by the plugin system. */
+
+void
+finalize_plugins (void)
+{
+  if (!plugin_name_args_tab)
+    return;
+
+  /* We can now delete the plugin_name_args object as it will no longer
+     be used. Note that base_name and argv fields (both of which were also
+     dynamically allocated) are not freed as they could still be used by
+     the plugin code.  */
+
+  htab_traverse_noresize (plugin_name_args_tab, finalize_one_plugin, NULL);
+
   /* PLUGIN_NAME_ARGS_TAB is no longer needed, just delete it.  */
   htab_delete (plugin_name_args_tab);
   plugin_name_args_tab = NULL;
+}
 
-  timevar_pop (TV_PLUGIN_INIT);
+/* Used to pass options to htab_traverse callbacks. */
+
+struct print_options
+{
+  FILE *file;
+  const char *indent;
+};
+
+/* Print the version of one plugin. */
+
+static int
+print_version_one_plugin (void **slot, void *data)
+{
+  struct print_options *opt = (struct print_options *) data;
+  struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
+  const char *version = plugin->version ? plugin->version : "Unknown version.";
+
+  fprintf (opt->file, " %s%s: %s\n", opt->indent, plugin->base_name, version);
+  return 1;
+}
+
+/* Print the version of each plugin. */
+
+void
+print_plugins_versions (FILE *file, const char *indent)
+{
+  struct print_options opt;
+  opt.file = file;
+  opt.indent = indent;
+  if (!plugin_name_args_tab || htab_elements (plugin_name_args_tab) == 0)
+    return;
+
+  fprintf (file, "%sVersions of loaded plugins:\n", indent);
+  htab_traverse_noresize (plugin_name_args_tab, print_version_one_plugin, &opt);
 }
 
 
index 40f864c446b94514befb20af319d612c45acb06f..d8cf6919a4a9d058c42f0bdf4de5e343712db40b 100644 (file)
@@ -29,5 +29,7 @@ extern void initialize_plugins (void);
 extern bool plugins_active_p (void);
 extern void dump_active_plugins (FILE *);
 extern void debug_active_plugins (void);
+extern void print_plugins_versions (FILE *file, const char *indent);
+extern void finalize_plugins (void);
 
 #endif /* PLUGIN_H */
index 675cdf249cfb61f19b09492670a572d812e9e5c2..725c3762767035c985adb5e71b766eb1dc376cda 100644 (file)
@@ -969,7 +969,6 @@ compile_file (void)
   init_final (main_input_filename);
   coverage_init (aux_base_name);
   statistics_init ();
-  initialize_plugins ();
 
   timevar_push (TV_PARSE);
 
@@ -1164,6 +1163,8 @@ print_version (FILE *file, const char *indent)
           file == stderr ? _(fmt4) : fmt4,
           indent, *indent != 0 ? " " : "",
           PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
+
+  print_plugins_versions (file, indent);
 }
 
 #ifdef ASM_COMMENT_START
@@ -2273,6 +2274,11 @@ toplev_main (unsigned int argc, const char **argv)
 
   init_local_tick ();
 
+  initialize_plugins ();
+
+  if (version_flag)
+    print_version (stderr, "");
+
   /* Exit early if we can (e.g. -help).  */
   if (!exit_after_options)
     do_compile ();
@@ -2283,6 +2289,7 @@ toplev_main (unsigned int argc, const char **argv)
   /* Invoke registered plugin callbacks if any.  */
   invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
 
+  finalize_plugins ();
   if (errorcount || sorrycount)
     return (FATAL_EXIT_CODE);