//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the CallSite class, which is a handy wrapper for code that
// wants to treat Call and Invoke instructions in a generic way. When in non-
// mutation context (e.g. an analysis) ImmutableCallSite should be used.
// Finally, when some degree of customization is necessary between these two
// extremes, CallSiteBase<> can be supplied with fine-tuned parameters.
//
// NOTE: These classes are supposed to have "value semantics". So they should be
// passed by value, not by reference; they should not be "new"ed or "delete"d.
// They are efficiently copyable, assignable and constructable, with cost
// equivalent to copying a pointer (notice that they have only a single data
// member). The internal representation carries a flag which indicates which of
// the two variants is enclosed. This allows for cheaper checks when various
// accessors of CallSite are employed.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_CALLSITE_H
#define LLVM_SUPPORT_CALLSITE_H

#include "llvm/ADT/PointerIntPair.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Instructions.h"

namespace llvm {

class CallInst;
class InvokeInst;

template <typename FunTy = const Function,
          typename ValTy = const Value,
          typename UserTy = const User,
          typename InstrTy = const Instruction,
          typename CallTy = const CallInst,
          typename InvokeTy = const InvokeInst,
          typename IterTy = User::const_op_iterator>
class CallSiteBase {
protected:
  PointerIntPair<InstrTy*, 1, bool> I;
public:
  CallSiteBase() : I(0, false) {}
  CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
  CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
  CallSiteBase(ValTy *II) { *this = get(II); }
protected:
  /// CallSiteBase::get - This static method is sort of like a constructor.  It
  /// will create an appropriate call site for a Call or Invoke instruction, but
  /// it can also create a null initialized CallSiteBase object for something
  /// which is NOT a call site.
  ///
  static CallSiteBase get(ValTy *V) {
    if (InstrTy *II = dyn_cast<InstrTy>(V)) {
      if (II->getOpcode() == Instruction::Call)
        return CallSiteBase(static_cast<CallTy*>(II));
      else if (II->getOpcode() == Instruction::Invoke)
        return CallSiteBase(static_cast<InvokeTy*>(II));
    }
    return CallSiteBase();
  }
public:
  /// isCall - true if a CallInst is enclosed.
  /// Note that !isCall() does not mean it is an InvokeInst enclosed,
  /// it also could signify a NULL Instruction pointer.
  bool isCall() const { return I.getInt(); }

  /// isInvoke - true if a InvokeInst is enclosed.
  ///
  bool isInvoke() const { return getInstruction() && !I.getInt(); }

  InstrTy *getInstruction() const { return I.getPointer(); }
  InstrTy *operator->() const { return I.getPointer(); }
  operator bool() const { return I.getPointer(); }

  /// getCalledValue - Return the pointer to function that is being called.
  ///
  ValTy *getCalledValue() const {
    assert(getInstruction() && "Not a call or invoke instruction!");
    return *getCallee();
  }

  /// getCalledFunction - Return the function being called if this is a direct
  /// call, otherwise return null (if it's an indirect call).
  ///
  FunTy *getCalledFunction() const {
    return dyn_cast<FunTy>(getCalledValue());
  }

  /// setCalledFunction - Set the callee to the specified value.
  ///
  void setCalledFunction(Value *V) {
    assert(getInstruction() && "Not a call or invoke instruction!");
    *getCallee() = V;
  }

  /// isCallee - Determine whether the passed iterator points to the
  /// callee operand's Use.
  ///
  bool isCallee(value_use_iterator<UserTy> UI) const {
    return getCallee() == &UI.getUse();
  }

  ValTy *getArgument(unsigned ArgNo) const {
    assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
    return *(arg_begin() + ArgNo);
  }

  void setArgument(unsigned ArgNo, Value* newVal) {
    assert(getInstruction() && "Not a call or invoke instruction!");
    assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
    getInstruction()->setOperand(ArgNo, newVal);
  }

  /// Given a value use iterator, returns the argument that corresponds to it.
  /// Iterator must actually correspond to an argument.
  unsigned getArgumentNo(value_use_iterator<UserTy> I) const {
    assert(getInstruction() && "Not a call or invoke instruction!");
    assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end()
           && "Argument # out of range!");
    return &I.getUse() - arg_begin();
  }

  /// arg_iterator - The type of iterator to use when looping over actual
  /// arguments at this call site.
  typedef IterTy arg_iterator;

  /// arg_begin/arg_end - Return iterators corresponding to the actual argument
  /// list for a call site.
  IterTy arg_begin() const {
    assert(getInstruction() && "Not a call or invoke instruction!");
    // Skip non-arguments
    return (*this)->op_begin();
  }

  IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
  bool arg_empty() const { return arg_end() == arg_begin(); }
  unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
  
  /// getType - Return the type of the instruction that generated this call site
  ///
  Type *getType() const { return (*this)->getType(); }

