//===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the internal state used for llvm translation for block literals.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_CODEGEN_CGBLOCKS_H
#define CLANG_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"
#include "llvm/IR/Module.h"

namespace llvm {
  class Module;
  class Constant;
  class Function;
  class GlobalValue;
  class DataLayout;
  class FunctionType;
  class PointerType;
  class Value;
  class LLVMContext;
}

namespace clang {

namespace CodeGen {

class CodeGenModule;
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_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 = (1 << 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);
  }
};
inline BlockFieldFlags operator|(BlockFieldFlag_t l, BlockFieldFlag_t r) {
  return BlockFieldFlags(l) | BlockFieldFlags(r);
}

/// 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;

  public:
    bool isIndex() const { return (Data & 1) != 0; }
    bool isConstant() const { return !isIndex(); }
    unsigned getIndex() const { assert(isIndex()); return Data >> 1; }
    llvm::Value *getConstant() const {
      assert(isConstant());
      return reinterpret_cast<llvm::Value*>(Data);
    }
    EHScopeStack::stable_iterator getCleanup() const {
      assert(isIndex());
      return Cleanup;
    }
    void setCleanup(EHScopeStack::stable_iterator cleanup) {
      assert(isIndex());
      Cleanup = cleanup;
    }

    static Capture makeIndex(unsigned index) {
      Capture v;
      v.Data = (index << 1) | 1;
      return v;
    }

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

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

  /// True if the block needs a custom copy or dispose function.
  bool NeedsCopyDispose : 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;

  /// The mapping of allocated indexes within the block.
  llvm::DenseMap<const VarDecl*, Capture> Captures;  

  llvm::AllocaInst *Address;
  llvm::StructType *StructureType;
  const BlockDecl *Block;
  const BlockExpr *BlockExpression;
  CharUnits BlockSize;
  CharUnits BlockAlign;
  
  // 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;

  /// An instruction which dominates the full-expression that the
  /// block is inside.
  llvm::Instruction *DominatingIP;

  /// The next block in the block-info chain.  Invalid if this block
  /// info is not part of the CGF's block-info chain, which is true
  /// if it corresponds to a global block or a block whose expression
  /// has been encountered.
  CGBlockInfo *NextBlockInfo;

  const Capture &getCapture(const VarDecl *var) const {
    return const_cast<CGBlockInfo*>(this)->getCapture(var);
  }
  Capture &getCapture(const VarDecl *var) {
    llvm::DenseMap<const VarDecl*, Capture>::iterator
      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
