//===--- SILGenLazyConformance.cpp ----------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 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 "SILGen.h"
#include "swift/AST/Decl.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/ClangImporter/ClangModule.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILVisitor.h"

using namespace swift;
using namespace swift::Lowering;

void SILGenModule::useConformance(ProtocolConformanceRef conformanceRef) {
  // We don't need to emit dependent conformances.
  if (conformanceRef.isAbstract())
    return;

  auto conformance = conformanceRef.getConcrete();

  // Always look through inherited conformances.
  if (auto *inherited = dyn_cast<InheritedProtocolConformance>(conformance))
    conformance = inherited->getInheritedConformance();

  // Get the normal conformance. If we don't have one, this is a self
  // conformance, which we can ignore.
  auto normal = dyn_cast<NormalProtocolConformance>(
      conformance->getRootConformance());
  if (normal == nullptr)
    return;

  // Emit any conformances implied by conditional requirements.
  if (auto *specialized = dyn_cast<SpecializedProtocolConformance>(conformance))
    useConformancesFromSubstitutions(specialized->getSubstitutionMap());

  // If this conformance was not synthesized by the ClangImporter, we're not
  // going to be emitting it lazily either, so we can avoid doing anything
  // below.
  if (!isa<ClangModuleUnit>(normal->getDeclContext()->getModuleScopeContext()))
    return;

  // If we already emitted this witness table, we don't need to track the fact
  // we need it.
  if (emittedWitnessTables.count(normal))
    return;

  // Check if we already forced this witness table but haven't emitted it yet.
  if (!forcedConformances.insert(normal).second)
    return;

  pendingConformances.push_back(normal);
}

void SILGenModule::useConformancesFromSubstitutions(
                                                const SubstitutionMap subs) {
  for (auto conf : subs.getConformances())
    useConformance(conf);
}

void SILGenModule::useConformancesFromType(CanType type) {
  if (!usedConformancesFromTypes.insert(type.getPointer()).second)
    return;

  type.visit([&](Type t) {
    auto *decl = t->getAnyNominal();
    if (!decl)
      return;

    if (isa<ProtocolDecl>(decl))
      return;

    auto genericSig = decl->getGenericSignature();
    if (!genericSig)
      return;

    auto subMap = t->getContextSubstitutionMap(SwiftModule, decl);
    useConformancesFromSubstitutions(subMap);
    return;
  });
}

void SILGenModule::useConformancesFromObjectiveCType(CanType type) {
  if (!usedConformancesFromObjectiveCTypes.insert(type.getPointer()).second)
    return;

  auto &ctx = getASTContext();
  auto objectiveCBridgeable = ctx.getProtocol(
      KnownProtocolKind::ObjectiveCBridgeable);
  auto bridgedStoredNSError = ctx.getProtocol(
      KnownProtocolKind::BridgedStoredNSError);
  if (!objectiveCBridgeable && !bridgedStoredNSError)
    return;

  type.visit([&](Type t) {
    auto *decl = t->getAnyNominal();
    if (!decl)
      return;

    if (!isa<ClangModuleUnit>(decl->getModuleScopeContext()))
      return;

    if (objectiveCBridgeable) {
      if (auto subConformance =
              SwiftModule->lookupConformance(t, objectiveCBridgeable))
        useConformance(subConformance);
    }

    if (bridgedStoredNSError) {
      if (auto subConformance =
              SwiftModule->lookupConformance(t, bridgedStoredNSError))
        useConformance(subConformance);
    }
  });
}

/// A visitor class that tries to guess which SIL instructions can cause
/// IRGen to emit references to witness tables. This is used to emit
/// ClangImporter-synthesized conformances lazily.
///
/// In the long run, we'll instead have IRGen directly ask SILGen to
/// generate a witness table when needed, so that we don't have to do
/// any "guessing" here.
class LazyConformanceEmitter : public SILInstructionVisitor<LazyConformanceEmitter> {
  SILGenModule &SGM;

public:
  LazyConformanceEmitter(SILGenModule &SGM) : SGM(SGM) {}

  void visitAllocExistentialBoxInst(AllocExistentialBoxInst *AEBI) {
    SGM.useConformancesFromType(AEBI->getFormalConcreteType());
    SGM.useConformancesFromObjectiveCType(AEBI->getFormalConcreteType());
    for (auto conformance : AEBI->getConformances())
      SGM.useConformance(conformance);
  }

  void visitAllocGlobalInst(AllocGlobalInst *AGI) {
    SGM.useConformancesFromType(
        AGI->getReferencedGlobal()->getLoweredType().getASTType());
  }

