//===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- 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
//
//===----------------------------------------------------------------------===//
//
// This is the internal state used for llvm translation for block literals.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_CODEGEN_CGBLOCKS_H
#define LLVM_CLANG_LIB_CODEGEN_CGBLOCKS_H

#include "CGBuilder.h"
#include "CGCall.h"
#include "CGValue.h"
#include "CodeGenFunction.h"
#include "CodeGenTypes.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Type.h"
#include "clang/Basic/TargetInfo.h"

namespace llvm {
class Value;
}

namespace clang {
namespace CodeGen {

class CGBlockInfo;

// Flags stored in __block variables.
enum BlockByrefFlags {
  BLOCK_BYREF_HAS_COPY_DISPOSE         = (1   << 25), // compiler
  BLOCK_BYREF_LAYOUT_MASK              = (0xF << 28), // compiler
  BLOCK_BYREF_LAYOUT_EXTENDED          = (1   << 28),
  BLOCK_BYREF_LAYOUT_NON_OBJECT        = (2   << 28),
  BLOCK_BYREF_LAYOUT_STRONG            = (3   << 28),
  BLOCK_BYREF_LAYOUT_WEAK              = (4   << 28),
  BLOCK_BYREF_LAYOUT_UNRETAINED        = (5   << 28)
};

enum BlockLiteralFlags {
  BLOCK_IS_NOESCAPE      =  (1 << 23),
  BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
  BLOCK_HAS_CXX_OBJ =       (1 << 26),
  BLOCK_IS_GLOBAL =         (1 << 28),
  BLOCK_USE_STRET =         (1 << 29),
  BLOCK_HAS_SIGNATURE  =    (1 << 30),
  BLOCK_HAS_EXTENDED_LAYOUT = (1u << 31)
};
class BlockFlags {
  uint32_t flags;

public:
  BlockFlags(uint32_t flags) : flags(flags) {}
  BlockFlags() : flags(0) {}
  BlockFlags(BlockLiteralFlags flag) : flags(flag) {}
  BlockFlags(BlockByrefFlags flag) : flags(flag) {}

  uint32_t getBitMask() const { return flags; }
  bool empty() const { return flags == 0; }

  friend BlockFlags operator|(BlockFlags l, BlockFlags r) {
    return BlockFlags(l.flags | r.flags);
  }
  friend BlockFlags &operator|=(BlockFlags &l, BlockFlags r) {
    l.flags |= r.flags;
    return l;
  }
  friend bool operator&(BlockFlags l, BlockFlags r) {
    return (l.flags & r.flags);
  }
  bool operator==(BlockFlags r) {
    return (flags == r.flags);
  }
};
inline BlockFlags operator|(BlockLiteralFlags l, BlockLiteralFlags r) {
  return BlockFlags(l) | BlockFlags(r);
}

enum BlockFieldFlag_t {
  BLOCK_FIELD_IS_OBJECT   = 0x03,  /* id, NSObject, __attribute__((NSObject)),
                                    block, ... */
  BLOCK_FIELD_IS_BLOCK    = 0x07,  /* a block variable */

  BLOCK_FIELD_IS_BYREF    = 0x08,  /* the on stack structure holding the __block
                                    variable */
  BLOCK_FIELD_IS_WEAK     = 0x10,  /* declared __weak, only used in byref copy
                                    helpers */
  BLOCK_FIELD_IS_ARC      = 0x40,  /* field has ARC-specific semantics */
  BLOCK_BYREF_CALLER      = 128,   /* called from __block (byref) copy/dispose
                                      support routines */
  BLOCK_BYREF_CURRENT_MAX = 256
};

class BlockFieldFlags {
  uint32_t flags;

  BlockFieldFlags(uint32_t flags) : flags(flags) {}
public:
  BlockFieldFlags() : flags(0) {}
  BlockFieldFlags(BlockFieldFlag_t flag) : flags(flag) {}

  uint32_t getBitMask() const { return flags; }
  bool empty() const { return flags == 0; }

  /// Answers whether the flags indicate that this field is an object
  /// or block pointer that requires _Block_object_assign/dispose.
  bool isSpecialPointer() const { return flags & BLOCK_FIELD_IS_OBJECT; }

  friend BlockFieldFlags operator|(BlockFieldFlags l, BlockFieldFlags r) {
    return BlockFieldFlags(l.flags | r.flags);
  }
  friend BlockFieldFlags &operator|=(BlockFieldFlags &l, BlockFieldFlags r) {
    l.flags |= r.flags;
    return l;
  }
  friend bool operator&(BlockFieldFlags l, BlockFieldFlags r) {
    return (l.flags & r.flags);
  }
  bool operator==(BlockFieldFlags Other) const {
    return flags == Other.flags;
  }
};
inline BlockFieldFlags operator|(BlockFieldFlag_t l, BlockFieldFlag_t r) {
  return BlockFieldFlags(l) | BlockFieldFlags(r);
}

/// Information about the layout of a __block variable.
class BlockByrefInfo {
public:
  llvm::StructType *Type;
  unsigned FieldIndex;
  CharUnits ByrefAlignment;
  CharUnits FieldOffset;
};

/// Represents a type of copy/destroy operation that should be performed for an
/// entity that's captured by a block.
enum class BlockCaptureEntityKind {
  None,
  CXXRecord, // Copy or destroy
  AddressDiscriminatedPointerAuth,
  ARCWeak,
  ARCStrong,
  NonTrivialCStruct,
  BlockObject, // Assign or release
};

/// CGBlockInfo - Information to generate a block literal.
class CGBlockInfo {
public:
  /// Name - The name of the block, kindof.
  StringRef Name;

