2013年07月17日

GCC のプラグインを作ってみる (2) C++ で g++ のプラグインを書いてみる

GCC はバージョン 4.8 から、実装言語が C++ になりました。というわけで、プラグインも今後は C++ で書きたいところです。また、せっかくなので、gcc ではなく g++ のプラグインを C++ で書いてみました。



参考サイト:Parsing C++ with GCC plugins, Part 2

とりあえず、g++ -4.7 をインストールします。

$ sudo apt-get install g++-4.7

以下のような g++ のプラグインを書いてみました。PLUGIN_OVERRIDE_GATE だと、何回もコールバックが呼び出されてしまうので、PLUGIN_FINISH_UNIT でコンパイル単位(cpp ファイル)が終わった時だけ、global namespace 内の宣言(の名前だけ)を表示するようにしてみました。

#include "gcc-plugin.h" /* must be the first */
#include "tm.h"         /* main_input_filename */

#include "cp/cp-tree.h" /* C++ */

#include <iostream>

int plugin_is_GPL_compatible;

/* gcc_data  - event-specific data provided by GCC
   user_data - plugin-specific data provided by the plug-in.  */

extern "C"
void finish_unit_callback(void *gcc_data, void *user_data)
{
    cp_binding_level *level = NAMESPACE_LEVEL(global_namespace);
    for (tree decl = level->names; decl != NULL; decl = TREE_CHAIN(decl)) {
	if (!DECL_IS_BUILTIN(decl)) {
	    tree id = DECL_NAME(decl);
	    if (id != NULL) {
		const char *name = IDENTIFIER_POINTER(id);
		std::cerr << name << std::endl;
	    }
	}
    }
}

extern "C"
int plugin_init(struct plugin_name_args *info, struct plugin_gcc_version *version)
{
    std::cerr << "main_input_filename: " << main_input_filename << std::endl;
    register_callback(info->base_name, PLUGIN_FINISH_UNIT, finish_unit_callback, NULL/* user_data */);
    return 0;
}

※ 参考サイトでは、プラグイン関係のヘッダを include する時、全体を extern "C" で囲んでいますが、どうも tree.h などを C リンケージで include すると、大量のエラーが出てしまいます。プラグインの API を定義する gcc-plugin.h で、__cplusplus の場合は extern "C" しているので、API だけ C リンケージで公開しておけば、とりあえず問題無さそうです。

ビルドと実行は、g++-4.7 を gcc-4.7 の代わりに使うだけです。(プラグインは、gcc でも読み込むことが可能ですが、C には namespace という概念が無いのでエラーになります。)

$ g++-4.7 -I`g++-4.7 -print-file-name=plugin`/include -fPIC -shared -O2 test_gcc_plugin.cpp -o test_gcc_plugin.so
$ cat test.cpp 
int g()
{
    return 123;
}

int f()
{
    return g();
}

int main()
{
    return 0;
}
$ g++-4.7 -fplugin=./test_gcc_plugin.so test.cpp
main_input_filename: test.cpp
main
f
g


トラックバックURL

コメントする

名前
URL
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード