//===--- SILGenDestructor.cpp - SILGen for destructors --------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "SILGenFunction.h"
#include "RValue.h"
#include "Scope.h"
#include "swift/AST/SubstitutionMap.h"
#include "swift/SIL/TypeLowering.h"

using namespace swift;
using namespace Lowering;

void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
  MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit"));

  RegularLocation Loc(dd);
  if (dd->isImplicit())
    Loc.markAutoGenerated();

  auto cd = cast<ClassDecl>(dd->getDeclContext());
  SILValue selfValue = emitSelfDecl(dd->getImplicitSelfDecl());

  // Create a basic block to jump to for the implicit destruction behavior
  // of releasing the elements and calling the superclass destructor.
  // We won't actually emit the block until we finish with the destructor body.
  prepareEpilog(Type(), false, CleanupLocation::get(Loc));

  emitProfilerIncrement(dd->getBody());
  // Emit the destructor body.
  emitStmt(dd->getBody());

  Optional<SILValue> maybeReturnValue;
  SILLocation returnLoc(Loc);
  std::tie(maybeReturnValue, returnLoc) = emitEpilogBB(Loc);

  if (!maybeReturnValue)
    return;

  auto cleanupLoc = CleanupLocation::get(Loc);

  // If we have a superclass, invoke its destructor.
  SILValue resultSelfValue;
  SILType objectPtrTy = SILType::getNativeObjectType(F.getASTContext());
  SILType classTy = selfValue->getType();
  if (cd->hasSuperclass()) {
    Type superclassTy = dd->mapTypeIntoContext(cd->getSuperclass());
    ClassDecl *superclass = superclassTy->getClassOrBoundGenericClass();
    auto superclassDtorDecl = superclass->getDestructor();
    SILDeclRef dtorConstant =
      SILDeclRef(superclassDtorDecl, SILDeclRef::Kind::Destroyer);
    SILType baseSILTy = getLoweredLoadableType(superclassTy);
    SILValue baseSelf = B.createUpcast(cleanupLoc, selfValue, baseSILTy);
    ManagedValue dtorValue;
    SILType dtorTy;
    auto subMap
      = superclassTy->getContextSubstitutionMap(SGM.M.getSwiftModule(),
                                                superclass);
    std::tie(dtorValue, dtorTy)
      = emitSiblingMethodRef(cleanupLoc, baseSelf, dtorConstant, subMap);

    SmallVector<Substitution, 4> subs;
    if (auto *genericSig = superclass->getGenericSignature())
      genericSig->getSubstitutions(subMap, subs);
    resultSelfValue = B.createApply(cleanupLoc, dtorValue.forward(*this),
                                    dtorTy, objectPtrTy, subs, baseSelf);
  } else {
    resultSelfValue = selfValue;
  }

  {
    Scope S(Cleanups, cleanupLoc);
    ManagedValue borrowedResultSelfValue =
        emitManagedBeginBorrow(cleanupLoc, resultSelfValue);
    SILValue borrowedValue = borrowedResultSelfValue.getUnmanagedValue();
    if (classTy != borrowedValue->getType()) {
      borrowedValue =
          B.createUncheckedRefCast(cleanupLoc, borrowedValue, classTy);
    }

    // Release our members.
    emitClassMemberDestruction(borrowedValue, cd, cleanupLoc);
  }

  if (resultSelfValue->getType() != objectPtrTy) {
    resultSelfValue =
        B.createUncheckedRefCast(cleanupLoc, resultSelfValue, objectPtrTy);
  }
  if (resultSelfValue.getOwnershipKind() != ValueOwnershipKind::Owned) {
    assert(resultSelfValue.getOwnershipKind() ==
           ValueOwnershipKind::Guaranteed);
    resultSelfValue = B.createUncheckedOwnershipConversion(
        cleanupLoc, resultSelfValue, ValueOwnershipKind::Owned);
  }
  B.createReturn(returnLoc, resultSelfValue);
}

void SILGenFunction::emitDeallocatingDestructor(DestructorDecl *dd) {
  MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit"));

  // The deallocating destructor is always auto-generated.
  RegularLocation loc(dd);
  loc.markAutoGenerated();

  // Emit the prolog.
  SILValue initialSelfValue = emitSelfDecl(dd->getImplicitSelfDecl());

  // Form a reference to the destroying destructor.
  SILDeclRef dtorConstant(dd, SILDeclRef::Kind::Destroyer);
  auto classTy = initialSelfValue->getType();
  auto classDecl = classTy.getSwiftRValueType()->getAnyNominal();
  ManagedValue dtorValue;
  SILType dtorTy;
  auto subMap = classTy.getSwiftRValueType()
    ->getContextSubstitutionMap(SGM.M.getSwiftModule(),
                                classDecl);
  std::tie(dtorValue, dtorTy)
    = emitSiblingMethodRef(loc, initialSelfValue, dtorConstant, subMap);

  SmallVector<Substitution, 4> subs;
  if (auto *genericSig = classDecl->getGenericSignature())
    genericSig->getSubstitutions(subMap, subs);

  // Call the destroying destructor.
  SILValue selfForDealloc;
  {
    FullExpr CleanupScope(Cleanups, CleanupLocation::get(loc));
    ManagedValue borrowedSelf = emitManagedBeginBorrow(loc, initialSelfValue);
    SILType objectPtrTy = SILType::getNativeObjectType(F.getASTContext());
    selfForDealloc = B.createApply(loc, dtorValue.forward(*this),
                                   dtorTy, objectPtrTy, subs,
                                   borrowedSelf.getUnmanagedValue());
  }

  // Balance out the +1 from the self argument using end_lifetime.
  //
  // The issue here is that:
  //
  // 1. Self is passed into deallocating deinits at +1.
  // 2. Destroying deinits take in self as a +0 value that is then returned at
  // +1.
  //
  // This means that the lifetime of self can not be modeled statically in a
  // deallocating deinit without analyzing the body of the destroying deinit
  // (something that violates semantic sil). Thus we add an artifical destroy of
  // self before the actual destroy of self so that the verifier can understand
  // that self is being properly balanced.
  B.createEndLifetime(loc, initialSelfValue);

  // Deallocate the object.
  selfForDealloc = B.createUncheckedRefCast(loc, selfForDealloc, classTy);
  B.createDeallocRef(loc, selfForDealloc, false);

  // Return.
  B.createReturn(loc, emitEmptyTuple(loc));
}

