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
handle_struct(void * event_data,void * data)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
handle_pre_generic(void * event_data,void * data)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
handle_end_of_compilation_unit(void * event_data,void * data)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:
pass_dumb_plugin_example(gcc::context * ctxt)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
execute(function *)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 *
make_pass_dumb_plugin_example(gcc::context * ctxt)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
plugin_init(struct plugin_name_args * plugin_info,struct plugin_gcc_version * version)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 }
153