+class AddOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
+ ~AddOperator() LLVM_DELETED_FUNCTION;
+};
+class SubOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
+ ~SubOperator() LLVM_DELETED_FUNCTION;
+};
+class MulOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
+ ~MulOperator() LLVM_DELETED_FUNCTION;
+};
+class ShlOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
+ ~ShlOperator() LLVM_DELETED_FUNCTION;
+};
+
+
+class SDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
+ ~SDivOperator() LLVM_DELETED_FUNCTION;
+};
+class UDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
+ ~UDivOperator() LLVM_DELETED_FUNCTION;
+};
+class AShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
+ ~AShrOperator() LLVM_DELETED_FUNCTION;
+};
+class LShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
+ ~LShrOperator() LLVM_DELETED_FUNCTION;
+};
+
+
+
+class GEPOperator
+ : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
+ ~GEPOperator() LLVM_DELETED_FUNCTION;
+
+ enum {
+ IsInBounds = (1 << 0)
+ };
+
+ friend class GetElementPtrInst;
+ friend class ConstantExpr;
+ void setIsInBounds(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
+ }
+
+public:
+ /// isInBounds - Test whether this is an inbounds GEP, as defined
+ /// by LangRef.html.
+ bool isInBounds() const {
+ return SubclassOptionalData & IsInBounds;
+ }
+
+ inline op_iterator idx_begin() { return op_begin()+1; }
+ inline const_op_iterator idx_begin() const { return op_begin()+1; }
+ inline op_iterator idx_end() { return op_end(); }
+ inline const_op_iterator idx_end() const { return op_end(); }
+
+ Value *getPointerOperand() {
+ return getOperand(0);
+ }
+ const Value *getPointerOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getPointerOperandIndex() {
+ return 0U; // get index for modifying correct operand
+ }
+
+ /// getPointerOperandType - Method to return the pointer operand as a
+ /// PointerType.
+ Type *getPointerOperandType() const {
+ return getPointerOperand()->getType();
+ }
+
+ /// getPointerAddressSpace - Method to return the address space of the
+ /// pointer operand.
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperandType())->getAddressSpace();
+ }
+
+ unsigned getNumIndices() const { // Note: always non-negative
+ return getNumOperands() - 1;
+ }
+
+ bool hasIndices() const {
+ return getNumOperands() > 1;
+ }
+
+ /// hasAllZeroIndices - Return true if all of the indices of this GEP are
+ /// zeros. If so, the result pointer and the first operand have the same
+ /// value, just potentially different types.
+ bool hasAllZeroIndices() const {
+ for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
+ if (ConstantInt *C = dyn_cast<ConstantInt>(I))
+ if (C->isZero())
+ continue;
+ return false;
+ }
+ return true;
+ }
+
+ /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+ /// constant integers. If so, the result pointer and the first operand have
+ /// a constant offset between them.
+ bool hasAllConstantIndices() const {
+ for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
+ if (!isa<ConstantInt>(I))
+ return false;
+ }
+ return true;
+ }
+};
+