cloud9_root/src/cloud9/lib/Module/ProgramDependenceGraph.cpp
// Given the passed callsite, return the matching set of functions which
// could be called from the callsite.
// If the called value is a literal function (i.e., not a function pointer)
// then the result will be a vector of size one containing this value.
//
// Otherwise, the return will be the set of all functions in the module which
// have the same number of arguments and the same type of arguments.
//
// If no functions are found, an empty vector is returned.
Given the passed callsite, return the matching set of functions which
could be called from the callsite.
If the called value is a literal function
then the result will be a vector of size one containing this value.

Otherwise, the return will be the set of all functions in the module which
have the same number of arguments and the same type of arguments.

If no functions are found, an empty vector is returned.
Given the passed callsite return the matching set of functions which could be called from the callsite . If the called value is a literal function then the result will be a vector of size one containing this value . Otherwise the return will be the set of all functions in the module which have the same number of arguments and the same type of arguments . If no functions are found an empty vector is returned .
std::vector<Function *> PDG::getMatchingFunctions(CallSite cs) {
	std::vector<Function *> ret;
	Function *callee = cs.getCalledFunction();
	if (callee != NULL) {
		ret.push_back(callee);
		assert(ret.size());
		return ret;
	}
	Value *called = cs.getCalledValue();
	assert(called && "function calling NULL");
	Instruction *csInst = cs.getInstruction();
	Module *M = csInst->getParent()->getParent()->getParent();
	std::vector<Type*> csArgTypes;
	for (size_t i = 0; i < cs.arg_size(); ++i) {
		Value *a = cs.getArgument(i);
		csArgTypes.push_back(a->getType());
	}
	Type *csRetTy = cs.getInstruction()->getType();
	for (Module::iterator fi = M->begin(), fe = M->end(); fi != fe; ++fi) {
		Function &f = *fi;
		FunctionType *fTy = f.getFunctionType();
		if (Utils::skipFunction(&f)) {
			continue;
		}
		if (fTy->isVarArg()) {
			errs() << "[Warning] var-arg function call: arguments are NOT followed in dependency graph (loss of precision) \n" << f << '\n';
		}
		if (csRetTy != fTy->getReturnType()) {
			continue;
		}
		if (fTy->getNumParams() != csArgTypes.size()) {
			continue;
		}
		if (!paramsMatch(fTy, csArgTypes)) {
			continue;
		}
		ret.push_back(&f);
	}
	return ret;
}
std :: vector < Function * > PDG :: getMatchingFunctions ( CallSite cs ) { std :: vector < Function * > ret ; Function * callee = cs . getCalledFunction ( ) ; if ( callee != NULL ) { ret . push_back ( callee ) ; assert ( ret . size ( ) ) ; return ret ; } Value * called = cs . getCalledValue ( ) ; assert ( called && " " ) ; Instruction * csInst = cs . getInstruction ( ) ; Module * M = csInst -> getParent ( ) -> getParent ( ) -> getParent ( ) ; std :: vector < Type * > csArgTypes ; for ( size_t i = 0 ; i < cs . arg_size ( ) ; ++ i ) { Value * a = cs . getArgument ( i ) ; csArgTypes . push_back ( a -> getType ( ) ) ; } Type * csRetTy = cs . getInstruction ( ) -> getType ( ) ; for ( Module :: iterator fi = M -> begin ( ) , fe = M -> end ( ) ; fi != fe ; ++ fi ) { Function & f = * fi ; FunctionType * fTy = f . getFunctionType ( ) ; if ( Utils :: skipFunction ( & f ) ) { continue ; } if ( fTy -> isVarArg ( ) ) { errs ( ) << " \n " << f << ' \n ' ; } if ( csRetTy != fTy -> getReturnType ( ) ) { continue ; } if ( fTy -> getNumParams ( ) != csArgTypes . size ( ) ) { continue ; } if ( ! paramsMatch ( fTy , csArgTypes ) ) { continue ; } ret . push_back ( & f ) ; } return ret ; }
Given the passed callsite, return the matching set of functions which
could be called from the callsite.
Given the passed callsite return the matching set of functions which could be called from the callsite .
// CallSite calls a literal function (non-function pointer) // Otherwise, the function is calling a function pointer // Collect the arguments used in the callsite // If there are no callsite arguments, then we are searching for a // function which similarly has no arguments // Return type of the function/callsite // Iterate over each function and find those which match the signature of // the callsite //		assert(!fTy->isVarArg() && "var-arg functions unhandled"); // If the function has no arguments and we are looking for an argument // with no functions then we are good to go // Check if the return types match // Check if the function has the same number of arguments // Check if the type of each argument matches // crash here for nbds-skiplistU1, sjguo, commented the following lines //	errs()<<"func name: "<<cs.getCalledFunction()->getName().str()<<"\n"; //	assert(ret.size() && "returning empty vector");