//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// These classes wrap the information about a call or function
// definition used to handle ABI compliancy.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H
#define LLVM_CLANG_LIB_CODEGEN_CGCALL_H

#include "CGValue.h"
#include "EHScopeStack.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/Type.h"
#include "llvm/IR/Value.h"

namespace llvm {
class Type;
class Value;
} // namespace llvm

namespace clang {
class Decl;
class FunctionDecl;
class VarDecl;

namespace CodeGen {

/// Abstract information about a function or function prototype.
class CGCalleeInfo {
  /// The function prototype of the callee.
  const FunctionProtoType *CalleeProtoTy;
  /// The function declaration of the callee.
  GlobalDecl CalleeDecl;

public:
  explicit CGCalleeInfo() : CalleeProtoTy(nullptr) {}
  CGCalleeInfo(const FunctionProtoType *calleeProtoTy, GlobalDecl calleeDecl)
      : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
  CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
      : CalleeProtoTy(calleeProtoTy) {}
  CGCalleeInfo(GlobalDecl calleeDecl)
      : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}

  const FunctionProtoType *getCalleeFunctionProtoType() const {
    return CalleeProtoTy;
  }
  const GlobalDecl getCalleeDecl() const { return CalleeDecl; }
};

/// All available information about a concrete callee.
class CGCallee {
  enum class SpecialKind : uintptr_t {
    Invalid,
    Builtin,
    PseudoDestructor,
    Virtual,

    Last = Virtual
  };

  struct BuiltinInfoStorage {
    const FunctionDecl *Decl;
    unsigned ID;
  };
  struct PseudoDestructorInfoStorage {
    const CXXPseudoDestructorExpr *Expr;
  };
  struct VirtualInfoStorage {
    const CallExpr *CE;
    GlobalDecl MD;
    Address Addr;
    llvm::FunctionType *FTy;
  };

  SpecialKind KindOrFunctionPointer;
  union {
    CGCalleeInfo AbstractInfo;
    BuiltinInfoStorage BuiltinInfo;
    PseudoDestructorInfoStorage PseudoDestructorInfo;
    VirtualInfoStorage VirtualInfo;
  };

  explicit CGCallee(SpecialKind kind) : KindOrFunctionPointer(kind) {}

  CGCallee(const FunctionDecl *builtinDecl, unsigned builtinID)
      : KindOrFunctionPointer(SpecialKind::Builtin) {
    BuiltinInfo.Decl = builtinDecl;
    BuiltinInfo.ID = builtinID;
  }

public:
  CGCallee() : KindOrFunctionPointer(SpecialKind::Invalid) {}

  /// Construct a callee.  Call this constructor directly when this
  /// isn't a direct call.
  CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr)
      : KindOrFunctionPointer(
            SpecialKind(reinterpret_cast<uintptr_t>(functionPtr))) {
    AbstractInfo = abstractInfo;
    assert(functionPtr && "configuring callee without function pointer");
    assert(functionPtr->getType()->isPointerTy());
    assert(functionPtr->getType()->isOpaquePointerTy() ||
           functionPtr->getType()->getNonOpaquePointerElementType()
               ->isFunctionTy());
  }

  static CGCallee forBuiltin(unsigned builtinID,
                             const FunctionDecl *builtinDecl) {
    CGCallee result(SpecialKind::Builtin);
    result.BuiltinInfo.Decl = builtinDecl;
    result.BuiltinInfo.ID = builtinID;
    return result;
  }