  void visitAllocRefInst(AllocRefInst *ARI) {
    SGM.useConformancesFromType(ARI->getType().getASTType());
  }

  void visitAllocStackInst(AllocStackInst *ASI) {
    SGM.useConformancesFromType(ASI->getType().getASTType());
  }

  void visitAllocValueBufferInst(AllocValueBufferInst *AVBI) {
    SGM.useConformancesFromType(AVBI->getType().getASTType());
  }

  void visitApplyInst(ApplyInst *AI) {
    SGM.useConformancesFromObjectiveCType(AI->getSubstCalleeType());
    SGM.useConformancesFromSubstitutions(AI->getSubstitutionMap());
  }

  void visitBeginApplyInst(BeginApplyInst *BAI) {
    SGM.useConformancesFromObjectiveCType(BAI->getSubstCalleeType());
    SGM.useConformancesFromSubstitutions(BAI->getSubstitutionMap());
  }

  void visitBuiltinInst(BuiltinInst *BI) {
    SGM.useConformancesFromSubstitutions(BI->getSubstitutions());
  }

  void visitCheckedCastBranchInst(CheckedCastBranchInst *CCBI) {
    SGM.useConformancesFromType(CCBI->getSourceFormalType());
    SGM.useConformancesFromType(CCBI->getTargetFormalType());
    SGM.useConformancesFromObjectiveCType(CCBI->getSourceFormalType());
    SGM.useConformancesFromObjectiveCType(CCBI->getTargetFormalType());
  }

  void visitCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CCABI) {
    SGM.useConformancesFromType(CCABI->getSourceFormalType());
    SGM.useConformancesFromType(CCABI->getTargetFormalType());
    SGM.useConformancesFromObjectiveCType(CCABI->getSourceFormalType());
    SGM.useConformancesFromObjectiveCType(CCABI->getTargetFormalType());
  }

  void visitCheckedCastValueBranchInst(CheckedCastValueBranchInst *CCVBI) {
    SGM.useConformancesFromType(CCVBI->getSourceFormalType());
    SGM.useConformancesFromType(CCVBI->getTargetFormalType());
    SGM.useConformancesFromObjectiveCType(CCVBI->getSourceFormalType());
    SGM.useConformancesFromObjectiveCType(CCVBI->getTargetFormalType());
  }

  void visitCopyAddrInst(CopyAddrInst *CAI) {
    SGM.useConformancesFromType(CAI->getSrc()->getType().getASTType());
    SGM.useConformancesFromType(CAI->getDest()->getType().getASTType());
  }

  void visitCopyValueInst(CopyValueInst *CVI) {
    SGM.useConformancesFromType(CVI->getOperand()->getType().getASTType());
  }

  void visitDestroyAddrInst(DestroyAddrInst *DAI) {
    SGM.useConformancesFromType(DAI->getOperand()->getType().getASTType());
  }

  void visitDestroyValueInst(DestroyValueInst *DVI) {
    SGM.useConformancesFromType(DVI->getOperand()->getType().getASTType());
  }

  void visitGlobalAddrInst(GlobalAddrInst *GAI) {
    SGM.useConformancesFromType(
        GAI->getReferencedGlobal()->getLoweredType().getASTType());
  }

  void visitGlobalValueInst(GlobalValueInst *GVI) {
    SGM.useConformancesFromType(
        GVI->getReferencedGlobal()->getLoweredType().getASTType());
  }

  void visitKeyPathInst(KeyPathInst *KPI) {
    SGM.useConformancesFromSubstitutions(KPI->getSubstitutions());
  }

  void visitInitEnumDataAddrInst(InitEnumDataAddrInst *IEDAI) {
    SGM.useConformancesFromType(
        IEDAI->getOperand()->getType().getASTType());
  }

  void visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI) {
    SGM.useConformancesFromType(IEAI->getOperand()->getType().getASTType());
  }

  void visitInitExistentialAddrInst(InitExistentialAddrInst *IEAI) {
    SGM.useConformancesFromType(IEAI->getFormalConcreteType());
    SGM.useConformancesFromObjectiveCType(IEAI->getFormalConcreteType());
    for (auto conformance : IEAI->getConformances())
      SGM.useConformance(conformance);
  }

  void visitInitExistentialMetatypeInst(InitExistentialMetatypeInst *IEMI) {
    SGM.useConformancesFromType(IEMI->getOperand()->getType().getASTType());
    for (auto conformance : IEMI->getConformances())
      SGM.useConformance(conformance);
  }

  void visitInitExistentialRefInst(InitExistentialRefInst *IERI) {
    SGM.useConformancesFromType(IERI->getFormalConcreteType());
    SGM.useConformancesFromObjectiveCType(IERI->getFormalConcreteType());
    for (auto conformance : IERI->getConformances())
      SGM.useConformance(conformance);
  }

  void visitInitExistentialValueInst(InitExistentialValueInst *IEVI) {
    SGM.useConformancesFromType(IEVI->getFormalConcreteType());
    SGM.useConformancesFromObjectiveCType(IEVI->getFormalConcreteType());
    for (auto conformance : IEVI->getConformances())
      SGM.useConformance(conformance);
  }

  void visitMetatypeInst(MetatypeInst *MI) {
    SGM.useConformancesFromType(MI->getType().getASTType());
  }

  void visitPartialApplyInst(PartialApplyInst *PAI) {
    SGM.useConformancesFromObjectiveCType(PAI->getSubstCalleeType());
    SGM.useConformancesFromSubstitutions(PAI->getSubstitutionMap());
  }

  void visitSelectEnumAddrInst(SelectEnumAddrInst *SEAI) {
    SGM.useConformancesFromType(
        SEAI->getEnumOperand()->getType().getASTType());
  }

  void visitStructElementAddrInst(StructElementAddrInst *SEAI) {
    SGM.useConformancesFromType(SEAI->getOperand()->getType().getASTType());
  }

  void visitTryApplyInst(TryApplyInst *TAI) {
    SGM.useConformancesFromObjectiveCType(TAI->getSubstCalleeType());
    SGM.useConformancesFromSubstitutions(TAI->getSubstitutionMap());
  }

  void visitTupleElementAddrInst(TupleElementAddrInst *TEAI) {
    SGM.useConformancesFromType(TEAI->getOperand()->getType().getASTType());
  }

  void visitUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *UCCI) {
    SGM.useConformancesFromType(UCCI->getSourceFormalType());
    SGM.useConformancesFromType(UCCI->getTargetFormalType());
    SGM.useConformancesFromObjectiveCType(UCCI->getSourceFormalType());
    SGM.useConformancesFromObjectiveCType(UCCI->getTargetFormalType());
  }

  void visitUnconditionalCheckedCastAddrInst(UnconditionalCheckedCastAddrInst *UCCAI) {
    SGM.useConformancesFromType(UCCAI->getSourceFormalType());
    SGM.useConformancesFromType(UCCAI->getTargetFormalType());
    SGM.useConformancesFromObjectiveCType(UCCAI->getSourceFormalType());
    SGM.useConformancesFromObjectiveCType(UCCAI->getTargetFormalType());
  }

  void visitUncheckedTakeEnumDataAddrInst(UncheckedTakeEnumDataAddrInst *UTEDAI) {
    SGM.useConformancesFromType(UTEDAI->getOperand()->getType().getASTType());
  }

  void visitWitnessMethodInst(WitnessMethodInst *WMI) {
    SGM.useConformance(WMI->getConformance());
  }

  void visitSILInstruction(SILInstruction *I) {}
};

