2011年9月29日木曜日

CLangでクラスの中身を調べる(3)

前回の続き。標準インクルードパスを設定する方法を探さねばならない。


クラス名的に最もクサイのはclang::HeaderSearchである。ということでHeaderSearchの.hから見てみると、SetSearchPaths()というAPIがある。
このAPIはclang::DirectoryLookupというクラスの配列を受け取る。これは単純にHeaderSearchのメンバ変数を書き換えるようだ。そちらのメンバ変数の説明によると

  • 最初にカレントフォルダを検索する。
  • 次に(当該メンバ変数)を順に検索する。
  • オプションで(当該メンバ変数)の検索開始インデックスを指定したり、カレントフォルダを検索しないようにできる。

という感じらしい。

DirectoryLookupはえーと・・・検索エントリで、単なるフォルダではなくフレームワーク?やヘッダマップ?も指定できるオブジェクトと説明があるがさっぱりわからない。DirectoryLookupは2種類のコンストラクタがあるが、そのうち片方ではclang::DirectoryEntryとclang::SrcMgr::CharacteristicKindを受け取る。DirectoryEntryは単にフォルダ名を格納するだけであるが、フォルダ名のセットAPIはない。代わりにFileManagerがfriend指定されているので、FileManagerから受け取るのだろう。CharacteristicKindは列挙でC_User, C_System, C_ExternCSystemが選べる。

FileManagerからDirectoryEntryを受け取る方法だが、単発のファイルパスの解決のときと同様、getDirectory()APIにファイルパス文字列を渡した結果として受け取れるようだ。

ってことで、以下のように実装してみる。
	llvm::StringRef stdHeaderPath1("C:\\Program Files (x86)\\Microsoft Visual Studio 8\\VC\\INCLUDE");
	llvm::StringRef stdHeaderPath2("C:\\Program Files (x86)\\Microsoft Visual Studio 8\\VC\\PlatformSDK\\include");
	std::vector<clang::directorylookup> stdHeaderPaths;
	{
		const clang::DirectoryEntry* p = fileMgr.getDirectory(stdHeaderPath1);
		clang::DirectoryLookup d(p, clang::SrcMgr::C_System, false, true);
		stdHeaderPaths.push_back(d);
	}
	{
		const clang::DirectoryEntry* p = fileMgr.getDirectory(stdHeaderPath2);
		clang::DirectoryLookup d(p, clang::SrcMgr::C_System, false, true);
		stdHeaderPaths.push_back(d);
	}
	headerSearch.SetSearchPaths(stdHeaderPaths, 0, false);

実行すると・・・まだダメ。headerSearchに追加したDirectoryLookupのLookupFile()は呼び出されているが、「フレームワーク」として登録されている場合、'/'文字が検索するファイルのパスに入ってないとダメらしい。フレームワークってboostとかclangとか、そういうのを指しているのか?

ためしにフーレムワーク指定をfalseにすると・・・今度は別の箇所でアサーションした。なるほど、標準ライブラリはフレームワークではないらしい。

ところで、ヘッダファイルが見つからないごときでアサーションが発生するのは勘弁してほしい気がする。次は先に進む前に、アサーションではなくエラーメッセージを表示させるようなことを考える。

0 件のコメント:

コメントを投稿