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()) {
- // We're just doing this to make sure it executes.
- TheExecutionEngine->finalizeObject();
- // JIT the function, returning a function pointer.
- double (*FP)() = (double (*)())(intptr_t)FPtr;
- // Ignore the return value for this.
- (void)FP;
- + if (!F->Codegen()) {
+ + if (!F->codegen()) {
+ fprintf(stderr, "Error generating code for top level expr");
}
} else {
=========
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 ``PrototypeAST::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.
DISubprogram *SP = DBuilder->createFunction(
FContext, Name, StringRef(), Unit, LineNo,
CreateFunctionType(Args.size(), Unit), false /* internal linkage */,
- true /* definition */, ScopeLine, DINode::FlagPrototyped, false, F);
+ true /* definition */, ScopeLine, DINode::FlagPrototyped, false);
+ F->setSubprogram(SP);
and we now have an DISubprogram that contains a reference to all of our
metadata for the function.
SourceLocation Loc;
public:
+ ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {}
+ virtual ~ExprAST() {}
+ virtual Value* codegen() = 0;
int getLine() const { return Loc.Line; }
int getCol() const { return Loc.Col; }
- ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {}
- virtual std::ostream &dump(std::ostream &out, int ind) {
+ virtual raw_ostream &dump(raw_ostream &out, int ind) {
return out << ':' << getLine() << ':' << getCol() << '\n';
}
DILocalVariable D = DBuilder->createParameterVariable(
Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true);
- Instruction *Call = DBuilder->insertDeclare(
- Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock());
- Call->setDebugLoc(DebugLoc::get(Line, 0, Scope));
+ DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(),
+ DebugLoc::get(Line, 0, Scope),
+ Builder.GetInsertBlock());
Here we're doing a few things. First, we're grabbing our current scope
for the variable so we can say what range of code our variable is valid
the name, source location, type, and since it's an argument, the argument
index. Third, we create an ``lvm.dbg.declare`` call to indicate at the IR
level that we've got a variable in an alloca (and it gives a starting
-location for the variable). Lastly, we set a source location for the
+location for the variable), and setting a source location for the
beginning of the scope on the declare.
One interesting thing to note at this point is that various debuggers have