(57)【要約】      （修正有）【課題】グローバル変数をローカル変数に変換する処理をソースコードに対して行うことにより、プログラムの保守性を高め、メモリ参照命令数を削減する。【解決手段】ソースコードから抽出された変換対象領域内に関数呼び出し元がある場合に、呼び出し先関数内で選択されたグローバル変数が使用されているか否かを判定し、使用されている場合には、関数呼び出し元に、当該グローバル変数の代替変数を宣言し、当該グローバル変数を使用するソースコード内の呼び出し先関数の全てに対して、前記代替変数を当該グローバル変数に対応する引数として追加するとともに、呼び出し先関数内における当該グローバル変数の使用を追加した引数の使用に置き換えた新たな関数を作成し、展開されたソースコード内の関数呼び出し元を新たな関数を呼び出せるように修正し、この処理が終了したら、当該グローバル変数を展開されたソースコードから削除する。【選択図】図３
2009048259.tif 000002
【特許請求の範囲】
【請求項１】
グローバル変数を用いているプログラムのソースコードを計算機システムの主記憶装置に展開するソースコード展開ステップと、
前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定する未処理グローバル変数判定ステップと、
前記展開されたソースコード内に前記未処理のグローバル変数が存在する場合、前記展開されたソースコードから変換対象領域を抽出する変換対象領域抽出ステップと、
前記未処理のグローバル変数を１つ選択する未処理グローバル変数選択ステップと、
前記抽出された変換対象領域内に未処理の関数呼び出し元がある場合、呼び出し先関数内で前記選択された未処理のグローバル変数が使用されているか否かを判定する未処理文探索ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されている場合、前記関数呼び出し元に前記選択された未処理のグローバル変数の代替変数を宣言する代替変数宣言ステップと、
前記選択された未処理のグローバル変数を使用する前記展開されたソースコード内の前記呼び出し先関数の全てに対して、前記代替変数を前記選択された未処理のグローバル変数に対応する引数として追加するとともに、前記呼び出し先関数内における前記選択された未処理のグローバル変数の使用を前記追加した引数の使用に置き換えた新たな関数を作成する引数追加・新関数作成ステップと、
前記展開されたソースコード内の前記関数呼び出し元を前記新たな関数を呼び出せるように修正する呼び出し元修正ステップと、
前記選択された未処理のグローバル変数を前記展開されたソースコードから削除する未処理グローバル変数削除ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されていない場合、又は、前記選択された未処理のグローバル変数の削除が終了した場合、前記選択された未処理のグローバル変数を処理済みとする未処理グローバル変数処理済み化ステップと、
前記未処理グローバル変数選択ステップ、前記未処理文探索ステップ、前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ、前記未処理グローバル変数削除ステップ及び前記未処理グローバル変数処理済み化ステップを、前記未処理のグローバル変数が存在する間、繰り返し実行することを指示する繰り返し実行指示ステップと、
前記未処理のグローバル変数が存在しなくなったとき、前記展開されたソースコードを前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ及び前記未処理グローバル変数削除ステップによって修正したソースコードを、変換後ソースコードとして前記主記憶装置から前記計算機システムの外部記憶装置に格納する変換後ソースコード格納ステップと、
を含むことを特徴とするプログラム変換方法。
【請求項２】
前記未処理グローバル変数判定ステップは、前記展開されたソースコード内から未処理のグローバル変数を探索して未処理グローバル変数リストを作成する未処理グローバル変数リスト作成ステップと、前記作成された未処理グローバル変数リストを主記憶装置上に保持させる未処理グローバル変数リスト保持ステップと、を含み、前記保持された未処理グローバル変数リストに基づいて、前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定し、前記未処理グローバル変数処理済み化ステップは、前記未処理グローバル変数リストに対して前記処理済みの処理を行うことを特徴とする請求項１に記載のプログラム変換方法。
【請求項３】
請求項１または２記載のプログラム変換方法の各ステップをコンピュータに実行させることを特徴とする変換用プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、計算機の利用技術、特に、プログラムのソースコードを修正されたソースコードに変換するプログラム変換方法及び変換用プログラムに関する。
【背景技術】
【０００２】
大部分のプログラミング言語においては、特定の型のデータを収容する単位として、名前によって識別され、それに値を与えることができる変数という概念がサポートされているが、この変数は、大別して、グローバル変数とローカル変数の２種類に分けられる。
【０００３】
グローバル変数は、プログラム処理の中のすべてのモジュールで値が有効な変数であって、使用される関数の外で宣言されるものであるが、このようなグローバル変数がプログラムのソースコード内で多用されている場合には、プログラムのソースコードを広い範囲に渡ってチェックしなければグローバル変数の正当性を確認することができないので、プログラムのソースコードの保守のし易さに問題がある。
【０００４】
また、グローバル変数は、使用される関数の外で定義されるので、値が定義されていれば、関数を呼び出す前にメモリへのストアが必要となるが、呼び出し先関数が条件付き関数の場合には、条件判定の結果、グローバル変数を参照する必要のないことがあるので、呼び出し先関数を呼び出す前のメモリ・ストアは、冗長なメモリ参照となる可能性がある。
【０００５】
従来、関数の呼び出し関係を解析し、グローバル変数を用いて値を渡している部分をローカル変数とし、関数の引数として追加するものがある（特許文献１）。また、プログラム内のグローバル変数の分布とプログラム・モジュール間の呼び出し関係とに基づいてグローバル変数の散らばり具合を表す評価値を求めるものもある（特許文献２）。
【特許文献１】特開２００２−９９４２５号公報
【特許文献２】特開平６−２６６５５０号公報
【発明の開示】
【発明が解決しようとする課題】
【０００６】
しかしながら、特許文献１に記載されたものは、コンパイラの処理途中の中間コードに対して変換を行うものであって、プログラムのソースコードの保守性につながるものではない。また、特許文献２に記載されたものは、求めた評価値をプログラムの保守担当者の割り当て時やプログラム再設計時などの基礎データとするというものであって、グローバル変数の存在がプログラムのソースコードの保守性に大きな影響があることを示唆してはいるが、プログラムのソースコードの保守性を高めるものではない。
【０００７】
本発明は、このような従来の技術の問題点に鑑みてなされたものであり、グローバル変数をローカル変数に変換する処理をプログラムのソースコードに対して行うことにより、プログラムのソースコードの保守性を高めることができると共に、実行されるメモリ参照命令数を削減することができるプログラム変換方法及び変換用プログラムを提供することを目的とする。
【課題を解決するための手段】
【０００８】
上記課題を解決するために、本発明のプログラム変換方法は、
グローバル変数を用いているプログラムのソースコードを計算機システムの主記憶装置に展開するソースコード展開ステップと、
前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定する未処理グローバル変数判定ステップと、
前記展開されたソースコード内に前記未処理のグローバル変数が存在する場合、前記展開されたソースコードから変換対象領域を抽出する変換対象領域抽出ステップと、
前記未処理のグローバル変数を１つ選択する未処理グローバル変数選択ステップと、
前記抽出された変換対象領域内に未処理の関数呼び出し元がある場合、呼び出し先関数内で前記選択された未処理のグローバル変数が使用されているか否かを判定する未処理文探索ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されている場合、前記関数呼び出し元に前記選択された未処理のグローバル変数の代替変数を宣言する代替変数宣言ステップと、
前記選択された未処理のグローバル変数を使用する前記展開されたソースコード内の前記呼び出し先関数の全てに対して、前記代替変数を前記選択された未処理のグローバル変数に対応する引数として追加するとともに、前記呼び出し先関数内における前記選択された未処理のグローバル変数の使用を前記追加した引数の使用に置き換えた新たな関数を作成する引数追加・新関数作成ステップと、
前記展開されたソースコード内の前記関数呼び出し元を前記新たな関数を呼び出せるように修正する呼び出し元修正ステップと、
前記選択された未処理のグローバル変数を前記展開されたソースコードから削除する未処理グローバル変数削除ステップと、
前記呼び出し先関数内で前記選択された未処理のグローバル変数が使用されていない場合、又は、前記選択された未処理のグローバル変数の削除が終了した場合、前記選択された未処理のグローバル変数を処理済みとする未処理グローバル変数処理済み化ステップと、
前記未処理グローバル変数選択ステップ、前記未処理文探索ステップ、前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ、前記未処理グローバル変数削除ステップ及び前記未処理グローバル変数処理済み化ステップを、前記未処理のグローバル変数が存在する間、繰り返し実行することを指示する繰り返し実行指示ステップと、
前記未処理のグローバル変数が存在しなくなったとき、前記展開されたソースコードを前記代替変数宣言ステップ、前記引数追加・新関数作成ステップ、前記呼び出し元修正ステップ及び前記未処理グローバル変数削除ステップによって修正したソースコードを、変換後ソースコードとして前記主記憶装置から前記計算機システムの外部記憶装置に格納する変換後ソースコード格納ステップと、を含むことを特徴とする。
【０００９】
上記構成によれば、プログラムのソースコードからグローバル変数を取り除くことができることから、その独立性が高くなり、保守性を高めることができる。また、このことから、プログラムのソースコードの流用性が向上し、プログラムの生産効率を上げることが期待できる。さらに、本発明のプログラム変換方法によって変換されたプログラムのソースコードをコンパイルすると、冗長なメモリ参照の少ないオブジェクト・プログラムができ上がる。
【００１０】
また、前記未処理グローバル変数判定ステップは、前記展開されたソースコード内から未処理のグローバル変数を探索して未処理グローバル変数リストを作成する未処理グローバル変数リスト作成ステップと、前記作成された未処理グローバル変数リストを主記憶装置上に保持させる未処理グローバル変数リスト保持ステップと、を含み、前記保持された未処理グローバル変数リストに基づいて、前記展開されたソースコード内に未処理のグローバル変数が存在するか否かを判定し、前記未処理グローバル変数処理済み化ステップは、前記未処理グローバル変数リストに対して前記処理済みの処理を行うことを特徴とする。
【００１１】
また、上記構成によれば、最初に、展開されたソースコード内から未処理のグローバル変数を探索して未処理グローバル変数リストを作成し、以後の未処理のグローバル変数の探索処理や処理の終了したグローバル変数の処理済み化をこの未処理グローバル変数リストに基づいて行うため、未処理のグローバル変数の探索処理を短時間で済ませることができる。
【００１２】
また、本発明の変換用プログラムは、上記プログラム変換方法の各ステップをコンピュータに実行させることができる。
【００１３】
上記構成によれば、本発明の変換用プログラムをコンピュータにインストールすることによって、このコンピュータを、プログラムのソースコードを修正されたソースコードに変換するプログラム変換方法を実現するものとして構築することができる。
【発明を実施するための最良の形態】
【００１４】
以下図面を用いて本発明の実施形態を説明する。
【００１５】
＜計算機システム＞
図１は、本発明のプログラム変換方法を実施するための計算機システムの模式図であり、ＣＰＵ１、キーボード２、ディスプレイ３、プリンタ４、主記憶装置５及び外部記憶装置６は、計算機システムの内部バス７によって相互接続されている。
【００１６】
主記憶装置５には、展開されたソースコード５１、抽出された変換対象領域情報５１’、修正されたソースコード５２、プログラム変換の過程で用いる未処理グローバル変数リスト５３及び変換用プログラム５４が記憶され、外部記憶装置６には、変換前ソースコード６１及び変換後ソースコード６２が格納される。これら各種のソースコード及びリストの詳細については後述する。
【００１７】
＜変換概念＞
図２は、本発明のプログラム変換方法の処理概念図であり、外部記憶装置６に格納された変換前ソースコード６１を主記憶装置５にソースコード５１として展開し（ステップＳ２１）、この展開されたソースコード５１から変換対象領域を抽出し（ステップＳ２２）、抽出した変換対象領域内のソースコード５２の未処理文のそれぞれについて、必要な文の修正を行い（ステップＳ２３）、全ての未処理文についての処理が終了すると（ステップＳ２４：ＹＥＳ）、修正されたソースコード５２を変換後ソースコード６２として外部記憶装置５に格納する（ステップＳ２５）。
【００１８】
［変換手順］
次に、本発明のプログラム変換方法について、図３の処理フローを用いて詳細に説明する。
【００１９】
変換前ソースコード６１を外部記憶装置６から読み出し、主記憶装置５の作業エリア上にソースコード５１として展開し（ステップＳ３１）、次いで、この展開されたソースコード５１の中からグローバル変数を探索し、このグローバル変数を列挙した未処理グローバル変数リスト５３を作成する（ステップＳ３２）。この未処理グローバル変数リスト５３は、主記憶装置５の作業エリア上に保持される。
【００２０】
図４に、未処理グローバル変数リスト５３の一例を示す。この例は、グローバル変数名と処理フラグからなるもので、未処理のグローバル変数については未処理であることを示す“○”フラグを立て、処理の終了したグローバル変数については処理済みであることを示す“×”フラグを立てる例であるが、未処理のグローバル変数名のみのリストとし、処理が済んだグローバル変数については、その変数名を未処理グローバル変数リストから消去するものであってもよい。
【００２１】
次いで、保持された未処理グローバル変数リスト５３に基づいて、展開されたソースコード５１の中に未処理のグローバル変数が存在するか否かを判定し（ステップＳ３３）、未処理のグローバル変数がないと判定された場合（ステップＳ３３：ＮＯ）には、展開されたソースコード５１の修正が全て終了したと判断し、修正されたソースコード５２を変換後ソースコード６２として外部記憶装置６に格納する（ステップＳ４２）。この場合、変換後ソースコードのファイル名は、変換前ソースコードのファイル名と異なる方が好ましい。修正されたソースコード５２を変換後ソースコード６２として外部記憶装置６に格納した後、処理を終了する。
【００２２】
未処理のグローバル変数があると判定された場合（ステップＳ３３：ＹＥＳ）には、展開されたソースコード５１の中から変換の対象とする領域を抽出する（ステップＳ３４）。この抽出は、展開されたソースコードの中から変換の対象となるものだけを選択するために行われるものである。抽出された変換対象領域の情報も、主記憶装置５の作業エリア上に保持される。この抽出作業は、典型的には、関数の呼び出し関係をグラフ化したコールグラフを作成し、主記憶装置５の作業エリア上に保持する作業であるが、コールグラフの詳細については後述する。
【００２３】
展開されたソースコード５１の中から変換の対象とする領域を抽出した後、保持された未処理グローバル変数リスト５３から未処理のグローバル変数を１つ取り出し（ステップＳ３５）、抽出された変換対象領域情報５２’の中にある未処理の関数呼び出しについて、呼び出し先関数が未処理グローバル変数リスト５３から取り出された未処理のグローバル変数を使用するものであるか否かを判定する（ステップＳ３６）。
【００２４】
呼び出し先関数のいずれもが取り出された未処理のグローバル変数を使用するものではないと判定された場合（ステップＳ３６：ＮＯ）には、取り出された未処理のグローバル変数についての処理が終了したと判断し、保持された未処理グローバル変数リスト５３において、取り出された未処理のグローバル変数を処理済みとする（ステップＳ３７）。この処理の後は、保持された未処理グローバル変数リスト５３に基づいて、展開されたソースコード５１の中に更なる未処理のグローバル変数が存在するか否かの判定を行う処理（ステップＳ３３）に戻る。
【００２５】
呼び出し先関数が未処理のグローバル変数を使用するものであると判定された場合（ステップＳ３６：ＹＥＳ）には、展開されたソースコード５１の中にある関数呼び出し元に、取り出された未処理のグローバル変数をローカル変数に代替する宣言文を挿入する（ステップＳ３８）。その具体例は、例えば、“Gl”をグローバル変数名とし、“lo”をローカル変数名とすると、“lo=Gl”というものになる。
【００２６】
この宣言文の挿入の後、取り出された未処理のグローバル変数を使用する展開されたソースコード５１の中にある全ての呼び出し先関数に対して、代替変数であるローカル変数を、取り出された未処理のグローバル変数に対応する引数として追加するとともに、呼び出し先関数内におけるグローバル変数の使用を追加した引数の使用に置き換えた新たな関数を作成する（ステップＳ３９）。その具体例は、例えば、次のものである。
【００２７】
修正前の呼び出し先関数とその関数内でのグローバル変数の使用が、例えば、
int kingaku(int x)
{
int tanka;
if (x > Gl
tanka = Gl;
else
tanka = x;
return tanka;
}
とすると、新たな関数は、
int kingaku(int x, lo)
{
int tanka;
if (x > lo
tanka = lo;
else
tanka = x;
return tanka;
}
となる。
【００２８】
新たな関数の作成が終了すると、関数呼び出し元のソースコードを、作成された新たな関数を呼び出せるように修正する（ステップＳ４０）。その具体例は、先の例の関数を呼び出すとして、呼び出し元の旧文が、例えば、“soukei = soukei + kingaku(a(i))”であったとすると、“soukei = soukei + kingaku(a(i), lo)”という文に修正するというものである。
【００２９】
関数呼び出し元の修正が終了した後は、展開されたソースコード５１の中にある取り出された未処理のグローバル変数を削除する（ステップＳ４１）。
【００３０】
これらの処理が終了すると、保持された未処理グローバル変数リスト５３において、取り出された未処理のグローバル変数を処理済みとし（ステップＳ３７）、続いて、保持された未処理グローバル変数リスト５３に基づいて、展開されたソースコード５１の中に未処理のグローバル変数が存在するか否かを判定する処理（ステップＳ３３）に戻る。
【００３１】
［実現手段］
次に、本発明のプログラム変換方法を実現するための機能手段とこれら機能手段間の制御の流れ及び処理されるデータとの関係について、図５の模式図を用いて説明する。なお、図中、太線は、データ関係を示し、点線は、制御順序を示す。
【００３２】
変換前ソースコード展開手段ｍ１は、図３のステップＳ３１を実行するための手段であり、この手段ｍ１によって、外部記憶装置５に格納された変換前ソースコード６１が読み出され、主記憶装置５の作業エリア上に展開される。手段ｍ１による処理が終了すると、未処理グローバル変数リスト作成手段ｍ２が動作を開始する。
【００３３】
未処理グローバル変数リスト作成手段ｍ２は、図３のステップＳ３２を実行するための手段であり、この手段ｍ２によって、主記憶装置５の作業エリア上に展開されたソースコード５１の中からグローバル変数が探し出され、未処理グローバル変数リスト５３が作成される。この未処理グローバル変数リスト５３は、主記憶装置５の作業エリア上に保持される。手段ｍ２による処理が終了すると、未処理グローバル変数有無判定手段ｍ３が動作を開始する。
【００３４】
未処理グローバル変数有無判定手段ｍ３は、図３のステップＳ３３を実行するための手段であり、この手段ｍ３によって、保持された未処理グローバル変数リスト５３に未処理のグローバル変数が存在するか否かが判定される。手段ｍ３による処理が終了すると、変換対象領域抽出手段ｍ４又は変換後ソースコード格納手段ｍ１２のいずれかが動作を開始する。
【００３５】
変換対象領域抽出手段ｍ４は、図３のステップＳ３４を実行するための手段であり、この手段ｍ４によって、主記憶装置５の作業エリア上に展開されたソースコード５１から変換の対象となる情報を取り出す。手段ｍ４による処理が終了すると、未処理グローバル変数取り出し手段ｍ５が動作を開始する。
【００３６】
未処理グローバル変数取り出し手段ｍ５は、図３のステップＳ３５を実行するための手段であり、未処理グローバル変数有無判定手段ｍ４が保持された未処理グローバル変数リスト５３に未処理のグローバル変数が存在すると判定した場合に動作を開始する。この手段ｍ５によって、保持された未処理グローバル変数リストから未処理グローバル変数が順に１つ取り出される。手段ｍ５による処理が終了すると、未処理グローバル変数使用関数の組み探索手段ｍ６が動作を開始する。
【００３７】
変換後ソースコード格納手段ｍ１２は、図３のステップＳ４２を実行するための手段であり、未処理グローバル変数有無判定手段ｍ４が保持された未処理グローバル変数リスト５３に未処理のグローバル変数がないと判定した場合に動作を開始する。保持された未処理グローバル変数リスト５３に未処理のグローバル変数がないということは、展開されたソースコード５１の修正が全て終了したことを意味する。この手段ｍ１２によって、修正されたソースコード５２が変換後ソースコード６２として外部記憶装置６に格納される。手段ｍ１２による処理が終了すると、プログラム変換処理が終了する。
【００３８】
未処理グローバル変数使用関数の組み探索手段ｍ６は、図３のステップＳ３６を実行するための手段であり、この手段ｍ６によって、抽出された変換対象領域情報５２’の中にある未処理の関数呼び出しについて、呼び出し先関数が未処理グローバル変数リスト５３から取り出された未処理のグローバル変数を使用するものであるか否かが判定される。手段ｍ６による処理が終了すると、未処理グローバル変数の代替変数宣言手段ｍ７又は未処理グローバル変数処理済み化手段ｍ１１のいずれかが動作を開始する。
【００３９】
未処理グローバル変数の代替変数宣言手段ｍ７は、図３のステップＳ３８を実行するための手段であり、この手段ｍ７によって、展開されたソースコード５１の中にある関数呼び出し元に、取り出された未処理のグローバル変数をローカル変数に代替する宣言文が挿入される。手段ｍ７による処理が終了すると、引数追加・新関数作成手段ｍ８が動作を開始する。
【００４０】
引数追加・新関数作成手段ｍ８は、図３のステップＳ３９を実行するためのものであり、この手段ｍ８によって、取り出された未処理のグローバル変数を使用する展開されたソースコード５１の中にある全ての呼び出し先関数に対して、代替変数であるローカル変数を、取り出された未処理のグローバル変数に対応する引数として追加されるとともに、呼び出し先関数内におけるグローバル変数の使用を追加した引数の使用に置き換えた新たな関数が作成される。手段ｍ８による処理が終了すると、関数読み出し元修正手段ｍ９が動作を開始する。
【００４１】
関数読み出し元修正手段ｍ９は、図３のステップＳ４０を実行するための手段であり、この手段ｍ９によって、関数呼び出し元のソースコードが、作成された新たな関数を呼び出せるように修正される。手段ｍ９による処理が終了すると、未処理グローバル変数削除手段ｍ１０が動作を開始する。
【００４２】
未処理グローバル変数削除手段ｍ１０は、図３のステップＳ４１を実行するための手段であり、この手段ｍ１０によって、処理対象として取り出された未処理のグローバル変数が展開されたソースコード５１から削除される。手段m1０による処理が終了すると、未処理グローバル変数処理済み化手段ｍ１１が動作を開始する。
【００４３】
未処理グローバル変数処理済み化手段ｍ１１は、図３のステップＳ３７を実行するためのものであり、この手段ｍ１１によって、処理対象として取り出された未処理のグローバル変数が保持された未処理グローバル変数リスト５３において処理済みとされる。手段ｍ１１による処理が終了すると、未処理グローバル変数有無判定手段ｍ３が再び動作を開始する。
【００４４】
なお、上で説明した機能手段の全てが、変換用プログラムがコンピュータに読み込まれ、実行されることにより実現される機能実現手段であることはいうまでもない。
【００４５】
［参考例］
以上で、本発明のプログラム変換方法についての説明を終了するが、本発明のプログラム変換方法をソースコードがＣ言語で書かれたプログラムの変換に適用した場合の参考例について、図６〜図９を用いて説明する。
【００４６】
図６は、本発明のプログラム変換方法をソースコードがＣ言語で書かれたプログラムの変換に適用した場合の参考例のメイン処理フロー図である。
【００４７】
最初に、主記憶装置５に展開されたソースコード５１を解析して、このソースコード５１に存在するグローバル変数の列挙を行い、未処理グローバル変数リスト５３を作成する（ステップＳ６１）。この未処理グローバル変数リスト５３は、主記憶装置５の作業エリア上に保持される。これらの処理は、図３のステップＳ３１〜Ｓ３２に対応する処理である。未処理グローバル変数リストのフォームは、図４に示したものでよい。
【００４８】
続いて、保持された未処理グローバル変数リスト５３に基づいて、未処理のグローバル変数が存在するか否かを判定し（ステップＳ６２）、未処理のグローバル変数が存在しないと判定された場合（ステップＳ６２：存在しない）には、展開されたソースコード５１の修正が全て終了したと判断し、修正されたソースコード５２を変換後ソースコード６２として外部記憶装置６に格納し、処理を終了する。この処理は、図３のステップＳ３３：ＮＯ、ステップＳ４１に対応する処理である。
【００４９】
未処理のグローバル変数が存在すると判定された場合（ステップＳ６２：存在する）には、展開されたソースコードを解析し、関数の呼び出し関係をグラフ化したコールグラフを作成する（ステップＳ６３）。このコールグラフは、未処理グローバル変数リスト５３と同様に、主記憶装置５の作業エリア上に保持される。この処理は、図３のステップＳ３４に対応する処理である。コールグラフは、図８の『変換前のソースコードのコールグラフ』に示されるように、関数呼び出し元“int main(int arge, char *argv[]”と呼び出し先関数“void CountOne(void)”、“void CountN(int nAdd)”及び“void Print(int nNum)”との呼び出し関係を示すものである。コールグラフの概念自体は既知のものなので、ここでは、詳しく説明をしない。
【００５０】
コールグラフを作成・保持した後、保持された未処理グローバル変数リスト５３から未処理のグローバル変数を１つ取り出し（ステップＳ６４）、取り出された未処理のグローバル変数を使用している関数を含む最小の部分コールグラフを、保持されたコールグラフに基づいて作成する（ステップＳ６５）。この最小の部分コールグラフも、コールグラフと同様に、主記憶装置５の作業エリア上に保持される。これらの処理は、図３のステップＳ３５〜Ｓ３６に対応する処理である。最小の部分コールグラフは、図８の『変換前のソースコードの該グローバル変数を含む最小部分コールグラフ』に示されるように、関数呼び出し元“int main(int arge, char *argv[]”と取り出された未処理のグローバル変数の使用を含む呼び出し先関数“void CountOne(void)”及び“void CountN(int nAdd)”との呼び出し関係を示すものである。
【００５１】
最小の部分コールグラフを作成・保持した後、この最小の部分コールグラフの根の数を調べる（ステップＳ６６）。これは、取り出された未処理のグローバル変数の使用を含む呼び出し先関数が複数の関数呼び出し元から呼び出されることがあるので、その呼び出し元の数を調べるためである。その後の処理は、最小の部分コールグラフの根が１つか２つ以上で若干異なる。
【００５２】
最小の部分コールグラフの根の数が１つの場合には、最小の部分コールグラフの根の関数、つまり、関数呼び出し元において、取り出された未処理のグローバル変数の代替変数を宣言する（ステップＳ６７）。この代替変数の宣言によって、関数呼び出し元において、取り出された未処理のグローバル変数が呼び出し先関数に追加される引数であるローカル変数に置き換えられる。この処理は、図３のステップＳ３８に対応する処理である。この具体例は、図９に(1)と示されるものである。この例では、ローカル変数“int cnv_g_nCount”に“0”が代入されている。この処理の後、ステップＳ７２に移る。
【００５３】
最小の部分コールグラフの根の数が２つ以上の場合には、最小の部分コールグラフの根、つまり、関数呼び出し元がクラス間をまたがるものであるか否かが判定される（ステップＳ６８）。またがらない場合（ステップＳ６８：またがらない）については図７に示されるとおりであり、後述する。
【００５４】
最小の部分コールグラフの根、つまり、関数呼び出し元がクラス間をまたがるものである場合（ステップＳ６８：またがる）には、クラスを１つ選択し、そのクラスについて、取り出された未処理のグローバル変数に対応するメンバ変数を宣言する（ステップＳ６９）。メンバ変数とは、オブジェクトの状態を表す属性を保持するためのフィールドであって、クラスの中、且つメソッドの外側に記述されるものである。メンバ変数は、当該クラス内の任意のメソッドから参照可能であるだけなく、他のクラスから生成されたオブジェクトからもアクセスが可能なものである。
【００５５】
選択されたクラス内の未処理のグローバル変数の使用を静的メンバ変数に置き換え、この静的メンバ変数を参照できる静的メンバ関数を追加する（ステップＳ７０）。静的メンバ変数とは、修飾子“static”が指定されているメンバ変数のことを意味し、インスタンス毎に確保される変数となるので、インスタンス変数とも呼ばれるものである。また、静的メンバ関数とは、クラスをスコープとするグローバル関数のような存在であって、全てのオブジェクトに共有される関数なので、オブジェクトが無くても、クラス名を指定すればアクセスすることができるものである。
【００５６】
ステップＳ７０の置き換え・関数追加の後、最小の部分コールグラフの未修整の根、つまり、関数呼び出し元について、取り出された未処理のグローバル変数の代替変数を宣言し、先に説明した静的メンバ変数を参照できるようにする（ステップＳ７１）。代替変数の宣言については、ステップＳ６７で説明したとおりである。
【００５７】
関数呼び出し元において、取り出された未処理のグローバル変数の代替変数を宣言した後、最小の部分コールグラフの根以外の未修整の関数、つまり、呼び出し先関数の全てに対して、取り出された未処理のグローバル変数に対応する引数を追加するとともに、その関数内における取り出された未処理のグローバル変数の使用を先に説明した引数、つまり、ローカル変数の使用に置き換えた新たな関数を作成する（ステップＳ７２）。この処理は、図３のＳ３９に対応する処理である。この具体例は、図９に（２）及び（３）と示されるものである。この例は、旧呼び出し先関数
void CountOne(void)
{
g_nCount +;
}
が、新呼び出し先関数
void CountOne(int *cnv_g_nCount)
{
(*cnv_g_nCount) ++;
}
に修正されるとともに、旧呼び出し先関数
void CountN(int nAdd)
{
g_nCount + = nAdd;
}
が、新呼び出し先関数
void CountN(int nAdd,int *cnv_g_nCount)
{
(*cnv_g_nCount) + = nAdd;
}
に修正されたことを示している。“*cnv_g_nCount”は、引数として追加されたローカル変数である。“*”（アスタリスク）は、ポインタ型の変数であることを意味する
続けて、最小の部分コールグラフ内の関数呼び出しを、ステップＳ７２において作成した新たな関数を呼び出せるように修正する（ステップＳ７３）。この処理は、図３のＳ４０に対応する処理である。その具体例は、図９に（４）と示されるものである。この例は、関数呼び出し元の“CountOne()”及び“CountN(10)”が、それぞれ、“CountOne(&env_g_nCount)”及び“CountN(10, &env_g_nCount)”に修正された様子を示している。なお、“&”（アンパサンド）も、ポインタ型の変数であることを意味している。
【００５８】
関数呼び出し元を修正した後、関数呼び出し元に宣言されている未処理のグローバル変数を削除する（ステップＳ７４）。この処理は、図３のステップＳ４１に対応する処理である。その具体例は、図９に（５）と示されるものである。この例は、変換前のソースコードに記述されていた“int g_nCount = 0;”が変換後には削除されている様子を示している。なお、“int g_nCount”がグローバル変数であることはいうまでもない。
【００５９】
関数呼び出し元に宣言されている未処理のグローバル変数を削除した(ステップＳ７４）後、保持された未処理グローバル変数リスト５３に基づいて、次の未処理のグローバル変数が存在するか否かを判定する処理（ステップＳ６２）に戻る。なお、この処理に先立って、未処理グローバル変数リスト５３上の処理の済んだ未処理のグローバル変数を処理済みとする処理が行われることはいうまでもない。
【００６０】
最後に、図６の“ステップＳ６８：またがる場合”について、図７のコールバック関数用処理フローを用いて説明する。コールバック関数とは、Ｃ言語及びＣ++言語などにおいて、関数呼び出しの際に、関数のアドレスをパラメータとして渡すことで、呼び出した関数から自身の提供する関数を呼び出すようにすることがあるが、この際の呼び出した関数から実行される関数のことを意味する。
【００６１】
このコールバック関数用処理では、最小のコールバックグラフの根、つまり、関数呼び出し元の中に、コールバック関数でない関数が幾つあるかを調べる（ステップＳ８１）。２つ以上ある場合（ステップＳ８１：２つ以上）には、取り出された未処理のグローバル変数についての処理は不可能なので、処理の対象外として、処理を終了する。
【００６２】
最小の部分コールグラフの根、つまり、関数呼び出し元の中に、コールバック関数でない関数が１つである場合（ステップＳ８１：１つ）には、コールバック関数でない関数において、取り出された未処理のグローバル変数の代替宣言を行うとともに、この関数を、最小の部分コールグラフの根、つまり、関数呼び出し元内の全てのコールバック関数に対して、強制的に宣言した代替変数への参照をメッセージとして送信できるように修正する（ステップＳ８３）。
【００６３】
ステップＳ８３における処理後、最小の部分コールグラフの根、つまり、関数呼び出し元内の全てのコールバック関数について、“当該グローバル変数の代替変数の参照を受けるメッセージを処理する”処理を追加する（ステップＳ８４）。
【００６４】
この追加処理の後、最小の部分コールグラフの根以外の未修整の関数、つまり、呼び出し先関数の全てに対して、取り出された未処理のグローバル変数に対応する引数を追加するとともに、その関数内における取り出された未処理のグローバル変数の使用を先に説明した引数、つまり、ローカル変数の使用に置き換えた新たな関数を作成する（ステップＳ８５）。
【００６５】
これらの処理が終了した後、図６のステップＳ７３及びＳ７４と同様の処理が行われ（ステップＳ８６、Ｓ８７）、コールバック関数用処理が終了する。このコールバック関数用処理の終了後、図６の保持された未処理グローバル変数リスト５３に基づいて、次の未処理のグローバル変数が存在するか否かを判定する処理（ステップＳ６２）に戻る。
【００６６】
以上、本発明の一実施形態を説明したが、上記実施形態はあくまでも説明のためのものであり、本発明の範囲を制限するものではない。したがって、当業者であればこれらの各要素若しくは全要素をこれと均等なものに置換した実施形態を採用することが可能であるが、これらの実施形態も本発明の範囲に含まれる。
【図面の簡単な説明】
【００６７】
【図１】本発明のプログラム変換方法を実施するための計算機システムの模式図である。
【図２】本発明のプログラム変換方法の処理概念図である。
【図３】本発明のプログラム変換方法の詳細処理フロー図である。
【図４】本発明のプログラム変換方法において作成される未処理グローバル変数リストの１例を示す図である。
【図５】本発明のプログラム変換方法を実現するための機能手段とこれら機能手段間の制御の流れ及び処理されるデータとの関係を示す模式図である。
【図６】本発明のプログラム変換方法をソースコードがＣ言語で書かれたプログラムの変換に適用した場合の参考例のメイン処理フロー図である。
【図７】図６のメイン処理フローにおけるコールバック関数用処理の詳細を示す処理フロー図である。
【図８】図６のメイン処理フローによる処理によって作成されるコールグラフの例を示す図である。
【図９】ソースコードがＣ言語で書かれたプログラムの変換例を示す図である。
【符号の説明】
【００６８】
１：ＣＰＵ、２：キーボード、３：ディスプレイ、４：プリンタ、５：主記憶装置、６：外部記憶装置、ｍ１：変換前ソースコード展開手段、ｍ２：未処理グローバル変数リスト作成手段、ｍ３：未処理グローバル変数有無判定手段、ｍ４：未処理グローバル変数取り出し手段、ｍ５：未処理関数呼び出し・未処理グローバル変数使用の呼び出し先関数探索手段、ｍ６：引数追加・新関数作成手段、ｍ７：呼び出し元修正手段、ｍ８：グローバル変数処理済み化手段、ｍ９：変換後ソースコード格納手段
【図１】
2009048259.tif 000003
【図２】
2009048259.tif 000004
【図３】
2009048259.tif 000005
【図４】
2009048259.tif 000006
【図５】
2009048259.tif 000007
【図６】
2009048259.tif 000008
【図７】
2009048259.tif 000009
【図８】
2009048259.tif 000010
【図９】
2009048259.tif 000011