assert(VMap.count(I) && "No mapping from source argument specified!");
#endif
+ // Copy all attributes other than those stored in the AttributeSet. We need
+ // to remap the parameter indices of the AttributeSet.
+ AttributeSet NewAttrs = NewFunc->getAttributes();
+ NewFunc->copyAttributesFrom(OldFunc);
+ NewFunc->setAttributes(NewAttrs);
+
AttributeSet OldAttrs = OldFunc->getAttributes();
// Clone any argument attributes that are present in the VMap.
- for (Function::const_arg_iterator I = OldFunc->arg_begin(),
- E = OldFunc->arg_end();
- I != E; ++I)
- if (Argument *Anew = dyn_cast<Argument>(VMap[I])) {
+ for (const Argument &OldArg : OldFunc->args())
+ if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
AttributeSet attrs =
- OldAttrs.getParamAttributes(I->getArgNo() + 1);
+ OldAttrs.getParamAttributes(OldArg.getArgNo() + 1);
if (attrs.getNumSlots() > 0)
- Anew->addAttr(attrs);
+ NewArg->addAttr(attrs);
}
- NewFunc->setAttributes(NewFunc->getAttributes()
- .addAttributes(NewFunc->getContext(),
- AttributeSet::ReturnIndex,
- OldAttrs.getRetAttributes()));
- NewFunc->setAttributes(NewFunc->getAttributes()
- .addAttributes(NewFunc->getContext(),
- AttributeSet::FunctionIndex,
- OldAttrs.getFnAttributes()));
+ NewFunc->setAttributes(
+ NewFunc->getAttributes()
+ .addAttributes(NewFunc->getContext(), AttributeSet::ReturnIndex,
+ OldAttrs.getRetAttributes())
+ .addAttributes(NewFunc->getContext(), AttributeSet::FunctionIndex,
+ OldAttrs.getFnAttributes()));
// Loop over all of the basic blocks in the function, cloning them as
// appropriate. Note that we save BE this way in order to handle cloning of
delete F2;
}
+TEST_F(CloneInstruction, CallingConvention) {
+ Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
+ FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
+
+ Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
+ F1->setCallingConv(CallingConv::Cold);
+ BasicBlock *BB = BasicBlock::Create(context, "", F1);
+ IRBuilder<> Builder(BB);
+ Builder.CreateRetVoid();
+
+ Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
+
+ SmallVector<ReturnInst*, 4> Returns;
+ ValueToValueMapTy VMap;
+ VMap[F1->arg_begin()] = F2->arg_begin();
+
+ CloneFunctionInto(F2, F1, VMap, false, Returns);
+ EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
+
+ delete F1;
+ delete F2;
+}
+
class CloneFunc : public ::testing::Test {
protected:
virtual void SetUp() {