//===--- HeapTypeInfo.h - Utilities for reference-counted types -*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines some routines that are useful for emitting
// types that are single, reference-counted pointers.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_IRGEN_HEAPTYPEINFO_H
#define SWIFT_IRGEN_HEAPTYPEINFO_H

#include "llvm/IR/DerivedTypes.h"
#include "ExtraInhabitants.h"
#include "ReferenceTypeInfo.h"
#include "ScalarTypeInfo.h"
#include "SwiftTargetInfo.h"
#include "GenType.h"

namespace swift {
namespace irgen {

/// \group HeapTypeInfo
  
/// The kind of 'isa' encoding a heap object uses to reference its heap
/// metadata.
enum class IsaEncoding : unsigned char {
  /// The object stores a plain pointer to its heap metadata as its first word.
  Pointer,
  /// The object's isa is managed by the Objective-C runtime and must be
  /// accessed with object_getClass. This is a superset of "Pointer" because
  /// object_getClass is compatible with pointer isas.
  ObjC,
  /// The isa encoding is unknown and must be accessed in a maximally-compatible
  /// way.
  Unknown = ObjC,
};
  
/// HeapTypeInfo - A type designed for use implementing a type
/// which consists solely of something reference-counted.
///
/// Subclasses should implement the following method, returning true
/// if it's known to be OK to use Swift reference-counting on values
/// of this type:
///   ReferenceCounting getReferenceCounting() const;
template <class Impl>
class HeapTypeInfo : public SingleScalarTypeInfo<Impl, ReferenceTypeInfo> {
  typedef SingleScalarTypeInfo<Impl, ReferenceTypeInfo> super;
protected:
  using super::asDerived;
public:
  HeapTypeInfo(llvm::PointerType *storage, Size size, SpareBitVector spareBits,
               Alignment align)
    : super(storage, size, spareBits, align) {}

  bool isSingleRetainablePointer(ResilienceExpansion expansion,
                                 ReferenceCounting *refcounting) const override {
    if (refcounting)
      *refcounting = asDerived().getReferenceCounting();
    return true;
  }
  
  IsaEncoding getIsaEncoding(ResilienceExpansion expansion) const {
    switch (asDerived().getReferenceCounting()) {
    // We can access the isa of pure Swift heap objects directly.
    case ReferenceCounting::Native:
      return IsaEncoding::Pointer;
    // Use the ObjC runtime to access ObjC or mixed-heritage isas.
    case ReferenceCounting::ObjC:
    case ReferenceCounting::Block:
      return IsaEncoding::ObjC;
    case ReferenceCounting::Unknown:
      return IsaEncoding::Unknown;
    case ReferenceCounting::Error:
      llvm_unreachable("errortype doesn't have an isa");
    }
  }

  static const bool IsScalarPOD = false;

  // Emit the copy/destroy operations required by SingleScalarTypeInfo
  // using strong reference counting.
  void emitScalarRelease(IRGenFunction &IGF, llvm::Value *value,
                         Atomicity atomicity) const {
    IGF.emitStrongRelease(value, asDerived().getReferenceCounting(), atomicity);
  }

  void emitScalarFixLifetime(IRGenFunction &IGF, llvm::Value *value) const {
    return IGF.emitFixLifetime(value);
  }

  void emitScalarRetain(IRGenFunction &IGF, llvm::Value *value,
                        Atomicity atomicity) const {
    IGF.emitStrongRetain(value, asDerived().getReferenceCounting(), atomicity);
  }

  // Implement the primary retain/release operations of ReferenceTypeInfo
  // using basic reference counting.
  void strongRetain(IRGenFunction &IGF, Explosion &e,
                    Atomicity atomicity) const override {
    llvm::Value *value = e.claimNext();
    asDerived().emitScalarRetain(IGF, value, atomicity);
  }

  void strongRelease(IRGenFunction &IGF, Explosion &e,
                     Atomicity atomicity) const override {
    llvm::Value *value = e.claimNext();
    asDerived().emitScalarRelease(IGF, value, atomicity);
  }

  void strongRetainUnowned(IRGenFunction &IGF, Explosion &e) const override {
    llvm::Value *value = e.claimNext();
    IGF.emitStrongRetainUnowned(value, asDerived().getReferenceCounting());
  }

  void strongRetainUnownedRelease(IRGenFunction &IGF,
                                  Explosion &e) const override {
    llvm::Value *value = e.claimNext();
    IGF.emitStrongRetainAndUnownedRelease(value,
                                          asDerived().getReferenceCounting());
  }

  void unownedRetain(IRGenFunction &IGF, Explosion &e) const override {
    llvm::Value *value = e.claimNext();
    IGF.emitUnownedRetain(value, asDerived().getReferenceCounting());
  }

  void unownedRelease(IRGenFunction &IGF, Explosion &e) const override {
    llvm::Value *value = e.claimNext();
    IGF.emitUnownedRelease(value, asDerived().getReferenceCounting());
  }

  void unownedLoadStrong(IRGenFunction &IGF, Address src,
                         Explosion &out) const override {
    llvm::Value *value = IGF.emitUnownedLoadStrong(src, this->getStorageType(),
                                           asDerived().getReferenceCounting());
    out.add(value);
  }

  void unownedTakeStrong(IRGenFunction &IGF, Address src,
                         Explosion &out) const override {
    llvm::Value *value = IGF.emitUnownedTakeStrong(src, this->getStorageType(),
                                           asDerived().getReferenceCounting());
    out.add(value);
  }

  void unownedInit(IRGenFunction &IGF, Explosion &in,
                   Address dest) const override {
    IGF.emitUnownedInit(in.claimNext(), dest,
                        asDerived().getReferenceCounting());
  }

  void unownedAssign(IRGenFunction &IGF, Explosion &in,
                     Address dest) const override {
    IGF.emitUnownedAssign(in.claimNext(), dest,
                          asDerived().getReferenceCounting());
  }

  LoadedRef loadRefcountedPtr(IRGenFunction &IGF, SourceLoc loc,
                              Address addr) const override {
    llvm::Value *ptr =
      IGF.emitLoadRefcountedPtr(addr, asDerived().getReferenceCounting());
    return LoadedRef(ptr, true);
  }

  const WeakTypeInfo *createWeakStorageType(TypeConverter &TC) const override {
    return TC.createWeakStorageType(this->getStorageType(),
                                    asDerived().getReferenceCounting());
  }

  const TypeInfo *
  createUnownedStorageType(TypeConverter &TC) const override {
    return TC.createUnownedStorageType(this->getStorageType(),
                                       asDerived().getReferenceCounting());
  }

  const TypeInfo *createUnmanagedStorageType(TypeConverter &TC) const override {
    return TC.createUnmanagedStorageType(this->getStorageType());
  }


  // Extra inhabitants of heap object pointers.

  bool mayHaveExtraInhabitants(IRGenModule &IGM) const override {
    return true;
  }

  unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override {
    return getHeapObjectExtraInhabitantCount(IGM);
  }

  APInt getFixedExtraInhabitantValue(IRGenModule &IGM,
                                     unsigned bits,
                                     unsigned index) const override {
    return getHeapObjectFixedExtraInhabitantValue(IGM, bits, index, 0);
  }

  llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
                                       SILType T)
  const override {
    return getHeapObjectExtraInhabitantIndex(IGF, src);
  }

  void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
                            Address dest, SILType T) const override {
    return storeHeapObjectExtraInhabitant(IGF, index, dest);
  }
};

}
}

#endif
