2013-04-16

LLVMによる自動C++11移行ツール

LLVM Project Blog: Status of the C++11 Migrator

先月のRSSフィードに一瞬だけ現れたのだが、すぐ消えてしまった記事が復活した。

cpp11-migrateは、LLVMのツールに含まれる、既存のコードをC++11に変換する移行ツールである。

現在のところ、四種類の変換が可能だ。

STLコンテナーや配列の要素をループでなめるコードをRange-based forに変換する。

こんないけてないコードが、

std::vector<int> myVec;
for (std::vector<int>::iterator I = myVec.begin(),
                                E = myVec.end();
     I != E; ++I)
  llvm::outs() << *I;

こんなに格好良くなる。

std::vector<int> myVec;
for (auto & elem : myVec)
  llvm::outs() << elem;

nullポインターの値としての0やNULLの利用を、nullポインターリテラルであるnullptrに変換。

こんないけてないコードが、

int * ptr1 = 0 ;
int * ptr2 = NULL ;

nullポインターリテラルのキーワードを利用したまともなコードに変わる。

int * ptr1 = nullptr ;
int * ptr2 = nullptr ;

auto指定子の変換。

auto指定子は、ほとんどの変数の宣言を置き換えることができるが、このツールでは、特殊な場合のみを置き換える。

STLコンテナーのイテレーター

こんなイケてないコードが、

void f( std::vector< std::string > & v )
{
    std::vector< std::string >::iterator iter = v.begin() ;
}

こんなに超絶カッチョイイコードに早変わり。

void f( std::vector< std::string > & v )
{
    auto iter = v.begin() ;
}

new式を受け取る。

こんな冗長で誤りの元なコードが、

MyType * ptr = new MyType() ;
MyType * const ptr = new MyType() ;

すっきりする。

auto * ptr = new MyType() ;
auto * const ptr = new MyType() ;

これで、変数の型名を間違えてつまらないコンパイルエラーになることはない。

overrideの付加

virtual関数がオーバーライドしている場合、overrideを自動的につけてくれる。

こんなコードでも

struct Base
{
    virtual void func() { }
} ;

struct Derived : Base
{
    virtual void func() { }
} ;

こうなる。

struct Base
{
    virtual void func() { }
} ;

struct Derived : Base
{
    virtual void func() override { }
} ;

関数名のtypoなどといったつまらない間違いをコンパイル時にエラーにできる。

予定されている将来の機能追加では、TR1のライブラリを正式な標準ライブラリに置き換えるだとか、auto_ptrの利用を置き換えるなどといった置換が提案されている。

LLVMの強力な解析とハックしやすいコードベースの力と言えるだろう。GCCの地位がますます脅かされる。

No comments: