GCCのプラグインを作ってみようとおもって,Webサイトのサンプルをみてみると,4.7や4.8を対象としているであろうサンプルが多々みつかる.プラグインは4.5以降でサポートされているけど,いろいろとバージョンで違いがあるよう.
たとえば,Narrow Escape GCC pluginを試してみるもその一つで,4.7を対象としたサンプルが掲載されている.
シンプルでよさそうなサンプルだったのでエントリとして試してみたかったのだけど,後半の方のサンプルはそのままだとコンパイルできなかったので,修正してみた.修正箇所はこんな感じ.
--- orig.cpp 2016-11-30 15:18:08.797853450 +0900
+++ my_gcc_plugin3.cpp 2016-11-30 15:02:28.085853450 +0900
@@ -1,14 +1,52 @@
#include <gcc-plugin.h>
#include <coretypes.h>
#include <diagnostic.h>
-#include <gimple.h>
#include <tree.h>
-#include <tree-flow.h>
+#include <function.h>
+#include <basic-block.h>
+#include <coretypes.h>
+#include <is-a.h>
+#include <predict.h>
+#include <internal-fn.h>
+#include <tree-ssa-alias.h>
+#include <gimple-expr.h>
+#include <gimple.h>
#include <tree-pass.h>
+#include <context.h>
#include <execinfo.h>
int plugin_is_GPL_compatible;
+namespace{
+
+const pass_data pass_data_PLUGIN_PASS_MANAGER_SETUP_pass =
+{
+ GIMPLE_PASS, /* type */
+ "PLUGIN_PASS_MANAGER_SETUP", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class PLUGIN_PASS_MANAGER_SETUP_pass : public gimple_opt_pass
+{
+public:
+ PLUGIN_PASS_MANAGER_SETUP_pass(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_PLUGIN_PASS_MANAGER_SETUP_pass, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *);
+ virtual unsigned int execute (function *);
+
+}; // class one_pass
+
+}
+
#define __pr_dbg(...) \
do { \
fprintf(stderr, __VA_ARGS__); \
@@ -86,38 +124,26 @@ static void pr_curr_func(void)
__pr_dbg(")\n");
}
-static bool PLUGIN_PASS_MANAGER_SETUP_gate(void)
+bool PLUGIN_PASS_MANAGER_SETUP_pass::gate(function *)
{
return true;
}
-static unsigned PLUGIN_PASS_MANAGER_SETUP_exec(void)
+unsigned PLUGIN_PASS_MANAGER_SETUP_pass::execute(function *)
{
pr_curr_func();
return 0;
}
-static struct gimple_opt_pass PLUGIN_PASS_MANAGER_SETUP_pass =
- {
- {
- .type = GIMPLE_PASS,
- .name = "PLUGIN_PASS_MANAGER_SETUP",
- .gate = PLUGIN_PASS_MANAGER_SETUP_gate,
- .execute = PLUGIN_PASS_MANAGER_SETUP_exec,
- }
- };
-
int plugin_init(struct plugin_name_args *args,
struct plugin_gcc_version *version)
{
- struct register_pass_info pass =
- {
- .pass = &PLUGIN_PASS_MANAGER_SETUP_pass.pass,
- .reference_pass_name = "cfg",
- .ref_pass_instance_number = 1,
- .pos_op = PASS_POS_INSERT_AFTER,
- };
- register_callback(args->base_name, PLUGIN_PASS_MANAGER_SETUP,
- NULL, &pass);
+ struct register_pass_info pass;
+ pass.pass = new PLUGIN_PASS_MANAGER_SETUP_pass(g);
+ pass.reference_pass_name = "cfg",
+ pass.ref_pass_instance_number = 1,
+ pass.pos_op = PASS_POS_INSERT_AFTER,
+
+ register_callback(args->base_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass);
return 0;
}
コンパイルするときも
g++ -Wall -I`g++ -print-file-name=plugin`/include -fPIC -fno-rtti -shared my_gcc_plugin3.cpp -o my_gcc_plugin3.so
と,-fno-rttiをつけないとシンボルが解決されなくて使えない.
詳しくはあとで.