  /// The field index of 'this' within the block, if there is one.
  unsigned CXXThisIndex;

  class Capture {
    uintptr_t Data;
    EHScopeStack::stable_iterator Cleanup;
    CharUnits::QuantityType Offset;

    /// Type of the capture field. Normally, this is identical to the type of
    /// the capture's VarDecl, but can be different if there is an enclosing
    /// lambda.
    QualType FieldType;

  public:
    bool isIndex() const { return (Data & 1) != 0; }
    bool isConstant() const { return !isIndex(); }

    unsigned getIndex() const {
      assert(isIndex());
      return Data >> 1;
    }
    CharUnits getOffset() const {
      assert(isIndex());
      return CharUnits::fromQuantity(Offset);
    }
    EHScopeStack::stable_iterator getCleanup() const {
      assert(isIndex());
      return Cleanup;
    }
    void setCleanup(EHScopeStack::stable_iterator cleanup) {
      assert(isIndex());
      Cleanup = cleanup;
    }

    llvm::Value *getConstant() const {
      assert(isConstant());
      return reinterpret_cast<llvm::Value*>(Data);
    }

    QualType fieldType() const {
      return FieldType;
    }

    static Capture
    makeIndex(unsigned index, CharUnits offset, QualType FieldType,
              BlockCaptureEntityKind CopyKind, BlockFieldFlags CopyFlags,
              BlockCaptureEntityKind DisposeKind, BlockFieldFlags DisposeFlags,
              const BlockDecl::Capture *Cap) {
      Capture v;
      v.Data = (index << 1) | 1;
      v.Offset = offset.getQuantity();
      v.FieldType = FieldType;
      v.CopyKind = CopyKind;
      v.CopyFlags = CopyFlags;
      v.DisposeKind = DisposeKind;
      v.DisposeFlags = DisposeFlags;
      v.Cap = Cap;
      return v;
    }

    static Capture makeConstant(llvm::Value *value,
                                const BlockDecl::Capture *Cap) {
      Capture v;
      v.Data = reinterpret_cast<uintptr_t>(value);
      v.Cap = Cap;
      return v;
    }

    bool isConstantOrTrivial() const {
      return CopyKind == BlockCaptureEntityKind::None &&
             DisposeKind == BlockCaptureEntityKind::None;
    }

    BlockCaptureEntityKind CopyKind = BlockCaptureEntityKind::None,
                           DisposeKind = BlockCaptureEntityKind::None;
    BlockFieldFlags CopyFlags, DisposeFlags;
    const BlockDecl::Capture *Cap;
  };

  /// CanBeGlobal - True if the block can be global, i.e. it has
  /// no non-constant captures.
  bool CanBeGlobal : 1;

  /// True if the block has captures that would necessitate custom copy or
  /// dispose helper functions if the block were escaping.
  bool NeedsCopyDispose : 1;

  /// Indicates whether the block is non-escaping.
  bool NoEscape : 1;

  /// HasCXXObject - True if the block's custom copy/dispose functions
  /// need to be run even in GC mode.
  bool HasCXXObject : 1;

  /// UsesStret : True if the block uses an stret return.  Mutable
  /// because it gets set later in the block-creation process.
  mutable bool UsesStret : 1;

  /// HasCapturedVariableLayout : True if block has captured variables
  /// and their layout meta-data has been generated.
  bool HasCapturedVariableLayout : 1;

  /// Indicates whether an object of a non-external C++ class is captured. This
  /// bit is used to determine the linkage of the block copy/destroy helper
  /// functions.
  bool CapturesNonExternalType : 1;

  /// Mapping from variables to pointers to captures in SortedCaptures.
  llvm::DenseMap<const VarDecl *, Capture *> Captures;

  /// The block's captures. Non-constant captures are sorted by their offsets.
  llvm::SmallVector<Capture, 4> SortedCaptures;

  // Currently we assume that block-pointer types are never signed.
  RawAddress LocalAddress;
  llvm::StructType *StructureType;
  const BlockDecl *Block;
  const BlockExpr *BlockExpression;
  CharUnits BlockSize;
  CharUnits BlockAlign;
  CharUnits CXXThisOffset;

  // Offset of the gap caused by block header having a smaller
  // alignment than the alignment of the block descriptor. This
  // is the gap offset before the first capturued field.
  CharUnits BlockHeaderForcedGapOffset;
  // Gap size caused by aligning first field after block header.
  // This could be zero if no forced alignment is required.
  CharUnits BlockHeaderForcedGapSize;

  void buildCaptureMap() {
    for (auto &C : SortedCaptures)
      Captures[C.Cap->getVariable()] = &C;
  }

  const Capture &getCapture(const VarDecl *var) const {
    return const_cast<CGBlockInfo*>(this)->getCapture(var);
  }
  Capture &getCapture(const VarDecl *var) {
    auto it = Captures.find(var);
    assert(it != Captures.end() && "no entry for variable!");
    return *it->second;
  }

  const BlockDecl *getBlockDecl() const { return Block; }
  const BlockExpr *getBlockExpr() const {
    assert(BlockExpression);
    assert(BlockExpression->getBlockDecl() == Block);
    return BlockExpression;
  }

  CGBlockInfo(const BlockDecl *blockDecl, StringRef Name);
};

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

#endif
