+
+
+
+/// ConcreteOperator - A helper template for defining operators for individual
+/// opcodes.
+template<typename SuperClass, unsigned Opc>
+class ConcreteOperator : public SuperClass {
+ ~ConcreteOperator(); // DO NOT IMPLEMENT
+public:
+ static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) {
+ return true;
+ }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Opc;
+ }
+ static inline bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Opc;
+ }
+ static inline bool classof(const Value *V) {
+ return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+ }
+};
+
+class AddOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
+ ~AddOperator(); // DO NOT IMPLEMENT
+};
+class SubOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
+ ~SubOperator(); // DO NOT IMPLEMENT
+};
+class MulOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
+ ~MulOperator(); // DO NOT IMPLEMENT
+};
+class ShlOperator
+ : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
+ ~ShlOperator(); // DO NOT IMPLEMENT
+};
+
+
+class SDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
+ ~SDivOperator(); // DO NOT IMPLEMENT
+};
+class UDivOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
+ ~UDivOperator(); // DO NOT IMPLEMENT
+};
+class AShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
+ ~AShrOperator(); // DO NOT IMPLEMENT
+};
+class LShrOperator
+ : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
+ ~LShrOperator(); // DO NOT IMPLEMENT
+};
+
+
+
+class GEPOperator
+ : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
+ ~GEPOperator(); // DO NOT IMPLEMENT
+
+ 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.
+ PointerType *getPointerOperandType() const {
+ return reinterpret_cast<PointerType*>(getPointerOperand()->getType());
+ }
+
+ 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;
+ }
+};