Sono abbastanza nuovo a llvm e ho fatto solo il tutorial online qui: http://llvm.org/docs/tutorial/LangImpl1.html Ora volevo fare il mio piccolo linguaggio e ho avuto un piccolo problema. Voglio analizzare questo:no Terminatore di blocco di base generato in llvm
(def i 1)
Si dovrebbe fare due cose:
- definire una nuova funzione che restituisce 1
- restituire un valore in modo che possa essere utilizzato come espressione
La funzione viene creata correttamente, ma ho un problema con l'utilizzo come espressione. l'AST si presenta così:
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
Il Codice per la creazione di codice per la funzione è simile al seguente:
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;
}
E la DefExprAST in questo modo:
Value *DefExprAST::Codegen() {
if (Body->Codegen() == 0) return 0;
return ConstantFP::get(getGlobalContext(), APFloat(0.0));
}
Il verifyFunction
dà la errore seguente:
Basic Block in function '' does not have terminator!
label %entry
LLVM ERROR: Broken module, no Basic Block terminator!
E infatti, la funzione generata non ha una voce ret. Il suo vuoto:
define double @0() {
entry:
}
Ma RetVal
sia correttamente riempito con un doppio e Builder.CreateRet(RetVal)
dà di nuovo la dichiarazione ret ma non viene inserita nella voce.