Implement basic block successor iterators.  Rename BBDestination ->
BasicBlockOperand to be more consistent with InstOperand.  Rename
getDestinations() to getBasicBlockOperands() to reduce confusion on their role.

PiperOrigin-RevId: 206192327
diff --git a/include/mlir/IR/BasicBlock.h b/include/mlir/IR/BasicBlock.h
index ce8df72..52a661d 100644
--- a/include/mlir/IR/BasicBlock.h
+++ b/include/mlir/IR/BasicBlock.h
@@ -23,6 +23,7 @@
 
 namespace mlir {
 class BBArgument;
+template <typename BlockType> class SuccessorIterator;
 
 /// Each basic block in a CFG function contains a list of basic block arguments,
 /// normal instructions, and a terminator instruction.
@@ -118,6 +119,31 @@
 
   TerminatorInst *getTerminator() const { return terminator; }
 
+  //===--------------------------------------------------------------------===//
+  // Predecessors and successors.
+  //===--------------------------------------------------------------------===//
+
+  unsigned getNumSuccessors() const {
+    return getTerminator()->getNumSuccessors();
+  }
+  const BasicBlock *getSuccessor(unsigned i) const {
+    return const_cast<BasicBlock *>(this)->getSuccessor(i);
+  }
+  BasicBlock *getSuccessor(unsigned i) {
+    return getTerminator()->getSuccessor(i);
+  }
+
+  // Support successor iteration.
+  using const_succ_iterator = SuccessorIterator<const BasicBlock>;
+  const_succ_iterator succ_begin() const;
+  const_succ_iterator succ_end() const;
+  llvm::iterator_range<const_succ_iterator> getSuccessors() const;
+
+  using succ_iterator = SuccessorIterator<BasicBlock>;
+  succ_iterator succ_begin();
+  succ_iterator succ_end();
+  llvm::iterator_range<succ_iterator> getSuccessors();
+
   void print(raw_ostream &os) const;
   void dump() const;
 
@@ -144,6 +170,53 @@
   friend struct llvm::ilist_traits<BasicBlock>;
 };
 
+/// This template implments the successor iterators for basic block.
+template <typename BlockType>
+class SuccessorIterator final
+    : public IndexedAccessorIterator<SuccessorIterator<BlockType>, BlockType,
+                                     BlockType> {
+public:
+  /// Initializes the result iterator to the specified index.
+  SuccessorIterator(BlockType *object, unsigned index)
+      : IndexedAccessorIterator<SuccessorIterator<BlockType>, BlockType,
+                                BlockType>(object, index) {}
+
+  /// Support converting to the const variant. This will be a no-op for const
+  /// variant.
+  operator SuccessorIterator<const BlockType>() const {
+    return SuccessorIterator<const BlockType>(this->object, this->index);
+  }
+
+  BlockType *operator*() const {
+    return this->object->getSuccessor(this->index);
+  }
+};
+
+inline auto BasicBlock::succ_begin() const -> const_succ_iterator {
+  return const_succ_iterator(this, 0);
+}
+
+inline auto BasicBlock::succ_end() const -> const_succ_iterator {
+  return const_succ_iterator(this, getNumSuccessors());
+}
+
+inline auto BasicBlock::getSuccessors() const
+    -> llvm::iterator_range<const_succ_iterator> {
+  return {succ_begin(), succ_end()};
+}
+
+inline auto BasicBlock::succ_begin() -> succ_iterator {
+  return succ_iterator(this, 0);
+}
+
+inline auto BasicBlock::succ_end() -> succ_iterator {
+  return succ_iterator(this, getNumSuccessors());
+}
+
+inline auto BasicBlock::getSuccessors() -> llvm::iterator_range<succ_iterator> {
+  return {succ_begin(), succ_end()};
+}
+
 } // end namespace mlir
 
 //===----------------------------------------------------------------------===//
diff --git a/include/mlir/IR/Instructions.h b/include/mlir/IR/Instructions.h
index da41825..be8c99a 100644
--- a/include/mlir/IR/Instructions.h
+++ b/include/mlir/IR/Instructions.h
@@ -35,8 +35,8 @@
 class OperationInst;
 class TerminatorInst;
 
-/// The operand of a CFG Instruction contains a CFGValue.
-using BBDestination = IROperandImpl<BasicBlock, TerminatorInst>;
+/// The operand of a TerminatorInst contains a BasicBlock.
+using BasicBlockOperand = IROperandImpl<BasicBlock, TerminatorInst>;
 
 /// Instruction is the root of the operation and terminator instructions in the
 /// hierarchy.
@@ -296,20 +296,23 @@
   /// Remove this terminator from its BasicBlock and delete it.
   void eraseFromBlock();
 
-  /// Return the list of destination entries that this terminator branches to.
-  MutableArrayRef<BBDestination> getDestinations();
+  /// Return the list of BasicBlockOperand operands of this terminator that
+  /// this terminator holds.
+  MutableArrayRef<BasicBlockOperand> getBasicBlockOperands();
 
