Taken into account Duncan's comments for r149481 dated by 2nd Feb 2012:
[oota-llvm.git] / include / llvm / Instructions.h
index 52fa8d7f722cb17b4efb5837fe0cbb0b1711c38d..13ed8c1f6ed393663b4e2722f7c781228dce0660 100644 (file)
@@ -24,7 +24,6 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <iterator>
-#include <limits.h>
 
 namespace llvm {
 
@@ -2468,8 +2467,119 @@ class SwitchInst : public TerminatorInst {
 protected:
   virtual SwitchInst *clone_impl() const;
 public:
+  
+  static const unsigned DefaultPseudoIndex = ~0L-1; // -2 
+  
+  template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy> 
+  class CaseIteratorT {
+  protected:
+    
+    SwitchInstTy *SI;
+    unsigned Index;
+    
+  public:
+    
+    typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self;
+    
+    /// Initializes case iterator for given SwitchInst and for given
+    /// case number.    
+    CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
+      this->SI = SI;
+      Index = CaseNum;
+    }
+    
+    /// Initializes case iterator for given SwitchInst and for given
+    /// TerminatorInst's successor index.
+    static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
+      assert(SuccessorIndex < SI->getNumSuccessors() &&
+             "Successor index # out of range!");    
+      return SuccessorIndex != 0 ? 
+             Self(SI, SuccessorIndex - 1) :
+             Self(SI, DefaultPseudoIndex);       
+    }
+    
+    /// Resolves case value for current case.
+    ConstantIntTy *getCaseValue() {
+      assert(Index < SI->getNumCases() && "Index out the number of cases.");
+      return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
+    }
+    
+    /// Resolves successor for current case.
+    BasicBlockTy *getCaseSuccessor() {
+      assert((Index < SI->getNumCases() || DefaultPseudoIndex) &&
+             "Index out the number of cases.");
+      return SI->getSuccessor(getSuccessorIndex());      
+    }
+    
+    /// Returns number of current case.
+    unsigned getCaseIndex() const { return Index; }
+    
+    /// Returns TerminatorInst's successor index for current case successor.
+    unsigned getSuccessorIndex() const {
+      assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
+             "Index out the number of cases.");
+      return Index != DefaultPseudoIndex ? Index + 1 : 0;
+    }
+    
+    Self operator++() {
+      // Check index correctness after increment.
+      // Note: Index == getNumCases() means end().      
+      assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
+      ++Index;
+      return *this;
+    }
+    Self operator++(int) {
+      Self tmp = *this;
+      ++(*this);
+      return tmp;
+    }
+    Self operator--() { 
+      // Check index correctness after decrement.
+      // Note: Index == getNumCases() means end().
+      // Also allow "-1" iterator here. That will became valid after ++.
+      assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
+             "Index out the number of cases.");
+      --Index;
+      return *this;
+    }
+    Self operator--(int) {
+      Self tmp = *this;
+      --(*this);
+      return tmp;
+    }
+    bool operator==(const Self& RHS) const {
+      assert(RHS.SI == SI && "Incompatible operators.");
+      return RHS.Index == Index;
+    }
+    bool operator!=(const Self& RHS) const {
+      assert(RHS.SI == SI && "Incompatible operators.");
+      return RHS.Index != Index;
+    }
+  };
+  
+  typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
+    ConstCaseIt;
 
-  enum { ErrorIndex = UINT_MAX };
+  class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
+    
+    typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
+  
+  public:
+    
+    CaseIt(const ParentTy& Src) : ParentTy(Src) {}
+    CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
+
+    /// Sets the new value for current case.    
+    void setValue(ConstantInt *V) {
+      assert(Index < SI->getNumCases() && "Index out the number of cases.");
+      SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
+    }
+    
+    /// Sets the new successor for current case.
+    void setSuccessor(BasicBlock *S) {
+      SI->setSuccessor(getSuccessorIndex(), S);      
+    }
+  };
 
   static SwitchInst *Create(Value *Value, BasicBlock *Default,
                             unsigned NumCases, Instruction *InsertBefore = 0) {
@@ -2479,6 +2589,7 @@ public:
                             unsigned NumCases, BasicBlock *InsertAtEnd) {
     return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
   }
+  
   ~SwitchInst();
 
   /// Provide fast operand accessors
@@ -2502,64 +2613,64 @@ public:
     return getNumOperands()/2 - 1;
   }
 
