//===-- include/flang/Semantics/scope.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_SEMANTICS_SCOPE_H_
#define FORTRAN_SEMANTICS_SCOPE_H_

#include "attr.h"
#include "symbol.h"
#include "flang/Common/Fortran.h"
#include "flang/Common/idioms.h"
#include "flang/Common/reference.h"
#include "flang/Parser/message.h"
#include "flang/Parser/provenance.h"
#include <list>
#include <map>
#include <optional>
#include <set>
#include <string>

namespace llvm {
class raw_ostream;
}

namespace Fortran::semantics {

using namespace parser::literals;

using common::ConstantSubscript;

class SemanticsContext;

// An equivalence object is represented by a symbol for the variable name,
// the indices for an array element, and the lower bound for a substring.
struct EquivalenceObject {
  EquivalenceObject(Symbol &symbol, std::vector<ConstantSubscript> subscripts,
      std::optional<ConstantSubscript> substringStart, parser::CharBlock source)
      : symbol{symbol}, subscripts{subscripts},
        substringStart{substringStart}, source{source} {}
  explicit EquivalenceObject(Symbol &symbol)
      : symbol{symbol}, source{symbol.name()} {}

  bool operator==(const EquivalenceObject &) const;
  bool operator<(const EquivalenceObject &) const;
  std::string AsFortran() const;

  Symbol &symbol;
  std::vector<ConstantSubscript> subscripts; // for array elem
  std::optional<ConstantSubscript> substringStart;
  parser::CharBlock source;
};
using EquivalenceSet = std::vector<EquivalenceObject>;

class Scope {
  using mapType = std::map<SourceName, MutableSymbolRef>;

public:
  ENUM_CLASS(Kind, Global, Module, MainProgram, Subprogram, BlockData,
      DerivedType, Block, Forall, ImpliedDos)
  using ImportKind = common::ImportKind;

  // Create the Global scope -- the root of the scope tree
  explicit Scope(SemanticsContext &context)
      : Scope{*this, Kind::Global, nullptr, context} {}
  Scope(Scope &parent, Kind kind, Symbol *symbol, SemanticsContext &context)
      : parent_{parent}, kind_{kind}, symbol_{symbol}, context_{context} {
    if (symbol) {
      symbol->set_scope(this);
    }
  }
  Scope(const Scope &) = delete;

  bool operator==(const Scope &that) const { return this == &that; }
  bool operator!=(const Scope &that) const { return this != &that; }

  Scope &parent() {
    CHECK(&parent_ != this);
    return parent_;
  }
  const Scope &parent() const {
    CHECK(&parent_ != this);
    return parent_;
  }
  Kind kind() const { return kind_; }
  bool IsGlobal() const { return kind_ == Kind::Global; }
  bool IsModule() const {
    return kind_ == Kind::Module &&
        !symbol_->get<ModuleDetails>().isSubmodule();
  }
  bool IsSubmodule() const {
    return kind_ == Kind::Module && symbol_->get<ModuleDetails>().isSubmodule();
  }
  bool IsDerivedType() const { return kind_ == Kind::DerivedType; }
  bool IsStmtFunction() const;
  bool IsParameterizedDerivedType() const;
  bool IsParameterizedDerivedTypeInstantiation() const {
    return kind_ == Kind::DerivedType && !symbol_;
  }
  Symbol *symbol() { return symbol_; }
  const Symbol *symbol() const { return symbol_; }
  SemanticsContext &context() const { return context_; }

  inline const Symbol *GetSymbol() const;
  const Scope *GetDerivedTypeParent() const;
  const Scope &GetDerivedTypeBase() const;
  inline std::optional<SourceName> GetName() const;
  bool Contains(const Scope &) const;
  /// Make a scope nested in this one
  Scope &MakeScope(Kind kind, Symbol *symbol = nullptr);
  SemanticsContext &GetMutableSemanticsContext() const {
    return const_cast<SemanticsContext &>(context());
  }

  using size_type = mapType::size_type;
  using iterator = mapType::iterator;
  using const_iterator = mapType::const_iterator;

