//===--- Conversion.h - Types for value conversion --------------*- 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
//
//===----------------------------------------------------------------------===//
//
// Defines the Conversion class as well as ConvertingInitialization.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_LOWERING_CONVERSION_H
#define SWIFT_LOWERING_CONVERSION_H

#include "swift/Basic/ExternalUnion.h"
#include "Initialization.h"
#include "SGFContext.h"

namespace swift {
namespace Lowering {

/// An abstraction representing certain kinds of conversion that SILGen can
/// do automatically in various situations.
class Conversion {
public:
  enum KindTy {
    /// A bridging conversion to a foreign type.
    BridgeToObjC,

    /// A bridging conversion to a foreign type following a force.
    /// Although it's not reflected in the name, this is always an
    /// implicit force cast.
    ForceAndBridgeToObjC,

    /// A bridging conversion from a foreign type.
    BridgeFromObjC,

    /// A bridging conversion for a function result.
    BridgeResultFromObjC,

    /// An erasure to Any (possibly wrapped in optional conversions).
    /// This is sortof a bridging conversion.
    AnyErasure,

    LastBridgingKind = AnyErasure,

    /// An orig-to-subst conversion.
    OrigToSubst,

    /// A subst-to-orig conversion.  These can always be annihilated.
    SubstToOrig,
  };

  static bool isBridgingKind(KindTy kind) {
    return kind <= LastBridgingKind;
  }

private:
  KindTy Kind;

  struct BridgingTypes {
    CanType OrigType;
    CanType ResultType;
    SILType LoweredResultType;
    bool IsExplicit;
  };

  struct ReabstractionTypes {
    AbstractionPattern OrigType;
    CanType SubstType;
    SILType LoweredResultType;
  };

  using Members = ExternalUnionMembers<BridgingTypes, ReabstractionTypes>;

  static Members::Index getStorageIndexForKind(KindTy kind) {
    switch (kind) {
    case BridgeToObjC:
    case ForceAndBridgeToObjC:
    case BridgeFromObjC:
    case BridgeResultFromObjC:
    case AnyErasure:
      return Members::indexOf<BridgingTypes>();

    case OrigToSubst:
    case SubstToOrig:
      return Members::indexOf<ReabstractionTypes>();
    }
    llvm_unreachable("bad kind");
  }

  ExternalUnion<KindTy, Members, getStorageIndexForKind> Types;
  static_assert(decltype(Types)::union_is_trivially_copyable,
                "define the special members if this changes");

  Conversion(KindTy kind, CanType origType, CanType resultType,
             SILType loweredResultTy, bool isExplicit)
      : Kind(kind) {
    Types.emplaceAggregate<BridgingTypes>(kind, origType, resultType,
                                          loweredResultTy, isExplicit);
  }

  Conversion(KindTy kind, AbstractionPattern origType, CanType substType,
             SILType loweredResultTy)
      : Kind(kind) {
    Types.emplaceAggregate<ReabstractionTypes>(kind, origType, substType,
                                               loweredResultTy);
  }

public:
  static Conversion getOrigToSubst(AbstractionPattern origType,
                                   CanType substType,
                                   SILType loweredResultTy) {
    return Conversion(OrigToSubst, origType, substType, loweredResultTy);
  }

  static Conversion getSubstToOrig(AbstractionPattern origType,
                                   CanType substType,
                                   SILType loweredResultTy) {
    return Conversion(SubstToOrig, origType, substType, loweredResultTy);
  }

  static Conversion getBridging(KindTy kind, CanType origType,
                                CanType resultType, SILType loweredResultTy,
                                bool isExplicit = false) {
    assert(isBridgingKind(kind));
    return Conversion(kind, origType, resultType, loweredResultTy, isExplicit);
  }

  KindTy getKind() const {
    return Kind;
  }

  bool isBridging() const {
    return isBridgingKind(getKind());
  }

  AbstractionPattern getReabstractionOrigType() const {
    return Types.get<ReabstractionTypes>(Kind).OrigType;
  }

  CanType getReabstractionSubstType() const {
    return Types.get<ReabstractionTypes>(Kind).SubstType;
  }

  SILType getReabstractionLoweredResultType() const {
    return Types.get<ReabstractionTypes>(Kind).LoweredResultType;
  }

  bool isBridgingExplicit() const {
    return Types.get<BridgingTypes>(Kind).IsExplicit;
  }

  CanType getBridgingSourceType() const {
    return Types.get<BridgingTypes>(Kind).OrigType;
  }

  CanType getBridgingResultType() const {
    return Types.get<BridgingTypes>(Kind).ResultType;
  }

  SILType getBridgingLoweredResultType() const {
    return Types.get<BridgingTypes>(Kind).LoweredResultType;
  }

  ManagedValue emit(SILGenFunction &SGF, SILLocation loc,
                    ManagedValue source, SGFContext ctxt) const;

  /// Try to form a conversion that does an optional injection
  /// or optional-to-optional conversion followed by this conversion.
  Optional<Conversion>
  adjustForInitialOptionalConversions(CanType newSourceType) const;

