ググって出てくるドキュメントには要注意。バージョンアップでI/Fが変更されている箇所が非常に多いのだ。だから正確な情報を得るには、CLangのソースコードの.hを見たり、.hや.cppに記述されているdoxygenスタイルコメントを読む必要がある。
では続き。
ドキュメントによるとプリプロセッサの実行はclang::Preprocessor::Lex関数によるようだ。そしてLex関数の引数はclang::Tokenで戻り値はvoidなので、引数がoutなんだろうと推測される。
しかし、今まで対象のファイルやフォルダを指定していない。何も指定せずにLex関数をコールするとどうなるだろうか?
clang::Token token; pp.Lex(token); 実行すると見事になにもエラーが発生しない。CLangは例外をthrowしないのか?
ということで対象ファイルを指定する方法を探す。前回ちょっと触ったクラスのうち、たぶんFileManagerあたりでファイルやフォルダを指定し、SourceManagerで読み込む、という感じではないかと推測して各クラスを調べる。
そしてFileManagerのヘッダを見ると、FileEntryとかDirectoryEntiryというのを返却するAPIがある。そしてSourceManagerのドキュメントを見ると、FileEntryを受け取るAPIとしてcreateFileID()やcreateMainFileID()がある。
createFileID()などはclang::FileIDを返す。そこでPreprocessorのヘッダを見ると、FileIDを引数に取るEnterSourceFile()や、引数はないけどFileIDとmain source fileに言及しているEnterMainSourceFile()がある。だいぶ見えてきた。
ということで、main source fileとmainじゃないsource fileの違いがよくわからないが、とりあえずmain source fileを処理しそうなコードを書いて実行してみる。
llvm::StringRef cppPath("D:\\develop\\Clang\\temp.cpp"); const clang::FileEntry* cppEntry = fileMgr.getFile(cppPath); clang::FileID fileId = srcMgr.createMainFileID(cppEntry); pp.EnterMainSourceFile(); clang::Token token; pp.Lex(token);ちなみにtemp.cppの中身はこんな感じ:
#include <cstdio> int main(int, char**) { std::printf("Hello,world\n"); std::getchar(); return 0; }
そうすると、clang::Preprocessor::Lex()の実行でアサーションされてしまった。コールスタックを見るとclang::Preprocessor::HandleIncludeDirective()という関数にて「Search include directories.」とコメントされている箇所で、処理結果の診断がNGになっているようだ。なるほど。
0 件のコメント:
コメントを投稿