さくらんぼのlambda日記

lambdaちっくなことからゲーム開発までいろいろ書きます。

clangで相互参照の情報解析

前回の記事の続きです。ソースコードから以下の情報を取りたいです。

  • 定義されている関数、変数の詳細
  • 関数、変数の参照関係

前回の内容では、「定義されている関数、変数の詳細」の情報は取得できました。ですが、「関数、変数の参照関係」を取る方法がわかりませんでした。

相互参照情報の取得

ソースを色々調べてみると、clangのサンプルの中のwpaではIndexerにTranslationUnitを渡してコールグラフの生成を行うコードがありました。コールグラフには参照情報が必須です。つまりIndexerを使えば参照情報の取得ができそうです。

Indexerの定義されているファイル付近(同じディレクトリ)で定義されているクラスもきっと有益なクラスに違いないと考え色々調べてみました。

  • clang/Index/

具体的には上記のディレクトリを眺めてみます。ざっくり眺めていると、以下のクラスが重要そうです。

  • clang::idx::Analyzer
  • clang::idx::Indexer
  • clang::idx::Program

このあたりのクラスで、プログラム中に現れている概念(clangではEntityと呼ぶ)の関連を調査できそうです。

  • clang::idx::Analyzer::findReferences

とかがかなりそれっぽいです。

clang::idx::Analyzerをつくろう

とりあえず、clang::idx::Analyzerをnewするところから始めたいので、コンストラクタを眺めてみます。

clang::idx::Analyzer::Analyzer ( Program &  prog,IndexProvider &  idxer);

clang::idx::Programとclang::idx::IndexProviderが引数みたいですね。Analyzerを作成する前に、これらを先にnewする必要がありますね。

Programクラス

Programのコンストラクタには引数がないので、何もしなくても作成できそうです。ついでにコメントに

\brief Top level object that owns and maintains information
that is common across translation units.

と書いてありますね。

IndexProvider

IndexProviderはvirtualなクラスなので、これをimplemantしているIndexerというクラスがすでにclangに用意されています。
なので、Indexerのコンストラクタを眺めてみます。…特に指定されてません。デフォルトでよさそうです。

Indexerのメンバには、Programもあります。なので、Indexerをひとつ作ってしまえば、Analyzerを作成できそうですね。また、Indexerのメソッドで興味深いものとしては

 /// \brief Find all Entities and map them to the given translation unit.
void IndexAST(TranslationUnit *TU);

このあたりでしょうか。

解析の流れ

ここまでの情報から、恐らくclangのAnalyzerの使い方としては以下を想定しているように見えます。

  1. Indexerを作る
  2. IndexerにTranslationUnitを複数個渡していく
  3. IndexerからAnalyzerを作成
  4. Analyzerで参照の情報を取得


Indexerを作るのは難しくないことがわかっているので、TranslationUnitを自由に作れるようにできれば、Analyzerを使えるようになるのではないかと予想できます。