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(); });
void TypeRegistry::collect_pure_methods(const TypeDesc &td, FunctionList &fl) const { for (BaseTypeList::const_iterator i=td.base_types.begin(); i!=td.base_types.end(); ++i) { const TypeDesc *base = findTypeDescription(i->name); if (base) collect_pure_methods(*base, fl); } FunctionList methods; std::copy(td.methods.begin(), td.methods.end(), std::back_inserter(methods)); std::copy(td.prot_methods.begin(), td.prot_methods.end(), std::back_inserter(methods)); std::copy(td.priv_methods.begin(), td.priv_methods.end(), std::back_inserter(methods)); for (FunctionList::const_iterator i=methods.begin(); i!=methods.end(); ++i) { if (i->is_pure_virtual) { fl.push_back(*i); } else { for (FunctionList::iterator j=fl.begin(); j!=fl.end();) { if (j->get_signature() == i->get_signature()) { fl.erase(j); } else ++j; } } } }
void SerialPlugIn::AddDMFunctions( void ) { fFunctionList.push_back( AddFunction( 0, "void SerialOpen(char * port, long baud)", 3, (void *) &SerialOpen ) ); fFunctionList.push_back( AddFunction( 0, "void SerialCheck(char * port)", 3, (void *) &SerialCheck ) ); fFunctionList.push_back( AddFunction( 0, "void SerialClose( void )", 3, (void *) &SerialClose ) ); fFunctionList.push_back( AddFunction( 0, "short RxByte( void )", 3, (void *) &RxByte ) ); fFunctionList.push_back( AddFunction( 0, "void TxByte(short byte)", 3, (void *) &TxByte ) ); fFunctionList.push_back( AddFunction( 0, "void TxInt(unsigned int num)", 3, (void *) &TxInt ) ); }