//===--- ArgumentSource.h - Abstracted source of an argument ----*- 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
//
//===----------------------------------------------------------------------===//
//
// A structure for holding an abstracted source of a call argument.
// It's either:
//
//  - an expression, yielding an l-value or r-value
//  - an RValue
//  - an LValue
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_LOWERING_ARGUMENTSOURCE_H
#define SWIFT_LOWERING_ARGUMENTSOURCE_H

#include "RValue.h"
#include "LValue.h"

namespace swift {
namespace Lowering {

/// A means of generating an argument.
///
/// This is useful as a way to pass values around without either:
///   - requiring them to have already been evaluated or
///   - requiring them to come from an identifiable expression.
///
/// Being able to propagate values is important because there are a
/// number of cases (involving, say, property accessors) where values
/// are implicitly or previously generated.  However, being able to
/// propagate Expr*s is also important because there are several kinds
/// of expressions (such as closures) which can be emitted more
/// efficiently with a known target abstraction level.
///
/// Because an ArgumentSource might contain an unevaluated expression,
/// care must be taken when dealing with multiple ArgumentSources to
/// preserve the original evaluation order of the program.  APIs
/// working with multiple ArgumentSources should document the order in
/// which they plan to evaluate them.
class ArgumentSource {
  union Storage {
    struct {
      RValue Value;
      SILLocation Loc;
    } TheRV;
    struct {
      LValue Value;
      SILLocation Loc;
    } TheLV;
    Expr *TheExpr;

    Storage() {}
    ~Storage() {}
  } Storage;

  enum class Kind : unsigned char {
    RValue,
    LValue,
    Expr,
  } StoredKind;

  void initRV(SILLocation loc, RValue &&value) {
    assert(StoredKind == Kind::RValue);
    Storage.TheRV.Loc = loc;
    new (&Storage.TheRV.Value) RValue(std::move(value));
  }

  void initLV(SILLocation loc, LValue &&value) {
    assert(StoredKind == Kind::LValue);
    Storage.TheLV.Loc = loc;
    new (&Storage.TheLV.Value) LValue(std::move(value));
  }

public:
  ArgumentSource() : StoredKind(Kind::Expr) {
    Storage.TheExpr = nullptr;
  }
  ArgumentSource(SILLocation loc, RValue &&value) : StoredKind(Kind::RValue) {
    initRV(loc, std::move(value));
  }
  ArgumentSource(SILLocation loc, LValue &&value) : StoredKind(Kind::LValue) {
    initLV(loc, std::move(value));
  }
  ArgumentSource(Expr *e) : StoredKind(Kind::Expr) {
    assert(e && "initializing ArgumentSource with null expression");
    Storage.TheExpr = e;
  }

  // Cannot be copied.
  ArgumentSource(const ArgumentSource &other) = delete;
  ArgumentSource &operator=(const ArgumentSource &other) = delete;

  // Can be moved.
  ArgumentSource(ArgumentSource &&other) : StoredKind(other.StoredKind) {
    switch (StoredKind) {
    case Kind::RValue:
      initRV(other.getKnownRValueLocation(), std::move(other).asKnownRValue());
      return;
    case Kind::LValue:
      initLV(other.getKnownLValueLocation(), std::move(other).asKnownLValue());
      return;
    case Kind::Expr:
      Storage.TheExpr = std::move(other).asKnownExpr();
      return;
    }
    llvm_unreachable("bad kind");
  }

  ArgumentSource &operator=(ArgumentSource &&other) {
    // If the kinds don't align, just move the other object over this.
    if (StoredKind != other.StoredKind) {
      this->~ArgumentSource();
      new (this) ArgumentSource(std::move(other));
      return *this;
    }

    // Otherwise, move RValue and LValue objects in-place.
    switch (StoredKind) {
    case Kind::RValue:
      Storage.TheRV.Value = std::move(other).asKnownRValue();
      Storage.TheRV.Loc = other.getKnownRValueLocation();
      return *this;
    case Kind::LValue:
      Storage.TheLV.Value = std::move(other).asKnownLValue();
      Storage.TheLV.Loc = other.getKnownLValueLocation();
      return *this;
    case Kind::Expr:
      Storage.TheExpr = std::move(other).asKnownExpr();
      return *this;
    }
    llvm_unreachable("bad kind");
  }

  ~ArgumentSource() {
    switch (StoredKind) {
    case Kind::RValue:
      asKnownRValue().~RValue();
      return;
    case Kind::LValue:
      asKnownLValue().~LValue();
      return;
    case Kind::Expr:
      return;
    }
    llvm_unreachable("bad kind");
  }

