+//===----------------------------------------------------------------------===//
+// CleanupReturnInst Implementation
+//===----------------------------------------------------------------------===//
+
+CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI)
+ : TerminatorInst(CRI.getType(), Instruction::CleanupRet,
+ OperandTraits<CleanupReturnInst>::op_end(this) -
+ CRI.getNumOperands(),
+ CRI.getNumOperands()) {
+ setInstructionSubclassData(CRI.getSubclassDataFromInstruction());
+ Op<0>() = CRI.Op<0>();
+ if (CRI.hasUnwindDest())
+ Op<1>() = CRI.Op<1>();
+}
+
+void CleanupReturnInst::init(Value *CleanupPad, BasicBlock *UnwindBB) {
+ if (UnwindBB)
+ setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
+
+ Op<0>() = CleanupPad;
+ if (UnwindBB)
+ Op<1>() = UnwindBB;
+}
+
+CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, Instruction *InsertBefore)
+ : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
+ Instruction::CleanupRet,
+ OperandTraits<CleanupReturnInst>::op_end(this) - Values,
+ Values, InsertBefore) {
+ init(CleanupPad, UnwindBB);
+}
+
+CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, BasicBlock *InsertAtEnd)
+ : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
+ Instruction::CleanupRet,
+ OperandTraits<CleanupReturnInst>::op_end(this) - Values,
+ Values, InsertAtEnd) {
+ init(CleanupPad, UnwindBB);
+}
+
+BasicBlock *CleanupReturnInst::getSuccessorV(unsigned Idx) const {
+ assert(Idx == 0);
+ return getUnwindDest();
+}
+unsigned CleanupReturnInst::getNumSuccessorsV() const {
+ return getNumSuccessors();
+}
+void CleanupReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
+ assert(Idx == 0);
+ setUnwindDest(B);
+}
+
+//===----------------------------------------------------------------------===//
+// CatchReturnInst Implementation
+//===----------------------------------------------------------------------===//
+void CatchReturnInst::init(Value *CatchPad, BasicBlock *BB) {
+ Op<0>() = CatchPad;
+ Op<1>() = BB;
+}
+
+CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
+ : TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
+ OperandTraits<CatchReturnInst>::op_begin(this), 2) {
+ Op<0>() = CRI.Op<0>();
+ Op<1>() = CRI.Op<1>();
+}
+
+CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB,
+ Instruction *InsertBefore)
+ : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
+ OperandTraits<CatchReturnInst>::op_begin(this), 2,
+ InsertBefore) {
+ init(CatchPad, BB);
+}
+
+CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB,
+ BasicBlock *InsertAtEnd)
+ : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
+ OperandTraits<CatchReturnInst>::op_begin(this), 2,
+ InsertAtEnd) {
+ init(CatchPad, BB);
+}
+
+BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const {
+ assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
+ return getSuccessor();
+}
+unsigned CatchReturnInst::getNumSuccessorsV() const {
+ return getNumSuccessors();
+}
+void CatchReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
+ assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
+ setSuccessor(B);
+}
+
+//===----------------------------------------------------------------------===//
+// CatchSwitchInst Implementation
+//===----------------------------------------------------------------------===//
+
+CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
+ unsigned NumReservedValues,
+ const Twine &NameStr,
+ Instruction *InsertBefore)
+ : TerminatorInst(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0,
+ InsertBefore) {
+ if (UnwindDest)
+ ++NumReservedValues;
+ init(ParentPad, UnwindDest, NumReservedValues + 1);
+ setName(NameStr);
+}
+
+CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
+ unsigned NumReservedValues,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : TerminatorInst(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0,
+ InsertAtEnd) {
+ if (UnwindDest)
+ ++NumReservedValues;
+ init(ParentPad, UnwindDest, NumReservedValues + 1);
+ setName(NameStr);
+}
+
+CatchSwitchInst::CatchSwitchInst(const CatchSwitchInst &CSI)
+ : TerminatorInst(CSI.getType(), Instruction::CatchSwitch, nullptr,
+ CSI.getNumOperands()) {
+ init(CSI.getParentPad(), CSI.getUnwindDest(), CSI.getNumOperands());
+ setNumHungOffUseOperands(ReservedSpace);
+ Use *OL = getOperandList();
+ const Use *InOL = CSI.getOperandList();
+ for (unsigned I = 1, E = ReservedSpace; I != E; ++I)
+ OL[I] = InOL[I];
+}
+
+void CatchSwitchInst::init(Value *ParentPad, BasicBlock *UnwindDest,
+ unsigned NumReservedValues) {
+ assert(ParentPad && NumReservedValues);
+
+ ReservedSpace = NumReservedValues;
+ setNumHungOffUseOperands(UnwindDest ? 2 : 1);
+ allocHungoffUses(ReservedSpace);
+
+ Op<0>() = ParentPad;
+ if (UnwindDest) {
+ setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
+ setUnwindDest(UnwindDest);
+ }
+}
+
+/// growOperands - grow operands - This grows the operand list in response to a
+/// push_back style of operation. This grows the number of ops by 2 times.
+void CatchSwitchInst::growOperands(unsigned Size) {
+ unsigned NumOperands = getNumOperands();
+ assert(NumOperands >= 1);
+ if (ReservedSpace >= NumOperands + Size)
+ return;
+ ReservedSpace = (NumOperands + Size / 2) * 2;
+ growHungoffUses(ReservedSpace);
+}
+
+void CatchSwitchInst::addHandler(BasicBlock *Handler) {
+ unsigned OpNo = getNumOperands();
+ growOperands(1);
+ assert(OpNo < ReservedSpace && "Growing didn't work!");
+ setNumHungOffUseOperands(getNumOperands() + 1);
+ getOperandList()[OpNo] = Handler;
+}
+
+BasicBlock *CatchSwitchInst::getSuccessorV(unsigned idx) const {
+ return getSuccessor(idx);
+}
+unsigned CatchSwitchInst::getNumSuccessorsV() const {
+ return getNumSuccessors();
+}
+void CatchSwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
+ setSuccessor(idx, B);
+}
+
+//===----------------------------------------------------------------------===//
+// FuncletPadInst Implementation
+//===----------------------------------------------------------------------===//
+void FuncletPadInst::init(Value *ParentPad, ArrayRef<Value *> Args,
+ const Twine &NameStr) {
+ assert(getNumOperands() == 1 + Args.size() && "NumOperands not set up?");
+ std::copy(Args.begin(), Args.end(), op_begin());
+ setParentPad(ParentPad);
+ setName(NameStr);
+}
+
+FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI)
+ : Instruction(FPI.getType(), FPI.getOpcode(),
+ OperandTraits<FuncletPadInst>::op_end(this) -
+ FPI.getNumOperands(),
+ FPI.getNumOperands()) {
+ std::copy(FPI.op_begin(), FPI.op_end(), op_begin());
+ setParentPad(FPI.getParentPad());
+}
+
+FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore)
+ : Instruction(ParentPad->getType(), Op,
+ OperandTraits<FuncletPadInst>::op_end(this) - Values, Values,
+ InsertBefore) {
+ init(ParentPad, Args, NameStr);
+}
+
+FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : Instruction(ParentPad->getType(), Op,
+ OperandTraits<FuncletPadInst>::op_end(this) - Values, Values,
+ InsertAtEnd) {
+ init(ParentPad, Args, NameStr);
+}
+