  static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E) {
    CGCallee result(SpecialKind::PseudoDestructor);
    result.PseudoDestructorInfo.Expr = E;
    return result;
  }

  static CGCallee forDirect(llvm::Constant *functionPtr,
                            const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
    return CGCallee(abstractInfo, functionPtr);
  }

  static CGCallee forDirect(llvm::FunctionCallee functionPtr,
                            const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
    return CGCallee(abstractInfo, functionPtr.getCallee());
  }

  static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr,
                             llvm::FunctionType *FTy) {
    CGCallee result(SpecialKind::Virtual);
    result.VirtualInfo.CE = CE;
    result.VirtualInfo.MD = MD;
    result.VirtualInfo.Addr = Addr;
    result.VirtualInfo.FTy = FTy;
    return result;
  }

  bool isBuiltin() const {
    return KindOrFunctionPointer == SpecialKind::Builtin;
  }
  const FunctionDecl *getBuiltinDecl() const {
    assert(isBuiltin());
    return BuiltinInfo.Decl;
  }
  unsigned getBuiltinID() const {
    assert(isBuiltin());
    return BuiltinInfo.ID;
  }

  bool isPseudoDestructor() const {
    return KindOrFunctionPointer == SpecialKind::PseudoDestructor;
  }
  const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
    assert(isPseudoDestructor());
    return PseudoDestructorInfo.Expr;
  }

  bool isOrdinary() const {
    return uintptr_t(KindOrFunctionPointer) > uintptr_t(SpecialKind::Last);
  }
  CGCalleeInfo getAbstractInfo() const {
    if (isVirtual())
      return VirtualInfo.MD;
    assert(isOrdinary());
    return AbstractInfo;
  }
  llvm::Value *getFunctionPointer() const {
    assert(isOrdinary());
    return reinterpret_cast<llvm::Value *>(uintptr_t(KindOrFunctionPointer));
  }
  void setFunctionPointer(llvm::Value *functionPtr) {
    assert(isOrdinary());
    KindOrFunctionPointer =
        SpecialKind(reinterpret_cast<uintptr_t>(functionPtr));
  }

  bool isVirtual() const {
    return KindOrFunctionPointer == SpecialKind::Virtual;
  }
  const CallExpr *getVirtualCallExpr() const {
    assert(isVirtual());
    return VirtualInfo.CE;
  }
  GlobalDecl getVirtualMethodDecl() const {
    assert(isVirtual());
    return VirtualInfo.MD;
  }
  Address getThisAddress() const {
    assert(isVirtual());
    return VirtualInfo.Addr;
  }
  llvm::FunctionType *getVirtualFunctionType() const {
    assert(isVirtual());
    return VirtualInfo.FTy;
  }

  /// If this is a delayed callee computation of some sort, prepare
  /// a concrete callee.
  CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const;
};

struct CallArg {
private:
  union {
    RValue RV;
    LValue LV; /// The argument is semantically a load from this l-value.
  };
  bool HasLV;

  /// A data-flow flag to make sure getRValue and/or copyInto are not
  /// called twice for duplicated IR emission.
  mutable bool IsUsed;

public:
  QualType Ty;
  CallArg(RValue rv, QualType ty)
      : RV(rv), HasLV(false), IsUsed(false), Ty(ty) {}
  CallArg(LValue lv, QualType ty)
      : LV(lv), HasLV(true), IsUsed(false), Ty(ty) {}
  bool hasLValue() const { return HasLV; }
  QualType getType() const { return Ty; }

  /// \returns an independent RValue. If the CallArg contains an LValue,
  /// a temporary copy is returned.
  RValue getRValue(CodeGenFunction &CGF) const;

  LValue getKnownLValue() const {
    assert(HasLV && !IsUsed);
    return LV;
  }
  RValue getKnownRValue() const {
    assert(!HasLV && !IsUsed);
    return RV;
  }
  void setRValue(RValue _RV) {
    assert(!HasLV);
    RV = _RV;
  }

  bool isAggregate() const { return HasLV || RV.isAggregate(); }

  void copyInto(CodeGenFunction &CGF, Address A) const;
};

/// CallArgList - Type for representing both the value and type of
/// arguments in a call.
class CallArgList : public SmallVector<CallArg, 8> {
public:
  CallArgList() : StackBase(nullptr) {}

