Function *FunctionAST::Codegen() { NamedValues.clear(); Function *TheFunction = Proto->Codegen(); if (TheFunction == 0) return 0; // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); if (Value *RetVal = Body->Codegen()) { // Finish off the function. Builder.CreateRet(RetVal); // Validate the generated code, checking for consistency. verifyFunction(*TheFunction); // Optimize the function. TheFPM->run(*TheFunction); return TheFunction; } // Error reading body, remove function. TheFunction->eraseFromParent(); return 0; }
Function *FunctionAST::Codegen() { NamedValues.clear(); Function *TheFunction = Proto->Codegen(); if (TheFunction == 0) return 0; // If this is an operator, install it. if (Proto->isBinaryOp()) BinopPrecedence[Proto->getOperatorName()] = Proto->getBinaryPrecedence(); // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction); Builder.SetInsertPoint(BB); // Add all arguments to the symbol table and create their allocas. Proto->CreateArgumentAllocas(TheFunction); if (Value *RetVal = Body->Codegen()) { // Finish off the function. Builder.CreateRet(RetVal); // Validate the generated code, checking for consistency. verifyFunction(*TheFunction); return TheFunction; } // Error reading body, remove function. TheFunction->eraseFromParent(); if (Proto->isBinaryOp()) BinopPrecedence.erase(Proto->getOperatorName()); return 0; }
FunctionAST *Parser::visitFuncttionDefinition() { int bkup = Tokens->getCurIndex(); PrototypeAST *proto = visitPrototype(); if (!proto) { return NULL; } else if ((PrototypeTable.find(proto->getName()) != PrototypeTable.end() && PrototypeTable[proto->getName()] != proto->getParamNum()) || FunctionTable.find(proto->getName()) != FunctionTable.end()) { fprintf(stderr, "Function: %s is redefined", proto->getName().c_str()); SAFE_DELETE(proto); return NULL; } VariableTable.clear(); FunctionStmtAST *func_stmt = visitFunctionStatement(proto); if (func_stmt) { FunctionTable[proto->getName()] = proto->getParamNum(); return new FunctionAST(proto, func_stmt); } else { SAFE_DELETE(proto); Tokens->applyTokenIndex(bkup); return NULL; } }
//! Compares two function prototypes to see if they have the same signature bool PrototypeAST::operator==( const PrototypeAST& rhs ) const { if( GetName() != rhs.GetName() ) return false; if( m_pReturnType != rhs.m_pReturnType ) return false; if( m_pArgs.size() != rhs.m_pArgs.size() ) return false; for( uint iArg=0; iArg<m_pArgs.size(); ++iArg ) { if( m_pArgs[iArg]->GetType() != rhs.m_pArgs[iArg]->GetType() ) return false; } // end for arg return true; } // end PrototypeAST::operator==()
PrototypeAST *Parser::visitFunctionDeclaration() { int bkup = Tokens->getCurIndex(); PrototypeAST *proto = visitPrototype(); if (!proto) { return NULL; } if (Tokens->getCurString() == ";") { if (PrototypeTable.find(proto->getName()) != ProtoytypeTable.end() || (FunctionTable.find(proto->getName()) != FunctionTable.end() && FunctionTable[proto->getName()] != proto->getParamNum())) { fprintf(stderr, "Function; %s is redefined", proto->getName().c_str()); SAFE_DELETE(proto); return NULL; } PrototypeTable[proto->getName()] = proto->getParamNum(); Tokens->getNextToken(); return proto; } else { SAFE_DELETE(proto); Tokens->applyTokenIndex(bkup); return NULL; } }