/// getArgOperand/setArgOperand - Return/set the i-th call argument.
///
- Value *getArgOperand(unsigned i) const { return getOperand(i); }
- void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+ Value *getArgOperand(unsigned i) const {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ return getOperand(i);
+ }
+ void setArgOperand(unsigned i, Value *v) {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ setOperand(i, v);
+ }
/// arg_operands - iteration adapter for range-for loops.
iterator_range<op_iterator> arg_operands() {
}
/// \brief Wrappers for getting the \c Use of a call argument.
- const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
- Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+ const Use &getArgOperandUse(unsigned i) const {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ return getOperandUse(i);
+ }
+ Use &getArgOperandUse(unsigned i) {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ return getOperandUse(i);
+ }
/// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call.
addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate);
}
+ /// \brief Determine if the call is convergent
+ bool isConvergent() const { return hasFnAttr(Attribute::Convergent); }
+ void setConvergent() {
+ addAttribute(AttributeSet::FunctionIndex, Attribute::Convergent);
+ }
+
/// \brief Determine if the call returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
- *(&Op<-1>() - idx) = (Value*)NewSucc;
+ *(&Op<-1>() - idx) = NewSucc;
}
/// \brief Swap the successors of this branch instruction.
}
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
- setOperand(idx*2+1, (Value*)NewSucc);
+ setOperand(idx * 2 + 1, NewSucc);
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
return cast<BasicBlock>(getOperand(i+1));
}
void setSuccessor(unsigned i, BasicBlock *NewSucc) {
- setOperand(i+1, (Value*)NewSucc);
+ setOperand(i + 1, NewSucc);
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
/// getArgOperand/setArgOperand - Return/set the i-th invoke argument.
///
- Value *getArgOperand(unsigned i) const { return getOperand(i); }
- void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+ Value *getArgOperand(unsigned i) const {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ return getOperand(i);
+ }
+ void setArgOperand(unsigned i, Value *v) {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ setOperand(i, v);
+ }
/// arg_operands - iteration adapter for range-for loops.
iterator_range<op_iterator> arg_operands() {
}
/// \brief Wrappers for getting the \c Use of a invoke argument.
- const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
- Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+ const Use &getArgOperandUse(unsigned i) const {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ return getOperandUse(i);
+ }
+ Use &getArgOperandUse(unsigned i) {
+ assert(i < getNumArgOperands() && "Out of bounds!");
+ return getOperandUse(i);
+ }
/// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call.
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
-//===----------------------------------------------------------------------===//
-// CleanupReturnInst Class
-//===----------------------------------------------------------------------===//
-
-class CleanupReturnInst : public TerminatorInst {
- CleanupReturnInst(const CleanupReturnInst &RI);
-
-private:
- void init(Value *RetVal, BasicBlock *UnwindBB);
- CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
- unsigned Values, Instruction *InsertBefore = nullptr);
- CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
- unsigned Values, BasicBlock *InsertAtEnd);
-
- int getUnwindLabelOpIdx() const {
- assert(hasUnwindDest());
- return 0;
- }
-
- int getRetValOpIdx() const {
- assert(hasReturnValue());
- if (hasUnwindDest())
- return 1;
- return 0;
- }
-
-protected:
- // Note: Instruction needs to be a friend here to call cloneImpl.
- friend class Instruction;
- CleanupReturnInst *cloneImpl() const;
-
-public:
- static CleanupReturnInst *Create(LLVMContext &C,
- Value *RetVal = nullptr,
- BasicBlock *UnwindBB = nullptr,
- Instruction *InsertBefore = nullptr) {
- unsigned Values = 0;
- if (RetVal)
- ++Values;
- if (UnwindBB)
- ++Values;
- return new (Values)
- CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertBefore);
- }
- static CleanupReturnInst *Create(LLVMContext &C, Value *RetVal,
- BasicBlock *UnwindBB,
- BasicBlock *InsertAtEnd) {
- unsigned Values = 0;
- if (RetVal)
- ++Values;
- if (UnwindBB)
- ++Values;
- return new (Values)
- CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertAtEnd);
- }
-
- /// Provide fast operand accessors
- DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
-
- bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
- bool unwindsToCaller() const { return !hasUnwindDest(); }
- bool hasReturnValue() const { return getSubclassDataFromInstruction() & 2; }
-
- /// Convenience accessor. Returns null if there is no return value.
- Value *getReturnValue() const {
- if (!hasReturnValue())
- return nullptr;
- return getOperand(getRetValOpIdx());
- }
- void setReturnValue(Value *RetVal) {
- assert(hasReturnValue());
- setOperand(getRetValOpIdx(), RetVal);
- }
-
- unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
-
- BasicBlock *getUnwindDest() const;
- void setUnwindDest(BasicBlock *NewDest);
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Instruction *I) {
- return (I->getOpcode() == Instruction::CleanupRet);
- }
- static inline bool classof(const Value *V) {
- return isa<Instruction>(V) && classof(cast<Instruction>(V));
- }
-
-private:
- BasicBlock *getSuccessorV(unsigned Idx) const override;
- unsigned getNumSuccessorsV() const override;
- void setSuccessorV(unsigned Idx, BasicBlock *B) override;
-
- // Shadow Instruction::setInstructionSubclassData with a private forwarding
- // method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
- }
-};
-
-template <>
-struct OperandTraits<CleanupReturnInst>
- : public VariadicOperandTraits<CleanupReturnInst> {};
-
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
-
//===----------------------------------------------------------------------===//
// CatchEndPadInst Class
//===----------------------------------------------------------------------===//
class CatchEndPadInst : public TerminatorInst {
+private:
CatchEndPadInst(const CatchEndPadInst &RI);
-private:
void init(BasicBlock *UnwindBB);
CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
- Instruction *InsertBefore = nullptr);
+ Instruction *InsertBefore = nullptr);
CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
- BasicBlock *InsertAtEnd);
+ BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
CatchEndPadInst *cloneImpl() const;
public:
- static CatchEndPadInst *Create(LLVMContext &C,
- BasicBlock *UnwindBB = nullptr,
- Instruction *InsertBefore = nullptr) {
+ static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB = nullptr,
+ Instruction *InsertBefore = nullptr) {
unsigned Values = UnwindBB ? 1 : 0;
return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertBefore);
}
static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB,
- BasicBlock *InsertAtEnd) {
+ BasicBlock *InsertAtEnd) {
unsigned Values = UnwindBB ? 1 : 0;
return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertAtEnd);
}
unsigned getNumSuccessorsV() const override;
void setSuccessorV(unsigned Idx, BasicBlock *B) override;
-private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
void setInstructionSubclassData(unsigned short D) {
CatchPadInst(const CatchPadInst &CPI);
- explicit CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- unsigned Values, const Twine &NameStr,
- Instruction *InsertBefore);
- explicit CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- unsigned Values, const Twine &NameStr,
- BasicBlock *InsertAtEnd);
+ explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
CatchPadInst *cloneImpl() const;
public:
- static CatchPadInst *Create(Type *RetTy, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr) {
+ static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
unsigned Values = unsigned(Args.size()) + 2;
- return new (Values) CatchPadInst(RetTy, IfNormal, IfException, Args,
- Values, NameStr, InsertBefore);
+ return new (Values) CatchPadInst(IfNormal, IfException, Args, Values,
+ NameStr, InsertBefore);
}
- static CatchPadInst *Create(Type *RetTy, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- const Twine &NameStr, BasicBlock *InsertAtEnd) {
+ static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
unsigned Values = unsigned(Args.size()) + 2;
- return new (Values) CatchPadInst(RetTy, IfNormal, IfException, Args,
- Values, NameStr, InsertAtEnd);
+ return new (Values)
+ CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd);
}
/// Provide fast operand accessors
// get*Dest - Return the destination basic blocks...
BasicBlock *getNormalDest() const { return cast<BasicBlock>(Op<-2>()); }
BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
- void setNormalDest(BasicBlock *B) { Op<-2>() = reinterpret_cast<Value *>(B); }
- void setUnwindDest(BasicBlock *B) { Op<-1>() = reinterpret_cast<Value *>(B); }
+ void setNormalDest(BasicBlock *B) { Op<-2>() = B; }
+ void setUnwindDest(BasicBlock *B) { Op<-1>() = B; }
BasicBlock *getSuccessor(unsigned i) const {
assert(i < 2 && "Successor # out of range for catchpad!");
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
assert(idx < 2 && "Successor # out of range for catchpad!");
- *(&Op<-2>() + idx) = reinterpret_cast<Value *>(NewSucc);
+ *(&Op<-2>() + idx) = NewSucc;
}
unsigned getNumSuccessors() const { return 2; }
class TerminatePadInst : public TerminatorInst {
private:
- void init(BasicBlock *BB, ArrayRef<Value *> Args, const Twine &NameStr);
+ void init(BasicBlock *BB, ArrayRef<Value *> Args);
TerminatePadInst(const TerminatePadInst &TPI);
explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
- ArrayRef<Value *> Args, unsigned Values,
- const Twine &NameStr, Instruction *InsertBefore);
+ ArrayRef<Value *> Args, unsigned Values,
+ Instruction *InsertBefore);
explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
- ArrayRef<Value *> Args, unsigned Values,
- const Twine &NameStr, BasicBlock *InsertAtEnd);
+ ArrayRef<Value *> Args, unsigned Values,
+ BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
public:
static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB = nullptr,
- ArrayRef<Value *> Args = {},
- const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr) {
+ ArrayRef<Value *> Args = None,
+ Instruction *InsertBefore = nullptr) {
unsigned Values = unsigned(Args.size());
if (BB)
++Values;
- return new (Values)
- TerminatePadInst(C, BB, Args, Values, NameStr, InsertBefore);
+ return new (Values) TerminatePadInst(C, BB, Args, Values, InsertBefore);
}
static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB,
- ArrayRef<Value *> Args,
- const Twine &NameStr,
- BasicBlock *InsertAtEnd) {
+ ArrayRef<Value *> Args,
+ BasicBlock *InsertAtEnd) {
unsigned Values = unsigned(Args.size());
if (BB)
++Values;
- return new (Values)
- TerminatePadInst(C, BB, Args, Values, NameStr, InsertAtEnd);
+ return new (Values) TerminatePadInst(C, BB, Args, Values, InsertAtEnd);
}
/// Provide fast operand accessors
}
void setUnwindDest(BasicBlock *B) {
assert(B && hasUnwindDest());
- Op<-1>() = reinterpret_cast<Value *>(B);
+ Op<-1>() = B;
}
unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
CleanupPadInst(const CleanupPadInst &CPI);
- explicit CleanupPadInst(Type *RetTy, ArrayRef<Value *> Args,
- const Twine &NameStr, Instruction *InsertBefore);
- explicit CleanupPadInst(Type *RetTy, ArrayRef<Value *> Args,
- const Twine &NameStr, BasicBlock *InsertAtEnd);
+ explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
CleanupPadInst *cloneImpl() const;
public:
- static CleanupPadInst *Create(Type *RetTy, ArrayRef<Value *> Args,
- const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr) {
- return new (Args.size())
- CleanupPadInst(RetTy, Args, NameStr, InsertBefore);
+ static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertBefore);
}
- static CleanupPadInst *Create(Type *RetTy, ArrayRef<Value *> Args,
- const Twine &NameStr,
- BasicBlock *InsertAtEnd) {
- return new (Args.size())
- CleanupPadInst(RetTy, Args, NameStr, InsertAtEnd);
+ static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd) {
+ return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertAtEnd);
}
/// Provide fast operand accessors
class CatchReturnInst : public TerminatorInst {
CatchReturnInst(const CatchReturnInst &RI);
-private:
- void init(Value *RetVal, BasicBlock *UnwindBB);
- CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore = nullptr);
- CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd);
+ void init(CatchPadInst *CatchPad, BasicBlock *BB);
+ CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
+ Instruction *InsertBefore);
+ CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
+ BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
CatchReturnInst *cloneImpl() const;
public:
- static CatchReturnInst *Create(BasicBlock *BB,
+ static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB,
Instruction *InsertBefore = nullptr) {
- return new (1) CatchReturnInst(BB, InsertBefore);
+ assert(CatchPad);
+ assert(BB);
+ return new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
}
- static CatchReturnInst *Create(BasicBlock *BB, BasicBlock *InsertAtEnd) {
- return new (1) CatchReturnInst(BB, InsertAtEnd);
+ static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB,
+ BasicBlock *InsertAtEnd) {
+ assert(CatchPad);
+ assert(BB);
+ return new (2) CatchReturnInst(CatchPad, BB, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// Convenience accessors.
- BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<0>()); }
- void setSuccessor(BasicBlock *NewSucc) { Op<0>() = (Value *)NewSucc; }
+ CatchPadInst *getCatchPad() const { return cast<CatchPadInst>(Op<0>()); }
+ void setCatchPad(CatchPadInst *CatchPad) {
+ assert(CatchPad);
+ Op<0>() = CatchPad;
+ }
+
+ BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<1>()); }
+ void setSuccessor(BasicBlock *NewSucc) {
+ assert(NewSucc);
+ Op<1>() = NewSucc;
+ }
unsigned getNumSuccessors() const { return 1; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
template <>
struct OperandTraits<CatchReturnInst>
- : public FixedNumOperandTraits<CatchReturnInst, /*ARITY=*/1> {};
+ : public FixedNumOperandTraits<CatchReturnInst, 2> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
+//===----------------------------------------------------------------------===//
+// CleanupEndPadInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupEndPadInst : public TerminatorInst {
+private:
+ CleanupEndPadInst(const CleanupEndPadInst &CEPI);
+
+ void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB);
+ CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, Instruction *InsertBefore = nullptr);
+ CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CleanupEndPadInst *cloneImpl() const;
+
+public:
+ static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB = nullptr,
+ Instruction *InsertBefore = nullptr) {
+ unsigned Values = UnwindBB ? 2 : 1;
+ return new (Values)
+ CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertBefore);
+ }
+ static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = UnwindBB ? 2 : 1;
+ return new (Values)
+ CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ /// Convenience accessors
+ CleanupPadInst *getCleanupPad() const {
+ return cast<CleanupPadInst>(Op<-1>());
+ }
+ void setCleanupPad(CleanupPadInst *CleanupPad) {
+ assert(CleanupPad);
+ Op<-1>() = CleanupPad;
+ }
+
+ BasicBlock *getUnwindDest() const {
+ return hasUnwindDest() ? cast<BasicBlock>(Op<-2>()) : nullptr;
+ }
+ void setUnwindDest(BasicBlock *NewDest) {
+ assert(hasUnwindDest());
+ assert(NewDest);
+ Op<-2>() = NewDest;
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CleanupEndPad);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CleanupEndPadInst>
+ : public VariadicOperandTraits<CleanupEndPadInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupEndPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+// CleanupReturnInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupReturnInst : public TerminatorInst {
+private:
+ CleanupReturnInst(const CleanupReturnInst &RI);
+
+ void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB);
+ CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, Instruction *InsertBefore = nullptr);
+ CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+ unsigned Values, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ CleanupReturnInst *cloneImpl() const;
+
+public:
+ static CleanupReturnInst *Create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB = nullptr,
+ Instruction *InsertBefore = nullptr) {
+ assert(CleanupPad);
+ unsigned Values = 1;
+ if (UnwindBB)
+ ++Values;
+ return new (Values)
+ CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore);
+ }
+ static CleanupReturnInst *Create(CleanupPadInst *CleanupPad,
+ BasicBlock *UnwindBB,
+ BasicBlock *InsertAtEnd) {
+ assert(CleanupPad);
+ unsigned Values = 1;
+ if (UnwindBB)
+ ++Values;
+ return new (Values)
+ CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+ /// Convenience accessor.
+ CleanupPadInst *getCleanupPad() const {
+ return cast<CleanupPadInst>(Op<-1>());
+ }
+ void setCleanupPad(CleanupPadInst *CleanupPad) {
+ assert(CleanupPad);
+ Op<-1>() = CleanupPad;
+ }
+
+ unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+ BasicBlock *getUnwindDest() const {
+ return hasUnwindDest() ? cast<BasicBlock>(Op<-2>()) : nullptr;
+ }
+ void setUnwindDest(BasicBlock *NewDest) {
+ assert(NewDest);
+ assert(hasUnwindDest());
+ Op<-2>() = NewDest;
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::CleanupRet);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ BasicBlock *getSuccessorV(unsigned Idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CleanupReturnInst>
+ : public VariadicOperandTraits<CleanupReturnInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
+
//===----------------------------------------------------------------------===//
// UnreachableInst Class
//===----------------------------------------------------------------------===//