2013-04-08 11 views
6

私はかなりllvmを初めて使いました。ここではオンラインチュートリアルのみでした:http://llvm.org/docs/tutorial/LangImpl1.html 私は自分の小さな言語を使いたいと思っていましたが、少し問題がありました。それは二つのことをすべきllvmで生成されたベーシックブロックターミネーター

(def i 1) 

: は、私はこれを解析する

  1. は、それが表現として使用することができますので、1
  2. 戻り値を返す新しい関数を定義し

関数は正しく作成されますが、式として使用する際に問題があります。

Value *DefExprAST::Codegen() { 
    if (Body->Codegen() == 0) return 0; 

    return ConstantFP::get(getGlobalContext(), APFloat(0.0)); 
} 

verifyFunctionが得られます。このような

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:このようになります関数のコードを作成するための

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 

コード:ASTはこのようになります次のエラー:

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ステートメントをバック与えるが、それはエントリに挿入されません。

答えて

8

質問を作成して少し休憩すると、問題を非常にうまく解決できます。 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)); 
} 
関連する問題