我对llvm很新,只在这里做了在线教程:http://llvm.org/docs/tutorial/LangImpl1.html 现在我想做自己的小语言并遇到一些问题。 我想解析一下:
(def i 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
正确填充了一个双精度而Builder.CreateRet( RetVal )
会返回ret语句,但它不会插入到条目中。
答案 0 :(得分:9)
有时候提出一个问题并稍稍休息有助于很好地解决问题。我更改了DefExprAST::Codegen
以记住父块,并将其设置为返回值的插入点。
Value *DefExprAST::Codegen() {
BasicBlock *Parent = Builder.GetInsertBlock();
if ( Body->Codegen() == 0 ) return 0;
Builder.SetInsertPoint( Parent );
return ConstantFP::get( getGlobalContext(), APFloat( 0.0 ) );
}