clangとはC++の「静的コード解析」ができるコマンドラインツールです。
(本家)http://clang.llvm.org/get_started.html
clang (クラン(グ)のように発音 [2] )とは、C、C++、Objective-Cプログラミング言語向けのコンパイ
ラのフロントエンドであり、Low Level Virtual Machine (LLVM) をバックエンドとして使用する。
(wikipediaから引用)
(test2.cpp)
class foo{
int get();
void set(int x);
};
int hoge(foo &c){
c.
}
(コマンドライン)
clang.exe -cc1 -fsyntax-only -code-completion-at=test2.cpp:7:7 test2.cpp
COMPLETION: foo : foo::
COMPLETION: get : [#int#]get()
COMPLETION: operator= : [#foo &#]operator=(<#const foo &#>)
COMPLETION: set : [#void#]set(<#int x#>)
COMPLETION: ~foo : [#void#]~foo()
こんなかんじで、COMPLETION の後に補完候補が現われます。
とりあえず、秀丸エディタに組み込んでみました。
メソッドの補完
スコープも対応しています。変数cはスコープによって型が異なる。
std::stringのメソッド候補
クラス中でtypedefされた型の候補
operator[]
typedef も認識しています。
とりあえず作った秀丸マクロ
githubはこちら。(右上のダウンロードからzipを選択)
https://github.com/ohtorii/clang
$g_clang_exe = "C:\\Users\\hoge\\Documents\\hidemaru_macro\\clang\\clang.exe";
$g_include_dir[0] = "C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\include";
$g_include_dir[1] = "C:\\Program Files\\Microsoft Visual Studio 10.0\\VC\\atlmfc\\include";
$g_include_dir[2] = "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0A\\include";
#g_include_dir_num=3;
$g_define = "-DWIN32 -D_WINDOWS -DNDEBUG -D_MSC_VER=1600 -D__MSVCRT_VERSION__=0x700 -D_WIN32_WINNT=0x0500";
$g_option = "-cc1 -fsyntax-only -x c++ -fno-caret-diagnostics -fdiagnostics-print-source-range-info -std=c++0x -fms-extensions -fmsc-version=1600 -fgnu-runtime";
setcompatiblemode 0x0003|0x000c|0x0200|0x2000;
$old_searchbuffer = searchbuffer;
#old_searchoption = searchoption;
call Main;
setsearch $old_searchbuffer, #old_searchoption;
endmacro;
Main:
if("new"==filetype){
message("ファイルに保存してから試してください。\nこのマクロはサンプルなので手抜きです。");
return false;
}
if(updated){
message("ファイルが更新されています、まずは保存してから試してください。\nこのマクロはサンプルなので手抜きです。");
return false;
}
call MakeIncludeOption;
$$include = $$return;
if(0==strlen($$include)){
message("includeディレクトリが空白です。グローバル変数 $g_include_dir[] の定義が間違っているかも。");
return false;
}
$$fn = basename;
$$completion = "-code-completion-at=" + $$fn + ":"+str(lineno)+":"+str(column+1)+" " + $$fn;
$$arg = $g_option + " " + $$completion + " " + $g_define + " " + $$include;
title "running clang.";
##old_hidemaru = hidemaruhandle(0);
openfile "/h ";
disabledraw;
disableinvert;
##cur_hidemaru = hidemaruhandle(0);
runex $g_clang_exe + " " + $$arg, 1
, 0, ""
, 5, ""
, 0, ""
, 1, ""
, 2, 1, 0;
if(!result){
message("runexの呼び出しで失敗");
setactivehidemaru ##old_hidemaru;
closehidemaruforced ##cur_hidemaru;
return false;
}
gofiletop;
##guess_num = 0;
$$guess[0] = "";
$$guess_str = "";
searchdown2 "(?<=^COMPLETION:[ \\t]+)[^ ]+",casesense,regular,nohilight;
while(result){
$$tmp = gettext2(seltopcolumn,seltoplineno,selendcolumn,selendlineno);
if(strlen($$tmp)){
$$guess_str = $$guess_str + $$tmp + "\n";
$$guess[##guess_num] = $$tmp;
##guess_num = ##guess_num + 1;
}
finddown2;
}
if(##guess_num){
selectall;
backspace;
insert($$guess_str);
setactivehidemaru ##old_hidemaru;
autocomplete -1, 0x00000040, 0x00008000;
}else{
setactivehidemaru ##old_hidemaru;
}
closehidemaruforced ##cur_hidemaru;
title 0;
return true;
MakeIncludeOption:
##i = 0;
$$retult= "";
while(##i < #g_include_dir_num){
if(0 < ##i){
$$retult = $$retult + " ";
}
call ConvertShortFolderName $g_include_dir[##i];
$$short_name = $$return;
if(! strlen($$short_name)){
return"";
}
$$retult = $$retult + "-I" + $$short_name;
##i=##i+1;
}
return $$retult;
ConvertShortFolderName:
ConvertShortName:
$$fn = $$1;
##fso = createobject("Scripting.FileSystemObject");
##obj = callmethod_returnobj(##fso,"GetFolder",$$fn);
$$short_name = getpropstr(##obj,"ShortPath");
releaseobject(##fso);
return $$short_name;
今回書いた秀丸マクロについて(まとめ)
clangを使用して型を認識した補完が出来ましたが、ヘッダファイルを増やすと候補リストが表示されるまで時間がかかります。clangはプリコンパイルヘッダ(.PCH)が使用できるようなので、今後はその対応とかでしょうか。
今のところ常用できるほど高速ではないです。
常用できるようにするにはバックグランドで更新したりキャッシュを導入したりして高速化しないと駄目っぽいです。
参考になるマクロとか
clang_complete.vim
vimのマクロです。
clang.exeを呼び出すだけの素直な実装と、pythonのctypeモジュール経由で libclang.dll を呼び出す実装がある。
unix 環境だと libclang.so を呼び出すらしい。
auto-complete-clang.el
emacsのマクロです。
clang.exeを呼び出すだけの素直な実装っぽいです。