106f32e7eSjoerg #include "llvm/ADT/APFloat.h"
206f32e7eSjoerg #include "llvm/ADT/Optional.h"
306f32e7eSjoerg #include "llvm/ADT/STLExtras.h"
406f32e7eSjoerg #include "llvm/IR/BasicBlock.h"
506f32e7eSjoerg #include "llvm/IR/Constants.h"
606f32e7eSjoerg #include "llvm/IR/DerivedTypes.h"
706f32e7eSjoerg #include "llvm/IR/Function.h"
806f32e7eSjoerg #include "llvm/IR/Instructions.h"
906f32e7eSjoerg #include "llvm/IR/IRBuilder.h"
1006f32e7eSjoerg #include "llvm/IR/LLVMContext.h"
1106f32e7eSjoerg #include "llvm/IR/LegacyPassManager.h"
1206f32e7eSjoerg #include "llvm/IR/Module.h"
1306f32e7eSjoerg #include "llvm/IR/Type.h"
1406f32e7eSjoerg #include "llvm/IR/Verifier.h"
1506f32e7eSjoerg #include "llvm/Support/FileSystem.h"
1606f32e7eSjoerg #include "llvm/Support/Host.h"
1706f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
1806f32e7eSjoerg #include "llvm/Support/TargetRegistry.h"
1906f32e7eSjoerg #include "llvm/Support/TargetSelect.h"
2006f32e7eSjoerg #include "llvm/Target/TargetMachine.h"
2106f32e7eSjoerg #include "llvm/Target/TargetOptions.h"
2206f32e7eSjoerg #include <algorithm>
2306f32e7eSjoerg #include <cassert>
2406f32e7eSjoerg #include <cctype>
2506f32e7eSjoerg #include <cstdio>
2606f32e7eSjoerg #include <cstdlib>
2706f32e7eSjoerg #include <map>
2806f32e7eSjoerg #include <memory>
2906f32e7eSjoerg #include <string>
3006f32e7eSjoerg #include <system_error>
3106f32e7eSjoerg #include <utility>
3206f32e7eSjoerg #include <vector>
3306f32e7eSjoerg
3406f32e7eSjoerg using namespace llvm;
3506f32e7eSjoerg using namespace llvm::sys;
3606f32e7eSjoerg
3706f32e7eSjoerg //===----------------------------------------------------------------------===//
3806f32e7eSjoerg // Lexer
3906f32e7eSjoerg //===----------------------------------------------------------------------===//
4006f32e7eSjoerg
4106f32e7eSjoerg // The lexer returns tokens [0-255] if it is an unknown character, otherwise one
4206f32e7eSjoerg // of these for known things.
4306f32e7eSjoerg enum Token {
4406f32e7eSjoerg tok_eof = -1,
4506f32e7eSjoerg
4606f32e7eSjoerg // commands
4706f32e7eSjoerg tok_def = -2,
4806f32e7eSjoerg tok_extern = -3,
4906f32e7eSjoerg
5006f32e7eSjoerg // primary
5106f32e7eSjoerg tok_identifier = -4,
5206f32e7eSjoerg tok_number = -5,
5306f32e7eSjoerg
5406f32e7eSjoerg // control
5506f32e7eSjoerg tok_if = -6,
5606f32e7eSjoerg tok_then = -7,
5706f32e7eSjoerg tok_else = -8,
5806f32e7eSjoerg tok_for = -9,
5906f32e7eSjoerg tok_in = -10,
6006f32e7eSjoerg
6106f32e7eSjoerg // operators
6206f32e7eSjoerg tok_binary = -11,
6306f32e7eSjoerg tok_unary = -12,
6406f32e7eSjoerg
6506f32e7eSjoerg // var definition
6606f32e7eSjoerg tok_var = -13
6706f32e7eSjoerg };
6806f32e7eSjoerg
6906f32e7eSjoerg static std::string IdentifierStr; // Filled in if tok_identifier
7006f32e7eSjoerg static double NumVal; // Filled in if tok_number
7106f32e7eSjoerg
7206f32e7eSjoerg /// gettok - Return the next token from standard input.
gettok()7306f32e7eSjoerg static int gettok() {
7406f32e7eSjoerg static int LastChar = ' ';
7506f32e7eSjoerg
7606f32e7eSjoerg // Skip any whitespace.
7706f32e7eSjoerg while (isspace(LastChar))
7806f32e7eSjoerg LastChar = getchar();
7906f32e7eSjoerg
8006f32e7eSjoerg if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
8106f32e7eSjoerg IdentifierStr = LastChar;
8206f32e7eSjoerg while (isalnum((LastChar = getchar())))
8306f32e7eSjoerg IdentifierStr += LastChar;
8406f32e7eSjoerg
8506f32e7eSjoerg if (IdentifierStr == "def")
8606f32e7eSjoerg return tok_def;
8706f32e7eSjoerg if (IdentifierStr == "extern")
8806f32e7eSjoerg return tok_extern;
8906f32e7eSjoerg if (IdentifierStr == "if")
9006f32e7eSjoerg return tok_if;
9106f32e7eSjoerg if (IdentifierStr == "then")
9206f32e7eSjoerg return tok_then;
9306f32e7eSjoerg if (IdentifierStr == "else")
9406f32e7eSjoerg return tok_else;
9506f32e7eSjoerg if (IdentifierStr == "for")
9606f32e7eSjoerg return tok_for;
9706f32e7eSjoerg if (IdentifierStr == "in")
9806f32e7eSjoerg return tok_in;
9906f32e7eSjoerg if (IdentifierStr == "binary")
10006f32e7eSjoerg return tok_binary;
10106f32e7eSjoerg if (IdentifierStr == "unary")
10206f32e7eSjoerg return tok_unary;
10306f32e7eSjoerg if (IdentifierStr == "var")
10406f32e7eSjoerg return tok_var;
10506f32e7eSjoerg return tok_identifier;
10606f32e7eSjoerg }
10706f32e7eSjoerg
10806f32e7eSjoerg if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
10906f32e7eSjoerg std::string NumStr;
11006f32e7eSjoerg do {
11106f32e7eSjoerg NumStr += LastChar;
11206f32e7eSjoerg LastChar = getchar();
11306f32e7eSjoerg } while (isdigit(LastChar) || LastChar == '.');
11406f32e7eSjoerg
11506f32e7eSjoerg NumVal = strtod(NumStr.c_str(), nullptr);
11606f32e7eSjoerg return tok_number;
11706f32e7eSjoerg }
11806f32e7eSjoerg
11906f32e7eSjoerg if (LastChar == '#') {
12006f32e7eSjoerg // Comment until end of line.
12106f32e7eSjoerg do
12206f32e7eSjoerg LastChar = getchar();
12306f32e7eSjoerg while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
12406f32e7eSjoerg
12506f32e7eSjoerg if (LastChar != EOF)
12606f32e7eSjoerg return gettok();
12706f32e7eSjoerg }
12806f32e7eSjoerg
12906f32e7eSjoerg // Check for end of file. Don't eat the EOF.
13006f32e7eSjoerg if (LastChar == EOF)
13106f32e7eSjoerg return tok_eof;
13206f32e7eSjoerg
13306f32e7eSjoerg // Otherwise, just return the character as its ascii value.
13406f32e7eSjoerg int ThisChar = LastChar;
13506f32e7eSjoerg LastChar = getchar();
13606f32e7eSjoerg return ThisChar;
13706f32e7eSjoerg }
13806f32e7eSjoerg
13906f32e7eSjoerg //===----------------------------------------------------------------------===//
14006f32e7eSjoerg // Abstract Syntax Tree (aka Parse Tree)
14106f32e7eSjoerg //===----------------------------------------------------------------------===//
14206f32e7eSjoerg
14306f32e7eSjoerg namespace {
14406f32e7eSjoerg
14506f32e7eSjoerg /// ExprAST - Base class for all expression nodes.
14606f32e7eSjoerg class ExprAST {
14706f32e7eSjoerg public:
14806f32e7eSjoerg virtual ~ExprAST() = default;
14906f32e7eSjoerg
15006f32e7eSjoerg virtual Value *codegen() = 0;
15106f32e7eSjoerg };
15206f32e7eSjoerg
15306f32e7eSjoerg /// NumberExprAST - Expression class for numeric literals like "1.0".
15406f32e7eSjoerg class NumberExprAST : public ExprAST {
15506f32e7eSjoerg double Val;
15606f32e7eSjoerg
15706f32e7eSjoerg public:
NumberExprAST(double Val)15806f32e7eSjoerg NumberExprAST(double Val) : Val(Val) {}
15906f32e7eSjoerg
16006f32e7eSjoerg Value *codegen() override;
16106f32e7eSjoerg };
16206f32e7eSjoerg
16306f32e7eSjoerg /// VariableExprAST - Expression class for referencing a variable, like "a".
16406f32e7eSjoerg class VariableExprAST : public ExprAST {
16506f32e7eSjoerg std::string Name;
16606f32e7eSjoerg
16706f32e7eSjoerg public:
VariableExprAST(const std::string & Name)16806f32e7eSjoerg VariableExprAST(const std::string &Name) : Name(Name) {}
16906f32e7eSjoerg
17006f32e7eSjoerg Value *codegen() override;
getName() const17106f32e7eSjoerg const std::string &getName() const { return Name; }
17206f32e7eSjoerg };
17306f32e7eSjoerg
17406f32e7eSjoerg /// UnaryExprAST - Expression class for a unary operator.
17506f32e7eSjoerg class UnaryExprAST : public ExprAST {
17606f32e7eSjoerg char Opcode;
17706f32e7eSjoerg std::unique_ptr<ExprAST> Operand;
17806f32e7eSjoerg
17906f32e7eSjoerg public:
UnaryExprAST(char Opcode,std::unique_ptr<ExprAST> Operand)18006f32e7eSjoerg UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
18106f32e7eSjoerg : Opcode(Opcode), Operand(std::move(Operand)) {}
18206f32e7eSjoerg
18306f32e7eSjoerg Value *codegen() override;
18406f32e7eSjoerg };
18506f32e7eSjoerg
18606f32e7eSjoerg /// BinaryExprAST - Expression class for a binary operator.
18706f32e7eSjoerg class BinaryExprAST : public ExprAST {
18806f32e7eSjoerg char Op;
18906f32e7eSjoerg std::unique_ptr<ExprAST> LHS, RHS;
19006f32e7eSjoerg
19106f32e7eSjoerg public:
BinaryExprAST(char Op,std::unique_ptr<ExprAST> LHS,std::unique_ptr<ExprAST> RHS)19206f32e7eSjoerg BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
19306f32e7eSjoerg std::unique_ptr<ExprAST> RHS)
19406f32e7eSjoerg : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
19506f32e7eSjoerg
19606f32e7eSjoerg Value *codegen() override;
19706f32e7eSjoerg };
19806f32e7eSjoerg
19906f32e7eSjoerg /// CallExprAST - Expression class for function calls.
20006f32e7eSjoerg class CallExprAST : public ExprAST {
20106f32e7eSjoerg std::string Callee;
20206f32e7eSjoerg std::vector<std::unique_ptr<ExprAST>> Args;
20306f32e7eSjoerg
20406f32e7eSjoerg public:
CallExprAST(const std::string & Callee,std::vector<std::unique_ptr<ExprAST>> Args)20506f32e7eSjoerg CallExprAST(const std::string &Callee,
20606f32e7eSjoerg std::vector<std::unique_ptr<ExprAST>> Args)
20706f32e7eSjoerg : Callee(Callee), Args(std::move(Args)) {}
20806f32e7eSjoerg
20906f32e7eSjoerg Value *codegen() override;
21006f32e7eSjoerg };
21106f32e7eSjoerg
21206f32e7eSjoerg /// IfExprAST - Expression class for if/then/else.
21306f32e7eSjoerg class IfExprAST : public ExprAST {
21406f32e7eSjoerg std::unique_ptr<ExprAST> Cond, Then, Else;
21506f32e7eSjoerg
21606f32e7eSjoerg public:
IfExprAST(std::unique_ptr<ExprAST> Cond,std::unique_ptr<ExprAST> Then,std::unique_ptr<ExprAST> Else)21706f32e7eSjoerg IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
21806f32e7eSjoerg std::unique_ptr<ExprAST> Else)
21906f32e7eSjoerg : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
22006f32e7eSjoerg
22106f32e7eSjoerg Value *codegen() override;
22206f32e7eSjoerg };
22306f32e7eSjoerg
22406f32e7eSjoerg /// ForExprAST - Expression class for for/in.
22506f32e7eSjoerg class ForExprAST : public ExprAST {
22606f32e7eSjoerg std::string VarName;
22706f32e7eSjoerg std::unique_ptr<ExprAST> Start, End, Step, Body;
22806f32e7eSjoerg
22906f32e7eSjoerg public:
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)23006f32e7eSjoerg ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
23106f32e7eSjoerg std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
23206f32e7eSjoerg std::unique_ptr<ExprAST> Body)
23306f32e7eSjoerg : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
23406f32e7eSjoerg Step(std::move(Step)), Body(std::move(Body)) {}
23506f32e7eSjoerg
23606f32e7eSjoerg Value *codegen() override;
23706f32e7eSjoerg };
23806f32e7eSjoerg
23906f32e7eSjoerg /// VarExprAST - Expression class for var/in
24006f32e7eSjoerg class VarExprAST : public ExprAST {
24106f32e7eSjoerg std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
24206f32e7eSjoerg std::unique_ptr<ExprAST> Body;
24306f32e7eSjoerg
24406f32e7eSjoerg public:
VarExprAST(std::vector<std::pair<std::string,std::unique_ptr<ExprAST>>> VarNames,std::unique_ptr<ExprAST> Body)24506f32e7eSjoerg VarExprAST(
24606f32e7eSjoerg std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
24706f32e7eSjoerg std::unique_ptr<ExprAST> Body)
24806f32e7eSjoerg : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
24906f32e7eSjoerg
25006f32e7eSjoerg Value *codegen() override;
25106f32e7eSjoerg };
25206f32e7eSjoerg
25306f32e7eSjoerg /// PrototypeAST - This class represents the "prototype" for a function,
25406f32e7eSjoerg /// which captures its name, and its argument names (thus implicitly the number
25506f32e7eSjoerg /// of arguments the function takes), as well as if it is an operator.
25606f32e7eSjoerg class PrototypeAST {
25706f32e7eSjoerg std::string Name;
25806f32e7eSjoerg std::vector<std::string> Args;
25906f32e7eSjoerg bool IsOperator;
26006f32e7eSjoerg unsigned Precedence; // Precedence if a binary op.
26106f32e7eSjoerg
26206f32e7eSjoerg public:
PrototypeAST(const std::string & Name,std::vector<std::string> Args,bool IsOperator=false,unsigned Prec=0)26306f32e7eSjoerg PrototypeAST(const std::string &Name, std::vector<std::string> Args,
26406f32e7eSjoerg bool IsOperator = false, unsigned Prec = 0)
26506f32e7eSjoerg : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
26606f32e7eSjoerg Precedence(Prec) {}
26706f32e7eSjoerg
26806f32e7eSjoerg Function *codegen();
getName() const26906f32e7eSjoerg const std::string &getName() const { return Name; }
27006f32e7eSjoerg
isUnaryOp() const27106f32e7eSjoerg bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
isBinaryOp() const27206f32e7eSjoerg bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
27306f32e7eSjoerg
getOperatorName() const27406f32e7eSjoerg char getOperatorName() const {
27506f32e7eSjoerg assert(isUnaryOp() || isBinaryOp());
27606f32e7eSjoerg return Name[Name.size() - 1];
27706f32e7eSjoerg }
27806f32e7eSjoerg
getBinaryPrecedence() const27906f32e7eSjoerg unsigned getBinaryPrecedence() const { return Precedence; }
28006f32e7eSjoerg };
28106f32e7eSjoerg
28206f32e7eSjoerg /// FunctionAST - This class represents a function definition itself.
28306f32e7eSjoerg class FunctionAST {
28406f32e7eSjoerg std::unique_ptr<PrototypeAST> Proto;
28506f32e7eSjoerg std::unique_ptr<ExprAST> Body;
28606f32e7eSjoerg
28706f32e7eSjoerg public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,std::unique_ptr<ExprAST> Body)28806f32e7eSjoerg FunctionAST(std::unique_ptr<PrototypeAST> Proto,
28906f32e7eSjoerg std::unique_ptr<ExprAST> Body)
29006f32e7eSjoerg : Proto(std::move(Proto)), Body(std::move(Body)) {}
29106f32e7eSjoerg
29206f32e7eSjoerg Function *codegen();
29306f32e7eSjoerg };
29406f32e7eSjoerg
29506f32e7eSjoerg } // end anonymous namespace
29606f32e7eSjoerg
29706f32e7eSjoerg //===----------------------------------------------------------------------===//
29806f32e7eSjoerg // Parser
29906f32e7eSjoerg //===----------------------------------------------------------------------===//
30006f32e7eSjoerg
30106f32e7eSjoerg /// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current
30206f32e7eSjoerg /// token the parser is looking at. getNextToken reads another token from the
30306f32e7eSjoerg /// lexer and updates CurTok with its results.
30406f32e7eSjoerg static int CurTok;
getNextToken()30506f32e7eSjoerg static int getNextToken() { return CurTok = gettok(); }
30606f32e7eSjoerg
30706f32e7eSjoerg /// BinopPrecedence - This holds the precedence for each binary operator that is
30806f32e7eSjoerg /// defined.
30906f32e7eSjoerg static std::map<char, int> BinopPrecedence;
31006f32e7eSjoerg
31106f32e7eSjoerg /// GetTokPrecedence - Get the precedence of the pending binary operator token.
GetTokPrecedence()31206f32e7eSjoerg static int GetTokPrecedence() {
31306f32e7eSjoerg if (!isascii(CurTok))
31406f32e7eSjoerg return -1;
31506f32e7eSjoerg
31606f32e7eSjoerg // Make sure it's a declared binop.
31706f32e7eSjoerg int TokPrec = BinopPrecedence[CurTok];
31806f32e7eSjoerg if (TokPrec <= 0)
31906f32e7eSjoerg return -1;
32006f32e7eSjoerg return TokPrec;
32106f32e7eSjoerg }
32206f32e7eSjoerg
32306f32e7eSjoerg /// LogError* - These are little helper functions for error handling.
LogError(const char * Str)32406f32e7eSjoerg std::unique_ptr<ExprAST> LogError(const char *Str) {
32506f32e7eSjoerg fprintf(stderr, "Error: %s\n", Str);
32606f32e7eSjoerg return nullptr;
32706f32e7eSjoerg }
32806f32e7eSjoerg
LogErrorP(const char * Str)32906f32e7eSjoerg std::unique_ptr<PrototypeAST> LogErrorP(const char *Str) {
33006f32e7eSjoerg LogError(Str);
33106f32e7eSjoerg return nullptr;
33206f32e7eSjoerg }
33306f32e7eSjoerg
33406f32e7eSjoerg static std::unique_ptr<ExprAST> ParseExpression();
33506f32e7eSjoerg
33606f32e7eSjoerg /// numberexpr ::= number
ParseNumberExpr()33706f32e7eSjoerg static std::unique_ptr<ExprAST> ParseNumberExpr() {
33806f32e7eSjoerg auto Result = std::make_unique<NumberExprAST>(NumVal);
33906f32e7eSjoerg getNextToken(); // consume the number
34006f32e7eSjoerg return std::move(Result);
34106f32e7eSjoerg }
34206f32e7eSjoerg
34306f32e7eSjoerg /// parenexpr ::= '(' expression ')'
ParseParenExpr()34406f32e7eSjoerg static std::unique_ptr<ExprAST> ParseParenExpr() {
34506f32e7eSjoerg getNextToken(); // eat (.
34606f32e7eSjoerg auto V = ParseExpression();
34706f32e7eSjoerg if (!V)
34806f32e7eSjoerg return nullptr;
34906f32e7eSjoerg
35006f32e7eSjoerg if (CurTok != ')')
35106f32e7eSjoerg return LogError("expected ')'");
35206f32e7eSjoerg getNextToken(); // eat ).
35306f32e7eSjoerg return V;
35406f32e7eSjoerg }
35506f32e7eSjoerg
35606f32e7eSjoerg /// identifierexpr
35706f32e7eSjoerg /// ::= identifier
35806f32e7eSjoerg /// ::= identifier '(' expression* ')'
ParseIdentifierExpr()35906f32e7eSjoerg static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
36006f32e7eSjoerg std::string IdName = IdentifierStr;
36106f32e7eSjoerg
36206f32e7eSjoerg getNextToken(); // eat identifier.
36306f32e7eSjoerg
36406f32e7eSjoerg if (CurTok != '(') // Simple variable ref.
36506f32e7eSjoerg return std::make_unique<VariableExprAST>(IdName);
36606f32e7eSjoerg
36706f32e7eSjoerg // Call.
36806f32e7eSjoerg getNextToken(); // eat (
36906f32e7eSjoerg std::vector<std::unique_ptr<ExprAST>> Args;
37006f32e7eSjoerg if (CurTok != ')') {
37106f32e7eSjoerg while (true) {
37206f32e7eSjoerg if (auto Arg = ParseExpression())
37306f32e7eSjoerg Args.push_back(std::move(Arg));
37406f32e7eSjoerg else
37506f32e7eSjoerg return nullptr;
37606f32e7eSjoerg
37706f32e7eSjoerg if (CurTok == ')')
37806f32e7eSjoerg break;
37906f32e7eSjoerg
38006f32e7eSjoerg if (CurTok != ',')
38106f32e7eSjoerg return LogError("Expected ')' or ',' in argument list");
38206f32e7eSjoerg getNextToken();
38306f32e7eSjoerg }
38406f32e7eSjoerg }
38506f32e7eSjoerg
38606f32e7eSjoerg // Eat the ')'.
38706f32e7eSjoerg getNextToken();
38806f32e7eSjoerg
38906f32e7eSjoerg return std::make_unique<CallExprAST>(IdName, std::move(Args));
39006f32e7eSjoerg }
39106f32e7eSjoerg
39206f32e7eSjoerg /// ifexpr ::= 'if' expression 'then' expression 'else' expression
ParseIfExpr()39306f32e7eSjoerg static std::unique_ptr<ExprAST> ParseIfExpr() {
39406f32e7eSjoerg getNextToken(); // eat the if.
39506f32e7eSjoerg
39606f32e7eSjoerg // condition.
39706f32e7eSjoerg auto Cond = ParseExpression();
39806f32e7eSjoerg if (!Cond)
39906f32e7eSjoerg return nullptr;
40006f32e7eSjoerg
40106f32e7eSjoerg if (CurTok != tok_then)
40206f32e7eSjoerg return LogError("expected then");
40306f32e7eSjoerg getNextToken(); // eat the then
40406f32e7eSjoerg
40506f32e7eSjoerg auto Then = ParseExpression();
40606f32e7eSjoerg if (!Then)
40706f32e7eSjoerg return nullptr;
40806f32e7eSjoerg
40906f32e7eSjoerg if (CurTok != tok_else)
41006f32e7eSjoerg return LogError("expected else");
41106f32e7eSjoerg
41206f32e7eSjoerg getNextToken();
41306f32e7eSjoerg
41406f32e7eSjoerg auto Else = ParseExpression();
41506f32e7eSjoerg if (!Else)
41606f32e7eSjoerg return nullptr;
41706f32e7eSjoerg
41806f32e7eSjoerg return std::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
41906f32e7eSjoerg std::move(Else));
42006f32e7eSjoerg }
42106f32e7eSjoerg
42206f32e7eSjoerg /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
ParseForExpr()42306f32e7eSjoerg static std::unique_ptr<ExprAST> ParseForExpr() {
42406f32e7eSjoerg getNextToken(); // eat the for.
42506f32e7eSjoerg
42606f32e7eSjoerg if (CurTok != tok_identifier)
42706f32e7eSjoerg return LogError("expected identifier after for");
42806f32e7eSjoerg
42906f32e7eSjoerg std::string IdName = IdentifierStr;
43006f32e7eSjoerg getNextToken(); // eat identifier.
43106f32e7eSjoerg
43206f32e7eSjoerg if (CurTok != '=')
43306f32e7eSjoerg return LogError("expected '=' after for");
43406f32e7eSjoerg getNextToken(); // eat '='.
43506f32e7eSjoerg
43606f32e7eSjoerg auto Start = ParseExpression();
43706f32e7eSjoerg if (!Start)
43806f32e7eSjoerg return nullptr;
43906f32e7eSjoerg if (CurTok != ',')
44006f32e7eSjoerg return LogError("expected ',' after for start value");
44106f32e7eSjoerg getNextToken();
44206f32e7eSjoerg
44306f32e7eSjoerg auto End = ParseExpression();
44406f32e7eSjoerg if (!End)
44506f32e7eSjoerg return nullptr;
44606f32e7eSjoerg
44706f32e7eSjoerg // The step value is optional.
44806f32e7eSjoerg std::unique_ptr<ExprAST> Step;
44906f32e7eSjoerg if (CurTok == ',') {
45006f32e7eSjoerg getNextToken();
45106f32e7eSjoerg Step = ParseExpression();
45206f32e7eSjoerg if (!Step)
45306f32e7eSjoerg return nullptr;
45406f32e7eSjoerg }
45506f32e7eSjoerg
45606f32e7eSjoerg if (CurTok != tok_in)
45706f32e7eSjoerg return LogError("expected 'in' after for");
45806f32e7eSjoerg getNextToken(); // eat 'in'.
45906f32e7eSjoerg
46006f32e7eSjoerg auto Body = ParseExpression();
46106f32e7eSjoerg if (!Body)
46206f32e7eSjoerg return nullptr;
46306f32e7eSjoerg
46406f32e7eSjoerg return std::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
46506f32e7eSjoerg std::move(Step), std::move(Body));
46606f32e7eSjoerg }
46706f32e7eSjoerg
46806f32e7eSjoerg /// varexpr ::= 'var' identifier ('=' expression)?
46906f32e7eSjoerg // (',' identifier ('=' expression)?)* 'in' expression
ParseVarExpr()47006f32e7eSjoerg static std::unique_ptr<ExprAST> ParseVarExpr() {
47106f32e7eSjoerg getNextToken(); // eat the var.
47206f32e7eSjoerg
47306f32e7eSjoerg std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
47406f32e7eSjoerg
47506f32e7eSjoerg // At least one variable name is required.
47606f32e7eSjoerg if (CurTok != tok_identifier)
47706f32e7eSjoerg return LogError("expected identifier after var");
47806f32e7eSjoerg
47906f32e7eSjoerg while (true) {
48006f32e7eSjoerg std::string Name = IdentifierStr;
48106f32e7eSjoerg getNextToken(); // eat identifier.
48206f32e7eSjoerg
48306f32e7eSjoerg // Read the optional initializer.
48406f32e7eSjoerg std::unique_ptr<ExprAST> Init = nullptr;
48506f32e7eSjoerg if (CurTok == '=') {
48606f32e7eSjoerg getNextToken(); // eat the '='.
48706f32e7eSjoerg
48806f32e7eSjoerg Init = ParseExpression();
48906f32e7eSjoerg if (!Init)
49006f32e7eSjoerg return nullptr;
49106f32e7eSjoerg }
49206f32e7eSjoerg
49306f32e7eSjoerg VarNames.push_back(std::make_pair(Name, std::move(Init)));
49406f32e7eSjoerg
49506f32e7eSjoerg // End of var list, exit loop.
49606f32e7eSjoerg if (CurTok != ',')
49706f32e7eSjoerg break;
49806f32e7eSjoerg getNextToken(); // eat the ','.
49906f32e7eSjoerg
50006f32e7eSjoerg if (CurTok != tok_identifier)
50106f32e7eSjoerg return LogError("expected identifier list after var");
50206f32e7eSjoerg }
50306f32e7eSjoerg
50406f32e7eSjoerg // At this point, we have to have 'in'.
50506f32e7eSjoerg if (CurTok != tok_in)
50606f32e7eSjoerg return LogError("expected 'in' keyword after 'var'");
50706f32e7eSjoerg getNextToken(); // eat 'in'.
50806f32e7eSjoerg
50906f32e7eSjoerg auto Body = ParseExpression();
51006f32e7eSjoerg if (!Body)
51106f32e7eSjoerg return nullptr;
51206f32e7eSjoerg
51306f32e7eSjoerg return std::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
51406f32e7eSjoerg }
51506f32e7eSjoerg
51606f32e7eSjoerg /// primary
51706f32e7eSjoerg /// ::= identifierexpr
51806f32e7eSjoerg /// ::= numberexpr
51906f32e7eSjoerg /// ::= parenexpr
52006f32e7eSjoerg /// ::= ifexpr
52106f32e7eSjoerg /// ::= forexpr
52206f32e7eSjoerg /// ::= varexpr
ParsePrimary()52306f32e7eSjoerg static std::unique_ptr<ExprAST> ParsePrimary() {
52406f32e7eSjoerg switch (CurTok) {
52506f32e7eSjoerg default:
52606f32e7eSjoerg return LogError("unknown token when expecting an expression");
52706f32e7eSjoerg case tok_identifier:
52806f32e7eSjoerg return ParseIdentifierExpr();
52906f32e7eSjoerg case tok_number:
53006f32e7eSjoerg return ParseNumberExpr();
53106f32e7eSjoerg case '(':
53206f32e7eSjoerg return ParseParenExpr();
53306f32e7eSjoerg case tok_if:
53406f32e7eSjoerg return ParseIfExpr();
53506f32e7eSjoerg case tok_for:
53606f32e7eSjoerg return ParseForExpr();
53706f32e7eSjoerg case tok_var:
53806f32e7eSjoerg return ParseVarExpr();
53906f32e7eSjoerg }
54006f32e7eSjoerg }
54106f32e7eSjoerg
54206f32e7eSjoerg /// unary
54306f32e7eSjoerg /// ::= primary
54406f32e7eSjoerg /// ::= '!' unary
ParseUnary()54506f32e7eSjoerg static std::unique_ptr<ExprAST> ParseUnary() {
54606f32e7eSjoerg // If the current token is not an operator, it must be a primary expr.
54706f32e7eSjoerg if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
54806f32e7eSjoerg return ParsePrimary();
54906f32e7eSjoerg
55006f32e7eSjoerg // If this is a unary operator, read it.
55106f32e7eSjoerg int Opc = CurTok;
55206f32e7eSjoerg getNextToken();
55306f32e7eSjoerg if (auto Operand = ParseUnary())
55406f32e7eSjoerg return std::make_unique<UnaryExprAST>(Opc, std::move(Operand));
55506f32e7eSjoerg return nullptr;
55606f32e7eSjoerg }
55706f32e7eSjoerg
55806f32e7eSjoerg /// binoprhs
55906f32e7eSjoerg /// ::= ('+' unary)*
ParseBinOpRHS(int ExprPrec,std::unique_ptr<ExprAST> LHS)56006f32e7eSjoerg static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
56106f32e7eSjoerg std::unique_ptr<ExprAST> LHS) {
56206f32e7eSjoerg // If this is a binop, find its precedence.
56306f32e7eSjoerg while (true) {
56406f32e7eSjoerg int TokPrec = GetTokPrecedence();
56506f32e7eSjoerg
56606f32e7eSjoerg // If this is a binop that binds at least as tightly as the current binop,
56706f32e7eSjoerg // consume it, otherwise we are done.
56806f32e7eSjoerg if (TokPrec < ExprPrec)
56906f32e7eSjoerg return LHS;
57006f32e7eSjoerg
57106f32e7eSjoerg // Okay, we know this is a binop.
57206f32e7eSjoerg int BinOp = CurTok;
57306f32e7eSjoerg getNextToken(); // eat binop
57406f32e7eSjoerg
57506f32e7eSjoerg // Parse the unary expression after the binary operator.
57606f32e7eSjoerg auto RHS = ParseUnary();
57706f32e7eSjoerg if (!RHS)
57806f32e7eSjoerg return nullptr;
57906f32e7eSjoerg
58006f32e7eSjoerg // If BinOp binds less tightly with RHS than the operator after RHS, let
58106f32e7eSjoerg // the pending operator take RHS as its LHS.
58206f32e7eSjoerg int NextPrec = GetTokPrecedence();
58306f32e7eSjoerg if (TokPrec < NextPrec) {
58406f32e7eSjoerg RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
58506f32e7eSjoerg if (!RHS)
58606f32e7eSjoerg return nullptr;
58706f32e7eSjoerg }
58806f32e7eSjoerg
58906f32e7eSjoerg // Merge LHS/RHS.
59006f32e7eSjoerg LHS =
59106f32e7eSjoerg std::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
59206f32e7eSjoerg }
59306f32e7eSjoerg }
59406f32e7eSjoerg
59506f32e7eSjoerg /// expression
59606f32e7eSjoerg /// ::= unary binoprhs
59706f32e7eSjoerg ///
ParseExpression()59806f32e7eSjoerg static std::unique_ptr<ExprAST> ParseExpression() {
59906f32e7eSjoerg auto LHS = ParseUnary();
60006f32e7eSjoerg if (!LHS)
60106f32e7eSjoerg return nullptr;
60206f32e7eSjoerg
60306f32e7eSjoerg return ParseBinOpRHS(0, std::move(LHS));
60406f32e7eSjoerg }
60506f32e7eSjoerg
60606f32e7eSjoerg /// prototype
60706f32e7eSjoerg /// ::= id '(' id* ')'
60806f32e7eSjoerg /// ::= binary LETTER number? (id, id)
60906f32e7eSjoerg /// ::= unary LETTER (id)
ParsePrototype()61006f32e7eSjoerg static std::unique_ptr<PrototypeAST> ParsePrototype() {
61106f32e7eSjoerg std::string FnName;
61206f32e7eSjoerg
61306f32e7eSjoerg unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
61406f32e7eSjoerg unsigned BinaryPrecedence = 30;
61506f32e7eSjoerg
61606f32e7eSjoerg switch (CurTok) {
61706f32e7eSjoerg default:
61806f32e7eSjoerg return LogErrorP("Expected function name in prototype");
61906f32e7eSjoerg case tok_identifier:
62006f32e7eSjoerg FnName = IdentifierStr;
62106f32e7eSjoerg Kind = 0;
62206f32e7eSjoerg getNextToken();
62306f32e7eSjoerg break;
62406f32e7eSjoerg case tok_unary:
62506f32e7eSjoerg getNextToken();
62606f32e7eSjoerg if (!isascii(CurTok))
62706f32e7eSjoerg return LogErrorP("Expected unary operator");
62806f32e7eSjoerg FnName = "unary";
62906f32e7eSjoerg FnName += (char)CurTok;
63006f32e7eSjoerg Kind = 1;
63106f32e7eSjoerg getNextToken();
63206f32e7eSjoerg break;
63306f32e7eSjoerg case tok_binary:
63406f32e7eSjoerg getNextToken();
63506f32e7eSjoerg if (!isascii(CurTok))
63606f32e7eSjoerg return LogErrorP("Expected binary operator");
63706f32e7eSjoerg FnName = "binary";
63806f32e7eSjoerg FnName += (char)CurTok;
63906f32e7eSjoerg Kind = 2;
64006f32e7eSjoerg getNextToken();
64106f32e7eSjoerg
64206f32e7eSjoerg // Read the precedence if present.
64306f32e7eSjoerg if (CurTok == tok_number) {
64406f32e7eSjoerg if (NumVal < 1 || NumVal > 100)
64506f32e7eSjoerg return LogErrorP("Invalid precedence: must be 1..100");
64606f32e7eSjoerg BinaryPrecedence = (unsigned)NumVal;
64706f32e7eSjoerg getNextToken();
64806f32e7eSjoerg }
64906f32e7eSjoerg break;
65006f32e7eSjoerg }
65106f32e7eSjoerg
65206f32e7eSjoerg if (CurTok != '(')
65306f32e7eSjoerg return LogErrorP("Expected '(' in prototype");
65406f32e7eSjoerg
65506f32e7eSjoerg std::vector<std::string> ArgNames;
65606f32e7eSjoerg while (getNextToken() == tok_identifier)
65706f32e7eSjoerg ArgNames.push_back(IdentifierStr);
65806f32e7eSjoerg if (CurTok != ')')
65906f32e7eSjoerg return LogErrorP("Expected ')' in prototype");
66006f32e7eSjoerg
66106f32e7eSjoerg // success.
66206f32e7eSjoerg getNextToken(); // eat ')'.
66306f32e7eSjoerg
66406f32e7eSjoerg // Verify right number of names for operator.
66506f32e7eSjoerg if (Kind && ArgNames.size() != Kind)
66606f32e7eSjoerg return LogErrorP("Invalid number of operands for operator");
66706f32e7eSjoerg
66806f32e7eSjoerg return std::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
66906f32e7eSjoerg BinaryPrecedence);
67006f32e7eSjoerg }
67106f32e7eSjoerg
67206f32e7eSjoerg /// definition ::= 'def' prototype expression
ParseDefinition()67306f32e7eSjoerg static std::unique_ptr<FunctionAST> ParseDefinition() {
67406f32e7eSjoerg getNextToken(); // eat def.
67506f32e7eSjoerg auto Proto = ParsePrototype();
67606f32e7eSjoerg if (!Proto)
67706f32e7eSjoerg return nullptr;
67806f32e7eSjoerg
67906f32e7eSjoerg if (auto E = ParseExpression())
68006f32e7eSjoerg return std::make_unique<FunctionAST>(std::move(Proto), std::move(E));
68106f32e7eSjoerg return nullptr;
68206f32e7eSjoerg }
68306f32e7eSjoerg
68406f32e7eSjoerg /// toplevelexpr ::= expression
ParseTopLevelExpr()68506f32e7eSjoerg static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
68606f32e7eSjoerg if (auto E = ParseExpression()) {
68706f32e7eSjoerg // Make an anonymous proto.
68806f32e7eSjoerg auto Proto = std::make_unique<PrototypeAST>("__anon_expr",
68906f32e7eSjoerg std::vector<std::string>());
69006f32e7eSjoerg return std::make_unique<FunctionAST>(std::move(Proto), std::move(E));
69106f32e7eSjoerg }
69206f32e7eSjoerg return nullptr;
69306f32e7eSjoerg }
69406f32e7eSjoerg
69506f32e7eSjoerg /// external ::= 'extern' prototype
ParseExtern()69606f32e7eSjoerg static std::unique_ptr<PrototypeAST> ParseExtern() {
69706f32e7eSjoerg getNextToken(); // eat extern.
69806f32e7eSjoerg return ParsePrototype();
69906f32e7eSjoerg }
70006f32e7eSjoerg
70106f32e7eSjoerg //===----------------------------------------------------------------------===//
70206f32e7eSjoerg // Code Generation
70306f32e7eSjoerg //===----------------------------------------------------------------------===//
70406f32e7eSjoerg
705*da58b97aSjoerg static std::unique_ptr<LLVMContext> TheContext;
70606f32e7eSjoerg static std::unique_ptr<Module> TheModule;
707*da58b97aSjoerg static std::unique_ptr<IRBuilder<>> Builder;
70806f32e7eSjoerg static std::map<std::string, AllocaInst *> NamedValues;
70906f32e7eSjoerg static std::map<std::string, std::unique_ptr<PrototypeAST>> FunctionProtos;
710*da58b97aSjoerg static ExitOnError ExitOnErr;
71106f32e7eSjoerg
LogErrorV(const char * Str)71206f32e7eSjoerg Value *LogErrorV(const char *Str) {
71306f32e7eSjoerg LogError(Str);
71406f32e7eSjoerg return nullptr;
71506f32e7eSjoerg }
71606f32e7eSjoerg
getFunction(std::string Name)71706f32e7eSjoerg Function *getFunction(std::string Name) {
71806f32e7eSjoerg // First, see if the function has already been added to the current module.
71906f32e7eSjoerg if (auto *F = TheModule->getFunction(Name))
72006f32e7eSjoerg return F;
72106f32e7eSjoerg
72206f32e7eSjoerg // If not, check whether we can codegen the declaration from some existing
72306f32e7eSjoerg // prototype.
72406f32e7eSjoerg auto FI = FunctionProtos.find(Name);
72506f32e7eSjoerg if (FI != FunctionProtos.end())
72606f32e7eSjoerg return FI->second->codegen();
72706f32e7eSjoerg
72806f32e7eSjoerg // If no existing prototype exists, return null.
72906f32e7eSjoerg return nullptr;
73006f32e7eSjoerg }
73106f32e7eSjoerg
73206f32e7eSjoerg /// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
73306f32e7eSjoerg /// the function. This is used for mutable variables etc.
CreateEntryBlockAlloca(Function * TheFunction,StringRef VarName)73406f32e7eSjoerg static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
735*da58b97aSjoerg StringRef VarName) {
73606f32e7eSjoerg IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
73706f32e7eSjoerg TheFunction->getEntryBlock().begin());
738*da58b97aSjoerg return TmpB.CreateAlloca(Type::getDoubleTy(*TheContext), nullptr, VarName);
73906f32e7eSjoerg }
74006f32e7eSjoerg
codegen()74106f32e7eSjoerg Value *NumberExprAST::codegen() {
742*da58b97aSjoerg return ConstantFP::get(*TheContext, APFloat(Val));
74306f32e7eSjoerg }
74406f32e7eSjoerg
codegen()74506f32e7eSjoerg Value *VariableExprAST::codegen() {
74606f32e7eSjoerg // Look this variable up in the function.
74706f32e7eSjoerg Value *V = NamedValues[Name];
74806f32e7eSjoerg if (!V)
74906f32e7eSjoerg return LogErrorV("Unknown variable name");
75006f32e7eSjoerg
75106f32e7eSjoerg // Load the value.
752*da58b97aSjoerg return Builder->CreateLoad(Type::getDoubleTy(*TheContext), V, Name.c_str());
75306f32e7eSjoerg }
75406f32e7eSjoerg
codegen()75506f32e7eSjoerg Value *UnaryExprAST::codegen() {
75606f32e7eSjoerg Value *OperandV = Operand->codegen();
75706f32e7eSjoerg if (!OperandV)
75806f32e7eSjoerg return nullptr;
75906f32e7eSjoerg
76006f32e7eSjoerg Function *F = getFunction(std::string("unary") + Opcode);
76106f32e7eSjoerg if (!F)
76206f32e7eSjoerg return LogErrorV("Unknown unary operator");
76306f32e7eSjoerg
764*da58b97aSjoerg return Builder->CreateCall(F, OperandV, "unop");
76506f32e7eSjoerg }
76606f32e7eSjoerg
codegen()76706f32e7eSjoerg Value *BinaryExprAST::codegen() {
76806f32e7eSjoerg // Special case '=' because we don't want to emit the LHS as an expression.
76906f32e7eSjoerg if (Op == '=') {
77006f32e7eSjoerg // Assignment requires the LHS to be an identifier.
77106f32e7eSjoerg // This assume we're building without RTTI because LLVM builds that way by
77206f32e7eSjoerg // default. If you build LLVM with RTTI this can be changed to a
77306f32e7eSjoerg // dynamic_cast for automatic error checking.
77406f32e7eSjoerg VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
77506f32e7eSjoerg if (!LHSE)
77606f32e7eSjoerg return LogErrorV("destination of '=' must be a variable");
77706f32e7eSjoerg // Codegen the RHS.
77806f32e7eSjoerg Value *Val = RHS->codegen();
77906f32e7eSjoerg if (!Val)
78006f32e7eSjoerg return nullptr;
78106f32e7eSjoerg
78206f32e7eSjoerg // Look up the name.
78306f32e7eSjoerg Value *Variable = NamedValues[LHSE->getName()];
78406f32e7eSjoerg if (!Variable)
78506f32e7eSjoerg return LogErrorV("Unknown variable name");
78606f32e7eSjoerg
787*da58b97aSjoerg Builder->CreateStore(Val, Variable);
78806f32e7eSjoerg return Val;
78906f32e7eSjoerg }
79006f32e7eSjoerg
79106f32e7eSjoerg Value *L = LHS->codegen();
79206f32e7eSjoerg Value *R = RHS->codegen();
79306f32e7eSjoerg if (!L || !R)
79406f32e7eSjoerg return nullptr;
79506f32e7eSjoerg
79606f32e7eSjoerg switch (Op) {
79706f32e7eSjoerg case '+':
798*da58b97aSjoerg return Builder->CreateFAdd(L, R, "addtmp");
79906f32e7eSjoerg case '-':
800*da58b97aSjoerg return Builder->CreateFSub(L, R, "subtmp");
80106f32e7eSjoerg case '*':
802*da58b97aSjoerg return Builder->CreateFMul(L, R, "multmp");
80306f32e7eSjoerg case '<':
804*da58b97aSjoerg L = Builder->CreateFCmpULT(L, R, "cmptmp");
80506f32e7eSjoerg // Convert bool 0/1 to double 0.0 or 1.0
806*da58b97aSjoerg return Builder->CreateUIToFP(L, Type::getDoubleTy(*TheContext), "booltmp");
80706f32e7eSjoerg default:
80806f32e7eSjoerg break;
80906f32e7eSjoerg }
81006f32e7eSjoerg
81106f32e7eSjoerg // If it wasn't a builtin binary operator, it must be a user defined one. Emit
81206f32e7eSjoerg // a call to it.
81306f32e7eSjoerg Function *F = getFunction(std::string("binary") + Op);
81406f32e7eSjoerg assert(F && "binary operator not found!");
81506f32e7eSjoerg
81606f32e7eSjoerg Value *Ops[] = {L, R};
817*da58b97aSjoerg return Builder->CreateCall(F, Ops, "binop");
81806f32e7eSjoerg }
81906f32e7eSjoerg
codegen()82006f32e7eSjoerg Value *CallExprAST::codegen() {
82106f32e7eSjoerg // Look up the name in the global module table.
82206f32e7eSjoerg Function *CalleeF = getFunction(Callee);
82306f32e7eSjoerg if (!CalleeF)
82406f32e7eSjoerg return LogErrorV("Unknown function referenced");
82506f32e7eSjoerg
82606f32e7eSjoerg // If argument mismatch error.
82706f32e7eSjoerg if (CalleeF->arg_size() != Args.size())
82806f32e7eSjoerg return LogErrorV("Incorrect # arguments passed");
82906f32e7eSjoerg
83006f32e7eSjoerg std::vector<Value *> ArgsV;
83106f32e7eSjoerg for (unsigned i = 0, e = Args.size(); i != e; ++i) {
83206f32e7eSjoerg ArgsV.push_back(Args[i]->codegen());
83306f32e7eSjoerg if (!ArgsV.back())
83406f32e7eSjoerg return nullptr;
83506f32e7eSjoerg }
83606f32e7eSjoerg
837*da58b97aSjoerg return Builder->CreateCall(CalleeF, ArgsV, "calltmp");
83806f32e7eSjoerg }
83906f32e7eSjoerg
codegen()84006f32e7eSjoerg Value *IfExprAST::codegen() {
84106f32e7eSjoerg Value *CondV = Cond->codegen();
84206f32e7eSjoerg if (!CondV)
84306f32e7eSjoerg return nullptr;
84406f32e7eSjoerg
84506f32e7eSjoerg // Convert condition to a bool by comparing non-equal to 0.0.
846*da58b97aSjoerg CondV = Builder->CreateFCmpONE(
847*da58b97aSjoerg CondV, ConstantFP::get(*TheContext, APFloat(0.0)), "ifcond");
84806f32e7eSjoerg
849*da58b97aSjoerg Function *TheFunction = Builder->GetInsertBlock()->getParent();
85006f32e7eSjoerg
85106f32e7eSjoerg // Create blocks for the then and else cases. Insert the 'then' block at the
85206f32e7eSjoerg // end of the function.
853*da58b97aSjoerg BasicBlock *ThenBB = BasicBlock::Create(*TheContext, "then", TheFunction);
854*da58b97aSjoerg BasicBlock *ElseBB = BasicBlock::Create(*TheContext, "else");
855*da58b97aSjoerg BasicBlock *MergeBB = BasicBlock::Create(*TheContext, "ifcont");
85606f32e7eSjoerg
857*da58b97aSjoerg Builder->CreateCondBr(CondV, ThenBB, ElseBB);
85806f32e7eSjoerg
85906f32e7eSjoerg // Emit then value.
860*da58b97aSjoerg Builder->SetInsertPoint(ThenBB);
86106f32e7eSjoerg
86206f32e7eSjoerg Value *ThenV = Then->codegen();
86306f32e7eSjoerg if (!ThenV)
86406f32e7eSjoerg return nullptr;
86506f32e7eSjoerg
866*da58b97aSjoerg Builder->CreateBr(MergeBB);
86706f32e7eSjoerg // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
868*da58b97aSjoerg ThenBB = Builder->GetInsertBlock();
86906f32e7eSjoerg
87006f32e7eSjoerg // Emit else block.
87106f32e7eSjoerg TheFunction->getBasicBlockList().push_back(ElseBB);
872*da58b97aSjoerg Builder->SetInsertPoint(ElseBB);
87306f32e7eSjoerg
87406f32e7eSjoerg Value *ElseV = Else->codegen();
87506f32e7eSjoerg if (!ElseV)
87606f32e7eSjoerg return nullptr;
87706f32e7eSjoerg
878*da58b97aSjoerg Builder->CreateBr(MergeBB);
87906f32e7eSjoerg // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
880*da58b97aSjoerg ElseBB = Builder->GetInsertBlock();
88106f32e7eSjoerg
88206f32e7eSjoerg // Emit merge block.
88306f32e7eSjoerg TheFunction->getBasicBlockList().push_back(MergeBB);
884*da58b97aSjoerg Builder->SetInsertPoint(MergeBB);
885*da58b97aSjoerg PHINode *PN = Builder->CreatePHI(Type::getDoubleTy(*TheContext), 2, "iftmp");
88606f32e7eSjoerg
88706f32e7eSjoerg PN->addIncoming(ThenV, ThenBB);
88806f32e7eSjoerg PN->addIncoming(ElseV, ElseBB);
88906f32e7eSjoerg return PN;
89006f32e7eSjoerg }
89106f32e7eSjoerg
89206f32e7eSjoerg // Output for-loop as:
89306f32e7eSjoerg // var = alloca double
89406f32e7eSjoerg // ...
89506f32e7eSjoerg // start = startexpr
89606f32e7eSjoerg // store start -> var
89706f32e7eSjoerg // goto loop
89806f32e7eSjoerg // loop:
89906f32e7eSjoerg // ...
90006f32e7eSjoerg // bodyexpr
90106f32e7eSjoerg // ...
90206f32e7eSjoerg // loopend:
90306f32e7eSjoerg // step = stepexpr
90406f32e7eSjoerg // endcond = endexpr
90506f32e7eSjoerg //
90606f32e7eSjoerg // curvar = load var
90706f32e7eSjoerg // nextvar = curvar + step
90806f32e7eSjoerg // store nextvar -> var
90906f32e7eSjoerg // br endcond, loop, endloop
91006f32e7eSjoerg // outloop:
codegen()91106f32e7eSjoerg Value *ForExprAST::codegen() {
912*da58b97aSjoerg Function *TheFunction = Builder->GetInsertBlock()->getParent();
91306f32e7eSjoerg
91406f32e7eSjoerg // Create an alloca for the variable in the entry block.
91506f32e7eSjoerg AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
91606f32e7eSjoerg
91706f32e7eSjoerg // Emit the start code first, without 'variable' in scope.
91806f32e7eSjoerg Value *StartVal = Start->codegen();
91906f32e7eSjoerg if (!StartVal)
92006f32e7eSjoerg return nullptr;
92106f32e7eSjoerg
92206f32e7eSjoerg // Store the value into the alloca.
923*da58b97aSjoerg Builder->CreateStore(StartVal, Alloca);
92406f32e7eSjoerg
92506f32e7eSjoerg // Make the new basic block for the loop header, inserting after current
92606f32e7eSjoerg // block.
927*da58b97aSjoerg BasicBlock *LoopBB = BasicBlock::Create(*TheContext, "loop", TheFunction);
92806f32e7eSjoerg
92906f32e7eSjoerg // Insert an explicit fall through from the current block to the LoopBB.
930*da58b97aSjoerg Builder->CreateBr(LoopBB);
93106f32e7eSjoerg
93206f32e7eSjoerg // Start insertion in LoopBB.
933*da58b97aSjoerg Builder->SetInsertPoint(LoopBB);
93406f32e7eSjoerg
93506f32e7eSjoerg // Within the loop, the variable is defined equal to the PHI node. If it
93606f32e7eSjoerg // shadows an existing variable, we have to restore it, so save it now.
93706f32e7eSjoerg AllocaInst *OldVal = NamedValues[VarName];
93806f32e7eSjoerg NamedValues[VarName] = Alloca;
93906f32e7eSjoerg
94006f32e7eSjoerg // Emit the body of the loop. This, like any other expr, can change the
94106f32e7eSjoerg // current BB. Note that we ignore the value computed by the body, but don't
94206f32e7eSjoerg // allow an error.
94306f32e7eSjoerg if (!Body->codegen())
94406f32e7eSjoerg return nullptr;
94506f32e7eSjoerg
94606f32e7eSjoerg // Emit the step value.
94706f32e7eSjoerg Value *StepVal = nullptr;
94806f32e7eSjoerg if (Step) {
94906f32e7eSjoerg StepVal = Step->codegen();
95006f32e7eSjoerg if (!StepVal)
95106f32e7eSjoerg return nullptr;
95206f32e7eSjoerg } else {
95306f32e7eSjoerg // If not specified, use 1.0.
954*da58b97aSjoerg StepVal = ConstantFP::get(*TheContext, APFloat(1.0));
95506f32e7eSjoerg }
95606f32e7eSjoerg
95706f32e7eSjoerg // Compute the end condition.
95806f32e7eSjoerg Value *EndCond = End->codegen();
95906f32e7eSjoerg if (!EndCond)
96006f32e7eSjoerg return nullptr;
96106f32e7eSjoerg
96206f32e7eSjoerg // Reload, increment, and restore the alloca. This handles the case where
96306f32e7eSjoerg // the body of the loop mutates the variable.
964*da58b97aSjoerg Value *CurVar = Builder->CreateLoad(Type::getDoubleTy(*TheContext), Alloca,
965*da58b97aSjoerg VarName.c_str());
966*da58b97aSjoerg Value *NextVar = Builder->CreateFAdd(CurVar, StepVal, "nextvar");
967*da58b97aSjoerg Builder->CreateStore(NextVar, Alloca);
96806f32e7eSjoerg
96906f32e7eSjoerg // Convert condition to a bool by comparing non-equal to 0.0.
970*da58b97aSjoerg EndCond = Builder->CreateFCmpONE(
971*da58b97aSjoerg EndCond, ConstantFP::get(*TheContext, APFloat(0.0)), "loopcond");
97206f32e7eSjoerg
97306f32e7eSjoerg // Create the "after loop" block and insert it.
97406f32e7eSjoerg BasicBlock *AfterBB =
975*da58b97aSjoerg BasicBlock::Create(*TheContext, "afterloop", TheFunction);
97606f32e7eSjoerg
97706f32e7eSjoerg // Insert the conditional branch into the end of LoopEndBB.
978*da58b97aSjoerg Builder->CreateCondBr(EndCond, LoopBB, AfterBB);
97906f32e7eSjoerg
98006f32e7eSjoerg // Any new code will be inserted in AfterBB.
981*da58b97aSjoerg Builder->SetInsertPoint(AfterBB);
98206f32e7eSjoerg
98306f32e7eSjoerg // Restore the unshadowed variable.
98406f32e7eSjoerg if (OldVal)
98506f32e7eSjoerg NamedValues[VarName] = OldVal;
98606f32e7eSjoerg else
98706f32e7eSjoerg NamedValues.erase(VarName);
98806f32e7eSjoerg
98906f32e7eSjoerg // for expr always returns 0.0.
990*da58b97aSjoerg return Constant::getNullValue(Type::getDoubleTy(*TheContext));
99106f32e7eSjoerg }
99206f32e7eSjoerg
codegen()99306f32e7eSjoerg Value *VarExprAST::codegen() {
99406f32e7eSjoerg std::vector<AllocaInst *> OldBindings;
99506f32e7eSjoerg
996*da58b97aSjoerg Function *TheFunction = Builder->GetInsertBlock()->getParent();
99706f32e7eSjoerg
99806f32e7eSjoerg // Register all variables and emit their initializer.
99906f32e7eSjoerg for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
100006f32e7eSjoerg const std::string &VarName = VarNames[i].first;
100106f32e7eSjoerg ExprAST *Init = VarNames[i].second.get();
100206f32e7eSjoerg
100306f32e7eSjoerg // Emit the initializer before adding the variable to scope, this prevents
100406f32e7eSjoerg // the initializer from referencing the variable itself, and permits stuff
100506f32e7eSjoerg // like this:
100606f32e7eSjoerg // var a = 1 in
100706f32e7eSjoerg // var a = a in ... # refers to outer 'a'.
100806f32e7eSjoerg Value *InitVal;
100906f32e7eSjoerg if (Init) {
101006f32e7eSjoerg InitVal = Init->codegen();
101106f32e7eSjoerg if (!InitVal)
101206f32e7eSjoerg return nullptr;
101306f32e7eSjoerg } else { // If not specified, use 0.0.
1014*da58b97aSjoerg InitVal = ConstantFP::get(*TheContext, APFloat(0.0));
101506f32e7eSjoerg }
101606f32e7eSjoerg
101706f32e7eSjoerg AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
1018*da58b97aSjoerg Builder->CreateStore(InitVal, Alloca);
101906f32e7eSjoerg
102006f32e7eSjoerg // Remember the old variable binding so that we can restore the binding when
102106f32e7eSjoerg // we unrecurse.
102206f32e7eSjoerg OldBindings.push_back(NamedValues[VarName]);
102306f32e7eSjoerg
102406f32e7eSjoerg // Remember this binding.
102506f32e7eSjoerg NamedValues[VarName] = Alloca;
102606f32e7eSjoerg }
102706f32e7eSjoerg
102806f32e7eSjoerg // Codegen the body, now that all vars are in scope.
102906f32e7eSjoerg Value *BodyVal = Body->codegen();
103006f32e7eSjoerg if (!BodyVal)
103106f32e7eSjoerg return nullptr;
103206f32e7eSjoerg
103306f32e7eSjoerg // Pop all our variables from scope.
103406f32e7eSjoerg for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
103506f32e7eSjoerg NamedValues[VarNames[i].first] = OldBindings[i];
103606f32e7eSjoerg
103706f32e7eSjoerg // Return the body computation.
103806f32e7eSjoerg return BodyVal;
103906f32e7eSjoerg }
104006f32e7eSjoerg
codegen()104106f32e7eSjoerg Function *PrototypeAST::codegen() {
104206f32e7eSjoerg // Make the function type: double(double,double) etc.
1043*da58b97aSjoerg std::vector<Type *> Doubles(Args.size(), Type::getDoubleTy(*TheContext));
104406f32e7eSjoerg FunctionType *FT =
1045*da58b97aSjoerg FunctionType::get(Type::getDoubleTy(*TheContext), Doubles, false);
104606f32e7eSjoerg
104706f32e7eSjoerg Function *F =
104806f32e7eSjoerg Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
104906f32e7eSjoerg
105006f32e7eSjoerg // Set names for all arguments.
105106f32e7eSjoerg unsigned Idx = 0;
105206f32e7eSjoerg for (auto &Arg : F->args())
105306f32e7eSjoerg Arg.setName(Args[Idx++]);
105406f32e7eSjoerg
105506f32e7eSjoerg return F;
105606f32e7eSjoerg }
105706f32e7eSjoerg
codegen()105806f32e7eSjoerg Function *FunctionAST::codegen() {
105906f32e7eSjoerg // Transfer ownership of the prototype to the FunctionProtos map, but keep a
106006f32e7eSjoerg // reference to it for use below.
106106f32e7eSjoerg auto &P = *Proto;
106206f32e7eSjoerg FunctionProtos[Proto->getName()] = std::move(Proto);
106306f32e7eSjoerg Function *TheFunction = getFunction(P.getName());
106406f32e7eSjoerg if (!TheFunction)
106506f32e7eSjoerg return nullptr;
106606f32e7eSjoerg
106706f32e7eSjoerg // If this is an operator, install it.
106806f32e7eSjoerg if (P.isBinaryOp())
106906f32e7eSjoerg BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
107006f32e7eSjoerg
107106f32e7eSjoerg // Create a new basic block to start insertion into.
1072*da58b97aSjoerg BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", TheFunction);
1073*da58b97aSjoerg Builder->SetInsertPoint(BB);
107406f32e7eSjoerg
107506f32e7eSjoerg // Record the function arguments in the NamedValues map.
107606f32e7eSjoerg NamedValues.clear();
107706f32e7eSjoerg for (auto &Arg : TheFunction->args()) {
107806f32e7eSjoerg // Create an alloca for this variable.
107906f32e7eSjoerg AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, Arg.getName());
108006f32e7eSjoerg
108106f32e7eSjoerg // Store the initial value into the alloca.
1082*da58b97aSjoerg Builder->CreateStore(&Arg, Alloca);
108306f32e7eSjoerg
108406f32e7eSjoerg // Add arguments to variable symbol table.
1085*da58b97aSjoerg NamedValues[std::string(Arg.getName())] = Alloca;
108606f32e7eSjoerg }
108706f32e7eSjoerg
108806f32e7eSjoerg if (Value *RetVal = Body->codegen()) {
108906f32e7eSjoerg // Finish off the function.
1090*da58b97aSjoerg Builder->CreateRet(RetVal);
109106f32e7eSjoerg
109206f32e7eSjoerg // Validate the generated code, checking for consistency.
109306f32e7eSjoerg verifyFunction(*TheFunction);
109406f32e7eSjoerg
109506f32e7eSjoerg return TheFunction;
109606f32e7eSjoerg }
109706f32e7eSjoerg
109806f32e7eSjoerg // Error reading body, remove function.
109906f32e7eSjoerg TheFunction->eraseFromParent();
110006f32e7eSjoerg
110106f32e7eSjoerg if (P.isBinaryOp())
110206f32e7eSjoerg BinopPrecedence.erase(P.getOperatorName());
110306f32e7eSjoerg return nullptr;
110406f32e7eSjoerg }
110506f32e7eSjoerg
110606f32e7eSjoerg //===----------------------------------------------------------------------===//
110706f32e7eSjoerg // Top-Level parsing and JIT Driver
110806f32e7eSjoerg //===----------------------------------------------------------------------===//
110906f32e7eSjoerg
InitializeModuleAndPassManager()111006f32e7eSjoerg static void InitializeModuleAndPassManager() {
111106f32e7eSjoerg // Open a new module.
1112*da58b97aSjoerg TheContext = std::make_unique<LLVMContext>();
1113*da58b97aSjoerg TheModule = std::make_unique<Module>("my cool jit", *TheContext);
1114*da58b97aSjoerg
1115*da58b97aSjoerg // Create a new builder for the module.
1116*da58b97aSjoerg Builder = std::make_unique<IRBuilder<>>(*TheContext);
111706f32e7eSjoerg }
111806f32e7eSjoerg
HandleDefinition()111906f32e7eSjoerg static void HandleDefinition() {
112006f32e7eSjoerg if (auto FnAST = ParseDefinition()) {
112106f32e7eSjoerg if (auto *FnIR = FnAST->codegen()) {
112206f32e7eSjoerg fprintf(stderr, "Read function definition:");
112306f32e7eSjoerg FnIR->print(errs());
112406f32e7eSjoerg fprintf(stderr, "\n");
112506f32e7eSjoerg }
112606f32e7eSjoerg } else {
112706f32e7eSjoerg // Skip token for error recovery.
112806f32e7eSjoerg getNextToken();
112906f32e7eSjoerg }
113006f32e7eSjoerg }
113106f32e7eSjoerg
HandleExtern()113206f32e7eSjoerg static void HandleExtern() {
113306f32e7eSjoerg if (auto ProtoAST = ParseExtern()) {
113406f32e7eSjoerg if (auto *FnIR = ProtoAST->codegen()) {
113506f32e7eSjoerg fprintf(stderr, "Read extern: ");
113606f32e7eSjoerg FnIR->print(errs());
113706f32e7eSjoerg fprintf(stderr, "\n");
113806f32e7eSjoerg FunctionProtos[ProtoAST->getName()] = std::move(ProtoAST);
113906f32e7eSjoerg }
114006f32e7eSjoerg } else {
114106f32e7eSjoerg // Skip token for error recovery.
114206f32e7eSjoerg getNextToken();
114306f32e7eSjoerg }
114406f32e7eSjoerg }
114506f32e7eSjoerg
HandleTopLevelExpression()114606f32e7eSjoerg static void HandleTopLevelExpression() {
114706f32e7eSjoerg // Evaluate a top-level expression into an anonymous function.
114806f32e7eSjoerg if (auto FnAST = ParseTopLevelExpr()) {
114906f32e7eSjoerg FnAST->codegen();
115006f32e7eSjoerg } else {
115106f32e7eSjoerg // Skip token for error recovery.
115206f32e7eSjoerg getNextToken();
115306f32e7eSjoerg }
115406f32e7eSjoerg }
115506f32e7eSjoerg
115606f32e7eSjoerg /// top ::= definition | external | expression | ';'
MainLoop()115706f32e7eSjoerg static void MainLoop() {
115806f32e7eSjoerg while (true) {
115906f32e7eSjoerg switch (CurTok) {
116006f32e7eSjoerg case tok_eof:
116106f32e7eSjoerg return;
116206f32e7eSjoerg case ';': // ignore top-level semicolons.
116306f32e7eSjoerg getNextToken();
116406f32e7eSjoerg break;
116506f32e7eSjoerg case tok_def:
116606f32e7eSjoerg HandleDefinition();
116706f32e7eSjoerg break;
116806f32e7eSjoerg case tok_extern:
116906f32e7eSjoerg HandleExtern();
117006f32e7eSjoerg break;
117106f32e7eSjoerg default:
117206f32e7eSjoerg HandleTopLevelExpression();
117306f32e7eSjoerg break;
117406f32e7eSjoerg }
117506f32e7eSjoerg }
117606f32e7eSjoerg }
117706f32e7eSjoerg
117806f32e7eSjoerg //===----------------------------------------------------------------------===//
117906f32e7eSjoerg // "Library" functions that can be "extern'd" from user code.
118006f32e7eSjoerg //===----------------------------------------------------------------------===//
118106f32e7eSjoerg
118206f32e7eSjoerg #ifdef _WIN32
118306f32e7eSjoerg #define DLLEXPORT __declspec(dllexport)
118406f32e7eSjoerg #else
118506f32e7eSjoerg #define DLLEXPORT
118606f32e7eSjoerg #endif
118706f32e7eSjoerg
118806f32e7eSjoerg /// putchard - putchar that takes a double and returns 0.
putchard(double X)118906f32e7eSjoerg extern "C" DLLEXPORT double putchard(double X) {
119006f32e7eSjoerg fputc((char)X, stderr);
119106f32e7eSjoerg return 0;
119206f32e7eSjoerg }
119306f32e7eSjoerg
119406f32e7eSjoerg /// printd - printf that takes a double prints it as "%f\n", returning 0.
printd(double X)119506f32e7eSjoerg extern "C" DLLEXPORT double printd(double X) {
119606f32e7eSjoerg fprintf(stderr, "%f\n", X);
119706f32e7eSjoerg return 0;
119806f32e7eSjoerg }
119906f32e7eSjoerg
120006f32e7eSjoerg //===----------------------------------------------------------------------===//
120106f32e7eSjoerg // Main driver code.
120206f32e7eSjoerg //===----------------------------------------------------------------------===//
120306f32e7eSjoerg
main()120406f32e7eSjoerg int main() {
120506f32e7eSjoerg // Install standard binary operators.
120606f32e7eSjoerg // 1 is lowest precedence.
120706f32e7eSjoerg BinopPrecedence['<'] = 10;
120806f32e7eSjoerg BinopPrecedence['+'] = 20;
120906f32e7eSjoerg BinopPrecedence['-'] = 20;
121006f32e7eSjoerg BinopPrecedence['*'] = 40; // highest.
121106f32e7eSjoerg
121206f32e7eSjoerg // Prime the first token.
121306f32e7eSjoerg fprintf(stderr, "ready> ");
121406f32e7eSjoerg getNextToken();
121506f32e7eSjoerg
121606f32e7eSjoerg InitializeModuleAndPassManager();
121706f32e7eSjoerg
121806f32e7eSjoerg // Run the main "interpreter loop" now.
121906f32e7eSjoerg MainLoop();
122006f32e7eSjoerg
122106f32e7eSjoerg // Initialize the target registry etc.
122206f32e7eSjoerg InitializeAllTargetInfos();
122306f32e7eSjoerg InitializeAllTargets();
122406f32e7eSjoerg InitializeAllTargetMCs();
122506f32e7eSjoerg InitializeAllAsmParsers();
122606f32e7eSjoerg InitializeAllAsmPrinters();
122706f32e7eSjoerg
122806f32e7eSjoerg auto TargetTriple = sys::getDefaultTargetTriple();
122906f32e7eSjoerg TheModule->setTargetTriple(TargetTriple);
123006f32e7eSjoerg
123106f32e7eSjoerg std::string Error;
123206f32e7eSjoerg auto Target = TargetRegistry::lookupTarget(TargetTriple, Error);
123306f32e7eSjoerg
123406f32e7eSjoerg // Print an error and exit if we couldn't find the requested target.
123506f32e7eSjoerg // This generally occurs if we've forgotten to initialise the
123606f32e7eSjoerg // TargetRegistry or we have a bogus target triple.
123706f32e7eSjoerg if (!Target) {
123806f32e7eSjoerg errs() << Error;
123906f32e7eSjoerg return 1;
124006f32e7eSjoerg }
124106f32e7eSjoerg
124206f32e7eSjoerg auto CPU = "generic";
124306f32e7eSjoerg auto Features = "";
124406f32e7eSjoerg
124506f32e7eSjoerg TargetOptions opt;
124606f32e7eSjoerg auto RM = Optional<Reloc::Model>();
124706f32e7eSjoerg auto TheTargetMachine =
124806f32e7eSjoerg Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
124906f32e7eSjoerg
125006f32e7eSjoerg TheModule->setDataLayout(TheTargetMachine->createDataLayout());
125106f32e7eSjoerg
125206f32e7eSjoerg auto Filename = "output.o";
125306f32e7eSjoerg std::error_code EC;
125406f32e7eSjoerg raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);
125506f32e7eSjoerg
125606f32e7eSjoerg if (EC) {
125706f32e7eSjoerg errs() << "Could not open file: " << EC.message();
125806f32e7eSjoerg return 1;
125906f32e7eSjoerg }
126006f32e7eSjoerg
126106f32e7eSjoerg legacy::PassManager pass;
1262*da58b97aSjoerg auto FileType = CGFT_ObjectFile;
126306f32e7eSjoerg
126406f32e7eSjoerg if (TheTargetMachine->addPassesToEmitFile(pass, dest, nullptr, FileType)) {
126506f32e7eSjoerg errs() << "TheTargetMachine can't emit a file of this type";
126606f32e7eSjoerg return 1;
126706f32e7eSjoerg }
126806f32e7eSjoerg
126906f32e7eSjoerg pass.run(*TheModule);
127006f32e7eSjoerg dest.flush();
127106f32e7eSjoerg
127206f32e7eSjoerg outs() << "Wrote " << Filename << "\n";
127306f32e7eSjoerg
127406f32e7eSjoerg return 0;
127506f32e7eSjoerg }
1276