///
class TerminatorInst : public Instruction {
protected:
- TerminatorInst(Instruction::TermOps iType, Use *Ops, unsigned NumOps,
- Instruction *InsertBefore = 0);
TerminatorInst(const Type *Ty, Instruction::TermOps iType,
- Use *Ops, unsigned NumOps,
- const std::string &Name = "", Instruction *InsertBefore = 0)
- : Instruction(Ty, iType, Ops, NumOps, Name, InsertBefore) {}
+ Use *Ops, unsigned NumOps,
+ Instruction *InsertBefore = 0)
+ : Instruction(Ty, iType, Ops, NumOps, InsertBefore) {}
- TerminatorInst(Instruction::TermOps iType, Use *Ops, unsigned NumOps,
- BasicBlock *InsertAtEnd);
TerminatorInst(const Type *Ty, Instruction::TermOps iType,
- Use *Ops, unsigned NumOps,
- const std::string &Name, BasicBlock *InsertAtEnd)
- : Instruction(Ty, iType, Ops, NumOps, Name, InsertAtEnd) {}
+ Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd)
+ : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
// Out of line virtual method, so the vtable, etc has a home.
~TerminatorInst();
class UnaryInstruction : public Instruction {
Use Op;
protected:
- UnaryInstruction(const Type *Ty, unsigned iType, Value *V,
- const std::string &Name = "", Instruction *IB = 0)
- : Instruction(Ty, iType, &Op, 1, Name, IB), Op(V, this) {
+ UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB =0)
+ : Instruction(Ty, iType, &Op, 1, IB), Op(V, this) {
}
- UnaryInstruction(const Type *Ty, unsigned iType, Value *V,
- const std::string &Name, BasicBlock *IAE)
- : Instruction(Ty, iType, &Op, 1, Name, IAE), Op(V, this) {
+ UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
+ : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this) {
}
public:
// Out of line virtual method, so the vtable, etc has a home.
protected:
void init(BinaryOps iType);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
- const std::string &Name, Instruction *InsertBefore)
- : Instruction(Ty, iType, Ops, 2, Name, InsertBefore) {
- Ops[0].init(S1, this);
- Ops[1].init(S2, this);
- init(iType);
- }
+ const std::string &Name, Instruction *InsertBefore);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
- const std::string &Name, BasicBlock *InsertAtEnd)
- : Instruction(Ty, iType, Ops, 2, Name, InsertAtEnd) {
- Ops[0].init(S1, this);
- Ops[1].init(S2, this);
- init(iType);
- }
-
+ const std::string &Name, BasicBlock *InsertAtEnd);
public:
/// Transparently provide more efficient getOperand methods.
protected:
/// @brief Constructor with insert-before-instruction semantics for subclasses
CastInst(const Type *Ty, unsigned iType, Value *S,
- const std::string &Name = "", Instruction *InsertBefore = 0)
- : UnaryInstruction(Ty, iType, S, Name, InsertBefore) {
+ const std::string &Name = "", Instruction *InsertBefore = 0)
+ : UnaryInstruction(Ty, iType, S, InsertBefore) {
+ setName(Name);
}
/// @brief Constructor with insert-at-end-of-block semantics for subclasses
CastInst(const Type *Ty, unsigned iType, Value *S,
- const std::string &Name, BasicBlock *InsertAtEnd)
- : UnaryInstruction(Ty, iType, S, Name, InsertAtEnd) {
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : UnaryInstruction(Ty, iType, S, InsertAtEnd) {
+ setName(Name);
}
public:
/// Provides a way to construct any of the CastInst subclasses using an
return Instruction::CastOps(Instruction::getOpcode());
}
+ /// @brief Return the source type, as a convenience
+ const Type* getSrcTy() const { return getOperand(0)->getType(); }
+ /// @brief Return the destination type, as a convenience
+ const Type* getDestTy() const { return getType(); }
+
+ /// This method can be used to determine if a cast from S to DstTy using
+ /// Opcode op is valid or not.
+ /// @returns true iff the proposed cast is valid.
+ /// @brief Determine if a cast is valid without creating one.
+ static bool castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy);
+
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const CastInst *) { return true; }
static inline bool classof(const Instruction *I) {