//===--- ScalarPairTypeInfo.h - Type info for scalar pairs ------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines ScalarPairTypeInfo, which is a convenient abstract
// implementation of TypeInfo for working with types that are
// efficiently scalarizable.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_IRGEN_SCALARPAIRTYPEINFO_H
#define SWIFT_IRGEN_SCALARPAIRTYPEINFO_H

#include "NativeConventionSchema.h"
#include "ScalarTypeInfo.h"

namespace swift {
namespace irgen {

template <class Derived, class Base>
class ScalarPairTypeInfo : public ScalarTypeInfo<Derived, Base> {
  using super = ScalarTypeInfo<Derived, Base>;
protected:
  template <class... T> ScalarPairTypeInfo(T &&...args)
    : super(::std::forward<T>(args)...) {}

  const Derived &asDerived() const {
    return static_cast<const Derived &>(*this);
  }

public:
  llvm::StructType *getStorageType() const {
    return cast<llvm::StructType>(TypeInfo::getStorageType());
  }

  Address projectFirstElement(IRGenFunction &IGF, Address address) const {
    return IGF.Builder.CreateStructGEP(address, 0, Size(0),
                                       address->getName()
                                         + asDerived().getFirstElementLabel());
  }

  Address projectSecondElement(IRGenFunction &IGF, Address address) const {
    return IGF.Builder.CreateStructGEP(address, 1,
                 asDerived().getSecondElementOffset(IGF.IGM),
                 address->getName() + asDerived().getSecondElementLabel());
  }

  unsigned getExplosionSize() const override {
    return 2;
  }

  void getSchema(ExplosionSchema &schema) const override {
    llvm::StructType *structTy = getStorageType();
    schema.add(ExplosionSchema::Element::forScalar(structTy->getElementType(0)));
    schema.add(ExplosionSchema::Element::forScalar(structTy->getElementType(1)));
  }

  void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
                        Size offset) const override {
    llvm::StructType *structTy = getStorageType();
    this->addScalarToAggLowering(IGM, lowering, structTy->getElementType(0),
                                 offset, asDerived().getFirstElementSize(IGM));
    this->addScalarToAggLowering(IGM, lowering, structTy->getElementType(1),
                              offset + asDerived().getSecondElementOffset(IGM),
                                 asDerived().getSecondElementSize(IGM));
  }

  void loadAsCopy(IRGenFunction &IGF, Address address,
                  Explosion &e) const override {
    Address firstAddr = projectFirstElement(IGF, address);
    auto first =
      IGF.Builder.CreateLoad(firstAddr, firstAddr->getName() + ".load");
    asDerived().emitRetainFirstElement(IGF, first);
    e.add(first);

    Address secondAddr = projectSecondElement(IGF, address);
    auto second = IGF.Builder.CreateLoad(secondAddr);
    asDerived().emitRetainSecondElement(IGF, second);
    e.add(second);
  }

  void loadAsTake(IRGenFunction &IGF, Address addr,
                  Explosion &e) const override {
    // Load the function.
    Address firstAddr = projectFirstElement(IGF, addr);
    e.add(IGF.Builder.CreateLoad(firstAddr));

    Address secondAddr = projectSecondElement(IGF, addr);
    e.add(IGF.Builder.CreateLoad(secondAddr));
  }

  void assign(IRGenFunction &IGF, Explosion &e, Address address,
              bool isOutlined) const override {
    // Store the function pointer.
    Address firstAddr = projectFirstElement(IGF, address);
    asDerived().emitAssignFirstElement(IGF, e.claimNext(), firstAddr);

    Address secondAddr = projectSecondElement(IGF, address);
    asDerived().emitAssignSecondElement(IGF, e.claimNext(), secondAddr);
  }

  void initialize(IRGenFunction &IGF, Explosion &e, Address address,
                  bool isOutlined) const override {
    Address firstAddr = projectFirstElement(IGF, address);
    IGF.Builder.CreateStore(e.claimNext(), firstAddr);

    Address secondAddr = projectSecondElement(IGF, address);
    IGF.Builder.CreateStore(e.claimNext(), secondAddr);
  }

  void copy(IRGenFunction &IGF, Explosion &src,
            Explosion &dest, Atomicity atomicity) const override {
    auto first = src.claimNext();
    asDerived().emitRetainFirstElement(IGF, first, atomicity);
    dest.add(first);

    auto second = src.claimNext();
    asDerived().emitRetainSecondElement(IGF, second, atomicity);
    dest.add(second);
  }

  void consume(IRGenFunction &IGF, Explosion &src,
               Atomicity atomicity) const override {
    auto first = src.claimNext();
    asDerived().emitReleaseFirstElement(IGF, first, atomicity);

    auto second = src.claimNext();
    asDerived().emitReleaseSecondElement(IGF, second, atomicity);
  }

  void fixLifetime(IRGenFunction &IGF, Explosion &src) const override {
    auto first = src.claimNext();
    if (!asDerived().isFirstElementTrivial())
      IGF.emitFixLifetime(first);

    auto second = src.claimNext();
    if (!asDerived().isSecondElementTrivial())
      IGF.emitFixLifetime(second);
  }

  void destroy(IRGenFunction &IGF, Address addr, SILType T,
               bool isOutlined) const override {
    if (!asDerived().isFirstElementTrivial()) {
      auto first = IGF.Builder.CreateLoad(projectFirstElement(IGF, addr));
      asDerived().emitReleaseFirstElement(IGF, first);
    }

    if (!asDerived().isSecondElementTrivial()) {
      auto first = IGF.Builder.CreateLoad(projectSecondElement(IGF, addr));
      asDerived().emitReleaseSecondElement(IGF, first);
    }
  }

  void packIntoEnumPayload(IRGenFunction &IGF,
                           EnumPayload &payload,
                           Explosion &src,
                           unsigned offset) const override {
    payload.insertValue(IGF, src.claimNext(), offset);
    payload.insertValue(IGF, src.claimNext(),
      offset + asDerived().getSecondElementOffset(IGF.IGM).getValueInBits());
  }
  
  void unpackFromEnumPayload(IRGenFunction &IGF,
                             const EnumPayload &payload,
                             Explosion &dest,
                             unsigned offset) const override {
    auto storageTy = getStorageType();
    dest.add(payload.extractValue(IGF, storageTy->getElementType(0), offset));
    dest.add(payload.extractValue(IGF, storageTy->getElementType(1),
      offset + asDerived().getSecondElementOffset(IGF.IGM).getValueInBits()));
  }
};

}
}

#endif
