InvokeInst(const InvokeInst &BI);
void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
Value* const *Args, unsigned NumArgs);
+
+ template<typename InputIterator>
+ void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name,
+ // This argument ensures that we have an iterator we can
+ // do arithmetic on in constant time
+ std::random_access_iterator_tag) {
+ typename std::iterator_traits<InputIterator>::difference_type NumArgs =
+ std::distance(ArgBegin, ArgEnd);
+
+ if (NumArgs > 0) {
+ // This requires that the iterator points to contiguous memory.
+ init(Func, IfNormal, IfException, &*ArgBegin, NumArgs);
+ }
+ else {
+ init(Func, IfNormal, IfException, 0, NumArgs);
+ }
+
+ setName(Name);
+ }
+
public:
- InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
- Value* const* Args, unsigned NumArgs, const std::string &Name = "",
- Instruction *InsertBefore = 0);
- InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
- Value* const* Args, unsigned NumArgs, const std::string &Name,
- BasicBlock *InsertAtEnd);
+ /// Construct an InvokeInst given a range of arguments.
+ /// InputIterator must be a random-access iterator pointing to
+ /// contiguous storage (e.g. a std::vector<>::iterator). Checks are
+ /// made for random-accessness but not for contiguous storage as
+ /// that would incur runtime overhead.
+ ///
+ /// @brief Construct an InvokeInst from a range of arguments
+ template<typename InputIterator>
+ InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name = "", Instruction *InsertBefore = 0)
+ : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Invoke, 0, 0, InsertBefore) {
+ init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+
+ /// Construct an InvokeInst given a range of arguments.
+ /// InputIterator must be a random-access iterator pointing to
+ /// contiguous storage (e.g. a std::vector<>::iterator). Checks are
+ /// made for random-accessness but not for contiguous storage as
+ /// that would incur runtime overhead.
+ ///
+ /// @brief Construct an InvokeInst from a range of arguments
+ template<typename InputIterator>
+ InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ InputIterator ArgBegin, InputIterator ArgEnd,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Invoke, 0, 0, InsertAtEnd) {
+ init(Func, IfNormal, IfException, ArgBegin, ArgEnd, Name,
+ typename std::iterator_traits<InputIterator>::iterator_category());
+ }
+
~InvokeInst();
virtual InvokeInst *clone() const;
}
/// CreateInvoke - Create an invoke instruction.
+ template<typename InputIterator>
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
- BasicBlock *UnwindDest,
- Value *const* Args, unsigned NumArgs,
- const char *Name = "") {
- return Insert(new InvokeInst(Callee, NormalDest, UnwindDest, Args, NumArgs,
- Name));
+ BasicBlock *UnwindDest, InputIterator ArgBegin,
+ InputIterator ArgEnd, const char *Name = "") {
+ return(Insert(new InvokeInst(Callee, NormalDest, UnwindDest,
+ ArgBegin, ArgEnd, Name)));
}
UnwindInst *CreateUnwind() {
}
// Create the InvokeInst
- InvokeInst *II = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
+ InvokeInst *II = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
II->setCallingConv($2);
$$ = II;
delete $6;
}
}
- I = new InvokeInst(Callee, NormalBB, UnwindBB, &Ops[0], Ops.size());
+ I = new InvokeInst(Callee, NormalBB, UnwindBB, Ops.begin(), Ops.end());
cast<InvokeInst>(I)->setCallingConv(CCInfo);
break;
}
Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
- &Args[0], Args.size(), "", Call);
+ Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
- &Args[0], Args.size(), "", Call);
+ Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
- &Args[0], Args.size(), "", Call);
+ Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
std::vector<Value*> Params(CI.op_begin() + 1, CI.op_end());
InvokeInst* II = new
InvokeInst(CI.getCalledValue(), NewBB, PrelimBBMap[Func],
- &Params[0], Params.size(), CI.getName(), Term);
+ Params.begin(), Params.end(), CI.getName(), Term);
// Replace the old call inst with the invoke inst and remove the call.
CI.replaceAllUsesWith(II);
Instruction *NC;
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
NC = new InvokeInst(Callee, II->getNormalDest(), II->getUnwindDest(),
- &Args[0], Args.size(), Caller->getName(), Caller);
+ Args.begin(), Args.end(), Caller->getName(), Caller);
cast<InvokeInst>(NC)->setCallingConv(II->getCallingConv());
} else {
NC = new CallInst(Callee, Args.begin(), Args.end(),
std::vector<Value*> Args(CI->op_begin()+1, CI->op_end());
Value *II = new InvokeInst(CI->getCalledValue(), NewBB, Cleanup,
- &Args[0], Args.size(), CI->getName(), CBB);
+ Args.begin(), Args.end(), CI->getName(), CBB);
CI->replaceAllUsesWith(II);
delete CI;
}
SmallVector<Value*, 8> InvokeArgs(CI->op_begin()+1, CI->op_end());
InvokeInst *II =
new InvokeInst(CI->getCalledValue(), Split, InvokeDest,
- &InvokeArgs[0], InvokeArgs.size(),
+ InvokeArgs.begin(), InvokeArgs.end(),
CI->getName(), BB->getTerminator());
II->setCallingConv(CI->getCallingConv());
}
}
-InvokeInst::InvokeInst(Value *Fn, BasicBlock *IfNormal,
- BasicBlock *IfException,
- Value* const *Args, unsigned NumArgs,
- const std::string &Name, Instruction *InsertBefore)
- : TerminatorInst(cast<FunctionType>(cast<PointerType>(Fn->getType())
- ->getElementType())->getReturnType(),
- Instruction::Invoke, 0, 0, InsertBefore) {
- init(Fn, IfNormal, IfException, Args, NumArgs);
- setName(Name);
-}
-
-InvokeInst::InvokeInst(Value *Fn, BasicBlock *IfNormal,
- BasicBlock *IfException,
- Value* const *Args, unsigned NumArgs,
- const std::string &Name, BasicBlock *InsertAtEnd)
- : TerminatorInst(cast<FunctionType>(cast<PointerType>(Fn->getType())
- ->getElementType())->getReturnType(),
- Instruction::Invoke, 0, 0, InsertAtEnd) {
- init(Fn, IfNormal, IfException, Args, NumArgs);
- setName(Name);
-}
-
InvokeInst::InvokeInst(const InvokeInst &II)
: TerminatorInst(II.getType(), Instruction::Invoke,
new Use[II.getNumOperands()], II.getNumOperands()) {
// Create the call node...
if (!$6) { // Has no arguments?
- $$.TI = new InvokeInst(V, Normal, Except, 0, 0);
+ std::vector<Value*> Args;
+ $$.TI = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
} else { // Has arguments?
// Loop through FunctionType's arguments and ensure they are specified
// correctly!
if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
error("Invalid number of parameters detected");
- $$.TI = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
+ $$.TI = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
}
cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
delete $3.PAT;
<< opNames[0] << ", "
<< opNames[1] << ", "
<< opNames[2] << ", "
- << "&" << iName << "_params[0], " << inv->getNumOperands() - 3
- << ", \"";
+ << iName << "_params.begin(), " << iName << "_params.end(), \"";
printEscapedString(inv->getName());
Out << "\", " << bbname << ");";
nl(Out) << iName << "->setCallingConv(";