//===-- llvm/iTerminators.h - Termintator instruction nodes -----*- C++ -*-===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file contains the declarations for all the subclasses of the Instruction
// class which represent "terminator" instructions.  Terminator instructions are
// the only instructions allowed and required to terminate a BasicBlock.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ITERMINATORS_H
#define LLVM_ITERMINATORS_H

#include "llvm/InstrTypes.h"

//===---------------------------------------------------------------------------
// ReturnInst - Return a value (possibly void), from a function.  Execution does
//              not continue in this function any longer.
//
class ReturnInst : public TerminatorInst {
  ReturnInst(const ReturnInst &RI) : TerminatorInst(Instruction::Ret) {
    if (RI.Operands.size()) {
      assert(RI.Operands.size() == 1 && "Return insn can only have 1 operand!");
      Operands.reserve(1);
      Operands.push_back(Use(RI.Operands[0], this));
    }
  }
public:
  ReturnInst(Value *RetVal = 0, Instruction *InsertBefore = 0)
    : TerminatorInst(Instruction::Ret, InsertBefore) {
    if (RetVal) {
      Operands.reserve(1);
      Operands.push_back(Use(RetVal, this));
    }
  }

  virtual Instruction *clone() const { return new ReturnInst(*this); }

  inline const Value *getReturnValue() const {
    return Operands.size() ? Operands[0].get() : 0; 
  }
  inline       Value *getReturnValue()       {
    return Operands.size() ? Operands[0].get() : 0;
  }

  virtual const BasicBlock *getSuccessor(unsigned idx) const {
    assert(0 && "ReturnInst has no successors!");
    abort();
    return 0;
  }
  virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
    assert(0 && "ReturnInst has no successors!");
  }
  virtual unsigned getNumSuccessors() const { return 0; }

  // Methods for support type inquiry through isa, cast, and dyn_cast:
  static inline bool classof(const ReturnInst *) { return true; }
  static inline bool classof(const Instruction *I) {
    return (I->getOpcode() == Instruction::Ret);
  }
  static inline bool classof(const Value *V) {
    return isa<Instruction>(V) && classof(cast<Instruction>(V));
  }
};

//===---------------------------------------------------------------------------
// BranchInst - Conditional or Unconditional Branch instruction.
//
class BranchInst : public TerminatorInst {
  BranchInst(const BranchInst &BI);
public:
  // If cond = null, then is an unconditional br...
  BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *cond = 0,
             Instruction *InsertBefore = 0);
  BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = 0);

  virtual Instruction *clone() const { return new BranchInst(*this); }

  inline bool isUnconditional() const { return Operands.size() == 1; }
  inline bool isConditional()   const { return Operands.size() == 3; }

  inline Value *getCondition() const {
    return isUnconditional() ? 0 : (Value*)Operands[2].get();
  }

  void setCondition(Value *V) {
    assert(isConditional() && "Cannot set condition of unconditional branch!");
    setOperand(2, V);
  }

  // setUnconditionalDest - Change the current branch to an unconditional branch
  // targeting the specified block.
  //
  void setUnconditionalDest(BasicBlock *Dest) {
    if (isConditional()) Operands.erase(Operands.begin()+1, Operands.end());
    Operands[0] = (Value*)Dest;
  }

  virtual const BasicBlock *getSuccessor(unsigned i) const {
    assert(i < getNumSuccessors() && "Successor # out of range for Branch!");
    return (i == 0) ? cast<BasicBlock>(Operands[0].get()) : 
                      cast<BasicBlock>(Operands[1].get());
  }
  inline BasicBlock *getSuccessor(unsigned idx) {
    return (BasicBlock*)((const BranchInst *)this)->getSuccessor(idx);
  }

  virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
    assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
    Operands[idx] = (Value*)NewSucc;
  }

  virtual unsigned getNumSuccessors() const { return 1+isConditional(); }

  // Methods for support type inquiry through isa, cast, and dyn_cast:
  static inline bool classof(const BranchInst *) { return true; }
  static inline bool classof(const Instruction *I) {
    return (I->getOpcode() == Instruction::Br);
  }
  static inline bool classof(const Value *V) {
    return isa<Instruction>(V) && classof(cast<Instruction>(V));
  }
};


//===---------------------------------------------------------------------------
// SwitchInst - Multiway switch
//
class SwitchInst : public TerminatorInst {
  // Operand[0]    = Value to switch on
  // Operand[1]    = Default basic block destination
  // Operand[2n  ] = Value to match
  // Operand[2n+1] = BasicBlock to go to on match
  SwitchInst(const SwitchInst &RI);
public:
  SwitchInst(Value *Value, BasicBlock *Default, Instruction *InsertBefore = 0);

  virtual Instruction *clone() const { return new SwitchInst(*this); }

  // Accessor Methods for Switch stmt
  //
  inline const Value *getCondition() const { return Operands[0]; }
  inline       Value *getCondition()       { return Operands[0]; }
  inline const BasicBlock *getDefaultDest() const {
    return cast<BasicBlock>(Operands[1].get());
  }
  inline       BasicBlock *getDefaultDest()       {
    return cast<BasicBlock>(Operands[1].get());
  }