  iterator begin() { return symbols_.begin(); }
  iterator end() { return symbols_.end(); }
  const_iterator begin() const { return symbols_.begin(); }
  const_iterator end() const { return symbols_.end(); }
  const_iterator cbegin() const { return symbols_.cbegin(); }
  const_iterator cend() const { return symbols_.cend(); }

  // Return symbols in declaration order (the iterators above are in name order)
  SymbolVector GetSymbols() const;
  MutableSymbolVector GetSymbols();

  iterator find(const SourceName &name);
  const_iterator find(const SourceName &name) const {
    return symbols_.find(name);
  }
  size_type erase(const SourceName &);
  bool empty() const { return symbols_.empty(); }

  // Look for symbol by name in this scope and host (depending on imports).
  Symbol *FindSymbol(const SourceName &) const;

  // Look for component symbol by name in a derived type's scope and
  // parents'.
  Symbol *FindComponent(SourceName) const;

  /// Make a Symbol with unknown details.
  std::pair<iterator, bool> try_emplace(
      const SourceName &name, Attrs attrs = Attrs()) {
    return try_emplace(name, attrs, UnknownDetails());
  }
  /// Make a Symbol with provided details.
  template <typename D>
  common::IfNoLvalue<std::pair<iterator, bool>, D> try_emplace(
      const SourceName &name, D &&details) {
    return try_emplace(name, Attrs(), std::move(details));
  }
  /// Make a Symbol with attrs and details
  template <typename D>
  common::IfNoLvalue<std::pair<iterator, bool>, D> try_emplace(
      const SourceName &name, Attrs attrs, D &&details) {
    Symbol &symbol{MakeSymbol(name, attrs, std::move(details))};
    return symbols_.emplace(name, symbol);
  }
  // Make a copy of a symbol in this scope; nullptr if one is already there
  Symbol *CopySymbol(const Symbol &);

  std::list<EquivalenceSet> &equivalenceSets() { return equivalenceSets_; }
  const std::list<EquivalenceSet> &equivalenceSets() const {
    return equivalenceSets_;
  }
  void add_equivalenceSet(EquivalenceSet &&);
  // Cray pointers are saved as map of pointee name -> pointer symbol
  const mapType &crayPointers() const { return crayPointers_; }
  void add_crayPointer(const SourceName &, Symbol &);
  mapType &commonBlocks() { return commonBlocks_; }
  const mapType &commonBlocks() const { return commonBlocks_; }
  Symbol &MakeCommonBlock(const SourceName &);
  Symbol *FindCommonBlock(const SourceName &) const;

  /// Make a Symbol but don't add it to the scope.
  template <typename D>
  common::IfNoLvalue<Symbol &, D> MakeSymbol(
      const SourceName &name, Attrs attrs, D &&details) {
    return allSymbols.Make(*this, name, attrs, std::move(details));
  }

  std::list<Scope> &children() { return children_; }
  const std::list<Scope> &children() const { return children_; }

  // For Module scope, maintain a mapping of all submodule scopes with this
  // module as its ancestor module. AddSubmodule returns false if already there.
  Scope *FindSubmodule(const SourceName &) const;
  bool AddSubmodule(const SourceName &, Scope &);

  const DeclTypeSpec *FindType(const DeclTypeSpec &) const;
  const DeclTypeSpec &MakeNumericType(TypeCategory, KindExpr &&kind);
  const DeclTypeSpec &MakeLogicalType(KindExpr &&kind);
  const DeclTypeSpec &MakeCharacterType(
      ParamValue &&length, KindExpr &&kind = KindExpr{0});
  DeclTypeSpec &MakeDerivedType(DeclTypeSpec::Category, DerivedTypeSpec &&);
  const DeclTypeSpec &MakeTypeStarType();
  const DeclTypeSpec &MakeClassStarType();
  const DeclTypeSpec *GetType(const SomeExpr &);

  std::size_t size() const { return size_; }
  void set_size(std::size_t size) { size_ = size; }
  std::optional<std::size_t> alignment() const { return alignment_; }

  void SetAlignment(std::size_t n) {
    alignment_ = std::max(alignment_.value_or(0), n);
  }

