clang_complete

さて、前回も書きましたが OmniCppComplete (ctags)では補完されるコードに限界があります。
例えば、次のようなコードはうまく補完が行えません。

#include <boost/mpl/vector.hpp>

namespace mpl = boost::mpl;
mpl::    // ←ここでうまく補完されない。


そこで、clang_complete というプラグインを使用してみます。
clang_complete は現在開発中のコンパイラ『clang』を利用して、コードの補完を行ってくれるプラグインです。

☆環境

WindowsXP
gcc 4.5.0
・msvc2010(msvc2008)
・clang_complete
・clang 2.9

☆clang

clang とは、LLVM をバックエンドとして使用する次世代のコンパイラです。。
clang では『静的コード解析』を行うことができ、clang_complete は、それを使用して補完を行います。


さて、clang_complete を使用するのであれば、まず、clang のバイナリを用意する必要があります。
Windows であれば、clang のソースコードを落としてきて、gcc や msvc でビルドしてバイナリを作成する必要があります。
しかし、今回は、msvc2008 でビルドされた clang のバイナリが clang_complete 側で用意されているのでそれを使用したいと思います。
こちらからバイナリを落としてきて、適当な場所に保存しておいてください。
http://unitedsoft.ch/clang/clang.exe


Windows 以外や、自力でビルドを行う場合は、こちらを参照してください。
http://clang.llvm.org/get_started.html
https://github.com/Rip-Rip/clang_complete/wiki
http://lyuts.net/blog/2010/06/llvm-clang-mingw


☆clang でコード解析

バイナリからコード解析を行う場合は、次のようなコマンドを使用します。

clang -cc1 -fsyntax-only -code-completion-at=[ソースファイル]:[行番号]:[列番号]  [ソースファイル]


実際にコード解析を行うとこんな感じです。
[test.cpp]

int
main(){
    struct vec{
        int x, y, z;
    };
    vec v;
    v.    // ←ここでメンバを表示したい
}


[コマンド]

$ clang -cc1 -fsyntax-only -code-completion-at=test.cpp:7:7 test.cpp
COMPLETION: operator= : [#vec &#]operator=(<#const vec &#>)
COMPLETION: vec : vec::
COMPLETION: x : [#int#]x
COMPLETION: y : [#int#]y
COMPLETION: z : [#int#]z
COMPLETION: ~vec : [#void#]~vec()

こんな感じで、補完候補が出力されます。

☆clang_complete

プラグインはこちらから落としてきます。
https://github.com/Rip-Rip/clang_complete


設定はこんな感じです。

let g:clang_complete_auto=1
let g:clang_use_library=0
let g:clang_exec='"C:/clang/clang.exe'
let g:clang_user_options='-I D:/boost_1_45_0 -fms-extensions -fmsc-version=1300 -fgnu-runtime -D__MSVCRT_VERSION__=0x700 -D_WIN32_WINNT=0x0500 2> NUL || exit 0"'

これでコード補完を行う事ができます。
[※追記]
上記の設定で動かなければこちらを設定して試してみてください。

let g:clang_complete_auto=1
let g:clang_use_library=0
let g:clang_exec='"C:/clang/clang.exe'
let g:clang_user_options = '2> NUL || exit 0"'

☆所感

  • タグファイルを作成する必要がない
  • ctags を使うよりも補完の精度が高い
  • 補完に時間がかかってしまう
  • C++0x には未対応(?)


補完に関して IntelliSense のそれと殆ど変わらない精度を測ると思います。
しかし、やはり ctags に比べるとやはり遅いです。
補完速度が気になるようならば、

let g:clang_complete_auto=0

で、自動補完を無効にしておいたほうがいいです。
手動()で補完を行うので、ストレスは軽減されると思います。


ちなみにわたしの環境だと boost::array のメンバがうまく補完されませんでした。
原因は不明。試してないだけで他のライブラリも動かない可能性があるかも知れません。
gcc でビルドしたバイナリだと動いたので、msvcが原因???)

☆注意

わたしの環境では上記のような設定で動作することを確認しました。
しかし、環境によってはうまく動作しないかも知れません。
動作しなかった場合は、直接コマンドから clang を呼び出してみたり、clang へのコマンドがあっているかどうかを確認してみてください。


あ、ついでに neocomplcache が有効だとうまく補完がされませんでした。
曰く、clang_comple 側で何かオプションをいじっているんじゃないのか、との事。
まぁこれに関してもこれから調べてみます。


[参照]
http://clang.llvm.org/get_started.html
https://github.com/Rip-Rip/clang_complete/wiki
http://d.hatena.ne.jp/eagletmt/20101031/1288457112