llvm

2013-04-08 8 views
6

में उत्पन्न कोई मूल ब्लॉक टर्मिनेटर नहीं, मैं llvm के लिए बहुत नया हूं और यहां केवल ऑनलाइन ट्यूटोरियल किया: http://llvm.org/docs/tutorial/LangImpl1.html अब मैं अपनी छोटी भाषा करना चाहता हूं और थोड़ा सा समस्या प्राप्त करना चाहता हूं।llvm

(def i 1) 

यह दो बातें करना चाहिए:: मैं इस पार्स करने के लिए चाहता हूँ

  1. एक नया कार्य जो 1
  2. वापसी एक मान देता है तो यह अभिव्यक्ति के रूप में इस्तेमाल किया जा सकता को परिभाषित करें

फ़ंक्शन सही ढंग से बनाया जाता है, लेकिन मुझे इसे अभिव्यक्ति के रूप में उपयोग करने में समस्या है। एएसटी इस तरह दिखता है:

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! 

और वास्तव में, जेनरेट किए गए फ़ंक्शन में रीट एंट्री नहीं है। इसके खाली:

define double @0() { 
entry: 
} 

लेकिन RetVal सही ढंग से एक डबल से भर जाता है और Builder.CreateRet(RetVal) वापस सेवानिवृत्त बयान देता है, लेकिन यह प्रविष्टि में डाला नहीं होती है।

उत्तर

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