/// cloneFunctionBody - Create a new function based on F and /// insert it into module. Remove first argument. Use STy as /// the return type for new function. Function *SRETPromotion::cloneFunctionBody(Function *F, const StructType *STy) { const FunctionType *FTy = F->getFunctionType(); std::vector<const Type*> Params; // Attributes - Keep track of the parameter attributes for the arguments. SmallVector<AttributeWithIndex, 8> AttributesVec; const AttrListPtr &PAL = F->getAttributes(); // Add any return attributes. if (Attributes attrs = PAL.getRetAttributes()) AttributesVec.push_back(AttributeWithIndex::get(0, attrs)); // Skip first argument. Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); ++I; // 0th parameter attribute is reserved for return type. // 1th parameter attribute is for first 1st sret argument. unsigned ParamIndex = 2; while (I != E) { Params.push_back(I->getType()); if (Attributes Attrs = PAL.getParamAttributes(ParamIndex)) AttributesVec.push_back(AttributeWithIndex::get(ParamIndex - 1, Attrs)); ++I; ++ParamIndex; } // Add any fn attributes. if (Attributes attrs = PAL.getFnAttributes()) AttributesVec.push_back(AttributeWithIndex::get(~0, attrs)); FunctionType *NFTy = FunctionType::get(STy, Params, FTy->isVarArg()); Function *NF = Function::Create(NFTy, F->getLinkage()); NF->takeName(F); NF->copyAttributesFrom(F); NF->setAttributes(AttrListPtr::get(AttributesVec.begin(), AttributesVec.end())); F->getParent()->getFunctionList().insert(F, NF); NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList()); // Replace arguments I = F->arg_begin(); E = F->arg_end(); Function::arg_iterator NI = NF->arg_begin(); ++I; while (I != E) { I->replaceAllUsesWith(NI); NI->takeName(I); ++I; ++NI; } return NF; }