void SILGenModule::emitLazyConformancesForFunction(SILFunction *F) {
  LazyConformanceEmitter emitter(*this);

  for (auto &BB : *F)
    for (auto &I : BB)
      emitter.visit(&I);
}

void SILGenModule::emitLazyConformancesForType(NominalTypeDecl *NTD) {
  auto genericSig = NTD->getGenericSignature();

  if (genericSig) {
    for (auto reqt : genericSig->getRequirements()) {
      if (reqt.getKind() != RequirementKind::Layout)
        useConformancesFromType(reqt.getSecondType()->getCanonicalType());
    }
  }

  if (auto *ED = dyn_cast<EnumDecl>(NTD)) {
    for (auto *EED : ED->getAllElements()) {
      if (EED->hasAssociatedValues()) {
        useConformancesFromType(EED->getArgumentInterfaceType()
                                   ->getCanonicalType(genericSig));
      }
    }
  }

  if (isa<StructDecl>(NTD) || isa<ClassDecl>(NTD)) {
    for (auto *VD : NTD->getStoredProperties()) {
      useConformancesFromType(VD->getValueInterfaceType()
                                ->getCanonicalType(genericSig));
    }
  }

  if (auto *CD = dyn_cast<ClassDecl>(NTD))
    if (auto superclass = CD->getSuperclass())
      useConformancesFromType(superclass->getCanonicalType(genericSig));

  if (auto *PD = dyn_cast<ProtocolDecl>(NTD)) {
    for (auto reqt : PD->getRequirementSignature()) {
      if (reqt.getKind() != RequirementKind::Layout)
        useConformancesFromType(reqt.getSecondType()->getCanonicalType());
    }
  }
}
