2013-04-08 27 views
6

Tôi khá mới đối với llvm và chỉ làm hướng dẫn trực tuyến tại đây: http://llvm.org/docs/tutorial/LangImpl1.html Bây giờ tôi muốn làm ngôn ngữ nhỏ của riêng mình và gặp vấn đề nhỏ. Tôi muốn phân tích này:không có Trình tạo khối Cơ bản nào được tạo trong llvm

(def i 1) 

Nó nên làm hai việc:

  1. Xác định một chức năng mới mà trả về 1
  2. Return một giá trị để nó có thể được sử dụng như là một biểu

Chức năng được tạo chính xác, nhưng tôi gặp sự cố khi sử dụng chức năng dưới dạng biểu thức. AST trông như thế này:

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 

Bộ luật cho Bộ luật Creation cho hàm trông như thế này:

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; 
} 

Và DefExprAST như thế này:

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

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

Các verifyFunction cung cấp cho các lỗi sau:

Basic Block in function '' does not have terminator! 
label %entry 
LLVM ERROR: Broken module, no Basic Block terminator! 

Và thực tế, hàm được tạo ra không có mục nhập ret. rỗng của nó:

define double @0() { 
entry: 
} 

Nhưng RetVal được điền một cách chính xác với một đôi và Builder.CreateRet(RetVal) cho phía sau tuyên bố ret nhưng nó không được đưa vào nhập cảnh.

Trả lời

8

Đôi khi xây dựng câu hỏi và nghỉ ngơi một chút sẽ giúp giải quyết vấn đề rất tốt. Tôi đã thay đổi số DefExprAST::Codegen để nhớ khối Gốc và đặt nó làm điểm chèn cho giá trị trả lại.

Value *DefExprAST::Codegen() { 
    BasicBlock *Parent = Builder.GetInsertBlock(); 
    if (Body->Codegen() == 0) return 0; 

    Builder.SetInsertPoint(Parent); 

    return ConstantFP::get(getGlobalContext(), APFloat(0.0)); 
} 
Các vấn đề liên quan