void SILGenFunction::emitIVarDestroyer(SILDeclRef ivarDestroyer) {
  auto cd = cast<ClassDecl>(ivarDestroyer.getDecl());
  RegularLocation loc(cd);
  loc.markAutoGenerated();

  SILValue selfValue = emitSelfDecl(cd->getDestructor()->getImplicitSelfDecl());

  auto cleanupLoc = CleanupLocation::get(loc);
  prepareEpilog(TupleType::getEmpty(getASTContext()), false, cleanupLoc);
  emitClassMemberDestruction(selfValue, cd, cleanupLoc);
  B.createReturn(loc, emitEmptyTuple(loc));
  emitEpilog(loc);
}

void SILGenFunction::emitClassMemberDestruction(SILValue selfValue,
                                                ClassDecl *cd,
                                                CleanupLocation cleanupLoc) {
  for (VarDecl *vd : cd->getStoredProperties()) {
    const TypeLowering &ti = getTypeLowering(vd->getType());
    if (!ti.isTrivial()) {
      SILValue addr = B.createRefElementAddr(cleanupLoc, selfValue, vd,
                                         ti.getLoweredType().getAddressType());
      B.createDestroyAddr(cleanupLoc, addr);
    }
  }
}


void SILGenFunction::emitObjCDestructor(SILDeclRef dtor) {
  auto dd = cast<DestructorDecl>(dtor.getDecl());
  auto cd = cast<ClassDecl>(dd->getDeclContext());
  MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit"));

  RegularLocation loc(dd);
  if (dd->isImplicit())
    loc.markAutoGenerated();

  SILValue selfValue = emitSelfDecl(dd->getImplicitSelfDecl());

  // Create a basic block to jump to for the implicit destruction behavior
  // of releasing the elements and calling the superclass destructor.
  // We won't actually emit the block until we finish with the destructor body.
  prepareEpilog(Type(), false, CleanupLocation::get(loc));

  // Emit the destructor body.
  emitStmt(dd->getBody());

  Optional<SILValue> maybeReturnValue;
  SILLocation returnLoc(loc);
  std::tie(maybeReturnValue, returnLoc) = emitEpilogBB(loc);

  if (!maybeReturnValue)
    return;

  auto cleanupLoc = CleanupLocation::get(loc);

  // Note: the ivar destroyer is responsible for destroying the
  // instance variables before the object is actually deallocated.

  // Form a reference to the superclass -dealloc.
  Type superclassTy = dd->mapTypeIntoContext(cd->getSuperclass());
  assert(superclassTy && "Emitting Objective-C -dealloc without superclass?");
  ClassDecl *superclass = superclassTy->getClassOrBoundGenericClass();
  auto superclassDtorDecl = superclass->getDestructor();
  SILDeclRef superclassDtor(superclassDtorDecl,
                            SILDeclRef::Kind::Deallocator,
                            SILDeclRef::ConstructAtBestResilienceExpansion,
                            SILDeclRef::ConstructAtNaturalUncurryLevel,
                            /*isForeign=*/true);
  auto superclassDtorType = SGM.getConstantType(superclassDtor);
  SILValue superclassDtorValue = B.createSuperMethod(
                                   cleanupLoc, selfValue, superclassDtor,
                                   superclassDtorType);

  // Call the superclass's -dealloc.
  SILType superclassSILTy = getLoweredLoadableType(superclassTy);
  SILValue superSelf = B.createUpcast(cleanupLoc, selfValue, superclassSILTy);
  auto subMap
    = superclassTy->getContextSubstitutionMap(SGM.M.getSwiftModule(),
                                              superclass);

  auto substDtorType = superclassDtorType.substGenericArgs(SGM.M, subMap);
  SILFunctionConventions dtorConv(substDtorType.castTo<SILFunctionType>(),
                                  SGM.M);

  SmallVector<Substitution, 4> subs;
    if (auto *genericSig = superclass->getGenericSignature())
      genericSig->getSubstitutions(subMap, subs);

  B.createApply(cleanupLoc, superclassDtorValue, substDtorType,
                dtorConv.getSILResultType(), subs, superSelf);

  // Return.
  B.createReturn(returnLoc, emitEmptyTuple(cleanupLoc));
}