-  ArrayRef<BBDestination> getDestinations() const {
-    return const_cast<TerminatorInst *>(this)->getDestinations();
+  ArrayRef<BasicBlockOperand> getBasicBlockOperands() const {
+    return const_cast<TerminatorInst *>(this)->getBasicBlockOperands();
   }
 
-  unsigned getNumSuccessors() const { return getDestinations().size(); }
+  unsigned getNumSuccessors() const { return getBasicBlockOperands().size(); }
 
   const BasicBlock *getSuccessor(unsigned i) const {
-    return getDestinations()[i].get();
+    return getBasicBlockOperands()[i].get();
   }
 
-  BasicBlock *getSuccessor(unsigned i) { return getDestinations()[i].get(); }
+  BasicBlock *getSuccessor(unsigned i) {
+    return getBasicBlockOperands()[i].get();
+  }
 
 protected:
   TerminatorInst(Kind kind) : Instruction(kind) {}
@@ -341,8 +344,8 @@
   /// Erase a specific argument from the arg list.
   // TODO: void eraseArgument(int Index);
 
-  MutableArrayRef<BBDestination> getDestinations() { return dest; }
-  ArrayRef<BBDestination> getDestinations() const { return dest; }
+  MutableArrayRef<BasicBlockOperand> getBasicBlockOperands() { return dest; }
+  ArrayRef<BasicBlockOperand> getBasicBlockOperands() const { return dest; }
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast.
   static bool classof(const Instruction *inst) {
@@ -352,7 +355,7 @@
 private:
   explicit BranchInst(BasicBlock *dest);
 
-  BBDestination dest;
+  BasicBlockOperand dest;
   std::vector<InstOperand> operands;
 };
 
@@ -501,8 +504,8 @@
   /// Add a list of values to the operand list.
   void addFalseOperands(ArrayRef<CFGValue *> values);
 
-  MutableArrayRef<BBDestination> getDestinations() { return dests; }
-  ArrayRef<BBDestination> getDestinations() const { return dests; }
+  MutableArrayRef<BasicBlockOperand> getBasicBlockOperands() { return dests; }
+  ArrayRef<BasicBlockOperand> getBasicBlockOperands() const { return dests; }
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast.
   static bool classof(const Instruction *inst) {
@@ -514,7 +517,7 @@
                  BasicBlock *falseDest);
 
   CFGValue *condition;
-  BBDestination dests[2]; // 0 is the true dest, 1 is the false dest.
+  BasicBlockOperand dests[2]; // 0 is the true dest, 1 is the false dest.
 
   // Operand list. The true operands are stored first, followed by the false
   // operands.
diff --git a/include/mlir/IR/Operation.h b/include/mlir/IR/Operation.h
index d17ddde..2222ab7 100644
--- a/include/mlir/IR/Operation.h
+++ b/include/mlir/IR/Operation.h
@@ -220,7 +220,7 @@
   unsigned index;
 };
 
-/// This template implments the operand iterators for the various IR classes
+/// This template implements the operand iterators for the various IR classes
 /// in terms of getOperand(idx).
 template <typename ObjectType, typename ElementType>
 class OperandIterator final
@@ -244,7 +244,7 @@
   }
 };
 
-/// This template implments the result iterators for the various IR classes
+/// This template implements the result iterators for the various IR classes
 /// in terms of getResult(idx).
 template <typename ObjectType, typename ElementType>
 class ResultIterator final
diff --git a/include/mlir/Support/STLExtras.h b/include/mlir/Support/STLExtras.h
index 905694b..4ea236f 100644
--- a/include/mlir/Support/STLExtras.h
+++ b/include/mlir/Support/STLExtras.h
@@ -130,6 +130,6 @@
   }
 };
 
-}
+} // end namespace llvm
 
 #endif // MLIR_SUPPORT_STLEXTRAS_H
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index fa578f1..c3f0b1e 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -107,7 +107,7 @@
     op.drop();
 
   if (auto *term = dyn_cast<TerminatorInst>(this))
-    for (auto &dest : term->getDestinations())
+    for (auto &dest : term->getBasicBlockOperands())
       dest.drop();
 }
 
@@ -224,14 +224,14 @@
 }
 
 /// Return the list of destination entries that this terminator branches to.
-MutableArrayRef<BBDestination> TerminatorInst::getDestinations() {
+MutableArrayRef<BasicBlockOperand> TerminatorInst::getBasicBlockOperands() {
   switch (getKind()) {
   case Kind::Operation:
     llvm_unreachable("not a terminator");
   case Kind::Branch:
-    return cast<BranchInst>(this)->getDestinations();
+    return cast<BranchInst>(this)->getBasicBlockOperands();
   case Kind::CondBranch:
-    return cast<CondBranchInst>(this)->getDestinations();
+    return cast<CondBranchInst>(this)->getBasicBlockOperands();
   case Kind::Return:
     // Return has no basic block successors.
     return {};