(root)/
gcc-13.2.0/
gcc/
testsuite/
g++.dg/
plugin/
dumb_plugin.c
       1  /* A trivial (dumb) plugin example that shows how to use the GCC plugin
       2     mechanism.  */
       3  
       4  #include "gcc-plugin.h"
       5  #include <stdlib.h>
       6  #include "config.h"
       7  #include "system.h"
       8  #include "coretypes.h"
       9  #include "tree.h"
      10  #include "tree-pass.h"
      11  #include "intl.h"
      12  #include "toplev.h"
      13  #include "diagnostic.h"
      14  #include "context.h"
      15  
      16  int plugin_is_GPL_compatible;
      17  
      18  /* Callback function to invoke after GCC finishes parsing a struct.  */
      19  
      20  void
      21  handle_struct (void *event_data, void *data)
      22  {
      23    tree type = (tree) event_data;
      24    warning (0, G_("Process struct %s"),
      25             IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
      26  }
      27  
      28  /* Callback function to invoke before the function body is genericized.  */ 
      29  
      30  void
      31  handle_pre_generic (void *event_data, void *data)
      32  {
      33    tree fndecl = (tree) event_data;
      34    warning (0, G_("Before genericizing function %s"),
      35             IDENTIFIER_POINTER (DECL_NAME (fndecl)));
      36  }
      37  
      38  /* Callback function to invoke after GCC finishes the compilation unit.  */
      39  
      40  void
      41  handle_end_of_compilation_unit (void *event_data, void *data)
      42  {
      43    warning (0, G_("End of compilation unit"));
      44  }
      45  
      46  
      47  namespace {
      48  
      49  const pass_data pass_data_dumb_plugin_example =
      50  {
      51    GIMPLE_PASS, /* type */
      52    "dumb_plugin_example", /* name */
      53    OPTGROUP_NONE, /* optinfo_flags */
      54    TV_NONE, /* tv_id */
      55    PROP_cfg, /* properties_required */
      56    0, /* properties_provided */
      57    0, /* properties_destroyed */
      58    0, /* todo_flags_start */
      59    0, /* todo_flags_finish */
      60  };
      61  
      62  class pass_dumb_plugin_example : public gimple_opt_pass
      63  {
      64  public:
      65    pass_dumb_plugin_example(gcc::context *ctxt)
      66      : gimple_opt_pass(pass_data_dumb_plugin_example, ctxt)
      67    {}
      68  
      69    /* opt_pass methods: */
      70    virtual unsigned int execute (function *);
      71  
      72  }; // class pass_dumb_plugin_example
      73  
      74  unsigned int
      75  pass_dumb_plugin_example::execute (function *)
      76  {
      77    warning (0, G_("Analyze function %s"),
      78             IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
      79    return 0;
      80  }
      81  
      82  } // anon namespace
      83  
      84  static gimple_opt_pass *
      85  make_pass_dumb_plugin_example (gcc::context *ctxt)
      86  {
      87    return new pass_dumb_plugin_example (ctxt);
      88  }
      89  
      90  /* Initialization function that GCC calls. This plugin takes an argument
      91     that specifies the name of the reference pass and an instance number,
      92     both of which determine where the plugin pass should be inserted.  */
      93  
      94  int
      95  plugin_init (struct plugin_name_args *plugin_info,
      96               struct plugin_gcc_version *version)
      97  {
      98    struct register_pass_info pass_info;
      99    const char *plugin_name = plugin_info->base_name;
     100    int argc = plugin_info->argc;
     101    struct plugin_argument *argv = plugin_info->argv;
     102    char *ref_pass_name = NULL;
     103    int ref_instance_number = 0;
     104    int i;
     105  
     106    /* Process the plugin arguments. This plugin takes the following arguments:
     107       ref-pass-name=<PASS_NAME> and ref-pass-instance-num=<NUM>.  */
     108    for (i = 0; i < argc; ++i)
     109      {
     110        if (!strcmp (argv[i].key, "ref-pass-name"))
     111          {
     112            if (argv[i].value)
     113              ref_pass_name = argv[i].value;
     114            else
     115              warning (0, G_("option '-fplugin-arg-%s-ref-pass-name'"
     116                             " requires a pass name"), plugin_name);
     117          }
     118        else if (!strcmp (argv[i].key, "ref-pass-instance-num"))
     119          {
     120            if (argv[i].value)
     121              ref_instance_number = strtol (argv[i].value, NULL, 0);
     122            else
     123              warning (0, G_("option '-fplugin-arg-%s-ref-pass-instance-num'"
     124                             " requires an integer value"), plugin_name);
     125          }
     126        else
     127          warning (0, G_("plugin %qs: unrecognized argument %qs ignored"),
     128                   plugin_name, argv[i].key);
     129      }
     130  
     131    if (!ref_pass_name)
     132      {
     133        error (G_("plugin %qs requires a reference pass name"), plugin_name);
     134        return 1;
     135      }
     136  
     137    pass_info.pass = make_pass_dumb_plugin_example (g);
     138    pass_info.reference_pass_name = ref_pass_name;
     139    pass_info.ref_pass_instance_number = ref_instance_number;
     140    pass_info.pos_op = PASS_POS_INSERT_AFTER;
     141  
     142    register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
     143  
     144    register_callback (plugin_name, PLUGIN_FINISH_TYPE, handle_struct, NULL);
     145  
     146    register_callback (plugin_name, PLUGIN_PRE_GENERICIZE,
     147                       handle_pre_generic, NULL);
     148  
     149    register_callback (plugin_name, PLUGIN_FINISH_UNIT,
     150                       handle_end_of_compilation_unit, NULL);
     151    return 0;
     152  }