summaryrefslogtreecommitdiff
path: root/docs/tutorial
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2015-08-18 18:11:06 +0000
committerLang Hames <lhames@gmail.com>2015-08-18 18:11:06 +0000
commitafae23bc2154e23240467c7699fa61752eb43e92 (patch)
tree65a6e1f42761c1b23d88b6f5eeac513ddb422f18 /docs/tutorial
parent896f064a4900458e3fb245ad3f6fc9e7a3d8c8cd (diff)
[Kaleidoscope] Start C++11'ifying the kaleidoscope tutorials.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245322 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs/tutorial')
-rw-r--r--docs/tutorial/LangImpl1.rst2
-rw-r--r--docs/tutorial/LangImpl2.rst115
-rw-r--r--docs/tutorial/LangImpl3.rst2
-rw-r--r--docs/tutorial/LangImpl4.rst8
-rw-r--r--docs/tutorial/LangImpl5.rst60
-rw-r--r--docs/tutorial/LangImpl6.rst49
-rw-r--r--docs/tutorial/LangImpl7.rst33
-rw-r--r--docs/tutorial/LangImpl8.rst13
8 files changed, 150 insertions, 132 deletions
diff --git a/docs/tutorial/LangImpl1.rst b/docs/tutorial/LangImpl1.rst
index f4b019166af..6840bd6b090 100644
--- a/docs/tutorial/LangImpl1.rst
+++ b/docs/tutorial/LangImpl1.rst
@@ -25,7 +25,7 @@ It is useful to point out ahead of time that this tutorial is really
about teaching compiler techniques and LLVM specifically, *not* about
teaching modern and sane software engineering principles. In practice,
this means that we'll take a number of shortcuts to simplify the
-exposition. For example, the code leaks memory, uses global variables
+exposition. For example, the code uses global variables
all over the place, doesn't use nice design patterns like
`visitors <http://en.wikipedia.org/wiki/Visitor_pattern>`_, etc... but
it is very simple. If you dig in and use the code as a basis for future
diff --git a/docs/tutorial/LangImpl2.rst b/docs/tutorial/LangImpl2.rst
index 06b18ff6c23..4b28e02a523 100644
--- a/docs/tutorial/LangImpl2.rst
+++ b/docs/tutorial/LangImpl2.rst
@@ -45,7 +45,7 @@ We'll start with expressions first:
class NumberExprAST : public ExprAST {
double Val;
public:
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
};
The code above shows the definition of the base ExprAST class and one
@@ -66,16 +66,17 @@ language:
class VariableExprAST : public ExprAST {
std::string Name;
public:
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
- ExprAST *LHS, *RHS;
+ std::unique_ptr<ExprAST> LHS, RHS;
public:
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
- : Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
};
/// CallExprAST - Expression class for function calls.
@@ -83,8 +84,9 @@ language:
std::string Callee;
std::vector<ExprAST*> Args;
public:
- CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
};
This is all (intentionally) rather straight-forward: variables capture
@@ -110,17 +112,18 @@ way to talk about functions themselves:
std::string Name;
std::vector<std::string> Args;
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args)
- : Name(name), Args(args) {}
+ PrototypeAST(const std::string &name, std::vector<std::string> Args)
+ : Name(name), Args(std::move(Args)) {}
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
public:
- FunctionAST(PrototypeAST *proto, ExprAST *body)
- : Proto(proto), Body(body) {}
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
};
In Kaleidoscope, functions are typed with just a count of their
@@ -142,9 +145,10 @@ be generated with calls like this:
.. code-block:: c++
- ExprAST *X = new VariableExprAST("x");
- ExprAST *Y = new VariableExprAST("y");
- ExprAST *Result = new BinaryExprAST('+', X, Y);
+ auto LHS = llvm::make_unique<VariableExprAST>("x");
+ auto RHS = llvm::make_unique<VariableExprAST>("y");
+ auto Result = std::make_unique<BinaryExprAST>('+', std::move(LHS),
+ std::move(RHS));
In order to do this, we'll start by defining some basic helper routines:
@@ -190,10 +194,10 @@ which parses that production. For numeric literals, we have:
.. code-block:: c++
/// numberexpr ::= number
- static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+ static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
- return Result;
+ return std::move(Result);
}
This routine is very simple: it expects to be called when the current
@@ -211,10 +215,10 @@ the parenthesis operator is defined like this:
.. code-block:: c++
/// parenexpr ::= '(' expression ')'
- static ExprAST *ParseParenExpr() {
+ static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
- ExprAST *V = ParseExpression();
- if (!V) return 0;
+ auto V = ParseExpression();
+ if (!V) return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@@ -250,22 +254,22 @@ function calls:
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
- static ExprAST *ParseIdentifierExpr() {
+ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
- std::vector<ExprAST*> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg) return 0;
- Args.push_back(Arg);
+ auto Arg = ParseExpression();
+ if (!Arg) return nullptr;
+ Args.push_back(std::move(Arg));
if (CurTok == ')') break;
@@ -278,7 +282,7 @@ function calls:
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
This routine follows the same style as the other routines. (It expects
@@ -303,7 +307,7 @@ primary expression, we need to determine what sort of expression it is:
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
- static ExprAST *ParsePrimary() {
+ static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@@ -390,11 +394,11 @@ a sequence of [binop,primaryexpr] pairs:
/// expression
/// ::= primary binoprhs
///
- static ExprAST *ParseExpression() {
- ExprAST *LHS = ParsePrimary();
- if (!LHS) return 0;
+ static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParsePrimary();
+ if (!LHS) return nullptr;
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
``ParseBinOpRHS`` is the function that parses the sequence of pairs for
@@ -416,7 +420,8 @@ starts with:
/// binoprhs
/// ::= ('+' primary)*
- static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
@@ -440,8 +445,8 @@ expression:
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
- ExprAST *RHS = ParsePrimary();
- if (!RHS) return 0;
+ auto RHS = ParsePrimary();
+ if (!RHS) return nullptr;
As such, this code eats (and remembers) the binary operator and then
parses the primary expression that follows. This builds up the whole
@@ -474,7 +479,8 @@ then continue parsing:
}
// Merge LHS/RHS.
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+ std::move(RHS));
} // loop around to the top of the while loop.
}
@@ -498,11 +504,12 @@ above two blocks duplicated for context):
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, RHS);
+ RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
if (RHS == 0) return 0;
}
// Merge LHS/RHS.
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+ std::move(RHS));
} // loop around to the top of the while loop.
}
@@ -541,7 +548,7 @@ expressions):
/// prototype
/// ::= id '(' id* ')'
- static PrototypeAST *ParsePrototype() {
+ static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
@@ -561,7 +568,7 @@ expressions):
// success.
getNextToken(); // eat ')'.
- return new PrototypeAST(FnName, ArgNames);
+ return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
}
Given this, a function definition is very simple, just a prototype plus
@@ -570,14 +577,14 @@ an expression to implement the body:
.. code-block:: c++
/// definition ::= 'def' prototype expression
- static FunctionAST *ParseDefinition() {
+ static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
- PrototypeAST *Proto = ParsePrototype();
- if (Proto == 0) return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto) return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
In addition, we support 'extern' to declare functions like 'sin' and
@@ -587,7 +594,7 @@ In addition, we support 'extern' to declare functions like 'sin' and
.. code-block:: c++
/// external ::= 'extern' prototype
- static PrototypeAST *ParseExtern() {
+ static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@@ -599,13 +606,13 @@ nullary (zero argument) functions for them:
.. code-block:: c++
/// toplevelexpr ::= expression
- static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+ static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
- return 0;
+ return nullptr;
}
Now that we have all the pieces, let's build a little driver that will
diff --git a/docs/tutorial/LangImpl3.rst b/docs/tutorial/LangImpl3.rst
index 26ba4aae956..0920aa3f6a2 100644
--- a/docs/tutorial/LangImpl3.rst
+++ b/docs/tutorial/LangImpl3.rst
@@ -42,7 +42,7 @@ class:
class NumberExprAST : public ExprAST {
double Val;
public:
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
virtual Value *Codegen();
};
...
diff --git a/docs/tutorial/LangImpl4.rst b/docs/tutorial/LangImpl4.rst
index cdaac634dd7..8abb7456949 100644
--- a/docs/tutorial/LangImpl4.rst
+++ b/docs/tutorial/LangImpl4.rst
@@ -260,12 +260,12 @@ parses a top-level expression to look like this:
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
- LF->dump(); // Dump the function for exposition purposes.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (auto *FnIR = FnAST->Codegen()) {
+ FnIR->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
- void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
+ void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
diff --git a/docs/tutorial/LangImpl5.rst b/docs/tutorial/LangImpl5.rst
index ca2ffebc19a..add0e188734 100644
--- a/docs/tutorial/LangImpl5.rst
+++ b/docs/tutorial/LangImpl5.rst
@@ -90,10 +90,11 @@ To represent the new expression we add a new AST node for it:
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
- ExprAST *Cond, *Then, *Else;
+ std::unique<ExprAST> Cond, Then, Else;
public:
- IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
- : Cond(cond), Then(then), Else(_else) {}
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
virtual Value *Codegen();
};
@@ -109,36 +110,37 @@ First we define a new parsing function:
.. code-block:: c++
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
- static ExprAST *ParseIfExpr() {
+ static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
// condition.
- ExprAST *Cond = ParseExpression();
- if (!Cond) return 0;
+ auto Cond = ParseExpression();
+ if (!Cond) return nullptr;
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
- ExprAST *Then = ParseExpression();
- if (Then == 0) return 0;
+ auto Then = ParseExpression();
+ if (Then) return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
- ExprAST *Else = ParseExpression();
- if (!Else) return 0;
+ auto Else = ParseExpression();
+ if (!Else) return nullptr;
- return new IfExprAST(Cond, Then, Else);
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
+ std::move(Else));
}
Next we hook it up as a primary expression:
.. code-block:: c++
- static ExprAST *ParsePrimary() {
+ static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@@ -269,7 +271,7 @@ for ``IfExprAST``:
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
- if (CondV == 0) return 0;
+ if (!CondV) return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(CondV,
@@ -464,11 +466,13 @@ variable name and the constituent expressions in the node.
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
- ExprAST *Start, *End, *Step, *Body;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
- ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
- ExprAST *step, ExprAST *body)
- : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
virtual Value *Codegen();
};
@@ -483,7 +487,7 @@ value to null in the AST node:
.. code-block:: c++
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
- static ExprAST *ParseForExpr() {
+ static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
@@ -497,31 +501,33 @@ value to null in the AST node:
getNextToken(); // eat '='.
- ExprAST *Start = ParseExpression();
- if (Start == 0) return 0;
+ auto Start = ParseExpression();
+ if (!Start) return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
- ExprAST *End = ParseExpression();
- if (End == 0) return 0;
+ auto End = ParseExpression();
+ if (!End) return nullptr;
// The step value is optional.
- ExprAST *Step = 0;
+ std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
- if (Step == 0) return 0;
+ if (!Step) return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0) return 0;
+ auto Body = ParseExpression();
+ if (!Body) return nullptr;
- return new ForExprAST(IdName, Start, End, Step, Body);
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start),
+ std::move(End), std::move(Step),
+ std::move(Body));
}
LLVM IR for the 'for' Loop
diff --git a/docs/tutorial/LangImpl6.rst b/docs/tutorial/LangImpl6.rst
index bf78bdea74d..b3138182a29 100644
--- a/docs/tutorial/LangImpl6.rst
+++ b/docs/tutorial/LangImpl6.rst
@@ -129,15 +129,16 @@ this:
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
- bool isOperator;
+ bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args,
- bool isoperator = false, unsigned prec = 0)
- : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
+ PrototypeAST(const std::string &name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
- bool isUnaryOp() const { return isOperator && Args.size() == 1; }
- bool isBinaryOp() const { return isOperator && Args.size() == 2; }
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
@@ -161,7 +162,7 @@ user-defined operator, we need to parse it:
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
- static PrototypeAST *ParsePrototype() {
+ static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
@@ -210,7 +211,8 @@ user-defined operator, we need to parse it:
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
- return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence);
+ return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames),
+ Kind != 0, BinaryPrecedence);
}
This is all fairly straightforward parsing code, and we have already
@@ -305,10 +307,10 @@ that, we need an AST node:
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
- ExprAST *Operand;
+ std::unique_ptr<ExprAST> Operand;
public:
- UnaryExprAST(char opcode, ExprAST *operand)
- : Opcode(opcode), Operand(operand) {}
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
virtual Value *Codegen();
};
@@ -322,7 +324,7 @@ simple: we'll add a new function to do it:
/// unary
/// ::= primary
/// ::= '!' unary
- static ExprAST *ParseUnary() {
+ static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
@@ -330,9 +332,9 @@ simple: we'll add a new function to do it:
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
- if (ExprAST *Operand = ParseUnary())
- return new UnaryExprAST(Opc, Operand);
- return 0;
+ if (auto Operand = ParseUnary())
+ return llvm::unique_ptr<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
}
The grammar we add is pretty straightforward here. If we see a unary
@@ -350,21 +352,22 @@ call ParseUnary instead:
/// binoprhs
/// ::= ('+' unary)*
- static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
...
// Parse the unary expression after the binary operator.
- ExprAST *RHS = ParseUnary();
- if (!RHS) return 0;
+ auto RHS = ParseUnary();
+ if (!RHS) return nullptr;
...
}
/// expression
/// ::= unary binoprhs
///
- static ExprAST *ParseExpression() {
- ExprAST *LHS = ParseUnary();
- if (!LHS) return 0;
+ static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS) return nullptr;
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
With these two simple changes, we are now able to parse unary operators
@@ -378,7 +381,7 @@ operator code above with:
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
- static PrototypeAST *ParsePrototype() {
+ static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
diff --git a/docs/tutorial/LangImpl7.rst b/docs/tutorial/LangImpl7.rst
index 648940785b0..33f48535f16 100644
--- a/docs/tutorial/LangImpl7.rst
+++ b/docs/tutorial/LangImpl7.rst
@@ -573,7 +573,7 @@ implement codegen for the assignment operator. This looks like:
// 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<VariableExprAST*>(LHS);
+ VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
@@ -663,12 +663,12 @@ var/in, it looks like this:
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
- std::vector<std::pair<std::string, ExprAST*> > VarNames;
- ExprAST *Body;
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
public:
- VarExprAST(const std::vector<std::pair<std::string, ExprAST*> > &varnames,
- ExprAST *body)
- : VarNames(varnames), Body(body) {}
+ VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
virtual Value *Codegen();
};
@@ -690,7 +690,7 @@ do is add it as a primary expression:
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
- static ExprAST *ParsePrimary() {
+ static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@@ -708,10 +708,10 @@ Next we define ParseVarExpr:
/// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression
- static ExprAST *ParseVarExpr() {
+ static std::unique_ptr<ExprAST> ParseVarExpr() {
getNextToken(); // eat the var.
- std::vector<std::pair<std::string, ExprAST*> > VarNames;
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
// At least one variable name is required.
if (CurTok != tok_identifier)
@@ -727,15 +727,15 @@ into the local ``VarNames`` vector.
getNextToken(); // eat identifier.
// Read the optional initializer.
- ExprAST *Init = 0;
+ std::unique_ptr<ExprAST> Init;
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
- if (Init == 0) return 0;
+ if (!Init) return nullptr;
}
- VarNames.push_back(std::make_pair(Name, Init));
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
// End of var list, exit loop.
if (CurTok != ',') break;
@@ -755,10 +755,11 @@ AST node:
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0) return 0;
+ auto Body = ParseExpression();
+ if (!Body) return nullptr;
- return new VarExprAST(VarNames, Body);
+ return llvm::make_unique<VarExprAST>(std::move(VarNames),
+ std::move(Body));
}
Now that we can parse and represent the code, we need to support
@@ -774,7 +775,7 @@ emission of LLVM IR for it. This code starts out with:
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
- ExprAST *Init = VarNames[i].second;
+ ExprAST *Init = VarNames[i].second.get();
Basically it loops over all the variables, installing them one at a
time. For each variable we put into the symbol table, we remember the
diff --git a/docs/tutorial/LangImpl8.rst b/docs/tutorial/LangImpl8.rst
index 24c4d171f85..2f994c23d25 100644
--- a/docs/tutorial/LangImpl8.rst
+++ b/docs/tutorial/LangImpl8.rst
@@ -75,8 +75,8 @@ statement be our "main":
.. code-block:: udiff
- - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- + PrototypeAST *Proto = new PrototypeAST("main", std::vector<std::string>());
+ - auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ + auto Proto = llvm::make_unique<PrototypeAST>("main", std::vector<std::string>());
just with the simple change of giving it a name.
@@ -108,12 +108,12 @@ code is that the llvm IR goes to standard error:
@@ -1108,17 +1108,8 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- - if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ - if (auto *FnIR = FnAST->Codegen()) {
- // We're just doing this to make sure it executes.
- TheExecutionEngine->finalizeObject();
- // JIT the function, returning a function pointer.
- - void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
+ - void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
@@ -318,7 +318,8 @@ that we pass down through when we create a new expression:
.. code-block:: c++
- LHS = new BinaryExprAST(BinLoc, BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS),
+ std::move(RHS));
giving us locations for each of our expressions and variables.