diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst @@ -38,7 +38,7 @@ /// ExprAST - Base class for all expression nodes. class ExprAST { public: - virtual ~ExprAST() {} + virtual ~ExprAST() = default; }; /// NumberExprAST - Expression class for numeric literals like "1.0". @@ -77,9 +77,9 @@ std::unique_ptr LHS, RHS; public: - BinaryExprAST(char op, std::unique_ptr LHS, + BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) - : Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} + : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} }; /// CallExprAST - Expression class for function calls. @@ -117,8 +117,8 @@ std::vector Args; public: - PrototypeAST(const std::string &name, std::vector Args) - : Name(name), Args(std::move(Args)) {} + PrototypeAST(const std::string &Name, std::vector Args) + : Name(Name), Args(std::move(Args)) {} const std::string &getName() const { return Name; } }; @@ -180,7 +180,7 @@ /// LogError* - These are little helper functions for error handling. std::unique_ptr LogError(const char *Str) { - fprintf(stderr, "LogError: %s\n", Str); + fprintf(stderr, "Error: %s\n", Str); return nullptr; } std::unique_ptr LogErrorP(const char *Str) { @@ -280,7 +280,7 @@ getNextToken(); // eat ( std::vector> Args; if (CurTok != ')') { - while (1) { + while (true) { if (auto Arg = ParseExpression()) Args.push_back(std::move(Arg)); else @@ -444,7 +444,7 @@ static std::unique_ptr ParseBinOpRHS(int ExprPrec, std::unique_ptr LHS) { // If this is a binop, find its precedence. - while (1) { + while (true) { int TokPrec = GetTokPrecedence(); // If this is a binop that binds at least as tightly as the current binop, @@ -653,7 +653,7 @@ /// top ::= definition | external | expression | ';' static void MainLoop() { - while (1) { + while (true) { fprintf(stderr, "ready> "); switch (CurTok) { case tok_eof: diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst @@ -73,8 +73,8 @@ .. code-block:: c++ - static LLVMContext TheContext; - static IRBuilder<> Builder(TheContext); + static std::unique_ptr TheContext; + static std::unique_ptr> Builder(TheContext); static std::unique_ptr TheModule; static std::map NamedValues; @@ -122,7 +122,7 @@ .. code-block:: c++ Value *NumberExprAST::codegen() { - return ConstantFP::get(TheContext, APFloat(Val)); + return ConstantFP::get(*TheContext, APFloat(Val)); } In the LLVM IR, numeric constants are represented with the @@ -163,16 +163,16 @@ switch (Op) { case '+': - return Builder.CreateFAdd(L, R, "addtmp"); + return Builder->CreateFAdd(L, R, "addtmp"); case '-': - return Builder.CreateFSub(L, R, "subtmp"); + return Builder->CreateFSub(L, R, "subtmp"); case '*': - return Builder.CreateFMul(L, R, "multmp"); + return Builder->CreateFMul(L, R, "multmp"); case '<': - L = Builder.CreateFCmpULT(L, R, "cmptmp"); + L = Builder->CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 - return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), - "booltmp"); + return Builder->CreateUIToFP(L, Type::getDoubleTy(TheContext), + "booltmp"); default: return LogErrorV("invalid binary operator"); } @@ -233,7 +233,7 @@ return nullptr; } - return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); + return Builder->CreateCall(CalleeF, ArgsV, "calltmp"); } Code generation for function calls is quite straightforward with LLVM. The code @@ -270,9 +270,9 @@ Function *PrototypeAST::codegen() { // Make the function type: double(double,double) etc. std::vector Doubles(Args.size(), - Type::getDoubleTy(TheContext)); + Type::getDoubleTy(*TheContext)); FunctionType *FT = - FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false); + FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false); Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get()); @@ -346,13 +346,13 @@ .. code-block:: c++ // Create a new basic block to start insertion into. - BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction); - Builder.SetInsertPoint(BB); + BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction); + Builder->SetInsertPoint(BB); // Record the function arguments in the NamedValues map. NamedValues.clear(); for (auto &Arg : TheFunction->args()) - NamedValues[Arg.getName()] = &Arg; + NamedValues[std::string(Arg.getName())] = &Arg; Now we get to the point where the ``Builder`` is set up. The first line creates a new `basic block `_ @@ -371,7 +371,7 @@ if (Value *RetVal = Body->codegen()) { // Finish off the function. - Builder.CreateRet(RetVal); + Builder->CreateRet(RetVal); // Validate the generated code, checking for consistency. verifyFunction(*TheFunction); diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst @@ -138,8 +138,8 @@ .. code-block:: c++ void InitializeModuleAndPassManager(void) { - // Open a new module. - TheModule = std::make_unique("my cool jit", TheContext); + // Open a new context and module. + TheModule = std::make_unique("my cool jit", *TheContext); // Create a new pass manager attached to it. TheFPM = std::make_unique(TheModule.get()); @@ -270,9 +270,13 @@ .. code-block:: c++ void InitializeModuleAndPassManager(void) { - // Open a new module. + // Open a new context and module. + TheContext = std::make_unique(); TheModule = std::make_unique("my cool jit", TheContext); - TheModule->setDataLayout(TheJIT->getTargetMachine().createDataLayout()); + TheModule->setDataLayout(TheJIT->getDataLayout()); + + // Create a new builder for the module. + Builder = std::make_unique>(*TheContext); // Create a new pass manager attached to it. TheFPM = std::make_unique(TheModule.get()); @@ -280,31 +284,35 @@ The KaleidoscopeJIT class is a simple JIT built specifically for these tutorials, available inside the LLVM source code -at llvm-src/examples/Kaleidoscope/include/KaleidoscopeJIT.h. +at `llvm-src/examples/Kaleidoscope/include/KaleidoscopeJIT.h +`_. In later chapters we will look at how it works and extend it with new features, but for now we will take it as given. Its API is very simple: ``addModule`` adds an LLVM IR module to the JIT, making its functions -available for execution; ``removeModule`` removes a module, freeing any -memory associated with the code in that module; and ``findSymbol`` allows us -to look up pointers to the compiled code. +available for execution (with its memory managed by a ``ResourceTracker``); and +``lookup`` allows us to look up pointers to the compiled code. We can take this simple API and change our code that parses top-level expressions to look like this: .. code-block:: c++ + static ExitOnError ExitOnErr; + ... static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. if (auto FnAST = ParseTopLevelExpr()) { if (FnAST->codegen()) { + // Create a ResourceTracker to track JIT'd memory allocated to our + // anonymous expression -- that way we can free it after executing. + auto RT = TheJIT->getMainJITDylib().createResourceTracker(); - // JIT the module containing the anonymous expression, keeping a handle so - // we can free it later. - auto H = TheJIT->addModule(std::move(TheModule)); + auto TSM = ThreadSafeModule(std::move(TheModule), std::move(TheContext)); + ExitOnErr(TheJIT->addModule(std::move(TSM), RT)); InitializeModuleAndPassManager(); // Search the JIT for the __anon_expr symbol. - auto ExprSymbol = TheJIT->findSymbol("__anon_expr"); + auto ExprSymbol = ExitOnErr(TheJIT->lookup("__anon_expr")); assert(ExprSymbol && "Function not found"); // Get the symbol's address and cast it to the right type (takes no @@ -313,20 +321,20 @@ fprintf(stderr, "Evaluated to %f\n", FP()); // Delete the anonymous expression module from the JIT. - TheJIT->removeModule(H); + ExitOnErr(RT->remove()); } If parsing and codegen succeed, the next step is to add the module containing the top-level expression to the JIT. We do this by calling addModule, which -triggers code generation for all the functions in the module, and returns a -handle that can be used to remove the module from the JIT later. Once the module +triggers code generation for all the functions in the module, and accepts a +``ResourceTracker`` which can be used to remove the module from the JIT later. Once the module has been added to the JIT it can no longer be modified, so we also open a new module to hold subsequent code by calling ``InitializeModuleAndPassManager()``. Once we've added the module to the JIT we need to get a pointer to the final -generated code. We do this by calling the JIT's findSymbol method, and passing +generated code. We do this by calling the JIT's ``lookup`` method, and passing the name of the top-level expression function: ``__anon_expr``. Since we just -added this function, we assert that findSymbol returned a result. +added this function, we assert that ``lookup`` returned a result. Next, we get the in-memory address of the ``__anon_expr`` function by calling ``getAddress()`` on the symbol. Recall that we compile top-level expressions @@ -495,7 +503,8 @@ fprintf(stderr, "Read function definition:"); FnIR->print(errs()); fprintf(stderr, "\n"); - TheJIT->addModule(std::move(TheModule)); + ExitOnErr(TheJIT->addModule( + ThreadSafeModule(std::move(TheModule), std::move(TheContext)))); InitializeModuleAndPassManager(); } } else { @@ -623,7 +632,7 @@ } Note, that for Windows we need to actually export the functions because -the dynamic symbol loader will use GetProcAddress to find the symbols. +the dynamic symbol loader will use ``GetProcAddress`` to find the symbols. Now we can produce simple output to the console by using things like: "``extern putchard(x); putchard(120);``", which prints a lowercase 'x' diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst @@ -292,8 +292,8 @@ return nullptr; // Convert condition to a bool by comparing non-equal to 0.0. - CondV = Builder.CreateFCmpONE( - CondV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond"); + CondV = Builder->CreateFCmpONE( + CondV, ConstantFP::get(*TheContext, APFloat(0.0)), "ifcond"); This code is straightforward and similar to what we saw before. We emit the expression for the condition, then compare that value to zero to get @@ -301,16 +301,16 @@ .. code-block:: c++ - Function *TheFunction = Builder.GetInsertBlock()->getParent(); + Function *TheFunction = Builder->GetInsertBlock()->getParent(); // Create blocks for the then and else cases. Insert the 'then' block at the // end of the function. BasicBlock *ThenBB = - BasicBlock::Create(TheContext, "then", TheFunction); - BasicBlock *ElseBB = BasicBlock::Create(TheContext, "else"); - BasicBlock *MergeBB = BasicBlock::Create(TheContext, "ifcont"); + BasicBlock::Create(*TheContext, "then", TheFunction); + BasicBlock *ElseBB = BasicBlock::Create(*TheContext, "else"); + BasicBlock *MergeBB = BasicBlock::Create(*TheContext, "ifcont"); - Builder.CreateCondBr(CondV, ThenBB, ElseBB); + Builder->CreateCondBr(CondV, ThenBB, ElseBB); This code creates the basic blocks that are related to the if/then/else statement, and correspond directly to the blocks in the example above. @@ -336,15 +336,15 @@ .. code-block:: c++ // Emit then value. - Builder.SetInsertPoint(ThenBB); + Builder->SetInsertPoint(ThenBB); Value *ThenV = Then->codegen(); if (!ThenV) return nullptr; - Builder.CreateBr(MergeBB); + Builder->CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. - ThenBB = Builder.GetInsertBlock(); + ThenBB = Builder->GetInsertBlock(); After the conditional branch is inserted, we move the builder to start inserting into the "then" block. Strictly speaking, this call moves the @@ -378,15 +378,15 @@ // Emit else block. TheFunction->insert(TheFunction->end(), ElseBB); - Builder.SetInsertPoint(ElseBB); + Builder->SetInsertPoint(ElseBB); Value *ElseV = Else->codegen(); if (!ElseV) return nullptr; - Builder.CreateBr(MergeBB); + Builder->CreateBr(MergeBB); // codegen of 'Else' can change the current block, update ElseBB for the PHI. - ElseBB = Builder.GetInsertBlock(); + ElseBB = Builder->GetInsertBlock(); Code generation for the 'else' block is basically identical to codegen for the 'then' block. The only significant difference is the first line, @@ -399,9 +399,9 @@ // Emit merge block. TheFunction->insert(TheFunction->end(), MergeBB); - Builder.SetInsertPoint(MergeBB); + Builder->SetInsertPoint(MergeBB); PHINode *PN = - Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp"); + Builder->CreatePHI(Type::getDoubleTy(*TheContext), 2, "iftmp"); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); @@ -646,13 +646,13 @@ // Make the new basic block for the loop header, inserting after current // block. - Function *TheFunction = Builder.GetInsertBlock()->getParent(); - BasicBlock *PreheaderBB = Builder.GetInsertBlock(); + Function *TheFunction = Builder->GetInsertBlock()->getParent(); + BasicBlock *PreheaderBB = Builder->GetInsertBlock(); BasicBlock *LoopBB = - BasicBlock::Create(TheContext, "loop", TheFunction); + BasicBlock::Create(*TheContext, "loop", TheFunction); // Insert an explicit fall through from the current block to the LoopBB. - Builder.CreateBr(LoopBB); + Builder->CreateBr(LoopBB); This code is similar to what we saw for if/then/else. Because we will need it to create the Phi node, we remember the block that falls through @@ -663,11 +663,11 @@ .. code-block:: c++ // Start insertion in LoopBB. - Builder.SetInsertPoint(LoopBB); + Builder->SetInsertPoint(LoopBB); // Start the PHI node with an entry for Start. - PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(TheContext), - 2, VarName.c_str()); + PHINode *Variable = Builder->CreatePHI(Type::getDoubleTy(*TheContext), + 2, VarName); Variable->addIncoming(StartVal, PreheaderBB); Now that the "preheader" for the loop is set up, we switch to emitting @@ -717,10 +717,10 @@ return nullptr; } else { // If not specified, use 1.0. - StepVal = ConstantFP::get(TheContext, APFloat(1.0)); + StepVal = ConstantFP::get(*TheContext, APFloat(1.0)); } - Value *NextVar = Builder.CreateFAdd(Variable, StepVal, "nextvar"); + Value *NextVar = Builder->CreateFAdd(Variable, StepVal, "nextvar"); Now that the body is emitted, we compute the next value of the iteration variable by adding the step value, or 1.0 if it isn't present. @@ -735,8 +735,8 @@ return nullptr; // Convert condition to a bool by comparing non-equal to 0.0. - EndCond = Builder.CreateFCmpONE( - EndCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond"); + EndCond = Builder->CreateFCmpONE( + EndCond, ConstantFP::get(*TheContext, APFloat(0.0)), "loopcond"); Finally, we evaluate the exit value of the loop, to determine whether the loop should exit. This mirrors the condition evaluation for the @@ -745,15 +745,15 @@ .. code-block:: c++ // Create the "after loop" block and insert it. - BasicBlock *LoopEndBB = Builder.GetInsertBlock(); + BasicBlock *LoopEndBB = Builder->GetInsertBlock(); BasicBlock *AfterBB = - BasicBlock::Create(TheContext, "afterloop", TheFunction); + BasicBlock::Create(*TheContext, "afterloop", TheFunction); // Insert the conditional branch into the end of LoopEndBB. - Builder.CreateCondBr(EndCond, LoopBB, AfterBB); + Builder->CreateCondBr(EndCond, LoopBB, AfterBB); // Any new code will be inserted in AfterBB. - Builder.SetInsertPoint(AfterBB); + Builder->SetInsertPoint(AfterBB); With the code for the body of the loop complete, we just need to finish up the control flow for it. This code remembers the end block (for the @@ -775,7 +775,7 @@ NamedValues.erase(VarName); // for expr always returns 0.0. - return Constant::getNullValue(Type::getDoubleTy(TheContext)); + return Constant::getNullValue(Type::getDoubleTy(*TheContext)); } The final code handles various cleanups: now that we have the "NextVar" diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst @@ -138,9 +138,9 @@ unsigned Precedence; // Precedence if a binary op. public: - PrototypeAST(const std::string &name, std::vector Args, + PrototypeAST(const std::string &Name, std::vector Args, bool IsOperator = false, unsigned Prec = 0) - : Name(name), Args(std::move(Args)), IsOperator(IsOperator), + : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), Precedence(Prec) {} Function *codegen(); @@ -244,15 +244,15 @@ switch (Op) { case '+': - return Builder.CreateFAdd(L, R, "addtmp"); + return Builder->CreateFAdd(L, R, "addtmp"); case '-': - return Builder.CreateFSub(L, R, "subtmp"); + return Builder->CreateFSub(L, R, "subtmp"); case '*': - return Builder.CreateFMul(L, R, "multmp"); + return Builder->CreateFMul(L, R, "multmp"); case '<': - L = Builder.CreateFCmpULT(L, R, "cmptmp"); + L = Builder->CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 - return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), + return Builder->CreateUIToFP(L, Type::getDoubleTy(*TheContext), "booltmp"); default: break; @@ -264,7 +264,7 @@ assert(F && "binary operator not found!"); Value *Ops[2] = { L, R }; - return Builder.CreateCall(F, Ops, "binop"); + return Builder->CreateCall(F, Ops, "binop"); } As you can see above, the new code is actually really simple. It just @@ -291,7 +291,7 @@ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence(); // Create a new basic block to start insertion into. - BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction); + BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction); ... Basically, before codegening a function, if it is a user-defined @@ -438,7 +438,7 @@ if (!F) return LogErrorV("Unknown unary operator"); - return Builder.CreateCall(F, OperandV, "unop"); + return Builder->CreateCall(F, OperandV, "unop"); } This code is similar to, but simpler than, the code for binary diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst @@ -319,7 +319,7 @@ these will both need memory locations. To start our transformation of Kaleidoscope, we'll change the -NamedValues map so that it maps to AllocaInst\* instead of Value\*. Once +``NamedValues`` map so that it maps to AllocaInst\* instead of Value\*. Once we do this, the C++ compiler will tell us what parts of the code we need to update: @@ -339,8 +339,8 @@ const std::string &VarName) { IRBuilder<> TmpB(&TheFunction->getEntryBlock(), TheFunction->getEntryBlock().begin()); - return TmpB.CreateAlloca(Type::getDoubleTy(TheContext), 0, - VarName.c_str()); + return TmpB.CreateAlloca(Type::getDoubleTy(*TheContext), nullptr, + VarName); } This funny looking code creates an IRBuilder object that is pointing at @@ -357,12 +357,12 @@ Value *VariableExprAST::codegen() { // Look this variable up in the function. - Value *V = NamedValues[Name]; - if (!V) + AllocaInst *A = NamedValues[Name]; + if (!A) return LogErrorV("Unknown variable name"); // Load the value. - return Builder.CreateLoad(V, Name.c_str()); + return Builder->CreateLoad(A->getAllocatedType(), A, Name.c_str()); } As you can see, this is pretty straightforward. Now we need to update @@ -372,7 +372,7 @@ .. code-block:: c++ - Function *TheFunction = Builder.GetInsertBlock()->getParent(); + Function *TheFunction = Builder->GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); @@ -383,7 +383,7 @@ return nullptr; // Store the value into the alloca. - Builder.CreateStore(StartVal, Alloca); + Builder->CreateStore(StartVal, Alloca); ... // Compute the end condition. @@ -393,9 +393,10 @@ // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. - Value *CurVar = Builder.CreateLoad(Alloca); - Value *NextVar = Builder.CreateFAdd(CurVar, StepVal, "nextvar"); - Builder.CreateStore(NextVar, Alloca); + Value *CurVar = Builder->CreateLoad(Alloca->getAllocatedType(), Alloca, + VarName.c_str()); + Value *NextVar = Builder->CreateFAdd(CurVar, StepVal, "nextvar"); + Builder->CreateStore(NextVar, Alloca); ... This code is virtually identical to the code `before we allowed mutable @@ -410,7 +411,7 @@ Function *FunctionAST::codegen() { ... - Builder.SetInsertPoint(BB); + Builder->SetInsertPoint(BB); // Record the function arguments in the NamedValues map. NamedValues.clear(); @@ -419,10 +420,10 @@ AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName()); // Store the initial value into the alloca. - Builder.CreateStore(&Arg, Alloca); + Builder->CreateStore(&Arg, Alloca); // Add arguments to variable symbol table. - NamedValues[Arg.getName()] = Alloca; + NamedValues[std::string(Arg.getName())] = Alloca; } if (Value *RetVal = Body->codegen()) { @@ -577,8 +578,10 @@ Value *BinaryExprAST::codegen() { // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { - // Assignment requires the LHS to be an identifier. - VariableExprAST *LHSE = dynamic_cast(LHS.get()); + // This assume we're building without RTTI because LLVM builds that way by + // default. If you build LLVM with RTTI this can be changed to a + // dynamic_cast for automatic error checking. + VariableExprAST *LHSE = static_cast(LHS.get()); if (!LHSE) return LogErrorV("destination of '=' must be a variable"); @@ -601,7 +604,7 @@ if (!Variable) return LogErrorV("Unknown variable name"); - Builder.CreateStore(Val, Variable); + Builder->CreateStore(Val, Variable); return Val; } ... @@ -741,7 +744,7 @@ .. code-block:: c++ - while (1) { + while (true) { std::string Name = IdentifierStr; getNextToken(); // eat identifier. @@ -790,7 +793,7 @@ Value *VarExprAST::codegen() { std::vector OldBindings; - Function *TheFunction = Builder.GetInsertBlock()->getParent(); + Function *TheFunction = Builder->GetInsertBlock()->getParent(); // Register all variables and emit their initializer. for (unsigned i = 0, e = VarNames.size(); i != e; ++i) { @@ -814,11 +817,11 @@ if (!InitVal) return nullptr; } else { // If not specified, use 0.0. - InitVal = ConstantFP::get(TheContext, APFloat(0.0)); + InitVal = ConstantFP::get(*TheContext, APFloat(0.0)); } AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); - Builder.CreateStore(InitVal, Alloca); + Builder->CreateStore(InitVal, Alloca); // Remember the old variable binding so that we can restore the binding when // we unrecurse. diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst @@ -114,7 +114,7 @@ auto Features = ""; TargetOptions opt; - auto RM = Optional(); + auto RM = std::optional(); auto TargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM); diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst @@ -87,7 +87,7 @@ @@ -1129,7 +1129,6 @@ static void HandleTopLevelExpression() { /// top ::= definition | external | expression | ';' static void MainLoop() { - while (1) { + while (true) { - fprintf(stderr, "ready> "); switch (CurTok) { case tok_eof: @@ -120,7 +120,7 @@ - double (*FP)() = (double (*)())(intptr_t)FPtr; - // Ignore the return value for this. - (void)FP; - + if (!F->codegen()) { + + if (!FnAST->codegen()) { + fprintf(stderr, "Error generating code for top level expr"); } } else { @@ -184,7 +184,7 @@ .. code-block:: c++ - static DIBuilder *DBuilder; + static std::unique_ptr DBuilder; struct DebugInfo { DICompileUnit *TheCU; @@ -205,11 +205,11 @@ .. code-block:: c++ - DBuilder = new DIBuilder(*TheModule); + DBuilder = std::make_unique(*TheModule); KSDbgInfo.TheCU = DBuilder->createCompileUnit( dwarf::DW_LANG_C, DBuilder->createFile("fib.ks", "."), - "Kaleidoscope Compiler", 0, "", 0); + "Kaleidoscope Compiler", false, "", 0); There are a couple of things to note here. First, while we're producing a compile unit for a language called Kaleidoscope we used the language @@ -238,7 +238,7 @@ ========= Now that we have our ``Compile Unit`` and our source locations, we can add -function definitions to the debug info. So in ``PrototypeAST::codegen()`` we +function definitions to the debug info. So in ``FunctionAST::codegen()`` we add a few lines of code to describe a context for our subprogram, in this case the "File", and the actual definition of the function itself. @@ -246,8 +246,8 @@ .. code-block:: c++ - DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(), - KSDbgInfo.TheCU.getDirectory()); + DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(), + KSDbgInfo.TheCU->getDirectory()); giving us an DIFile and asking the ``Compile Unit`` we created above for the directory and filename where we are currently. Then, for now, we use some @@ -336,19 +336,21 @@ .. code-block:: c++ void DebugInfo::emitLocation(ExprAST *AST) { + if (!AST) + return Builder->SetCurrentDebugLocation(DebugLoc()); DIScope *Scope; if (LexicalBlocks.empty()) Scope = TheCU; else Scope = LexicalBlocks.back(); - Builder.SetCurrentDebugLocation( + Builder->SetCurrentDebugLocation( DILocation::get(Scope->getContext(), AST->getLine(), AST->getCol(), Scope)); } This both tells the main ``IRBuilder`` where we are, but also what scope we're in. The scope can either be on compile-unit level or be the nearest enclosing lexical block like the current function. -To represent this we create a stack of scopes: +To represent this we create a stack of scopes in ``DebugInfo``: .. code-block:: c++ @@ -402,13 +404,13 @@ DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(), DILocation::get(SP->getContext(), LineNo, 0, SP), - Builder.GetInsertBlock()); + Builder->GetInsertBlock()); // Store the initial value into the alloca. - Builder.CreateStore(&Arg, Alloca); + Builder->CreateStore(&Arg, Alloca); // Add arguments to variable symbol table. - NamedValues[Arg.getName()] = Alloca; + NamedValues[std::string(Arg.getName())] = Alloca; } diff --git a/llvm/examples/Kaleidoscope/Chapter9/toy.cpp b/llvm/examples/Kaleidoscope/Chapter9/toy.cpp --- a/llvm/examples/Kaleidoscope/Chapter9/toy.cpp +++ b/llvm/examples/Kaleidoscope/Chapter9/toy.cpp @@ -799,8 +799,8 @@ static std::unique_ptr ParseTopLevelExpr() { SourceLocation FnLoc = CurLoc; if (auto E = ParseExpression()) { - // Make an anonymous proto. - auto Proto = std::make_unique(FnLoc, "__anon_expr", + // Make the top-level expression be our "main" function. + auto Proto = std::make_unique(FnLoc, "main", std::vector()); return std::make_unique(std::move(Proto), std::move(E)); }