私は llvm を初めて使用し、ここでオンライン チュートリアルのみを行いまし た。これを解析したい:
(def i 1)
次の 2 つのことを行う必要があります。
- 1 を返す新しい関数を定義する
- 式として使用できるように値を返す
関数は正しく作成されますが、式として使用する際に問題があります。AST は次のようになります。
FunctionAST // the whole statement
- Prototype // is an nameless statement
- Body // contains the definition expression
- DefExprAST
- Body // contains the Function definition
- FunctionAST
- Prototype // named i
- Body // the value 1
関数のコード作成のコードは次のようになります。
Function *FunctionAST::Codegen() {
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
if ( TheFunction == 0 ) return 0;
BasicBlock *BB = BasicBlock::Create( getGlobalContext(), "entry", TheFunction );
Builder.SetInsertPoint( BB );
if ( Value *RetVal = Body->Codegen() ) {
Builder.CreateRet( RetVal );
verifyFunction( *TheFunction );
return TheFunction;
}
return 0;
}
そして、DefExprAST は次のようになります。
Value *DefExprAST::Codegen() {
if ( Body->Codegen() == 0 ) return 0;
return ConstantFP::get( getGlobalContext(), APFloat( 0.0 ) );
}
verifyFunction
次のエラーが表示されます。
Basic Block in function '' does not have terminator!
label %entry
LLVM ERROR: Broken module, no Basic Block terminator!
実際、生成された関数には ret エントリがありません。空っぽです:
define double @0() {
entry:
}
しかしRetVal
、double で正しく埋められBuilder.CreateRet( RetVal )
、ret ステートメントを返しますが、エントリに挿入されません。