/// Codegen function prototype and all blocks. llvm::Constant *Function::generate(llvm::Module *M) { if (LoweredValue) { return cast<llvm::Constant>(LoweredValue); } auto K = context(); auto CurrentFunction = getOrInsert(M); /// Bind argument symbols to function argument values in symbol table auto ArgList = getArguments(); auto S = ArgList.begin(); for (auto &Arg : CurrentFunction->args()) { auto SourceLoc = (*S)->sourceLocation(); (*S)->setLoweredValue(&Arg); ++S; } // Add function symbol to symbol table, global scope setLoweredValue(CurrentFunction); /// Codegens all blocks getEntryBlock()->generate(M); auto ExitBlock = getExitBlock(); if (!ExitBlock->size() || !isa<ReturnInst>(ExitBlock->back())) K->Builder->CreateRet(nullptr); return CurrentFunction; }
llvm::Constant *Function::toLL(llvm::Module *M) { auto K = getContext(); auto CurrentFunction = getOrInsert(M); /// Bind argument symbols to function argument values in symbol table auto ArgList = getArguments(); auto S = ArgList.begin(); for (auto &Arg : CurrentFunction->args()) { auto SourceLoc = (*S)->getSourceLocation(); if (!K->Map.add(*S, &Arg)) DiagnosticPrinter(SourceLoc) << "argument " + (*S)->getName() + " conflicts with existing symbol name"; ++S; } // Add function symbol to symbol table, global scope K->Map.add(this, CurrentFunction); /// Codegens all blocks getEntryBlock()->toLL(M); auto ExitBlock = getExitBlock(); if (!ExitBlock->size() || !isa<ReturnInst>(ExitBlock->back())) K->Builder->CreateRet(nullptr); return CurrentFunction; }