-  /// getCaseValue - Return the specified case value. Note that case #0, means
-  /// first case, not a default case.
-  ConstantInt *getCaseValue(unsigned i) {
-    assert(i < getNumCases() && "Illegal case value to get!");
-    return reinterpret_cast<ConstantInt*>(getOperand(2 + i*2));
+  /// Returns a read/write iterator that points to the first
+  /// case in SwitchInst.
+  CaseIt caseBegin() {
+    return CaseIt(this, 0);
   }
-
-  /// getCaseValue - Return the specified case value. Note that case #0, means
-  /// first case, not a default case.
-  const ConstantInt *getCaseValue(unsigned i) const {
-    assert(i < getNumCases() && "Illegal case value to get!");
-    return reinterpret_cast<const ConstantInt*>(getOperand(2 + i*2));
+  /// Returns a read-only iterator that points to the first
+  /// case in the SwitchInst.
+  ConstCaseIt caseBegin() const {
+    return ConstCaseIt(this, 0);
   }
-
-  // setSuccessorValue - Updates the value associated with the specified
-  // case.
-  void setCaseValue(unsigned i, ConstantInt *CaseValue) {
-    assert(i < getNumCases() && "Case index # out of range!");
-    setOperand(2 + i*2, reinterpret_cast<Value*>(CaseValue));
+  
+  /// Returns a read/write iterator that points one past the last
+  /// in the SwitchInst.
+  CaseIt caseEnd() {
+    return CaseIt(this, getNumCases());
   }
-
-  /// findCaseValue - Search all of the case values for the specified constant.
-  /// If it is explicitly handled, return the case number of it, otherwise
-  /// return ErrorIndex to indicate that it is handled by the default handler.
-  unsigned findCaseValue(const ConstantInt *C) const {
-    for (unsigned i = 0, e = getNumCases(); i != e; ++i)
-      if (getCaseValue(i) == C)
-        return i;
-    return ErrorIndex;
+  /// Returns a read-only iterator that points one past the last
+  /// in the SwitchInst.
+  ConstCaseIt caseEnd() const {
+    return ConstCaseIt(this, getNumCases());
   }
-  
-  /// resolveSuccessorIndex - Converts case index to index of its successor
-  /// index in TerminatorInst successors collection.
-  /// If CaseIndex == ErrorIndex, "default" successor will returned then. 
-  unsigned resolveSuccessorIndex(unsigned CaseIndex) const {
-    assert((CaseIndex == ErrorIndex || CaseIndex < getNumCases()) &&
-           "Case index # out of range!");
-    return CaseIndex != ErrorIndex ? CaseIndex + 1 : 0;
+  /// Returns an iterator that points to default case.
+  /// Note: this iterator allows to resolve successor only. Attempt
+  /// to resolve case value causes an assertion.
+  CaseIt caseDefault() {
+    return CaseIt(this, DefaultPseudoIndex);
+  }
+  ConstCaseIt caseDefault() const {
+    return ConstCaseIt(this, DefaultPseudoIndex);
   }
   
-  /// resolveCaseIndex - Converts index of successor in TerminatorInst
-  /// collection to index of case that corresponds to this successor.
-  unsigned resolveCaseIndex(unsigned SuccessorIndex) const {
-    assert(SuccessorIndex < getNumSuccessors() &&
-           "Successor index # out of range!");    
-    return SuccessorIndex != 0 ? SuccessorIndex - 1 : ErrorIndex; 
+  /// findCaseValue - Search all of the case values for the specified constant.
+  /// If it is explicitly handled, return the case iterator of it, otherwise
+  /// return default case iterator to indicate
+  /// that it is handled by the default handler.
+  CaseIt findCaseValue(const ConstantInt *C) {
+    for (CaseIt i = caseBegin(), e = caseEnd(); i != e; ++i)
+      if (i.getCaseValue() == C)
+        return i;
+    return caseDefault();
   }
-
+  ConstCaseIt findCaseValue(const ConstantInt *C) const {
+    for (ConstCaseIt i = caseBegin(), e = caseEnd(); i != e; ++i)
+      if (i.getCaseValue() == C)
+        return i;
+    return caseDefault();
+  }    
+  
   /// findCaseDest - Finds the unique case value for a given successor. Returns
   /// null if the successor is not found, not unique, or is the default case.
   ConstantInt *findCaseDest(BasicBlock *BB) {
     if (BB == getDefaultDest()) return NULL;
 
     ConstantInt *CI = NULL;
-    for (unsigned i = 0, e = getNumCases(); i != e; ++i) {
-      if (getSuccessor(i + 1) == BB) {
+    for (CaseIt i = caseBegin(), e = caseEnd(); i != e; ++i) {
+      if (i.getCaseSuccessor() == BB) {
         if (CI) return NULL;   // Multiple cases lead to BB.
-        else CI = getCaseValue(i);
+        else CI = i.getCaseValue();
       }
     }
     return CI;
@@ -2573,7 +2684,7 @@ public:
   /// from the switch instruction. Note that this operation may reorder the
   /// remaining cases at index idx and above.
   ///
-  void removeCase(unsigned idx);
+  void removeCase(CaseIt i);
 
   unsigned getNumSuccessors() const { return getNumOperands()/2; }
   BasicBlock *getSuccessor(unsigned idx) const {
@@ -2585,36 +2696,6 @@ public:
     setOperand(idx*2+1, (Value*)NewSucc);
   }
 
-  /// Resolves successor for idx-th case.
-  /// Use getCaseSuccessor instead of TerminatorInst::getSuccessor,
-  /// since internal SwitchInst organization of operands/successors is
-  /// hidden and may be changed in any moment.
-  BasicBlock *getCaseSuccessor(unsigned idx) const {
-    return getSuccessor(resolveSuccessorIndex(idx));
-  }
-
-  /// Set new successor for idx-th case.
-  /// Use setCaseSuccessor instead of TerminatorInst::setSuccessor,
-  /// since internal SwitchInst organization of operands/successors is
-  /// hidden and may be changed in any moment.
-  void setCaseSuccessor(unsigned idx, BasicBlock *NewSucc) {
-    setSuccessor(resolveSuccessorIndex(idx), NewSucc);
-  }
-
-  // getSuccessorValue - Return the value associated with the specified
-  // successor.
-  ConstantInt *getSuccessorValue(unsigned idx) const {
-    assert(idx < getNumSuccessors() && "Successor # out of range!");
-    return reinterpret_cast<ConstantInt*>(getOperand(idx*2));
-  }
-
-  // setSuccessorValue - Updates the value associated with the specified
-  // successor.
-  void setSuccessorValue(unsigned idx, ConstantInt* SuccessorValue) {
-    assert(idx < getNumSuccessors() && "Successor # out of range!");
-    setOperand(idx*2, reinterpret_cast<Value*>(SuccessorValue));
-  }
-
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const SwitchInst *) { return true; }
   static inline bool classof(const Instruction *I) {