(57)【要約】      （修正有）【課題】実行性能を向上させ、コードサイズを小さくするため、仮想関数呼び出しを関数の直接呼出しに変換可能なプログラム変換方法を提供する。【解決手段】  プログラム１１１中に含まれる全てのクラスを抽出してクラス間の継承関係を解析し、クラスの継承関係情報１１３を得る（Ｓ１０４）。クラスの仮想関数が基底クラスの仮想関数を再定義しているか否かを解析し、仮想関数再定義情報１１４を得る（Ｓ１０５）。プログラム１１１中で直接呼び出しされている仮想関数および起動オブジェクトを解析し、仮想関数直接呼び出し情報１１５を得る（Ｓ１０７）。クラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５を参照し、仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、変換可能な場合に関数の直接呼び出しに変換する（Ｓ１０８）。【選択図】図３
2006146613.tif 000002
【特許請求の範囲】
【請求項１】
オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、
前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、
前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップと、
前記メソッド解析ステップの解析結果に応じて、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップと
を含むことを特徴とするプログラム変換方法。
【請求項２】
前記メソッド解析ステップは、
前記プログラムにおいて、クラスの継承関係を解析するクラス継承関係解析ステップと、
前記クラスにおける前記仮想的なメソッドの再定義の状況を解析する仮想的メソッド再定義解析ステップと、
前記プログラムにおいて、前記仮想的なメソッドの直接的な呼び出しを解析する仮想的メソッド直接呼び出し解析ステップと、
前記クラス継承関係解析ステップ、前記仮想的メソッド再定義解析ステップおよび前記仮想的メソッド直接呼び出し解析ステップの解析結果に応じて、前記メソッドを呼び出す前記インスタンスの型を特定するインスタンス特定ステップとを含み、
前記仮想的メソッド呼び出し変換ステップは、前記メソッド解析ステップにより前記インスタンスの型が特定できる場合に、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッド呼び出しを直接的なメソッドの呼び出しに変換する
ことを特徴とする請求項１記載のプログラム変換方法。
【請求項３】
前記インスタンス特定ステップは、
前記メソッドの属するクラスが派生クラスを持つか否かを判定するステップと、
前記クラスが派生クラスを持つ場合、前記クラスを直接的に継承する全てのクラスで前記メソッドが再定義されているか否かを判定するステップと、
前記クラスの全ての派生クラスのインスタンスに対して前記メソッドが直接的に呼び出されているか否かを判定するステップと
を含むことを特徴とする請求項２記載のプログラム変換方法。
【請求項４】
前記インスタンス特定ステップは、
前記メソッドの属するクラスが派生クラスを持つか否かを判定するステップと、
前記クラスが派生クラスを持つ場合、前記仮想的メソッド呼び出し抽出ステップにより抽出された前記仮想的なメソッドを再定義する第二のクラスで前記メソッドが再定義されているか否かを判定するステップと、
前記第二のクラスおよび前記第二のクラスの全ての派生クラスのインスタンスに対して、前記メソッドが直接的に呼び出されているか否かを判定するステップと
を含むことを特徴とする請求項２記載のプログラム変換方法。
【請求項５】
前記メソッド解析ステップは、前記メソッドがインスタンス生成メソッドである時に前記メソッドを呼び出す前記インスタンスの型を特定する
ことを特徴とする請求項１記載のプログラム変換方法。
【請求項６】
前記メソッド解析ステップは、前記メソッドがインスタンス削除メソッドである時に前記メソッドを呼び出す前記インスタンスの型を特定する
ことを特徴とする請求項１記載のプログラム変換方法。
【請求項７】
オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、
前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、
前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップと、
前記メソッド解析ステップの結果に応じて、前記仮想的なメソッドを複製する仮想的メソッド複製ステップと、
前記メソッド解析ステップの解析結果に応じて、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップと
を含むことを特徴とするプログラム変換方法。
【請求項８】
前記メソッド解析ステップは、
前記プログラムにおいて、クラスの継承関係を解析するクラス継承関係解析ステップと、
前記クラスにおける前記仮想的なメソッドの再定義の状況を解析する仮想的メソッド再定義解析ステップと、
前記プログラムにおいて、前記仮想的なメソッドの直接的な呼び出しを解析する仮想的メソッド直接呼び出し解析ステップと、
前記クラス継承関係解析ステップ、前記仮想的メソッド再定義解析ステップおよび前記仮想的メソッド直接呼び出し解析ステップの解析結果に応じて、前記メソッドを呼び出す前記インスタンスの型を特定するインスタンス特定ステップとを含み、
前記仮想的メソッド呼び出し変換ステップは、前記メソッド解析ステップにより前記インスタンスの型が特定できる場合に、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッド呼び出しを直接的なメソッドの呼び出しに変換する
ことを特徴とする請求項７記載のプログラム変換方法。
【請求項９】
前記インスタンス特定ステップは、
前記メソッドの属するクラスが派生クラスを持つか否かを判定するステップと、
前記クラスの全ての派生クラスのインスタンスに対して前記メソッドが直接的に呼び出されているか否かを判定するステップとを含み、
前記仮想的メソッド複製ステップは、前記プログラムに含まれる全てのクラスに対して、前記クラスが基底クラスをもつ場合に前記基底クラスに含まれる仮想的なメソッドのうち、前記クラスで再定義していない前記仮想的なメソッドを前記クラスで再定義する
ことを特徴とする請求項８記載のプログラム変換方法。
【請求項１０】
前記インスタンス特定ステップは、
前記メソッドの属するクラスが派生クラスを持つか否かを判定するステップと、
前記クラスの全ての派生クラスのインスタンスに対して前記メソッドが直接的に呼び出されているか否かを判定するステップとを含み、
前記仮想的メソッド複製ステップは、前記メソッドの属するクラスを直接的に継承する全ての第二のクラスに対して、前記第二のクラスで前記メソッドが再定義されていない場合に、前記メソッドを前記第二のクラスで再定義する
ことを特徴とする請求項８記載のプログラム変換方法。
【請求項１１】
前記インスタンス特定ステップは、
前記メソッドの属するクラスが派生クラスを持つか否かを判定するステップと、
前記クラスが派生クラスを持つ場合、前記仮想的メソッド呼び出し抽出ステップにより抽出された前記仮想的なメソッドを再定義する第三のクラスを抽出するステップと、
前記第三のクラスおよび前記第三のクラスの全ての派生クラスのインスタンスに対して、前記メソッドが直接的に呼び出されているか否かを判定するステップとを含み、
前記仮想的メソッド複製ステップは、前記第三のクラスで前記メソッドが再定義されていない場合に、前記メソッドを前記第三のクラスで再定義する
ことを特徴とする請求項８記載のプログラム変換方法。
【請求項１２】
オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、
前記プログラムを翻訳する翻訳ステップと、
前記翻訳ステップでの翻訳結果を結合する結合ステップとを含み、
前記翻訳ステップは、
前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、
前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップと、
前記メソッド解析ステップの解析結果および前記仮想的メソッド呼び出し抽出ステップの解析結果および前記プログラムの変換結果を出力する出力ステップとを含み、
前記結合ステップは、
前記翻訳ステップの出力を入力し、前記翻訳ステップの出力に含まれる解析結果を抽出する解析データ抽出ステップと、
前記解析結果抽出ステップの結果に応じて、前記仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップと、
前記仮想的メソッド呼び出し変換ステップの結果をリンクするリンクステップとを含む
ことを特徴とするプログラム変換方法。
【請求項１３】
オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、
前記プログラムより所定の情報を抽出するプリコンパイルステップと、
前記プリコンパイルステップにおける抽出結果に基づいて、仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する変換ステップとを含み、
前記プリコンパイルステップは、
前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、
前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップとを含み、
前記変換ステップは、
前記プログラムおよび前記メソッド解析ステップの解析結果および前記仮想的メソッド呼び出し抽出ステップの解析結果を入力として受ける入力ステップと、
前記入力ステップにより入力される解析結果に応じて、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップとを含む
ことを特徴とするプログラム変換方法。
【請求項１４】
オブジェクト指向言語で記述されたプログラムを変換するプログラムであって、
請求項１〜１３のいずれか１項に記載のプログラム変換方法に含まれるステップをコンピュータに実行させる
ことを特徴とするプログラム。
【請求項１５】
オブジェクト指向言語で記述されたプログラムを受け、目的プログラムを出力するプログラムを記録したコンピュータ読み取り可能な記録媒体であって、
請求項１４に記載のプログラムを記録した
ことを特徴とするコンピュータ読み取り可能な記録媒体。
【請求項１６】
オブジェクト指向言語で記述されたプログラムを変換するプログラム変換装置であって、
前記プログラムを入力として受ける入力手段と、
前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析手段と、
前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出手段と、
前記メソッド解析ステップの解析結果に応じて、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換手段と
を備えることを特徴とするプログラム変換装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、オブジェクト指向言語により記述されたプログラムを変換するプログラム変換方法に関し、特に、仮想的な関数の呼び出しを直接的な関数の呼び出しに変換するプログラム変換方法に関する。
【背景技術】
【０００２】
近年、プログラムの大規模化に伴い、プログラムの開発効率を高め、再利用化をはかるため、またはプログラムの保守性を向上させるために、Ｃ＋＋やＪａｖａ(登録商標）などのオブジェクト指向言語によるプログラム開発が頻繁に行なわれるようになってきている。
【０００３】
オブジェクト指向言語の特徴の一つとして多態性があげられる。「多態性」とは、プログラム実行時のオブジェクトの実体の型に応じて、その動作が動的に変化するような性質を表す。
【０００４】
この多態性を実現するために、例えばＣ＋＋言語では仮想関数という機能を持つ。この仮想関数について、図５８〜図６１を用いて説明する。
【０００５】
図５８はオブジェクト指向言語Ｃ＋＋によって記述したプログラムである。クラスＡのメンバ関数ｆ、ｇおよびｈの宣言で指定されているキーワード”ｖｉｒｔｕａｌ”はメンバ関数ｆ、ｇおよびｈが仮想関数であることを指定している。「仮想関数」とは、プログラム実行時にポインタが指しているオブジェクトの型に応じて、実行される関数が動的に決定される関数のことであり、基底クラスの仮想関数を派生クラスで再定義した場合には、ポインタが派生クラスのオブジェクトを指している場合には、派生クラスの仮想関数が実行される。
【０００６】
クラスＢはクラスＡを継承しており、クラスＢのメンバ関数ｇは基底クラスＡの仮想関数ｇを上書きしており、クラスＢに固有の動作を実行するものとする。
【０００７】
この時、関数ｔ２内でポインタ変数ｐに対してメンバ関数ｇを呼び出すと、仮想関数呼び出しとなる。この時、ポインタ変数ｐが指しているオブジェクトがクラスＡのオブジェクトであればクラスＡの関数ｇが実行され、クラスＢのオブジェクトであればクラスＢの関数ｇが実行される。このように、ポインタ変数ｐが指しているオブジェクトの型に応じて実行される関数が実行時に決定される。
【０００８】
この仮想関数の実現方法の概略図を図５９に示す。
クラスＢ型のオブジェクトｏｂｊ＿ｂは、内部に仮想関数テーブルを指すポインタメンバｖｐｔｒを保持する。メンバｖｐｔｒはクラスＢの仮想関数テーブルｖｔｂｌ＿Ｂを指している。クラスＢの仮想関数テーブルには、クラスＢで呼び出し可能な全ての仮想関数のアドレスが保持されている。
【０００９】
ポインタ変数ｐに対して仮想関数ｇを呼び出す場合について考える。
ポインタ変数ｐがクラスＢ型のオブジェクトｏｂｊ＿ｂを指している場合、ｐはｏｂｊ＿ｂの先頭アドレスを保持している。仮想関数呼び出しによって呼び出される関数のアドレスは、まず仮想関数テーブルを取得し、次に呼び出す関数のアドレスを取得するという手順により取得する必要がある。
【００１０】
即ち、ポインタ変数ｐの値にｏｆｆｓｅｔ１を加算したアドレスの内容を取得し、その値にｏｆｆｓｅｔ２を加算したアドレスの内容が呼び出す関数のアドレスとなる。
【００１１】
従って、仮想関数呼び出しを実行するアセンブラコードは図６０のようになる。一方、関数の直接呼び出しを実行するアセンブラコードは図６１のようになり、仮想関数呼び出しのコードの方が命令数が多く、実行速度も遅くなる傾向にある。
【００１２】
そのため、仮想関数呼び出しをできるだけ少なくした方が、プログラムの実行性能が向上する。
【００１３】
仮想関数呼び出しが実行される回数を少なくし、実行性能を向上するための従来技術として、仮想関数呼び出しで呼び出される関数のアドレスを比較して、呼び出される関数がある特定の関数である場合にはその関数を直接呼び出すという技術がある（例えば、特許文献１参照）。これによって、仮想関数呼び出しで実行される関数が特定できる場合はその関数を直接呼び出すコードを実行し、特定できない場合は通常の仮想関数呼び出しのコードを実行するように変換することができる。図６２に示すプログラムの矢印（Ａ）の関数ｈを特許文献１によって変換した概略図を図６３に示す。このように、仮想関数のアドレスがメンバ関数「Ａ：：ｆ」（クラスＡで定義されている関数ｆ）のアドレスの場合には、関数「Ａ：：ｆ」を直接呼び出し、それ以外の場合には、仮想関数呼び出しを行う。さらに、関数の直接呼び出しをインライン展開することにより実行性能を向上させることができる。
【００１４】
また、クラスの継承関係を解析し、派生クラスを持たないクラスに対する仮想関数呼び出しを関数の直接呼び出しに変換するという技術がある（例えば、特許文献２参照）。これによって、プログラムのコンパイル時に仮想関数呼び出しを関数の直接呼び出しに変換することが可能であるため、プログラムの実行性能を向上することができる。図６２に示すプログラムの矢印（Ａ）の関数ｈを特許文献２によって変換した概略図を図６４に示す。
【特許文献１】特開２０００−４０００７号公報
【特許文献２】特開平１０−３２０２０４号公報
【発明の開示】
【発明が解決しようとする課題】
【００１５】
ここで、仮想関数を呼び出すクラスが特定可能な場合、仮想関数呼び出しによって呼び出される関数を特定することが可能である。例えば、図６２の矢印（Ｂ）で示すクラスＡのメンバ関数ｆは、ｔｈｉｓポインタの型がクラスＡのみであると特定できる場合がある。この時、ｔｈｉｓポインタに対して仮想関数ｇを呼び出した場合に実行される関数は必ずクラスＡのメンバ関数ｇとなる。ここで、ｔｈｉｓポインタとは、メンバ関数の内部で、そのメンバ関数が起動されたオブジェクトを指す特別なポインタを表す。
【００１６】
しかし、特許文献１の技術では、図６５に示すように、仮想関数を呼び出すクラスを特定できた場合でも関数のアドレス比較をするコードを生成するため、関数を直接呼び出すコードに比べると実行性能およびコードサイズが悪くなるという問題がある。
【００１７】
また、ｔｈｉｓポインタの型がクラスＡであるため、特許文献２の技術では、仮想関数を呼び出すクラスが派生クラスを持っている場合には、仮想関数呼び出しを関数の直接呼び出しには変換することができないという問題がある。
【００１８】
本発明は、上述の課題を解決するためになされたもので、メンバ関数のｔｈｉｓポインタの型が特定可能な場合があることに着目し、実行性能を向上させ、かつコードサイズを小さくしつつ、仮想関数呼び出しを関数の直接呼出しに変換することができるプログラム変換方法を提供することを目的とする。
【課題を解決するための手段】
【００１９】
上記従来の課題を解決するために、本発明に係るプログラム変換方法は、オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップと、前記メソッド解析ステップの解析結果に応じて、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップとを含むことを特徴とする。
【００２０】
仮想的なメソッド（すなわち、仮想関数）の呼び出しを直接的なメソッドの呼び出し（すなわち、関数の直接呼出し）に変換することができ、プログラムの実行性能を向上することができる。また、プログラムのコードサイズを小さくすることができる。
【００２１】
また、本発明の他の局面に係るプログラム変換方法は、オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップと、前記メソッド解析ステップの結果に応じて、前記仮想的なメソッドを複製する仮想的メソッド複製ステップと、前記メソッド解析ステップの解析結果に応じて、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップとを含むことを特徴とする。
【００２２】
仮想的なメソッドを複製することによって仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換できる可能性が高くなる。このため、プログラムの実行性能をより向上させることができ、かつプログラムのコードサイズを小さくすることができる。
【００２３】
また、本発明のさらに他の局面に係るプログラム変換方法は、オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、前記プログラムを翻訳する翻訳ステップと、前記翻訳ステップでの翻訳結果を結合する結合ステップとを含み、前記翻訳ステップは、前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップと、前記メソッド解析ステップの解析結果および前記仮想的メソッド呼び出し抽出ステップの解析結果および前記プログラムの変換結果を出力する出力ステップとを含み、前記結合ステップは、前記翻訳ステップの出力を入力し、前記翻訳ステップの出力に含まれる解析結果を抽出する解析データ抽出ステップと、前記解析結果抽出ステップの結果に応じて、前記仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップと、前記仮想的メソッド呼び出し変換ステップの結果をリンクするリンクステップとを含むことを特徴とする
上述のプログラム変換方法とは異なる構成で、同様のプログラムの実行性能を得ることができる。
【００２４】
また、本発明のさらに他の局面に係るプログラム変換方法は、オブジェクト指向言語で記述されたプログラムを変換するプログラム変換方法であって、前記プログラムより所定の情報を抽出するプリコンパイルステップと、前記プリコンパイルステップにおける抽出結果に基づいて、仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する変換ステップとを含み、前記プリコンパイルステップは、前記プログラムにおいて、メソッドを呼び出すインスタンスの型を解析するメソッド解析ステップと、前記メソッドの定義中で、前記インスタンスに対する仮想的なメソッドの呼び出しを抽出する仮想的メソッド呼び出し抽出ステップとを含み、前記変換ステップは、前記プログラムおよび前記メソッド解析ステップの解析結果および前記仮想的メソッド呼び出し抽出ステップの解析結果を入力として受ける入力ステップと、前記入力ステップにより入力される解析結果に応じて、前記仮想的メソッド呼び出し抽出ステップにより抽出された仮想的なメソッドの呼び出しを直接的なメソッドの呼び出しに変換する仮想的メソッド呼び出し変換ステップとを含むことを特徴とする。
【００２５】
上述のプログラム変換方法とはさらに異なる構成で、同様のプログラムの実行性能を得ることができる。
【発明の効果】
【００２６】
実行性能を向上させ、かつコードサイズを小さくしつつ、仮想関数呼び出しを関数の直接呼出しに変換することができるプログラム変換方法を提供することができる。
【発明を実施するための最良の形態】
【００２７】
［実施の形態１］
以下、本発明のプログラム変換装置の実施形態の一例について図面を参照しながら説明する。
【００２８】
本実施の形態では、以下の条件（１）から条件（４）を満たす場合に、ｔｈｉｓポインタの型を特定することができるため、仮想関数Ｆ１の呼び出しを直接関数呼び出しに変換する。
【００２９】
すなわち、
条件（１）：仮想関数Ｆ１が仮想関数Ｆ２の定義中に記述されている。
【００３０】
条件（２）：仮想関数Ｆ１がｔｈｉｓポインタに対して呼び出されている。
条件（３）：仮想関数Ｆ２の属するクラスＣ１が派生クラスを持たないか、または仮想関数Ｆ２がクラスＣ１の全ての直接派生クラスで再定義されている。
【００３１】
条件（４）：クラスＣ１の派生クラスのオブジェクトに対して仮想関数Ｆ２が直接呼び出されていない。
【００３２】
図１は、上述の４つの条件に従い、実施の形態１に係るプログラム変換装置の実行する処理の概略を説明する図である。すなわち、図１（ａ）に示されるようなクラスの定義が与えられ、かつ図１（ｂ）に示されるようなプログラムが与えられた場合を考える。
【００３３】
仮想関数ｇを仮想関数Ｆ１とし、仮想関数ｆを仮想関数Ｆ２とした場合には、図１（ｂ）の文「ｔｈｉｓ−＞ｇ（）」は、条件（１）および条件（２）を満たす。すなわち、仮想関数Ｆ１（仮想関数ｇ）が仮想関数Ｆ２（仮想関数ｆ）の定義中に記述されているため、条件（１）を満たす。また、仮想関数Ｆ１（仮想関数ｇ）は、ｔｈｉｓポインタに対して呼び出されているため、条件（２）を満たす。
【００３４】
また、条件（３）について考えると、図１（ｂ）に示されるように仮想関数Ｆ２（仮想関数ｆ）の属するクラスＣ１はクラスＡである。このため、図１（ａ）に示されるように、仮想関数Ｆ２（仮想関数ｆ）がクラスＣ１（クラスＡ）のすべての直接派生クラス（すなわち、クラスＢ）で再定義されている。したがって、条件（３）を満たす。
【００３５】
さらに、条件（４）について考えると、プログラム中にＡ：：ｆ（ｖｏｉｄ）の直接呼び出しが存在しない。このため、クラスＣ１（クラスＡ）の派生クラス（クラスＢ、Ｃ、Ｄ）のオブジェクトに対して仮想関数Ｆ２（仮想関数ｆ）が直接呼び出されていないことになる。したがって、条件（４）を満たす。
【００３６】
このため、このような場合には、図１（ｂ）に示されるような仮想関数ｇの呼び出しを、図１（ｃ）に示されるように、クラスＡの仮想関数ｇの直接呼び出しに変換することができる。
［プログラム変換装置の構成］
図２は本発明の実施の形態１におけるプログラム変換装置１００の構成を示す図である。プログラム変換装置１００は、オブジェクト指向言語であるＣ＋＋言語で記述されたプログラムを受け、目的プログラムを出力する装置であり、プログラム記憶部１０１と、入力部１０２と、構文解析部１０３と、クラス継承関係解析部１０４と、仮想関数再定義解析部１０５と、解析情報記憶部１０６と、仮想関数直接呼び出し解析部１０７と、仮想関数呼び出し変換部１０８と、出力部１０９と、生成コード記憶部１１０とを備えている。
【００３７】
プログラム記憶部１０１は、プログラム変換装置１００における変換対象となる、オブジェクト指向言語であるＣ＋＋言語で記述されたプログラム１１１を記憶する記憶装置である。プログラム記憶部１０１には、１つ以上のプログラム１１１が記憶されている。
【００３８】
入力部１０２は、プログラム記憶部１０１に格納されている全てのプログラム１１１を順次入力し、構文解析部１０３に出力する処理部である。
【００３９】
構文解析部１０３は、入力部１０２から受けとったプログラム１１１の構文を解析し、シンボルテーブルの生成や構文木の生成などを行ない、その解析結果をクラス継承関係解析部１０４に渡す処理部である。
【００４０】
クラス継承関係解析部１０４は、プログラム１１１中に含まれる全てのクラスを抽出してクラス間の継承関係を解析し、解析結果であるクラスの継承関係情報を生成する処理部である。
【００４１】
仮想関数再定義解析部１０５は、クラスの仮想関数が基底クラスの仮想関数を再定義しているか否かを解析し、解析結果である仮想関数再定義情報を生成する処理部である。
【００４２】
仮想関数直接呼び出し解析部１０７は、プログラム中で直接呼び出しされている仮想関数および起動オブジェクトを解析し、仮想関数直接呼び出し情報を生成する処理部である。
【００４３】
解析情報記憶部１０６は、クラス継承関係解析部１０４で生成されたクラスの継承関係情報１１３、仮想関数再定義解析部１０５で生成された仮想関数再定義情報１１４および仮想関数直接呼び出し解析部１０７で生成された仮想関数直接呼び出し情報１１５を記憶する記憶装置である。
【００４４】
仮想関数呼び出し変換部１０８は、解析情報記憶部１０６に格納されているクラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５を参照し、仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、変換可能な場合に関数の直接呼び出しに変換する処理部である。
【００４５】
出力部１０９は、仮想関数呼び出し変換部１０８での変換結果を目的プログラム１１２として生成コード記憶部１１０に格納する処理部である。
【００４６】
生成コード記憶部１１０は、目的プログラム１１２を記憶する記憶装置である。
［プログラム変換装置の実行する処理の概要］
図３は、本発明の実施の形態１におけるプログラム変換装置１００の実行する処理のフローチャートである。
【００４７】
入力部１０２は、プログラム記憶部１０１に格納されている全てのプログラム１１１を順次入力し、構文解析部１０３に渡す（Ｓ１０２）。
【００４８】
構文解析部１０３は、入力部１０２から受けとったプログラム１１１の構文を解析し、シンボルテーブルの生成や構文木の生成などを行ない、その解析結果をクラス継承関係解析部１０４に渡す（Ｓ１０３）。
【００４９】
クラス継承関係解析部１０４は、プログラム１１１中に含まれる全てのクラスを抽出してクラス間の継承関係を解析し、解析結果をクラスの継承関係情報１１３として解析情報記憶部１０６に格納する（Ｓ１０４）。
【００５０】
仮想関数再定義解析部１０５は、クラスの仮想関数が基底クラスの仮想関数を再定義しているか否かを解析し、解析結果を仮想関数再定義情報１１４として解析情報記憶部１０６に格納する（Ｓ１０５）。
【００５１】
仮想関数直接呼び出し解析部１０７は、プログラム１１１中で直接呼び出しされている仮想関数および起動オブジェクトを解析し、解析結果を仮想関数直接呼び出し情報１１５として解析情報記憶部１０６に格納する（Ｓ１０７）。
【００５２】
仮想関数呼び出し変換部１０８は、解析情報記憶部１０６に格納されているクラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５を参照し、仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、変換可能な場合に関数の直接呼び出しに変換する（Ｓ１０８）。
【００５３】
出力部１０９は、仮想関数呼び出し変換部１０８での変換結果を目的プログラム１１２として生成コード記憶部１１０に格納する（Ｓ１０９）。
【００５４】
なお、入力ステップＳ１０２、構文解析ステップＳ１０３、出力ステップＳ１０９については、本発明の主眼ではないため、詳細な説明は省略する。
［プログラム変換装置の実行する処理の詳細］
次に、プログラム変換装置１００の実行する処理の詳細について、プログラム例を参照しながら説明していく。
【００５５】
まず、入力部１０２は、プログラム記憶部１０１から全てのプログラム１１１を入力し（Ｓ１０２）、構文解析部１０３は、プログラム１１１の構文木やシンボルテーブルの作成などを行なう（Ｓ１０３）。
【００５６】
次に、クラス継承関係解析処理（Ｓ１０４）の詳細について説明する。図４は、クラス継承関係解析処理（Ｓ１０４）の詳細なフローチャートである。ここでは、プログラム変換装置１００へ入力されるプログラム１１１として、図５に示されるプログラム１１１を考える。
【００５７】
クラス継承関係解析処理（Ｓ１０４）は、ａ１からａ７までのステップを含む。以下記号の順に説明していく。
【００５８】
ステップａ１では、クラス継承関係解析部１０４は、構文解析部１０３で解析された全てのプログラム１１１中に含まれる、全てのクラスＣ１について以下の処理を繰り返す。すなわち、図５の全てのプログラム１１１中に含まれるクラスＡ、Ｂ、ＣおよびＤについて以下の処理を繰り返す。
【００５９】
ステップａ２では、クラス継承関係解析部１０４は、クラスＣ１がクラスの継承関係情報１１３に既に記録済みかどうかを調べる。既に記録済みの場合は、ステップａ７に処理を移行し、記録済みでない場合は、ステップａ３に処理を移行する。図５のクラスＡを最初に解析した時にはステップａ２の判定はＮｏとなり、ステップａ３へと処理を移行する。また、これ以降にクラスＡを解析した時にはステップａ２の判定はＹｅｓとなり、ステップａ７へと処理を移行する。クラスＢ、ＣおよびＤについても同様である。
【００６０】
ステップａ３では、クラス継承関係解析部１０４は、クラスＣ１をクラスの継承関係情報１１３に登録する。図５のクラスＡに適用した場合、クラスの継承関係情報１１３にクラスＡを登録する。クラスＢ、ＣおよびＤについても同様である。
【００６１】
ステップａ４では、クラス継承関係解析部１０４は、クラスＣ１が基底クラスＣ２を持つかどうかを調べる。クラスＣ１が基底クラスＣ２を持たない場合は、ステップａ５に処理を移行し、基底クラスＣ２を持つ場合は、ステップａ６に処理を移行する。図５のクラスＡの場合、クラスＡは基底クラスを持たない。このためステップａ４の判定はＮｏとなり、ステップａ５へと処理を移行する。また、クラスＢの場合は基底クラスとしてクラスＡを持つので、ステップａ４の判定はＹｅｓとなり、ステップａ６へと処理を移行する。クラスＣおよびＤもそれぞれ基底クラスＢを持つので、ステップａ４の判定はＹｅｓとなり、ステップａ６へと処理を移行する。
【００６２】
ステップａ５では、クラス継承関係解析部１０４は、クラスＣ１のクラスツリーを生成し、クラスの継承関係情報１１３に登録する（ａ５）。クラスツリーとは、クラスの継承関係を示すグラフのことである。図５のクラスＡの場合、クラス継承関係解析部１０４は、クラスＡについて、クラスツリーを生成し、クラスの継承関係情報１１３に、生成したクラスツリーを登録する。
【００６３】
ステップａ６では、クラス継承関係解析部１０４は、クラスＣ１をクラスＣ２の派生クラスとしてＣ２の属するクラスツリーに追加し、クラスツリーを更新する。図５のクラスＢの場合、クラスＢをクラスＡの属するクラスツリーにクラスＡの派生クラスとして登録する。クラスＣおよびＤも同様にクラスＢの派生クラスとしてクラスツリーに登録する。
【００６４】
ステップａ７では、ステップａ１に処理を移行し、ループの処理を繰り返す。
図６は、図５のプログラム１１１をクラス継承関係解析部１０４によって解析した結果のクラスの継承関係情報１１３を示す図である。クラスの継承関係情報１１３には、クラスＢがクラスＡの派生クラスであり、クラスＣおよびＤがクラスＢの派生クラスであることが示されている。
【００６５】
次に、仮想関数再定義解析処理（Ｓ１０５）の詳細について説明する。図７は、仮想関数再定義解析処理（Ｓ１０５）の詳細なフローチャートである。ここでは、プログラム変換装置１００へ入力されるプログラム１１１として、図５に示されるプログラム１１１を考える。
【００６６】
仮想関数再定義解析処理（Ｓ１０５）はｂ１からｂ８までのステップを含む。以下記号の順に説明していく。
【００６７】
ステップｂ１では、仮想関数再定義解析部１０５は、クラスの継承関係情報１１３に含まれる全てのクラスＣ１について、以下の処理を繰り返す。すなわち、図６に示されるクラスＡ、Ｂ、ＣおよびＤの各々について以下の処理を繰り返す。
【００６８】
ステップｂ２では、仮想関数再定義解析部１０５は、クラスＣ１の全ての仮想関数の再定義フラグをＯＦＦにし、仮想関数再定義情報１１４に記録する。クラスＡの場合、仮想関数ｆ、ｇおよびｈについて、再定義フラグをＯＦＦにし、仮想関数再定義情報１１４に記録する。クラスＢ、ＣおよびＤについても同様に記録する。
【００６９】
ステップｂ３では、仮想関数再定義解析部１０５は、クラスＣ１が基底クラスＣ２を持つかどうかを調べる。クラスＣ１が基底クラスＣ２を持つ場合は、ステップｂ４に処理を移行し、基底クラスＣ２を持たない場合は、ステップｂ８に処理を移行する。図６のクラスの継承関係情報１１３に示されるクラスＡの場合、クラスＡは基底クラスを持たないためステップｂ３の判定はＮｏとなり、ステップｂ８へと処理を移行する。また、クラスＢの場合は基底クラスとしてクラスＡを持つので、ステップｂ３の判定はＹｅｓとなり、ステップｂ４へと処理を移行する。クラスＣおよびＤもそれぞれ基底クラスＢを持つので、ステップｂ３の判定はＹｅｓとなり、ステップｂ４へと処理を移行する。
【００７０】
ステップｂ４では、仮想関数再定義解析部１０５は、クラスＣ１の全ての仮想関数Ｆ１について以下の処理を繰り返す。図５のクラスＢの場合は、クラスＢの仮想関数ｆ、ｇおよびｈについて以降の処理を繰り返す。
【００７１】
ステップｂ５では、仮想関数再定義解析部１０５は、仮想関数Ｆ１がクラスＣ１の基底クラスＣ２の仮想関数を上書きしているかどうかを調べる。仮想関数Ｆ１が基底クラスＣ２の仮想関数を上書きしている場合はステップｂ６へと処理を移行し、上書きしていない場合はステップｂ７へと処理を移行する。図５のクラスＢの仮想関数ｆの場合は、基底クラスＡの仮想関数ｆを上書きしているので、ステップｂ５の判定はＹｅｓとなりステップｂ６へと処理を移行する。また、クラスＢの仮想関数ｈの場合は、基底クラスＡの仮想関数ｈを上書きしていないので、ステップｂ５の判定はＮｏとなり、ステップｂ７へと処理を移行する。
【００７２】
ステップｂ６では、仮想関数再定義解析部１０５は、仮想関数Ｆ１の再定義フラグをＯＮにする。図５のクラスＢの仮想関数ｆの場合は、クラスＢの仮想関数ｆに対応する再定義フラグをＯＮに設定する。
【００７３】
ステップｂ７では、仮想関数再定義解析部１０５は、ステップｂ４に処理を移行し、ループの処理を繰り返す。
【００７４】
ステップｂ８では、仮想関数再定義解析部１０５は、ステップｂ１に処理を移行し、ループの処理を繰り返す。
【００７５】
図８は、図５のプログラム１１１を仮想関数再定義解析部１０５によって解析した結果の仮想関数再定義情報１１４を示す図である。仮想関数再定義情報１１４の左欄は、クラス名を示し、中欄は仮想関数名を示し、右欄は仮想関数が再定義しているか否かを示している。ＯＮの場合には再定義していることを示し、ＯＦＦの場合には再定義していないことを示す。たとえば、クラスＢにおいては、仮想関数ｆとｇとが再定義しているが、仮想関数ｈは再定義していないことが示されている。
【００７６】
次に、仮想関数直接呼び出し解析処理（Ｓ１０７）の詳細について説明する。図９は、仮想関数直接呼び出し解析処理（Ｓ１０７）の詳細なフローチャートである。ここでは、プログラム変換装置１００へ入力されるプログラム１１１として、図５に示すプログラム１１１を考える。
【００７７】
仮想関数直接呼び出し解析処理（Ｓ１０７）はｃ１からｃ４までのステップを含む。以下記号の順に説明していく。
【００７８】
ステップｃ１では、仮想関数直接呼び出し解析部１０７は、構文解析処理（Ｓ１０３）で解析された全てのプログラム１１１中の全ての文Ｓ１について以下の処理を繰り返す。図５では「ｔｈｉｓ−＞ｇ（）；」や「ｏｂｊ＿ｃ．ｇ（）；」などが対象となる。
【００７９】
ステップｃ２では、仮想関数直接呼び出し解析部１０７は、文Ｓ１に仮想関数Ｆ１の直接呼び出しを含むかどうかを調べる。文Ｓ１に仮想関数Ｆ１の直接呼び出しを含む場合はステップｃ３に処理を移行し、直接呼び出しを含まない場合はステップｃ４に処理を移行する。図５の文「ｔｈｉｓ−＞ｇ（）；」では、クラスＡの仮想関数ｇが直接呼び出されていないのでステップｃ２の判定はＮｏとなり、ステップｃ４へと処理を移行する。一方、文「ｏｂｊ＿ｃ．ｇ（）；」では、クラスＢの仮想関数ｇが直接呼び出されているのでステップｃ２の判定はＹｅｓとなり、ステップｃ３へと処理を移行する。
【００８０】
ステップｃ３では、仮想関数直接呼び出し解析部１０７は、仮想関数Ｆ１の起動オブジェクトのクラスＣ１と仮想関数Ｆ１とを仮想関数直接呼び出し情報１１５に記録する。図５の文「ｏｂｊ＿ｃ．ｇ（）；」では、起動オブジェクトのクラスＣ、および「Ｂ：：ｇ」とを仮想関数直接呼び出し情報１１５に記録する。
【００８１】
ステップｃ４では、仮想関数直接呼び出し解析部１０７は、ステップｃ１に処理を移行し、ループの処理を繰り返す。
【００８２】
図１０は、図５のプログラム１１１を仮想関数直接呼び出し解析部１０７によって解析した結果の仮想関数直接呼び出し情報１１５を示す図である。
【００８３】
次に、仮想関数呼び出し変換処理（Ｓ１０８）の詳細について説明する。図１１は、仮想関数呼び出し変換処理（Ｓ１０８）の詳細なフローチャートである。ここでは、プログラム変換装置１００に入力されるプログラム１１１として、図５に示すプログラムを考える。
【００８４】
仮想関数呼び出し変換処理（Ｓ１０８）はｄ１からｄ８までのステップを含む。以下記号の順に説明していく。
【００８５】
ステップｄ１では、仮想関数呼び出し変換部１０８は、プログラム１１１中の仮想関数Ｆ１の呼び出しを含む全ての文Ｓ１について以下の処理を繰り返す。図５では「ｔｈｉｓ−＞ｇ（）；」、「ｔｈｉｓ−＞ｈ（）；」などが対象となる。
【００８６】
ステップｄ２では、仮想関数呼び出し変換部１０８は、文Ｓ１が仮想関数定義Ｆ２中に含まれるかどうかを調べる。文Ｓ１が仮想関数定義Ｆ２中に含まれる場合はステップｄ３に処理を移行し、仮想関数定義Ｆ２中に含まれない場合はステップｄ８に処理を移行する。図５の文「ｔｈｉｓ−＞ｇ（）；」は、仮想関数「Ａ：：ｆ」中に含まれているのでステップｄ２の判定はＹｅｓとなり、ステップｄ３へと処理を移行する。同様に、文「ｔｈｉｓ−＞ｈ（）；」は、仮想関数「Ｂ：：ｇ」中に含まれているのでステップｄ２の判定はＹｅｓとなり、ステップｄ３へと処理を移行する。一方、文「ｏｂｊ＿ｃ．ｇ（）；」は、関数ｔ中に含まれるが、関数ｔは仮想関数ではないので、ステップｄ２の判定はＮｏとなり、ステップｄ８へと処理を移行する。
【００８７】
ステップｄ３では、仮想関数呼び出し変換部１０８は、文Ｓ１がｔｈｉｓポインタに対する呼び出しかどうかを調べる。文Ｓ１がｔｈｉｓポインタに対する呼び出しの場合はステップｄ４に処理を移行し、ｔｈｉｓポインタに対する呼び出しでない場合はステップｄ８に処理を移行する。図５の文「ｔｈｉｓ−＞ｇ（）；」および文「ｔｈｉｓ−＞ｈ（）；」では、仮想関数ｇおよびｈの呼び出しはｔｈｉｓポインタに対して行なわれているためステップｄ３の判定はＹｅｓとなり、ステップｄ４へと処理を移行する。ここで、ｔｈｉｓポインタについて説明すると、上述したようにｔｈｉｓポインタとはメンバ関数の内部で、そのメンバ関数が起動されたオブジェクトを指す特別なポインタを表す。例えば、図５の関数ｔ内でのメンバ関数呼び出し「ｏｂｊ＿ｃ．ｇ（）；」によって、クラスＢのメンバ関数ｇが実行される。このとき、クラスＢのメンバ関数ｇのｔｈｉｓポインタはメンバ関数ｇを起動したオブジェクトｏｂｊ＿ｃを指す。
【００８８】
ステップｄ４では、仮想関数呼び出し変換部１０８は、仮想関数Ｆ２が属するクラスＣ１が派生クラスを持つかどうかをクラスの継承関係情報１１３を参照して調べる。クラスＣ１が派生クラスを持つ場合はステップｄ５に処理を移行し、派生クラスを持たない場合はステップｄ７に処理を移行する。図５の仮想関数「Ａ：：ｆ」では、ｆが属するクラスＡはクラスの継承関係情報１１３を参照すると派生クラスを持つことがわかるのでステップｄ４の判定はＹｅｓとなり、ステップｄ５へと処理を移行する。同様に仮想関数「Ｂ：：ｇ」では、ｇが属するクラスＢは派生クラスを持つことがわかるのでステップｄ４の判定はＹｅｓとなる。
【００８９】
ステップｄ５では、仮想関数呼び出し変換部１０８は、クラスＣ１の全ての直接派生クラスＣ２で仮想関数Ｆ２が再定義されているかどうかを調べる。全ての直接派生クラスＣ２で仮想関数Ｆ２が再定義されている場合はステップｄ６に処理を移行し、再定義されていない場合はステップｄ８に処理を移行する。図５では、仮想関数再定義情報１１４を参照すると、クラスＡの全ての直接派生クラスＢで仮想関数ｆが再定義されていることがわかるので、ステップｄ５の判定はＹｅｓとなり、ステップｄ６へと処理を移行する。一方、クラスＢの直接派生クラスＤでは仮想関数ｇが再定義されているが、直接派生クラスＣでは仮想関数ｇは再定義されていないため、ステップｄ５の判定はＮｏとなり、ステップｄ８へと処理を移行する。
【００９０】
ステップｄ６では、仮想関数呼び出し変換部１０８は、クラスＣ１の全ての派生クラスＣ３のオブジェクトに対して仮想関数Ｆ２が直接呼び出しされていないかどうかを調べる。仮想関数Ｆ２が直接呼び出しされていない場合はステップｄ７に処理を移行し、直接呼び出しされている場合はステップｄ８に処理を移行する。図５のプログラム１１１について考えると、仮想関数直接呼び出し情報１１５を参照すると、クラスＡの全ての派生クラスＢ、ＣおよびＤのオブジェクトに対して仮想関数ｆが直接呼び出されていることはないので、ステップｄ６の判定はＹｅｓとなり、ステップｄ７へと処理を移行する。
【００９１】
ステップｄ７では、仮想関数呼び出し変換部１０８は、文Ｓ１を関数Ｆ１の直接呼び出しに変換する。図５の文「ｔｈｉｓ−＞ｇ（）；」に対しては、仮想関数ｇを直接呼び出しに変換し、「ｔｈｉｓ−＞Ａ：：ｇ（）；」と記述された場合と同等のコードに変換する。
【００９２】
ステップｄ８では、仮想関数呼び出し変換部１０８は、ステップｄ１に処理を移行し、ループの処理を繰り返す。
【００９３】
図１２は、図５のプログラム１１１を仮想関数呼び出し変換部１０８によって変換した結果、得られるコードを示す図である。このコードでは、仮想関数Ａ：：ｇが直接呼び出されている。
【００９４】
以上説明したように、本実施の形態に係るプログラム変換装置１００に、図５に示すプログラム１１１を入力した結果、仮想関数呼び出しを含む文「ｔｈｉｓ−＞ｇ（）；」を関数の直接呼び出しに変換することができる。このため、目的プログラム１１２実行時の実行速度の向上を図ることができる。
【００９５】
なお、上記実施形態において、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）、仮想関数呼び出し変換処理（Ｓ１０８）は、それぞれ一回のみ実行することとしているが、必要に応じて複数回繰り返すようにしても良い。
【００９６】
また、仮想関数および仮想関数が属するクラスが、特定の条件を満たした場合に、その仮想関数定義においてｔｈｉｓポインタの型を特定することができるとしているが、クラスオブジェクトの生成処理を行なうコンストラクタや、削除処理を行なうデストラクタでは、ｔｈｉｓポインタの型はそのコンストラクタやデストラクタが属するクラスに特定可能である。このため、コンストラクタやデストラクタ中に記述されているｔｈｉｓポインタに対する仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
【００９７】
また、プログラムの性質上や実行結果からｔｈｉｓポインタの型が明らかに特定できるような場合は、ｐｒａｇｍａ指令、オプション指定およびプログラムの実行履歴情報などを元に、仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
［実施の形態２］
本実施の形態では、仮想関数呼び出し変換部１０８の実行する処理が実施の形態１とは異なる。
【００９８】
本実施の形態では、以下の条件（１）から条件（４）を満たす場合に、ｔｈｉｓポインタの型を特定することができるため、仮想関数Ｆ１の呼び出しを直接関数呼び出しに変換する。
【００９９】
すなわち、
（１）  仮想関数Ｆ１が仮想関数Ｆ２の定義中に記述されている。
【０１００】
（２）  仮想関数Ｆ１がｔｈｉｓポインタに対して呼び出されている。
（３）  仮想関数Ｆ２の属するクラスＣ１が派生クラスを持たないか、または仮想関数Ｆ１が再定義されている派生クラスＣ２で仮想関数Ｆ２も再定義されている。
【０１０１】
（４）  クラスＣ２以外の派生クラスのオブジェクトに対して仮想関数Ｆ２が直接呼び出されていない。
【０１０２】
図１３は、上述の４つの条件に従い、実施の形態２に係るプログラム変換装置の実行する処理の概略を説明する図である。すなわち、図１３（ａ）に示されるようなクラスの定義が与えられ、かつ図１３（ｂ）に示されるようなプログラムが与えられた場合を考える。
【０１０３】
仮想関数ｇを仮想関数Ｆ１とし、仮想関数ｆを仮想関数Ｆ２とした場合には、図１３（ｂ）の文「ｔｈｉｓ−＞ｇ（）」は、条件（１）および条件（２）を満たす。すなわち、仮想関数Ｆ１（仮想関数ｇ）が仮想関数Ｆ２（仮想関数ｆ）の定義中に記述されているため、条件（１）を満たす。また、仮想関数Ｆ１（仮想関数ｇ）は、ｔｈｉｓポインタに対して呼び出されているため、条件（２）を満たす。
【０１０４】
また、条件（３）について考えると、図１３（ａ）に示されるように、仮想関数Ｆ１（仮想関数ｇ）が再定義されている派生クラスＣ２（クラスＣ）で仮想関数Ｆ２（仮想関数ｆ）も再定義されている。したがって、条件（３）を満たす。
【０１０５】
さらに、条件（４）について考えると、プログラム中にクラスＢ以外のＡ：：ｆ（ｖｏｉｄ）の直接呼び出しがない。このため、クラスＣ２（クラスＣ）以外の派生クラス（クラスＢ、Ｄ）のオブジェクトに対して仮想関数Ｆ２（仮想関数ｆ）が直接呼び出されていないことになる。したがって、条件（４）を満たす。
【０１０６】
このため、このような場合には、図１３（ｂ）に示されるような仮想関数ｇの呼び出しを、図１３（ｃ）に示されるように、クラスＡの仮想関数ｇの直接呼び出しに変換することができる。
【０１０７】
以下では、実施の形態２に係るプログラム変換装置１００の実行する処理について、プログラム例を参照しながら説明していく。
【０１０８】
図３に示されるように、まず、入力部１０２は、プログラム記憶部１０１から全てのプログラム１１１を入力し（Ｓ１０２）、構文解析部１０３は、プログラムの構文木やシンボルテーブルの作成などを行なう（Ｓ１０３）。
【０１０９】
次に、クラス継承関係解析部１０４は、プログラム１１１中に含まれるクラスおよびクラス間の継承関係を解析し、解析結果をクラスの継承関係情報１１３に記録する（Ｓ１０４）。クラス継承関係解析処理（Ｓ１０４）は、図４に示したものと同様である。図５のプログラム１１１をクラス継承関係解析処理（Ｓ１０４）によって解析した結果であるクラスの継承関係情報１１３を図１４に示す。
【０１１０】
次に、仮想関数再定義解析部１０５は、基底クラスの仮想関数の再定義状態を解析し、解析結果を仮想関数再定義情報１１４に記録する（Ｓ１０５）。仮想関数再定義解析処理（Ｓ１０５）は、図７に示したものと同様である。図５のプログラム１１１を仮想関数再定義解析処理（Ｓ１０５）によって解析した結果である仮想関数再定義情報１１４を図１５に示す。
【０１１１】
次に、仮想関数直接呼び出し解析部１０７は、直接呼び出しされる仮想関数を解析し、解析結果を仮想関数直接呼び出し情報１１５に記録する（Ｓ１０７）。仮想関数直接呼び出し解析処理（Ｓ１０７）は図９に示したものと同様である。図５のプログラム１１１を仮想関数直接呼び出し解析処理（Ｓ１０７）によって解析した結果である仮想関数直接呼び出し情報１１５を図１６に示す。
【０１１２】
次に、仮想関数呼び出し変換部１０８の実行する処理について、当該処理を図５に示すプログラム１１１に適用した場合を例にして、図１７を参考にしながら説明する。
【０１１３】
仮想関数呼び出し変換部１０８が実行する仮想関数呼び出し変換処理（Ｓ１０８）はｅ１からｅ８までのステップを含む。以下記号の順に説明していく。
【０１１４】
ステップｅ１では、仮想関数呼び出し変換部１０８は、プログラム中の仮想関数呼び出しを含む全ての文Ｓ１について以下の処理を繰り返す。図５では「ｔｈｉｓ−＞ｇ（）；」、「ｔｈｉｓ−＞ｈ（）；」などが対象となる。
【０１１５】
ステップｅ２では、仮想関数呼び出し変換部１０８は、文Ｓ１が仮想関数定義Ｆ２中に含まれるかどうかを調べる。文Ｓ１が仮想関数定義Ｆ２中に含まれる場合はステップｅ３に処理を移行し、仮想関数定義Ｆ２中に含まれない場合はステップｅ８に処理を移行する。図５の文「ｔｈｉｓ−＞ｇ（）；」は、仮想関数「Ａ：：ｆ」中に含まれているのでステップｅ２の判定はＹｅｓとなり、ステップｅ３へと処理を移行する。同様に、文「ｔｈｉｓ−＞ｈ（）；」は、仮想関数「Ｂ：：ｇ」中に含まれているのでステップｅ２の判定はＹｅｓとなり、ステップｅ３へと処理を移行する。一方、文「ｏｂｊ＿ｃ．ｇ（）；」は、関数ｔ中に含まれ、関数ｔは仮想関数ではないので、ステップｅ２の判定はＮｏとなり、ステップｅ８へと処理を移行する。
【０１１６】
ステップｅ３では、仮想関数呼び出し変換部１０８は、文Ｓ１がｔｈｉｓポインタに対する呼び出しかどうかを調べる。文Ｓ１がｔｈｉｓポインタに対する呼び出しの場合はステップｅ４に処理を移行し、ｔｈｉｓポインタに対する呼び出しでない場合はステップｅ８に処理を移行する。図５の文「ｔｈｉｓ−＞ｇ（）；」、および文「ｔｈｉｓ−＞ｈ（）；」では、仮想関数ｇおよびｈの呼び出しはｔｈｉｓポインタに対して行なわれているため、ステップｅ３の判定はＹｅｓとなり、ステップｅ４へと処理を移行する。
【０１１７】
ステップｅ４では、仮想関数呼び出し変換部１０８は、仮想関数Ｆ２が属するクラスＣ１が派生クラスを持つかどうかをクラスの継承関係情報１１３を参照して調べる。クラスＣ１が派生クラスを持つ場合は、ステップｅ５に処理を移行し、派生クラスを持たない場合は、ステップｅ７に処理を移行する。図５の仮想関数「Ａ：：ｆ」では、ｆが属するクラスＡはクラスの継承関係情報１１３を参照すると派生クラスを持つことがわかるので、ステップｅ４の判定はＹｅｓとなり、ステップｅ５へと処理を移行する。同様に仮想関数「Ｂ：：ｇ」では、ｇが属するクラスＢは派生クラスを持つことがわかるのでステップｅ４の判定はＹｅｓとなる。
【０１１８】
ステップｅ５では、仮想関数呼び出し変換部１０８は、クラスＣ１の派生クラスのうち、仮想関数Ｆ１が再定義されている派生クラスＣ２で仮想関数Ｆ２が再定義されているかどうかを調べる。仮想関数Ｆ２が再定義されている場合はステップｅ６に処理を移行し、再定義されていない場合はステップｅ８に処理を移行する。図５では、仮想関数再定義情報１１４を参照すると、仮想関数「Ａ：：ｇ」が再定義されているクラスＡの派生クラスはクラスＢのみであることがわかり、同時にクラスＢで仮想関数ｆが再定義されていることがわかる。従ってステップｅ５の判定はＹｅｓとなり、ステップｅ６へと処理を移行する。一方、仮想関数「Ａ：：ｈ」が再定義されているクラスＢの派生クラスはクラスＤのみであり、同時にクラスＤで仮想関数ｇが再定義されているため、ステップｅ５の判定はＹｅｓとなる。
【０１１９】
なお、仮想関数Ｆ１が派生クラスＣ２で一旦再定義されると、ステップｅ５の処理ではＣ２を継承した派生クラスまでは探索対象とする必要はない。なぜなら、Ｃ２を継承した派生クラスで仮想関数Ｆ１が再定義されていなかったとしても、Ｃ２の派生クラスから呼び出されるＦ１はクラスＣ２のＦ１であり、クラスＣ１の仮想関数Ｆ１は必ず再定義された状態であるためである。
【０１２０】
ステップｅ６では、仮想関数呼び出し変換部１０８は、クラスＣ２およびＣ２の全ての派生クラスのオブジェクトに対して仮想関数Ｆ２が直接呼び出しされていないかどうかを調べる。仮想関数Ｆ２が直接呼び出しされていない場合はステップｅ７に処理を移行し、直接呼び出しされている場合はステップｅ８に処理を移行する。図５では、仮想関数直接呼び出し情報１１５を参照すると、クラスＢおよびクラスＢの派生クラスであるクラスＣ、Ｄのオブジェクトに対して仮想関数ｆが直接呼び出しされていないので、ステップｅ６の判定はＹｅｓとなり、ステップｅ７へと処理を移行する。同様に、仮想関数ｇが直接呼び出されているのはクラスＣのオブジェクトに対してのみであり、クラスＤのオブジェクトに対しては呼び出されていないため、ステップｅ６の判定はＹｅｓとなる。
【０１２１】
ステップｅ７では、仮想関数呼び出し変換部１０８は、文Ｓ１を関数Ｆ１の直接呼び出しに変換する。図５の文「ｔｈｉｓ−＞ｇ（）；」に対しては、仮想関数ｇを直接呼び出しに変換し、「ｔｈｉｓ−＞Ａ：：ｇ（）；」と記述された場合と同等のコードに変換する。
同様に、「ｔｈｉｓ−＞ｈ（）；」は「ｔｈｉｓ−＞Ｂ：：ｈ（）；」と記述された場合と同等のコードに変換する。
【０１２２】
ステップｅ８では、仮想関数呼び出し変換部１０８は、ステップｅ１に処理を移行し、ループの処理を繰り返す。
【０１２３】
図５のプログラム１１１を仮想関数呼び出し変換部１０８によって変換した結果得られるコードを図１８に示す。このコードでは、仮想関数Ａ：：ｇ（）と、仮想関数Ｂ：：ｈ（）とが直接呼び出しされている。
【０１２４】
以上説明したように、本実施の形態に係るプログラム変換装置１００に、図５に示すプログラム１１１を入力した結果、仮想関数呼び出しを含む文「ｔｈｉｓ−＞ｇ（）；」および文「ｔｈｉｓ−＞ｈ（）；」を関数の直接呼び出しに変換することができる。このため、目的プログラム１１２実行時の実行速度の向上を図ることができる。
【０１２５】
なお、上記実施形態において、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）、仮想関数呼び出し変換処理（Ｓ１０８）は、それぞれ一回のみ実行することとしているが、必要に応じて複数回繰り返すようにしても良い。
【０１２６】
また、仮想関数および仮想関数が属するクラスが、特定の条件を満たした場合に、その仮想関数定義においてｔｈｉｓポインタの型を特定することができるとしているが、クラスオブジェクトの生成処理を行なうコンストラクタや、削除処理を行なうデストラクタでは、ｔｈｉｓポインタの型はそのコンストラクタやデストラクタが属するクラスに特定可能である。このため、コンストラクタやデストラクタ中に記述されているｔｈｉｓポインタに対する仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
【０１２７】
また、プログラムの性質上や実行結果からｔｈｉｓポインタの型が明らかに特定できるような場合は、ｐｒａｇｍａ指令、オプション指定およびプログラムの実行履歴情報などを元に、仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
［実施の形態３］
本実施の形態では、以下の条件（１）から条件（４）を満たす場合に、ｔｈｉｓポインタの型を特定することができるため、仮想関数Ｆ１の呼び出しを直接関数呼び出しに変換する。
【０１２８】
すなわち、
（１）  仮想関数Ｆ１が仮想関数Ｆ２の定義中に記述されている。
【０１２９】
（２）  仮想関数Ｆ１がｔｈｉｓポインタに対して呼び出されている。
（３）  仮想関数Ｆ２の属するクラスＣ１の派生クラスのオブジェクトに対して仮想関数Ｆ２が直接呼び出されていない。
【０１３０】
（４）  派生クラスで再定義されていない仮想関数を全て複製する。
図１９は、上述の４つの条件に従い、実施の形態３に係るプログラム変換装置の実行する処理の概略を説明する図である。すなわち、図１９（ａ）に示されるようなクラスの定義と、図１９（ｃ）に示されるようなプログラムが与えられた場合を考える。
【０１３１】
仮想関数ｇを仮想関数Ｆ１とし、仮想関数ｆを仮想関数Ｆ２とした場合には、図１９（ｃ）の文「ｔｈｉｓ−＞ｇ（）」は、条件（１）および条件（２）を満たす。すなわち、仮想関数Ｆ１（仮想関数ｇ）が仮想関数Ｆ２（仮想関数ｆ）の定義中に記述されているため、条件（１）を満たす。また、仮想関数Ｆ１（仮想関数ｇ）は、ｔｈｉｓポインタに対して呼び出されているため、条件（２）を満たす。
【０１３２】
また、条件（３）について考えると、プログラム中にＡ：：ｆ（ｖｏｉｄ）の直接呼び出しが存在しない。このため、仮想関数Ｆ２（仮想関数ｆ）の属するクラスＣ１（クラスＡ）の派生クラス（クラスＢ、Ｃ、Ｄ）のオブジェクトに対して仮想関数Ｆ２（仮想関数ｆ）が直接呼び出されていない。したがって、条件（３）を満たす。
【０１３３】
さらに、派生クラス（クラスＢ、Ｃ、Ｄ）で再定義されていない仮想関数を全て複製する。すなわち、図１９（ｂ）に示すように、クラスＢでは仮想関数ｆおよび仮想関数ｇを複製し、クラスＤでは仮想関数ｇを複製する。これにより、条件（４）を満たす。
【０１３４】
このため、このような場合には、図１９（ｃ）に示されるような仮想関数ｇの呼び出しを、図１９（ｄ）に示されるように、クラスＡの仮想関数ｇの直接呼び出しに変換することができる。
［プログラム変換装置の構成］
図２０は本発明の実施の形態３におけるプログラム変換装置２００の構成を示す図である。プログラム変換装置２００は、入力部１０２と、構文解析部１０３と、クラス継承関係解析部１０４と、仮想関数再定義解析部１０５と、解析情報記憶部２０６と、仮想関数直接呼び出し解析部１０７と、仮想関数呼び出し変換判定部２０１と、仮想関数定義複製部２０２と、仮想関数呼び出し変換部２０３と、出力部１０９とから構成されている。
【０１３５】
このうち、プログラム記憶部１０１、入力部１０２、構文解析部１０３、クラス継承関係解析部１０４、仮想関数再定義解析部１０５、仮想関数直接呼び出し解析部１０７、出力部１０９および生成コード記憶部１１０は、図２に示した実施の形態１に係るプログラム変換装置１００の各部と同様の処理を行う。このため、その詳細な説明はここでは繰り返さない。
【０１３６】
仮想関数呼び出し変換判定部２０１は、解析情報記憶部１０６に格納されたクラスの継承関係情報１１３および仮想関数直接呼び出し情報１１５を参照し、仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、直接呼び出しに変換可能な仮想関数呼び出しを含む文に関する情報（以下、「直接呼び出し可能文情報」と称する。）を解析情報記憶部１０６に格納する。
【０１３７】
仮想関数定義複製部２０２は、解析情報記憶部１０６に格納されたクラスの継承関係情報１１３および仮想関数再定義情報１１４を参照し、派生クラスで再定義されていない仮想関数を複製し、派生クラスで再定義された状態に変換する。
【０１３８】
仮想関数呼び出し変換部２０３は、解析情報記憶部１０６に格納された直接呼び出し可能文情報１１６に含まれる文を、関数の直接呼び出しに変換する。
【０１３９】
解析情報記憶部１０６は、各ステップで解析された情報を記憶する記憶装置である。すなわち、解析情報記憶部１０６は、クラスの継承関係情報１１３、仮想関数再定義情報１１４、仮想関数直接呼び出し情報１１５および直接呼び出し可能文情報１１６を記憶する記憶装置である。
［プログラム変換装置の実行する処理の概要］
図２１は、本実施の形態におけるプログラム変換装置２００の実行する処理のフローチャートである。
【０１４０】
このうち、入力処理（Ｓ１０２）、構文解析処理（Ｓ１０３）、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）および出力処理（Ｓ１０９）は、図３に示したプログラム変換装置１００の実行する対応する処理と同様である。このため、その詳細な説明はここでは繰り返さない。
【０１４１】
仮想関数呼び出し変換判定処理（Ｓ２０１）では、仮想関数呼び出し変換判定部２０１は、解析情報記憶部１０６に格納されたクラスの継承関係情報１１３および仮想関数直接呼び出し情報１１５を参照し、仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、直接呼び出し可能文情報１１６を解析情報記憶部２０６に格納する。
【０１４２】
仮想関数定義複製処理（Ｓ２０２）では、仮想関数定義複製部２０２は、解析情報記憶部１０６に格納されたクラスの継承関係情報１１３および仮想関数再定義情報１１４を参照し、派生クラスで再定義されていない仮想関数を複製し、派生クラスで再定義された状態に変換する。
【０１４３】
仮想関数呼び出し変換処理（Ｓ２０３）では、仮想関数呼び出し変換部２０３は、解析情報記憶部１０６に格納された直接呼び出し可能文情報１１６に含まれる文を、関数の直接呼び出しに変換する。
［プログラム変換装置の実行する処理の詳細］
次に、プログラム変換装置２００の実行する処理の詳細について、図２２に示すプログラム１１１を参照しながら説明していく。
【０１４４】
まず、入力部１０２は、プログラム記憶部１０１から全てのプログラム１１１を入力し（Ｓ１０２）、構文解析部１０３は、プログラム１１１の構文木やシンボルテーブルの作成などを行なう（Ｓ１０３）。
【０１４５】
次に、クラス継承関係解析部１０４は、プログラム１１１中に含まれるクラスおよびクラス間の継承関係を解析し、解析結果をクラスの継承関係情報１１３に記録する（Ｓ１０４）。クラス継承関係解析処理（Ｓ１０４）は、図４に示したものと同様である。図２２のプログラム１１１をクラス継承関係解析処理（Ｓ１０４）によって解析した結果であるクラスの継承関係情報１１３を図２３に示す。
【０１４６】
次に、仮想関数再定義解析部１０５は、基底クラスの仮想関数の再定義状態を解析し、解析結果を仮想関数再定義情報１１４に記録する（Ｓ１０５）。仮想関数再定義解析処理（Ｓ１０５）は図７に示したものと同様である。図２２のプログラム１１１を仮想関数再定義解析処理（Ｓ１０５）によって解析した結果である仮想関数再定義情報１１４を図２４に示す。
【０１４７】
次に、仮想関数直接呼び出し解析部１０７は、直接呼び出しされる仮想関数を解析し、解析結果を仮想関数直接呼び出し情報１１５に記録する（Ｓ１０７）。仮想関数直接呼び出し解析処理（Ｓ１０７）は図９に示したものと同様である。図２２のプログラム１１１を仮想関数直接呼び出し解析処理（Ｓ１０７）によって解析した結果である仮想関数直接呼び出し情報１１５を図２５に示す。
【０１４８】
次に、仮想関数呼び出し変換判定部２０１の実行する処理について、当該処理を図２２に示すプログラム１１１に適用した場合を例にして、図２６を参考にしながら説明する。
【０１４９】
仮想関数呼び出し変換判定部２０１が実行する仮想関数呼び出し変換判定処理（Ｓ２０１）は、ｆ１からｆ６までのステップを含む。以下記号の順に説明していく。
【０１５０】
ステップｆ１では、仮想関数呼び出し変換判定部２０１は、プログラム１１１中の仮想関数呼び出しを含む全ての文Ｓ１について、以下の処理を繰り返す。図２２では「ｔｈｉｓ−＞ｇ（）；」、「ｔｈｉｓ−＞ｈ（）；」などが対象となる。
【０１５１】
ステップｆ２では、仮想関数呼び出し変換判定部２０１は、文Ｓ１が仮想関数定義Ｆ２中に含まれるかどうかを調べる。文Ｓ１が仮想関数定義Ｆ２中に含まれる場合はステップｆ３に処理を移行し、仮想関数定義Ｆ２中に含まれない場合はステップｆ６に処理を移行する。図２２の文「ｔｈｉｓ−＞ｇ（）；」は、仮想関数「Ａ：：ｆ」中に含まれているのでステップｆ２の判定はＹｅｓとなり、ステップｆ３へと処理を移行する。同様に、文「ｔｈｉｓ−＞ｈ（）；」は、仮想関数「Ｂ：：ｇ」中に含まれているのでステップｆ２の判定はＹｅｓとなり、ステップｆ３へと処理を移行する。一方、文「ｏｂｊ＿ｃ．ｇ（）；」で、関数ｔ中に含まれ、関数ｔは仮想関数ではないので、ステップｆ２の判定はＮｏとなり、ステップｆ６へと処理を移行する。
【０１５２】
ステップｆ３では、仮想関数呼び出し変換判定部２０１は、文Ｓ１がｔｈｉｓポインタに対する呼び出しかどうかを調べる。文Ｓ１がｔｈｉｓポインタに対する呼び出しの場合はステップｆ４に処理を移行し、ｔｈｉｓポインタに対する呼び出しでない場合はステップｆ６に処理を移行する。図２２の文「ｔｈｉｓ−＞ｇ（）；」、および文「ｔｈｉｓ−＞ｈ（）；」では、仮想関数ｇおよびｈの呼び出しはｔｈｉｓポインタに対して行なわれているためステップｆ３の判定はＹｅｓとなり、ステップｆ４へと処理を移行する。
【０１５３】
ステップｆ４では、仮想関数呼び出し変換判定部２０１は、仮想関数Ｆ２の属するクラスＣ１の全ての派生クラスＣ３のオブジェクトに対して仮想関数Ｆ２が直接呼び出しされていないかどうかを調べる。仮想関数Ｆ２が直接呼び出しされていない場合はステップｆ５に処理を移行し、直接呼び出しされている場合はステップｆ６に処理を移行する。図２２では、仮想関数直接呼び出し情報１１５を参照すると、クラスＡの全ての派生クラスＢ、ＣおよびＤのオブジェクトに対して仮想関数「Ａ：：ｆ」が直接呼び出されていることはないので、ステップｆ４の判定はＹｅｓとなり、ステップｆ５へと処理を移行する。一方、仮想関数「Ｂ：：ｇ」の直接呼び出しを調べると、クラスＣのオブジェクトに対して仮想関数「Ｂ：：ｇ」が直接呼び出しされているので、ステップｆ４の判定はＮｏとなり、ステップｆ６へと処理を移行する。
【０１５４】
ステップｆ５では、仮想関数呼び出し変換判定部２０１は、文Ｓ１を直接呼び出し可能文情報１１６に追加する。図２２では、文「ｔｈｉｓ−＞ｇ（）；」を直接呼び出し可能文情報１１６に追加する。
【０１５５】
ステップｆ６では、仮想関数呼び出し変換判定部２０１は、ステップｆ１に処理を移行し、ループの処理を繰り返す。
【０１５６】
図２２のプログラム１１１を仮想関数呼び出し変換判定部２０１による仮想関数呼び出し変換判定処理（Ｓ２０１）によって解析した結果である直接呼び出し可能文情報１１６を図２７に示す。
【０１５７】
次に、仮想関数定義複製部２０２が実行する仮想関数定義複製処理（Ｓ２０２）について、当該処理を図２２に示すプログラム１１１に適用した場合を例にして、図２８を参考にしながら説明する。
【０１５８】
仮想関数定義複製部２０２が実行する仮想関数定義複製処理（Ｓ２０２）は、ｇ１からｇ７までのステップを含む。以下記号の順に説明していく。
【０１５９】
ステップｇ１では、仮想関数定義複製部２０２は、直接呼び出し可能文情報１１６が空集合かどうかを調べる。空集合の場合は仮想関数定義複製処理（Ｓ２０２）を終了し、空集合でない場合はステップｇ２に処理を移行する。図２２のプログラム１１１では、直接呼び出し可能文情報１１６は空集合ではないので、ステップｇ１の判定はＮｏとなり、ステップｇ２へと処理を移行する。
【０１６０】
ステップｇ２では、仮想関数定義複製部２０２は、全てのプログラム１１１中に含まれる、全てのクラスＣ１について以下の処理を繰り返す。すなわち、図２２の全てのプログラム１１１中に含まれるクラスＡ、Ｂ、ＣおよびＤについて繰り返す。
【０１６１】
ステップｇ３では、仮想関数定義複製部２０２は、クラスＣ１が基底クラスＣ２を持つかどうかを調べる。クラスＣ１が基底クラスＣ２を持つ場合はステップｇ４に処理を移行し、基底クラスＣ２を持たない場合はステップｇ７に処理を移行する。図２２のクラスＡの場合、クラスＡは基底クラスを持たないためステップｇ３の判定はＮｏとなり、ステップｇ７へと処理を移行する。また、クラスＢの場合は基底クラスとしてクラスＡを持つので、ステップｇ３の判定はＹｅｓとなり、ステップｇ４へと処理を移行する。クラスＣおよびＤもそれぞれ基底クラスＢを持つので、ステップｇ３の判定はＹｅｓとなり、ステップｇ４へと処理を移行する。
【０１６２】
ステップｇ４では、仮想関数定義複製部２０２は、クラスＣ２の仮想関数でクラスＣ１で再定義されていない関数Ｆ１が存在するかどうかを調べる。クラスＣ１で再定義されていない関数Ｆ１が存在する場合はステップｇ５に処理を移行し、存在しない場合はステップｇ７に処理を移行する。図２２のクラスＢの場合、仮想関数再定義情報１１４を参照すると、基底クラスＡの仮想関数ｆおよびｈを再定義していないことがわかるので、ステップｇ４の判定はＹｅｓとなり、ステップｇ５へと処理を移行する。同様に、クラスＢ、ＣおよびＤの場合もそれぞれ基底クラスの仮想関数を再定義していないものがあるので、ステップｇ４の判定はＹｅｓとなる。
【０１６３】
ステップｇ５では、仮想関数定義複製部２０２は、クラスＣ２の仮想関数Ｆ１を複製して仮想関数Ｆ２を生成し、クラスＣ１で再定義されたようにクラスＣ１の定義を変換する。図２２のクラスＢの場合、基底クラスＡの仮想関数ｆおよびｈを複製してｆ’およびｈ’を生成し、クラスＢで再定義されたようにクラスＢの定義を変換する。クラスＣおよびＤの場合も同様に基底クラスＢの仮想関数を複製してクラスの定義を変換する。
【０１６４】
ステップｇ６では、仮想関数定義複製部２０２は、クラスＣ１の仮想関数テーブルの関数Ｆ１の欄を関数Ｆ２に置き換える。図２２のクラスＢの場合、クラスＢの仮想関数テーブルの関数ｆおよびｈの欄はそれぞれ「Ａ：：ｆ（ｖｏｉｄ）」、「Ａ：：ｈ（ｖｏｉｄ）」であったが、複製した関数「Ｂ：：ｆ’（ｖｏｉｄ）」「Ｂ：：ｈ’（ｖｏｉｄ）」に書き換える。同様に、クラスＣ、クラスＤの仮想関数テーブルの欄を複製した関数に書き換える。
【０１６５】
ステップｇ７では、仮想関数定義複製部２０２は、ステップｇ２に処理を移行し、ループの処理を繰り返す。
【０１６６】
図２２のプログラム１１１を仮想関数定義複製処理（Ｓ２０２）によって変換した結果のプログラムおよび各クラスの仮想関数テーブルを図２９および図３０にそれぞれ示す。
【０１６７】
次に、仮想関数呼び出し変換部２０３が実行する仮想関数呼び出し変換処理（Ｓ２０３）について、当該処理を図２２に示すプログラム１１１に適用した場合を例にして、図３１を参考にしながら説明する。
【０１６８】
仮想関数呼び出し変換部２０３が実行する仮想関数呼び出し変換処理（Ｓ２０３）はｈ１からｈ３までのステップを含む。以下記号の順に説明していく。
【０１６９】
ステップｈ１では、仮想関数呼び出し変換部２０３は、直接呼び出し可能文情報１１６に含まれる全ての文Ｓ１について以下の処理を繰り返す。図２２のプログラム１１１では、直接呼び出し可能文情報１１６に含まれる文「ｔｈｉｓ−＞ｇ（）」について以降の処理を実行する。
【０１７０】
ステップｈ２では、仮想関数呼び出し変換部２０３は、文Ｓ１に含まれる仮想関数呼び出しを関数の直接呼び出しに変換する。図２２では、文「ｔｈｉｓ−＞ｇ（）」の仮想関数呼び出しを関数の直接呼び出しに変換し、「ｔｈｉｓ−＞Ａ：：ｇ（）；」と記述された場合と同等のコードに変換する。
【０１７１】
ステップｈ３では、仮想関数呼び出し変換部２０３は、ステップｈ１に処理を移行し、ループの処理を繰り返す。
【０１７２】
図２２のプログラム１１１を仮想関数呼び出し変換処理（Ｓ２０３）によって変換した結果、得られるコードを図３２に示す。
【０１７３】
以上説明したように、本実施の形態に係るプログラム変換装置２００に、図２２に示すプログラム１１１を適用した結果、仮想関数呼び出しを含む文「ｔｈｉｓ−＞ｇ（）；」を関数の直接呼び出しに変換することができる。このため、目的プログラム１１２実行時の実行速度の向上を図ることができる。
【０１７４】
なお、上記実施形態において、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）、仮想関数呼び出し変換判定処理（Ｓ２０１）、仮想関数定義複製処理（Ｓ２０２）、仮想関数呼び出し変換処理（Ｓ２０３）は一回のみ実行するとしているが、必要に応じて複数回繰り返すようにしても良い。
【０１７５】
また、仮想関数および仮想関数が属するクラスが、特定の条件を満たした場合に、その仮想関数定義においてｔｈｉｓポインタの型を特定することができるとしているが、クラスオブジェクトの生成処理を行なうコンストラクタや、削除処理を行なうデストラクタでは、ｔｈｉｓポインタの型はそのコンストラクタやデストラクタが属するクラスに特定可能である。このため、コンストラクタやデストラクタ中に記述されているｔｈｉｓポインタに対する仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
【０１７６】
また、プログラムの性質上や実行結果からｔｈｉｓポインタの型が明らかに特定できるような場合は、ｐｒａｇｍａ指令、オプション指定およびプログラムの実行履歴情報などを元に、仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
［実施の形態４］
本実施の形態では、仮想関数呼び出し変換判定部２０１および仮想関数定義複製部２０２の実行する処理が実施の形態３とは異なる。仮想関数呼び出し変換判定部２０１および仮想関数定義複製部２０２がそれぞれ実行する仮想関数呼び出し変換判定処理（Ｓ２０１）および仮想関数定義複製処理（Ｓ２０２）については後述する。
【０１７７】
また、解析情報記憶部２０６は、さらに、複製仮想関数情報（図示せず）を記憶する。複製仮想関数情報については後述する。
【０１７８】
本実施の形態では、以下の条件（１）から条件（４）を満たす場合に、ｔｈｉｓポインタの型を特定することができるため、仮想関数Ｆ１の呼び出しを直接関数呼び出しに変換する。
【０１７９】
すなわち、
（１）  仮想関数Ｆ１が仮想関数Ｆ２の定義中に記述されている。
【０１８０】
（２）  仮想関数Ｆ１がｔｈｉｓポインタに対して呼び出されている。
（３）  仮想関数Ｆ２の属するクラスＣ１以外の派生クラスのオブジェクトに対して仮想関数Ｆ２が直接呼び出されていない。
【０１８１】
（４）  クラスＣ１の直接派生クラスで再定義されていない仮想関数Ｆ２を全て複製する。
【０１８２】
図３３は、上述の４つの条件に従い、実施の形態４に係るプログラム変換装置の実行する処理の概略を説明する図である。すなわち、図３３（ａ）に示されるようなクラスの定義と、図３３（ｃ）に示されるようなプログラムが与えられた場合を考える。
【０１８３】
仮想関数ｇを仮想関数Ｆ１とし、仮想関数ｆを仮想関数Ｆ２とした場合には、図３３（ｃ）の文「ｔｈｉｓ−＞ｇ（）」は、条件（１）および条件（２）を満たす。すなわち、仮想関数Ｆ１（仮想関数ｇ）が仮想関数Ｆ２（仮想関数ｆ）の定義中に記述されているため、条件（１）を満たす。また、仮想関数Ｆ１（仮想関数ｇ）は、ｔｈｉｓポインタに対して呼び出されているため、条件（２）を満たす。
【０１８４】
また、条件（３）について考えると、プログラム中にＡ：：ｆ（ｖｏｉｄ）の直接呼び出しが存在しない。このため、仮想関数Ｆ２（仮想関数ｇ）の属するクラスＣ１（クラスＡ）以外の派生クラス（クラスＢ、Ｃ、Ｄ）のオブジェクトに対して仮想関数Ｆ２（仮想関数ｇ）が直接呼び出されていない。このため、条件（３）を満たす。
【０１８５】
さらに、クラスＣ１（クラスＡ）の直接派生クラス（クラスＢ）で再定義されていない仮想関数Ｆ２（仮想関数ｆ）を全て複製する。すなわち、図３３（ｂ）に示されるように、クラスＢで仮想関数ｆを複製する。これにより、条件（４）を満たす。
【０１８６】
このため、このような場合には、図３３（ｃ）に示されるような仮想関数ｇの呼び出しを、図３３（ｄ）に示されるように、クラスＡの仮想関数ｇの直接呼び出しに変換することができる。
【０１８７】
以下では、実施の形態４に係るプログラム変換装置２００が実行する処理について、プログラム例を参照しながら説明していく。
【０１８８】
まず、入力部１０２は、プログラム記憶部１０１から全てのプログラム１１１を入力し（Ｓ１０２）、構文解析部１０３は、プログラムの構文木やシンボルテーブルの作成などを行なう（Ｓ１０３）。
【０１８９】
次に、クラス継承関係解析部１０４は、プログラム中に含まれるクラスおよびクラス間の継承関係を解析し、解析結果をクラスの継承関係情報１１３に記録する（Ｓ１０４）。クラス継承関係解析処理（Ｓ１０４）は、図４に示したものと同様である。図２２のプログラム１１１をクラス継承関係解析処理（Ｓ１０４）によって解析した結果であるクラスの継承関係情報１１３を図３４に示す。
【０１９０】
次に、仮想関数再定義解析部１０５は、基底クラスの仮想関数の再定義状態を解析し、解析結果を仮想関数再定義情報１１４に記録する（Ｓ１１５）。仮想関数再定義解析処理（Ｓ１０５）は、図７に示したものと同様である。図２２のプログラム１１１を仮想関数再定義解析処理（Ｓ１０５）によって解析した結果である仮想関数再定義情報１１４を図３５に示す。
【０１９１】
次に、仮想関数直接呼び出し解析部１０７は、直接呼び出しされる仮想関数を解析し、解析結果を仮想関数直接呼び出し情報１１５に記録する（Ｓ１０７）。仮想関数直接呼び出し解析処理（Ｓ１０７）は、図９に示したものと同様である。図２２のプログラム１１１を仮想関数直接呼び出し解析処理（Ｓ１０７）によって解析した結果である仮想関数直接呼び出し情報１１５を図３６に示す。
【０１９２】
次に、仮想関数呼び出し変換判定部２０１の実行する仮想関数呼び出し変換判定処理（Ｓ２０１）の詳細について、当該処理を図２２に示すプログラム１１１に適用した場合を例にして、図３７を参考にしながら説明する。
【０１９３】
仮想関数呼び出し変換判定処理（Ｓ２０１）は、ｊ１からｊ７までのステップを含む。以下記号の順に説明していく。
【０１９４】
ステップｊ１では、仮想関数呼び出し変換判定部２０１は、プログラム１１１中の仮想関数呼び出しを含む全ての文Ｓ１について以下の処理を繰り返す。図２２では「ｔｈｉｓ−＞ｇ（）；」、「ｔｈｉｓ−＞ｈ（）；」などが対象となる。
【０１９５】
ステップｊ２では、仮想関数呼び出し変換判定部２０１は、文Ｓ１が仮想関数定義Ｆ２中に含まれるかどうかを調べる。文Ｓ１が仮想関数定義Ｆ２中に含まれる場合はステップｊ３に処理を移行し、仮想関数定義Ｆ２中に含まれない場合はステップｊ７に処理を移行する。図２２の文「ｔｈｉｓ−＞ｇ（）；」では、仮想関数Ａ：：ｆ中に含まれているのでステップｊ２の判定はＹｅｓとなり、ステップｊ３へと処理を移行する。同様に、文「ｔｈｉｓ−＞ｈ（）；」では、仮想関数「Ｂ：：ｇ」中に含まれているのでステップｊ２の判定はＹｅｓとなり、ステップｊ３へと処理を移行する。一方、文「ｏｂｊ＿ｃ．ｇ（）；」では、関数ｔ中に含まれ、関数ｔは仮想関数ではないので、ステップｊ２の判定はＮｏとなり、ステップｊ７へと処理を移行する。
【０１９６】
ステップｊ３では、仮想関数呼び出し変換判定部２０１は、文Ｓ１がｔｈｉｓポインタに対する呼び出しかどうかを調べる。文Ｓ１がｔｈｉｓポインタに対する呼び出しの場合はステップｊ４に処理を移行し、ｔｈｉｓポインタに対する呼び出しでない場合はステップｊ７に処理を移行する。図２２の文「ｔｈｉｓ−＞ｇ（）；」、および文「ｔｈｉｓ−＞ｈ（）；」では、仮想関数ｇおよびｈの呼び出しはｔｈｉｓポインタに対して行なわれているためステップｊ３の判定はＹｅｓとなり、ステップｊ４へと処理を移行する。
【０１９７】
ステップｊ４では、仮想関数呼び出し変換判定部２０１は、仮想関数Ｆ２の属するクラスＣ１の全ての派生クラスＣ３のオブジェクトに対して仮想関数Ｆ２が直接呼び出しされていないかどうかを調べる。仮想関数Ｆ２が直接呼び出しされていない場合はステップｊ５に処理を移行し、直接呼び出しされている場合はステップｊ７に処理を移行する。図２２では、仮想関数直接呼び出し情報１１５を参照すると、クラスＡの全ての派生クラスＢ、ＣおよびＤのオブジェクトに対して仮想関数「Ａ：：ｆ」が直接呼び出されていることはないので、ステップｊ４の判定はＹｅｓとなり、ステップｊ５へと処理を移行する。一方、仮想関数「Ｂ：：ｇ」の直接呼び出しを調べると、クラスＣのオブジェクトに対して仮想関数「Ｂ：：ｇ」が直接呼び出しされているので、ステップｊ４の判定はＮｏとなり、ステップｊ７へと処理を移行する。
【０１９８】
ステップｊ５では、仮想関数呼び出し変換判定部２０１は、文Ｓ１を直接呼び出し可能文情報１１６に追加する。図２２では、文「ｔｈｉｓ−＞ｇ（）；」を直接呼び出し可能文情報１１６に追加する。
【０１９９】
ステップｊ６では、仮想関数呼び出し変換判定部２０１は、クラスＣ１の全ての直接基底クラスと仮想関数Ｆ２との対Ｐ１を、解析情報記憶部２０６に複製仮想関数情報として追加する。図２２では、クラスＡの直接基底クラスはクラスＢのみであるので、クラスＢとＡ：：ｆとの対を複製仮想関数情報に追加する。直接基底クラスが複数個ある場合は複数個の対を複製仮想関数情報に追加する。
【０２００】
ステップｊ７では、仮想関数呼び出し変換判定部２０１は、ステップｊ１に処理を移行し、ループの処理を繰り返す。
【０２０１】
図２２のプログラム１１１を仮想関数呼び出し変換判定処理（Ｓ２０１）によって解析した結果である直接呼び出し可能文情報１１６および複製仮想関数情報を図３８および図３９にそれぞれ示す。
【０２０２】
次に、仮想関数定義複製部２０２が実行する仮想関数定義複製処理（Ｓ２０２）について、当該処理を図２２に示すプログラム１１１に適用した場合を例にして、図４０を参考にしながら説明する。
【０２０３】
仮想関数定義複製処理（Ｓ２０２）はｋ１からｋ６までのステップを含む。以下記号の順に説明していく。
【０２０４】
ステップｋ１では、仮想関数定義複製部２０２は、直接呼び出し可能文情報１１６が空集合かどうかを調べる。空集合の場合は仮想関数定義複製処理（Ｓ２０２）を終了し、空集合でない場合はステップｋ２に処理を移行する。図２２のプログラム１１１では、直接呼び出し可能文情報１１６は空集合ではないので、ステップｋ１の判定はＮｏとなり、ステップｋ２へと処理を移行する。
【０２０５】
ステップｋ２では、仮想関数定義複製部２０２は、複製仮想関数情報の全ての対Ｐ１について以下の処理を繰り返す。図２２では、クラスＢと仮想関数「Ａ：：ｆ」との対について以下の処理を繰り返す。
【０２０６】
ステップｋ３では、仮想関数定義複製部２０２は、対Ｐ１のクラスＣ１で対Ｐ１の仮想関数Ｆ１が再定義されているかどうかを調べる。再定義されていない場合はステップｋ４に処理を移行し、再定義されている場合はステップｋ６に処理を移行する。図２２の対Ｐ１のクラスＢの場合、仮想関数再定義情報１１４を参照すると、対Ｐ１の仮想関数「Ａ：：ｆ」がクラスＢで再定義されていないことがわかるので、ステップｋ３の判定はＹｅｓとなり、ステップｋ４へと処理を移行する。
【０２０７】
ステップｋ４では、仮想関数定義複製部２０２は、仮想関数Ｆ１を複製して仮想関数Ｆ２を生成し、クラスＣ１で再定義されたようにクラスＣ１の定義を変換する。図２２のクラスＢの場合、仮想関数「Ａ：：ｆ」を複製してｆ’を生成し、クラスＢで再定義されたようにクラスＢの定義を変換する。
【０２０８】
ステップｋ５では、仮想関数定義複製部２０２は、全てのクラスＣ２の仮想関数テーブルの関数Ｆ１が登録されている欄を関数Ｆ２に置き換える。図２２では、クラスＢ、ＣおよびＤの仮想関数テーブルの関数ｆ「Ａ：：ｆ（ｖｏｉｄ）」の欄を、複製した関数「Ｂ：：ｆ’（ｖｏｉｄ）」に書き換える。
【０２０９】
ステップｋ６では、仮想関数定義複製部２０２は、ステップｋ２に処理を移行し、ループの処理を繰り返す。
【０２１０】
図２２のプログラム１１１を仮想関数定義複製部２０２が実行する仮想関数定義複製処理（Ｓ２０２）によって変換した結果であるプログラムおよび各クラスの仮想関数テーブルを図４１および図４２にそれぞれ示す。
【０２１１】
次に、仮想関数呼び出し変換部２０３は、仮想関数呼び出しを関数の直接呼び出しに変換する（Ｓ２０３）。仮想関数呼び出し変換処理（Ｓ２０３）は図３１に示したものと同様である。図２２のプログラム１１１を仮想関数呼び出し変換処理（Ｓ２０３）によって変換した結果、得られるコードを図４３に示す。
【０２１２】
以上説明したように、本実施の形態に係るプログラム変換装置２００に、図２２に示すプログラムを入力した結果、仮想関数呼び出しを含む文「ｔｈｉｓ−＞ｇ（）；」を関数の直接呼び出しに変換することができる。このため、目的プログラム１１２実行時の実行速度の向上を図ることができる。また、プログラム変換装置２００は、必要最低限の仮想関数を複製する。このため、目的プログラム１１２のコードサイズの増加も少なくすることができる。
【０２１３】
なお、上記実施形態において、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）、仮想関数呼び出し変換判定処理（Ｓ２０１）、仮想関数定義複製処理（Ｓ２０２）、仮想関数呼び出し変換処理（Ｓ２０３）は一回のみ実行するとしているが、必要に応じて複数回繰り返すようにしても良い。
【０２１４】
また、仮想関数および仮想関数が属するクラスが、特定の条件を満たした場合に、その仮想関数定義においてｔｈｉｓポインタの型を特定することができるとしているが、クラスオブジェクトの生成処理を行なうコンストラクタや、削除処理を行なうデストラクタでは、ｔｈｉｓポインタの型はそのコンストラクタやデストラクタが属するクラスに特定可能である。このため、コンストラクタやデストラクタ中に記述されているｔｈｉｓポインタに対する仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
【０２１５】
また、プログラムの性質上や実行結果からｔｈｉｓポインタの型が明らかに特定できるような場合は、ｐｒａｇｍａ指令、オプション指定およびプログラムの実行履歴情報などを元に、仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
［実施の形態５］
本発明の実施の形態５に係るプログラム変換装置２００は、仮想関数呼び出し変換判定部２０１の行う処理が実施の形態４と異なる。仮想関数呼び出し変換判定部２０１が実行する仮想関数呼び出し判定処理（Ｓ２０１）については後述する。
【０２１６】
本実施の形態では、以下の条件（１）から条件（４）を満たす場合に、ｔｈｉｓポインタの型を特定することができるため、仮想関数Ｆ１の呼び出しを直接関数呼び出しに変換する。
【０２１７】
すなわち、
（１）  仮想関数Ｆ１が仮想関数Ｆ２の定義中に記述されている。
【０２１８】
（２）  仮想関数Ｆ１がｔｈｉｓポインタに対して呼び出されている。
（３）  仮想関数Ｆ２の属するクラスＣ１の派生クラスで、仮想関数Ｆ１が再定義されていないクラスＣ２以外のクラスのオブジェクトに対して仮想関数Ｆ２が直接呼び出されていない。
【０２１９】
（４）  クラスＣ２以外の派生クラスで再定義されていない仮想関数Ｆ２を全て複製する。
【０２２０】
図４４は、上述の４つの条件に従い、実施の形態５に係るプログラム変換装置の実行する処理の概略を説明する図である。すなわち、図４４（ａ）に示されるようなクラスの定義と、図４４（ｃ）に示されるようなプログラムが与えられた場合を考える。
【０２２１】
仮想関数ｇを仮想関数Ｆ１とし、仮想関数ｆを仮想関数Ｆ２とした場合には、図４４（ｃ）の文「ｔｈｉｓ−＞ｇ（）」は、条件（１）および条件（２）を満たす。すなわち、仮想関数Ｆ１（仮想関数ｇ）が仮想関数Ｆ２（仮想関数ｆ）の定義中に記述されているため、条件（１）を満たす。また、仮想関数Ｆ１（仮想関数ｇ）は、ｔｈｉｓポインタに対して呼び出されているため、条件（２）を満たす。
【０２２２】
また、条件（３）について考えると、プログラム中にクラスＢ以外のＡ：：ｆ（ｖｏｉｄ）の直接呼び出しが存在しない。このため、仮想関数Ｆ２（仮想関数ｆ）の属するクラスＣ１（クラスＡ）の派生クラス（クラスＢ、Ｃ、Ｄ）で、仮想関数Ｆ１（仮想関数ｇ）が再定義されていないクラスＣ２（クラスＢ、Ｄ）以外のクラス（クラスＣ）のオブジェクトに対して仮想関数Ｆ２（仮想関数ｆ）が直接呼び出されていない。このため、条件（３）を満たす。
【０２２３】
さらに、クラスＣ２（クラスＢ、Ｄ）以外の派生クラス（クラスＣ）で再定義されていない仮想関数Ｆ２（仮想関数ｆ）を全て複製する。すなわち、図４４（ｂ）に示されるように、クラスＣで仮想関数ｆを複製する。これにより、条件（４）を満たす。
【０２２４】
このため、このような場合には、図４４（ｃ）に示されるような仮想関数ｇの呼び出しを、図４４（ｄ）に示されるように、クラスＡの仮想関数ｇの直接呼び出しに変換することができる。
【０２２５】
以下では、実施の形態５のプログラム変換装置２００が実行する処理について、プログラム例を参照しながら説明していく。
【０２２６】
まず、入力部１０２は、プログラム記憶部１０１から全てのプログラム１１１を入力し（Ｓ１０２）、構文解析部１０３は、プログラムの構文木やシンボルテーブルの作成などを行なう（Ｓ１０３）。
【０２２７】
次に、クラス継承関係解析部１０４は、プログラム中に含まれるクラスおよびクラス間の継承関係を解析し、解析結果をクラスの継承関係情報１１３に記録する（Ｓ１０４）。クラス継承関係解析処理（Ｓ１０４）の処理は図４に示したものと同様である。図２２のプログラム１１１をクラス継承関係解析処理（Ｓ１０４）によって解析した結果であるクラスの継承関係情報１１３を図４５に示す。
【０２２８】
次に、仮想関数再定義解析部１０５は、基底クラスの仮想関数の再定義状態を解析し、解析結果を仮想関数再定義情報１１４に記録する（Ｓ１０５）。仮想関数再定義解析処理（Ｓ１０５）の処理は図７に示したものと同様である。図２２のプログラム１１１を仮想関数再定義解析処理（Ｓ１０５）によって解析した結果である仮想関数再定義情報１１４を図４６に示す。
【０２２９】
次に、仮想関数直接呼び出し解析部１０７は、直接呼び出しされる仮想関数を解析し、解析結果を仮想関数直接呼び出し情報１１５に記録する（Ｓ１０７）。仮想関数直接呼び出し解析処理（Ｓ１０７）は図９に示したものと同様である。図２２のプログラム１１１を仮想関数直接呼び出し解析処理（Ｓ１０７）によって解析した結果である仮想関数直接呼び出し情報１１５を図４７に示す。
【０２３０】
次に、仮想関数呼び出し変換判定部２０１が実行する仮想関数呼び出し変換判定処理（Ｓ２０１）について、当該処理を図２２に示すプログラム１１１に適用した場合を例にして、図４８を参考にしながら説明する。
【０２３１】
仮想関数呼び出し変換判定部２０１が実行する仮想関数呼び出し変換判定処理（Ｓ２０１）は、ｍ１からｍ８までのステップを含む。以下記号の順に説明していく。
【０２３２】
ステップｍ１では、仮想関数呼び出し変換判定部２０１は、プログラム１１１中の仮想関数呼び出しを含む全ての文Ｓ１について以下の処理を繰り返す。図２２では「ｔｈｉｓ−＞ｇ（）；」、「ｔｈｉｓ−＞ｈ（）；」などが対象となる。
【０２３３】
ステップｍ２では、仮想関数呼び出し変換判定部２０１は、文Ｓ１が仮想関数定義Ｆ２中に含まれるかどうかを調べる。文Ｓ１が仮想関数定義Ｆ２中に含まれる場合はステップｍ３に処理を移行し、仮想関数定義Ｆ２中に含まれない場合はステップｍ８に処理を移行する。図２２の文「ｔｈｉｓ−＞ｇ（）；」は、仮想関数「Ａ：：ｆ」中に含まれているのでステップｍ２の判定はＹｅｓとなり、ステップｍ３へと処理を移行する。同様に、文「ｔｈｉｓ−＞ｈ（）；」は、仮想関数「Ｂ：：ｇ」中に含まれているのでステップｍ２の判定はＹｅｓとなり、ステップｍ３へと処理を移行する。一方、文「ｏｂｊ＿ｃ．ｇ（）；」で、関数ｔ中に含まれ、関数ｔは仮想関数ではないので、ステップｍ２の判定はＮｏとなり、ステップｍ８へと処理を移行する。
【０２３４】
ステップｍ３では、仮想関数呼び出し変換判定部２０１は、文Ｓ１がｔｈｉｓポインタに対する呼び出しかどうかを調べる。文Ｓ１がｔｈｉｓポインタに対する呼び出しの場合はステップｍ４に処理を移行し、ｔｈｉｓポインタに対する呼び出しでない場合はステップｍ８に処理を移行する。図２２の文「ｔｈｉｓ−＞ｇ（）；」および文「ｔｈｉｓ−＞ｈ（）；」では、仮想関数ｇおよびｈの呼び出しはｔｈｉｓポインタに対して行なわれている。このためステップｍ３の判定はＹｅｓとなり、ステップｍ４へと処理を移行する。
【０２３５】
ステップｍ４では、仮想関数呼び出し変換判定部２０１は、仮想関数Ｆ２の属するクラスＣ１の全ての派生クラスのうち、Ｆ１を再定義するクラスＣ２があるかどうかを調べる。Ｆ１を再定義するクラスＣ２がある場合はステップｍ５に処理を移行し、ない場合はステップｍ６に処理を移行する。図２２では、仮想関数「Ａ：：ｆ」の属するクラスＡの派生クラスＢ、ＣおよびＤのうち仮想関数ｇを再定義するクラスは、仮想関数再定義情報１１４を参照するとクラスＢであることがわかる。従ってステップｍ４の判定はＹｅｓとなり、ステップｍ５へと処理を移行する。また、仮想関数「Ｂ：：ｇ」の属するクラスＢの派生クラスＣおよびＤのうち、仮想関数ｈを再定義するクラスはクラスＤであるので、ステップｍ４の判定はＹｅｓとなり、ステップｍ５へと処理を移行する。
【０２３６】
ステップｍ５では、仮想関数呼び出し変換判定部２０１は、クラスＣ２の全ての派生クラスＣ３のオブジェクトに対して仮想関数Ｆ２が直接呼び出しされているかどうかを調べる。直接呼び出しされている場合はステップｍ８に処理を移行し、直接呼び出しされていない場合はステップｍ６に処理を移行する。図２２のプログラム１１１では、仮想関数直接呼び出し情報１１５を参照すると、クラスＢの全ての派生クラスＣおよびＤで仮想関数「Ａ：：ｆ」が直接呼び出されていないことがわかるので、ステップｍ５の判定はＹｅｓとなりステップｍ６へと処理を移行する。また、クラスＤは派生クラスを持たないため、派生クラスに対して仮想関数「Ｂ：：ｇ」が直接呼び出されることはないため、ステップｍ５の判定はＹｅｓとなる。
【０２３７】
ステップｍ６では、仮想関数呼び出し変換判定部２０１は、文Ｓ１を直接呼び出し可能文情報１１６に追加する。図２２では、文「ｔｈｉｓ−＞ｇ（）；」および文「ｔｈｉｓ−＞ｈ（）；」を直接呼び出し可能文情報１１６に追加する。
【０２３８】
ステップｍ７では、仮想関数呼び出し変換判定部２０１は、クラスＣ２および仮想関数Ｆ２の対Ｐ１を複製仮想関数情報に追加する。図２２では、クラスＢとＡ：：ｆとの対、およびクラスＤとＢ：：ｇとの対を複製仮想関数情報に追加する。
【０２３９】
ステップｍ８では、仮想関数呼び出し変換判定部２０１は、ステップｍ１に処理を移行し、ループの処理を繰り返す。
【０２４０】
図２２のプログラムを仮想関数呼び出し変換判定処理（Ｓ２０１）によって解析した結果である直接呼び出し可能文情報１１６および複製仮想関数情報を図４９および図５０にそれぞれ示す。
【０２４１】
次に、仮想関数定義複製部２０２は、仮想関数の定義を必要に応じて複製し、クラス定義および仮想関数テーブルを変換する（Ｓ２０２）。仮想関数定義複製処理（Ｓ２０２）は図４０に示したものと同様である。図２２のプログラム１１１を仮想関数定義複製処理（Ｓ２０２）によって変換した結果であるプログラムおよび各クラスの仮想関数テーブルを図５１および図５２にそれぞれ示す。
【０２４２】
次に、仮想関数呼び出し変換部２０３は、仮想関数呼び出しを関数の直接呼び出しに変換する（Ｓ２０３）。仮想関数呼び出し変換処理（Ｓ２０３）は図３１に示したものと同様である。図２２のプログラム１１１を仮想関数呼び出し変換処理（Ｓ２０３）によって変換した結果、得られるコードを図５３に示す。
【０２４３】
以上説明したように、本実施の形態に係るプログラム変換装置２００に、図２２に示すプログラム１１１を入力した結果、仮想関数呼び出しを含む文「ｔｈｉｓ−＞ｇ（）；」および文「ｔｈｉｓ−＞ｈ（）；」を関数の直接呼び出しに変換することができる。このため、目的プログラム１１２実行時の実行速度の向上を図ることができる。また、プログラム変換装置２００は、必要最低限の仮想関数を複製するため、目的プログラム１１２のコードサイズの増加も少なくすることができる。
【０２４４】
なお、上記実施形態において、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）、仮想関数呼び出し変換判定処理（Ｓ２０１）、仮想関数定義複製処理（Ｓ２０２）、仮想関数呼び出し変換処理（Ｓ２０３）は一回のみ実行するとしているが、必要に応じて複数回繰り返すようにしても良い。
【０２４５】
また、仮想関数および仮想関数が属するクラスが、特定の条件を満たした場合に、その仮想関数定義においてｔｈｉｓポインタの型を特定することができるとしているが、クラスオブジェクトの生成処理を行なうコンストラクタや、削除処理を行なうデストラクタでは、ｔｈｉｓポインタの型はそのコンストラクタやデストラクタが属するクラスに特定可能である。このため、コンストラクタやデストラクタ中に記述されているｔｈｉｓポインタに対する仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
【０２４６】
また、プログラムの性質上や実行結果からｔｈｉｓポインタの型が明らかに特定できるような場合は、ｐｒａｇｍａ指令、オプション指定およびプログラムの実行履歴情報などを元に、仮想関数呼び出しを関数の直接呼び出しに変換することも可能である。
［実施の形態６］
実施の形態１に係るプログラム変換装置１００では、全てのプログラム１１１を順次入力し、全てのプログラム１１１に対して一度に処理を行うようにしていたが、実施の形態６に係るプログラム変換装置では、プログラムをファイルごとに入力し、ファイルごとにプログラム変換処理を行なう。
【０２４７】
図５４は、本発明の実施の形態６に係るプログラム変換装置３００の構成を示す図である。プログラム変換装置３００は、オブジェクト指向言語であるＣ＋＋言語で記述された複数のプログラムを受け、実行形式プログラムを出力する装置であり、プログラム記憶部３０１と、翻訳部３１０と、目的プログラム記憶部３０２と、結合部３２０と、実行形式プログラム記憶部３０３とを備えている。
【０２４８】
プログラム記憶部３０１は、プログラム変換装置３００における変換対象となる、オブジェクト指向言語であるＣ＋＋言語で記述された複数のプログラム１１１ａ〜１１１ｃをファイルごとに記憶する記憶装置である。
【０２４９】
翻訳部３１０は、複数のプログラム１１１ａ〜１１１ｃを複数の目的プログラム１１２ａ〜１１２ｃに翻訳する処理部であり、入力部３１２と、構文解析部３１３と、クラス継承関係解析部３１４と、仮想関数再定義解析部３１５と、仮想関数直接呼び出し解析部３１７と、出力部３１８とから構成されている。
【０２５０】
目的プログラム記憶部３０２は、プログラム記憶部３０１に格納されているプログラム１１１ａ〜１１１ｃにそれぞれ対応する目的プログラム１１２ａ〜１１２ｃを記憶する記憶装置である。
【０２５１】
結合部３２０は、目的プログラム記憶部３０２に記憶されている複数の目的プログラム１１２ａ〜１１２ｃから１つの実行形式プログラム３２４を生成する処理部であり、入力部３２１と、仮想関数呼び出し変換部３２２と、リンク部３２３とから構成されている。
【０２５２】
実行形式プログラム記憶部３０３は、結合部３２０のリンク部３２３より出力される実行形式プログラム３２４を記憶する記憶装置である。
【０２５３】
その他の処理部については、以下に説明するプログラム変換装置３００が実行する処理とあわせて説明する。
【０２５４】
図５５は、プログラム変換装置３００の実行する処理のフローチャートである。
入力部３１２は、プログラム記憶部３０１に格納されているプログラム１１１ａ〜１１１ｃのうち１つのファイル（１つのプログラム）を選択し、構文解析部３１３に渡す（Ｓ３１２）。なお、入力部３１２は、翻訳部３１０において１つのファイルに対する翻訳処理が終了するごとに、次のファイルを構文解析部３１３に渡す。
【０２５５】
構文解析部３１３は、入力部３１２から受けとったプログラムの構文を解析し、シンボルテーブルの生成や構文木の生成などを行ない、その解析結果をクラス継承関係解析部３１４に渡す（Ｓ３１３）。
【０２５６】
クラス継承関係解析部３１４は、プログラム中に含まれる全てのクラスを抽出してクラス間の継承関係を解析し、解析結果をクラスの継承関係情報１１３として解析情報記憶部３１６に格納する（Ｓ３１４）。
【０２５７】
仮想関数再定義解析部３１５は、クラスの仮想関数が基底クラスの仮想関数を再定義しているか否かを解析し、解析結果を仮想関数再定義情報１１４として解析情報記憶部３１６に格納する（Ｓ３１５）。
【０２５８】
仮想関数直接呼び出し解析部３１７は、プログラム中で直接呼び出しされている仮想関数および起動オブジェクトを解析し、解析結果を仮想関数直接呼び出し情報１１５として解析情報記憶部３１６に格納する（Ｓ３１５）。
【０２５９】
出力部３１８は、仮想関数直接呼び出し解析部３１７での変換結果および解析情報記憶部３１６に格納されている解析情報を目的プログラム記憶部３０２に目的プログラムとして格納する（Ｓ３１８）。
【０２６０】
入力部３２１は、目的プログラム記憶部３０２に記憶されている全ての目的プログラム１１２ａ〜１１２ｃを受け、仮想関数呼び出し変換部３２２に渡す（Ｓ３２１）。
【０２６１】
仮想関数呼び出し変換部３２２は、入力部３２１より受けた目的プログラム１１２ａ〜１１２ｃに含まれる解析情報に格納されたクラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５を参照し、仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、変換可能な場合に関数の直接呼び出しに変換する（Ｓ３２２）。
【０２６２】
リンク部３２３は、仮想関数呼び出し変換部３２２における変換後の全ての目的プログラムを結合することにより実行形式プログラム３２４を作成し、当該実行形式プログラム３２４を実行形式プログラム記憶部３０３に記録する（Ｓ３２３）。
【０２６３】
なお、構文解析処理（Ｓ３１３）、クラス継承関係解析処理（Ｓ３１４）、仮想関数再定義解析処理（Ｓ３１５）、仮想関数直接呼び出し解析処理（Ｓ３１７）および仮想関数呼び出し変換処理（Ｓ３２２）の処理は、それぞれ実施の形態１の構文解析処理（Ｓ１０３）、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）および仮想関数呼び出し変換処理（Ｓ１０８）と同様である。
【０２６４】
したがって、実施の形態１のプログラム変換装置１００と同様に、図５に示すプログラム１１１をプログラム変換装置３００に入力した結果、仮想関数呼び出しのコードを図１２に示すようなコードに変換することができる。このため、実行形式プログラム３２４実行時の実行速度の向上を図ることができる。
【０２６５】
なお、実施の形態２、実施の形態３、実施の形態４および実施の形態５についても実施の形態６と同様に構成することにより、各実施形態と同様の変換結果を得ることができる。
［実施の形態７］
実施の形態１に係るプログラム変換装置１００では、解析情報の収集と仮想関数呼び出しの変換とを同時に行なっていたが、解析情報の収集と仮想関数呼び出しの変換とを別々に実行することも可能である。本実施の形態に係るプログラム変換装置では、解析情報の収集と仮想関数呼び出しの変換とを別々に実行することを特徴とする。
【０２６６】
図５６は、本発明の実施の形態７に係るプログラム変換装置４００の構成を示す図である。プログラム変換装置４００は、オブジェクト指向言語であるＣ＋＋言語で記述された複数のプログラムを受け、目的プログラムを出力する装置であり、プログラム記憶部４０１と、プリコンパイル部４１０と、解析情報記憶部４０２と、プログラム変換部４２０と、生成コード記憶部４０３とを備えている。
【０２６７】
プログラム記憶部４０１は、プログラム変換装置４００における変換対象となる、オブジェクト指向言語であるＣ＋＋言語で記述された複数のプログラム１１１ａ〜１１１ｃをファイルごとに記憶する記憶装置である。
【０２６８】
プリコンパイル部４１０は、プログラム記憶部４０１に格納されている全てのプログラム１１１ａ〜１１１ｃを順次受け、各種解析情報（クラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５）を生成する処理部であり、入力部４１２と、構文解析部４１３と、クラス継承関係解析部４１４と、仮想関数再定義解析部４１５と、仮想関数直接呼び出し解析部４１６とから構成される。
【０２６９】
プログラム変換部４２０は、解析情報記憶部４０２に格納されているクラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５を参照し、プログラム１１１ａ〜１１１ｃ中の仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、変換可能な場合に関数の直接呼び出しに変換する処理部であり、入力部４２１と、構文解析部４２２と、仮想関数呼び出し変換部４２３と、出力部４２４とから構成されている。
【０２７０】
生成コード記憶部４０３は、プログラム変換部４２０より出力される目的プログラム１１２を記憶する記憶装置である。
【０２７１】
その他の処理部については、以下に説明するプログラム変換装置４００が実行する処理とあわせて説明する。
【０２７２】
図５７は、プログラム変換装置４００の実行する処理のフローチャートである。
入力部４１２は、プログラム記憶部４０１に格納されている全てのプログラム１１１ａ〜１１１ｃを順次入力し、構文解析部４１３に渡す（Ｓ４１２）。
【０２７３】
構文解析部４１３は、入力部４１２から受けとったプログラム１１１ａ〜１１１ｃの構文を解析し、シンボルテーブルの生成や構文木の生成などを行ない、その解析結果をクラス継承関係解析部４１４に渡す（Ｓ４１３）。
【０２７４】
クラス継承関係解析部４１４は、プログラム１１１ａ〜１１１ｃ中に含まれる全てのクラスを抽出してクラス間の継承関係を解析し、解析結果をクラスの継承関係情報１１３として解析情報記憶部４０２に格納する（Ｓ４１４）。
【０２７５】
仮想関数再定義解析部４１５は、クラスの仮想関数が基底クラスの仮想関数を再定義しているか否かを解析し、解析結果を仮想関数再定義情報１１４として解析情報記憶部４０２に格納する（Ｓ４１５）。
【０２７６】
仮想関数直接呼び出し解析部４１６は、プログラム１１１ａ〜１１１ｃ中で直接呼び出しされている仮想関数および起動オブジェクトを解析し、解析結果を仮想関数直接呼び出し情報１１５として解析情報記憶部４０２に格納する（Ｓ４１６）。
【０２７７】
入力部４２１は、解析情報記憶部４０２に格納されているクラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５、ならびにプログラム記憶部４０１に格納されているプログラム１１１ａ〜１１１ｃを順次入力し、構文解析部４２２に渡す（Ｓ４２１）。
【０２７８】
構文解析部４２２は、入力部４２１から受けとったプログラム１１１ａ〜１１１ｃの構文を解析し、シンボルテーブルの生成や構文木の生成などを行ない、その解析結果を仮想関数呼び出し変換部４２３に渡す（Ｓ４２２）。また、構文解析部４２２は、クラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５を仮想関数呼び出し変換部４２３に渡す。
【０２７９】
仮想関数呼び出し変換部４２３は、構文解析部４２２より受け取ったクラスの継承関係情報１１３、仮想関数再定義情報１１４および仮想関数直接呼び出し情報１１５を参照し、仮想関数呼び出しを関数の直接呼び出しに変換可能か否かを判定し、変換可能な場合に関数の直接呼び出しに変換する（Ｓ４２３）。
【０２８０】
出力部４２４は、各ステップによって変換されたプログラムを目的プログラム１１２として生成コード記憶部４０３に記録する。
【０２８１】
なお、構文解析処理（Ｓ４１３、Ｓ４２２）クラス継承関係解析処理（Ｓ４１４）、仮想関数再定義解析処理（Ｓ４１５）、仮想関数直接呼び出し解析処理（Ｓ４１６）および仮想関数呼び出し変換処理（Ｓ４２３）は、それぞれ実施の形態１の構文解析処理（Ｓ１０３）、クラス継承関係解析処理（Ｓ１０４）、仮想関数再定義解析処理（Ｓ１０５）、仮想関数直接呼び出し解析処理（Ｓ１０７）および仮想関数呼び出し変換処理（Ｓ１０８）と同様である。
【０２８２】
したがって、実施の形態１のプログラム変換装置１００と同様に、図５に示すプログラム１１１をプログラム変換装置３００に入力した結果、仮想関数呼び出しのコードを図１２に示すようなコードに変換することができる。このため、目的プログラム１１２実行時の実行速度の向上を図ることができる。
【０２８３】
なお、実施の形態２、実施の形態３、実施の形態４および実施の形態５についても実施の形態７と同様に構成することにより、各実施形態と同様の変換結果を得ることができる。
【産業上の利用可能性】
【０２８４】
本発明は、コンパイラに適用でき、特に、オブジェクト指向言語により記述されたプログラムを変換するコンパイラ等に適用できる。
【図面の簡単な説明】
【０２８５】
【図１】本発明の実施の形態１に係るプログラム変換装置の実行する処理の概略を説明する図である。
【図２】本発明の実施の形態１におけるプログラム変換装置の構成を示す図である。
【図３】本発明の実施の形態１におけるプログラム変換ステップの構成図である。
【図４】クラス継承関係解析処理（Ｓ１０４）のフローチャートである。
【図５】本発明の実施の形態１におけるプログラム記憶部１０１に格納されているプログラム例を示す図である。
【図６】本発明の実施の形態１におけるクラスの継承関係情報１１３を示す図である。
【図７】仮想関数再定義解析処理（Ｓ１０５）のフローチャートである。
【図８】本発明の実施の形態１における仮想関数再定義情報１１４を示す図である。
【図９】仮想関数直接呼び出し解析処理（Ｓ１０７）のフローチャートである。
【図１０】本発明の実施の形態１における仮想関数直接呼び出し情報１１５を示す図である。
【図１１】仮想関数呼び出し変換処理（Ｓ１０８）のフローチャートである。
【図１２】本発明の実施の形態１における仮想関数呼び出し変換ステップにおいて生成されるプログラムを示す図である。
【図１３】本発明の実施の形態２に係るプログラム変換装置の実行する処理の概略を説明する図である。
【図１４】本発明の実施の形態２におけるクラスの継承関係情報１１３を示す図である。
【図１５】本発明の実施の形態２における仮想関数再定義情報１１４を示す図である。
【図１６】本発明の実施の形態２における仮想関数直接呼び出し情報１１５を示す図である。
【図１７】本発明の実施の形態２における仮想関数呼び出し変換処理（Ｓ１０８）のフローチャートである。
【図１８】本発明の実施の形態２における仮想関数呼び出し変換処理において生成されるプログラムを示す図である。
【図１９】本発明の実施の形態３に係るプログラム変換装置の実行する処理の概略を説明する図である。
【図２０】本発明の実施の形態３におけるプログラム変換装置の構成を示す図である。
【図２１】本発明の実施の形態３におけるプログラム変換ステップの構成図である。
【図２２】本発明の実施の形態３におけるプログラム記憶部１０１に格納されているプログラム例を示す図である。
【図２３】本発明の実施の形態３におけるクラスの継承関係情報１１３を示す図である。
【図２４】本発明の実施の形態３における仮想関数再定義情報１１４を示す図である。
【図２５】本発明の実施の形態３における仮想関数直接呼び出し情報１１５を示す図である。
【図２６】仮想関数呼び出し変換判定処理（Ｓ２０１）のフローチャートである。
【図２７】本発明の実施の形態３における直接呼び出し可能文情報１１６を示す図である。
【図２８】仮想関数定義複製処理（Ｓ２０２）のフローチャートである。
【図２９】本発明の実施の形態３における仮想関数定義複製ステップにおいて生成されるクラス定義を示す図である。
【図３０】本発明の実施の形態３における仮想関数定義複製ステップにおいて生成される仮想関数テーブルを示す図である。
【図３１】仮想関数呼び出し変換処理（Ｓ２０３）のフローチャートである。
【図３２】本発明の実施の形態３における仮想関数呼び出し変換ステップにおいて生成されるプログラムを示す図である。
【図３３】本発明の実施の形態４に係るプログラム変換装置の実行する処理の概略を説明する図である。
【図３４】本発明の実施の形態４におけるクラスの継承関係情報１１３を示す図である。
【図３５】本発明の実施の形態４における仮想関数再定義情報１１４を示す図である。
【図３６】本発明の実施の形態４における仮想関数直接呼び出し情報１１５を示す図である。
【図３７】本発明の実施の形態４における仮想関数呼び出し変換判定処理（Ｓ２０１）のフローチャートである。
【図３８】本発明の実施の形態４における直接呼び出し可能文情報１１６を示す図である。
【図３９】本発明の実施の形態４における複製仮想関数情報を示す図である。
【図４０】本発明の実施の形態４における仮想関数定義複製処理（Ｓ２０２）を示すフローチャートである。
【図４１】本発明の実施の形態４における仮想関数定義複製処理において生成されるクラス定義を示す図である。
【図４２】本発明の実施の形態４における仮想関数定義複製処理において生成される仮想関数テーブルを示す図である。
【図４３】本発明の実施の形態４における仮想関数呼び出し変換処理において生成されるプログラムを示す図である。
【図４４】本発明の実施の形態５に係るプログラム変換装置の実行する処理の概略を説明する図である。
【図４５】本発明の実施の形態５におけるクラスの継承関係情報１１３を示す図である。
【図４６】本発明の実施の形態５における仮想関数再定義情報１１４を示す図である。
【図４７】本発明の実施の形態５における仮想関数直接呼び出し情報１１５を示す図である。
【図４８】本発明の実施の形態５における仮想関数呼び出し変換判定処理（Ｓ２０１）のフローチャートである。
【図４９】本発明の実施の形態５における直接呼び出し可能文記憶情報１１６を示す図である。
【図５０】本発明の実施の形態５における複製仮想関数情報に格納されている情報を示す図である。
【図５１】本発明の実施の形態５における仮想関数定義複製ステップにおいて生成されるクラス定義を示す図である。
【図５２】本発明の実施の形態５における仮想関数定義複製ステップにおいて生成される仮想関数テーブルを示す図である。
【図５３】本発明の実施の形態５における仮想関数呼び出し変換ステップにおいて生成されるプログラムを示す図である。
【図５４】本発明の実施の形態６におけるプログラム変換装置の構成を示すブロック図である。
【図５５】本発明の実施の形態６におけるプログラム変換装置の実行する処理のフローチャートである。
【図５６】本発明の実施の形態７におけるプログラム変換装置の構成を示すブロック図である。
【図５７】本発明の実施の形態７におけるプログラム変換装置の実行する処理のフローチャートである。
【図５８】仮想関数呼び出しを含むプログラム例を示す図である。
【図５９】仮想関数呼び出し機構の実装例を示す図である。
【図６０】仮想関数呼び出しに対応するアセンブラコードを示す図である。
【図６１】関数の直接呼び出しに対応するアセンブラコードを示す図である。
【図６２】従来技術を説明するための仮想関数呼び出しを含むプログラム例を示す図である。
【図６３】特許文献１による変換結果を示す図である。
【図６４】特許文献２による変換結果を示す図である。
【図６５】従来技術における課題を示す図である。
【符号の説明】
【０２８６】
１００，２００，３００，４００          プログラム変換装置
１０１，３０１                          プログラム記憶部
１０２，３１２，３２１，４１２，４２１  入力部
１０３，３１３，４１３，４２２          構文解析部
１０４，３１４，４１４                  クラス継承関係解析部
１０５，３１５，４１５                  仮想関数再定義解析部
１０６，２０６，３１６，４０２          解析情報記憶部
１０７，３１７，４１６                  仮想関数直接呼び出し解析部
１０８，２０３，３２２，４２３          仮想関数呼び出し変換部
１０９，３１８，４２４                  出力部
１１０，４０３                          生成コード記憶部
１１１，１１１ａ〜１１１ｃ              プログラム
１１２，１１２ａ〜１１２ｃ              目的プログラム
１１３                                  クラスの継承関係情報
１１４                                  仮想関数再定義情報
１１５                                  仮想関数直接呼び出し情報
１１６                                  直接呼び出し可能文情報
２０１                                  仮想関数呼び出し変換判定部
２０２                                  仮想関数定義複製部
３０２                                  目的プログラム記憶部
３０３                                  実行形式プログラム記憶部
３１０                                  翻訳部
３２０                                  結合部
３２３                                  リンク部
３２４                                  実行形式プログラム
４１０                                  プリコンパイル部
４２０                                  プログラム変換部
【図１】
2006146613.tif 000003
【図２】
2006146613.tif 000004
【図３】
2006146613.tif 000005
【図４】
2006146613.tif 000006
【図５】
2006146613.tif 000007
【図６】
2006146613.tif 000008
【図７】
2006146613.tif 000009
【図８】
2006146613.tif 000010
【図９】
2006146613.tif 000011
【図１０】
2006146613.tif 000012
【図１１】
2006146613.tif 000013
【図１２】
2006146613.tif 000014
【図１３】
2006146613.tif 000015
【図１４】
2006146613.tif 000016
【図１５】
2006146613.tif 000017
【図１６】
2006146613.tif 000018
【図１７】
2006146613.tif 000019
【図１８】
2006146613.tif 000020
【図１９】
2006146613.tif 000021
【図２０】
2006146613.tif 000022
【図２１】
2006146613.tif 000023
【図２２】
2006146613.tif 000024
【図２３】
2006146613.tif 000025
【図２４】
2006146613.tif 000026
【図２５】
2006146613.tif 000027
【図２６】
2006146613.tif 000028
【図２７】
2006146613.tif 000029
【図２８】
2006146613.tif 000030
【図２９】
2006146613.tif 000031
【図３０】
2006146613.tif 000032
【図３１】
2006146613.tif 000033
【図３２】
2006146613.tif 000034
【図３３】
2006146613.tif 000035
【図３４】
2006146613.tif 000036
【図３５】
2006146613.tif 000037
【図３６】
2006146613.tif 000038
【図３７】
2006146613.tif 000039
【図３８】
2006146613.tif 000040
【図３９】
2006146613.tif 000041
【図４０】
2006146613.tif 000042
【図４１】
2006146613.tif 000043
【図４２】
2006146613.tif 000044
【図４３】
2006146613.tif 000045
【図４４】
2006146613.tif 000046
【図４５】
2006146613.tif 000047
【図４６】
2006146613.tif 000048
【図４７】
2006146613.tif 000049
【図４８】
2006146613.tif 000050
【図４９】
2006146613.tif 000051
【図５０】
2006146613.tif 000052
【図５１】
2006146613.tif 000053
【図５２】
2006146613.tif 000054
【図５３】
2006146613.tif 000055
【図５４】
2006146613.tif 000056
【図５５】
2006146613.tif 000057
【図５６】
2006146613.tif 000058
【図５７】
2006146613.tif 000059
【図５８】
2006146613.tif 000060
【図５９】
2006146613.tif 000061
【図６０】
2006146613.tif 000062
【図６１】
2006146613.tif 000063
【図６２】
2006146613.tif 000064
【図６３】
2006146613.tif 000065
【図６４】
2006146613.tif 000066
【図６５】
2006146613.tif 000067