  /// addCase - Add an entry to the switch instruction...
  ///
  void addCase(Constant *OnVal, BasicBlock *Dest);

  /// removeCase - This method removes the specified successor from the switch
  /// instruction.  Note that this cannot be used to remove the default
  /// destination (successor #0).
  ///
  void removeCase(unsigned idx);

  virtual const BasicBlock *getSuccessor(unsigned idx) const {
    assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
    return cast<BasicBlock>(Operands[idx*2+1].get());
  }
  inline BasicBlock *getSuccessor(unsigned idx) {
    assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
    return cast<BasicBlock>(Operands[idx*2+1].get());
  }

  virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
    assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
    Operands[idx*2+1] = (Value*)NewSucc;
  }

  // getSuccessorValue - Return the value associated with the specified
  // successor.
  inline const Constant *getSuccessorValue(unsigned idx) const {
    assert(idx < getNumSuccessors() && "Successor # out of range!");
    return cast<Constant>(Operands[idx*2].get());
  }
  inline Constant *getSuccessorValue(unsigned idx) {
    assert(idx < getNumSuccessors() && "Successor # out of range!");
    return cast<Constant>(Operands[idx*2].get());
  }
  virtual unsigned getNumSuccessors() const { return Operands.size()/2; }

  // 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) {
    return (I->getOpcode() == Instruction::Switch);
  }
  static inline bool classof(const Value *V) {
    return isa<Instruction>(V) && classof(cast<Instruction>(V));
  }
};


//===---------------------------------------------------------------------------
// InvokeInst - Invoke instruction
//
class InvokeInst : public TerminatorInst {
  InvokeInst(const InvokeInst &BI);
public:
  InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
	     const std::vector<Value*> &Params, const std::string &Name = "",
             Instruction *InsertBefore = 0);

  virtual Instruction *clone() const { return new InvokeInst(*this); }

  bool mayWriteToMemory() const { return true; }

  // getCalledFunction - Return the function called, or null if this is an
  // indirect function invocation...
  //
  inline const Function *getCalledFunction() const {
    return dyn_cast<Function>(Operands[0].get());
  }
  inline Function *getCalledFunction() {
    return dyn_cast<Function>(Operands[0].get());
  }

  // getCalledValue - Get a pointer to a function that is invoked by this inst.
  inline const Value *getCalledValue() const { return Operands[0]; }
  inline       Value *getCalledValue()       { return Operands[0]; }

  // get*Dest - Return the destination basic blocks...
  inline const BasicBlock *getNormalDest() const {
    return cast<BasicBlock>(Operands[1].get());
  }
  inline       BasicBlock *getNormalDest() {
    return cast<BasicBlock>(Operands[1].get());
  }
  inline const BasicBlock *getExceptionalDest() const {
    return cast<BasicBlock>(Operands[2].get());
  }
  inline       BasicBlock *getExceptionalDest() {
    return cast<BasicBlock>(Operands[2].get());
  }

  inline void setNormalDest(BasicBlock *B){
    Operands[1] = (Value*)B;
  }

  inline void setExceptionalDest(BasicBlock *B){
    Operands[2] = (Value*)B;
  }

  virtual const BasicBlock *getSuccessor(unsigned i) const {
    assert(i < 2 && "Successor # out of range for invoke!");
    return i == 0 ? getNormalDest() : getExceptionalDest();
  }
  inline BasicBlock *getSuccessor(unsigned i) {
    assert(i < 2 && "Successor # out of range for invoke!");
    return i == 0 ? getNormalDest() : getExceptionalDest();
  }

  virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
    assert(idx < 2 && "Successor # out of range for invoke!");
    Operands[idx+1] = (Value*)NewSucc;
  }

  virtual unsigned getNumSuccessors() const { return 2; }

  // Methods for support type inquiry through isa, cast, and dyn_cast:
  static inline bool classof(const InvokeInst *) { return true; }
  static inline bool classof(const Instruction *I) {
    return (I->getOpcode() == Instruction::Invoke);
  }
  static inline bool classof(const Value *V) {
    return isa<Instruction>(V) && classof(cast<Instruction>(V));
  }
};


//===---------------------------------------------------------------------------
/// UnwindInst - Immediately exit the current function, unwinding the stack
/// until an invoke instruction is found.
///
struct UnwindInst : public TerminatorInst {
  UnwindInst(Instruction *InsertBefore = 0)
    : TerminatorInst(Instruction::Unwind, InsertBefore) {
  }

  virtual Instruction *clone() const { return new UnwindInst(); }

  virtual const BasicBlock *getSuccessor(unsigned idx) const {
    assert(0 && "UnwindInst has no successors!");
    abort();
    return 0;
  }
  virtual void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
    assert(0 && "UnwindInst has no successors!");
  }
  virtual unsigned getNumSuccessors() const { return 0; }

  // Methods for support type inquiry through isa, cast, and dyn_cast:
  static inline bool classof(const UnwindInst *) { return true; }
  static inline bool classof(const Instruction *I) {
    return I->getOpcode() == Instruction::Unwind;
  }
  static inline bool classof(const Value *V) {
    return isa<Instruction>(V) && classof(cast<Instruction>(V));
  }
};

#endif
