5

LLVMには、LLVMContextストレージの単位でllvm::Moduleあるがあり、新しいシンボル(関数とタイプ)が構築される場所にあります。

私の質問は; コンパイルユニットに使用する正しいllvm抽象化は何ですか?Module?_ または、これは実際にはより広い範囲を対象としています。つまり、共有ライブラリターゲット

コンパイルユニットは、オールオアナッシングの結果を満たさなければならないように思えます。エラーなしですべてのコンテンツをコンパイルするか、エラーがあり、CU内のシンボルを使用する前に、修正して再構築する必要があります。私の頭の中では、これはコンパイルユニットが表すべきものの定義です

モジュールがCUの正しい抽象化である場合、他の(正しくコンパイルされた)Moduleオブジェクトのシンボルを、ビルドしようとしている新しいモジュールに提示して、それらを見つけることができるようにするにはどうすればよいですか?宣言を追加する必要がありますか、それとも他の迅速な方法がありますか?

の関連する行へのポイントclangは非常に役立ちます

4

2 に答える 2

5

モジュールは、コンパイル単位の正しい抽象化です。モジュールをリンクして、そこからプログラム全体の分析を行うことができます。

于 2012-03-24T19:24:07.290 に答える
4

これは私自身の質問に答えるための進行中の試みです:

このクラスllvm::Linkerには、複数のモジュールを取得して、既存のモジュールのすべてのシンボルを含む単一の複合モジュールを返す機能があります。リンクが完了し、複合モジュールが作成された後でも、入力モジュールの所有権に関する規則が何であるかはまだわかりません。

いずれにせよ、このクラスでは、モジュールを拡張するための増分パスを使用できるようにする必要があります。REPLを実装しようとしているとしましょう。これは、グローバル名前空間に新しいシンボルを追加することを意味します。

REPLの概要は次のように機能します。

  • REPLで関数を書く
  • 関数を単一のモジュールとしてコンパイルし、「ベース」と呼びます
  • REPLでさらにいくつかの関数を書く
  • 新しいモジュールで新しい関数をコンパイルします
  • 新しい関数モジュールが正常にコンパイルされた場合は、「base」と新しいモジュールを新しいモジュールにリンクし、「base.2」と呼びます。
  • すすぎ、繰り返します

    シンボルまたは関数を名前で置き換える場合は、古いシンボルにオーバーライドされたバージョンのシンボルが表示されるようにします。したがって、新しい関数を定義するときはgetOrInsertFunction、既存の「ベース」モジュールと新しいモジュールで自分が呼び出されていることを確認する必要があります。

于 2012-04-01T15:08:40.997 に答える