  struct Writeback {
    /// The original argument.  Note that the argument l-value
    /// is potentially null.
    LValue Source;

    /// The temporary alloca.
    Address Temporary;

    /// A value to "use" after the writeback, or null.
    llvm::Value *ToUse;
  };

  struct CallArgCleanup {
    EHScopeStack::stable_iterator Cleanup;

    /// The "is active" insertion point.  This instruction is temporary and
    /// will be removed after insertion.
    llvm::Instruction *IsActiveIP;
  };

  void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); }

  void addUncopiedAggregate(LValue LV, QualType type) {
    push_back(CallArg(LV, type));
  }

  /// Add all the arguments from another CallArgList to this one. After doing
  /// this, the old CallArgList retains its list of arguments, but must not
  /// be used to emit a call.
  void addFrom(const CallArgList &other) {
    insert(end(), other.begin(), other.end());
    Writebacks.insert(Writebacks.end(), other.Writebacks.begin(),
                      other.Writebacks.end());
    CleanupsToDeactivate.insert(CleanupsToDeactivate.end(),
                                other.CleanupsToDeactivate.begin(),
                                other.CleanupsToDeactivate.end());
    assert(!(StackBase && other.StackBase) && "can't merge stackbases");
    if (!StackBase)
      StackBase = other.StackBase;
  }

  void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse) {
    Writeback writeback = {srcLV, temporary, toUse};
    Writebacks.push_back(writeback);
  }

  bool hasWritebacks() const { return !Writebacks.empty(); }

  typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator>
      writeback_const_range;

  writeback_const_range writebacks() const {
    return writeback_const_range(Writebacks.begin(), Writebacks.end());
  }

  void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup,
                                 llvm::Instruction *IsActiveIP) {
    CallArgCleanup ArgCleanup;
    ArgCleanup.Cleanup = Cleanup;
    ArgCleanup.IsActiveIP = IsActiveIP;
    CleanupsToDeactivate.push_back(ArgCleanup);
  }

  ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const {
    return CleanupsToDeactivate;
  }

  void allocateArgumentMemory(CodeGenFunction &CGF);
  llvm::Instruction *getStackBase() const { return StackBase; }
  void freeArgumentMemory(CodeGenFunction &CGF) const;

  /// Returns if we're using an inalloca struct to pass arguments in
  /// memory.
  bool isUsingInAlloca() const { return StackBase; }

private:
  SmallVector<Writeback, 1> Writebacks;

  /// Deactivate these cleanups immediately before making the call.  This
  /// is used to cleanup objects that are owned by the callee once the call
  /// occurs.
  SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;

  /// The stacksave call.  It dominates all of the argument evaluation.
  llvm::CallInst *StackBase;
};

/// FunctionArgList - Type for representing both the decl and type
/// of parameters to a function. The decl must be either a
/// ParmVarDecl or ImplicitParamDecl.
class FunctionArgList : public SmallVector<const VarDecl *, 16> {};

/// ReturnValueSlot - Contains the address where the return value of a
/// function can be stored, and whether the address is volatile or not.
class ReturnValueSlot {
  Address Addr = Address::invalid();

  // Return value slot flags
  unsigned IsVolatile : 1;
  unsigned IsUnused : 1;
  unsigned IsExternallyDestructed : 1;

public:
  ReturnValueSlot()
      : IsVolatile(false), IsUnused(false), IsExternallyDestructed(false) {}
  ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false,
                  bool IsExternallyDestructed = false)
      : Addr(Addr), IsVolatile(IsVolatile), IsUnused(IsUnused),
        IsExternallyDestructed(IsExternallyDestructed) {}

  bool isNull() const { return !Addr.isValid(); }
  bool isVolatile() const { return IsVolatile; }
  Address getValue() const { return Addr; }
  bool isUnused() const { return IsUnused; }
  bool isExternallyDestructed() const { return IsExternallyDestructed; }
};

} // end namespace CodeGen
} // end namespace clang

#endif
