//===----- 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"

// FIXME: Restructure so we don't have to expose so much stuff.
#include "ABIInfo.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()->getPointerElementType()->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
