//===-- include/flang/Evaluate/fold-designator.h ----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_EVALUATE_FOLD_DESIGNATOR_H_
#define FORTRAN_EVALUATE_FOLD_DESIGNATOR_H_

// Resolves a designator at compilation time to a base symbol, a byte offset
// from that symbol, and a byte size.  Also resolves in the reverse direction,
// reconstructing a designator from a symbol, byte offset, and size.
// Used for resolving variables in DATA statements to ranges in their
// initial images.
// Some designators can also be folded into constant pointer descriptors,
// which also have per-dimension extent and stride information suitable
// for initializing a descriptor.
// (The designators that cannot be folded are those with vector-valued
// subscripts; they are allowed as DATA statement objects, but are not valid
// initial pointer targets.)

#include "common.h"
#include "expression.h"
#include "fold.h"
#include "shape.h"
#include "type.h"
#include "variable.h"
#include <optional>
#include <variant>

namespace Fortran::evaluate {

using common::ConstantSubscript;

// Identifies a single contiguous interval of bytes at a fixed offset
// from a known symbol.
class OffsetSymbol {
public:
  OffsetSymbol(const Symbol &symbol, std::size_t bytes)
      : symbol_{symbol}, size_{bytes} {}
  DECLARE_CONSTRUCTORS_AND_ASSIGNMENTS(OffsetSymbol)

  const Symbol &symbol() const { return *symbol_; }
  void set_symbol(const Symbol &symbol) { symbol_ = symbol; };
  ConstantSubscript offset() const { return offset_; }
  void Augment(ConstantSubscript n) { offset_ += n; }
  std::size_t size() const { return size_; }
  void set_size(std::size_t bytes) { size_ = bytes; }

private:
  SymbolRef symbol_;
  ConstantSubscript offset_{0};
  std::size_t size_;
};

// Folds a Designator<T> into a sequence of OffsetSymbols, if it can
// be so folded.  Array sections yield multiple results, each
// corresponding to an element in array element order.
class DesignatorFolder {
public:
  explicit DesignatorFolder(FoldingContext &c) : context_{c} {}

  bool isEmpty() const { return isEmpty_; }
  bool isOutOfRange() const { return isOutOfRange_; }

  template <typename T>
  std::optional<OffsetSymbol> FoldDesignator(const Expr<T> &expr) {
    return std::visit(
        [&](const auto &x) { return FoldDesignator(x, elementNumber_++); },
        expr.u);
  }

private:
  std::optional<OffsetSymbol> FoldDesignator(const Symbol &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const SymbolRef &x, ConstantSubscript which) {
    return FoldDesignator(*x, which);
  }
  std::optional<OffsetSymbol> FoldDesignator(
      const ArrayRef &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const Component &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const ComplexPart &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const Substring &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const DataRef &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const NamedEntity &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const CoarrayRef &, ConstantSubscript);
  std::optional<OffsetSymbol> FoldDesignator(
      const ProcedureDesignator &, ConstantSubscript);

  template <typename T>
  std::optional<OffsetSymbol> FoldDesignator(
      const Expr<T> &expr, ConstantSubscript which) {
    return std::visit(
        [&](const auto &x) { return FoldDesignator(x, which); }, expr.u);
  }

  template <typename A>
  std::optional<OffsetSymbol> FoldDesignator(const A &x, ConstantSubscript) {
    return std::nullopt;
  }

  template <typename T>
  std::optional<OffsetSymbol> FoldDesignator(
      const Designator<T> &designator, ConstantSubscript which) {
    return std::visit(
        [&](const auto &x) { return FoldDesignator(x, which); }, designator.u);
  }
  template <int KIND>
  std::optional<OffsetSymbol> FoldDesignator(
      const Designator<Type<TypeCategory::Character, KIND>> &designator,
      ConstantSubscript which) {
    return std::visit(
        common::visitors{
            [&](const Substring &ss) {
              if (const auto *dataRef{ss.GetParentIf<DataRef>()}) {
                if (auto result{FoldDesignator(*dataRef, which)}) {
                  if (auto start{ToInt64(ss.lower())}) {
                    std::optional<ConstantSubscript> end;
                    auto len{dataRef->LEN()};
                    if (ss.upper()) {
                      end = ToInt64(*ss.upper());
                    } else if (len) {
                      end = ToInt64(*len);
                    }
                    if (end) {
                      if (*start < 1) {
                        isOutOfRange_ = true;
                      }
                      result->Augment(KIND * (*start - 1));
                      result->set_size(
                          *end >= *start ? KIND * (*end - *start + 1) : 0);
                      if (len) {
                        if (auto lenVal{ToInt64(*len)}) {
                          if (*end > *lenVal) {
                            isOutOfRange_ = true;
                          }
                        }
                      }
                      return result;
                    }
                  }
                }
              }
              return std::optional<OffsetSymbol>{};
            },
            [&](const auto &x) { return FoldDesignator(x, which); },
        },
        designator.u);
  }

  FoldingContext &context_;
  ConstantSubscript elementNumber_{0}; // zero-based
  bool isEmpty_{false};
  bool isOutOfRange_{false};
};

// Reconstructs a Designator<> from a symbol and an offset.
std::optional<Expr<SomeType>> OffsetToDesignator(
    FoldingContext &, const Symbol &, ConstantSubscript offset, std::size_t);
std::optional<Expr<SomeType>> OffsetToDesignator(
    FoldingContext &, const OffsetSymbol &);

// Represents a compile-time constant Descriptor suitable for use
// as a pointer initializer.  Lower bounds are always 1.
struct ConstantObjectPointer : public OffsetSymbol {
  struct Dimension {
    ConstantSubscript byteStride;
    ConstantSubscript extent;
  };
  using Dimensions = std::vector<Dimension>;

  ConstantObjectPointer(
      const Symbol &symbol, std::size_t size, Dimensions &&dims)
      : OffsetSymbol{symbol, size}, dimensions{std::move(dims)} {}

  // Folds a designator to a constant pointer.  Crashes on failure.
  // Use IsInitialDataTarget() to validate the expression beforehand.
  static ConstantObjectPointer From(FoldingContext &, const Expr<SomeType> &);

  Dimensions dimensions;
};

} // namespace Fortran::evaluate
#endif // FORTRAN_EVALUATE_FOLD_DESIGNATOR_H_