  explicit operator bool() const & {
    switch (StoredKind) {
    case Kind::RValue:
      return bool(asKnownRValue());
    case Kind::LValue:
      return asKnownLValue().isValid();
    case Kind::Expr:
      return asKnownExpr() != nullptr;
    }
    llvm_unreachable("bad kind");
  }

  CanType getSubstType() const & {
    switch (StoredKind) {
    case Kind::RValue:
      return asKnownRValue().getType();
    case Kind::LValue:
      return CanInOutType::get(asKnownLValue().getSubstFormalType());
    case Kind::Expr:
      return asKnownExpr()->getType()->getCanonicalType();
    }
    llvm_unreachable("bad kind");
  }

  CanType getSubstRValueType() const & {
    switch (StoredKind) {
    case Kind::RValue:
      return asKnownRValue().getType();
    case Kind::LValue:
      return asKnownLValue().getSubstFormalType();
    case Kind::Expr:
      return asKnownExpr()->getType()->getInOutObjectType()->getCanonicalType();
    }
    llvm_unreachable("bad kind");
  }

  bool hasLValueType() const & {
    switch (StoredKind) {
    case Kind::RValue: return false;
    case Kind::LValue: return true;
    case Kind::Expr: return asKnownExpr()->getType()->is<InOutType>();
    }
    llvm_unreachable("bad kind");    
  }

  SILLocation getLocation() const & {
    switch (StoredKind) {
    case Kind::RValue:
      return getKnownRValueLocation();
    case Kind::LValue:
      return getKnownLValueLocation();
    case Kind::Expr:
      return asKnownExpr();
    }
    llvm_unreachable("bad kind");
  }

  bool isRValue() const & { return StoredKind == Kind::RValue; }
  bool isLValue() const & { return StoredKind == Kind::LValue; }

  /// Given that this source is storing an RValue, extract and clear
  /// that value.
  RValue &&asKnownRValue() && {
    assert(isRValue());
    return std::move(Storage.TheRV.Value);
  }
  SILLocation getKnownRValueLocation() const & {
    assert(isRValue());
    return Storage.TheRV.Loc;
  }

  /// Given that this source is storing an LValue, extract and clear
  /// that value.
  LValue &&asKnownLValue() && {
    assert(isLValue());
    return std::move(Storage.TheLV.Value);
  }
  SILLocation getKnownLValueLocation() const & {
    assert(isLValue());
    return Storage.TheLV.Loc;
  }

  /// Given that this source is an expression, extract and clear
  /// that expression.
  Expr *asKnownExpr() && {
    assert(StoredKind == Kind::Expr);
    Expr *result = Storage.TheExpr;
    Storage.TheExpr = nullptr;
    return result;
  }

  /// Force this source to become an r-value, then return an unmoved
  /// handle to that r-value.
  RValue &forceAndPeekRValue(SILGenFunction &gen) &;

  /// Return an unowned handle to the r-value stored in this source. Undefined
  /// if this ArgumentSource is not an rvalue.
  RValue &peekRValue() &;

  RValue getAsRValue(SILGenFunction &gen, SGFContext C = SGFContext()) &&;
  ManagedValue getAsSingleValue(SILGenFunction &gen,
                                SGFContext C = SGFContext()) &&;
  ManagedValue getAsSingleValue(SILGenFunction &gen,
                                AbstractionPattern origFormalType,
                                SGFContext C = SGFContext()) &&;

  void forwardInto(SILGenFunction &gen, Initialization *dest) &&;
  void forwardInto(SILGenFunction &gen, AbstractionPattern origFormalType,
                   Initialization *dest, const TypeLowering &destTL) &&;

  ManagedValue materialize(SILGenFunction &gen) &&;

  /// Emit this value to memory so that it follows the abstraction
  /// patterns of the original formal type.
  ///
  /// \param expectedType - the lowering of getSubstType() under the
  ///   abstractions of origFormalType
  ManagedValue materialize(SILGenFunction &gen,
                           AbstractionPattern origFormalType,
                           SILType expectedType = SILType()) &&;

  // This is a hack and should be avoided.
  void rewriteType(CanType newType) &;

  /// Whether this argument source requires the callee to evaluate.
  bool requiresCalleeToEvaluate();

private:
  // Make the non-move accessors private to make it more difficult
  // to accidentally re-emit values.
  const RValue &asKnownRValue() const & {
    assert(isRValue());
    return Storage.TheRV.Value;
  }

  // Make the non-move accessors private to make it more difficult
  // to accidentally re-emit values.
  const LValue &asKnownLValue() const & {
    assert(isLValue());
    return Storage.TheLV.Value;
  }

  Expr *asKnownExpr() const & {
    assert(StoredKind == Kind::Expr);
    return Storage.TheExpr;
  }
};

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

#endif
