Я довольно новичок в llvm и только сделал онлайн-учебник здесь: http://llvm.org/docs/tutorial/LangImpl1.html Теперь я хотел сделать свой собственный маленький язык и получил небольшую проблему. Я хочу, чтобы разобрать это:no Базовый блок-терминатор, сгенерированный в llvm
(def i 1)
Он должен сделать две вещи:
- Определить новую функцию, которая возвращает 1
- возвращает значение, так что он может быть использован в качестве выражения
Функция создается правильно, но у меня есть проблема с ее использованием в качестве выражения. АСТ выглядит следующим образом:
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)
возвращает заявление в отставке, но не вставляются в сени.