#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
#include <cctype>
#include <cstdio>
#include <map>
class ExprAST {
public:
virtual ~ExprAST() {}
- virtual Value *Codegen() = 0;
+ virtual Value *codegen() = 0;
};
/// NumberExprAST - Expression class for numeric literals like "1.0".
public:
NumberExprAST(double Val) : Val(Val) {}
- Value *Codegen() override;
+ Value *codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
- Value *Codegen() override;
+ Value *codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
- Value *Codegen() override;
+ Value *codegen() override;
};
/// CallExprAST - Expression class for function calls.
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
- Value *Codegen() override;
+ Value *codegen() override;
};
/// PrototypeAST - This class represents the "prototype" for a function,
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
: Name(Name), Args(std::move(Args)) {}
- Function *Codegen();
+ Function *codegen();
+ const std::string &getName() const { return Name; }
};
/// FunctionAST - This class represents a function definition itself.
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
- Function *Codegen();
+ Function *codegen();
};
} // end anonymous namespace
Error(Str);
return nullptr;
}
-std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
- Error(Str);
- return nullptr;
-}
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto =
- llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ auto Proto = llvm::make_unique<PrototypeAST>("__anon_expr",
+ std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
// Code Generation
//===----------------------------------------------------------------------===//
+static std::unique_ptr<Module> TheModule;
+static IRBuilder<> Builder(getGlobalContext());
+static std::map<std::string, Value *> NamedValues;
+
Value *ErrorV(const char *Str) {
Error(Str);
return nullptr;
}
-static Module *TheModule;
-static IRBuilder<> Builder(getGlobalContext());
-static std::map<std::string, Value *> NamedValues;
-
-Value *NumberExprAST::Codegen() {
+Value *NumberExprAST::codegen() {
return ConstantFP::get(getGlobalContext(), APFloat(Val));
}
-Value *VariableExprAST::Codegen() {
+Value *VariableExprAST::codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (!V)
return V;
}
-Value *BinaryExprAST::Codegen() {
- Value *L = LHS->Codegen();
- Value *R = RHS->Codegen();
+Value *BinaryExprAST::codegen() {
+ Value *L = LHS->codegen();
+ Value *R = RHS->codegen();
if (!L || !R)
return nullptr;
}
}
-Value *CallExprAST::Codegen() {
+Value *CallExprAST::codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (!CalleeF)
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
- ArgsV.push_back(Args[i]->Codegen());
+ ArgsV.push_back(Args[i]->codegen());
if (!ArgsV.back())
return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
-Function *PrototypeAST::Codegen() {
+Function *PrototypeAST::codegen() {
// Make the function type: double(double,double) etc.
std::vector<Type *> Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
Function *F =
- Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
-
- // If F conflicted, there was already something named 'Name'. If it has a
- // body, don't allow redefinition or reextern.
- if (F->getName() != Name) {
- // Delete the one we just made and get the existing one.
- F->eraseFromParent();
- F = TheModule->getFunction(Name);
-
- // If F already has a body, reject this.
- if (!F->empty()) {
- ErrorF("redefinition of function");
- return nullptr;
- }
-
- // If F took a different number of args, reject.
- if (F->arg_size() != Args.size()) {
- ErrorF("redefinition of function with different # args");
- return nullptr;
- }
- }
+ Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
// Set names for all arguments.
unsigned Idx = 0;
- for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
- ++AI, ++Idx) {
- AI->setName(Args[Idx]);
-
- // Add arguments to variable symbol table.
- NamedValues[Args[Idx]] = AI;
- }
+ for (auto &Arg : F->args())
+ Arg.setName(Args[Idx++]);
return F;
}
-Function *FunctionAST::Codegen() {
- NamedValues.clear();
+Function *FunctionAST::codegen() {
+ // First, check for an existing function from a previous 'extern' declaration.
+ Function *TheFunction = TheModule->getFunction(Proto->getName());
+
+ if (!TheFunction)
+ TheFunction = Proto->codegen();
- Function *TheFunction = Proto->Codegen();
if (!TheFunction)
return nullptr;
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
Builder.SetInsertPoint(BB);
- if (Value *RetVal = Body->Codegen()) {
+ // Record the function arguments in the NamedValues map.
+ NamedValues.clear();
+ for (auto &Arg : TheFunction->args())
+ NamedValues[Arg.getName()] = &Arg;
+
+ if (Value *RetVal = Body->codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
static void HandleDefinition() {
if (auto FnAST = ParseDefinition()) {
- if (auto *FnIR = FnAST->Codegen()) {
+ if (auto *FnIR = FnAST->codegen()) {
fprintf(stderr, "Read function definition:");
FnIR->dump();
}
static void HandleExtern() {
if (auto ProtoAST = ParseExtern()) {
- if (auto *FnIR = ProtoAST->Codegen()) {
+ if (auto *FnIR = ProtoAST->codegen()) {
fprintf(stderr, "Read extern: ");
FnIR->dump();
}
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (auto FnAST = ParseTopLevelExpr()) {
- if (auto *FnIR = FnAST->Codegen()) {
+ if (auto *FnIR = FnAST->codegen()) {
fprintf(stderr, "Read top-level expression:");
FnIR->dump();
}
//===----------------------------------------------------------------------===//
int main() {
- LLVMContext &Context = getGlobalContext();
-
// Install standard binary operators.
// 1 is lowest precedence.
BinopPrecedence['<'] = 10;
getNextToken();
// Make the module, which holds all the code.
- std::unique_ptr<Module> Owner =
- llvm::make_unique<Module>("my cool jit", Context);
- TheModule = Owner.get();
+ TheModule = llvm::make_unique<Module>("my cool jit", getGlobalContext());
// Run the main "interpreter loop" now.
MainLoop();