  ImportKind GetImportKind() const;
  // Names appearing in IMPORT statements in this scope
  std::set<SourceName> importNames() const { return importNames_; }

  // Set the kind of imports from host into this scope.
  // Return an error message for incompatible kinds.
  std::optional<parser::MessageFixedText> SetImportKind(ImportKind);

  void add_importName(const SourceName &);

  // These members pertain to instantiations of parameterized derived types.
  const DerivedTypeSpec *derivedTypeSpec() const { return derivedTypeSpec_; }
  DerivedTypeSpec *derivedTypeSpec() { return derivedTypeSpec_; }
  void set_derivedTypeSpec(DerivedTypeSpec &spec) { derivedTypeSpec_ = &spec; }
  parser::Message::Reference instantiationContext() const {
    return instantiationContext_;
  };
  void set_instantiationContext(parser::Message::Reference &&mref) {
    instantiationContext_ = std::move(mref);
  }

  bool hasSAVE() const { return hasSAVE_; }
  void set_hasSAVE(bool yes = true) { hasSAVE_ = yes; }

  // The range of the source of this and nested scopes.
  const parser::CharBlock &sourceRange() const { return sourceRange_; }
  void AddSourceRange(const parser::CharBlock &);
  // Find the smallest scope under this one that contains source
  const Scope *FindScope(parser::CharBlock) const;
  Scope *FindScope(parser::CharBlock);

  // Attempts to find a match for a derived type instance
  const DeclTypeSpec *FindInstantiatedDerivedType(const DerivedTypeSpec &,
      DeclTypeSpec::Category = DeclTypeSpec::TypeDerived) const;

  bool IsModuleFile() const {
    return kind_ == Kind::Module && symbol_ &&
        symbol_->test(Symbol::Flag::ModFile);
  }

  void InstantiateDerivedTypes();

  const Symbol *runtimeDerivedTypeDescription() const {
    return runtimeDerivedTypeDescription_;
  }
  void set_runtimeDerivedTypeDescription(const Symbol &symbol) {
    runtimeDerivedTypeDescription_ = &symbol;
  }

private:
  Scope &parent_; // this is enclosing scope, not extended derived type base
  const Kind kind_;
  std::size_t size_{0}; // size in bytes
  std::optional<std::size_t> alignment_; // required alignment in bytes
  parser::CharBlock sourceRange_;
  Symbol *const symbol_; // if not null, symbol_->scope() == this
  std::list<Scope> children_;
  mapType symbols_;
  mapType commonBlocks_;
  std::list<EquivalenceSet> equivalenceSets_;
  mapType crayPointers_;
  std::map<SourceName, common::Reference<Scope>> submodules_;
  std::list<DeclTypeSpec> declTypeSpecs_;
  std::optional<ImportKind> importKind_;
  std::set<SourceName> importNames_;
  DerivedTypeSpec *derivedTypeSpec_{nullptr}; // dTS->scope() == this
  parser::Message::Reference instantiationContext_;
  bool hasSAVE_{false}; // scope has a bare SAVE statement
  const Symbol *runtimeDerivedTypeDescription_{nullptr};
  SemanticsContext &context_;
  // When additional data members are added to Scope, remember to
  // copy them, if appropriate, in FindOrInstantiateDerivedType().

  // Storage for all Symbols. Every Symbol is in allSymbols and every Symbol*
  // or Symbol& points to one in there.
  static Symbols<1024> allSymbols;

  bool CanImport(const SourceName &) const;
  const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);

  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Scope &);
};

// Inline so that it can be called from Evaluate without a link-time dependency.

inline const Symbol *Scope::GetSymbol() const {
  return symbol_         ? symbol_
      : derivedTypeSpec_ ? &derivedTypeSpec_->typeSymbol()
                         : nullptr;
}

inline std::optional<SourceName> Scope::GetName() const {
  if (const auto *sym{GetSymbol()}) {
    return sym->name();
  } else {
    return std::nullopt;
  }
}

} // namespace Fortran::semantics
#endif // FORTRAN_SEMANTICS_SCOPE_H_