  /// getCaller - Return the caller function for this call site
  ///
  FunTy *getCaller() const { return (*this)->getParent()->getParent(); }

#define CALLSITE_DELEGATE_GETTER(METHOD) \
  InstrTy *II = getInstruction();    \
  return isCall()                        \
    ? cast<CallInst>(II)->METHOD         \
    : cast<InvokeInst>(II)->METHOD

#define CALLSITE_DELEGATE_SETTER(METHOD) \
  InstrTy *II = getInstruction();    \
  if (isCall())                          \
    cast<CallInst>(II)->METHOD;          \
  else                                   \
    cast<InvokeInst>(II)->METHOD

  /// getCallingConv/setCallingConv - get or set the calling convention of the
  /// call.
  CallingConv::ID getCallingConv() const {
    CALLSITE_DELEGATE_GETTER(getCallingConv());
  }
  void setCallingConv(CallingConv::ID CC) {
    CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
  }

  /// getAttributes/setAttributes - get or set the parameter attributes of
  /// the call.
  const AttributeSet &getAttributes() const {
    CALLSITE_DELEGATE_GETTER(getAttributes());
  }
  void setAttributes(const AttributeSet &PAL) {
    CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
  }

  /// \brief Return true if this function has the given attribute.
  bool hasFnAttr(Attribute::AttrKind A) const {
    CALLSITE_DELEGATE_GETTER(hasFnAttr(A));
  }

  /// \brief Return true if the call or the callee has the given attribute.
  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
    CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
  }

  /// @brief Extract the alignment for a call or parameter (0=unknown).
  uint16_t getParamAlignment(uint16_t i) const {
    CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
  }

  /// @brief Return true if the call should not be inlined.
  bool isNoInline() const {
    CALLSITE_DELEGATE_GETTER(isNoInline());
  }
  void setIsNoInline(bool Value = true) {
    CALLSITE_DELEGATE_SETTER(setIsNoInline(Value));
  }

  /// @brief Determine if the call does not access memory.
  bool doesNotAccessMemory() const {
    CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
  }
  void setDoesNotAccessMemory() {
    CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory());
  }

  /// @brief Determine if the call does not access or only reads memory.
  bool onlyReadsMemory() const {
    CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
  }
  void setOnlyReadsMemory() {
    CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
  }

  /// @brief Determine if the call cannot return.
  bool doesNotReturn() const {
    CALLSITE_DELEGATE_GETTER(doesNotReturn());
  }
  void setDoesNotReturn() {
    CALLSITE_DELEGATE_SETTER(setDoesNotReturn());
  }

  /// @brief Determine if the call cannot unwind.
  bool doesNotThrow() const {
    CALLSITE_DELEGATE_GETTER(doesNotThrow());
  }
  void setDoesNotThrow() {
    CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
  }

#undef CALLSITE_DELEGATE_GETTER
#undef CALLSITE_DELEGATE_SETTER

  /// @brief Determine whether this argument is not captured.
  bool doesNotCapture(unsigned ArgNo) const {
    return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
  }

  /// @brief Determine whether this argument is passed by value.
  bool isByValArgument(unsigned ArgNo) const {
    return paramHasAttr(ArgNo + 1, Attribute::ByVal);
  }

  /// hasArgument - Returns true if this CallSite passes the given Value* as an
  /// argument to the called function.
  bool hasArgument(const Value *Arg) const {
    for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E;
         ++AI)
      if (AI->get() == Arg)
        return true;
    return false;
  }

private:
  unsigned getArgumentEndOffset() const {
    if (isCall())
      return 1; // Skip Callee
    else
      return 3; // Skip BB, BB, Callee
  }

  IterTy getCallee() const {
    if (isCall()) // Skip Callee
      return cast<CallInst>(getInstruction())->op_end() - 1;
    else // Skip BB, BB, Callee
      return cast<InvokeInst>(getInstruction())->op_end() - 3;
  }
};

class CallSite : public CallSiteBase<Function, Value, User, Instruction,
                                     CallInst, InvokeInst, User::op_iterator> {
  typedef CallSiteBase<Function, Value, User, Instruction,
                       CallInst, InvokeInst, User::op_iterator> Base;
public:
  CallSite() {}
  CallSite(Base B) : Base(B) {}
  CallSite(Value* V) : Base(V) {}
  CallSite(CallInst *CI) : Base(CI) {}
  CallSite(InvokeInst *II) : Base(II) {}
  CallSite(Instruction *II) : Base(II) {}

  bool operator==(const CallSite &CS) const { return I == CS.I; }
  bool operator!=(const CallSite &CS) const { return I != CS.I; }
  bool operator<(const CallSite &CS) const {
    return getInstruction() < CS.getInstruction();
  }

private:
  User::op_iterator getCallee() const;
};

/// ImmutableCallSite - establish a view to a call site for examination
class ImmutableCallSite : public CallSiteBase<> {
  typedef CallSiteBase<> Base;
public:
  ImmutableCallSite(const Value* V) : Base(V) {}
  ImmutableCallSite(const CallInst *CI) : Base(CI) {}
  ImmutableCallSite(const InvokeInst *II) : Base(II) {}
  ImmutableCallSite(const Instruction *II) : Base(II) {}
  ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
};

} // End llvm namespace

#endif
