FunctionList DSNodeEquivs::getCallees(CallSite &CS) { const Function *CalledFunc = CS.getCalledFunction(); // If the called function is casted from one function type to another, peer // into the cast instruction and pull out the actual function being called. if (ConstantExpr *CExpr = dyn_cast<ConstantExpr>(CS.getCalledValue())) { if (CExpr->getOpcode() == Instruction::BitCast && isa<Function>(CExpr->getOperand(0))) CalledFunc = cast<Function>(CExpr->getOperand(0)); } FunctionList Callees; // Direct calls are simple. if (CalledFunc) { Callees.push_back(CalledFunc); return Callees; } // Okay, indirect call. // Ask the DSCallGraph what this calls... TDDataStructures &TDDS = getAnalysis<TDDataStructures>(); const DSCallGraph &DSCG = TDDS.getCallGraph(); DSCallGraph::callee_iterator CalleeIt = DSCG.callee_begin(CS); DSCallGraph::callee_iterator CalleeItEnd = DSCG.callee_end(CS); for (; CalleeIt != CalleeItEnd; ++CalleeIt) Callees.push_back(*CalleeIt); // If the callgraph doesn't give us what we want, query the DSGraph // ourselves. if (Callees.empty()) { Instruction *Inst = CS.getInstruction(); Function *Parent = Inst->getParent()->getParent(); Value *CalledValue = CS.getCalledValue(); DSNodeHandle &NH = TDDS.getDSGraph(*Parent)->getNodeForValue(CalledValue); if (!NH.isNull()) { DSNode *Node = NH.getNode(); Node->addFullFunctionList(Callees); } } // For debugging, dump out the callsites we are unable to get callees for. DEBUG( if (Callees.empty()) { errs() << "Failed to get callees for callsite:\n"; CS.getInstruction()->dump(); });
/* call function */ Value Object::call (const std::string& function, const List& params) const { FunctionList list = mClass->getFunctions (function); /* no function found */ if (list.empty()) throw std::runtime_error ( "Cannot find the function '" + function + "' in the class '" + mClass->getName() + "'."); FunctionList::iterator iter; /* find a function which can handle the parameters */ for (iter = list.begin(); iter != list.end(); ++iter) { Function* func = *iter; /* found match, execute the function */ if (func->getType()->checkParamTypes (params)) return func->call (params); } /* no capable function found */ throw std::runtime_error ( "Cannot find a function capable of handling the provided " "parameters"); }