//===--- SGFContext.h - Expression emission context -------------*- 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
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SILGEN_SGFCONTEXT_H
#define SWIFT_SILGEN_SGFCONTEXT_H

#include "Initialization.h"

namespace swift {
namespace Lowering {

/// Internal context information for the SILGenFunction visitor.
///
/// In general, emission methods which take an SGFContext indicate
/// that they've initialized the emit-into buffer (if they have) by
/// returning a "isInContext()" ManagedValue of whatever type.  Callers who
/// propagate down an SGFContext that might have an emit-into buffer must be
/// aware of this.
///
/// Clients of emission routines that take an SGFContext can also specify that
/// they are ok getting back an RValue at +0 instead of requiring it to be at
/// +1.  The client is then responsible for checking the ManagedValue to see if
/// it got back a ManagedValue at +0 or +1.
class SGFContext {
  enum DesiredTransfer {
    PlusOne,
    ImmediatePlusZero,
    GuaranteedPlusZero,
  };
  llvm::PointerIntPair<Initialization *, 2, DesiredTransfer> state;
public:
  SGFContext() = default;

  enum AllowImmediatePlusZero_t {
    /// The client is okay with getting a +0 value and plans to use it
    /// immediately.
    ///
    /// For example, in this context, it would be okay to return +0
    /// even for a load from a mutable variable, because the only way
    /// the value could be invalidated before it's used is a race
    /// condition.
    AllowImmediatePlusZero
  };

  enum AllowGuaranteedPlusZero_t {
    /// The client is okay with getting a +0 value as long as it's
    /// guaranteed to last at least as long as the current evaluation.
    /// (For expression evaluation, this generally means at least
    /// until the end of the current statement.)
    ///
    /// For example, in this context, it would be okay to return +0
    /// for a reference to a local 'let' because that will last until
    /// the 'let' goes out of scope.  However, it would not be okay to
    /// return +0 for a load from a mutable 'var', because that could
    /// be mutated before the end of the statement.
    AllowGuaranteedPlusZero
  };

  /// Creates an emitInto context that will store the result of the visited expr
  /// into the given Initialization.
  explicit SGFContext(Initialization *emitInto) : state(emitInto, PlusOne) {
  }

  /*implicit*/
  SGFContext(AllowImmediatePlusZero_t) : state(nullptr, ImmediatePlusZero) {
  }

  /*implicit*/
  SGFContext(AllowGuaranteedPlusZero_t) : state(nullptr, GuaranteedPlusZero) {
  }

  /// Returns a pointer to the Initialization that the current expression should
  /// store its result to, or null if the expression should allocate temporary
  /// storage for its result.
  Initialization *getEmitInto() const {
    return state.getPointer();
  }

  /// Try to get the address of the emit-into initialization if we can.
  /// Otherwise, return an empty SILValue.
  ///
  /// Note that, if this returns a non-empty address, the caller must
  /// finish the emit-into initialization.
  SILValue getAddressForInPlaceInitialization(SILGenFunction &SGF,
                                              SILLocation loc) const {
    if (auto *init = getEmitInto()) {
      if (init->canPerformInPlaceInitialization())
        return init->getAddressForInPlaceInitialization(SGF, loc);
    }
    return SILValue();
  }

  /// If getAddressForInPlaceInitialization did (or would have)
  /// returned a non-null address, finish the initialization and
  /// return true.  Otherwise, return false.
  bool finishInPlaceInitialization(SILGenFunction &SGF) const {
    if (auto *init = getEmitInto()) {
      if (init->canPerformInPlaceInitialization()) {
        init->finishInitialization(SGF);
        return true;
      }
    }

    return false;
  }

  /// Try to get this context as a conversion initialization.
  ///
  /// This does not commit the caller to anything, whether it succeeds
  /// or fails.
  ConvertingInitialization *getAsConversion() const {
    if (auto init = getEmitInto())
      return init->getAsConversion();
    return nullptr;
  }

  /// Return true if a ManagedValue producer is allowed to return at
  /// +0, given that it cannot guarantee that the value will be valid
  /// until the end of the current evaluation.
  bool isImmediatePlusZeroOk() const {
    return state.getInt() == ImmediatePlusZero;
  }

  /// Return true if a ManagedValue producer is allowed to return at
  /// +0 if it can guarantee that the value will be valid until the
  /// end of the current evaluation.
  bool isGuaranteedPlusZeroOk() const {
    // Either ImmediatePlusZero or GuaranteedPlusZero is fine.
    return state.getInt() >= ImmediatePlusZero;
  }

  /// Get a context for a sub-expression given that arbitrary side
  /// effects may follow the subevaluation.
  SGFContext withFollowingSideEffects() const {
    SGFContext copy = *this;
    if (copy.state.getInt() == ImmediatePlusZero) {
      copy.state.setInt(GuaranteedPlusZero);
    }
    return copy;
  }

  /// Get a context for a sub-expression where we plan to project out
  /// a value.  The Initialization is not okay to propagate down, but
  /// the +0/+1-ness is.
  SGFContext withFollowingProjection() const {
    SGFContext result;
    result.state.setInt(state.getInt());
    return result;
  }

  /// Get a context for a sub-expression where we plan to evaluate arbitrary
  /// side-effects. This means we propagate down the initialization, but
  /// eliminates the +0/+1-ness.
  SGFContext withSubExprSideEffects() const {
    if (auto *init = getEmitInto()) {
      return SGFContext(init);
    }

    return SGFContext();
  }
};

using ValueProducerRef =
  llvm::function_ref<ManagedValue(SILGenFunction &SGF, SILLocation loc,
                                  SGFContext context)>;

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

#endif