  /// Try to form a conversion that does a force-value followed by
  /// this conversion.
  Optional<Conversion> adjustForInitialForceValue() const;

  void dump() const LLVM_ATTRIBUTE_USED;
  void print(llvm::raw_ostream &out) const;
};

/// Information about how to peephole two conversions.
///
/// This is really the private state of SILGenConvert.
class ConversionPeepholeHint {
public:
  enum Kind : uint8_t {
    /// The value will be exactly the right type.
    Identity,

    /// The value needs to be bridged to AnyObject (possibly optionally).
    BridgeToAnyObject,

    /// The value just needs to undergo a subtype conversion.
    Subtype
  };

private:
  Kind TheKind;
  bool Forced;

public:
  ConversionPeepholeHint(Kind kind, bool forced)
    : TheKind(kind), Forced(forced) {
  }

  Kind getKind() const { return TheKind; }

  /// Does the value need to be forced before the conversion?
  /// This comes up with result conversions where the result was imported
  /// as non-optional, as well as with implicitly unwrapped optionals.
  bool isForced() const { return Forced; }
};

Optional<ConversionPeepholeHint>
canPeepholeConversions(SILGenFunction &SGF,
                       const Conversion &outerConversion,
                       const Conversion &innerConversion);

ManagedValue emitPeepholedConversions(SILGenFunction &SGF, SILLocation loc,
                                      const Conversion &outerConversion,
                                      const Conversion &innerConversion,
                                      ConversionPeepholeHint hint,
                                      SGFContext C,
                                      ValueProducerRef produceValue);

/// An initialization where we ultimately want to apply a conversion to
/// the value before completing the initialization.
///
/// Value generators may call getAsConversion() to check whether an
/// Initialization is one of these.  If so, they may call either
/// tryPeephole or setConvertedValue.
class ConvertingInitialization final : public Initialization {
private:
  enum StateTy {
    /// Nothing has happened.
    Uninitialized,

    /// The converted value has been set.
    Initialized,

    /// finishInitialization has been called.
    Finished,

    /// The converted value has been extracted.
    Extracted
  };

  StateTy State;

  /// The conversion that needs to be applied to the formal value.
  Conversion TheConversion;

  /// The converted value, set if the initializing code calls tryPeephole,
  /// setReabstractedValue, or copyOrInitValueInto.
  ManagedValue Value;
  SGFContext FinalContext;

  StateTy getState() const {
    return State;
  }

public:
  ConvertingInitialization(Conversion conversion, SGFContext finalContext)
    : State(Uninitialized), TheConversion(conversion),
      FinalContext(finalContext) {}

  /// Return the conversion to apply to the unconverted value.
  const Conversion &getConversion() const {
    return TheConversion;
  }

  /// Return the context into which to emit the converted value.
  SGFContext getFinalContext() const {
    return FinalContext;
  }

  // The three ways to perform this initialization:

  /// Set the unconverted value for this initialization.
  void copyOrInitValueInto(SILGenFunction &SGF, SILLocation loc,
                           ManagedValue value, bool isInit) override;

  /// Given that the result of the given expression needs to sequentially
  /// undergo the the given conversion and then this conversion, attempt to
  /// peephole the result.  If successful, the value will be set in this
  /// initialization.  The initialization will not yet be finished.
  bool tryPeephole(SILGenFunction &SGF, Expr *E, Conversion innerConversion);
  bool tryPeephole(SILGenFunction &SGF, SILLocation loc,
                   Conversion innerConversion, ValueProducerRef producer);
  bool tryPeephole(SILGenFunction &SGF, SILLocation loc, ManagedValue value,
                   Conversion innerConversion);

  /// Set the converted value for this initialization.
  void setConvertedValue(ManagedValue value) {
    assert(getState() == Uninitialized);
    assert(!value.isInContext() || FinalContext.getEmitInto());
    Value = value;
    State = Initialized;
  }

  /// Given that an emitter was able to adjust the conversion when
  /// emitting into this initialization, continue emission into the
  /// new conversion.
  ManagedValue emitWithAdjustedConversion(SILGenFunction &SGF, SILLocation loc,
                                          Conversion adjustedConversion,
                                          ValueProducerRef producer);

  /// Given the unconverted result, i.e. the result of emitting a
  /// value formally of the unconverted type with this initialization
  /// as the SGFContext, produce the converted result.
  ///
  /// If this initialization was initialized, the unconverted result
  /// must be ManagedValue::forInContext(), and vice-versa.
  ///
  /// The result of this function may itself be
  /// ManagedValue::forInContext() if this Initialization was created
  /// with an SGFContext which contains another Initialization.
  ManagedValue finishEmission(SILGenFunction &SGF, SILLocation loc,
                              ManagedValue formalResult);

  // Implement to make the cast work.
  ConvertingInitialization *getAsConversion() override {
    return this;
  }

  // Bookkeeping.
  void finishInitialization(SILGenFunction &SGF) override {
    assert(getState() == Initialized);
    State = Finished;
  }
};

} // end namespace Lowering
} // end namespace swift

#endif
