cpp11-migrator を試してみた

[追記]

さっき気づいたんですが cpp11-migrate を行うとインクルードしているヘッダーファイル内も全て C++11 で書き換えられてしまうようです。
なのでインクルードしている標準ライブラリも書き換えられてしまうので注意して下さい。
回避方法はあるのかな…。

[関連]


LLVM/Clang に C++03 から C++11 のコードへと変換するツールがあるそうなので試してみました。

[導入]

cpp11-migrate は LLVM や Clang のソースコードには含まれていないようなので別にソースコードを落としておく必要があります。
cpp11-migrate は clang-tools-extra に含まれています。

$ cd llvm/tools/clang/tools
$ git clone http://llvm.org/git/clang-tools-extra.git extra


あとは普通に LLVM をビルドをビルドすれば実行バイナリ(cpp11-migrate)が吐出されます。

[使い方]

$ cpp11-migrate [options] <source0> [... <sourceN>]


詳しい使い方は cpp11-migrate User’s Manual を参照して下さい。

[使ってみた]

[コマンド]

$ cpp11-migrate -add-override -use-nullptr -loop-convert -use-auto main.cpp -- --std=c++11

[before]

#include <iostream>
#include <vector>

#define NULL 0

struct parent{
    virtual int age() = 0;
};

struct child : parent{
    virtual int age();
};


int
main(){
    std::vector<int> v;

    std::vector<int>::iterator first = v.begin();
    for(std::vector<int>::iterator it = first ; it != v.end() ; ++it){
        std::cout << *it << std::endl;
    }

    for(std::vector<int>::iterator it = v.begin() ; it != v.end() ; ++it){
        std::cout << *it << std::endl;
    }

    for(int i = 0 ; i < v.size() ; ++i){
        std::cout << v[i] << std::endl;
    }


    int* p = 0;
    int  n = NULL;
    float* p2 = NULL;

    return 0;
}

[after]

#include <iostream>
#include <vector>

#define NULL 0

struct parent{
    virtual int age() = 0;
};

struct child : parent{
    virtual int age() override;
};


int
main(){
    std::vector<int> v;

    auto first = v.begin();
    for(auto it = first ; it != v.end() ; ++it){
        std::cout << *it << std::endl;
    }

    for(auto & elem : v){
        std::cout << elem << std::endl;
    }

    for(auto & elem : v){
        std::cout << elem << std::endl;
    }

    int* p = nullptr;
    int  n = NULL;
    float* p2 = nullptr;

    return 0;
}


こんな感じで C++03 のコードを C++11 のコードへと変換します。
変換する構文はコマンドオプションにて指定します。
現在対応している構文は、

  • range-based for
  • nullptr
  • auto
  • override

の4つになります。
Clang ぱねぇ。
あと主旨とはちょっと違うけど、C++11 → C++03 への変換とかもある程度出来れば幸せになる人がいるかもしれませんね(震え声。

[注意]

変換結果は別のファイルに出力されるのではなくて元のファイルを書き換えてしまいます。
使用する場合はそこに注意して下さい。